-removed LinearLayout switch (from now it's default behaviour)

This commit is contained in:
Mergul 2018-09-29 20:49:07 +02:00
parent 783ef72eae
commit bb3f07ac70
4 changed files with 140 additions and 348 deletions

View file

@ -7,9 +7,6 @@
"copyright": "Copyright © 2017-2018, Michał Masiukiewicz, Dawid Masiukiewicz", "copyright": "Copyright © 2017-2018, Michał Masiukiewicz, Dawid Masiukiewicz",
"license": "BSD", "license": "BSD",
"sourcePaths" : ["source\/"], "sourcePaths" : ["source\/"],
"versions": [
"LinearLayout"
],
"dflags-posix-ldc": [ "dflags-posix-ldc": [
"-defaultlib=phobos2-ldc,druntime-ldc" "-defaultlib=phobos2-ldc,druntime-ldc"
], ],

BIN
ecs Normal file

Binary file not shown.

View file

@ -6,11 +6,6 @@ struct EntityID
{ {
uint id; uint id;
uint counter; uint counter;
/*int opCmp(ref const EntityID s) const
{
return id < s.id;
}*/
} }
struct Entity struct Entity
@ -28,18 +23,12 @@ struct Entity
EntityManager.EntityInfo* info = block.type_info; EntityManager.EntityInfo* info = block.type_info;
if (T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0) if (T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0)
return null; return null;
version (LinearLayout)
{ static if (EntityID.sizeof == 8)
static if (EntityID.sizeof == 8) uint ind = cast(uint)((cast(void*)&this - block.dataBegin()) >> 3);
uint ind = cast(uint)((cast(void*)&this - block.dataBegin()) >> 3);
else
uint ind = cast(uint)((cast(void*)&this - block.dataBegin()) / EntityID.sizeof());
return cast(T*)(cast(void*)block + info.deltas[T.component_id] + ind * T.sizeof);
}
else else
{ uint ind = cast(uint)((cast(void*)&this - block.dataBegin()) / EntityID.sizeof());
return cast(T*)(cast(void*)&this + info.deltas[T.component_id]); return cast(T*)(cast(void*)block + info.deltas[T.component_id] + ind * T.sizeof);
}
} }
} }
@ -50,16 +39,7 @@ export struct EntityTemplate
T* getComponent(T)() T* getComponent(T)()
{ {
if(T.component_id >= info.tmpl_deltas.length)return null;
version(LinearLayout) return cast(T*)(entity_data.ptr + info.tmpl_deltas[T.component_id]);
{
if(T.component_id >= info.tmpl_deltas.length)return null;
return cast(T*)(entity_data.ptr + info.tmpl_deltas[T.component_id]);
}
else
{
if(T.component_id >= info.deltas.length)return null;
return cast(T*)(entity_data.ptr + info.deltas[T.component_id]);
}
} }
} }

View file

