事件订阅的性能考虑

本文关键字:性能 事件 | 更新日期: 2023-09-27 17:50:12

考虑以下代码:

class GameEventsManager
{
    public void StartGameEvent(GameEvent TheGameEvent)
    {       
        SubscribeToGameEvent(TheGameEvent);
        TheGameEvent.Begin();
        UnsubscribeToGameEvent(TheGameEvent);
    }
    private void SubscribeToGameEvent(GameEvent TheGameEvent)
    {
        TheGameEvent.OnPlaySound += OnPlaySound;
        TheGameEvent.OnShowWrittenItem += OnShowWrittenItem;
            ...
    }
    private void UnsubscribeToGameEvent(GameEvent TheGameEvent)
    {
        TheGameEvent.OnPlaySound -= OnPlaySound;
        TheGameEvent.OnShowWrittenItem -= OnShowWrittenItem;
            ...
    }
}

GameEvent基本上是这样一个类:当Begin()被调用时,它会引发传递给GameEventManager的事件,这样它就可以对游戏环境做出适当的改变(这是通过进一步将事件传播给负责执行每个特定指令的对象,就像在Observer模式中一样)。

现在考虑到我所有的InventoryItems(可以触发事件,如OnConsume, OnUse)都是它们特定类中的静态字段。虽然这看起来有点粗糙,但我觉得能够做到:

AddItem(WrittenItems.NoteFromKing) //NoteFromKing is a static field in WrittenItems

让事情变得更简单,考虑到我正在制作一款相当复杂的游戏,这是一个受欢迎的景象。

然而,这使得我很难在某个地方列出所有游戏道具,以防万一需要这样做。这就引出了我的问题:

管理玩家与关卡中特定道具互动等内容的LevelManager会告诉GameEventsManager在必要时运行特定的GameEvent。然后GameEventsManager订阅GameEvent,启动它,然后取消订阅。在遵循此订阅/运行/退订模式时,我是否应该期望看到明显的性能问题?最后,管理者可能会订阅/取消订阅GameEvent中的大约20个事件。

如果订阅/退订机制很慢,我可以在游戏初始化时运行一个订阅过程,但这将迫使我构建一个额外的结构,列出所有项目。

所以,简而言之,我想知道我是否应该期望从这种实现中得到相当大的减速。或者更准确地说,如果订阅大约20个事件,然后取消订阅它们相当慢。

语言为c#,使用Unity 4下的。net 2.0子集

事件订阅的性能考虑

然而,这让我很难列出所有的游戏道具

为什么?您可以创建一个ItemManager(它是一个单例):

public class ItemManager
{
    private static volatile ItemManager _instance;
    private static object syncRoot = new Object();
    private ObservableCollection<ItemBase> _registeredItems = new ObservableCollection<ItemBase>();
    private ItemManager()
    {
    }
    public ItemManager Instance
    {
        get
        {
             if (instance == null) 
             {
                 lock (syncRoot) 
                 {
                     if (instance == null) 
                         instance = new ItemManager();
                 }
             } 
             return instance;
        }
    }
    public void RegisterItem(ItemBase item)
    {
        _registeredItems.Add(item);
        // Do some stuff here, subscribe events, etc.
    }
    public void UnregisterItem(item)
    {
        // Do some stuff here, unregister events, etc.
        _registeredItems.Remove(item)
    }
}

之后你让所有的项目类都从一个叫做"ItemBase"的类派生出来。在ItemBases Constructor中你调用这个:

ItemManager.Instance.RegisterItem(this);

所以你不需要手动添加每一个项目。关于单例模式的更多信息,请看这里:http://msdn.microsoft.com/en-us/library/ff650316.aspx.

这样做的一个小好处是,你可以实现GameManager和ItemManager之间的通用通信