-
-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cattrs
support
#4
Comments
The more I look into it the less likely it seems I'll be able to register the ECS For components I could probably do something like this for their types and data: import importlib
from typing import Any
import cattrs
def unstructure_generic(obj: object, converter: cattrs.Converter) -> dict[str, Any]:
"""Unstructure any type or instance to a qualified path and its data."""
if isinstance(obj, type):
return {"module": obj.__module__, "type": obj.__name__}
return {
"module": obj.__class__.__module__,
"type": obj.__class__.__name__,
"data": converter.unstructure(obj, obj.__class__),
}
def structure_generic(blob: dict[str, Any], converter: cattrs.Converter) -> Any:
"""Structure a previously unstructured generic object."""
out_type: type[Any] = getattr(importlib.import_module(blob["module"]), blob["type"])
if "data" not in blob:
return out_type
return converter.structure(blob["data"], out_type) This should work for everything except |
Dropping a reminder to myself and a notice that I plan to take a look at this tomorrow, will need to look deeper into |
So class _ECSConverter:
... # Weak references to known Worlds and plain object are tracked by this class
def unstructure_uid(self, obj: object) -> dict[Any, str]:
"""Unstructure an object used as an ID, tracking seen objects."""
def structure_uid(self, blob: dict[Any, str]) -> Any:
"""Structure an object used as an ID, can return the same object if it is duplicate."""
def unstructure_entity(self, entity: Entity) -> dict[Any, str]:
"""Unstructure a (world, uid) pair."""
def structure_entity(self, blob: dict[Any, str]) -> Entity:
"""Structure a (world, uid) pair."""
def unstructure_world(self, world: World) -> dict[Any, str]:
"""Unstructure a World instance."""
def structure_world(self, blob: dict[Any, str]) -> World:
"""Structure an object used as an ID, can return the same object if it is duplicate."""
def handle_tcod_ecs(converter: cattrs.Converter) -> None:
"""Configure a cattrs converter to support ECS instances."""
ecs_converter = _ECSConverter(converter) # Bind to converter
converter.register_unstructure_hook(World, ecs_converter.unstructure_world)
converter.register_structure_hook(World, ecs_converter.structure_world)
converter.register_unstructure_hook(Entity, ecs_converter.unstructure_entity)
converter.register_structure_hook(Entity, ecs_converter.structure_entity)
converter.register_unstructure_hook(Any, ecs_converter.unstructure_uid)
converter.register_structure_hook(Any, ecs_converter.structure_uid) I think this solves the issue of how to handle when a world or uid is encountered multiple times. |
My attempt to write a cattrs converter with #5 is officially a failure. It works, saves and loads without issues and handles cycles and whatever I throw at it, but the resulting format is huge mess that I don't want to support. It might be good for me to look at how other tools serialize this kind of system. I vastly underestimated the complexity of unstructuring dictionaries with complex keys. Python does not like the keys being unstructured into unhashable dictionaries and even if I used frozendict some formats might not be able to handle serializing such keys.
I might try this again some time after I've become a lot more familiar with cattrs. |
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:
Entity
objects which are always a(world, uid)
pair.Code examples from @slavfox
How to handle
object()
asuid
?How to handle component types held by World?
The cattrs docs are pretty good, but it will take me a while to internalize them.
The text was updated successfully, but these errors were encountered: