Coder Social home page Coder Social logo

ecx's People

Contributors

eliasku avatar glidias avatar ilya-ku avatar mangelmaxime avatar sh-dave avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ecx's Issues

How to reset world?

Any documented way to try and reset the world by removing all entities and being able to recreate them again?

I tried something like this....but doesn't seem to work.

public function end():Void {
	
	for ( i in 1..world.capacity ){  // somehow, re-creating new entities after this doesn't work?
		world.destroy( world.getEntity(i));
	}
	world.invalidate();  // this is needed?
}

Also, how to add/remove Systems? Based on the architecture of ECX, i'd assume you have to set the system flags to use SystemFlags.IDLE or not, right? But how to do this dynamically at runtime since the _systemFlags is private?

Optional Family Components

Greeting @eliasku !

I am having fun with ecx, and this is my first experience with such frameworks.

I've read that a Family's components may be optional. Is this something that one must specify (if so how)? Or does the internal machinery gather into a Family all entities that may have one or more of the specified Family components?

Second, is it fair to assume that I need not create a Family when I'm looking to update entities in the context of a single component? I've seen in ecx-scene2d, that you simply Wire in the component and iterate over _dirtyVector. Is there much to gain over using a Family of a single component? (Edit: Nevermind, read through the custom Transform component).

Thank you,
Brad

ecx.ds.* as separate library?

I'm sniffing your codebase because I want to find where the speed comes from : )
The ecx.ds.* package looks very useful for general use, and was wondering if there are any plans on releasing it as a separate ds package?

How to add/remove Systems?

Also, how to add/remove Systems? Based on the architecture of ECX, i'd assume you have to set the system flags to use SystemFlags.IDLE or not, right? But how to do this dynamically at runtime since the _systemFlags is private?

System iterates over non-matching entities

Hi! I moved my project to current ecx dev version, but I encountered a bug (or misunderstood something):
https://github.com/Misiur/ECXRemoval

Basically when removing a component from an entity, systems still iterate over that entity causing errors.

Secondary question: shall I use world.commit everytime I fiddle around with an entity (creating, adding components, removing components, destroying entity), or only when creating it? (I tried adding it for problem I described, but nothing changed)

I can run ecx-asteroids without any problems, and I didn't encounter that problem there - even though I see you are using #remove in state machine callbacks. I was wrong: when you ram an asteroid, you'll get

Is it legal to use Primitive data types T directly for AutoComp?

Trying something out "funky", to avoid using an object/class wrapper to hold primitive data, but store data entirely as a non-object-based data type in array if it only consist of 1 field, in order to save memory.

class AgeTest extends AutoComp<String> {}
class AgeTest2 extends AutoComp<Float> {}

At the cost of a bit more initialization boilerplate.

 // in some entity creation function... entity = world.create();
	_ageTest.create(entity);
	_ageTest.set(entity, "Default");
	_ageTest2.create(entity);
	_ageTest2.set(entity, 5);

And in some system processing...

var  ageTest2:Float = _ageTest2.get(entity);
_ageTest2.set(entity, ageTest2-=dt);

Would be considered ok, right? I tested it on Asteroids. Compiles fine. Runs fine.


BTW, I even tested with Age extends AutoComp<Int>. There was an error because you did not support Int, so I made some changes...and also hooked it up to ds CInt32Array instead (counting in ms integers instead so i -=Std.int(dt*1000)) instead. From my Asteroid test, it appears fine and works as per normal., which would be good as it'll make use of CInt32Array which JS target takes advantage of as well.

The change i made to support primitive Int/UInt.. (seemed that you missed out "Int"/"Uint" primitives?? I saw you have "Float").
Glidias@1985603

Not sure about the repucussions if I use CInt32Array to cover UInt data types though, even thoughit runs fine as far as the compiler is concerned. Of course, UInt will have different implications value/result-wise.. I'm not too sure about this..... (scratches head..)

Primary Targets and Frameworks

Hi All,
What targets you use with ecx or hotmem? What game Frameworks?
Please share! I plan reduce supported targets implementations and tests.
For example maybe it's time to drop swf target. Totally no sense to support python and neko targets.
Thank you in advance

