Generator process
The generator process is the core of the generator build into LLBLGen Pro. It executes the tasks defined in the run queue defined by a preset which is done by creating task objects and task group objects in a hierarchy which are then performed by executing the task performers defined for each task.
Inner workings
When the generation process starts, the generator object is made available to all task performer objects which are instantiated by the generator process. The generator object instantiates all task performer assemblies defined with tasks before it starts executing the tasks.
This will stop the generator process early on when a task performer assembly can't be loaded. The generator object contains various objects, like the templatebindings objects chosen, the platform to use and the language chose, which allow you to access all the information you might need at generation time.
Among the objects available to you through the generator object is also
the project object which contains the complete project, which can be
helpful for the task performers. See the LLBLGen Pro designer core
assembly reference manual for details about the properties of the class.
The Generator
class is defined in the GeneratorCore
assembly, while a
lot of the classes used by the Generator
class like templatebindings are
defined in the ApplicationCore
.
The generator simply executes all tasks defined. It doesn't know nor cares what it executes. All task performers are executed in the same appDomain as the designer. The execution process is a recursive process.
This means that the root taskGroup
object simply calls Perform()
of all
task
objects and taskGroup
objects inside that taskGroup
. This results
in the execution of only the task
objects, since taskGroups
do not have
a task performer assembly associated with them.
Caches
The generator object contains a cache which can be used to store temporary values, which have to be passed on between tasks. It's a generic hash table which works with key-value pairs. The property returning the hash table is called TaskCache.
This cache can be useful when you want to work with data that is generated on the fly, for example the filenames of all the files that are generated. The task performers CodeEmitter and ProjectFileCreator use this cache for passing on all filenames of the files being generated.
This way, the ProjectFileCreator task performer can include all files in the project in the project file. See the source code for these two classes for details.
To prevent filenames being leaked into a project file of a following taskgroup, each taskgroup which will emit a VS.NET project file will require a clean cache: the TaskCache hashtable is cleared after each taskgroup which has requiresCleanCache set to true.
To cache data across taskgroups, e.g. to be used at the end of a preset with multiple
tasktgroups, use the IGenerator.RunQueueCache
. This dictionary is
never cleared during a runqueue execution.
Task performers and the generator object
When a task object is executed by the generator object (it is called by
the Perform()
method of the task group object the task object is located
in), the specified task performer class is in fact executed, by calling
one of the Perform()
overloads.
When the task object had any parameters
defined, the overload of ITaskPerformer.Perform()
is called which
accepts a parameters collection, otherwise the non-parameter collection
overload of ITaskPerformer.Perform()
is called. ITaskPerformer.Perform()
receives a reference to the generator object and the task object itself.
The generator object knows how many tasks there are to perform and takes care of the progress bars during code generation and also takes care of the verbose logging in the application output window of what tasks are executed using which assemblies.
When the task performer is done, it simply returns and the next task in
line is executed. The generator object stops execution of tasks when a
GeneratorAbortException
is caught.
Debugging task performers
Debugging task performers can be done by compiling a debug build of the task performer assembly and by placing the assembly and its related .pdb file into the TaskPerformers directory of LLBLGen Pro or the Additional task performers folder specified in the preferences or project properties.
Then, start the LLBLGen Pro designer and attach within visual studio the debugger to that process. Set a breakpoint in the task performer source code and start a generation process using a preset which contains a task which uses the task performer. The breakpoint should now be hit and the debugger should stop there and you can then step through the code.