#2275·flecs

Add context support to query `order_by` callbacks

Author: rashton-snlCreated Sep 2, 2026Updated Sep 2, 2026
Labelsenhancement

I’m working on Python bindings for Flecs. I would like to support Python callbacks for query sorting:

python
def compare_depth(e1, d1, e2, d2):
    return (d1.value > d2.value) - (d1.value < d2.value)

q = (
    world.query_builder()
    .with_(Position)
    .with_(Depth)
    .order_by(Depth, compare_depth)
    .build()
)

To implement this binding, I need to register an order_by_callback trampoline that calls the Python function. In order to recover the Python function, the trampoline function needs a way to recover a per-query binding context:

c
int order_by_trampoline(
    ecs_entity_t e1,
    const void *ptr1,
    ecs_entity_t e2,
    const void *ptr2,
    void *binding_ctx)
{
    // Use binding_ctx to find the Python callback.
    // Convert ptr1 & ptr2 to Python objects.
    // Call Python.
    // Return comparison result.
}

Currently ecs_order_by_action_t does not receive a context pointer:

c
typedef int (*ecs_order_by_action_t)(
    ecs_entity_t e1,
    const void *ptr1,
    ecs_entity_t e2,
    const void *ptr2);

Proposed changes

I think that you could mirror group_by_callback, which receives group_by_ctx:

c
typedef int (*ecs_order_by_action_t)(
    ecs_entity_t e1,
    const void *ptr1,
    ecs_entity_t e2,
    const void *ptr2,
    void *ctx);

ecs_query_desc_t would need order-by context fields:

c
void *order_by_ctx;
ecs_ctx_free_t order_by_ctx_free;

(Though for my purposes, I think that the existing binding_ctx field would work just as well?)

The call site would need to be updated:

c
compare(e1, ptr1, e2, ptr2, cache->order_by_ctx)