colyseus / schema

An incremental binary state serializer with delta encoding for games.
https://docs.colyseus.io/state/schema/
MIT License
134 stars 41 forks source link

Haxe macros compatible with colyseus-hxjs #19

Open endel opened 5 years ago

endel commented 5 years ago

@serjek made a Colyseus Server using macros to define the Schema https://github.com/serjek/colyseus-hxjs

It would be great to have the same for the schema decoder in the Haxe client. I've started doing this here: https://github.com/colyseus/schema/commit/fbf923089fb1ee3694b4ca8a2f065b4c54eb0321

The current problem is filtering fields from the parent class. Untyped fields (without @:type() annotations) shouldn't be considered when generating the decoding structure.

Problematic pieces of code are:

https://github.com/colyseus/schema/blob/fbf923089fb1ee3694b4ca8a2f065b4c54eb0321/decoders/haxe/io/colyseus/serializer/schema/Schema.hx#L52-L60

I've tried assigning metadata for declared fields, but it seems after they're evaluated, the metadata is gone: https://github.com/colyseus/schema/blob/fbf923089fb1ee3694b4ca8a2f065b4c54eb0321/decoders/haxe/io/colyseus/serializer/schema/Schema.hx#L28

I've opted out of using constants for type arguments like STRING in favor of "string" because the STRING constant gets evaluated as EConst(CIdent()), which makes it difficult to select if the field is going to be inside _childSchemaTypes or _childPrimitiveTypes: https://github.com/colyseus/schema/blob/fbf923089fb1ee3694b4ca8a2f065b4c54eb0321/decoders/haxe/io/colyseus/serializer/schema/Schema.hx#L68-L75

serjek commented 5 years ago

Hello! Perhaps this is the main restriction of build macro is that they apply only to class that extends a specified interface, not it's children (this is why you can't extend coconut model for instance). This is why I would recommend to specify in documentation that schema is not meant to be extended; if user needs some complex schema then he can insert one schema into another with annotation @:type(UnderneathSchemaType). To make compiler throw meaningful error you can add final to class definition with same build macro.

As for using constants as argument types, you can still keep them if you'd use abstract types from String to String (example: https://github.com/serjek/colyseus-hxjs/blob/b3b1368c9aa0119a75dd018e082de37d76d519aa/src/colyseus/server/schema/Schema.hx#L103)