docs: def _to_event_data(obj):
      '''
      Convert the specified object into a form that can be serialised by msgpack as event data.
  
      :param obj: The object to convert.
      '''
  
      if obj is None:
          return None
      if isinstance(obj, bool):
          return obj
      if isinstance(obj, int):
          return obj
      if isinstance(obj, float):
          return obj
      if isinstance(obj, str):
          return obj
      if isinstance(obj, bytes):
          return obj
      if isinstance(obj, dict):
          return obj
  
      if isinstance(obj, NodeDriver):  # Special case for NodeDriver (cyclic references)
          return obj.name
  
      if isinstance(obj, list):
          return [_to_event_data(item) for item in obj]
  
      event_data = {}
      for attribute_name in dir(obj):
          if attribute_name.startswith('_'):
              continue
  
          attribute_value = getattr(obj, attribute_name)
  
          if callable(attribute_value):  # Strip out methods
              continue
  
          event_data[attribute_name] = _to_event_data(attribute_value)
  
      return event_data