Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
Xlinka committed Dec 16, 2023
1 parent ee8744a commit b0144b4
Show file tree
Hide file tree
Showing 11 changed files with 343 additions and 162 deletions.
152 changes: 152 additions & 0 deletions Components/Network/ART-NET/ARTNETCLIENT.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using Elements.Core;
using FrooxEngine;

namespace Obsidian
{

[Category(new string[] { "Obsidian/Network/ArtNet" })]
public class ArtNetClient : Component
{
public readonly Sync<Uri> URL;
public readonly UserRef HandlingUser;
public readonly Sync<string> AccessReason;
public readonly Sync<float> ConnectRetryInterval;
public readonly Sync<bool> IsConnected;

private Uri _currentURL;
private UdpClient _udpClient;

public event Action<ArtNetClient> Connected;
public event Action<ArtNetClient> Closed;
public event Action<ArtNetClient, string> Error;
public event Action<ArtNetClient, byte[]> PacketReceived; // For ArtNet packets
public event Action<ArtNetClient, byte[]> DMXDataReceived; // For DMX512 data

protected override void OnAwake()
{
ConnectRetryInterval.Value = 10f;
}

protected override void OnChanges()
{
Uri uri = (Enabled ? URL.Value : null);
if (HandlingUser.Target != LocalUser)
{
uri = null;
}

if (uri != _currentURL)
{
_currentURL = uri;
CloseCurrent();
IsConnected.Value = false;
if (_currentURL != null)
{
StartTask(async delegate
{
await ConnectTo(_currentURL);
});
}
}
}

private async Task ConnectTo(Uri target)
{
if (target.Scheme != "artnet")
{
Error?.Invoke(this, "Invalid URL scheme. Expected 'artnet://'.");
return;
}

if (await Engine.Security.RequestAccessPermission(target.Host, target.Port, AccessReason.Value ?? "ArtNet Client") == HostAccessPermission.Allowed && !(target != _currentURL) && !IsRemoved)
{
_udpClient = new UdpClient(target.Port);
IsConnected.Value = true;
Connected?.Invoke(this);
StartTask(ReceiveLoop);
}
}

private async Task ReceiveLoop()
{
var remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
while (IsConnected.Value && _udpClient != null)
{
try
{
UdpReceiveResult result = await _udpClient.ReceiveAsync();
byte[] receivedData = result.Buffer;

// Check if the data is an ArtNet packet or DMX512 data
if (IsArtNetPacket(receivedData))
{
PacketReceived?.Invoke(this, receivedData);
}
else
{
DMXDataReceived?.Invoke(this, receivedData);
}
}
catch (Exception ex)
{
Error?.Invoke(this, ex.Message);
break;
}
}
}

private bool IsArtNetPacket(byte[] data)
{
// Art-Net packets start with the ASCII sequence for "Art-Net" followed by a null byte.
byte[] artNetHeader = new byte[] { 65, 114, 116, 45, 78, 101, 116, 0 };

if (data.Length < artNetHeader.Length)
{
return false;
}

for (int i = 0; i < artNetHeader.Length; i++)
{
if (data[i] != artNetHeader[i])
{
return false;
}
}

return true;
}

protected override void OnDispose()
{
CloseCurrent();
base.OnDispose();
}

private void CloseCurrent()
{
if (_udpClient != null)
{
UdpClient udpClient = _udpClient;
_udpClient = null;
try
{
Closed?.Invoke(this);
}
catch (Exception ex)
{
UniLog.Error("Exception in running Closed event on ArtNetClient:\n" + ex);
}
udpClient.Close();
}
}

public static implicit operator ArtNetClient(ProtoFlux.Runtimes.Execution.Nodes.FrooxEngine.Network.WebsocketConnect v)
{
throw new NotImplementedException();
}
}
}
3 changes: 3 additions & 0 deletions ProjectObsidian.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,7 @@
<HintPath>$(ResonitePath)Resonite_Data/Managed/Elements.Assets.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Folder Include="ProtoFlux\Bindings\Network\Art-Net\" />
</ItemGroup>
</Project>
28 changes: 18 additions & 10 deletions ProtoFlux/Bindings/Math/Physics/CentipetalForceBinding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,34 +13,42 @@ public class CentripetalForceCalculation : FrooxEngine.ProtoFlux.Runtimes.Execut
public readonly SyncRef<INodeValueOutput<float>> Velocity;
public readonly SyncRef<INodeValueOutput<float>> Radius;

