.. _stdlib_decs_boost: ====================== Boost package for DECS ====================== .. das:module:: decs_boost The DECS_BOOST module provides convenience macros and syntactic sugar for the DECS entity component system, including simplified component registration, entity creation, and system definition patterns. See also :doc:`decs` for the core ECS runtime and :doc:`decs_state` for entity state machines. See :ref:`tutorial_decs` for a hands-on tutorial. All functions and symbols are in "decs_boost" module, use require to get access to it. .. code-block:: das require daslib/decs_boost Example: .. code-block:: das options persistent_heap = true require daslib/decs_boost [export] def main() { restart() create_entity() @(eid, cmp) { cmp |> set("pos", float3(1, 2, 3)) cmp |> set("name", "hero") } commit() query() $(pos : float3; name : string) { print("{name} at {pos}\n") } } // output: // hero at 1,2,3 ++++++++++++++++++++ Function annotations ++++++++++++++++++++ .. _handle-decs_boost-decs: .. das:attribute:: decs This macro converts a function into a DECS pass stage query. Possible arguments are `stage`, `REQUIRE`, and `REQUIRE_NOT`. It has all other properties of a `query` (like ability to operate on templates). For example:: [decs(stage=update_ai, REQUIRE=ai_turret)] def update_ai ( eid:EntityId; var turret:Turret; pos:float3 ) ... In the example above a query is added to the `update_ai` stage. The query also requires that each entity passed to it has an `ai_turret` property. .. _handle-decs_boost-REQUIRE: .. das:attribute:: REQUIRE This annotation provides list of required components for entity. .. _handle-decs_boost-REQUIRE_NOT: .. das:attribute:: REQUIRE_NOT This annotation provides list of components, which are required to not be part of the entity. +++++++++++ Call macros +++++++++++ .. _call-macro-decs_boost-find_query: .. das:attribute:: find_query This macro implements `find_query` functionality. It is similar to `query` in most ways, with the main differences being: * there is no eid-based find query * the find_query stops once the first match is found For example:: let found = find_query() $ ( pos,dim:float3; obstacle:Obstacle ) { if (!obstacle.wall) { return false } let aabb = [[AABB min=pos-dim*0.5, max=pos+dim*0.5 ]] if (is_intersecting(ray, aabb, 0.1, dist)) { return true } return false } In the example above the find_query will return `true` once the first intersection is found. Note: if return is missing, or end of find_query block is reached - its assumed that find_query did not find anything, and will return false. .. _call-macro-decs_boost-query: .. das:attribute:: query This macro implements `query` functionality. There are 2 types of queries: * query(...) - returns a list of entities matching the query * query(eid) - returns a single entity matching the eid For example:: query() $ ( eid:EntityId; pos, vel : float3 ) { print("[{eid}] pos={pos} vel={vel}\n") } The query above will print all entities with position and velocity. Here is another example:: query(kaboom) $ ( var pos:float3&; vel:float3; col:uint=13u ) { pos += vel } The query above will add the velocity to the position of an entity with eid kaboom. Query can have `REQUIRE` and `REQUIRE_NOT` clauses:: var average : float3 query <| $ [REQUIRE(tank)] ( pos:float3 ) average += pos The query above will add `pos` components of all entities, which also have a `tank` component. Additionally queries can automatically expand components of entities. For example:: [decs_template(prefix="particle")] struct Particle pos, vel : float3 ... query $ ( var q : Particle ) { q.pos += q.vel // this is actually particlepos += particlevel } In the example above structure q : Particle does not exist as a variable. Instead it is expanded into accessing individual components of the entity. REQURE section of the query is automatically filled with all components of the template. If template prefix is not specified, prefix is taken from the name of the template (would be ``Particle_``). Specifying empty prefix `[decs_template(prefix)]` will result in no prefix being added. Note: apart from tagging structure as a template, the macro also generates `apply_decs_template` and `remove_decs_template` functions. `apply_decs_template` is used to add template to an entity, and `remove_decs_template` is used to remove all components of the template from the entity:: for i in range(3) create_entity <| @ ( eid, cmp ) apply_decs_template(cmp, [[Particle pos=float3(i), vel=float3(i+1)]]) .. _call-macro-decs_boost-from_decs: .. das:attribute:: from_decs This macro converts a DECS query into an iterator>. For example:: let it = from_decs($(index:int; text:string){}) for (item in it) { // process item print("Entity {item.index}: {item.text}\n") } Internally it generates the following code:: let it = invoke($() { var res : array> query($(index:int; text:string) { res |> push((index, text)) }) return res.to_sequence() ++++++++++++++++ Structure macros ++++++++++++++++ .. _handle-decs_boost-decs_template: .. das:attribute:: decs_template This macro creates a template for the given structure. The following functions are generated for the structure type: * ``apply_decs_template(cmp, src)`` — sets components via ComponentMap * ``remove_decs_template(cmp, src)`` — removes components from ComponentMap * ``apply_decs_template_arch(arch, eidx, eid, src)`` — writes directly into archetype storage * ``create_entities`T(count, blk)`` — bulk creation with direct archetype writes