Skip to content

Code Generator

Simon Schmid edited this page Feb 2, 2016 · 43 revisions

Entitas.CodeGenerator

The Code Generator generates classes and methods for you, so you can focus on getting the job done. It radically reduces the amount of code you have to write and improves readability by a huge magnitude. It makes your code less error-prone while ensuring best performance. I strongly recommend using it!

The Code Generator is flexible and can be customized to fit your needs. In a pure C# project, simply choose your provider and generators like this:

var codeGenerators = new ICodeGenerator[] {
    new ComponentsGenerator(),
    new ComponentIndicesGenerator(),
    new PoolAttributeGenerator(),
    new PoolsGenerator()
};

var assembly = Assembly.GetAssembly(typeof(CodeGenerator));
var provider = new TypeReflectionProvider(assembly.GetTypes(), new [] { "Meta", "Core", "UI" });
CodeGenerator.Generate(provider, "Generated/", codeGenerators);

In a Unity project you can set up the Code Generator by selecting desired generators:

Entitas.Unity.CodeGenerator

Customizing and extending the Code Generator

You can easily implement your own generators by implementing one of the available ICodeGenerator

  • IComponentCodeGenerator
  • IPoolCodeGenerator
  • ISystemCodeGenerator

ComponentsGenerator

This Code Generator is smart and produces different output based on the content of the component. The Code Generator differentiates between four types:

  • standard component with public fields (e.g. PositionComponent)
  • single standard component that is meant to exist only once in the pool (e.g. UserComponent)
  • flag component without any fields (e.g. MovableComponent)
  • single flag component that is meant to exist only once in the pool (e.g. AnimatingComponent)

Standard component (e.g. PositionComponent)

public class PositionComponent : IComponent {
    public int x;
    public int y;
    public int z;
}

You get

var pos = e.position;
var has = e.hasPosition;

e.AddPosition(x, y, z);
e.ReplacePosition(x, y, z);
e.RemovePosition();

Single standard component (e.g. UserComponent)

[SingleEntity]
public class UserComponent : IComponent {
    public string name;
    public int age;
}

You get

// all from standard component plus methods for the pool

var e = pool.userEntity;
var name = pool.user.name;
var has = pool.hasUser;

pool.SetUser("John", 42);
pool.ReplaceUser("Max", 24);
pool.RemoveUser();

Flag component (e.g. MovableComponent)

public class MovableComponent : IComponent {}

You get

var movable = e.isMovable;
e.isMovable = true;
e.isMovable = false;

Single flag component (e.g. AnimatingComponent)

[SingleEntity]
public class AnimatingComponent : IComponent {}

You get

// all from flag component plus methods for the pool

var e = pool.animatingEntity;
var isAnimating = pool.isAnimating;
pool.isAnimating = true;
pool.isAnimating = false;

Fixing compilation errors

The Code Generator is based on runtime reflection. The project has to compile before you can generate. This is not an issue when you creating new components, however when it comes to changing or deleting components, your code might stop compiling. Here is a list of recipes how you can avoid bigger hassle while changing and deleting components.

Renaming component fields

Use rename refactoring of your IDE and generate. Things should not break because fields only affect method parameter names in the generated methods.

Renaming component

Use rename refactoring of your IDE and also rename the existing methods, setters and getters in the generated class and generate.

Adding new fields to a component

Add the new fields and generate. This will result in compile errors because some methods now expect more parameters, e.g. e.AddXyz() and e.ReplaceXyz(). You'll have to update all the places where you call these methods.

Removing fields from a component

This will directly lead to compilation errors because at least the generated class is using them. In this case you can just comment out the implementation of the affected methods, e.g e.AddXyz() and e.ReplaceXyz(). After that, generate again.

Deleting a component

Delete the component and the generated class completely. After that, fix your code and generate again.

Renaming pool names

Use rename refactoring of your IDE to rename the PoolAttribute class name first, then generate.

Clone this wiki locally