@ -73,23 +73,21 @@ class EntityManager
static string genCall()() static string genCall()()
{ {
string ret; string ret;
version (LinearLayout)
{ {
uint i = 0;
uint opt = 0;
static foreach (param; (Parameters!(Sys.update))[1 .. $])
{ {
uint i = 0; i++;
uint opt = 0; if (isPointer!param)
static foreach (param; (Parameters!(Sys.update))[1 .. $])
{ {
i++; ret ~= "if(opt_array" ~ opt.to!string ~ " !is null)opt_ptr"
if (isPointer!param) ~ opt.to!string ~ " = &opt_array" ~ opt.to!string ~ "[i];";
{ opt++;
ret ~= "if(opt_array" ~ opt.to!string ~ " !is null)opt_ptr"
~ opt.to!string ~ " = &opt_array" ~ opt.to!string ~ "[i];";
opt++;
}
} }
} }
} }
/*foreach (i; 1 .. (Parameters!(Sys.update)).length) /*foreach (i; 1 .. (Parameters!(Sys.update)).length)
{ {
ret ~= "*cast(types[" ~ i.to!string ~ "]*)(pointers[" ~ (i - 1) ret ~= "*cast(types[" ~ i.to!string ~ "]*)(pointers[" ~ (i - 1)
@ -98,41 +96,21 @@ class EntityManager
uint i = 0; uint i = 0;
uint req = 0; uint req = 0;
uint opt = 0; uint opt = 0;
version (LinearLayout) ret ~= "s.update(id_array[i],";
static foreach (param; (Parameters!(Sys.update))[1 .. $])
{ {
ret ~= "s.update(id_array[i],"; i++;
static foreach (param; (Parameters!(Sys.update))[1 .. $]) if (isPointer!param)
{ {
i++; ret ~= "opt_ptr" ~ (opt++).to!string ~ ",";
if (isPointer!param) }
{ else
ret ~= "opt_ptr" ~ (opt++).to!string ~ ","; {
} ret ~= "array" ~ (req++).to!string ~ "[i],";
else
{
ret ~= "array" ~ (req++).to!string ~ "[i],";
}
}
}
else
{
ret ~= "s.update(*cast(Entity*)data_pointer,";
static foreach (param; (Parameters!(Sys.update))[1 .. $])
{
i++;
if (isPointer!param)
{
ret ~= "cast(types[" ~ i.to!string ~ "])(optional_pointers[" ~ (opt++)
.to!string ~ "]),";
}
else
{
ret ~= "*cast(types[" ~ i.to!string ~ "]*)(pointers[" ~ (req++)
.to!string ~ "]),";
}
} }
} }
ret ~= ");"; ret ~= ");";
return ret; return ret;
} }
@ -224,64 +202,21 @@ class EntityManager
EntitiesBlock* block = data.info.first_block; EntitiesBlock* block = data.info.first_block;
while (block !is null) while (block !is null)
{ {
version (LinearLayout) EntityInfo* info = block.type_info;
Entity[] id_array = (cast(Entity*) block.dataBegin())[0
.. block.entities_count];
mixin(genArrays());
foreach (i; 0 .. block.entities_count)
{ {
//uint size = block.type_info.size; mixin(genCall());
/*void* data_pointer = block.dataBegin(); //data_pointer += EntityID.sizeof; //data.info.size;
foreach (i, ref pointer; pointers) /*foreach (ref pointer; pointers)
{ pointer += size;
pointer = cast(void*) block + data.deltas[i]; foreach (ref pointer; optional_pointers)
} if (pointer != null)
foreach (i, ref pointer; optional_pointers) pointer += size;*/
{
uint ind = cast(uint)(i + pointers.length);
if (data.deltas[ind] != uint.max)
pointer = cast(void*) block + data.deltas[ind];
else
pointer = null;
}*/
EntityInfo* info = block.type_info;
Entity[] id_array = (cast(Entity*) block.dataBegin())[0
.. block.entities_count];
mixin(genArrays());
foreach (i; 0 .. block.entities_count)
{
mixin(genCall());
//data_pointer += EntityID.sizeof; //data.info.size;
/*foreach (ref pointer; pointers)
pointer += size;
foreach (ref pointer; optional_pointers)
if (pointer != null)
pointer += size;*/
}
}
else
{
uint size = block.type_info.size;
void* data_pointer = block.dataBegin();
foreach (i, ref pointer; pointers)
{
pointer = data_pointer + data.deltas[i];
}
foreach (i, ref pointer; optional_pointers)
{
uint ind = cast(uint)(i + pointers.length);
if (data.deltas[ind] != 0)
pointer = data_pointer + data.deltas[ind];
else
pointer = null;
}
foreach (i; 0 .. block.entities_count)
{
mixin(genCall());
data_pointer += size; //data.info.size;
foreach (ref pointer; pointers)
pointer += size;
foreach (ref pointer; optional_pointers)
if (pointer != null)
pointer += size;
}
} }
block = block.next_block; block = block.next_block;
} }
@ -511,23 +446,13 @@ class EntityManager
temp.info = info; temp.info = info;
//fill components with default data //fill components with default data
version (LinearLayout) foreach (comp; info.components)
{ {
foreach (comp; info.components) temp.entity_data[info.tmpl_deltas[comp] .. info.tmpl_deltas[comp] + components[comp].size]
{ = components[comp].init_data;
temp.entity_data[info.tmpl_deltas[comp] .. info.tmpl_deltas[comp] + components[comp].size]
= components[comp].init_data;
}
}
else
{
foreach (comp; info.components)
{
temp.entity_data[info.deltas[comp] .. info.deltas[comp] + components[comp].size]
= components[comp].init_data;
}
} }
return temp; return temp;
} }
@ -544,58 +469,43 @@ class EntityManager
info.size = EntityID.sizeof; info.size = EntityID.sizeof;
info.alignment = EntityID.alignof; info.alignment = EntityID.alignof;
version (LinearLayout) info.tmpl_deltas = Mallocator.instance.makeArray!ushort(ids[$ - 1] + 1);
uint components_size = EntityID.sizeof;
foreach (i, id; ids)
{ {
info.tmpl_deltas = Mallocator.instance.makeArray!ushort(ids[$ - 1] + 1); info.alignment = max(info.alignment, components[id].alignment);
uint components_size = EntityID.sizeof; alignNum(info.size, components[id].alignment);
info.tmpl_deltas[id] = info.size;
foreach (i, id; ids) info.size += components[id].size;
{ components_size += components[id].size;
info.alignment = max(info.alignment, components[id].alignment);
alignNum(info.size, components[id].alignment);
info.tmpl_deltas[id] = info.size;
info.size += components[id].size;
components_size += components[id].size;
}
alignNum(info.size, info.alignment);
/**/
uint block_memory = cast(uint)(
page_size - EntitiesBlock.sizeof - (info.size - components_size));
//uint entity_comps_size = EntityID.sizeof;
uint mem_begin = EntitiesBlock.sizeof;
/*foreach (id; ids)
{
entity_comps_size += components[id].size;
}*/
uint entites_in_block = block_memory / info.size; //entity_comps_size;
info.max_entities = cast(ushort) entites_in_block;
ushort current_delta = cast(ushort)(mem_begin + entites_in_block * EntityID.sizeof);
foreach (i, id; ids)
{
alignNum(current_delta, components[id].alignment);
info.deltas[id] = cast(ushort) current_delta;
current_delta += entites_in_block * components[id].size;
}
} }
else alignNum(info.size, info.alignment);
/**/
uint block_memory = cast(uint)(
page_size - EntitiesBlock.sizeof - (info.size - components_size));
//uint entity_comps_size = EntityID.sizeof;
uint mem_begin = EntitiesBlock.sizeof;
/*foreach (id; ids)
{ {
foreach (i, id; ids) entity_comps_size += components[id].size;
{ }*/
info.alignment = max(info.alignment, components[id].alignment);
alignNum(info.size, components[id].alignment);
info.deltas[id] = info.size;
info.size += components[id].size;
}
alignNum(info.size, info.alignment);
info.max_entities = (page_size - EntitiesBlock.sizeof) / info.size; uint entites_in_block = block_memory / info.size; //entity_comps_size;
info.max_entities = cast(ushort) entites_in_block;
ushort current_delta = cast(ushort)(mem_begin + entites_in_block * EntityID.sizeof);
foreach (i, id; ids)
{
alignNum(current_delta, components[id].alignment);
info.deltas[id] = cast(ushort) current_delta;
current_delta += entites_in_block * components[id].size;
} }
foreach (uint i, ref system; systems) foreach (uint i, ref system; systems)
{ {
if (system.m_update is null) if (system.m_update is null)
@ -733,36 +643,21 @@ class EntityManager
EntitiesBlock* new_block = findBlockWithFreeSpace(new_info); EntitiesBlock* new_block = findBlockWithFreeSpace(new_info);
version (LinearLayout) void* start = new_block.dataBegin() + new_block.entities_count * EntityID.sizeof;
void* start = new_block.dataBegin() + new_block.entities_count * EntityID.sizeof;
else
void* start = new_block.dataBegin() + new_block.entities_count * new_info.size;
Entity* new_entity = cast(Entity*) start; Entity* new_entity = cast(Entity*) start;
new_entity.id = entity.id; new_entity.id = entity.id;
new_entity.updateID(); new_entity.updateID();
version (LinearLayout) static if (EntityID.sizeof == 8)
{ uint ind = cast(uint)((cast(void*) entity - block.dataBegin()) >> 3);
static if (EntityID.sizeof == 8)
uint ind = cast(uint)((cast(void*) entity - block.dataBegin()) >> 3);
else
uint ind = cast(uint)((cast(void*) entity - block.dataBegin()) / EntityID.sizeof());
foreach (comp; new_info.components)
{
uint comp_size = components[comp].size;
memcpy(cast(void*) new_block + new_info.deltas[comp] + new_block.entities_count * comp_size,
cast(void*) block + info.deltas[comp] + ind * comp_size, comp_size);
}
}
else else
uint ind = cast(uint)((cast(void*) entity - block.dataBegin()) / EntityID.sizeof());
foreach (comp; new_info.components)
{ {
foreach (comp; new_info.components) uint comp_size = components[comp].size;
{ memcpy(cast(void*) new_block + new_info.deltas[comp] + new_block.entities_count * comp_size,
memcpy(cast(void*) new_entity + new_info.deltas[comp], cast(void*) block + info.deltas[comp] + ind * comp_size, comp_size);
cast(void*) entity + info.deltas[comp], components[comp].size);
}
} }
new_block.entities_count++; new_block.entities_count++;
@ -863,10 +758,7 @@ class EntityManager
//removeEntityNoID(entity, block); //removeEntityNoID(entity, block);
version (LinearLayout) void* start = new_block.dataBegin() + new_block.entities_count * EntityID.sizeof;
void* start = new_block.dataBegin() + new_block.entities_count * EntityID.sizeof;
else
void* start = new_block.dataBegin() + new_block.entities_count * new_info.size;
Entity* new_entity = cast(Entity*) start; Entity* new_entity = cast(Entity*) start;
new_entity.id = entity.id; new_entity.id = entity.id;
@ -874,68 +766,38 @@ class EntityManager
j = 0; j = 0;
k = 0; k = 0;
version (LinearLayout) static if (EntityID.sizeof == 8)
{ uint ind = cast(uint)((cast(void*) entity - block.dataBegin()) >> 3);
static if (EntityID.sizeof == 8)
uint ind = cast(uint)((cast(void*) entity - block.dataBegin()) >> 3);
else
uint ind = cast(uint)((cast(void*) entity - block.dataBegin()) / EntityID.sizeof());
foreach (ref id; ids)
{
void* dst = cast(void*) new_block + new_info.deltas[id] + (
new_block.entities_count + new_block.added_count) * components[id].size;
uint size = components[id].size;
if (k >= new_ids.length)
{
memcpy(dst, cast(void*) block + info.deltas[id] + ind * size, size);
j++;
}
else if (j >= info.components.length)
{
memcpy(dst, data_pointers[k], size);
k++;
}
else if (id == new_ids[k])
{
memcpy(dst, data_pointers[k], size);
k++;
}
else
{
memcpy(dst, cast(void*) block + info.deltas[id] + ind * size, size);
j++;
}
}
}
else else
uint ind = cast(uint)((cast(void*) entity - block.dataBegin()) / EntityID.sizeof());
foreach (ref id; ids)
{ {
foreach (ref id; ids) void* dst = cast(void*) new_block + new_info.deltas[id] + (
new_block.entities_count + new_block.added_count) * components[id].size;
uint size = components[id].size;
if (k >= new_ids.length)
{ {
void* dst = cast(void*) new_entity + new_info.deltas[id]; memcpy(dst, cast(void*) block + info.deltas[id] + ind * size, size);
uint size = components[id].size; j++;
if (k >= new_ids.length) }
{ else if (j >= info.components.length)
memcpy(dst, cast(void*) entity + info.deltas[id], size); {
j++; memcpy(dst, data_pointers[k], size);
} k++;
else if (j >= info.components.length) }
{ else if (id == new_ids[k])
memcpy(dst, data_pointers[k], size); {
k++; memcpy(dst, data_pointers[k], size);
} k++;
else if (id == new_ids[k]) }
{ else
memcpy(dst, data_pointers[k], size); {
k++; memcpy(dst, cast(void*) block + info.deltas[id] + ind * size, size);
} j++;
else
{
memcpy(dst, cast(void*) entity + info.deltas[id], size);
j++;
}
} }
} }
new_block.entities_count++; new_block.entities_count++;
removeEntityNoID(entity, block); removeEntityNoID(entity, block);
} }
@ -986,23 +848,16 @@ class EntityManager
uint id = (block.entities_count + block.added_count); uint id = (block.entities_count + block.added_count);
EntityInfo* info = tmpl.info; EntityInfo* info = tmpl.info;
version (LinearLayout) void* data_begin = block.dataBegin();
void* start = data_begin + EntityID.sizeof * id;
//memcpy(data_begin + EntityID.sizeof * id, tmpl.entity_data.ptr, EntityID.sizeof);
foreach (i, comp; info.components)
{ {
void* data_begin = block.dataBegin(); memcpy(cast(void*) block + info.deltas[comp] + components[comp].size * id,
void* start = data_begin + EntityID.sizeof * id; tmpl.entity_data.ptr + info.tmpl_deltas[comp], components[comp].size);
//memcpy(data_begin + EntityID.sizeof * id, tmpl.entity_data.ptr, EntityID.sizeof);
foreach (i, comp; info.components)
{
memcpy(cast(void*) block + info.deltas[comp] + components[comp].size * id,
tmpl.entity_data.ptr + info.tmpl_deltas[comp], components[comp].size);
}
}
else
{
void* start = block.dataBegin() + id * info.size;
memcpy(start, tmpl.entity_data.ptr, info.size);
} }
if (!block.added_count) if (!block.added_count)
blocks_to_update.add(block); blocks_to_update.add(block);
@ -1086,43 +941,26 @@ class EntityManager
if (info.first_with_free_space.id > block.id) if (info.first_with_free_space.id > block.id)
info.first_with_free_space = block; info.first_with_free_space = block;
version (LinearLayout) static if (EntityID.sizeof == 8)
{ uint pos = cast(uint)((cast(void*) entity - data_begin) >> 3);
static if (EntityID.sizeof == 8)
uint pos = cast(uint)((cast(void*) entity - data_begin) >> 3);
else
uint pos = cast(uint)((cast(void*) entity - data_begin) / EntityID.sizeof());
if (call_destructors)
{
//void* data = data_begin + pos * info.size;
foreach (comp; info.components)
{
if (components[comp].destroy_callback)
{
//components[comp].destroy_callback(data + info.deltas[comp]);
components[comp].destroy_callback(cast(
void*) block + info.deltas[comp] + pos * components[comp].size);
}
}
}
}
else else
uint pos = cast(uint)((cast(void*) entity - data_begin) / EntityID.sizeof());
if (call_destructors)
{ {
uint pos = cast(int)(cast(void*) entity - data_begin) / info.size; //void* data = data_begin + pos * info.size;
if (call_destructors) foreach (comp; info.components)
{ {
void* data = data_begin + pos * info.size; if (components[comp].destroy_callback)
foreach (comp; info.components)
{ {
if (components[comp].destroy_callback) //components[comp].destroy_callback(data + info.deltas[comp]);
{ components[comp].destroy_callback(cast(
components[comp].destroy_callback(data + info.deltas[comp]); void*) block + info.deltas[comp] + pos * components[comp].size);
}
} }
} }
} }
if (block.entities_count == 0) if (block.entities_count == 0)
{ {
if (info.first_block is block) if (info.first_block is block)
@ -1148,25 +986,15 @@ class EntityManager
if (pos == block.entities_count) if (pos == block.entities_count)
return; return;
version (LinearLayout) foreach (comp; info.components)
{ {
foreach (comp; info.components) void* ptr = cast(void*) block + info.deltas[comp];
{ uint size = components[comp].size;
void* ptr = cast(void*) block + info.deltas[comp]; memcpy(ptr + pos * size, ptr + block.entities_count * size, size);
uint size = components[comp].size;
memcpy(ptr + pos * size, ptr + block.entities_count * size, size);
}
entity.id = *cast(EntityID*)(data_begin + block.entities_count * EntityID.sizeof);
} }
else
{
//copy memory of last entity to position of removed entity
void* src = data_begin + block.entities_count * info.size;
void* dst = data_begin + pos * info.size;
memcpy(dst, src, info.size); entity.id = *cast(EntityID*)(data_begin + block.entities_count * EntityID.sizeof);
}
//update pointer for moved entity ID //update pointer for moved entity ID
//entity = cast(Entity*) dst; //entity = cast(Entity*) dst;
entity.updateID(); entity.updateID();
@ -1289,18 +1117,10 @@ class EntityManager
///entity components ///entity components
ushort[] components; ushort[] components;
version (LinearLayout) ///deltas in memory for components in EntitiesBlock
{ ushort[] deltas;
///deltas in memory for components in EntitiesBlock ///deltas in memory for components in EntityTemplate
ushort[] deltas; ushort[] tmpl_deltas;
///deltas in memory for components in EntityTemplate
ushort[] tmpl_deltas;
}
else
{
///deltas in memory for components
ushort[] deltas;
}
///alignment of whole entity ///alignment of whole entity
ushort alignment; //unused in linear-layout ushort alignment; //unused in linear-layout
@ -1334,11 +1154,6 @@ class EntityManager
export void* dataBegin() export void* dataBegin()
{ {
ushort dif = EntitiesBlock.sizeof; ushort dif = EntitiesBlock.sizeof;
version (LinearLayout)
{
}
else
alignNum(dif, type_info.alignment);
return cast(void*)&this + dif; return cast(void*)&this + dif;
} }