Git Product home page Git Product logo

Comments (18)

sschmid avatar sschmid commented on April 28, 2024

Once we add a component using a generated method like e.AddHealth(42) we could add an event handler for OnComponentRemoved. This handler could check if the component index is the same and push the component to the component pool. This way it would work for both cases e.RemoveAllComponents() and pool.DestroyEntity()

What do you think?
I also have unity project for performance testing where I could check if the added event handler has a negative effect on the performance.

from entitas.

sschmid avatar sschmid commented on April 28, 2024

Also, I think it's time to also add tests for the actual logic of the generated output, not only tests for the expected output of the generator. I'd like to add tests for the four component types (standard, flag, single std, single flag)

from entitas.

sschmid avatar sschmid commented on April 28, 2024

First tests revealed it adds 312byte per component even with cached event handlers
entitas component pool

from entitas.

sschmid avatar sschmid commented on April 28, 2024

Creating new components would be cheaper...

from entitas.

trumpets avatar trumpets commented on April 28, 2024

I see... The issue I stumbled upon, and thus discovering this intricacy, was that my object count was increasing a lot, I had a lot of entities which were being destroyed and created, and the GC was turning on once in ~10 secs and that was stuttering my game :/

I am tinkering with the code right now, trying to figure out another way...

from entitas.

sschmid avatar sschmid commented on April 28, 2024

91%, to be precise :)
entitas new component

from entitas.

sschmid avatar sschmid commented on April 28, 2024

Here's my test, if you're interested:

from entitas.

sschmid avatar sschmid commented on April 28, 2024
using System.Collections.Generic;

namespace Entitas {
    public partial class Entity {
        public PositionComponent position { get { return (PositionComponent)GetComponent(ComponentIds.Position); } }

        public bool hasPosition { get { return HasComponent(ComponentIds.Position); } }

        static readonly Stack<PositionComponent> _positionComponentPool = new Stack<PositionComponent>();

        public static void ClearPositionComponentPool() {
            _positionComponentPool.Clear();
        }

        EntityChanged cachedOnComponentRemoved {
            get {
                if (_cachedOnComponentRemoved == null) {
                    _cachedOnComponentRemoved = onComponentRemoved;
                }

                return _cachedOnComponentRemoved;
            }
        }

        EntityChanged _cachedOnComponentRemoved;

        public Entity AddPosition(float newX, float newY, float newZ) {
            OnComponentRemoved += cachedOnComponentRemoved;
            var component = _positionComponentPool.Count > 0 ? _positionComponentPool.Pop() : new PositionComponent();
            component.x = newX;
            component.y = newY;
            component.z = newZ;
            return AddComponent(ComponentIds.Position, component);
        }

        public Entity ReplacePosition(float newX, float newY, float newZ) {
//            var previousComponent = hasPosition ? position : null;
            var component = _positionComponentPool.Count > 0 ? _positionComponentPool.Pop() : new PositionComponent();
            component.x = newX;
            component.y = newY;
            component.z = newZ;
            ReplaceComponent(ComponentIds.Position, component);
//            if (previousComponent != null) {
//                _positionComponentPool.Push(previousComponent);
//            }
            return this;
        }

        public Entity RemovePosition() {
//            var component = position;
            RemoveComponent(ComponentIds.Position);
//            _positionComponentPool.Push(component);
            return this;
        }

        void onComponentRemoved(Entity entity, int index, IComponent component) {
            OnComponentRemoved -= cachedOnComponentRemoved;
            if (index == ComponentIds.Position) {
                _positionComponentPool.Push((PositionComponent)component);
            }
        }
    }

    public partial class Matcher {
        static IMatcher _matcherPosition;

        public static IMatcher Position {
            get {
                if (_matcherPosition == null) {
                    var matcher = (Matcher)Matcher.AllOf(ComponentIds.Position);
                    matcher.componentNames = ComponentIds.componentNames;
                    _matcherPosition = matcher;
                }

                return _matcherPosition;
            }
        }
    }
}

from entitas.

sschmid avatar sschmid commented on April 28, 2024

added onComponentRemoved

from entitas.

trumpets avatar trumpets commented on April 28, 2024

I found this article summarizing some garbage tests with events and delegates: http://jacksondunstan.com/articles/3264#comments and they confirm your findings. 104 bytes for creating a delegate and then another 208 bytes when adding that delegate to an event if it is the second+.

from entitas.

sschmid avatar sschmid commented on April 28, 2024

I could try writing a custom event system for Entitas. Might be (or not be) more efficient

from entitas.

sschmid avatar sschmid commented on April 28, 2024

I have an idea which works completely without events. An entity could have an array of stacks (similar to the array which holds the components). When removing a component it will get the stack at index and push the component. Done. If no stack exists, it doesn't (which means we're using entitas without the code generator)
I'll give it a try

from entitas.

sschmid avatar sschmid commented on April 28, 2024

fyi, I started writing tests for the existing generated component extensions. After that I will implement my idea test driven.

from entitas.

sschmid avatar sschmid commented on April 28, 2024

Ok, I found a way which works without events.
See PR #60

from entitas.

sschmid avatar sschmid commented on April 28, 2024

@trumpets @SvDvorak
If you like, you can test the latest version. Here are the zip files
fbfc99e

I'd be interested if it solves your issues. Let me know, if it works better now

from entitas.

sschmid avatar sschmid commented on April 28, 2024

See #60

from entitas.

SvDvorak avatar SvDvorak commented on April 28, 2024

A bit late but I checked through your solution, smart moving up the pools and creating a function to retrieve the correct one. Nicely done!

from entitas.

sschmid avatar sschmid commented on April 28, 2024

Thanks :)

from entitas.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.