-removed some unnecessary variables -started C-API implemantation: * added C-API option to Meson (build included to main library) * refactored some code (moved some code form templates to final code, removed delegates from system) * moved templates outside EntityManager to make it possible to use in different functions
203 lines
6.5 KiB
D
203 lines
6.5 KiB
D
/************************************************************************************************************************
|
|
System module.
|
|
|
|
Copyright: Copyright © 2018-2019, Dawid Masiukiewicz, Michał Masiukiewicz
|
|
License: BSD 3-clause, see LICENSE file in project root folder.
|
|
*/
|
|
module bubel.ecs.system;
|
|
|
|
import bubel.ecs.entity;
|
|
import bubel.ecs.manager;
|
|
|
|
/************************************************************************************************************************
|
|
System contain data required to proper glue EntityManager with Systems.
|
|
System callbacks:
|
|
$(LIST
|
|
* void onUpdate(EntitesData);
|
|
* void onEnable() - called inside system.enable() function
|
|
* void onDisable() - called inside system.disable() function
|
|
* bool onBegin() - called inside manager.begin()
|
|
* void onEnd() - called inside manager.end()
|
|
* void onCreate() - called after registration inside registerSystem function
|
|
* void onDestroy() - called during re-registration and inside manager destructor
|
|
* void onAddEntity(EntitesData) - called for every entity which are assigned to system (by adding new entity or changing its components)
|
|
* void onRemoveEntity(EntitiesData) - called for every entity removed from system update process
|
|
* void onChangeEntity(EntitiesData) - called for every entity which components are changed but it was previously assigned to system
|
|
* void handleEvent(Entity*, Event) - called for every event supported by system
|
|
)
|
|
*/
|
|
struct System
|
|
{
|
|
|
|
/************************************************************************************************************************
|
|
Check if system is enabled.
|
|
*/
|
|
export bool enabled() nothrow @nogc
|
|
{
|
|
return m_enabled;
|
|
}
|
|
|
|
/************************************************************************************************************************
|
|
Enable system. If actually it is enabled function do nothing.
|
|
*/
|
|
export void enable() nothrow @nogc
|
|
{
|
|
if (!m_enabled && m_enable)
|
|
(cast(void function(void*) nothrow @nogc) m_enable)(m_system_pointer);
|
|
m_enabled = true;
|
|
}
|
|
|
|
/************************************************************************************************************************
|
|
Disable system. If actually it is disabled function do nothing.
|
|
*/
|
|
export void disable() nothrow @nogc
|
|
{
|
|
if (m_enabled && m_disable)
|
|
(cast(void function(void*) nothrow @nogc) m_disable)(m_system_pointer);
|
|
m_enabled = false;
|
|
}
|
|
|
|
/************************************************************************************************************************
|
|
Get system priority.
|
|
*/
|
|
export int priority() nothrow @nogc
|
|
{
|
|
return m_priority;
|
|
}
|
|
|
|
/************************************************************************************************************************
|
|
Get if system will be executed during current frame. Should be checked after manager.begin(). Its value is setted as result of manager.onBegin() callback.
|
|
*/
|
|
export bool willExecute() nothrow @nogc
|
|
{
|
|
return m_execute;
|
|
}
|
|
|
|
/************************************************************************************************************************
|
|
Get system id.
|
|
*/
|
|
export ushort id() nothrow @nogc
|
|
{
|
|
return m_id;
|
|
}
|
|
|
|
/************************************************************************************************************************
|
|
Get system name.
|
|
*/
|
|
export const(char)[] name() nothrow @nogc
|
|
{
|
|
return cast(const(char)[]) m_name;
|
|
}
|
|
|
|
//package:
|
|
|
|
void destroy()
|
|
{
|
|
import bubel.ecs.std : Mallocator;
|
|
disable();
|
|
if (m_destroy)
|
|
(cast(void function(void*)) m_destroy)(m_system_pointer);
|
|
|
|
if (m_name)
|
|
Mallocator.dispose(m_name);
|
|
if (m_components)
|
|
Mallocator.dispose(m_components);
|
|
if (m_excluded_components)
|
|
Mallocator.dispose(m_excluded_components);
|
|
if (m_optional_components)
|
|
Mallocator.dispose(m_optional_components);
|
|
if (jobs)
|
|
Mallocator.dispose(jobs);
|
|
if (m_read_only_components)
|
|
Mallocator.dispose(m_read_only_components);
|
|
if (m_writable_components)
|
|
Mallocator.dispose(m_writable_components);
|
|
if (m_readonly_dependencies)
|
|
Mallocator.dispose(m_readonly_dependencies);
|
|
if (m_writable_dependencies)
|
|
Mallocator.dispose(m_writable_dependencies);
|
|
if (m_event_callers)
|
|
Mallocator.dispose(m_event_callers);
|
|
|
|
if (m_system_pointer)
|
|
Mallocator.dispose(m_system_pointer);
|
|
}
|
|
|
|
struct EventCaller
|
|
{
|
|
ushort id;
|
|
void* callback;
|
|
}
|
|
|
|
///should system be executed in current update?
|
|
bool m_execute = true;
|
|
///system id
|
|
ushort m_id;
|
|
///is system empty? Empty systems don't update entities, and is called once per update
|
|
bool m_empty = false;
|
|
|
|
///should system update and catch events?
|
|
bool m_enabled = false;
|
|
///system priority
|
|
int m_priority;
|
|
///pointer to system implementation
|
|
void* m_system_pointer;
|
|
///system pass index
|
|
int m_pass;
|
|
|
|
///system name
|
|
char[] m_name;
|
|
|
|
///required components
|
|
ushort[] m_components;
|
|
///excluded components
|
|
ushort[] m_excluded_components;
|
|
///optional components
|
|
ushort[] m_optional_components;
|
|
|
|
EntityManager.Job[] jobs;
|
|
|
|
//System*[] m_dependencies;
|
|
ushort[] m_read_only_components;
|
|
ushort[] m_writable_components;
|
|
|
|
ushort[] m_readonly_dependencies;
|
|
ushort[] m_writable_dependencies;
|
|
|
|
EntityManager.SystemCaller* m_any_system_caller;
|
|
|
|
EventCaller[] m_event_callers;
|
|
|
|
//void function(ref EntityManager.CallData data) m_update;
|
|
void* m_update; ///workaroud for DMD bug with upper line
|
|
//void delegate() m_update_delegate;
|
|
|
|
//void function(void* system_pointer) m_enable;
|
|
//void function(void* system_pointer) m_disable;
|
|
|
|
//void function(void* system_pointer) m_create;
|
|
//void function(void* system_pointer) m_destroy;
|
|
|
|
//void function(void* system_pointer) m_begin;
|
|
//void function(void* system_pointer) m_end;
|
|
|
|
void* m_enable;
|
|
void* m_disable;
|
|
|
|
void* m_create;
|
|
void* m_destroy;
|
|
|
|
void* m_begin;
|
|
void* m_end;
|
|
|
|
void* m_add_entity;
|
|
void* m_remove_entity;
|
|
void* m_change_entity;
|
|
|
|
void* m_filter_entity;
|
|
|
|
//void function(ref EntityManager.CallData data) m_initialize;
|
|
//void function(ref EntityManager.CallData data) m_deinitilize;
|
|
// void* m_initialize;
|
|
// void* m_deinitilize;
|
|
}
|