diff --git a/Unity/Thing.cs b/Unity/Thing.cs index 676a335..457f893 100644 --- a/Unity/Thing.cs +++ b/Unity/Thing.cs @@ -35,7 +35,6 @@ namespace RoboidControl.Unity { } siteServer.site.Add(thing); core.OnPoseChanged += PoseChanged; - core.OnHierarchyChanged += ParentChanged; } public static Thing Create(RoboidControl.Thing core) { @@ -60,15 +59,17 @@ namespace RoboidControl.Unity { this.transform.localRotation = core.orientation.ToQuaternion(); core.OnPoseChanged += this.PoseChanged; - core.OnHierarchyChanged += ParentChanged; } /// /// Update the Unity representation /// protected virtual void Update() { - if (core == null) + if (core == null) { + Debug.Log("Core thing is gone, self destruct in 0 seconds..."); + Destroy(this); return; + } if (core.linearVelocity != null && core.linearVelocity.distance != 0) { Vector3 direction = Quaternion.AngleAxis(core.linearVelocity.direction.horizontal, Vector3.up) * Vector3.forward; @@ -111,14 +112,6 @@ namespace RoboidControl.Unity { this.transform.localRotation = core.orientation.ToQuaternion(); } - private void ParentChanged() { - - // if (core.parent == null) - // this.transform.SetParent(null, true); - // else - // this.transform.SetParent(core.parent.component.transform, true); - } - private IEnumerator LoadJPG() { UnityWebRequest request = UnityWebRequestTexture.GetTexture(core.modelUrl); yield return request.SendWebRequest(); diff --git a/src/Messages/DestroyMsg.cs b/src/Messages/DestroyMsg.cs index 0fad15e..87eaf5b 100644 --- a/src/Messages/DestroyMsg.cs +++ b/src/Messages/DestroyMsg.cs @@ -26,9 +26,9 @@ namespace RoboidControl { /// /// The network ID of the thing /// The ID of the thing - public DestroyMsg(byte networkId, byte thingId) { + public DestroyMsg(byte networkId, Thing thing) { this.networkId = networkId; - this.thingId = thingId; + this.thingId = thing.id; } /// @copydoc Passer::RoboidControl::IMessage::IMessage(byte[] buffer) public DestroyMsg(byte[] buffer) : base(buffer) { diff --git a/src/ParticipantUDP.cs b/src/Participants/ParticipantUDP.cs similarity index 87% rename from src/ParticipantUDP.cs rename to src/Participants/ParticipantUDP.cs index e6aeb5d..b2d763a 100644 --- a/src/ParticipantUDP.cs +++ b/src/Participants/ParticipantUDP.cs @@ -95,17 +95,21 @@ namespace RoboidControl { #region Update protected ulong nextPublishMe = 0; - public override void Update(ulong currentTimeMS = 0) { - if (currentTimeMS == 0) { -#if UNITY_5_3_OR_NEWER - currentTimeMS = (ulong)(UnityEngine.Time.time * 1000); -#endif - } - if (this.publishInterval > 0 && currentTimeMS > this.nextPublishMe) { - Publish(); - // Console.WriteLine($"{this.name} Publish ClientMsg {this.networkId}"); - this.nextPublishMe = currentTimeMS + this.publishInterval; + public override void Update(ulong currentTimeMS = 0) { + if (currentTimeMS == 0) + currentTimeMS = Thing.GetTimeMs(); + + if (this.isIsolated == false) { + if (this.publishInterval > 0 && currentTimeMS > this.nextPublishMe) { + ParticipantMsg msg = new ParticipantMsg(this.networkId); + if (this.remoteSite == null) + this.Publish(msg); + else + this.Send(this.remoteSite, msg); + + this.nextPublishMe = currentTimeMS + this.publishInterval; + } } UpdateMyThings(currentTimeMS); @@ -113,26 +117,35 @@ namespace RoboidControl { } protected virtual void UpdateMyThings(ulong currentTimeMS) { - int n = this.things.Count; - for (int ix = 0; ix < n; ix++) { - Thing thing = this.things[ix]; - if (thing == null || thing.parent != null) + foreach (Thing thing in this.things) { + if (thing == null) continue; - + if (thing.hierarchyChanged && !(this.isIsolated || this.networkId == 0)) { ThingMsg thingMsg = new(this.networkId, thing); this.Send(this.remoteSite, thingMsg); } - thing.Update(currentTimeMS, true); - if (this.isIsolated || this.networkId == 0) - continue; - - // Send to remote site - PoseMsg poseMsg = new(thing.owner.networkId, thing); - this.Send(this.remoteSite, poseMsg); - BinaryMsg binaryMsg = new(thing.owner.networkId, thing); - this.Send(this.remoteSite, binaryMsg); + // Why don't we do recursive? + // Because when a thing creates a thing in the update, + // that new thing is not sent out (because of hierarchyChanged) + // before it is updated itself: it is immediatedly updated! + thing.Update(currentTimeMS, false); + if (!(this.isIsolated || this.networkId == 0)) { + if (thing.terminate) { + DestroyMsg destroyMsg = new(this.networkId, thing); + this.Send(this.remoteSite, destroyMsg); + } + else { + // Send to remote site + PoseMsg poseMsg = new(thing.owner.networkId, thing); + this.Send(this.remoteSite, poseMsg); + BinaryMsg binaryMsg = new(thing.owner.networkId, thing); + this.Send(this.remoteSite, binaryMsg); + } + } + if (thing.terminate) + this.Remove(thing); } } @@ -147,6 +160,9 @@ namespace RoboidControl { continue; foreach (Thing thing in participant.things) { + if (thing == null) + continue; + PoseMsg poseMsg = new(thing.owner.networkId, thing); this.Send(participant, poseMsg); BinaryMsg binaryMsg = new(thing.owner.networkId, thing); @@ -179,10 +195,6 @@ namespace RoboidControl { return true; } - public virtual void Publish() { - this.Publish(new ParticipantMsg(this.networkId)); - } - public void PublishThingInfo(Thing thing) { // Console.WriteLine("Publish thing info"); this.Publish(new ThingMsg(this.networkId, thing)); @@ -282,7 +294,7 @@ namespace RoboidControl { break; case DestroyMsg.Id: // 0x20 / 32 this.Process(sender, new DestroyMsg(data)); - // result = await DestroyMsg.Receive(dataStream, client, packetSize); + // result = await DestroyMsg.Receive(dataStream, client, packetSize); break; default: break; @@ -383,7 +395,10 @@ namespace RoboidControl { #if DEBUG Console.WriteLine($"Participant: Process Destroy Msg [{msg.networkId}/{msg.thingId}]"); #endif - + Thing thing = sender.Get(msg.networkId, msg.thingId); + if (thing != null) + this.Remove(thing); + thing.component.core = null; } private void ForwardMessage(IMessage msg) { diff --git a/src/SiteServer.cs b/src/Participants/SiteServer.cs similarity index 57% rename from src/SiteServer.cs rename to src/Participants/SiteServer.cs index 6a7c905..d86b21c 100644 --- a/src/SiteServer.cs +++ b/src/Participants/SiteServer.cs @@ -30,39 +30,40 @@ namespace RoboidControl { this.udpClient?.Close(); } + #region Update + protected override void UpdateMyThings(ulong currentTimeMS) { - int n = this.things.Count; - for (int ix = 0; ix < n; ix++) { - Thing thing = this.things[ix]; - if (thing == null || thing.parent != null) + foreach (Thing thing in this.things) { + if (thing == null) continue; - thing.Update(currentTimeMS, true); - if (this.isIsolated || this.networkId == 0) - continue; + thing.Update(currentTimeMS, false); - // Send to all other participants - foreach (Participant participant in Participant.participants) { - if (participant == null || participant == this) - continue; + if (this.isIsolated == false) { + // Send to all other participants + foreach (Participant participant in Participant.participants) { + if (participant == null || participant == this) + continue; - PoseMsg poseMsg = new(thing.owner.networkId, thing); - this.Send(participant, poseMsg); - BinaryMsg binaryMsg = new(thing.owner.networkId, thing); - this.Send(participant, binaryMsg); + PoseMsg poseMsg = new(thing.owner.networkId, thing); + this.Send(participant, poseMsg); + BinaryMsg binaryMsg = new(thing.owner.networkId, thing); + this.Send(participant, binaryMsg); + } } } } - public override void Publish() { - } + #endregion Update + + #region Receive protected override void Process(Participant sender, ParticipantMsg msg) { base.Process(sender, msg); - //if (msg.networkId == 0) { - //Console.WriteLine($"{this.name} received New Participant -> {sender.networkId}"); - this.Send(sender, new NetworkIdMsg(sender.networkId)); - //} + if (msg.networkId != sender.networkId) { + //Console.WriteLine($"{this.name} received New Participant -> {sender.networkId}"); + this.Send(sender, new NetworkIdMsg(sender.networkId)); + } } protected override void Process(Participant sender, NetworkIdMsg msg) { } @@ -70,23 +71,22 @@ namespace RoboidControl { protected override void Process(Participant sender, ThingMsg msg) { Console.WriteLine($"SiteServer: Process thing [{msg.networkId}/{msg.thingId}] {msg.thingType} {msg.parentId} "); Thing thing = sender.Get(msg.networkId, msg.thingId); - if (thing == null) { - thing = new Thing(sender, msg.networkId, msg.thingId, msg.thingType); - // Console.WriteLine("Created generic new core thing"); - // } - } + if (thing == null) + thing = new Thing(sender, msg.networkId, msg.thingId, msg.thingType); if (msg.parentId != 0) { - Thing parentThing = Get(msg.networkId, msg.parentId); - if (parentThing == null) + thing.parent = Get(msg.networkId, msg.parentId); + if (thing.parent == null) Console.WriteLine($"Could not find parent [{msg.networkId}/{msg.parentId}]"); - else - thing.parent = parentThing; } else { Console.Write($"Dropped {thing.id}"); thing.parent = null; } } + + #endregion Receive + } + } \ No newline at end of file diff --git a/src/Thing.cs b/src/Thing.cs index 856277d..a00774a 100644 --- a/src/Thing.cs +++ b/src/Thing.cs @@ -146,14 +146,9 @@ namespace RoboidControl { else { value.AddChild(this); } - OnHierarchyChanged?.Invoke(); this.hierarchyChanged = true; } } - /// - /// Event which is triggered when the parent changes - /// - public event ChangeHandler OnHierarchyChanged = delegate { }; /// /// Add a child Thing to this Thing @@ -352,10 +347,18 @@ namespace RoboidControl { public Unity.Thing component = null; #endif + public bool terminate = false; + #endregion Properties #region Methods + public static ulong GetTimeMs() { +#if UNITY_5_3_OR_NEWER + return (ulong)(UnityEngine.Time.time * 1000); +#endif + } + /// /// Update de state of the thing ///