ECS core imprevement
-Adedd function to resize array to Mallocator -significant speed up for first time ID allocation by using resizeArray instead of makeArray -fix: onUpdate called with zero length arrays -call updateBlocks before updateEvents (it's more accurate behaviour) -some minore fixes -fixed meson.build for GDC
This commit is contained in:
parent
66860b9042
commit
13e6ed8fd5
4 changed files with 83 additions and 36 deletions
|
|
@ -52,8 +52,8 @@ endif
|
|||
|
||||
if betterC_opt
|
||||
if comp_id == 'gcc'
|
||||
args += ['-flto','-fno-druntime']
|
||||
link_args += ['-flto','-fno-druntime']
|
||||
args += ['-fno-druntime']
|
||||
link_args += ['-fno-druntime']
|
||||
else
|
||||
args += '-betterC'
|
||||
link_args += '-betterC'
|
||||
|
|
|
|||
|
|
@ -177,15 +177,9 @@ struct IDManager
|
|||
if (m_last_id > m_ids_array.length)
|
||||
{
|
||||
uint begin = cast(uint) m_ids_array.length;
|
||||
Data[] new_array = Mallocator.makeArray!Data(begin + (m_blocks_count << 16));
|
||||
memcpy(new_array.ptr, m_ids_array.ptr, m_ids_array.length * Data.sizeof);
|
||||
Mallocator.dispose(m_ids_array);
|
||||
m_ids_array = new_array;
|
||||
|
||||
uint[] new_stack = Mallocator.makeArray!uint(m_ids_array.length);
|
||||
memcpy(new_stack.ptr, m_free_stack.ptr, m_free_stack.length * uint.sizeof);
|
||||
Mallocator.dispose(m_free_stack);
|
||||
m_free_stack = new_stack;
|
||||
m_ids_array = Mallocator.resizeArray(m_ids_array, begin + (m_blocks_count << 16));
|
||||
m_free_stack = Mallocator.resizeArray(m_free_stack, m_ids_array.length);
|
||||
|
||||
foreach (block; m_blocks[0 .. m_blocks_count - 1])
|
||||
{
|
||||
|
|
|
|||
|
|
@ -456,7 +456,7 @@ export struct EntityManager
|
|||
uint writable_dep = 1;
|
||||
}
|
||||
|
||||
static ComponentsCounts getComponentsCounts()()
|
||||
static ComponentsCounts getComponentsCounts()
|
||||
{
|
||||
ComponentsCounts components_counts;
|
||||
|
||||
|
|
@ -679,7 +679,7 @@ export struct EntityManager
|
|||
|
||||
}
|
||||
|
||||
static ComponentsIndices!component_counts getComponentsInfo()()
|
||||
static ComponentsIndices!component_counts getComponentsInfo()
|
||||
{
|
||||
ComponentsIndices!component_counts components_info;
|
||||
|
||||
|
|
@ -786,7 +786,7 @@ export struct EntityManager
|
|||
|
||||
enum ComponentsIndices!component_counts components_info = getComponentsInfo();
|
||||
|
||||
static void genCompList()(ref System system, ref HashMap!(char[], ushort) components_map)
|
||||
static void genCompList(ref System system, ref HashMap!(char[], ushort) components_map)
|
||||
{
|
||||
|
||||
foreach (member; __traits(allMembers, Sys.EntitiesData))
|
||||
|
|
@ -885,7 +885,7 @@ export struct EntityManager
|
|||
}
|
||||
}
|
||||
|
||||
static void fillInputData()(ref Sys.EntitiesData input_data, EntityInfo* info,
|
||||
static void fillInputData(ref Sys.EntitiesData input_data, EntityInfo* info,
|
||||
EntitiesBlock* block, uint offset, uint entities_count, System* system)
|
||||
{
|
||||
//enum ComponentsIndices components_info = getComponentsInfo();
|
||||
|
|
@ -907,7 +907,8 @@ export struct EntityManager
|
|||
}//*/
|
||||
|
||||
///FIXME: should be "components_info.req()" but it's not compile with GCC
|
||||
static foreach (iii, comp_info; components_info.m_req[0 .. components_info.m_req_counter])
|
||||
static foreach (iii, comp_info; components_info.m_req[0
|
||||
.. components_info.m_req_counter])
|
||||
{
|
||||
__traits(getMember, input_data, comp_info.name) = (cast(ForeachType!(typeof(__traits(getMember,
|
||||
Sys.EntitiesData, comp_info.name)))*)(
|
||||
|
|
@ -915,7 +916,8 @@ export struct EntityManager
|
|||
.. entities_count];
|
||||
}
|
||||
|
||||
static foreach (iii, comp_info; components_info.m_optional[0 .. components_info.m_optional_counter])
|
||||
static foreach (iii, comp_info; components_info.m_optional[0
|
||||
.. components_info.m_optional_counter])
|
||||
{
|
||||
if (system.m_optional_components[iii] < info.deltas.length
|
||||
&& info.deltas[system.m_optional_components[iii]] != 0)
|
||||
|
|
@ -929,7 +931,7 @@ export struct EntityManager
|
|||
}
|
||||
}
|
||||
|
||||
/*bool checkOnUpdateParams()()
|
||||
/*bool checkOnUpdateParams()
|
||||
{
|
||||
bool ret = false;
|
||||
foreach (func; __traits(getOverloads, Sys, "onUpdate"))
|
||||
|
|
@ -1006,6 +1008,8 @@ export struct EntityManager
|
|||
else
|
||||
entities_count = block.entities_count;
|
||||
|
||||
if (entities_count > 0)
|
||||
{
|
||||
assert(entities_count <= block.entities_count
|
||||
&& offset <= block.entities_count);
|
||||
|
||||
|
|
@ -1013,8 +1017,8 @@ export struct EntityManager
|
|||
|
||||
static if (hasMember!(Sys.EntitiesData, "thread_id"))
|
||||
{
|
||||
input_data.thread_id = cast(typeof(input_data.thread_id)) data
|
||||
.thread_id;
|
||||
input_data.thread_id = cast(
|
||||
typeof(input_data.thread_id)) data.thread_id;
|
||||
}
|
||||
|
||||
static if (hasMember!(Sys.EntitiesData, "job_id"))
|
||||
|
|
@ -1024,8 +1028,9 @@ export struct EntityManager
|
|||
|
||||
//s.onUpdate(input_data);
|
||||
(cast(typeof(&__traits(getOverloads, s,
|
||||
"onUpdate")[OnUpdateOverloadNum])) data.update_delegate)(input_data);
|
||||
|
||||
"onUpdate")[OnUpdateOverloadNum])) data.update_delegate)(
|
||||
input_data);
|
||||
}
|
||||
block = block.next_block;
|
||||
offset = 0;
|
||||
blocks--;
|
||||
|
|
@ -1339,10 +1344,12 @@ export struct EntityManager
|
|||
|
||||
export void callEntitiesFunction(Sys, T)(T func)
|
||||
{
|
||||
//TODO: check if onUpdate function is good
|
||||
Sys* s;
|
||||
static assert(isDelegate!func, "Function must be delegate.");
|
||||
static assert(__traits(hasMember, Sys, "EntitiesData"),
|
||||
"Can't call function with system which hasn't EntitesData structure.");
|
||||
///TODO: make possibly to call function to group without system with onUpdate function
|
||||
static assert(__traits(hasMember, Sys, "onUpdate"),
|
||||
"Can't call function with system which hasn't onUpdate function callback.");
|
||||
// static assert(is(SetFunctionAttributes!(T, functionLinkage!(s.onUpdate),
|
||||
|
|
@ -1353,6 +1360,8 @@ export struct EntityManager
|
|||
System* system = getSystem(Sys.system_id);
|
||||
assert(system != null,
|
||||
"System must be registered in EntityManager before any funcion can be called.");
|
||||
if (!system.m_any_system_caller)
|
||||
return;
|
||||
|
||||
foreach (info; system.m_any_system_caller.infos)
|
||||
{
|
||||
|
|
@ -3101,7 +3110,7 @@ export struct EntityManager
|
|||
swapData();
|
||||
|
||||
has_work = false;
|
||||
// has_work |= updateBlocks();
|
||||
has_work |= updateBlocks();
|
||||
// has_work |= changeEntities();
|
||||
// has_work |= removeEntities();
|
||||
has_work |= updateEvents();
|
||||
|
|
|
|||
|
|
@ -152,6 +152,50 @@ else
|
|||
|
||||
static struct Mallocator
|
||||
{
|
||||
static T[] resizeArray(T)(T[] array, size_t length) nothrow @nogc
|
||||
{
|
||||
T[] ret;
|
||||
|
||||
if(length > array.length)
|
||||
{
|
||||
ret = (cast(T*) realloc(array.ptr, T.sizeof * length))[0 .. length];
|
||||
static if (__traits(isPOD, T))
|
||||
{
|
||||
__gshared immutable T init = T.init;
|
||||
|
||||
foreach (i; array.length .. ret.length)
|
||||
{
|
||||
memcpy(&ret[i], &init, T.sizeof);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
static import std.conv;
|
||||
|
||||
foreach (i; array.length .. ret.length)
|
||||
{
|
||||
std.conv.emplace(&ret[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
static if (__traits(hasMember, T, "__xdtor"))
|
||||
foreach (i; length .. array.length)
|
||||
{
|
||||
array[i].__xdtor();
|
||||
}
|
||||
else static if (__traits(hasMember, T, "__dtor"))
|
||||
foreach (i; length .. array.length)
|
||||
{
|
||||
array[i].__dtor();
|
||||
}
|
||||
ret = (cast(T*) realloc(array.ptr, T.sizeof * length))[0 .. length];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static T[] makeArray(T)(size_t length) nothrow @nogc
|
||||
{
|
||||
T[] ret = (cast(T*) malloc(T.sizeof * length))[0 .. length];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue