From 632882d224bd43a02857961206f992ad031689b5 Mon Sep 17 00:00:00 2001 From: itn3000 Date: Fri, 2 Feb 2024 17:20:22 +0900 Subject: [PATCH 1/4] add collection and eventkey receiver, custom frameprovider factory --- .../R3.Stride.Sandbox/R3.Stride.Sandbox.sln | 1 + .../R3.Stride.Sandbox/Assets/Cube.sdpromodel | 12 ++ .../Assets/MainScene.sdscene | 77 ++++++++- .../R3.Stride.Sandbox/CubeCollisionTest.cs | 50 ++++++ .../R3.Stride.Sandbox/EventKeyReceiverTest.cs | 35 ++++ .../GlobalObservableTestScript.cs | 30 ---- .../R3.Stride.Sandbox/ObservableTestScript.cs | 11 +- src/R3.Stride/R3StrideCollectionExtension.cs | 31 ++++ src/R3.Stride/R3StrideEventExtension.cs | 154 ++++++++++++++++++ src/R3.Stride/StrideFrameProvider.cs | 25 ++- 10 files changed, 392 insertions(+), 34 deletions(-) create mode 100644 sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/Assets/Cube.sdpromodel create mode 100644 sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/CubeCollisionTest.cs create mode 100644 sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/EventKeyReceiverTest.cs delete mode 100644 sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/GlobalObservableTestScript.cs create mode 100644 src/R3.Stride/R3StrideCollectionExtension.cs create mode 100644 src/R3.Stride/R3StrideEventExtension.cs diff --git a/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox.sln b/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox.sln index e22feed8..150c433d 100644 --- a/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox.sln +++ b/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox.sln @@ -1,3 +1,4 @@ + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.8.34408.163 diff --git a/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/Assets/Cube.sdpromodel b/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/Assets/Cube.sdpromodel new file mode 100644 index 00000000..6721db48 --- /dev/null +++ b/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/Assets/Cube.sdpromodel @@ -0,0 +1,12 @@ +!ProceduralModelAsset +Id: b6a6bd83-1c1f-4d73-8cd8-bd8a66cbe3c5 +SerializedVersion: {Stride: 2.0.0.0} +Tags: [] +Type: !CubeProceduralModel + Size: {X: 1.0, Y: 1.0, Z: 1.0} + Scale: {X: 1.0, Y: 1.0, Z: 1.0} + UvScale: {X: 1.0, Y: 1.0} + LocalOffset: {X: 0.0, Y: 0.0, Z: 0.0} + NumberOfTextureCoordinates: 10 + MaterialInstance: + Material: 5b5781be-8137-4898-925e-5969eb8476a0:Sphere Material diff --git a/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/Assets/MainScene.sdscene b/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/Assets/MainScene.sdscene index 9e90a065..f2fd86cd 100644 --- a/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/Assets/MainScene.sdscene +++ b/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/Assets/MainScene.sdscene @@ -13,6 +13,7 @@ Hierarchy: - ref!! 56cd9852-d94c-4646-a513-85195ea3fe9b - ref!! b7806d41-f54f-4e99-9ec7-f9906f10b006 - ref!! 787562e5-0943-4493-85ce-6b0bd2abf47f + - ref!! 9c0e2928-6cdc-4033-b5cc-06d2dfdb291d Parts: - Entity: Id: 016064cc-d022-441a-9402-adc01926f5c6 @@ -53,13 +54,27 @@ Hierarchy: Id: 1a9d3c62-9ef5-4bde-b8e2-71ed721c0d9b Model: aff8da36-c1ef-43b3-8fc4-4212a0730901:Ground Materials: {} + 9cd507465eca3af487d41bf2b217d26d: !StaticColliderComponent + Id: 076e6b55-b3c6-4922-ae2d-298b28a31cf0 + CanSleep: false + Restitution: 0.0 + Friction: 0.5 + RollingFriction: 0.0 + CcdMotionThreshold: 0.0 + CcdSweptSphereRadius: 0.0 + IsTrigger: false + AlwaysUpdateNaviMeshCache: false + ColliderShapes: + 153eee591f3997346bb2929e45ea6830: !StaticPlaneColliderShapeDesc + Normal: {X: 0.0, Y: 1.0, Z: 0.0} + Offset: 0.0 - Entity: Id: 2b300ec9-5416-4771-ab62-636a1ce25643 Name: Camera Components: b8b773f875648c0554f1d1f77a3e6982: !TransformComponent Id: 6b2cd6ec-5617-4c0a-99f9-731f7a874820 - Position: {X: 2.6, Y: 0.6, Z: -1.0} + Position: {X: 5.0, Y: 0.6, Z: -2.0} Rotation: {X: 0.0, Y: 0.82903755, Z: 0.0, W: 0.5591929} Scale: {X: 1.0, Y: 1.0, Z: 1.0} Children: {} @@ -82,6 +97,26 @@ Hierarchy: Id: 0b8a72b5-76a3-447c-92fb-93e5302f01b9 Model: c4063b2b-caff-4757-9bcd-47c34e9452cc:Sphere Materials: {} + 9ecd94ecc0e9386fbd0c327a059558bc: !RigidbodyComponent + Id: fbf3f6ba-4737-4788-b5e9-f1b7506c5e79 + CanSleep: false + Restitution: 0.0 + Friction: 0.5 + RollingFriction: 0.0 + CcdMotionThreshold: 0.0 + CcdSweptSphereRadius: 0.0 + IsTrigger: false + IsKinematic: false + Mass: 1.0 + LinearDamping: 0.0 + AngularDamping: 0.0 + OverrideGravity: false + Gravity: {X: 0.0, Y: 0.0, Z: 0.0} + NodeName: null + ColliderShapes: + f07e140ad4c31956db525f8c23bc5f92: !SphereColliderShapeDesc + Is2D: false + LocalOffset: {X: 0.0, Y: 0.0, Z: 0.0} - Entity: Id: 5fe200ea-5597-4507-b15e-2a13ec790a29 Name: Skybox @@ -116,6 +151,44 @@ Hierarchy: Size: {X: 1.28, Y: 0.72, Z: 1.0} 87d8cfc0f2480a8c80ec5245c6710d2f: !R3.Stride.Sandbox.UIExtensionTest,R3.Stride.Sandbox Id: 65687212-b652-4f3f-a61a-f3320cc3e1e6 + - Entity: + Id: 9c0e2928-6cdc-4033-b5cc-06d2dfdb291d + Name: Cube + Components: + f3a9306cfab07ec9687f289ac04ebe44: !TransformComponent + Id: 6524d4a2-830b-4be5-96a4-e07c28761768 + Position: {X: 0.0, Y: 0.5, Z: 2.0} + Rotation: {X: 0.0, Y: 0.0, Z: 0.0, W: 1.0} + Scale: {X: 0.5, Y: 0.5, Z: 0.5} + Children: {} + 905fc01ae7567f30e72873cd6f9269ec: !ModelComponent + Id: b931a3a8-253e-4ad9-b4d9-1ef12891519d + Model: b6a6bd83-1c1f-4d73-8cd8-bd8a66cbe3c5:Cube + Materials: {} + 7e202eb6e07ed1ff4366b2c6eff48b73: !RigidbodyComponent + Id: 76143390-3505-458b-8165-a00cb34abfa7 + CanSleep: false + Restitution: 0.0 + Friction: 0.5 + RollingFriction: 0.0 + CcdMotionThreshold: 0.0 + CcdSweptSphereRadius: 0.0 + IsTrigger: true + IsKinematic: false + Mass: 0.0 + LinearDamping: 0.0 + AngularDamping: 0.0 + OverrideGravity: false + Gravity: {X: 0.0, Y: 0.0, Z: 0.0} + NodeName: null + ColliderShapes: + 59522ecd008781a40fe910ce5729b87f: !BoxColliderShapeDesc + Is2D: false + Size: {X: 0.5, Y: 0.5, Z: 0.5} + LocalOffset: {X: 0.0, Y: 0.0, Z: 0.0} + LocalRotation: {X: 0.0, Y: 0.0, Z: 0.0, W: 1.0} + f0e5f00a9db5203f5ec7e550b0e88491: !R3.Stride.Sandbox.CubeCollisionTest,R3.Stride.Sandbox + Id: 7ba17cb9-5eab-4c77-abd2-59f412561715 - Entity: Id: b7806d41-f54f-4e99-9ec7-f9906f10b006 Name: Entity @@ -130,3 +203,5 @@ Hierarchy: Id: ad787971-6f5a-440e-91f5-f247ce01d6b4 6f4023fe5b305442911adadcff8c385d: !R3.Stride.Sandbox.ObservableTestScript,R3.Stride.Sandbox Id: 1d8eed70-d32b-4820-a015-98f6b0634f8e + d6c08302e8bc4cff4f75a1bef919f3ea: !R3.Stride.Sandbox.EventKeyReceiverTest,R3.Stride.Sandbox + Id: 340c3d80-da0d-4b6f-b7b7-4071e161d717 diff --git a/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/CubeCollisionTest.cs b/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/CubeCollisionTest.cs new file mode 100644 index 00000000..0c2fbd96 --- /dev/null +++ b/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/CubeCollisionTest.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Stride.Core.Mathematics; +using Stride.Input; +using Stride.Engine; +using Stride.Physics; +using Silk.NET.OpenGL; + +namespace R3.Stride.Sandbox +{ + public class CubeCollisionTest : StartupScript + { + // Declared public member fields and properties will show in the game studio + + public override void Start() + { + // Initialization of the script. + var component = Entity.Get(); + component.AngularVelocity = Vector3.UnitZ; + component.Collisions.CollectionChangedAsObservable() + .Subscribe(x => + { + var (sender, arg) = x; + if(arg.Item is Collision collision) + { + Log.Info($"{sender}: {collision.ColliderA.Entity.Name}, {collision.ColliderB.Entity.Name}, {arg.Action}"); + } + else + { + Log.Info($"{sender}: {arg.Item}, {arg.Key} {arg.Index}, {arg.OldItem}, {arg.Action}"); + } + component.AngularVelocity = -component.AngularVelocity; + //component.UpdatePhysicsTransformation(); + }); + Observable.EveryUpdate() + .Subscribe(Entity, (_, ent) => + { + var velocity = component.LinearVelocity; + velocity.Z = MathF.Cos((float)Game.UpdateTime.Total.TotalSeconds / 2); + component.LinearVelocity = velocity; + //component.UpdatePhysicsTransformation(); + DebugText.Print($"{ent.Transform.Position}", new Int2(10, 300)); + }); + + } + } +} diff --git a/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/EventKeyReceiverTest.cs b/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/EventKeyReceiverTest.cs new file mode 100644 index 00000000..7668ad45 --- /dev/null +++ b/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/EventKeyReceiverTest.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Stride.Engine; +using Stride.Engine.Events; + +namespace R3.Stride.Sandbox; +public class EventKeyReceiverTest : StartupScript +{ + EventKey EventKey1 = new EventKey("EventKeyTest", "Event1"); + EventKey EventKey2 = new EventKey("EventKeyTest", "Event2"); + public override void Start() + { + EventKey1.AsObservable() + .Subscribe(x => + { + Log.Info($"event1 published: {x}"); + }); + EventKey2.AsObservable() + .Subscribe(_ => + { + Log.Info("event2 published"); + }); + Observable.EveryUpdate() + .ThrottleLastFrame(60) + .Select((_, i) => i) + .Subscribe(x => + { + EventKey1.Broadcast(x); + EventKey2.Broadcast(); + }); + } +} diff --git a/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/GlobalObservableTestScript.cs b/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/GlobalObservableTestScript.cs deleted file mode 100644 index 20c074d8..00000000 --- a/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/GlobalObservableTestScript.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Stride.Core.Mathematics; -using Stride.Input; -using Stride.Engine; - -namespace R3.Stride.Sandbox -{ - public class GlobalObservableTestScript : SyncScript - { - // Declared public member fields and properties will show in the game studio - - public override void Start() - { - Observable.EveryUpdate() - .ThrottleLastFrame(120) - .Subscribe(_ => - { - Log.Info($"global observable test: {Game.UpdateTime.FrameCount}, {Game.UpdateTime.Total}"); - }); - } - - public override void Update() - { - } - } -} diff --git a/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/ObservableTestScript.cs b/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/ObservableTestScript.cs index ef78bfa0..a77a1ad6 100644 --- a/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/ObservableTestScript.cs +++ b/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/ObservableTestScript.cs @@ -14,7 +14,8 @@ public class ObservableTestScript : SyncScript // Declared public member fields and properties will show in the game studio public override void Start() { - Observable.Interval(TimeSpan.FromSeconds(1)) + var customFrameProvider = StrideFrameProvider.Create(Game, Entity); + Observable.Interval(TimeSpan.FromSeconds(5)) .Subscribe(_ => { Log.Info($"interval: {Game.UpdateTime.Total}"); @@ -29,7 +30,13 @@ public override void Start() .ThrottleLastFrame(60) .Subscribe(x => { - throw new Exception("test exception"); + //throw new Exception("test exception"); + }); + Observable.EveryUpdate(customFrameProvider) + .ThrottleLastFrame(60, customFrameProvider) + .Subscribe(x => + { + Log.Info($"custom frame provider"); }); } diff --git a/src/R3.Stride/R3StrideCollectionExtension.cs b/src/R3.Stride/R3StrideCollectionExtension.cs new file mode 100644 index 00000000..05c93026 --- /dev/null +++ b/src/R3.Stride/R3StrideCollectionExtension.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Stride.Core.Collections; +using System.Threading; + +namespace R3.Stride; +public static class R3StrideCollectionExtension +{ + public static Observable<(object? sender, TrackingCollectionChangedEventArgs arg)> CollectionChangedAsObservable(this ITrackingCollectionChanged hashset, CancellationToken token = default) + { + return Observable.FromEventHandler(h => hashset.CollectionChanged += h, h => hashset.CollectionChanged -= h, token); + } + public static Observable<(object? sender, FastTrackingCollectionChangedEventArgs arg)> CollectionChangedAsObservable(this FastTrackingCollection collection, CancellationToken token = default) + { + return Observable.FromEvent.FastEventHandler, (object?, FastTrackingCollectionChangedEventArgs)>( + h => + { + void Handler(object? sender, ref FastTrackingCollectionChangedEventArgs arg) + { + h((sender, arg)); + } + return new FastTrackingCollection.FastEventHandler(Handler); + }, + h => collection.CollectionChanged += h, + h => collection.CollectionChanged -= h, + token); + } +} diff --git a/src/R3.Stride/R3StrideEventExtension.cs b/src/R3.Stride/R3StrideEventExtension.cs new file mode 100644 index 00000000..7f791279 --- /dev/null +++ b/src/R3.Stride/R3StrideEventExtension.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Stride.Engine; +using Stride.Engine.Events; + +namespace R3; +public static class R3StrideEventExtension +{ + public static Observable AsObservable(this EventKey eventKey, CancellationToken token = default) + { + return Observable.Create, CancellationToken)>((eventKey, token), static (observer, state) => + { + if(R3.Stride.StrideInitializer.DefaultFrameProvider == null) + { + throw new NullReferenceException("initialize default frameprovider first"); + } + var (evk, token) = state; + var receiver = new EventReceiver(evk); + var runnerItem = new EventReceiverRunnerItem(observer, receiver, R3.Stride.StrideInitializer.DefaultFrameProvider, token); + Stride.StrideInitializer.DefaultFrameProvider.Register(runnerItem); + return runnerItem; + }); + } + public static Observable AsObservable(this EventKey eventKey, CancellationToken token = default) + { + return Observable.Create((eventKey, token), static (observer, state) => + { + if (R3.Stride.StrideInitializer.DefaultFrameProvider == null) + { + throw new NullReferenceException("initialize default frameprovider first"); + } + var (evk, token) = state; + var receiver = new EventReceiver(evk); + var runnerItem = new EventReceiverRunnerItem(observer, receiver, R3.Stride.StrideInitializer.DefaultFrameProvider, token); + Stride.StrideInitializer.DefaultFrameProvider.Register(runnerItem); + return runnerItem; + }); + } + sealed class EventReceiverRunnerItem : IFrameRunnerWorkItem, IDisposable + { + Observer observer; + CancellationToken token; + IDisposable cancellationTokenSubscription; + EventReceiver _receiver; + public EventReceiverRunnerItem(Observer observer, EventReceiver receiver, FrameProvider frameProvider, CancellationToken token = default) + { + this.observer = observer; + this.token = token; + this._receiver = receiver; + if (token.CanBeCanceled) + { + this.cancellationTokenSubscription = token.UnsafeRegister(static (state) => + { + var item = state as EventReceiverRunnerItem; + if (item != null) + { + item.observer.OnCompleted(); + item.Dispose(); + } + }, this); + } + else + { + this.cancellationTokenSubscription = Disposable.Empty; + } + } + bool isDisposed = false; + public bool MoveNext(long frameCount) + { + if (token.IsCancellationRequested || isDisposed) + { + return false; + } + if (observer.IsDisposed) + { + Dispose(); + return false; + } + if (_receiver.TryReceive()) + { + observer.OnNext(Unit.Default); + } + return true; + } + public void Dispose() + { + if (!isDisposed) + { + isDisposed = true; + cancellationTokenSubscription.Dispose(); + } + } + } + // I did trying to merge EventReceiverRunnerItem and EventReceiverRunnerItem, but could not. + sealed class EventReceiverRunnerItem : IFrameRunnerWorkItem, IDisposable + { + Observer observer; + CancellationToken token; + IDisposable cancellationTokenSubscription; + EventReceiver _receiver; + public EventReceiverRunnerItem(Observer observer, EventReceiver receiver, FrameProvider frameProvider, CancellationToken token = default) + { + this.observer = observer; + this.token = token; + this._receiver = receiver; + if(token.CanBeCanceled) + { + this.cancellationTokenSubscription = token.UnsafeRegister(static (state) => + { + var item = state as EventReceiverRunnerItem; + if(item != null) + { + item.observer.OnCompleted(); + item.Dispose(); + } + }, this); + } + else + { + this.cancellationTokenSubscription = Disposable.Empty; + } + } + bool isDisposed = false; + public bool MoveNext(long frameCount) + { + if(token.IsCancellationRequested || isDisposed) + { + return false; + } + if(observer.IsDisposed) + { + Dispose(); + return false; + } + if(_receiver.TryReceive(out var item)) + { + observer.OnNext(item); + } + return true; + } + public void Dispose() + { + if(!isDisposed) + { + isDisposed = true; + cancellationTokenSubscription.Dispose(); + } + } + } +} diff --git a/src/R3.Stride/StrideFrameProvider.cs b/src/R3.Stride/StrideFrameProvider.cs index bd506fd9..408f9b77 100644 --- a/src/R3.Stride/StrideFrameProvider.cs +++ b/src/R3.Stride/StrideFrameProvider.cs @@ -1,6 +1,7 @@ -using System; +using System; using System.Runtime.CompilerServices; using R3.Collections; +using Stride.Engine; using Stride.Games; namespace R3; @@ -9,6 +10,28 @@ public sealed class StrideFrameProvider : FrameProvider { FreeListCore list; readonly object gate = new object(); + /// + /// create R3 FrameProvider for Stride + /// + /// Game object, UpdateTime will be used + /// FrameProvider's dispatcher component will be added + /// + public static StrideFrameProvider Create(IGame game, Entity entity) + { + var frameProvider = new StrideFrameProvider(game); + frameProvider.Delta = new StrongBox(); + var dispatcher = new FrameDispatcher(frameProvider); + entity.Add(dispatcher); + return frameProvider; + } + internal sealed class FrameDispatcher(StrideFrameProvider frameProvider) : SyncScript + { + public override void Update() + { + frameProvider.Delta.Value = Game.UpdateTime.Elapsed.TotalSeconds; + frameProvider.Run(Game.UpdateTime.Total.TotalSeconds); + } + } internal StrongBox Delta = default!; // set from Node before running process. From 17c998ca4ff57bf5b27b8c7be1e2fc515c73a615 Mon Sep 17 00:00:00 2001 From: itn3000 Date: Fri, 2 Feb 2024 17:27:02 +0900 Subject: [PATCH 2/4] omit Create for keep it simple --- .../R3.Stride.Sandbox/ObservableTestScript.cs | 7 ------ src/R3.Stride/StrideFrameProvider.cs | 23 ------------------- 2 files changed, 30 deletions(-) diff --git a/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/ObservableTestScript.cs b/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/ObservableTestScript.cs index a77a1ad6..08548d59 100644 --- a/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/ObservableTestScript.cs +++ b/sandbox/R3.Stride.Sandbox/R3.Stride.Sandbox/ObservableTestScript.cs @@ -14,7 +14,6 @@ public class ObservableTestScript : SyncScript // Declared public member fields and properties will show in the game studio public override void Start() { - var customFrameProvider = StrideFrameProvider.Create(Game, Entity); Observable.Interval(TimeSpan.FromSeconds(5)) .Subscribe(_ => { @@ -32,12 +31,6 @@ public override void Start() { //throw new Exception("test exception"); }); - Observable.EveryUpdate(customFrameProvider) - .ThrottleLastFrame(60, customFrameProvider) - .Subscribe(x => - { - Log.Info($"custom frame provider"); - }); } public override void Update() diff --git a/src/R3.Stride/StrideFrameProvider.cs b/src/R3.Stride/StrideFrameProvider.cs index 408f9b77..d486ec13 100644 --- a/src/R3.Stride/StrideFrameProvider.cs +++ b/src/R3.Stride/StrideFrameProvider.cs @@ -10,29 +10,6 @@ public sealed class StrideFrameProvider : FrameProvider { FreeListCore list; readonly object gate = new object(); - /// - /// create R3 FrameProvider for Stride - /// - /// Game object, UpdateTime will be used - /// FrameProvider's dispatcher component will be added - /// - public static StrideFrameProvider Create(IGame game, Entity entity) - { - var frameProvider = new StrideFrameProvider(game); - frameProvider.Delta = new StrongBox(); - var dispatcher = new FrameDispatcher(frameProvider); - entity.Add(dispatcher); - return frameProvider; - } - internal sealed class FrameDispatcher(StrideFrameProvider frameProvider) : SyncScript - { - public override void Update() - { - frameProvider.Delta.Value = Game.UpdateTime.Elapsed.TotalSeconds; - frameProvider.Run(Game.UpdateTime.Total.TotalSeconds); - } - } - internal StrongBox Delta = default!; // set from Node before running process. internal StrideFrameProvider(IGame game) From 29486c5fa87e197a13c6d100884e4ec88d79a4e7 Mon Sep 17 00:00:00 2001 From: itn3000 Date: Fri, 2 Feb 2024 17:28:23 +0900 Subject: [PATCH 3/4] remove unused using --- src/R3.Stride/StrideFrameProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/R3.Stride/StrideFrameProvider.cs b/src/R3.Stride/StrideFrameProvider.cs index d486ec13..c835ee98 100644 --- a/src/R3.Stride/StrideFrameProvider.cs +++ b/src/R3.Stride/StrideFrameProvider.cs @@ -1,7 +1,6 @@ using System; using System.Runtime.CompilerServices; using R3.Collections; -using Stride.Engine; using Stride.Games; namespace R3; @@ -10,6 +9,7 @@ public sealed class StrideFrameProvider : FrameProvider { FreeListCore list; readonly object gate = new object(); + internal StrongBox Delta = default!; // set from Node before running process. internal StrideFrameProvider(IGame game) From 4708a9344de175b27cd20d64c8e65631a8cc6c52 Mon Sep 17 00:00:00 2001 From: Yusuke Ito Date: Sat, 3 Feb 2024 07:45:53 +0900 Subject: [PATCH 4/4] fix namespace in R3StrideCollectionExtension.cs --- src/R3.Stride/R3StrideCollectionExtension.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/R3.Stride/R3StrideCollectionExtension.cs b/src/R3.Stride/R3StrideCollectionExtension.cs index 05c93026..c7eab58b 100644 --- a/src/R3.Stride/R3StrideCollectionExtension.cs +++ b/src/R3.Stride/R3StrideCollectionExtension.cs @@ -6,7 +6,7 @@ using Stride.Core.Collections; using System.Threading; -namespace R3.Stride; +namespace R3; public static class R3StrideCollectionExtension { public static Observable<(object? sender, TrackingCollectionChangedEventArgs arg)> CollectionChangedAsObservable(this ITrackingCollectionChanged hashset, CancellationToken token = default)