Can't destroy entities

Minimal reproduction:

package;

import ecx.common.EcxCommon;
import ecx.WorldConfig;
import ecx.World;
import ecx.Entity;
import ecx.Engine;

class Main
{
	private var _world:World;

	public static function main() {
		new Main();
	}

	public function new() {
		var config = new WorldConfig();

		_world = Engine.createWorld(config);

		var world = _world;
		var entity = world.create();
		world.commit(entity);
		world.invalidate();

		world.destroy(entity);
		world.invalidate();
	}
}
TypeError: Cannot read property 'has' of null
    at ecx_World.destroyComponents (main.js:791:17)
    at ecx_World.destroyEntities (main.js:863:10)
    at ecx_World.invalidate (main.js:754:9)
    at new Main (main.js:141:8)
    at Function.Main.main (main.js:146:2)
    at main.js:3589:6

When there are more than 0 components the componentsData for some reason contains null on second to last slot. I will dig some more, but maybe it's something obvious. Thanks

How to run this thing, and usage of `World#invalidate`

This might be a silly question, but I reread whole test folder and ecx benchmark code, yet I can't find the answer: How to run this thing? So far I met two types of ECS:

  1. Use world.run(), we'll take care of framerate and stuff.
  2. Create your own game loop, then put in world.update() and we'll take care of updating the systems.

I can see there is world._systems, but it's only used in WorldConstructor#initializeSystems.

The second question: when to use World#invalidate? When I add a component to an entity? When I add/remove entity from the world?

Thank you.

Duplicate metadata 'systems'

This happens occasionally depending on what frameworks you're working with. It is definitely related to this library, and could be related to macro changes in haxe 4. Currently running haxe 4 rc 3

Compilation issues with haxe4

Hi, trying to build some simple project with haxe 4 currently fails. A sample repo is available here.

haxe 4 preview 4

libs/ecx/src/ecx/macro/SystemBuilder.hx:12: characters 23-46 : Uncaught exception Cannot call null

haxe 4 latest git

libs/ecx/src/ecx/macro/SystemBuilder.hx:111: characters 30-35 : Uncaught exception Unbound variable
libs/ecx/src/ecx/macro/SystemBuilder.hx:36: characters 21-41 : Called from here
libs/ecx/src/ecx/macro/SystemBuilder.hx:25: characters 3-41 : Called from here

Typecompletion issue with Haxe 3.4

Haxe 3.3 doesn't have this issue. Looks like type-completion is completely broken in Haxe 3.4. You have to use Haxe 3.3 for now.

In Haxe 3.4, eg. var gun = _gun.get(entity);
Accessing any of the items like _gun. or gun. yields a vomit/rubbish typehinting list output of all Haxe's compile time metadata fields in alphabetical order.

eg. @:abi, @:abstract, @:access ......@:volatile
No relavant typehinting information is shown.

BTW, I encountered a similar issue with my framework HaxeVx before (between Haxe 3.3 and Haxe 3.4). I did a change for my framework some time ago that fixed this similar-looking issue Glidias/haxevx@5c15f58 , but for your case, it might be different, as I absolutely do not know the underlying cause of this issue.

BTW, the commit description is wrong (it has nothing to do with :keep, any metadata name will also trigger it), as I didn't know the cause of the issue. I just removed something off to avoid the problem altogether. It appears (on further investigation) like I couldn't add a build field's metadata annotation whose position pos:... is set to Context.getLocalClass().get().pos (using something like Context.currentPos) is fine. Note, however,, for mine case, what happens is that it shows the correct type-hinting initially, then after some lag time, it kills off the typehinting and spills out the rubbish @: metadata list. For your case, it happens immediately. Not sure if that difference matters or not.. Your case is likely to be entirely different as I don't see any explicit cases similar to mine in your codebase, and I removed the meta: reference in FieldsBuilder.as, but it doesn't change anything.

