Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Query DSL - ECS_SYSTEM : [out] pair in empty entity with Sync Point #1066

Closed
Felecarpp opened this issue Oct 31, 2023 · 1 comment
Closed
Labels
enhancement New feature or request

Comments

@Felecarpp
Copy link

Hello, I'm new to C and flecs. I would like to create a sync point between two systems using a relationship tag. I succeeded with the C binding for query building but I failed with the DSL.
Here is a restricted example : the first system create a new pair (DockedTo, earth) and the second system query (DockedTo, *). The goal is to have a sync point so the both systems must write a message in sdtout in the same round.

#include <stdio.h>
#include "flecs.h"

typedef struct { int instant, maximum; } Condition;

ECS_TAG_DECLARE(DockTo);
ECS_TAG_DECLARE(DockedTo);
ECS_COMPONENT_DECLARE(Condition);

/* Dock a Docking spaceship to its target */
void Docking(ecs_iter_t *it) {
    ecs_world_t *ecs = it->world;
    ecs_entity_t target = ecs_pair_second(ecs, ecs_field_id(it, 1));

    for (int i = 0; i < it->count; i++) {
        ecs_entity_t spaceship = it->entities[i];
        ecs_remove_pair(ecs, spaceship, DockTo, target);
        ecs_add_pair(ecs, spaceship, DockedTo, target);
        printf("spaceship dock to %lu\n", target);
    }
}

/* Repair a Docked spaceship */
void Repair(ecs_iter_t *it) {
    Condition *p = ecs_field(it, Condition, 1);

    for (int i = 0; i < it->count; i++) {
        if(p[i].instant < p[i].maximum)
            p[i].instant += 2;
        if(p[i].instant > p[i].maximum)
            p[i].instant = p[i].maximum;
        printf("spaceship repaired to %d/%d\n", p[i].instant, p[i].maximum);
    }
}


int main(int argc, char *argv[]) {
    ecs_world_t *ecs = ecs_init_w_args(argc, argv);

    ECS_TAG_DEFINE(ecs, DockTo);
    ECS_TAG_DEFINE(ecs, DockedTo);
    ECS_COMPONENT_DEFINE(ecs, Condition);

    ecs_system(ecs, {
        .entity = ecs_entity(ecs, {
             .name = "Docking",
             .add = { ecs_dependson(EcsOnUpdate) },
         }),
         .query.filter.terms = {
             {
                 .inout = EcsIn,
                 .id = ecs_pair(DockTo, EcsWildcard),
             },
             {
                 .inout = EcsOut,
                 .id = ecs_pair(DockedTo, EcsWildcard),
                 .src.flags = EcsIsEntity,
                 .src.id = 0,
             },
         },
         .callback = Docking,
    });
    ECS_SYSTEM(ecs, Repair, EcsOnUpdate, [in] Condition, [in] (DockedTo, *));

    ecs_entity_t spaceship = ecs_new_id(ecs);
    ecs_entity_t earth = ecs_new_id(ecs);

    ecs_set(ecs, spaceship, Condition, {4, 16});
    ecs_add_pair(ecs, spaceship, DockTo, earth);
    
    ecs_progress(ecs, 1);
    
    return ecs_fini(ecs);
}
$ cc main.c flecs.c -o spaceship
$ ./spaceship
spaceship dock to 533
spaceship repaired to 6/16

This works well. But I'd like to do the same with the DSL to save a few lines in the source code. I replaced the ecs_system call by ECS_SYSTEM(ecs, Docking, EcsOnUpdate, [in] (DockTo, *), [out] (DockedTo, *)); but I get an error :

error: Docking: expected end of expression or next term
[in] (DockTo, *), [out] (DockedTo, *)()
                                     ^
fatal: flect_test.c: 44: assert: ecs_id(Docking) != 0 INVALID_PARAMETER             
./spaceship(+0x3b86b) [0x5579fe2ff86b]                                                                                                   
./spaceship(+0x62602) [0x5579fe326602]
./spaceship(+0x13377) [0x5579fe2d7377]
./spaceship(+0xaf33) [0x5579fe2cef33]                                                                                                    
./spaceship(+0x2b14) [0x5579fe2c6b14]
/usr/lib/libc.so.6(+0x27cd0) [0x7ff7c48d7cd0]
/usr/lib/libc.so.6(__libc_start_main+0x8a) [0x7ff7c48d7d8a]
./spaceship(+0x2505) [0x5579fe2c6505]
Abandon (core dumped)

I conclude this syntax do not exist. But just I mixed a syntax from the documentation with relationships so I do not understand why.
https://www.flecs.dev/flecs/md_docs_Systems.html#autotoc_md290

[ECS_SYSTEM](world, SetTransform, EcsOnUpdate, Position, [out] Transform());

Is there a DSL syntax to do this ?

@Felecarpp Felecarpp added the enhancement New feature or request label Oct 31, 2023
@SanderMertens
Copy link
Owner

The correct DSL syntax for this is:

[out] DockedTo(0, *)

The reason for this is that (Foo, Bar) is short for Foo($this, Bar), where $this is a builtin variable that represents the entity on which components got matched. Replacing that with 0 is equivalent to what happens in the C API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants