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.