sdg*_*sdh 5 c# xna system.reactive monogame rx.net
我有一个游戏(基于MonoGame/XNA)和更新方法,如下所示:
public void Update(GameTime gameTime)
{
component.Update(gameTime);
}
Run Code Online (Sandbox Code Playgroud)
我想将其转换为Reactive模式.我目前的解决方案是:
public void Initialize()
{
updateSubject = new Subject<GameTime>();
component = new Component();
updateSubject.Subscribe((gameTime) => component.Update(gameTime));
}
public void Update(GameTime gameTime)
{
updateSubject.OnNext(gameTime);
}
Run Code Online (Sandbox Code Playgroud)
我是Rx的新手,所以我仍然在学习最好的做事方式.我读过Subject应该避免使用,Observable.Create应该使用它.
是Subject合适的吗?
我怎么能Observable.Create在这种情况下使用?
您在这里遇到的关键问题是您需要一个可观察源.通常,您可以从事件,委托,任务,许多可观察扩展(如.Interval或.Generate)和主题的各种来源创建可观察对象.
在您的情况下,您必须拥有一个源代码,您可以拥有代码,在您的observable外部,将值推送到.在这种情况下,主题完全没问题,但您也可以使用代理.
如果您使用主题,那么您的代码就可以了.唯一的缺点是你可以打电话updateSubject.OnCompleted并完成观察.
如果您想使用委托,那么您的代码可能如下所示:
private Action<GameTime> updateGameTime = null;
public void Initialize()
{
component = new Component();
Observable
.FromEvent<GameTime>(a => updateGameTime += a, a => updateGameTime -= a)
.Subscribe((gameTime) => component.Update(gameTime));
}
public void Update(GameTime gameTime)
{
updateGameTime(gameTime);
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式你唯一可以做的updateGameTime就是传递一个新的GameTime- 你不能"意外地"结束序列.
现在使用主题的整个问题Observable.Create是国家之一.在您的代码中,您需要状态,因此主题是可以的.一般而言,尽管如此,建议封装状态 - 这就是Observable.Create为您做的事情.
举个例子:
var i = -1;
var query =
Observable
.Range(0, 10).Select(x =>
{
i = -i * 2;
return x * i;
});
Run Code Online (Sandbox Code Playgroud)
如果我订阅这个可观察的两次,我得到这两个序列:
(1)
0 -4 16 -48 128 -320 768 -1792 4096 -9216
(2)
0 -4096 16384 -49152 131072 -327680 786432 -1835008 4194304 -9437184
序列改变因为我使用了状态(即var i = -1;).
如果我编写代码,Observable.Create我可以避免这种状态:
var query =
Observable
.Create<int>(o =>
{
var i = -1;
return
Observable
.Range(0, 10).Select(x =>
{
i = -i * 2;
return x * i;
})
.Subscribe(o);
});
Run Code Online (Sandbox Code Playgroud)
它仍然是相同的查询,但状态是封装的,所以如果我现在订阅两次,我得到:
(1)
0 -4 16 -48 128 -320 768 -1792 4096 -9216
(2)
0 -4 16 -48 128 -320 768 -1792 4096 -9216
有时编写复杂的查询时,您可能会认为使用主题会使其变得更容易,而且通常情况下,这就是错误发生的地方.在这种情况下,在使用主题之前,您应该总是尝试找到纯运算符方法.如果你不能然后封装主题的使用Observable.Create.
像你这样的时候使用主题很好,因为你需要那个外部状态.
| 归档时间: |
|
| 查看次数: |
469 次 |
| 最近记录: |