NOTE: For your case, the typehinting issue seems to ONLY occur inside the override function update() method of a given System. If placed anywhere else, (eg. _gun.) in constructor of class, it's fine, for example. Weird! What's so special about update()??

update while updating

I encountered a rather cryptic error:

D:/Dev/ecx-dev/src/ecx/macro/AutoCompBuilder.hx:190: No copy for: TInst(phys.component.MovementCollisionData,[])
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-0 spec-0 phys.component.MovementCollision
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:31: > [C] #0 phys.component.MovementCollision
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-1 spec-1 phys.system.ShadowPositionSystem
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-2 spec-2 phys.system.MovementSystem
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-3 spec-3 phys.system.CollisionPositionSystem
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-4 spec-4 phys.system.BulletCollisionSystem
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-5 spec-5 EntityCreator
D:/Dev/ecx-dev/src/ecx/macro/AutoCompBuilder.hx:190: No copy for: TInst(phys.component.BulletCollisionData,[])
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-6 spec-6 phys.component.BulletCollision
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:31: > [C] #1 phys.component.BulletCollision
D:/Dev/ecx-dev/src/ecx/macro/AutoCompBuilder.hx:190: No copy for: TInst(gameplay.component.LifeData,[])
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-7 spec-7 gameplay.component.Life
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:31: > [C] #2 gameplay.component.Life
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-8 spec-8 gameplay.system.DelayedBulletSystem
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-9 spec-9 gameplay.system.BulletAgeSystem
D:/Dev/ecx-dev/src/ecx/macro/AutoCompBuilder.hx:190: No copy for: TInst(gameplay.component.BulletData,[])
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-10 spec-10 gameplay.component.Bullet
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:31: > [C] #3 gameplay.component.Bullet
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-11 spec-11 input.system.WeaponControlSystem
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-12 spec-12 input.Input
D:/Dev/ecx-dev/src/ecx/macro/AutoCompBuilder.hx:190: No copy for: TInst(input.component.WeaponControlsData,[])
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-13 spec-13 input.component.WeaponControls
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:31: > [C] #4 input.component.WeaponControls
D:/Dev/ecx-dev/src/ecx/macro/AutoCompBuilder.hx:190: No copy for: TInst(gameplay.component.DelayedBulletData,[])
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-14 spec-14 gameplay.component.DelayedBullet
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:31: > [C] #5 gameplay.component.DelayedBullet
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-15 spec-15 input.system.MotionControlSystem
D:/Dev/ecx-dev/src/ecx/macro/AutoCompBuilder.hx:190: No copy for: TInst(input.component.MotionControlsData,[])
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-16 spec-16 input.component.MotionControls
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:31: > [C] #6 input.component.MotionControls
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-17 spec-17 input.system.InventoryControlSystem
D:/Dev/ecx-dev/src/ecx/macro/AutoCompBuilder.hx:190: No copy for: TInst(gameplay.component.WeaponData,[])
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-18 spec-18 gameplay.component.Weapon
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:31: > [C] #7 gameplay.component.Weapon
D:/Dev/ecx-dev/src/ecx/macro/AutoCompBuilder.hx:190: No copy for: TInst(gameplay.component.ShipData,[])
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-19 spec-19 gameplay.component.Ship
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:31: > [C] #8 gameplay.component.Ship
D:/Dev/ecx-dev/src/ecx/macro/AutoCompBuilder.hx:190: No copy for: TInst(input.component.InventoryControlsData,[])
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-20 spec-20 input.component.InventoryControls
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:31: > [C] #9 input.component.InventoryControls
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-21 spec-21 display.system.SailPositionSystem
D:/Dev/ecx-dev/src/ecx/macro/AutoCompBuilder.hx:190: No copy for: TInst(gameplay.component.SailData,[])
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-22 spec-22 gameplay.component.Sail
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:31: > [C] #10 gameplay.component.Sail
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-23 spec-23 effect.system.ShadowSystem
D:/Dev/ecx-dev/src/ecx/macro/AutoCompBuilder.hx:190: No copy for: TInst(effect.component.ShadowData,[])
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-24 spec-24 effect.component.Shadow
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:31: > [C] #11 effect.component.Shadow
D:/Dev/ecx-dev/src/ecx/macro/AutoCompBuilder.hx:190: No copy for: TInst(effect.component.DropsShadowData,[])
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-25 spec-25 effect.component.DropsShadow
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:31: > [C] #12 effect.component.DropsShadow
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-26 spec-26 core.system.EnterFrameSystem
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-27 spec-27 ai.system.PatrolSystem
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-28 spec-28 ai.system.FollowSystem
D:/Dev/ecx-dev/src/ecx/macro/AutoCompBuilder.hx:190: No copy for: TInst(phys.component.MotionData,[])
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-29 spec-29 phys.component.Motion
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:31: > [C] #13 phys.component.Motion
D:/Dev/ecx-dev/src/ecx/macro/AutoCompBuilder.hx:190: No copy for: TInst(ai.component.FollowerData,[])
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-30 spec-30 ai.component.Follower
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:31: > [C] #14 ai.component.Follower
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-31 spec-31 util.ShapeDebug
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-32 spec-32 util.FPS
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-12 spec-33 input.Keyboard : input.Input
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-33 spec-34 core.GameConfig
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-34 spec-35 display.system.Renderer
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-35 spec-36 gameplay.system.GameManagerSystem
D:/Dev/ecx-dev/src/ecx/macro/AutoCompBuilder.hx:190: No copy for: TInst(gameplay.component.GameStateData,[])
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-36 spec-37 gameplay.component.GameState
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:31: > [C] #15 gameplay.component.GameState
D:/Dev/ecx-dev/src/ecx/macro/AutoCompBuilder.hx:190: No copy for: TInst(ai.component.PatrollingData,[])
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-37 spec-38 ai.component.Patrolling
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:31: > [C] #16 ai.component.Patrolling
D:/Dev/ecx-dev/src/ecx/macro/AutoCompBuilder.hx:190: No copy for: TInst(display.component.RenderData,[])
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-38 spec-39 display.component.Render
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:31: > [C] #17 display.component.Render
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-39 spec-40 ecx.common.systems.TimeSystem
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-40 spec-41 ecx.common.systems.SystemRunner
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-41 spec-42 ecx.common.systems.FsmSystem
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-42 spec-43 ecx.common.systems.FpsMeter
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-43 spec-44 ecx.common.components.Name
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:31: > [C] #18 ecx.common.components.Name
D:/Dev/ecx-dev/src/ecx/macro/AutoCompBuilder.hx:190: No copy for: TInst(ecx.common.components.FsmData,[])
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:23: > (S) type-44 spec-45 ecx.common.components.Fsm
D:/Dev/ecx-dev/src/ecx/macro/MacroBuildDebug.hx:31: > [C] #19 ecx.common.components.Fsm
update while updating
    at ecx::World/changeEntities()[D:/Dev/ecx-dev/src/ecx/World.hx:371]
    at ecx::World/invalidate()[D:/Dev/ecx-dev/src/ecx/World.hx:165]
    at ecx.common.systems::SystemRunner/updateFrame()[D:/Dev/ecx-common/src/ecx/common/systems/SystemRunner.hx:38]
    at core.system::EnterFrameSystem/onEnterFrame()[Source/core/system/EnterFrameSystem.hx:22]
