flecs-hub / flecs-lua

Lua script host for flecs
MIT License
51 stars 9 forks source link

Systems #2

Closed randy408 closed 4 years ago

randy408 commented 4 years ago

My thoughts so far on how systems should work:

Some things that are not so obvious:

  1. If there are multiple systems registered from a state, how do we figure out which Lua system is supposed to run?

  2. Do we need a lua_State per system?

  3. Can we make multithreading work?

  4. How does it interact with host scripts that aren't modules/systems?

  5. Can we still make "simple" scripts work where sleep() is possible?

  6. Reloading script/systems is kinda important, what changes in flecs-lua would that require?

mo7sen commented 4 years ago

What I did so far:

This kind of guarantees that a LuaSystem imitates a flecs system as much as it could. However, I'm currently trying to find ways to:

Regarding multithreading, I don't think Lua has support for multithreading. As far as I know, we'd need to have multiple lua_States for this to be achievable

randy408 commented 4 years ago

Passing arrays without copying is premature optimization, I think the bigger problem is that if flecs-lua manages all the de/serialization everything will be a dumb table. It has to be aware which components need special metatables, e.g. vec3 + vec3 or scalar * vec3 should work as expected.

If we solve that efficiently we could make the columns special arrays, initially we could push the elements as-is on access and read back the pushed elements at the end.

There are many ways to do it which depend on the use case, which is why I don't want to get into it at this point, we could check for [in] for now.

The API needs some changes for multithreading, I'll have something ready soon.

mo7sen commented 4 years ago

A weird question. Would it be a bit dumb if we deviated a bit from the standard flecs API? What I have in mind is for the systems to work on each entity individually rather than on entire arrays. So the ecs_lua_entrypoint(..) would be something like this:

void ecs_lua_entrypoint(ecs_iter_t *it)
{
  for(int i = 0; i < it->count; ++i)
  {
    lua_rawgeti(L, LUA_REGISTRYINDEX, (long)(it->param));
    // TODO: Pass stuff
    lua_pcall(L, 0, 0, 0);
  }
}

instead of this:

void ecs_lua_entrypoint(ecs_iter_t *it)
{
  lua_rawgeti(L, LUA_REGISTRYINDEX, (long)(it->param));
  // TODO: Pass stuff
  lua_pcall(L, 0, 0, 0);
}

This way the lua system will be something like:

function move(position, velocity)
  position.x = position.x + velocity.x
  position.y = position.y + velocity.y
  return position, velocity
end

instead of having to loop in Lua itself.

randy408 commented 4 years ago

To make multithreading work flecs-lua could create states per-system and issue a callback for the host to de/initialize the state.

The registry would look like this:

ecs.system() CFunction:

I'm looking into the module API and how it could interact with scripts.

randy408 commented 4 years ago

What I have in mind is for the systems to work on each entity individually rather than on entire arrays.

There are situations where the opposite is preferable or even required, e.g. individual loops over with 2 components out of many one after the other, it's also possible to make API calls inside systems and create additional loops. Because this restricts access to just one cell of each column on each iteration it can't be made the default behavior.

mo7sen commented 4 years ago

What I have in mind is for the systems to work on each entity individually rather than on entire arrays.

There are situations where the opposite is preferable or even required, e.g. individual loops over with 2 components out of many one after the other, it's also possible to make API calls inside systems and create additional loops. Because this restricts access to just one cell of each column on each iteration it can't be made the default behavior.

Yeah, makes sense. I was just thinking about how that would give a new level of parallelism in the systems, but it does seem to be quite limiting.

randy408 commented 4 years ago

This is a solved problem at this point. multithreading is tracked by #3.