Skip to content
Jeff Campbell edited this page Oct 28, 2020 · 7 revisions

For Users

As a user, leveraging Genesis is very easy. At a high level, it involves:

  • Creating a GenesisSettings asset and configuring it.
  • Using any of the pre-included Genesis plugin attributes to decorate your existing code where code generation is desired.
  • Running code generation runner to create the desired script files.

Configuring Code Generation

The first thing you will want to do is to create a GenesisSettings asset in the project. This will enable you to configure which plugins should generate code, where it should be output to, and other per-plugin settings. A Unity project can have a single or multiple GenesisSettings assets to generate different subsets of code. An example of how this can be useful might be using two different GenesisSettings instances with one for generating production code and another for generating fixtures for Unit Tests.

Genesis Settings Inspector

There are several default included plugin settings exposed here when importing and using Genesis.

General Code Generation

This section houses core project settings for Genesis to execute code generation.

  • Auto Import Plugins This button enables a user to import all plugin settings into the GenesisSettings instance. This should typically be done when first creating a new GenesisSettings instance and when adding/creating new IConfigurable plugins.

Each of the mask fields below it enables confguring which plugins should be enabled on an individual basis when a code generation run takes place using this GenesisSettings instance. This can be useful for disabling undesired plugins or for troubleshooting how specific plugins behave.

For example, disabling the "Write Code Gen Files to Disk" IPostProcessor plugin enables running the code generation process without writing any of the generated CodeGenFile instances to disk.

Assemblies

This section enables a user to limit the scope of reflection for data providers and other plugins to an array of white-listed assemblies. By default, this feature is turned off, but is recommended to enhance the performance of code generation runs, particularly in larger projects where there may be many assemblies.

  • Do Use Whitelist: If enabled, searching via reflection for Data Providers will be limited to the array of assemblies below. Otherwise all loaded assemblies will be searched.

  • Assembly Whitelist: The comma delimited array of assemblies that searching via reflection for Data Providers should be limited to.

For Devs

Data providers are recommended to take advantage of this feature by implementing IConfigurable and use AssembliesConfig to acquire these user settings for which assemblies should be searched via reflection if enabled. ReflectionTools is a great example of a utility class that can then be used in a DataProvider to limit reflection search scope to only the assmblies the user has specified.

Convert Line Endings

This allows a user to configure the line endings all code-generated files generated from this GenesisSettings instance. This can be useful where one line ending type is preferred over another or plugins create files with mixed line endings which often causes Unity to warn about in the console.

Output Directory

This allows a user to specify the root folder all code-generated files will be written to directly or in a subfolder to.

Running Code Generation

Once you have a GenesisSettings asset created and configured, there are multiple ways to easily kick off a code-generation run:

  • Running the menu item "Tools/JCMG/Genesis/Generate Code" will execute code-gen for all GenesisSettings assets in the project. There is also a hotkey to execute this command via pressing Ctrl + Shift + G or CMD + Shift + G.
  • Selecting one or more GenesisSettings assets in the Project window, right-clicking, and selecting the context menu item Genesis => Generate Code will execute-code gen just for those assets/.
  • When selecting a single GenesisSettings asset, on its inspector underneath Actions you can click a button labeled Generate Code to execute code-gen just for that asset.

You'll notice at this point that there are likely not any generated files. Thats because Genesis plugins uses C# reflection to search through your code to find any classes decorated with custom attributes like [FactoryKeyEnumFor] as an example and generates code based on the discovered results.

For Developers

Adding code generation capabilities to your game or library can help to:

  • Automate creation of boilerplate, repetitive code files.
  • Reduce creation of bugs from manually writing or copying and pasting repetitive scripts.
  • Add to or extend APIs based on user code-base.

Genesis enables you to add code-generation to any game or library by offering:

  • A multi-stage code-generation process with a fine degree of control
  • Exposing several plugin types for integrating customized logic

Code-Generation Process

The process for generating code in Genesis is pretty straightforward. Starting a code generation run or hotkey will walk through the following stages:

Genesis Architecture Flow

  • Setup
    • All plugin types are discovered via reflection and:
      • If they implement ICacheable are assigned a shared cache between all other ICacheable plugins
      • If they implement IConfigurable they are assigned the GenesisSettings instance for this run.
  • Code Generation
    • All IPreProcessor plugins execute.
    • All IDataProvider plugins are executed and return a set of zero or more CodeGeneratorData instances.
    • All ICodeGenerator plugins are passed the superset of CodeGeneratorData derives instances and return a set of zero or more CodeGenFile instances representing a code-generated file.
    • All IPostProcessor plugins are passed the superset of all CodeGenFile instances and execute their logic.

Where there are multiple GenesisSettings instances, a code generation run will be executed for the steps listed above in sequence of when they were discovered. During that time Unity's compilation and AssetDatabase will be locked until either all code generation runs have completed or an error occurs, at which point both will be unlocked.

Clone this wiki locally