imm1
    at ecx.types::FamilyData/debugLock()[D:/Dev/ecx-dev/src/ecx/types/FamilyData.hx:100]
    at ecx.managers::WorldDebug$/lockFamilies()[D:/Dev/ecx-dev/src/ecx/managers/WorldDebug.hx:28]
    at ecx::World/invalidate()[D:/Dev/ecx-dev/src/ecx/World.hx:160]
    at ecx.common.systems::SystemRunner/updateFrame()[D:/Dev/ecx-common/src/ecx/common/systems/SystemRunner.hx:35]
    at core.system::EnterFrameSystem/onEnterFrame()[Source/core/system/EnterFrameSystem.hx:22]

It appears when I create a new entity in OnEntityAdded of some another system. I can't reproduce it in clean repository. world.create() is all it takes, even with comented out world.commit and component adding code it happens. Any ideas how can I debug it further?

Mb. strict type-check is better there?

I mean this workaround:

public function addComponent<T:Component>(entity:Entity, component:T, type:ComponentType):T {
    // workaround for old hxcpp
    var comp:Component = component;
    components[type.id][entity.id] = comp;

I don't know why and for what it but if it needed I think strict type-check will better there:

    components[type.id][entity.id] = (component : Component);

What do you think? ;)

Prevent using Family<> in services

