bubel-ecs/source/ecs/events.d
Mergul d3f7593afc -BlockAllocator is no longer template
-Multithreaded IDManager.getNewID()
 *use implementation with free IDs stack (instead of classic pool)
-support for multiple UpdatePasses. Passes are added by name, and must be called between begin() end() functions.
-removed mutex from addEntity()
-commit() function added. Used to commit all changes made while update() call. Called automatically by begin() end() functions.
2018-10-25 11:46:08 +02:00

125 lines
3.4 KiB
D

module ecs.events;
import ecs.manager;
import ecs.block_allocator;
import ecs.entity;
import std.algorithm.comparison : max;
/*
struct Event
{
uint type;
}*/
mixin template EventManagerCode()
{
//@disable this();
/*this(EntityManager m)
{
manager = m;
}*/
void sendSelfEvent(Ev)(EntityID id, Ev event)
{
ushort size = cast(ushort)(Ev.sizeof); // + EntityID.sizeof + ushort.sizeof);
ushort alignment = cast(ushort)(Ev.alignof);
EventList* list = &process_events;
if (list.current_block is null)
{
list.current_block = cast(EventBlock*) allocator.getBlock();
list.first_block = list.current_block;
list.current_block.index = cast(ushort)((void*).sizeof + ushort.sizeof);
}
ushort index = cast(ushort)(
list.current_block.index + ushort.sizeof + EntityID.sizeof + ushort.sizeof);
ushort aligned_index = index; //cast(ushort)(list.current_block.index);
alignNum(aligned_index, alignment);
if (aligned_index + Ev.sizeof > events_block_size)
{
list.current_block.next = cast(EventBlock*) allocator.getBlock();
list.current_block = list.current_block.next;
list.current_block.index = cast(ushort)((void*).sizeof + ushort.sizeof);
index = cast(ushort)((void*)
.sizeof + ushort.sizeof + ushort.sizeof + EntityID.sizeof + ushort.sizeof); // + EntityID.sizeof + ushort.sizeof;
aligned_index = index;
alignNum(aligned_index, alignment);
/*if(alignment > EntityID.sizeof + uint.sizeof)aligned_index = alignment;
else aligned_index = uint.sizeof * 4;*/
}
EventBlock* block = list.current_block;
ushort align_ = cast(ushort)(aligned_index - index);
*cast(ushort*)&block.data[block.index] = align_;
index = cast(ushort)(aligned_index - (EntityID.sizeof + ushort.sizeof));
*cast(ushort*)&block.data[index] = Ev.event_id;
*cast(EntityID*)&block.data[index + 2] = id;
*cast(Ev*)&block.data[aligned_index] = event;
block.index = cast(ushort)(aligned_index + Ev.sizeof);
}
void clearEvents()
{
EventList tmp = current_events;
current_events = process_events;
process_events = tmp;
EventBlock* block = process_events.first_block;
/*if(block)
{
import std.stdio;
writeln(block.data);
}*/
while (block)
{
EventBlock* free = block;
block = block.next;
allocator.freeBlock(free);
}
process_events.first_block = null;
process_events.current_block = null;
}
///Single page size. Must be power of two.
enum events_block_size = 1 << 12;
///Number of pages in block.
enum events_blocks_in_allocation = 128;
struct EventBlock
{
union
{
struct
{
EventBlock* next;
ushort index = 2;
}
ubyte[events_block_size] data;
}
}
struct EventList
{
EventBlock* first_block;
EventBlock* current_block;
}
EventList current_events;
EventList process_events;
BlockAllocator/*!(events_block_size, events_blocks_in_allocation)*/ allocator;
EntityManager manager;
}