-changes in gitignore

-changed "absent" to "excluded" everywhere
-added Events support:
 *systems are scanned by handleEvent() function
 *generate system callers for events
 *event sending have (untested) multithreaded support
 *EventInput structure in System has input components for event
This commit is contained in:
Mergul 2018-11-02 15:39:46 +01:00
parent 16a5696840
commit 3bc5ff2423
8 changed files with 689 additions and 310 deletions

View file

@ -4,15 +4,19 @@ import ecs.manager;
import ecs.block_allocator;
import ecs.entity;
import std.experimental.allocator;
import std.experimental.allocator.mallocator : AlignedMallocator, Mallocator;
import std.algorithm.comparison : max;
/*
struct Event
/*struct Event
{
uint type;
uint id;
}*/
mixin template EventManagerCode()
//mixin template EventManagerCode()
struct EventManager
{
//@disable this();
@ -22,7 +26,7 @@ mixin template EventManagerCode()
manager = m;
}*/
void sendSelfEvent(Ev)(EntityID id, Ev event)
/*void sendSelfEvent(Ev)(EntityID id, Ev event)
{
ushort size = cast(ushort)(Ev.sizeof); // + EntityID.sizeof + ushort.sizeof);
ushort alignment = cast(ushort)(Ev.alignof);
@ -53,8 +57,6 @@ mixin template EventManagerCode()
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;
@ -66,22 +68,101 @@ mixin template EventManagerCode()
*cast(EntityID*)&block.data[index + 2] = id;
*cast(Ev*)&block.data[aligned_index] = event;
block.index = cast(ushort)(aligned_index + Ev.sizeof);
}*/
void initialize(EntityManager m)
{
allocator = BlockAllocator(events_block_size, events_blocks_in_allocation);
manager = m;
}
void sendEvent(Ev)(EntityID id, Ev event, uint thread_id = 0)
{
uint block_id = current_index+thread_id;
EventData* data = &events[Ev.event_id];
EventBlock* block = data.blocks[block_id];
EntityManager.EventInfo* info = &gEM.events[Ev.event_id];
event.entity_id = id;
if(block is null)
{
block = cast(EventBlock*) allocator.getBlock();
*block = EventBlock();
data.first_blocks[block_id] = block;
data.blocks[block_id] = block;
}
if(block.count >= data.max_events)
{
EventBlock* new_block = cast(EventBlock*) allocator.getBlock();
*new_block = EventBlock();
block.next = new_block;
block = new_block;
data.blocks[block_id] = block;
}
/*void* start = cast(void*)block + data.data_offset + block.count * info.size;
Ev* event_ptr = cast(Ev*)start;
*event_ptr = event;*/
Ev* event_array = cast(Ev*)(cast(void*)block + data.data_offset);
event_array[block.count] = event;
block.count++;
}
void swapCurrent()
{
uint threads_count = cast(uint)manager.threads.length;
if(current_index == 0)current_index = threads_count;
else current_index = 0;
foreach(ref event;events)
{
foreach(ref first_block; event.first_blocks[current_index .. current_index + threads_count])
{
EventBlock* block = first_block;
while(block)
{
EventBlock* to_dispose = block;
block = block.next;
allocator.freeBlock(to_dispose);
}
first_block = null;
}
foreach(ref block; event.blocks[current_index .. current_index + threads_count])
{
block = null;
}
}
}
void clearEvents()
{
EventList tmp = current_events;
uint threads_count = cast(uint)manager.threads.length;
foreach(ref event;events)
{
foreach(ref first_block; event.first_blocks)
{
EventBlock* block = first_block;
while(block)
{
EventBlock* to_dispose = block;
block = block.next;
allocator.freeBlock(to_dispose);
}
first_block = null;
}
foreach(ref block; event.blocks)
{
block = null;
}
}
/*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;
@ -89,7 +170,30 @@ mixin template EventManagerCode()
allocator.freeBlock(free);
}
process_events.first_block = null;
process_events.current_block = null;
process_events.current_block = null;*/
}
void allocateData(uint threads_count)
{
if(events)
{
foreach(ref event;events)
{
Mallocator.instance.dispose(event.blocks);
Mallocator.instance.dispose(event.first_blocks);
}
Mallocator.instance.dispose(events);
}
events = Mallocator.instance.makeArray!EventData(gEM.events.length);
foreach(i,ref event;events)
{
event.blocks = Mallocator.instance.makeArray!(EventBlock*)(threads_count*2);
event.first_blocks = Mallocator.instance.makeArray!(EventBlock*)(threads_count*2);
event.data_offset = EventBlock.sizeof;//gEM.events[i].
gEM.alignNum(event.data_offset, gEM.events[i].alignment);
event.max_events = cast(ushort)((events_block_size - event.data_offset) / gEM.events[i].size);
}
}
///Single page size. Must be power of two.
@ -99,7 +203,7 @@ mixin template EventManagerCode()
struct EventBlock
{
union
/*union
{
struct
{
@ -108,17 +212,31 @@ mixin template EventManagerCode()
}
ubyte[events_block_size] data;
}
}*/
EventBlock* next;
ushort count = 0;
}
struct EventList
/*struct EventList
{
EventBlock* first_block;
EventBlock* current_block;
}*/
struct EventData
{
ushort data_offset;
ushort max_events;
EventBlock*[] blocks;
EventBlock*[] first_blocks;
//EventBlock*[] current_blocks;
}
EventList current_events;
EventList process_events;
/*EventList current_events;
EventList process_events;*/
uint current_index = 0;
EventData[] events;
BlockAllocator/*!(events_block_size, events_blocks_in_allocation)*/ allocator;
EntityManager manager;