I recently stumbled upon the following, when i defined a Family in a Service by accident (should have been a System), the field was never was initialized and accessing it crashed. It would be nice if the compiler could prevent that from happening and issue a warning or error.

Architectural Issues with Data storage and Memory Usage

From what i've observed with the framework, every component service holds it's own array which points to it's component data for the given entity slot. However, because the Array is treated as a Dense Array implementation, it ends up containing many null or 0 spots because various entities of different indices, do not necessarily have all the components, only some of it.

Wouldn't this consume a lot more memory compared to other regular Entity-bag based frameworks? I mean, I checked like: trace(_gunControls.data); in Asteroids example EntityCreator, and i see a large array with the 1st entity having gun controls, but all the other subsequent slots being null slots....Isn't this wasteful memory usage over empty slots?

Anyway of looking into the design such that an entity within a given component service context, may hold a different index under each component service? Then, you can do some pop-back strategies and truncate the array for each component service, to clean up the sparse empty gaps in between and therefore pack it for dense storage?. Not too sure....just saying it off my head.

World invalidate not having any effect

It seems that when doing world.invalidate nothing gets updated immediately, I have to manually add _component.has(entity) checks in systems to make sure component was removed. Any ideas how to circumvent this?

Custom component storage

Currently it seems that components must be allocated on the heap and a pointer is stored, this is bad for cache, which really only matters in tight loops, but I've always implemented my ECS's by having the Component parent class be something like ComponentStorage or so, and the subclass defines however they wish to store it, such as a tightly-packed array for components that are common, like Position2Df, or a sparse array for a quadtree component, a hash-map for rare components, pointers, etc..., or whatever other structure is appropriate.

A single ComponentStorage may store multiple useful things, for example I often have Position2Df (actually a full transformation) as well as physics information all in the same storage as it makes for extremely fast vectorization paths (can process a million moving positions in 60fps if made properly) and lookups in systems are more like this (in ecx'ish syntax):

class MovementSystem extends System {
    var _tp:Wire<TransPhyStorage>;
    var _entities:Family<Transform, Node, Renderable>;
    ...
    override function update() {
        // Note: typeof _entities in my systems is usually something like SortedSet<Entity>
        for(entity in _entities) {
            var trans = _tp.getTransformation(entity);
            var phys = _tp.getPhysics(entity);
            // do stuff
        }
    }
}

Or in that above specific case I often do not bother keeping a family at all and just vectorized operate over the entire packed array of transformation and physics data, which is exceedingly fast, and the few entities that do not have such components are so rare and the vectorized throughput so fast that it has never even gotten close to mattering.

This would flip the calls of things like

views[i].create(EcxPosition1).randomize();

To become like:

ecxPosition1.randomize(entity);

As you cannot have a unified method of accessing a component as each storage can do things in their own unique ways (unless you have something like a generic 'get' that returns the entire structure as a 'view' object to modify, but it is heavy-weight and I've not used that style in years, component access is necessarily dependent on the component and not generic, no point trying to hide that). I also find this access far more logical as well as every component can be thought of as an array (regardless of how it is internally) and you are just indexing into the array with the entity as the index value.

Thus have you thought of a style more like this? Where you still have Family, but you can Wire up storages to components instead of passing pointers all over the place, thus allowing for tightly packed storage in cases where it matters? You could even keep the current Component pointer API built on top of that model with potentially other subclasses of ComponentStorage (like ComponentArray, ComponentMap, ComponentSparseArray, etc...) that people could use to build off of to reduce the boilerplate?

References:

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.