Skip to content

Commit 1559d35

Browse files
committed
Merge branch 'streamline-updates'
2 parents 07f504e + 004fd61 commit 1559d35

File tree

11 files changed

+122
-62
lines changed

11 files changed

+122
-62
lines changed

appveyor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version: 3.8.{build}
1+
version: 3.9.{build}
22
branches:
33
only:
44
- master

src/EcsRx.Infrastructure/Dependencies/BindingBuilder.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,20 @@ public BindingBuilder<TFrom> ToMethod<TTo>(Func<IDependencyContainer, TTo> metho
6868
_configuration.ToMethod = container => method(container);
6969
return this;
7070
}
71+
72+
public BindingBuilder<TFrom> ToBoundType<TTo>() where TTo : TFrom
73+
{ return ToBoundType(typeof(TTo)); }
74+
75+
public BindingBuilder<TFrom> ToBoundType(Type boundType)
76+
{
77+
if(_configuration.ToMethod != null)
78+
{ throw new BindingException("Cannot use bound type when a method has been provided already"); }
79+
80+
if(_configuration.ToInstance != null)
81+
{ throw new BindingException("Cannot use bound type when an instance has been provided already"); }
82+
83+
_configuration.ToMethod = container => container.Resolve(boundType);
84+
return this;
85+
}
7186
}
7287
}

src/EcsRx.Infrastructure/Modules/FrameworkModule.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,12 @@ public void Setup(IDependencyContainer container)
2828
container.Bind<IEntityCollectionFactory, DefaultEntityCollectionFactory>();
2929
container.Bind<IObservableGroupFactory, DefaultObservableObservableGroupFactory>();
3030
container.Bind<IEntityCollectionManager, EntityCollectionManager>();
31-
container.Bind<IObservableGroupManager>(x => x.ToMethod(y => y.Resolve<IEntityCollectionManager>()));
31+
container.Bind<IObservableGroupManager>(x => x.ToBoundType<IEntityCollectionManager>());
3232
container.Bind<IConventionalSystemHandler, ManualSystemHandler>();
3333
container.Bind<IConventionalSystemHandler, BasicSystemHandler>();
3434
container.Bind<ISystemExecutor, SystemExecutor>();
35-
container.Bind<IObservableScheduler, DefaultObservableScheduler>();
35+
container.Bind<IUpdateScheduler, DefaultUpdateScheduler>();
36+
container.Bind<ITimeTracker>(x => x.ToBoundType(typeof(IUpdateScheduler)));
3637
container.Bind<IComponentTypeAssigner, DefaultComponentTypeAssigner>();
3738
container.Bind<IComponentTypeLookup>(new BindingConfiguration{ToMethod = CreateDefaultTypeLookup});
3839
container.Bind<IComponentDatabase, ComponentDatabase>();

