Custom RTTI for use in script-defined types

笑着哭i 提交于 2019-12-06 14:04:00

问题


I'm developing a game engine in C++ that allows Python scripting. Here's an example of how functions can be defined in Python that are then called by the an event manager whenever a certain event occurs:

# Import some classes defined in C++
from cpp.event import PlayerDiesEvent, EventManager

def onPlayerDeath(event):
    pass

em = EventManager()
em.connect(PlayerDiesEvent, onPlayerDeath)
em.post(PlayerDiesEvent(...)) # Will call `onPlayerDeath`

The user can also define new types of events:

from cpp.event import Event, EventManager

class CustomEvent(Event):
    pass

def onCustomEvent(event):
    pass

em = EventManager()
em.connect(CustomEvent, onCustomEvent)
em.post(CustomEvent())

However, I would also like the messaging system to work with inheritance, which it currently does not. Here's what I mean:

from cpp.event import PlayerDiesEvent, EventManager

class CustomEvent(PlayerDiesEvent):
    pass

def onPlayerDeath(event):
    pass

def onCustomEvent(event):
    pass

em = EventManager()

em.connect(PlayerDiesEvent, onPlayerDeath)
em.connect(CustomEvent, onCustomEvent)

# This notifies both functions, because `CustomEvent` is a `PlayerDiesEvent`
em.post(CustomEvent(...))

# This notifies only `onPlayerDeath`
em.post(PlayerDiesEvent(...))

tld;dr: Is there any C++ library that would allow me to more easily create a custom RTTI system that works with inheritance? If not, any ideas how I might implement this more easily and perhaps more generally (preferably in a way that is agnostic to my actual use case)?


回答1:


I'm not familiar with boost::python; it might have some feature that makes this easier. I just know of a custom RTTI system that works pretty well:

Qt has a meta-object system, where reflection and a degree of dynamic behavior is added by having a metaobject associated with each class that knows about that class's ancestors and methods. It's kind of like Python's class objects. A virtual method is used to get the metaobject from instances. A custom compiler is used to generate these.

Qt's Python bindings then also create these metaobjects for Python classes, making them look almost identical to native QObjects classes as far as the meta-object system is concerned.


You need quite a bit less than Qt's general solution (you don't need info about methods/properties). So instead of a custom compiler, you could go with a C++-class definition macro that stores information about the class's ancestors. And then also update the information from the __metaclass__ when a Python subclass is created, and query it when you're dispatching a message.



来源:https://stackoverflow.com/questions/7943854/custom-rtti-for-use-in-script-defined-types

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!