GameObjectSerialization.txt 4.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. TODO
  2. - Ability to break external references as a pre-processing step
  3. ---------------------------------------
  4. C# component serialization
  5. RuntimeScriptObjects
  6. - enumerateSerializable()
  7. - Goes through all (non-C++) Components and non-Component classes marked with [Serializable]
  8. - Using C++ it finds all fields in those classes. Fields and their references are stored in C++ classes.
  9. - Need to enumerate value type fields, or fields holding other [Serializable] structures, references to other Components, SceneObjects or Resources
  10. - Plus arrays, and possibly C# List
  11. - Considers attributes
  12. - [Serialized] - Forces field to be serialized (If valid type)
  13. - [NotSerialized] - Forced field not to be serialized
  14. - By default all public members are serialized and private ones are not
  15. - Something like SerializableComponentInfo (per-component), SerializableObjectInfo(per-non-component), SerializablePlainField,
  16. SerializableArrayField, SerializableResourceField, SerializableGameObjectField, SerializableObjectField, etc.
  17. - Internally it holds a Map with name -> Serializable*Info mapping for every supported type
  18. - User can query if type is supported or not, and retrieve the serialization info if needed
  19. - Using the serialization info user can retrieve actual values from an instance easily
  20. - Serializable*Info classes contain findField method that accepts a name and a type
  21. - This is used for deserialization
  22. - Using Serializable*Info you can create a brand new instance of a Component or a [Serializable] non-component
  23. ScriptComponent
  24. - C++ half of the C# component
  25. - Returned from SerializableComponentInfo::createInstance and created automatically whenever a managed component is created
  26. - Contains a managed type-name of the component
  27. - Has ScriptComponentRTTI
  28. ScriptComponentRTTI
  29. - Allows for easy and automatic serialization and deserialization
  30. - Saves managed component type-name
  31. - Uses RuntimeScriptObjects to get Serializable*Info, which is in turn used to find component fields
  32. - Has various methods returning arrays of fields
  33. - GetPlainFields
  34. - Returns FieldId -> (int, bool, byte, etc.) mapping
  35. - GetStringFields
  36. - Returns FieldId -> string mapping
  37. - GetSerializableObjectFields
  38. - Returns FieldId -> ReflectablePtr to ScriptSerializableObject (which will be serialized recursively)
  39. - GetGameObjectFields
  40. - Returns FieldId -> HGameObject
  41. - GetResourceFields
  42. - Returns FieldID -> HResource
  43. - When serializing all those arrays are prepared in OnSerializatioStarted
  44. - When deserializing they are send to the object in OnDeserializationEnded
  45. - However existance for the fields is first checked by getting new copy of SerializableComponentInfo and seeing
  46. which fields match
  47. - FieldId is just a name + type of the field.
  48. - When deserializing and component type name cannot be found, returns an empty ScriptComponent
  49. ScriptSerializableObject
  50. - Has ScriptSerializableObjectRTTI
  51. - When deserializing and component type name cannot be found, returns null
  52. - Otherwise equivalent to its ScriptComponent and ScriptComponentRTTI counterpart
  53. TO CUT DOWN ON SERIALIZATION SIZE
  54. - Serialize the Serializable*Info itself, and then FieldId can be just numerical ids
  55. - Just having the RTTI class holding a reference to Serializable*Info (and it being IReflectable) should
  56. ensure only one copy of it is stored.
  57. TODO - Possibly flesh out and example with Resources or Gameobject references a bit more
  58. - When deserializing HResource and HGameObject handles how do I find their managed counterparts? I can create new handles
  59. but they could already be loaded and it doesn't make sense to have two different handles.
  60. - Some kind of managed <-> native mapping?
  61. ------------------------------------------------------
  62. General C# component management
  63. Native components like Camera
  64. - ScriptCamera derives from Camera
  65. - Then whenever I check for managed Components I need to check if object type of ScriptComponent or
  66. any of the built-in types.
  67. - Checking each type might be a bit slow, but normally we will be looking for an exact type
  68. so hopefully this will only matter when enumerating all components which shouldn't be during performance
  69. critical moments.
  70. Inspector
  71. - RuntimeScriptObjects::enumerateInspectable creates a list of all inspectable classes (Components and others marked with [Serializable]
  72. - Returns a hierarchy very similar to Serializable*Info and their children (Likely re-use the same hierarchy but with different flags?)
  73. - This information is then used to generate needed fields
  74. - Importer inspectors are special and custom-built and shouldn't be considered here
  75. TODO - When reloading scripts how to handle restoring references?
  76. TODO - When I destroy a Component, how will I refresh the inspector to let it know that something has changed
  77. - Can happen from C# and C++