Skip to content

Commit

Permalink
Add RegisterInputHandler() which takes a delegate; track its type
Browse files Browse the repository at this point in the history
Fixes #1
  • Loading branch information
Nebual committed Jun 8, 2021
1 parent 4ff20e8 commit 4b26be2
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 74 deletions.
1 change: 1 addition & 0 deletions code/entities/ButtonEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public partial class ButtonEntity : Prop, IUse, WireOutputEntity
{
public bool On { get; set; } = false;
public bool IsToggle { get; set; } = false;
WirePortData IWireEntity.WirePorts { get; } = new WirePortData();

public override void Spawn()
{
Expand Down
19 changes: 5 additions & 14 deletions code/entities/LampEntity.wire.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,11 @@

public partial class LampEntity : WireInputEntity
{
public string[] WireGetInputs()
WirePortData IWireEntity.WirePorts { get; } = new WirePortData();
public void WireInitialize()
{
return new string[] { "On" };
}

void WireInputEntity.HandleWireInput<T>( string inputName, T value )
{
if ( inputName == "On" ) {
if ( typeof( T ) == typeof( int ) ) {
Enabled = ((int)(object)value) != 0;
}
if ( typeof( T ) == typeof( float ) ) {
Enabled = (float)(object)value != 0.0f;
}
}
((WireInputEntity)this).RegisterInputHandler( "On", ( bool value ) => {
Enabled = value;
} );
}
}
18 changes: 5 additions & 13 deletions code/entities/LightEntity.wire.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
using Sandbox;
public partial class LightEntity : WireInputEntity
{
public string[] WireGetInputs()
WirePortData IWireEntity.WirePorts { get; } = new WirePortData();
public void WireInitialize()
{
return new string[] { "On" };
}
void WireInputEntity.HandleWireInput<T>( string inputName, T value )
{
if ( inputName == "On" ) {
if ( typeof( T ) == typeof( int ) ) {
Enabled = ((int)(object)value) != 0;
}
if ( typeof( T ) == typeof( float ) ) {
Enabled = (float)(object)value != 0.0f;
}
}
((WireInputEntity)this).RegisterInputHandler( "On", ( bool value ) => {
Enabled = value;
} );
}
}
20 changes: 5 additions & 15 deletions code/entities/ThrusterEntity.wire.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,12 @@ public partial class ThrusterEntity : WireInputEntity
// todo: the vanilla ThrusterEntity is just on/off, so we'll probably want to just replace it entirely, rather than this extending...
[Net]
public float ForceMultiplier { get; set; } = 1.0f;

public string[] WireGetInputs()
{
return new string[] { "ForceMultiplier" };
}

void WireInputEntity.HandleWireInput<T>( string inputName, T value )
WirePortData IWireEntity.WirePorts { get; } = new WirePortData();
public void WireInitialize()
{
if ( inputName == "ForceMultiplier" ) {
if ( typeof( T ) == typeof( int ) ) {
ForceMultiplier = ((int)(object)value);
}
if ( typeof( T ) == typeof( float ) ) {
ForceMultiplier = (float)(object)value;
}
((WireInputEntity)this).RegisterInputHandler( "ForceMultiplier", ( float value ) => {
ForceMultiplier = value;
Enabled = ForceMultiplier != 0.0f;
}
} );
}
}
74 changes: 55 additions & 19 deletions code/entities/WireInputEntity.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using System;

namespace Sandbox
{
Expand All @@ -8,48 +9,83 @@ public class WireInput
public int value;
public Entity entity;
public string inputName;
public string type;
public List<WireOutput> connected = new List<WireOutput>();

public WireInput( Entity entity, string inputName )
public WireInput( Entity entity, string inputName, string type )
{
this.entity = entity;
this.inputName = inputName;
this.type = type;
}
}
public interface WireInputEntity
public interface WireInputEntity : IWireEntity
{
protected static Dictionary<int, Dictionary<string, WireInput>> allInputs = new Dictionary<int, Dictionary<string, WireInput>>();

public int NetworkIdent { get; }
public void WireTriggerInput<T>( string inputName, T value )
{
HandleWireInput( inputName, value );
if ( WirePorts.inputHandlers.Count == 0 ) { // these get cleared by hot reloading
WireInitialize();
}
WirePorts.inputHandlers[inputName]( value );
}
public virtual void HandleWireInput<T>( string inputName, T value ) { }
public virtual void WireInitialize() { }

public WireInput GetInput( string inputName )
{
if ( !allInputs.ContainsKey( this.NetworkIdent ) ) {
InitializeInputs();
if ( WirePorts.inputHandlers.Count == 0 ) {
WireInitialize();
}
return allInputs[this.NetworkIdent][inputName];
return WirePorts.inputs[inputName];
}
public string[] GetInputNames()
{
if ( !allInputs.ContainsKey( this.NetworkIdent ) ) {
InitializeInputs();
if ( WirePorts.inputHandlers.Count == 0 ) {
WireInitialize();
}
return allInputs[this.NetworkIdent].Keys.ToArray();
return WirePorts.inputs.Keys.ToArray();
}

protected void InitializeInputs()
public void RegisterInputHandler<T>( string inputName, Action<T> handler )
{
allInputs[this.NetworkIdent] = new Dictionary<string, WireInput>();
foreach ( var inputName in WireGetInputs() ) {
allInputs[this.NetworkIdent][inputName] = new WireInput( (Entity)this, inputName );
if ( typeof( T ) == typeof( bool ) ) {
WirePorts.inputHandlers[inputName] = (( value ) => {
if ( value is int valueInt ) {
handler( (T)(object)(valueInt != 0) );
}
else if ( value is float valueFloat ) {
handler( (T)(object)(valueFloat != 0.0f) );
}
else {
handler( (T)value );
}
});
WirePorts.inputs[inputName] = new WireInput( (Entity)this, inputName, "bool" );
}
else if ( typeof( T ) == typeof( float ) ) {
WirePorts.inputHandlers[inputName] = (( value ) => {
if ( value is int valueInt ) {
handler( (T)(object)(float)(valueInt) );
}
else {
handler( (T)value );
}
});
WirePorts.inputs[inputName] = new WireInput( (Entity)this, inputName, "float" );
}
else if ( typeof( T ) == typeof( int ) ) {
WirePorts.inputHandlers[inputName] = (( value ) => {
if ( value is float valueInt ) {
handler( (T)(object)(int)(valueInt) );
}
else {
handler( (T)value );
}
});
WirePorts.inputs[inputName] = new WireInput( (Entity)this, inputName, "int" );
}
else {
throw new Exception( "Wirebox RegisterInputHandler<" + typeof( T ) + "> unhandled type for " + this.GetType() );
}
}
abstract public string[] WireGetInputs();
}

}
23 changes: 11 additions & 12 deletions code/entities/WireOutputEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,8 @@ public WireOutput( Entity entity, string newOutputName )
}
}

public interface WireOutputEntity
public interface WireOutputEntity : IWireEntity
{
protected static Dictionary<int, Dictionary<string, WireOutput>> allOutputs = new Dictionary<int, Dictionary<string, WireOutput>>();

public int NetworkIdent { get; }

public static void WireTriggerOutput( WireOutputEntity ent, string outputName, int value )
{
var output = ent.GetOutput( outputName );
Expand All @@ -35,29 +31,32 @@ public static void WireTriggerOutput( WireOutputEntity ent, string outputName, i
}
public void WireConnect( WireInputEntity inputEnt, string outputName, string inputName )
{
GetOutput( outputName ).connected.Add( inputEnt.GetInput( inputName ) );
var connected = GetOutput( outputName ).connected;
var input = inputEnt.GetInput( inputName );
if ( !connected.Contains( input ) ) {
connected.Add( input );
}
}

public WireOutput GetOutput( string inputName )
{
if ( !allOutputs.ContainsKey( this.NetworkIdent ) ) {
if ( WirePorts.outputs.Count == 0 ) {
InitializeOutputs();
}
return allOutputs[this.NetworkIdent][inputName];
return WirePorts.outputs[inputName];
}
public string[] GetOutputNames()
{
if ( !allOutputs.ContainsKey( this.NetworkIdent ) ) {
if ( WirePorts.outputs.Count == 0 ) {
InitializeOutputs();
}
return allOutputs[this.NetworkIdent].Keys.ToArray();
return WirePorts.outputs.Keys.ToArray();
}

protected void InitializeOutputs()
{
allOutputs[this.NetworkIdent] = new Dictionary<string, WireOutput>();
foreach ( var outputName in WireGetOutputs() ) {
allOutputs[this.NetworkIdent][outputName] = new WireOutput( (Entity)this, outputName );
WirePorts.outputs[outputName] = new WireOutput( (Entity)this, outputName );
}
}
abstract public string[] WireGetOutputs();
Expand Down
19 changes: 19 additions & 0 deletions code/entities/WirePortData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace Sandbox
{
public class WirePortData
{
public Dictionary<string, Action<object>> inputHandlers { get; } = new Dictionary<string, Action<object>>();
public Dictionary<string, WireInput> inputs = new Dictionary<string, WireInput>();
public Dictionary<string, WireOutput> outputs = new Dictionary<string, WireOutput>();

}

public interface IWireEntity
{
public WirePortData WirePorts { get; }
}
}
6 changes: 5 additions & 1 deletion code/tools/Wire.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ public override void Simulate()
if ( tr.Entity is not WireOutputEntity wireOutputProp )
return;

wireOutputProp.WireConnect( wireInputProp, wireOutputProp.GetOutputNames()[0], wireInputProp.GetInputNames()[0] );
var outputName = wireOutputProp.GetOutputNames()[0];
var inputName = wireInputProp.GetInputNames()[0];

wireOutputProp.WireConnect( wireInputProp, outputName, inputName );
WireOutputEntity.WireTriggerOutput( wireOutputProp, outputName, wireOutputProp.GetOutput( outputName ).value );
Reset();
}
}
Expand Down

0 comments on commit 4b26be2

Please sign in to comment.