public override Type NodeType => typeof(CentripetalForceCalculation);
public override Type NodeType => typeof(ProtoFlux.Runtimes.Execution.Nodes.Obsidian.Math.Physics.CentripetalForceCalculationNode);

public CentripetalForceCalculationNode TypedNodeInstance { get; private set; }
public ProtoFlux.Runtimes.Execution.Nodes.Obsidian.Math.Physics.CentripetalForceCalculationNode TypedNodeInstance { get; private set; }

public override INode NodeInstance => TypedNodeInstance;

public override int NodeInputCount => base.NodeInputCount + 3;

public override TN Instantiate<TN>()
public override N Instantiate<N>()
{
if (TypedNodeInstance != null)
{
throw new InvalidOperationException("Node has already been instantiated");
var instance = (TypedNodeInstance = new CentripetalForceCalculationNode());
return instance as TN;
}
ProtoFlux.Runtimes.Execution.Nodes.Obsidian.Math.Physics.CentripetalForceCalculationNode centripetalForceCalculationNode2 = (TypedNodeInstance = new ProtoFlux.Runtimes.Execution.Nodes.Obsidian.Math.Physics.CentripetalForceCalculationNode());
return centripetalForceCalculationNode2 as N;
}

protected override void AssociateInstanceInternal(INode node)
{
if (node is not CentripetalForceCalculationNode typedNodeInstance)
throw new ArgumentException("Node instance is not of type " + typeof(CentripetalForceCalculationNode));
TypedNodeInstance = typedNodeInstance;
if (node is ProtoFlux.Runtimes.Execution.Nodes.Obsidian.Math.Physics.CentripetalForceCalculationNode typedNodeInstance)
{
TypedNodeInstance = typedNodeInstance;
return;
}
throw new ArgumentException("Node instance is not of type " + typeof(ProtoFlux.Runtimes.Execution.Nodes.Obsidian.Math.Physics.CentripetalForceCalculationNode));
}

public override void ClearInstance() => TypedNodeInstance = null;
public override void ClearInstance()
{
TypedNodeInstance = null;
}

