Giter Club home page Giter Club logo

Comments (10)

redxdev avatar redxdev commented on August 30, 2024

I'm not sure I like the idea of having a singleton entity as part of this library. You can easily implement that without touching the library code by creating an entity and storing it wherever you store the World object.

from ecs.

hongjiang-ye avatar hongjiang-ye commented on August 30, 2024

I did that before and definitely it worked, but I had to access them as the other non-singleton components by methods like world->each<T>, which made the code untidy. If your library could provide the simple 'get' and 'create' APIs, I need not to implement it in by creating an entity only for singletons.

I'm only a student, and I'm not dare to change your codes at low level. I just told you what I need to see whether you would like to implement it.

from ecs.

redxdev avatar redxdev commented on August 30, 2024

If you do it the way I suggested:

// These should be stored somewhere accessible
World* myWorld = World::createWorld();
Entity* mySingletonEntity = myWorld->create();
mySingletonEntity->assign<SomeComponent>();

You can access components on mySingletonEntity freely via Entity::get<T>():

ComponentHandle<SomeComponent> someComponent = mySingletonEntity->get<SomeComponent>();

// alternatively, use auto:
auto someComponent = mySingletonEntity->get<SomeComponent>();

Assuming you store mySingletonEntity in a place that's globally accessible (or at least accessible to anything that would otherwise be able to access the world), then you effectively have what you are asking for already.

from ecs.

hongjiang-ye avatar hongjiang-ye commented on August 30, 2024

Yeah I did that like:

Entity* singletons = world->create();
singletons->assign<CameraInfoSingletonComponent>();

In systems' tick:

virtual void tick(class World* world, float deltaTime) override {
    world->each<CameraInfoSingletonComponent>([&](Entity* ent, ComponentHandle<CameraInfoSingletonComponent> cameraCHandle) -> void {
        // do something with cameraCHandle...
    });
}

It works, just not neat. Actually there's only one CameraInfoSingletonComponent but it seems like there are many and I do something with all of them by world->each.

If I could do that like this, my team members could easily know that there's only one CameraInfoSingletonComponent.

virtual void tick(class World* world, float deltaTime) override {
    auto cameraCHandle = world->getSingletonComponent<CameraInfoSingletonComponent>();
    // do something with cameraCHandle...
}

from ecs.

hongjiang-ye avatar hongjiang-ye commented on August 30, 2024

You are right, it's not necessary, just few more lines. Feel free to close this issue.

from ecs.

redxdev avatar redxdev commented on August 30, 2024

I do suggest considering other options. world->each is not fast for trying to look up a single object. I highly recommend storing your singleton entity somewhere (maybe pass it into the system's constructor and have a field on the system to store it?) and then avoiding world->each altogether.

Closed.

from ecs.

zmj1316 avatar zmj1316 commented on August 30, 2024

What about a signature matching system? When a component is added or removed, use a container to trance the component, so the system can loop over the container instead of all the entities on each tick.
Should this be implemented by the framework or my own system?

from ecs.

redxdev avatar redxdev commented on August 30, 2024

I'm not quite sure what you mean, can you give an example?

from ecs.

zmj1316 avatar zmj1316 commented on August 30, 2024

For example, when I try to loop over entities with SomeComponent1 and SomeComponent2 using this:

    world->each<SomeComponent1,SomeComponent2>(...)

and there are very few entities having these components, so I don't want to loop over all the entities to get the result due to low performance.
Instead I want to maintain a container to record the entities that matching the rules by listening on the component add/remove events. And use this

    for(auto pair : world->component_recorder_SomeComponent1_SomeComponent2)
        do some thing with pair ........

The question is, should this done by the framework itself or an extra system based on the framework?

from ecs.

redxdev avatar redxdev commented on August 30, 2024

I suggest creating a new issue, what you are asking for doesn't have anything to do with singleton components. I'm going to lock this issue but feel free to open a new one with your idea.

As for the idea itself, yes world::each<> could be optimized to do a lookup on something like multimap<TypeIndex, Entity*> rather than iterating every single entity. There'd have to be some work done to notify the world whenever a component is created or destroyed, and there'd be an additional memory cost to the map.

Additionally, if you request multiple components then you'd still pay the cost of iterating entities (albeit a smaller set than the entire world) or you'd have to do a union of each set of entities with one of the requested components. I'm not convinced that in general this operation would be fast.

The last option would be to have some sort of structure you can register with the world that always contains a list of all entities with specified components - something like EntityContainer<MyComponent1, MyComponent2> could have an internal store that keeps an up-to-date list of all entities with MyComponent1 and MyComponent2. The upside is that it'd be fast for iteration and you'd only pay the costs of having such a system if you actually needed it. You could create containers for any common groups of components. The downside is that the world would now have to track a list of containers and there will be some overhead involved with creating and deleting components since each container would have to update its own internal list.

I think out of the options, I prefer the last one but I don't know if I'll get around to implementing it or not. Anyway, create a new issue if you're interested and hopefully I'll get to it or someone else will.

from ecs.

Related Issues (8)

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.