diff --git a/code/entities/ButtonEntity.cs b/code/entities/ButtonEntity.cs index 3462079..eccf4bd 100755 --- a/code/entities/ButtonEntity.cs +++ b/code/entities/ButtonEntity.cs @@ -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() { diff --git a/code/entities/LampEntity.wire.cs b/code/entities/LampEntity.wire.cs index cba6415..8e35e4b 100755 --- a/code/entities/LampEntity.wire.cs +++ b/code/entities/LampEntity.wire.cs @@ -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( 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; + } ); } } diff --git a/code/entities/LightEntity.wire.cs b/code/entities/LightEntity.wire.cs index f1fa7fd..67b14b2 100755 --- a/code/entities/LightEntity.wire.cs +++ b/code/entities/LightEntity.wire.cs @@ -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( 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; + } ); } } diff --git a/code/entities/ThrusterEntity.wire.cs b/code/entities/ThrusterEntity.wire.cs index cf1103e..87983bc 100755 --- a/code/entities/ThrusterEntity.wire.cs +++ b/code/entities/ThrusterEntity.wire.cs @@ -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( 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; - } + } ); } } diff --git a/code/entities/WireInputEntity.cs b/code/entities/WireInputEntity.cs index 4acec9e..174eb49 100755 --- a/code/entities/WireInputEntity.cs +++ b/code/entities/WireInputEntity.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System; namespace Sandbox { @@ -8,48 +9,83 @@ public class WireInput public int value; public Entity entity; public string inputName; + public string type; public List connected = new List(); - 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> allInputs = new Dictionary>(); - - public int NetworkIdent { get; } public void WireTriggerInput( 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( 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( string inputName, Action handler ) { - allInputs[this.NetworkIdent] = new Dictionary(); - 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(); } } diff --git a/code/entities/WireOutputEntity.cs b/code/entities/WireOutputEntity.cs index 026c145..fa419dd 100755 --- a/code/entities/WireOutputEntity.cs +++ b/code/entities/WireOutputEntity.cs @@ -17,12 +17,8 @@ public WireOutput( Entity entity, string newOutputName ) } } - public interface WireOutputEntity + public interface WireOutputEntity : IWireEntity { - protected static Dictionary> allOutputs = new Dictionary>(); - - public int NetworkIdent { get; } - public static void WireTriggerOutput( WireOutputEntity ent, string outputName, int value ) { var output = ent.GetOutput( outputName ); @@ -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(); 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(); diff --git a/code/entities/WirePortData.cs b/code/entities/WirePortData.cs new file mode 100755 index 0000000..a456544 --- /dev/null +++ b/code/entities/WirePortData.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Sandbox +{ + public class WirePortData + { + public Dictionary> inputHandlers { get; } = new Dictionary>(); + public Dictionary inputs = new Dictionary(); + public Dictionary outputs = new Dictionary(); + + } + + public interface IWireEntity + { + public WirePortData WirePorts { get; } + } +} diff --git a/code/tools/Wire.cs b/code/tools/Wire.cs index e0d1f72..c1d1572 100755 --- a/code/tools/Wire.cs +++ b/code/tools/Wire.cs @@ -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(); } }