-
-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Labels
enhancementNew feature or requestNew feature or request
Description
I was asked to support cattrs and other generic serialization libraries. With the boilerplate required to do this externally it would be better to add cattrs support directly to this package instead.
This has to do the following:
- Save and load anonymous
Entity
objects which are always a(world, uid)
pair. - Save and load anonymous objects without knowing their type ahead of time. These may be components, tags, or uid's.
Code examples from @slavfox
How to handle object()
as uid
?
# EntityId: some opaque type with a zero-argument constructor EntityId()
# ecs.entdict: dict[EntityId, collection[Any]]
# note: only typechecks with --enable-recursive-aliases
JsonValue: TypeAlias = dict[str, "JsonValue"] | list["JsonValue"] | int | float | bool | str | None
def serialize_ecs(ecs):
idmap: dict[EntityId, int] = {id_: i for i, id_ in enumerate(ecs.entdict)}
return {
idmap[id_]: [serialize_value(c, idmap=idmap) for c in components]
for id_, c in ecs.entdict.items()
}
def serialize_value(value: Any, idmap: dict[EntityId, int]) -> JsonValue:
match value:
case int(_) | float(_) | bool(_) | str(_) | None:
return value
case [*xs]:
return [serialize_value(x, idmap) for x in xs]
case {**xs}:
return {str(k): serialize_value(v, idmap) for (k, v) in xs}
case EntityId():
return idmap[value]
case _:
return {
field.name: serialize_value(field.value) for field in get_ecs_fields(value)
}
How to handle component types held by World?
The common pattern for using cattr is tagged enums, which you can think of as, roughly:
serializers = {}
deserializers = {}
# Decorator to register a class with cattr
def cattr(cls_):
serializers[cls_] = ...
cls_key = make_cls_key(cls_)
deserializers[cls_key] = ...
...
return cls_
def serialize(inst):
return {
"__type": make_cls_key(type(inst)),
**serializers[type(inst)](inst)
}
def deserialize(serialized):
key = serialized.pop("__type")
return deserializers[key](serialized)
The cattrs docs are pretty good, but it will take me a while to internalize them.
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request