Issue #21 resolved
The ControllerManager and Controller model are reasonable, but are somewhat underpowered.
Here are changes that should be made:
- Controller is renamed to Task. Its
postProcess()methods are replaced with a single
process()returns a nullable Task that is invoked as a post-process after the job.
- Tasks are collected into a Job. Results reported by tasks are only delivered to tasks within the same job.
- Tasks can implement a
ParallelAwareinterface that describes component types that are added/removed, read/written, and if entities are added/removed.
- Job acquires locks needed given the above, for all tasks and holds them for the duration of the task (ordered consistently to prevent deadblocks).
- The post-process Tasks are invoked after the locks are released, within an implicit job wrapping all post-process tasks from the initial job.
- This repeats until no further tasks need to be invoked.
- Jobs reset tasks before each execution of the job. When the job is created, it invokes
destroy()when the job is GC'ed.
- There is a scheduler that has a fixed size thread pool. Jobs are queued and run on an available thread.
- It also has a convenience interface for creating control threads that queue jobs at different rates, etc.
- The scheduling interface for repeated job execution lets the programmer specify a conditional that is evaluated before queuing (e.g. pause game simulation, without pausing rendering).
- Add a convenience paradigm to the abstract task that looks for a
processEntity()method that takes a number of ComponentData types as arguments.
- It automatically allocates the ComponentData instances
- Creates the ComponentIterator and invokes
processEntityfor each element
- Results are reported to other tasks by having those tasks expose
on(T extends Result)
- The methods are only invoked if the reported result is a subtype of the requested method
- A task can listen for multiple results by having multiple methods with different result types