DO NOT MERGE - this PR is for displaying this prototype code only, and is not meant to be merged.
This is a prototype of adding incon/fincon machinery to streamline, rather than writing it into core. Credit to Alex Greer for a lot of the ideas in here, especially the idea that streamline's particular implementation of a cell would be a good place to mix in incon/fincon functionality.
Since the "read incon" behavior and "write fincon" behavior should be tightly coupled, I've created an InconBehavior interface to package them together. The signatures on these methods allow them to be extended (see InconBehavior.map), which is important for allowing users to write an InconBehavior for simple types, that we can automatically extend to more complex or "wrapped" types. Otherwise, the InconBehavior is left highly general, treating incons as String-SerializedValue key-value pairs, which can be freely queried for incons and freely written for fincons.
The key principle in this design is "Every cell has an incon behavior." There are some cells where that behavior is degenerate, i.e., "For incons, use this constant value, and for fincons, write nothing out." However, this is an opt-out system, where the modeler needs to choose not to save the cell's value, rather than needing to remember everywhere else that they should save the cell's value.
To that end, I've modified streamline's cell allocation function to take an InconBehavior instead of an initial value. This interacts with a static incon manager to retrieve the initial value for the cell and register the fincon behavior, simultaneously. Doing the two operations simultaneously, I hope, will contribute to keeping the two halves of this behavior tightly coupled.
On top of this, I'm modifying the MutableResource constructors to add more user-friendly support for common use cases, namely
mapping the dynamics directly to a single key in the incon/fincon, and
not saving the dynamics at all.
There will still be a more general constructor for MutableResource which allows any incon/fincon behavior, to support edge cases.
Finally, that static incon manager is initialized and loaded with a set of incons when building the registrar, since building the registrar has evolved into the natural place to initialize all the streamline singletons, like the simulation clock and the global logger. That static incon manager then exposes a method to write a fincon, which the model may call at any time to invoke all the registered fincon behaviors, compose a full system fincon, and save that fincon. Note that this will mean it's up to the mission model to define something like a simulation config parameter and model task, or a "Fincon" activity, to actually save the fincon.
DO NOT MERGE - this PR is for displaying this prototype code only, and is not meant to be merged.
This is a prototype of adding incon/fincon machinery to streamline, rather than writing it into core. Credit to Alex Greer for a lot of the ideas in here, especially the idea that streamline's particular implementation of a cell would be a good place to mix in incon/fincon functionality.
Since the "read incon" behavior and "write fincon" behavior should be tightly coupled, I've created an InconBehavior interface to package them together. The signatures on these methods allow them to be extended (see InconBehavior.map), which is important for allowing users to write an InconBehavior for simple types, that we can automatically extend to more complex or "wrapped" types. Otherwise, the InconBehavior is left highly general, treating incons as String-SerializedValue key-value pairs, which can be freely queried for incons and freely written for fincons.
The key principle in this design is "Every cell has an incon behavior." There are some cells where that behavior is degenerate, i.e., "For incons, use this constant value, and for fincons, write nothing out." However, this is an opt-out system, where the modeler needs to choose not to save the cell's value, rather than needing to remember everywhere else that they should save the cell's value.
To that end, I've modified streamline's cell allocation function to take an InconBehavior instead of an initial value. This interacts with a static incon manager to retrieve the initial value for the cell and register the fincon behavior, simultaneously. Doing the two operations simultaneously, I hope, will contribute to keeping the two halves of this behavior tightly coupled.
On top of this, I'm modifying the MutableResource constructors to add more user-friendly support for common use cases, namely
Finally, that static incon manager is initialized and loaded with a set of incons when building the registrar, since building the registrar has evolved into the natural place to initialize all the streamline singletons, like the simulation clock and the global logger. That static incon manager then exposes a method to write a fincon, which the model may call at any time to invoke all the registered fincon behaviors, compose a full system fincon, and save that fincon. Note that this will mean it's up to the mission model to define something like a simulation config parameter and model task, or a "Fincon" activity, to actually save the fincon.