protected override ISyncRef GetInputInternal(ref int index)
{
var inputInternal = base.GetInputInternal(ref index);
ISyncRef inputInternal = base.GetInputInternal(ref index);
if (inputInternal != null)
{
return inputInternal;
Expand Down
63 changes: 18 additions & 45 deletions ProtoFlux/Bindings/Math/Physics/DragCalculationBinding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
using ProtoFlux.Runtimes.Execution;
using ProtoFlux.Runtimes.Execution.Nodes.Obsidian.Math.Physics;

[Category("ProtoFlux/Runtimes/Execution/Nodes/Obsidian/Math/Physics")]
public class DragCalculation : FrooxEngine.ProtoFlux.Runtimes.Execution.ValueFunctionNode<ExecutionContext, float3>
[Category(new string[] { "ProtoFlux/Runtimes/Execution/Nodes/Obsidian/Math/Physics" })]
public class DragCalculationNodeBinding : FrooxEngine.ProtoFlux.Runtimes.Execution.ValueFunctionNode<ExecutionContext, float3>
{
public readonly SyncRef<INodeValueOutput<float>> FluidDensity;
public readonly SyncRef<INodeValueOutput<float3>> ObjectVelocity;
Expand All @@ -20,64 +20,37 @@ public class DragCalculation : FrooxEngine.ProtoFlux.Runtimes.Execution.ValueFun

public override INode NodeInstance => TypedNodeInstance;

public override int NodeInputCount => base.NodeInputCount + 4;
public override int NodeInputCount => 4;

public override TN Instantiate<TN>()
public override N Instantiate<N>()
{
try
if (TypedNodeInstance != null)
{
if (TypedNodeInstance != null)
throw new InvalidOperationException("Node has already been instantiated");
var dragCalculationInstance = (TypedNodeInstance = new DragCalculationNode());
return dragCalculationInstance as TN;
}
catch (Exception ex)
{
UniLog.Log($"Error in DragCalculationBinding.Instantiate: {ex.Message}");
throw;
throw new InvalidOperationException("Node has already been instantiated");
}
TypedNodeInstance = new DragCalculationNode();
return TypedNodeInstance as N;
}

protected override void AssociateInstanceInternal(INode node)
{
try
{
if (node is not DragCalculationNode typedNodeInstance)
throw new ArgumentException("Node instance is not of type " + typeof(DragCalculationNode));
TypedNodeInstance = typedNodeInstance;
}
catch (Exception ex)
{
UniLog.Log($"Error in DragCalculationBinding.AssociateInstanceInternal: {ex.Message}");
throw;
}
TypedNodeInstance = node as DragCalculationNode ?? throw new ArgumentException("Node instance is not of type DragCalculationNode");
}

public override void ClearInstance() => TypedNodeInstance = null;
public override void ClearInstance()
{
TypedNodeInstance = null;
}

//without this it crashes i hate it
protected override ISyncRef GetInputInternal(ref int index)
{
var inputInternal = base.GetInputInternal(ref index);
if (inputInternal != null)
{
return inputInternal;
}
switch (index)
{
case 0:
return FluidDensity;
case 1:
return ObjectVelocity;
case 2:
return DragCoefficient;
case 3:
return CrossSectionalArea;
default:
index -= 4;
return null;
case 0: return FluidDensity;
case 1: return ObjectVelocity;
case 2: return DragCoefficient;
case 3: return CrossSectionalArea;
default: index -= 4; return null;
}
}


}
36 changes: 15 additions & 21 deletions ProtoFlux/Bindings/Math/Physics/KineticFrictionBinding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using ProtoFlux.Runtimes.Execution.Nodes.Obsidian.Math.Physics;

[Category(new string[] { "ProtoFlux/Runtimes/Execution/Nodes/Obsidian/Math/Physics" })]
public class KineticFrictionCalculation : FrooxEngine.ProtoFlux.Runtimes.Execution.ValueFunctionNode<ExecutionContext, float3>
public class KineticFrictionNodeBinding : FrooxEngine.ProtoFlux.Runtimes.Execution.ValueFunctionNode<ExecutionContext, float3>
{
public readonly SyncRef<INodeValueOutput<float3>> NormalForce;
public readonly SyncRef<INodeValueOutput<float>> KineticFrictionCoefficient;
Expand All @@ -18,41 +18,35 @@ public class KineticFrictionCalculation : FrooxEngine.ProtoFlux.Runtimes.Executi

public override INode NodeInstance => TypedNodeInstance;

public override int NodeInputCount => base.NodeInputCount + 2;
public override int NodeInputCount => 2;

public override TN Instantiate<TN>()
public override N Instantiate<N>()
{
if (TypedNodeInstance != null)
{
throw new InvalidOperationException("Node has already been instantiated");
var instance = (TypedNodeInstance = new KineticFrictionNode());
return instance as TN;
}
TypedNodeInstance = new KineticFrictionNode();
return TypedNodeInstance as N;
}

protected override void AssociateInstanceInternal(INode node)
{
if (node is not KineticFrictionNode typedNodeInstance)
throw new ArgumentException("Node instance is not of type " + typeof(KineticFrictionNode));
TypedNodeInstance = typedNodeInstance;
TypedNodeInstance = node as KineticFrictionNode ?? throw new ArgumentException("Node instance is not of type KineticFrictionNode");
}

public override void ClearInstance() => TypedNodeInstance = null;
public override void ClearInstance()
{
TypedNodeInstance = null;
}

protected override ISyncRef GetInputInternal(ref int index)
{
var inputInternal = base.GetInputInternal(ref index);
if (inputInternal != null)
{
return inputInternal;
}
switch (index)
{
case 0:
return NormalForce;
case 1:
return KineticFrictionCoefficient;
default:
index -= 2;
return null;
case 0: return NormalForce;
case 1: return KineticFrictionCoefficient;
default: index -= 2; return null;
}
}
}
Loading

0 comments on commit b0144b4

Please sign in to comment.