Skip to content

Instantly share code, notes, and snippets.

@ArnCarveris
Last active September 30, 2019 09:13
Show Gist options
  • Save ArnCarveris/f2cfdb11eb8e837987d04ce4f2f60214 to your computer and use it in GitHub Desktop.
Save ArnCarveris/f2cfdb11eb8e837987d04ce4f2f60214 to your computer and use it in GitHub Desktop.
flecs sandbox draft
#include "flecs_backup.h"
typedef uint32_t ecs_type_index_t;
bool ecs_type_next_index(ecs_type_t type, ecs_entity_t mask, ecs_type_index_t* index)
{
ecs_entity_t *array = (ecs_entity_t *)ecs_vector_first(type);
ecs_type_index_t count = ecs_vector_count(type);
for (ecs_type_index_t i = count - 1 - index[0]; i >= 0; i --) {
if (array[i] & mask) {
index[0] = i;
return true;
}
}
return false;
}
ecs_entity_t ecs_new_backup(ecs_world_t *world, ecs_entity_t entity)
{
ecs_type_t type = ecs_get_type(world, entity);
ecs_entity_t backup = _ecs_new(world, type);
ecs_inherit(world, entity, backup);
ecs_inherit(world, backup, entity);
ecs_add(world, backup, EcsDisabled);
//ecs_remove(world, backup, EcsId);
return backup;
}
void ecs_store_backup(ecs_world_t *world, ecs_entity_t entity)
{
ecs_type_t type = ecs_get_type(world, entity);
ecs_type_index_t type_index = 0;
if (ecs_type_next_index(type, ECS_INSTANCEOF, &type_index))
{
ecs_entity_t *array = (ecs_entity_t *)ecs_vector_first(type);
ecs_entity_t backup = array[type_index] & ECS_ENTITY_MASK;
ecs_type_t backup_type = ecs_get_type(world, backup);
ecs_assert(backup_type != NULL, ECS_INVALID_TYPE_EXPRESSION ,NULL);
_ecs_remove(world, backup, backup_type);
_ecs_add(world, backup, backup_type);
}
}
void ecs_restore_backup(ecs_world_t *world, ecs_entity_t entity)
{
ecs_type_t type = ecs_get_type(world, entity);
_ecs_remove(world, entity, type);
_ecs_add(world, entity, type);
}
void do_new_backup(ecs_rows_t *rows)
{
ecs_world_t *world = rows->world;
for (int i = 0; i < rows->count; i ++) {
ecs_entity_t e = rows->entities[i];
ecs_remove(world, e, setup);
ecs_new_backup(world, e);
}
}
void do_store_backup(ecs_rows_t *rows)
{
ecs_world_t *world = rows->world;
for (int i = 0; i < rows->count; i ++) {
ecs_store_backup(world, rows->entities[i]);
}
}
void do_restore_backup(ecs_rows_t *rows)
{
ecs_world_t *world = rows->world;
for (int i = 0; i < rows->count; i ++) {
ecs_restore_backup(world, rows->entities[i]);
}
}
#pragma once
#include <flecs.h>
ecs_entity_t ecs_new_backup(ecs_world_t *world, ecs_entity_t entity);
void ecs_store_backup(ecs_world_t *world, ecs_entity_t entity);
void ecs_restore_backup(ecs_world_t *world, ecs_entity_t entity);
void do_new_backup(ecs_rows_t *rows);
void do_store_backup(ecs_rows_t *rows);
void do_restore_backup(ecs_rows_t *rows);
#include "flecs_disabling.h"
void ecs_disable_task(ecs_rows_t* rows)
{
ecs_query_iter_t entites = ecs_query_iter((ecs_query_t*)ecs_column(rows, ecs_query_t, 1), 0, -1);
ecs_query_iter_t systems = ecs_query_iter((ecs_query_t*)ecs_column(rows, ecs_query_t, 2), 0, -1);
while (ecs_query_next(&entites))
{
for (int i = 0; i < entites.rows.count; ++i)
{
ecs_entity_t entity = entites.rows.entities[j];
ecs_add(rows->world, entity, EcsDisabled);
}
}
while (ecs_query_next(&systems))
{
for (int i = 0; i < systems.rows.count; ++i)
{
ecs_entity_t system = systems.rows.entities[j];
ecs_enable(rows->world, system, false);
}
}
}
void ecs_enable_task(ecs_rows_t* rows)
{
ecs_query_iter_t entites = ecs_query_iter((ecs_query_t*)ecs_column(rows, ecs_query_t, 1), 0, -1);
ecs_query_iter_t systems = ecs_query_iter((ecs_query_t*)ecs_column(rows, ecs_query_t, 2), 0, -1);
while (ecs_query_next(&entites))
{
for (int i = 0; i < entites.rows.count; ++i)
{
ecs_entity_t entity = entites.rows.entities[j];
ecs_remove(rows->world, entity, EcsDisabled);
}
}
while (ecs_query_next(&systems))
{
for (int i = 0; i < systems.rows.count; ++i)
{
ecs_entity_t system = systems.rows.entities[j];
ecs_enable(rows->world, system, true);
}
}
}
#pragma once
#include <flecs.h>
void ecs_disable_task(ecs_rows_t* rows);
void ecs_event_schedule(ecs_rows_t* rows);
#include "flecs_event.h"
void ecs_event_schedule(ecs_rows_t* rows)
{
for (int i = 0; i < rows->count; ++i)
{
ecs_entity_t entity = rows->entities[i];
for (int j = 1; rows->column_count; ++j)
{
ecs_entity_t system = rows->components[j];
ecs_set_system_context(rows->world, system, &entity);
}
}
}
void ecs_event_task(ecs_rows_t* rows)
{
void* event = ecs_get_system_context(rows->world, rows->system);
if (event == 0)
{
return;
}
for (int i = 0; i < rows->count; ++i)
{
ecs_entity_t system = rows->entities[i];
ecs_run(rows->world, system, rows->delta_time, event);
}
ecs_set_system_context(rows->world, rows->system, 0);
}
#pragma once
#include <flecs.h>
void ecs_event_schedule(ecs_rows_t* rows);
void ecs_event_task(ecs_rows_t* rows);
#define ECS_EVENT_MODULE(world, id, phase, kind, trigger)\
ECS_TAG(world, id);\
ecs_new_system(world, #id"_task", phase, #id", EcsColSystem", &ecs_event_task);\
ecs_new_system(world, #id"_schedule", kind, #trigger", ."#id"_task", &ecs_event_schedule);
#include "flecs_state.h"
void ecs_state_deselect(ecs_rows_t* rows)
{
ecs_entity_t target = ecs_column_entity(rows, 1);
ecs_query_t* query = ecs_column(rows, ecs_query_t, 2);
for (int i = 0; i < rows->count; ++i)
{
ecs_entity_t entity = rows->entities[i];
ecs_query_iter_t qiter = ecs_query_iter(query, 0, -1);
while (ecs_query_next(&qiter)) {
for (int j = 0; j < qiter.rows.count; ++j)
{
ecs_entity_t state = qiter.rows.entities[j];
if (target != state)
{
ecs_type_t type = ecs_type_from_entity(rows->world, state);
_ecs_remove(rows->world, entity, type);
}
}
}
}
}
#pragma once
#include <flecs.h>
#include "flecs_event.h"
#include "flecs_disabling.h"
void ecs_state_deselect(ecs_rows_t* rows);
#define ecs_state_setup(trigger) "SYSTEM."#trigger"_event_setup"
#define ecs_state_enter(trigger) "SYSTEM."#trigger"_event_enter"
#define ecs_state_leave(trigger) "SYSTEM."#trigger"_event_leave"
#define ecs_state_entity(id) #id"_entity"
#define ecs_state_system(id) "SYSTEM."#id"_system"
#define ECS_STATE_MACHINE(world, id)\
ECS_TAG(world, id);\
ecs_signature_t id##_sig = ecs_new_signature(world, #id);\
ecs_new_query(world, #id"_query", &id##_sig);
#define ECS_STATE_MODULE(world, machine, trigger, id)\
ECS_TAG(world, trigger);\
ECS_TAG(world, id##_entity);\
ECS_TAG(world, id##_system);\
ECS_COMPONENT(world, id);\
ecs_add(world, trigger, machine);\
ecs_signature_t id##_entites_sig = ecs_new_signature(world, #id"_entity");\
ecs_signature_t id##_systems_sig = ecs_new_signature(world, #id"_system");\
ecs_new_query(world, #id"_entites_query", &id##_entites_sig);\
ecs_new_query(world, #id"_systems_query", &id##_systems_sig);\
ecs_new_system(world, #id"_enable", EcsOnLoad, "."#id"_entities_query,."#id"_systems_query,"ecs_state_enter(trigger), &ecs_enable_task);\
ecs_new_system(world, #id"_disable", EcsOnLoad, "."#id"_entities_query,."#id"_systems_query,"ecs_state_leave(trigger)","ecs_state_setup(trigger), &ecs_disable_task);\
ecs_new_system(world, #id"_deselect", EcsOnAdd, #id", ."#machine"_query", &ecs_state_deselect);\
ECS_EVENT_MODULE(world, trigger##_event_setup, EcsOnLoad, EcsOnAdd, id);\
ECS_EVENT_MODULE(world, trigger##_event_enter, EcsOnLoad, EcsOnAdd, trigger);\
ECS_EVENT_MODULE(world, trigger##_event_leave, EcsOnLoad, EcsOnRemove, trigger);
#include <flecs.h>
#include "flecs_backup.h"
#include "flecs_state.h"
//////////////////////////////////////////////////////////////////////////////////////////////
// demo implementation
//////////////////////////////////////////////////////////////////////////////////////////////
#define ECS_MOVE_SPEED (1)
void on_move_square(ecs_rows_t* rows)
{
ECS_COLUMN(rows, EcsInput, input, 1);
ECS_COLUMN(rows, EcsPosition2D, position, 2);
if (input->mouse.left.state)
{
position->x += input->mouse.rel.x;
position->y += input->mouse.rel.y;
}
else
{
int x_v = input->keys[ECS_KEY_D].state || input->keys[ECS_KEY_RIGHT].state;
x_v -= input->keys[ECS_KEY_A].state || input->keys[ECS_KEY_LEFT].state;
int y_v = input->keys[ECS_KEY_S].state || input->keys[ECS_KEY_DOWN].state;
y_v -= input->keys[ECS_KEY_W].state || input->keys[ECS_KEY_UP].state;
position->x += x_v * ECS_DEMO_MOVE_SPEED;
position->y += y_v * ECS_DEMO_MOVE_SPEED;
}
}
void do_move_cursor(ecs_rows_t *rows) {
ECS_COLUMN(rows, EcsInput, input, 1);
ECS_COLUMN(rows, EcsPosition2D, position, 2);
position->x = input->mouse.wnd.x;
position->y = input->mouse.wnd.y;
}
struct editor {};
struct gameplay {};
void setup(ecs_world_t* world)
{
ECS_STATE_MACHINE(world, app_state);
ECS_STATE_MODULE(world, app_state, app_state_edit, editor);
ECS_STATE_MODULE(world, app_state, app_state_play, gameplay);
ECS_TAG(world, setup);
ECS_TAG(world, editable);
ECS_ENTITY(world, Cursor,
EcsPosition2D
, EcsRectangle
, EcsColor
, EcsLineColor
, ecs_state_entity(editor)
);
ECS_SYSTEM(world, do_move_cursor, EcsOnUpdate,
EcsInput
, Cursor.EcsPosition2D
, ecs_state_system(editor)
);
ECS_ENTITY(world, Square,
EcsPosition2D
, EcsSquare
, EcsColor
, EcsLineColor
, setup
, editable
);
ECS_SYSTEM(world, on_move_square, EcsOnUpdate,
EcsInput
, Square.EcsPosition2D
, ecs_state_system(gameplay)
);
ecs_new_system(world, "gameplay_setup_entities", EcsManual,
setup
, editable
, ecs_state_setup(gameplay)
, ecs_state_enter(gameplay)
,&do_new_backup
);
ecs_new_system(world, "gameplay_store_entities", EcsManual,
editable
, ecs_state_enter(gameplay)
,&do_store_backup
);
ecs_new_system(world, "gameplay_restore_entities", EcsManual,
editable
, ecs_state_leave(gameplay)
,&do_restore_backup
);
ecs_add(world, ECS_SINGLETON, editor);
ecs_add(world, ECS_SINGLETON, gameplay);
}
void tick(ecs_world_t* world, bool editing)
{
ecs_progress(world, 0);
if (editing)
{
ecs_add(world, ECS_SINGLETON, app_state_edit);
}
else
{
ecs_add(world, ECS_SINGLETON, app_state_play);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment