我目前正在调查.NET中的Reactivex,以用于模拟重型视频游戏。我的第一个目标是创建基本事件/渲染循环。我有以下代码几乎完全可以完成我想要的。
var frames = Observable
.Interval(TimeSpan.Zero, new EventLoopScheduler())
.Timestamp()
.Select(timestamp => new Frame
{
Count = timestamp.Value,
Timestamp = timestamp.Timestamp.ToUnixTimeMilliseconds()
});
frames.Subscribe(frame =>
{
Console.WriteLine($"GameObject 1 - frame.Count: {frame.Count} frame.Timestamp: {frame.Timestamp}");
});
frames.Subscribe(frame =>
{
Console.WriteLine($"GameObject 2 - frame.Count: {frame.Count} frame.Timestamp: {frame.Timestamp}");
});
frames.ToTask().Wait();
这将在主线程上尽可能快地发射框架事件。完美的!但是,我注意到两个订户之间的时间戳可能在同一框架中略有关闭。例如,
GameObject 1 - frame.Count: 772 frame.Timestamp: 1519215592309
GameObject 2 - frame.Count: 772 frame.Timestamp: 1519215592310
对于同一框架,时间戳是一毫秒。为此,这两个游戏对象/订户都需要获得完全相同的时间戳,否则模拟可能无法正常运行。
我猜测,在流中发出的每个事件的每个订阅者都会对时间戳运算符进行一次评估。有没有办法获取它,因此每次发出的所有订户对其进行了一次评估?谢谢!
whelp,我应该再给它几分钟的文档阅读。
解决方案是使我的框架事件流可连接。我要做的就是在附加订户之前发布框架事件流。然后在事件循环启动之前立即致电连接。完美的!该死的RX很棒。
var frames = Observable
.Interval(TimeSpan.Zero, new EventLoopScheduler())
.Timestamp()
.Select(timestamp => new Frame
{
Count = timestamp.Value,
Timestamp = timestamp.Timestamp.ToUnixTimeMilliseconds()
})
.Publish();
frames.Subscribe(frame =>
{
Console.WriteLine($"GameObject 1 - frame.Count: {frame.Count} frame.Timestamp: {frame.Timestamp}");
});
frames.Subscribe(frame =>
{
Console.WriteLine($"GameObject 2 - frame.Count: {frame.Count} frame.Timestamp: {frame.Timestamp}");
});
frames.Connect();
frames.ToTask().Wait();