ReactiveX 视频游戏渲染循环计时
ReactiveX video game render loop timing
我目前正在研究 .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
同一帧的时间戳相差一毫秒。为此,这两个 gameobjects/subscribers 需要在每个帧中获得完全相同的时间戳,否则模拟可能无法 运行 正确。
我猜 Timestamp 运算符正在为流中发出的每个事件的每个订阅者评估一次。有没有办法让它对每个发出的事件的所有订阅者进行一次评估?谢谢!
Whelp,我应该再花几分钟阅读文档。
解决方案是使我的框架事件流可连接。我所要做的就是在订阅者附加到它之前发布框架事件流。然后在事件循环开始之前立即调用 Connect。完美的!该死的 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();
我目前正在研究 .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
同一帧的时间戳相差一毫秒。为此,这两个 gameobjects/subscribers 需要在每个帧中获得完全相同的时间戳,否则模拟可能无法 运行 正确。
我猜 Timestamp 运算符正在为流中发出的每个事件的每个订阅者评估一次。有没有办法让它对每个发出的事件的所有订阅者进行一次评估?谢谢!
Whelp,我应该再花几分钟阅读文档。
解决方案是使我的框架事件流可连接。我所要做的就是在订阅者附加到它之前发布框架事件流。然后在事件循环开始之前立即调用 Connect。完美的!该死的 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();