我正在为多线程俄罗斯方块游戏实现类似于观察者设计模式的机制。有一个Game类,其中包含EventHandler对象的集合。如果一个类想将自己注册为Game对象的侦听器,则它必须继承Game::EventHandler类。在状态更改事件上,将在每个侦听器的EventHandler接口(interface)上调用相应的方法。代码如下所示:
class Game
{
public:
class EventHandler
{
public:
EventHandler();
virtual ~EventHandler();
virtual void onGameStateChanged(Game * inGame) = 0;
virtual void onLinesCleared(Game * inGame, int inLineCount) = 0;
private:
EventHandler(const EventHandler&);
EventHandler& operator=(const EventHandler&);
};
static void RegisterEventHandler(ThreadSafe<Game> inGame, EventHandler * inEventHandler);
static void UnregisterEventHandler(ThreadSafe<Game> inGame, EventHandler * inEventHandler);
typedef std::set<EventHandler*> EventHandlers;
EventHandlers mEventHandlers;
private:
typedef std::set<Game*> Instances;
static Instances sInstances;
};
void Game::RegisterEventHandler(ThreadSafe<Game> inGame, EventHandler * inEventHandler)
{
ScopedReaderAndWriter<Game> rwgame(inGame);
Game * game(rwgame.get());
if (sInstances.find(game) == sInstances.end())
{
LogWarning("Game::RegisterEventHandler: This game object does not exist!");
return;
}
game->mEventHandlers.insert(inEventHandler);
}
void Game::UnregisterEventHandler(ThreadSafe<Game> inGame, EventHandler * inEventHandler)
{
ScopedReaderAndWriter<Game> rwgame(inGame);
Game * game(rwgame.get());
if (sInstances.find(game) == sInstances.end())
{
LogWarning("Game::UnregisterEventHandler: The game object no longer exists!");
return;
}
game->mEventHandlers.erase(inEventHandler);
}
这种模式经常遇到两个问题:
我当前的解决方法是您可以在上面的代码示例中看到的一种。我将
UnregisterEventHandler
设为一个静态方法,该方法根据实例列表进行检查。这确实有帮助,但是我发现它有些棘手。有谁知道一套有关如何干净安全地实现通知者/听众系统的指导方针?关于如何避免上述陷阱的任何建议?
PS:如果您需要更多信息来回答此问题,可以在此处在线找到相关代码:Game.h,Game.cpp,SimpleGame.h,SimpleGame.cpp,MainWindow.cpp。
最佳答案
shared_ptr
来确保最后删除游戏。