c++完全通用的事件调度程序
我再次尝试更好地解释我将取得的成就。
我想做这样的事情(受到Unity的Unityevent的启发):
在某些类中声明的公共“变量”:
GameEvent<> OnEnemySpawn = GameEvent<>();
GameEvent<string> OnPlayerSpawn = GameEvent<string>();
GameEvent<string, float> OnEnemyDie = GameEvent<string, float>();
推荐其他一些类订阅其方法的转介:
...
enemySpawner.OnEnemySpawn.Subscribe(IncreaseEnemyAliveCountByOne);
...
playerSpawner.OnPlayerSpawn.Subscribe(NewPlayerSpawned);
...
enemy.OnEnemyDie.Subscribe(IncreasePlayerScore);
...
// Subscribed methods declaration
void IncreaseEnemyAliceCountByOne() { ... }
void NewPlayerSpawned(string playerName) { ... }
void IncreasePlayerScore(string playerName, float scoreToAdd) { ... }
然后GameEvent类可以通知事件:
...
OnEnemySpawn.Notify();
...
OnPlayerSpawn.Notify(newPlayer.PlayerName);
...
OnEnemyDie.Notify(playerKiller.PlayerName, scoreOnKill);
...
实际上,我实现了创建此类的声明和订阅部分:
templace<class ... T>
class GameEvent
{
private:
std::vector<std::function<void(T...)>> _subscribers;
public:
void Subscribe(std::function<void(T...)> newSubscriber)
{
_subscribers.push_back(newSubscriber);
}
}
使我疯狂的事情是如何实现通知方法。我应该如何知道我收到了多少个参数以及他们
void Notify(T...)
{
for (std::function<void(T...)> subscriber : _subscribers)
{
}
}
希望现在有哪些类型,这是一个有效的问题,因为我在此背后失去了理智
I try again to explain better again what I would achieve.
I would like make a thing like this (inspired to Unity's UnityEvent):
Public "variables" declared in some classes:
GameEvent<> OnEnemySpawn = GameEvent<>();
GameEvent<string> OnPlayerSpawn = GameEvent<string>();
GameEvent<string, float> OnEnemyDie = GameEvent<string, float>();
Referral where some other classes subscribe their methods:
...
enemySpawner.OnEnemySpawn.Subscribe(IncreaseEnemyAliveCountByOne);
...
playerSpawner.OnPlayerSpawn.Subscribe(NewPlayerSpawned);
...
enemy.OnEnemyDie.Subscribe(IncreasePlayerScore);
...
// Subscribed methods declaration
void IncreaseEnemyAliceCountByOne() { ... }
void NewPlayerSpawned(string playerName) { ... }
void IncreasePlayerScore(string playerName, float scoreToAdd) { ... }
And then GameEvent class would be able to notify the event happens:
...
OnEnemySpawn.Notify();
...
OnPlayerSpawn.Notify(newPlayer.PlayerName);
...
OnEnemyDie.Notify(playerKiller.PlayerName, scoreOnKill);
...
Actually, I achieved the declaration and subscription part creating this class:
templace<class ... T>
class GameEvent
{
private:
std::vector<std::function<void(T...)>> _subscribers;
public:
void Subscribe(std::function<void(T...)> newSubscriber)
{
_subscribers.push_back(newSubscriber);
}
}
The thing that makes me crazy is how implement the Notify method. How should I know how many parameters I received and which types they have
void Notify(T...)
{
for (std::function<void(T...)> subscriber : _subscribers)
{
}
}
I hope now this is a valid question cause I'm losing my mind behind this
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
明显的方式有什么问题?
What is wrong with the obvious way?
这非常有用,正是我想要的,我花了很长时间才添加取消订阅功能。
问题在于比较两个
std::function>
的相等性没有明确定义,因此很难知道要删除哪一个。我最终做的是使用第二个向量将
void*
存储到订阅对象本身,然后删除同一索引处的侦听器对象和侦听器函数。示例用法(在你的 ListenerClass 中的某个地方)
老实说,我对我在这方面找到的示例和资源如此之少感到惊讶,因为它是非常常见的,所以我很确定这种实现事件的方法有问题,但它确实现在工作所以...
this was very useful, exactly what I was going for, what took me ages to do was then adding the Unsubscribe function.
The problem is that comparing two
std::function<void(...T)>>
for equality is not well defined so it's hard to know which one to remove.What I ended up doing is having a second vector that stores a
void*
to the subscribing object itself, and then removing the listener object and listener function at the same index.Example usage (somewhere in your ListenerClass)
I'm honestly surprised by how few examples and resources I found on this as it's something that is pretty common, so I'm pretty sure something is wrong with this approach for implementing events, but it does work for now so...