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; }