jeffcampbellmakesgames / Entitas-Redux

An entity-component framework for Unity with code generation and visual debugging
MIT License
103 stars 13 forks source link

[FEATURE REQUEST] Executing code generation using `CleanupAttribute` on a component generates a system #11

Closed HollowGraphic closed 4 years ago

HollowGraphic commented 4 years ago

Genesis does not generate cleanup systems for components that use the Cleanup attribute, regardless of what options are used (CleanupMode.RemoveComponent, CleanupMode.DestroyEntity). Genesis does not give an error. Unity 2020.1.0f1

jeffcampbellmakesgames commented 4 years ago

I believe the ability to generate a Cleanup system via code-generation was restricted to the paid version of Entitas as noted here on the original Wiki. Since EntitasRedux is based on the free open source version which does contain the CleanupAttribute.cs file, but not the code-generation logic for the systems, it does not currently have it as a feature.

That being said, implementing new code generation to enable this functionality would be a good feature-addition. Let's talk a bit about the expected outcome based on the described functionality.

Decorating [Cleanup(CleanupMode.RemoveComponent)] onto a component should result in a system that creates a group for entities with that component and when its logic is executed should result in iterating through those entites and removing the component from each.

Decorating [Cleanup(CleanupMode.DestroyEntity)] onto a component should result in a system that creates a group for entities with that component and when its logic is executed should result in iterating through those entites and destroying each one.

Since this attribute isn't limited to a single usage per target currently, if a target has two instances of [Cleanup] with both CleanupMode.RemoveComponent and CleanupMode.DestroyEntity specified, both types of systems will be generated. Each system should be of type ICleanupSystem and if there are more than one CleanupAttribute instances they will be reduced to one of each distinct type (one remove and destroy limit) to avoid redundant code generation.

@HollowGraphic If this seems like a reasonable approach to you, I will convert this to a new feature rather than a bug and assign it to a milestone for a future release.

HollowGraphic commented 4 years ago

Sounds legit to me.

jeffcampbellmakesgames commented 4 years ago

Getting closer to finishing this up, just a bit more testing to go through. In it's current form, creating a component (in this case named Destroyed decorated with a Cleanup attribute (or two) like so:

using JCMG.EntitasRedux;

namespace ExampleContent.VisualDebugging
{
    [VisualDebug]
    [Cleanup(CleanupMode.DestroyEntity)]
    [Cleanup(CleanupMode.RemoveComponent)]
    public sealed class DestroyedComponent : IComponent
    {

    }
}

results in two files being created at Generated/Cleanup/Systems named:

where the systems look like so:

DestroyVisualDebugEntitiesWithDestroyedSystem

//------------------------------------------------------------------------------
// <auto-generated>
//      This code was generated by a tool (Genesis v1.2.1, branch:develop).
//
//
//      Changes to this file may cause incorrect behavior and will be lost if
//      the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System.Collections.Generic;
using JCMG.EntitasRedux;

public sealed class DestroyVisualDebugEntitiesWithDestroyedSystem : ICleanupSystem
{
    private readonly IGroup<VisualDebugEntity> _group;
    private readonly List<VisualDebugEntity> _entities;

    public DestroyVisualDebugEntitiesWithDestroyedSystem(IContext<VisualDebugEntity> context)
    {
        _group = context.GetGroup(VisualDebugMatcher.Destroyed);
        _entities = new List<VisualDebugEntity>();
    }

    /// <summary>
    /// Performs cleanup logic after other systems have executed.
    /// </summary>
    public void Cleanup()
    {
        _group.GetEntities(_entities);
        for (var i = 0; i < _entities.Count; ++i)
        {
            _entities[i].Destroy();
        }
    }
}

RemoveDestroyedFromVisualDebugEntitiesSystem

//------------------------------------------------------------------------------
// <auto-generated>
//      This code was generated by a tool (Genesis v1.2.1, branch:develop).
//
//
//      Changes to this file may cause incorrect behavior and will be lost if
//      the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System.Collections.Generic;
using JCMG.EntitasRedux;

public sealed class RemoveDestroyedFromVisualDebugEntitiesSystem : ICleanupSystem
{
    private readonly IGroup<VisualDebugEntity> _group;
    private readonly List<VisualDebugEntity> _entities;

    public RemoveDestroyedFromVisualDebugEntitiesSystem(IContext<VisualDebugEntity> context)
    {
        _group = context.GetGroup(VisualDebugMatcher.Destroyed);
        _entities = new List<VisualDebugEntity>();
    }

    /// <summary>
    /// Performs cleanup logic after other systems have executed.
    /// </summary>
    public void Cleanup()
    {
        _group.GetEntities(_entities);
        for (var i = 0; i < _entities.Count; ++i)
        {
            _entities[i].IsDestroyed = false;
        }
    }
}
jeffcampbellmakesgames commented 4 years ago

@HollowGraphic As far as an ETA, I'll likely have a branch with this work pushed up to github by this weekend at which point it would be helpful if you could check it out and test it yourself before a release is cut, otherwise I will likely cut a new release next week.

HollowGraphic commented 4 years ago

I'll test it as soon as I can.

jeffcampbellmakesgames commented 4 years ago

This feature is now available for testing on the feat/cleanup_system_code_generation branch of this repository. The example content has been updated to include two new components whose CleanupAttribute decorations will result in new systems when code generation takes place.

HollowGraphic commented 4 years ago

Hmm, I don't see the branch. Not sure if I'm doing something wrong.

jeffcampbellmakesgames commented 4 years ago

Weird, I could have swore I pushed this up last week. In any case, the branch is now pushed up on Github

HollowGraphic commented 4 years ago

So I tested the branch in 2020.1.0f1 and it all looks good.

jeffcampbellmakesgames commented 4 years ago

This feature has been merged to develop and included in release v1.2.3 found here. If using OpenUPM, please update to the latest version of the package.