Commits

rkruppe committed 263c1c9

Hacky, but apparantly working, support for customization

Comments (0)

Files changed (2)

tutagx/meta/from_yaml.py

         self._emit.line(obj, '._on_loaded()')
 
 
-@process.oneshot
-def _decoder():
+def _decoder(cls):
     RESERVED = ('classes', 'result', 'oid', 'json_val', 'k', '__Placeholder')
-    sig = cg.Signature('$obj', 'seen', 'unfinished')
+    emit = cg.CodeEmitter()
+    ocs_class = getattr(cls, 'CONSTRUCTION_STRATEGY', PlainObjectCreation)
+    ocs = ocs_class(emit)
+    sig = cg.Signature('$obj', 'seen', 'unfinished', *ocs.extra_args)
     symtab = cg.SymbolTable(RESERVED, sig)
-    emit = cg.CodeEmitter()
-    ocs = PlainObjectCreation(emit)
 
     classes = {}
 
 
     code_ns = {'classes': classes, '__Placeholder': _Placeholder}
 
-    return cg.generate_code(
+    gen = cg.generate_code(
         locals(), typeident, sig, emit, symtab,
         entry_point=visit_toplevel, code_ns=code_ns
     )
+    return gen(wrap_model(cls))
 
 
+#TODO replace this API with something better
 class YAMLReader:
-    #TODO document this class
-
     def __init__(self, model):
         self._mcls = type(model)
         self._cls = model
-        self._decoder = _decoder(wrap_model(model))
+        self._decoder = _decoder(model)
 
     def decode(self, val, namespace=None, validator_ns=None, source=None):
         results, errors = self.decode_many(
             namespace = type(self).new_namespace()
         if validator_ns is None:
             validator_ns = validate.Validator.new_namespace()
-        args = (namespace.seen, namespace.unfinished)
+        args = (namespace.seen, namespace.unfinished) + namespace.extra
         validator = validate.Validator(self._cls)
         results = []
         for raw_value in raw_values:

tutagx/model/entity.py

 from tutagx.model.context import GameContext
 
 
-class _EntityDecoder:#(from_yaml._Decoder):
-    _EXTRA_ARGS = ('gcx',)
-
-    def _construct_object(self, target, cls):
-        self.line(
+class EntityConstructionStrategy(from_yaml.ObjectCreationStrategy):
+    def construct(self, target, cls):
+        self._emit.linef(
             '{} = gcx.build(classes[{!r}, {!r}]).unfinished_object()',
             target, cls.__module__, cls.__name__
         )
 
-    def _add_attributes(self, obj, params):
+    def add_attributes(self, obj, params):
         for attr, expr in params:
-            self.line('{}._builder.set({!r}, {})', obj, attr, expr)
+            self._emit.linef('{}._builder.set({!r}, {})', obj, attr, expr)
 
-    def _finish_constructed(self, obj):
-        self.line('{}._builder.finish()', obj)
+    def finish(self, obj):
+        self._emit.line(obj, '._builder.finish()')
 
-    def _descend(self, *args):
-        args += ('gcx',)
-        return super()._descend(*args)
+    @property
+    def extra_args(self):
+        return ('gcx',)
 
 
 class _Reader(from_yaml.YAMLReader):
 
 class GameEntityMeta(model.ModelMeta):
     _MODEL_BASE_NAME = 'GameEntity'
-    _decoder = _EntityDecoder
+    CONSTRUCTION_STRATEGY = EntityConstructionStrategy
 
     def __repr__(self):
         s = type.__repr__(self)