[CodeGenerator:] More flexible architecture
See original GitHub issueGoal:
- simplify unit testing
- have modules for every feature
- enable simple extension
- enable simple integration for other types of parsers / data providers (roslyn, json, ECSLang, etc)
Suggestion:
Divide the whole generation process in 3 parts:
Step 1: Input --> Model
Turn given input (e.g. *.cs, *.ecs, *.json files, etc) into an abstract model. Implementations of ICodeGeneratorDataProvider emit CodeGeneratorData to build up the model by using reflection or parsing or any other technique. DataProviders should be really small and should just do one thing, e.g. provide ComponentName or ContextNames or PublicMemberInfos. This way every aspect of Step 1 can be unit tested easily. Future features can be added without modifying the existing code 👍
The model is dynamic and new features can be added by any developer without modifying the library code.
Reflection /
Parsing
+---------------+
input | | output
+-------------> | Build Model | +-------------+
| | | |
+ +---------------+ v
+---------+ +---------+
| | | |
| Input | | Model |
| | | |
+---------+ +---------+
e.g *.cs CodeGeneratorData[]
After this step there will be a complete model representation of the given input
+-------------------+
| |
| Model |
| |
+-------------------+
| |
| Data |
| Data |
| Data |
| |
+-------------------+
Again, Data can be anything, from component names, to contexts to attributes. Adding new features is as simple as plugging in a new data provider.
Step 2: Model --> Code Generation
Implementations of ICodeGenerator get the model as an input and can query the model for anything the need. ICodeGenerator should also just do one thing, e.g. generate methods to extend the entity, generate methods to extend the context, generate ContextAttributes, etc. Each ICodeGenerator can be tested individually, which makes unit testing way easier. They emit one or more CodeGenFile.
New CodeGenerators can be added by any developer without modifying the library code.
+-------------------+
input | | output
+-------------> | Code Generation | +-------------+
| | | |
+ +-------------------+ v
+---------+ +-----------------+
| | | |
| Model | | CodeGenFile[] |
| | | |
+---------+ +-----------------+
Step 3: Post Process
Implementations of ICodeGenFilePostProcessor work on the CodeGenFiles[]. Again, they should only do one thing, which makes testing very easy. E.g. modify newlines for a given platform, add a file header or write file to disk.
+-------------------+
input | |
+-------------> | Post Processors |
| | |
+ +-------------------+
+-----------------+
| |
| CodeGenFile[] |
| |
+-----------------+
Summary
This modular approach simplifies
- unit testing
- adding new features without modifying the library code
- adding new methods to parse input
- adding custom code generators for your special needs
Step 1 Step 2 Step 3
+------------+ +-------------+ +-----------+
| | | | | |
| Data | | Code | | Post |
| Provider | | Generator | | Process |
| | | | | |
+-+---------++ ++-----------++ ++----------+
^ | ^ | ^
| V | V |
+-------+-+ +--------++ +------------+----+
| | | | | |
| Input | | Model | | CodeGenFile[] |
| | | | | |
+---------+ +---------+ +-----------------+
Issue Analytics
- State:
- Created 7 years ago
- Reactions:5
- Comments:7 (4 by maintainers)

Top Related StackOverflow Question
Not anymore 😉
Unity support is missing…