#include "util.h"
#include <stdlib.h>
#include <string.h>
struct Cmd * _CmdBuf_allocate(struct CmdBuf * cbuf, size_t size) {
if(cbuf->pointer + size > cbuf->end) {
size_t new_capacity = (size + (cbuf->end - cbuf->start));
new_capacity += new_capacity >> 1;
void * start = realloc(cbuf->start, new_capacity);
size_t offset = cbuf->pointer - cbuf->start;
cbuf->start = start;
cbuf->pointer = start + offset;
cbuf->end = start + new_capacity;
}
struct Cmd * cmd = (struct Cmd *)cbuf->pointer;
cmd->size = size;
cbuf->pointer += size;
return cmd;
}
void CmdBuf_add_component(struct CmdBuf * cbuf, alias_ecs_EntityHandle entity, alias_ecs_ComponentHandle component, void * data, size_t data_size) {
struct Cmd * cmd = _CmdBuf_allocate(cbuf, sizeof(*cmd) + data_size);
cmd->tag = cmd_add_component;
cmd->entity = entity;
cmd->component = component;
memcpy(cmd + 1, data, data_size);
}
void CmdBuf_remove_component(struct CmdBuf * cbuf, alias_ecs_EntityHandle entity, alias_ecs_ComponentHandle component) {
struct Cmd * cmd = _CmdBuf_allocate(cbuf, sizeof(*cmd));
cmd->tag = cmd_remove_component;
cmd->entity = entity;
cmd->component = component;
}
void CmdBuf_despawn(struct CmdBuf * cbuf, alias_ecs_EntityHandle entity) {
struct Cmd * cmd = _CmdBuf_allocate(cbuf, sizeof(*cmd));
cmd->tag = cmd_despawn;
cmd->entity = entity;
}
void CmdBuf_begin_recording(struct CmdBuf * cbuf) {
cbuf->pointer = cbuf->start;
}
void CmdBuf_end_recording(struct CmdBuf * cbuf) {
cbuf->end = cbuf->pointer;
}
void CmdBuf_execute(struct CmdBuf * cbuf, alias_ecs_Instance * instance) {
struct Cmd * cmd = (struct Cmd *)cbuf->start;
while((void *)cmd < cbuf->end) {
switch(cmd->tag) {
case cmd_add_component:
alias_ecs_add_component_to_entity(instance, cmd->entity, cmd->component, cmd + 1);
break;
case cmd_remove_component:
alias_ecs_remove_component_from_entity(instance, cmd->entity, cmd->component);
break;
case cmd_despawn:
alias_ecs_despawn(instance, 1, &cmd->entity);
break;
}
cmd = (struct Cmd *)((uint8_t *)cmd + cmd->size);
}
}