The philosophy of keeping simple things simple yet allow for advanced usage. So, at first, things are verbose and try to work out-of-the-box. If it doesn't, let me know. I will document better or better yet, make architectural changes so that it fits with developer style. This is a work in progress so it will take time.
The use of so many defines seems a bit overkill at first. After all, many of the sections of code could be combined into one define. The purpose though is that you the developer could place code between the defines if needed or even remove the define and take responsibility for that section of code.
The purpose is that since the symbols cause changes in the Concept, giving the world access to them allows the world to drive the Concept. So, if you want to inject a symbol, make a method to do so. For example, in Data, when you change the data value, it causes the change symbol to occur. Triggers have the ability to inject a symbol with a method.
Where do I draw the line between the responsibilities of the Concept vs the Builder? The Concepts hold functionality (methods and data) which is externalized to other objects and inheriting Concepts. The Builder are library and toolkit specific. I have variables for every public Concept and State. In the Builders, I have every Concept and State as inheriting Builders might not have access to the internals of the Concept, only the externalized functionality.
Well, yeah. It is messy since the Concept and Builder both like to have references to the concepts. But, I like to have only one reference since there is the possibility of one pointer changing and the other not. So, if we put them all in the Concept, the extending Builders will not have access to them. The Builder only has access because it is a friend class. If we put it into the Builder, then the Concept has to reference the Builder every time it needs the component and, more importantly, the builder is not set until after the concept is constructed. So, it is messy but for now, BOTH have them.
Builders are required in case something specific for a library or toolkit is needed. To enforce this, the Builder is what sets up Responses.
A very annoying but useful method. You'll see every time you need to debug and use the displayMe call. For generating code, make the Concept displayMeInternal print generic information about the Concept. Then, have it call the Builder to display its information if the Builder wants. Then return to the Concept and always have the Concept print a newline. In this way, if a Builder is extended or if a Concept is extended, it will still always print information about them... neatly.
Symbols are protected. Only extending Concepts can use them, as they extend the Concept's state machine add functionality which requires them. Also, the Builder can get them with DIRECTOR->findSymbol(char*). I try to limit this to only methods which return symbols. Typically, the Builder should call a function on the builder which causes the Symbol.
The initialization of a Concept is tricky at best. To the user, it all exists as a weird static constructor. To someone that wants to delve inside... well, gads.
Static constructor called
Call default constructor
Set the Builder
Call builderInitialization... because here we know the builder is fully instantiated
Send init symbol to run do_inited
Builder called do_inited in CO.