src/EcsRx.Tests/Framework/Handlers/BasicSystemHandlerTests.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public void should_correctly_handle_systems()
2121
{
2222
var mockCollectionManager = Substitute.For<IEntityCollectionManager>();
2323
var threadHandler = Substitute.For<IThreadHandler>();
24-
var observableScheduler = Substitute.For<IObservableScheduler>();
24+
var observableScheduler = Substitute.For<IUpdateScheduler>();
2525
var reactToEntitySystemHandler = new BasicSystemHandler(mockCollectionManager, threadHandler, observableScheduler);
2626

2727
var fakeMatchingSystem = Substitute.For<IBasicSystem>();
@@ -49,8 +49,8 @@ public void should_execute_system_without_predicate()
4949

5050
var mockCollectionManager = Substitute.For<IEntityCollectionManager>();
5151
var threadHandler = Substitute.For<IThreadHandler>();
52-
var observableScheduler = Substitute.For<IObservableScheduler>();
53-
var observableSubject = new Subject<TimeSpan>();
52+
var observableScheduler = Substitute.For<IUpdateScheduler>();
53+
var observableSubject = new Subject<ElapsedTime>();
5454
observableScheduler.OnUpdate.Returns(observableSubject);
5555

5656
var fakeGroup = new Group();
@@ -62,7 +62,7 @@ public void should_execute_system_without_predicate()
6262
var systemHandler = new BasicSystemHandler(mockCollectionManager, threadHandler, observableScheduler);
6363
systemHandler.SetupSystem(mockSystem);
6464

65-
observableSubject.OnNext(TimeSpan.Zero);
65+
observableSubject.OnNext(new ElapsedTime());
6666

6767
mockSystem.ReceivedWithAnyArgs(2).Process(Arg.Any<IEntity>());
6868
Assert.Equal(1, systemHandler._systemSubscriptions.Count);
@@ -90,8 +90,8 @@ public void should_only_execute_system_when_predicate_met()
9090

9191
var mockCollectionManager = Substitute.For<IEntityCollectionManager>();
9292
var threadHandler = Substitute.For<IThreadHandler>();
93-
var observableScheduler = Substitute.For<IObservableScheduler>();
94-
var observableSubject = new Subject<TimeSpan>();
93+
var observableScheduler = Substitute.For<IUpdateScheduler>();
94+
var observableSubject = new Subject<ElapsedTime>();
9595
observableScheduler.OnUpdate.Returns(observableSubject);
9696

9797
var fakeGroup = new GroupWithPredicate(x => x.Id == idToMatch);
@@ -103,7 +103,7 @@ public void should_only_execute_system_when_predicate_met()
103103
var systemHandler = new BasicSystemHandler(mockCollectionManager, threadHandler, observableScheduler);
104104
systemHandler.SetupSystem(mockSystem);
105105

106-
observableSubject.OnNext(TimeSpan.Zero);
106+
observableSubject.OnNext(new ElapsedTime());
107107

108108
mockSystem.ReceivedWithAnyArgs(1).Process(Arg.Is(entityToMatch));
109109
Assert.Equal(1, systemHandler._systemSubscriptions.Count);
@@ -115,7 +115,7 @@ public void should_destroy_and_dispose_system()
115115
{
116116
var mockCollectionManager = Substitute.For<IEntityCollectionManager>();
117117
var threadHandler = Substitute.For<IThreadHandler>();
118-
var observableScheduler = Substitute.For<IObservableScheduler>();
118+
var observableScheduler = Substitute.For<IUpdateScheduler>();
119119
var mockSystem = Substitute.For<IBasicSystem>();
120120
var mockDisposable = Substitute.For<IDisposable>();
121121

src/EcsRx/Executor/Handlers/BasicSystemHandler.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ namespace EcsRx.Executor.Handlers
1717
public class BasicSystemHandler : IConventionalSystemHandler
1818
{
1919
public readonly IEntityCollectionManager _entityCollectionManager;
20-
public readonly IObservableScheduler _observableScheduler;
20+
public readonly IUpdateScheduler UpdateScheduler;
2121
public readonly IDictionary<ISystem, IDisposable> _systemSubscriptions;
2222
public readonly IThreadHandler _threadHandler;
2323

24-
public BasicSystemHandler(IEntityCollectionManager entityCollectionManager, IThreadHandler threadHandler, IObservableScheduler observableScheduler)
24+
public BasicSystemHandler(IEntityCollectionManager entityCollectionManager, IThreadHandler threadHandler, IUpdateScheduler updateScheduler)
2525
{
2626
_entityCollectionManager = entityCollectionManager;
2727
_threadHandler = threadHandler;
28-
_observableScheduler = observableScheduler;
28+
UpdateScheduler = updateScheduler;
2929
_systemSubscriptions = new Dictionary<ISystem, IDisposable>();
3030
}
3131

@@ -43,13 +43,13 @@ public void SetupSystem(ISystem system)
4343

4444
if (!hasEntityPredicate)
4545
{
46-
subscription = _observableScheduler.OnUpdate
46+
subscription = UpdateScheduler.OnUpdate
4747
.Subscribe(x => ExecuteForGroup(observableGroup, castSystem, runParallel));
4848
}
4949
else
5050
{
5151
var groupPredicate = system.Group as IHasPredicate;
52-
subscription = _observableScheduler.OnUpdate
52+
subscription = UpdateScheduler.OnUpdate
5353
.Subscribe(x => ExecuteForGroup(observableGroup
5454
.Where(groupPredicate.CanProcessEntity).ToList(), castSystem, runParallel));
5555
}

src/EcsRx/Scheduling/DefaultObservableScheduler.cs

Lines changed: 0 additions & 37 deletions
This file was deleted.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using System;
2+
using System.Timers;
3+
using EcsRx.Extensions;
4+
using EcsRx.MicroRx.Subjects;
5+
6+
namespace EcsRx.Scheduling
7+
{
8+
/// <summary>
9+
/// This default implementation only provides millisecond level accuracy
10+
/// however in most cases it will instead use a platform specific implementation
11+
/// which will be as accurate as the underlying platform provides
12+
/// </summary>
13+
public class DefaultUpdateScheduler : IUpdateScheduler
14+
{
15+
private readonly Timer _timer;
16+
private DateTime _previousDateTime;
17+
private readonly Subject<ElapsedTime> _onPreUpdate = new Subject<ElapsedTime>();
18+
private readonly Subject<ElapsedTime> _onUpdate = new Subject<ElapsedTime>();
19+
private readonly Subject<ElapsedTime> _onPostUpdate = new Subject<ElapsedTime>();
20+
21+
public ElapsedTime ElapsedTime { get; private set; }
22+
public IObservable<ElapsedTime> OnUpdate => _onUpdate;
23+
public IObservable<ElapsedTime> OnPreUpdate => _onPreUpdate;
24+
public IObservable<ElapsedTime> OnPostUpdate => _onPostUpdate;
25+
26+
public DefaultUpdateScheduler(int desiredFps = 60)
27+
{
28+
_timer = new Timer { Interval = 1000f / desiredFps };
29+
_timer.Elapsed += UpdateTick;
30+
31+
_previousDateTime = DateTime.Now;
32+
_timer.Start();
33+
}
34+
35+
private void UpdateTick(object sender, ElapsedEventArgs e)
36+
{
37+
var deltaTime = e.SignalTime - _previousDateTime;
38+
var totalTime = ElapsedTime.TotalTime + deltaTime;
39+
ElapsedTime = new ElapsedTime(deltaTime, totalTime);
40+
_onPreUpdate.OnNext(ElapsedTime);
41+
_onUpdate.OnNext(ElapsedTime);
42+
_onPostUpdate.OnNext(ElapsedTime);
43+
_previousDateTime = e.SignalTime;
44+
}
45+
46+
public void Dispose()
47+
{
48+
_timer.Stop();
49+
_timer.Dispose();
50+
51+
_onUpdate.Dispose();
52+
_onPreUpdate.Dispose();
53+
_onPostUpdate.Dispose();
54+
}
55+
}
56+
}

src/EcsRx/Scheduling/ElapsedTime.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
3+
namespace EcsRx.Scheduling
4+
{
5+
public struct ElapsedTime
6+
{
7+
public TimeSpan DeltaTime;
8+
public TimeSpan TotalTime;
9+
10+
public ElapsedTime(TimeSpan deltaTime, TimeSpan totalTime)
11+
{
12+
DeltaTime = deltaTime;
13+
TotalTime = totalTime;
14+
}
15+
}
16+
}

src/EcsRx/Scheduling/IObservableScheduler.cs

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/EcsRx/Scheduling/ITimeTracker.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace EcsRx.Scheduling
2+
{
3+
public interface ITimeTracker
4+
{
5+
ElapsedTime ElapsedTime { get; }
6+
}
7+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System;
2+
3+
namespace EcsRx.Scheduling
4+
{
5+
public interface IUpdateScheduler : ITimeTracker, IDisposable
6+
{
7+
IObservable<ElapsedTime> OnPreUpdate { get; }
8+
IObservable<ElapsedTime> OnUpdate { get; }
9+
IObservable<ElapsedTime> OnPostUpdate { get; }
10+
}
11+
}

0 commit comments

Comments
 (0)