diff --git a/native/flecs b/native/flecs index fb55f3c2..6566d4b7 160000 --- a/native/flecs +++ b/native/flecs @@ -1 +1 @@ -Subproject commit fb55f3c25660425cfe1bc4cf5e6bff8b3f18a9b8 +Subproject commit 6566d4b7bdc597d0b74d5e0a4104d4ae6ac49402 diff --git a/native/flecs_helpers.c b/native/flecs_helpers.c index 6d65fe47..eedf6d92 100644 --- a/native/flecs_helpers.c +++ b/native/flecs_helpers.c @@ -54,6 +54,7 @@ extern void* EcsColorCss; extern void* EcsColorHsl; extern void* EcsColorRgb; extern void* EcsConstant; +extern void* EcsCopy; extern void* EcsCounter; extern void* EcsCounterId; extern void* EcsCounterIncrement; @@ -157,6 +158,7 @@ extern void* EcsOnDeleteTarget; extern void* EcsOneOf; extern void* EcsOnInstantiate; extern void* EcsOnLoad; +extern void* EcsOnQueryCacheRevalidate; extern void* EcsOnRemove; extern void* EcsOnSet; extern void* EcsOnStart; @@ -166,7 +168,6 @@ extern void* EcsOnTableDelete; extern void* EcsOnUpdate; extern void* EcsOnValidate; extern void* EcsOrderedChildren; -extern void* EcsOverride; extern void* EcsPairIsTag; extern void* EcsPanic; extern void* EcsParentDepth; @@ -204,10 +205,11 @@ extern void* EcsRemove; extern void* EcsScopeClose; extern void* EcsScopeOpen; extern void* EcsScriptTemplate; +extern void* EcsScriptTemplateManual; +extern void* EcsScriptTemplatePending; extern void* EcsScriptVectorType; extern void* EcsSeconds; extern void* EcsSingleton; -extern void* EcsSlotOf; extern void* EcsSparse; extern void* EcsSpeed; extern void* EcsSymbol; @@ -255,6 +257,8 @@ extern void* FLECS_IDecs_id_tID_; extern void* FLECS_IDecs_iptr_tID_; extern void* FLECS_IDecs_misc_memory_tID_; extern void* FLECS_IDecs_query_memory_tID_; +extern void* FLECS_IDecs_script_template_ref_tID_; +extern void* FLECS_IDecs_shell_resource_tID_; extern void* FLECS_IDecs_string_tID_; extern void* FLECS_IDecs_table_histogram_tID_; extern void* FLECS_IDecs_table_memory_tID_; @@ -263,6 +267,7 @@ extern void* FLECS_IDecs_u32_tID_; extern void* FLECS_IDecs_u64_tID_; extern void* FLECS_IDecs_u8_tID_; extern void* FLECS_IDecs_uptr_tID_; +extern void* FLECS_IDecs_value_tID_; extern void* FLECS_IDEcsAlertCriticalID_; extern void* FLECS_IDEcsAlertErrorID_; extern void* FLECS_IDEcsAlertID_; @@ -273,16 +278,17 @@ extern void* FLECS_IDEcsAlertTimeoutID_; extern void* FLECS_IDEcsAlertWarningID_; extern void* FLECS_IDEcsArrayID_; extern void* FLECS_IDEcsBitmaskID_; +extern void* FLECS_IDEcsCommandSessionID_; extern void* FLECS_IDEcsComponentID_; extern void* FLECS_IDEcsConstantsID_; extern void* FLECS_IDEcsCounterID_; extern void* FLECS_IDEcsCounterIdID_; extern void* FLECS_IDEcsCounterIncrementID_; -extern void* FLECS_IDEcsDefaultChildComponentID_; extern void* FLECS_IDEcsDocDescriptionID_; extern void* FLECS_IDEcsEnumID_; extern void* FLECS_IDEcsGaugeID_; extern void* FLECS_IDEcsIdentifierID_; +extern void* FLECS_IDEcsMapID_; extern void* FLECS_IDEcsMemberID_; extern void* FLECS_IDEcsMemberRangesID_; extern void* FLECS_IDEcsMetricID_; @@ -297,12 +303,21 @@ extern void* FLECS_IDEcsPolyID_; extern void* FLECS_IDEcsPrimitiveID_; extern void* FLECS_IDEcsRateFilterID_; extern void* FLECS_IDEcsRestID_; +extern void* FLECS_IDEcsScriptActivateEventID_; extern void* FLECS_IDEcsScriptConstVarID_; +extern void* FLECS_IDEcsScriptFocusEventID_; extern void* FLECS_IDEcsScriptFunctionID_; extern void* FLECS_IDEcsScriptID_; +extern void* FLECS_IDEcsScriptKeyboardEventID_; extern void* FLECS_IDEcsScriptMethodID_; +extern void* FLECS_IDEcsScriptMouseEventID_; +extern void* FLECS_IDEcsScriptMutVarID_; extern void* FLECS_IDEcsScriptRngID_; +extern void* FLECS_IDEcsScriptShellID_; +extern void* FLECS_IDEcsScriptTaskID_; extern void* FLECS_IDEcsScriptTemplateID_; +extern void* FLECS_IDEcsScriptTemplateManualID_; +extern void* FLECS_IDEcsScriptTemplatePendingID_; extern void* FLECS_IDEcsScriptVectorTypeID_; extern void* FLECS_IDEcsStructID_; extern void* FLECS_IDEcsSystemStatsID_; @@ -320,6 +335,7 @@ extern void* FLECS_IDEcsWorldSummaryID_; extern void* FLECS_IDFlecsAlertsID_; extern void* FLECS_IDFlecsMetricsID_; extern void* FLECS_IDFlecsStatsID_; +extern void* FlecsMeta; BINDGEN_API void* ECS_AUTO_OVERRIDE_BindgenGetExtern() { return &ECS_AUTO_OVERRIDE; } @@ -473,6 +489,9 @@ BINDGEN_API void* EcsColorRgb_BindgenGetExtern() { BINDGEN_API void* EcsConstant_BindgenGetExtern() { return &EcsConstant; } +BINDGEN_API void* EcsCopy_BindgenGetExtern() { + return &EcsCopy; +} BINDGEN_API void* EcsCounter_BindgenGetExtern() { return &EcsCounter; } @@ -782,6 +801,9 @@ BINDGEN_API void* EcsOnInstantiate_BindgenGetExtern() { BINDGEN_API void* EcsOnLoad_BindgenGetExtern() { return &EcsOnLoad; } +BINDGEN_API void* EcsOnQueryCacheRevalidate_BindgenGetExtern() { + return &EcsOnQueryCacheRevalidate; +} BINDGEN_API void* EcsOnRemove_BindgenGetExtern() { return &EcsOnRemove; } @@ -809,9 +831,6 @@ BINDGEN_API void* EcsOnValidate_BindgenGetExtern() { BINDGEN_API void* EcsOrderedChildren_BindgenGetExtern() { return &EcsOrderedChildren; } -BINDGEN_API void* EcsOverride_BindgenGetExtern() { - return &EcsOverride; -} BINDGEN_API void* EcsPairIsTag_BindgenGetExtern() { return &EcsPairIsTag; } @@ -923,6 +942,12 @@ BINDGEN_API void* EcsScopeOpen_BindgenGetExtern() { BINDGEN_API void* EcsScriptTemplate_BindgenGetExtern() { return &EcsScriptTemplate; } +BINDGEN_API void* EcsScriptTemplateManual_BindgenGetExtern() { + return &EcsScriptTemplateManual; +} +BINDGEN_API void* EcsScriptTemplatePending_BindgenGetExtern() { + return &EcsScriptTemplatePending; +} BINDGEN_API void* EcsScriptVectorType_BindgenGetExtern() { return &EcsScriptVectorType; } @@ -932,9 +957,6 @@ BINDGEN_API void* EcsSeconds_BindgenGetExtern() { BINDGEN_API void* EcsSingleton_BindgenGetExtern() { return &EcsSingleton; } -BINDGEN_API void* EcsSlotOf_BindgenGetExtern() { - return &EcsSlotOf; -} BINDGEN_API void* EcsSparse_BindgenGetExtern() { return &EcsSparse; } @@ -1076,6 +1098,12 @@ BINDGEN_API void* FLECS_IDecs_misc_memory_tID__BindgenGetExtern() { BINDGEN_API void* FLECS_IDecs_query_memory_tID__BindgenGetExtern() { return &FLECS_IDecs_query_memory_tID_; } +BINDGEN_API void* FLECS_IDecs_script_template_ref_tID__BindgenGetExtern() { + return &FLECS_IDecs_script_template_ref_tID_; +} +BINDGEN_API void* FLECS_IDecs_shell_resource_tID__BindgenGetExtern() { + return &FLECS_IDecs_shell_resource_tID_; +} BINDGEN_API void* FLECS_IDecs_string_tID__BindgenGetExtern() { return &FLECS_IDecs_string_tID_; } @@ -1100,6 +1128,9 @@ BINDGEN_API void* FLECS_IDecs_u8_tID__BindgenGetExtern() { BINDGEN_API void* FLECS_IDecs_uptr_tID__BindgenGetExtern() { return &FLECS_IDecs_uptr_tID_; } +BINDGEN_API void* FLECS_IDecs_value_tID__BindgenGetExtern() { + return &FLECS_IDecs_value_tID_; +} BINDGEN_API void* FLECS_IDEcsAlertCriticalID__BindgenGetExtern() { return &FLECS_IDEcsAlertCriticalID_; } @@ -1130,6 +1161,9 @@ BINDGEN_API void* FLECS_IDEcsArrayID__BindgenGetExtern() { BINDGEN_API void* FLECS_IDEcsBitmaskID__BindgenGetExtern() { return &FLECS_IDEcsBitmaskID_; } +BINDGEN_API void* FLECS_IDEcsCommandSessionID__BindgenGetExtern() { + return &FLECS_IDEcsCommandSessionID_; +} BINDGEN_API void* FLECS_IDEcsComponentID__BindgenGetExtern() { return &FLECS_IDEcsComponentID_; } @@ -1145,9 +1179,6 @@ BINDGEN_API void* FLECS_IDEcsCounterIdID__BindgenGetExtern() { BINDGEN_API void* FLECS_IDEcsCounterIncrementID__BindgenGetExtern() { return &FLECS_IDEcsCounterIncrementID_; } -BINDGEN_API void* FLECS_IDEcsDefaultChildComponentID__BindgenGetExtern() { - return &FLECS_IDEcsDefaultChildComponentID_; -} BINDGEN_API void* FLECS_IDEcsDocDescriptionID__BindgenGetExtern() { return &FLECS_IDEcsDocDescriptionID_; } @@ -1160,6 +1191,9 @@ BINDGEN_API void* FLECS_IDEcsGaugeID__BindgenGetExtern() { BINDGEN_API void* FLECS_IDEcsIdentifierID__BindgenGetExtern() { return &FLECS_IDEcsIdentifierID_; } +BINDGEN_API void* FLECS_IDEcsMapID__BindgenGetExtern() { + return &FLECS_IDEcsMapID_; +} BINDGEN_API void* FLECS_IDEcsMemberID__BindgenGetExtern() { return &FLECS_IDEcsMemberID_; } @@ -1202,24 +1236,51 @@ BINDGEN_API void* FLECS_IDEcsRateFilterID__BindgenGetExtern() { BINDGEN_API void* FLECS_IDEcsRestID__BindgenGetExtern() { return &FLECS_IDEcsRestID_; } +BINDGEN_API void* FLECS_IDEcsScriptActivateEventID__BindgenGetExtern() { + return &FLECS_IDEcsScriptActivateEventID_; +} BINDGEN_API void* FLECS_IDEcsScriptConstVarID__BindgenGetExtern() { return &FLECS_IDEcsScriptConstVarID_; } +BINDGEN_API void* FLECS_IDEcsScriptFocusEventID__BindgenGetExtern() { + return &FLECS_IDEcsScriptFocusEventID_; +} BINDGEN_API void* FLECS_IDEcsScriptFunctionID__BindgenGetExtern() { return &FLECS_IDEcsScriptFunctionID_; } BINDGEN_API void* FLECS_IDEcsScriptID__BindgenGetExtern() { return &FLECS_IDEcsScriptID_; } +BINDGEN_API void* FLECS_IDEcsScriptKeyboardEventID__BindgenGetExtern() { + return &FLECS_IDEcsScriptKeyboardEventID_; +} BINDGEN_API void* FLECS_IDEcsScriptMethodID__BindgenGetExtern() { return &FLECS_IDEcsScriptMethodID_; } +BINDGEN_API void* FLECS_IDEcsScriptMouseEventID__BindgenGetExtern() { + return &FLECS_IDEcsScriptMouseEventID_; +} +BINDGEN_API void* FLECS_IDEcsScriptMutVarID__BindgenGetExtern() { + return &FLECS_IDEcsScriptMutVarID_; +} BINDGEN_API void* FLECS_IDEcsScriptRngID__BindgenGetExtern() { return &FLECS_IDEcsScriptRngID_; } +BINDGEN_API void* FLECS_IDEcsScriptShellID__BindgenGetExtern() { + return &FLECS_IDEcsScriptShellID_; +} +BINDGEN_API void* FLECS_IDEcsScriptTaskID__BindgenGetExtern() { + return &FLECS_IDEcsScriptTaskID_; +} BINDGEN_API void* FLECS_IDEcsScriptTemplateID__BindgenGetExtern() { return &FLECS_IDEcsScriptTemplateID_; } +BINDGEN_API void* FLECS_IDEcsScriptTemplateManualID__BindgenGetExtern() { + return &FLECS_IDEcsScriptTemplateManualID_; +} +BINDGEN_API void* FLECS_IDEcsScriptTemplatePendingID__BindgenGetExtern() { + return &FLECS_IDEcsScriptTemplatePendingID_; +} BINDGEN_API void* FLECS_IDEcsScriptVectorTypeID__BindgenGetExtern() { return &FLECS_IDEcsScriptVectorTypeID_; } @@ -1271,3 +1332,6 @@ BINDGEN_API void* FLECS_IDFlecsMetricsID__BindgenGetExtern() { BINDGEN_API void* FLECS_IDFlecsStatsID__BindgenGetExtern() { return &FLECS_IDFlecsStatsID_; } +BINDGEN_API void* FlecsMeta_BindgenGetExtern() { + return &FlecsMeta; +} diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 2679cc76..fbbec85a 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,6 +1,6 @@ - 4.1.6 + 4.2.0 BeanCheeseBurrito, deathbeam BeanCheeseBurrito, deathbeam https://github.com/deathbeam/Flecs.NET diff --git a/src/Flecs.NET.Bindings/Flecs.NET.Bindings.csproj b/src/Flecs.NET.Bindings/Flecs.NET.Bindings.csproj index 07d68755..151274b3 100644 --- a/src/Flecs.NET.Bindings/Flecs.NET.Bindings.csproj +++ b/src/Flecs.NET.Bindings/Flecs.NET.Bindings.csproj @@ -4,6 +4,7 @@ net9.0 enable true + $(NoWarn);CS9184 diff --git a/src/Flecs.NET.Bindings/Flecs.g.cs b/src/Flecs.NET.Bindings/Flecs.g.cs index d282979b..8e6ca2aa 100644 --- a/src/Flecs.NET.Bindings/Flecs.g.cs +++ b/src/Flecs.NET.Bindings/Flecs.g.cs @@ -52,12 +52,24 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_assert_log_")] public static extern void ecs_assert_log_(int error_code, byte* condition_str, byte* file, int line, byte* fmt); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_async_function_call")] + public static extern ecs_script_future_t* ecs_async_function_call(ecs_world_t* world, ulong function, int argc, ecs_value_t* argv); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_async_function_init")] + public static extern ulong ecs_async_function_init(ecs_world_t* world, ecs_async_function_desc_t* desc); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_async_method_init")] + public static extern ulong ecs_async_method_init(ecs_world_t* world, ecs_async_function_desc_t* desc); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_atfini")] public static extern void ecs_atfini(ecs_world_t* world, delegate* unmanaged action, void* ctx); [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_auto_override_id")] public static extern void ecs_auto_override_id(ecs_world_t* world, ulong entity, ulong component); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_base_field_w_size")] + public static extern void* ecs_base_field_w_size(ecs_iter_t* it, nint size, byte index); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_bitmask_init")] public static extern ulong ecs_bitmask_init(ecs_world_t* world, ecs_bitmask_desc_t* desc); @@ -82,9 +94,6 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_clone")] public static extern ulong ecs_clone(ecs_world_t* world, ulong dst, ulong src, bool copy_value); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_commit")] - public static extern bool ecs_commit(ecs_world_t* world, ulong entity, ecs_record_t* record, ecs_table_t* table, ecs_type_t* added, ecs_type_t* removed); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_component_index_memory_get")] public static extern ecs_component_index_memory_t ecs_component_index_memory_get(ecs_world_t* world); @@ -100,9 +109,15 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_const_var_get")] public static extern ecs_value_t ecs_const_var_get(ecs_world_t* world, ulong var); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_const_var_get_w_type")] + public static extern void* ecs_const_var_get_w_type(ecs_world_t* world, byte* name, ulong type, int size, void* @out); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_const_var_init")] public static extern ulong ecs_const_var_init(ecs_world_t* world, ecs_const_var_desc_t* desc); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_constant_to_entity_id")] + public static extern ulong ecs_constant_to_entity_id(ecs_world_t* world, ulong type, long value); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_count_id")] public static extern int ecs_count_id(ecs_world_t* world, ulong entity); @@ -139,18 +154,6 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_cpp_trim_module")] public static extern byte* ecs_cpp_trim_module(ecs_world_t* world, byte* type_name); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_defer_begin")] - public static extern bool ecs_defer_begin(ecs_world_t* world); - - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_defer_end")] - public static extern bool ecs_defer_end(ecs_world_t* world); - - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_defer_resume")] - public static extern void ecs_defer_resume(ecs_world_t* world); - - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_defer_suspend")] - public static extern void ecs_defer_suspend(ecs_world_t* world); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_delete")] public static extern void ecs_delete(ecs_world_t* world, ulong entity); @@ -301,6 +304,9 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_field_src")] public static extern ulong ecs_field_src(ecs_iter_t* it, byte index); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_field_stride")] + public static extern nint ecs_field_stride(ecs_iter_t* it, byte index); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_field_w_size")] public static extern void* ecs_field_w_size(ecs_iter_t* it, nint size, byte index); @@ -313,6 +319,9 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_frame_end")] public static extern void ecs_frame_end(ecs_world_t* world); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_function_call")] + public static extern int ecs_function_call(ecs_world_t* world, ulong function, int argc, ecs_value_t* argv, ecs_value_t* result); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_function_init")] public static extern ulong ecs_function_init(ecs_world_t* world, ecs_function_desc_t* desc); @@ -382,6 +391,9 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_get_scope")] public static extern ulong ecs_get_scope(ecs_world_t* world); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_get_sparse_id")] + public static extern void* ecs_get_sparse_id(ecs_world_t* world, ulong entity, ulong component, nint size); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_get_stage")] public static extern ecs_world_t* ecs_get_stage(ecs_world_t* world, int stage_id); @@ -415,9 +427,6 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_get_version")] public static extern uint ecs_get_version(ulong entity); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_get_with")] - public static extern ulong ecs_get_with(ecs_world_t* world); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_get_world")] public static extern ecs_world_t* ecs_get_world(void* poly); @@ -508,21 +517,21 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_init_w_args")] public static extern ecs_world_t* ecs_init_w_args(int argc, byte** argv); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_insert_w_values")] + public static extern ulong ecs_insert_w_values(ecs_world_t* world, ecs_value_t* values); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_is_alive")] public static extern bool ecs_is_alive(ecs_world_t* world, ulong e); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_is_defer_suspended")] - public static extern bool ecs_is_defer_suspended(ecs_world_t* world); - - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_is_deferred")] - public static extern bool ecs_is_deferred(ecs_world_t* world); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_is_enabled_id")] public static extern bool ecs_is_enabled_id(ecs_world_t* world, ulong entity, ulong component); [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_is_fini")] public static extern bool ecs_is_fini(ecs_world_t* world); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_is_stage")] + public static extern bool ecs_is_stage(ecs_world_t* world); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_is_valid")] public static extern bool ecs_is_valid(ecs_world_t* world, ulong e); @@ -580,9 +589,6 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_iter_skip")] public static extern void ecs_iter_skip(ecs_iter_t* it); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_iter_str")] - public static extern byte* ecs_iter_str(ecs_iter_t* it); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_iter_to_json")] public static extern byte* ecs_iter_to_json(ecs_iter_t* iter, ecs_iter_to_json_desc_t* desc); @@ -622,9 +628,15 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_log_start_capture")] public static extern void ecs_log_start_capture(bool capture_try); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_log_start_collect_errors")] + public static extern void ecs_log_start_collect_errors(ecs_vec_t* errors); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_log_stop_capture")] public static extern byte* ecs_log_stop_capture(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_log_stop_collect_errors")] + public static extern void ecs_log_stop_collect_errors(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_logv_")] public static extern void ecs_logv_(int level, byte* file, int line, byte* fmt, void* args); @@ -700,6 +712,9 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_map_remove_free")] public static extern void ecs_map_remove_free(ecs_map_t* map, ulong key); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_map_type_init")] + public static extern ulong ecs_map_type_init(ecs_world_t* world, ecs_map_desc_t* desc); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_measure_frame_time")] public static extern void ecs_measure_frame_time(ecs_world_t* world, bool enable); @@ -766,6 +781,12 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_meta_is_collection")] public static extern bool ecs_meta_is_collection(ecs_meta_cursor_t* cursor); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_meta_is_map")] + public static extern bool ecs_meta_is_map(ecs_meta_cursor_t* cursor); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_meta_key")] + public static extern int ecs_meta_key(ecs_meta_cursor_t* cursor, ecs_value_t* key); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_meta_member")] public static extern int ecs_meta_member(ecs_meta_cursor_t* cursor, byte* name); @@ -826,6 +847,9 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_meta_try_member")] public static extern int ecs_meta_try_member(ecs_meta_cursor_t* cursor, byte* name); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_method_call")] + public static extern int ecs_method_call(ecs_world_t* world, ulong method, ecs_value_t* instance, int argc, ecs_value_t* argv, ecs_value_t* result); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_method_init")] public static extern ulong ecs_method_init(ecs_world_t* world, ecs_function_desc_t* desc); @@ -853,12 +877,30 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_module_init")] public static extern ulong ecs_module_init(ecs_world_t* world, byte* c_name, ecs_component_desc_t* desc); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_mut_var_get")] + public static extern ecs_value_t ecs_mut_var_get(ecs_world_t* world, ulong var); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_mut_var_get_w_type")] + public static extern void* ecs_mut_var_get_w_type(ecs_world_t* world, byte* name, ulong type, int size, void* @out); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_mut_var_init")] + public static extern ulong ecs_mut_var_init(ecs_world_t* world, ecs_mut_var_desc_t* desc); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_mut_var_modified")] + public static extern void ecs_mut_var_modified(ecs_world_t* world, ulong var); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_mut_var_set_w_type")] + public static extern int ecs_mut_var_set_w_type(ecs_world_t* world, byte* name, ulong type, int size, void* value); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_new")] public static extern ulong ecs_new(ecs_world_t* world); [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_new_from_path_w_sep")] public static extern ulong ecs_new_from_path_w_sep(ecs_world_t* world, ulong parent, byte* path, byte* sep, byte* prefix); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_new_from_range")] + public static extern ulong ecs_new_from_range(ecs_world_t* world, ecs_entity_range_t* range); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_new_low_id")] public static extern ulong ecs_new_low_id(ecs_world_t* world); @@ -898,6 +940,9 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_os_get_api")] public static extern ecs_os_api_t ecs_os_get_api(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_os_has_dirs")] + public static extern bool ecs_os_has_dirs(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_os_has_dl")] public static extern bool ecs_os_has_dl(); @@ -937,6 +982,9 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_os_set_api_defaults")] public static extern void ecs_os_set_api_defaults(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_os_strdup_")] + public static extern byte* ecs_os_strdup_(byte* str); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_os_strerror")] public static extern byte* ecs_os_strerror(int err); @@ -1006,9 +1054,51 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_progress")] public static extern bool ecs_progress(ecs_world_t* world, float delta_time); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_ptr_copy")] + public static extern int ecs_ptr_copy(ecs_world_t* world, ulong type, void* dst, void* src); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_ptr_copy_w_type_info")] + public static extern int ecs_ptr_copy_w_type_info(ecs_world_t* world, ecs_type_info_t* ti, void* dst, void* src); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_ptr_fini")] + public static extern int ecs_ptr_fini(ecs_world_t* world, ulong type, void* ptr); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_ptr_fini_w_type_info")] + public static extern int ecs_ptr_fini_w_type_info(ecs_world_t* world, ecs_type_info_t* ti, void* ptr); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_ptr_free")] + public static extern int ecs_ptr_free(ecs_world_t* world, ulong type, void* ptr); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_ptr_free_w_type_info")] + public static extern int ecs_ptr_free_w_type_info(ecs_world_t* world, ecs_type_info_t* ti, void* ptr); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_ptr_from_json")] public static extern byte* ecs_ptr_from_json(ecs_world_t* world, ulong type, void* ptr, byte* json, ecs_from_json_desc_t* desc); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_ptr_init")] + public static extern int ecs_ptr_init(ecs_world_t* world, ulong type, void* ptr); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_ptr_init_w_type_info")] + public static extern int ecs_ptr_init_w_type_info(ecs_world_t* world, ecs_type_info_t* ti, void* ptr); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_ptr_move")] + public static extern int ecs_ptr_move(ecs_world_t* world, ulong type, void* dst, void* src); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_ptr_move_ctor")] + public static extern int ecs_ptr_move_ctor(ecs_world_t* world, ulong type, void* dst, void* src); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_ptr_move_ctor_w_type_info")] + public static extern int ecs_ptr_move_ctor_w_type_info(ecs_world_t* world, ecs_type_info_t* ti, void* dst, void* src); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_ptr_move_w_type_info")] + public static extern int ecs_ptr_move_w_type_info(ecs_world_t* world, ecs_type_info_t* ti, void* dst, void* src); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_ptr_new")] + public static extern void* ecs_ptr_new(ecs_world_t* world, ulong type); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_ptr_new_w_type_info")] + public static extern void* ecs_ptr_new_w_type_info(ecs_world_t* world, ecs_type_info_t* ti); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_ptr_to_expr")] public static extern byte* ecs_ptr_to_expr(ecs_world_t* world, ulong type, void* data); @@ -1132,35 +1222,14 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_randomize_timers")] public static extern void ecs_randomize_timers(ecs_world_t* world); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_read_begin")] - public static extern ecs_record_t* ecs_read_begin(ecs_world_t* world, ulong entity); - - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_read_end")] - public static extern void ecs_read_end(ecs_record_t* record); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_readonly_begin")] public static extern bool ecs_readonly_begin(ecs_world_t* world, bool multi_threaded); [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_readonly_end")] public static extern void ecs_readonly_end(ecs_world_t* world); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_record_ensure_id")] - public static extern void* ecs_record_ensure_id(ecs_world_t* world, ecs_record_t* record, ulong id); - - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_record_find")] - public static extern ecs_record_t* ecs_record_find(ecs_world_t* world, ulong entity); - - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_record_get_by_column")] - public static extern void* ecs_record_get_by_column(ecs_record_t* record, int column, nint size); - - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_record_get_entity")] - public static extern ulong ecs_record_get_entity(ecs_record_t* record); - - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_record_get_id")] - public static extern void* ecs_record_get_id(ecs_world_t* world, ecs_record_t* record, ulong id); - - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_record_has_id")] - public static extern bool ecs_record_has_id(ecs_world_t* world, ecs_record_t* record, ulong id); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_ref_from_ptr")] + public static extern ecs_ref_t ecs_ref_from_ptr(ecs_world_t* world, ulong entity, ulong component, void* ptr); [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_ref_get_id")] public static extern void* ecs_ref_get_id(ecs_world_t* world, ecs_ref_t* @ref, ulong component); @@ -1213,33 +1282,165 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_clear")] public static extern void ecs_script_clear(ecs_world_t* world, ulong script, ulong instance); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_edits_apply")] + public static extern byte* ecs_script_edits_apply(ecs_script_edits_t* edits); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_edits_clear")] + public static extern int ecs_script_edits_clear(ecs_script_edits_t* edits, ulong entity, ulong component); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_edits_count")] + public static extern int ecs_script_edits_count(ecs_script_edits_t* edits); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_edits_delete")] + public static extern int ecs_script_edits_delete(ecs_script_edits_t* edits, ulong entity); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_edits_free")] + public static extern void ecs_script_edits_free(ecs_script_edits_t* edits); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_edits_new")] + public static extern ecs_script_edits_t* ecs_script_edits_new(ecs_script_t* script); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_edits_remove")] + public static extern int ecs_script_edits_remove(ecs_script_edits_t* edits, ulong entity, ulong component); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_edits_set")] + public static extern int ecs_script_edits_set(ecs_script_edits_t* edits, ulong entity, ulong component, void* value); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_edits_set_expr")] + public static extern int ecs_script_edits_set_expr(ecs_script_edits_t* edits, ulong entity, ulong component, byte* expr); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_entity_owner")] + public static extern ulong ecs_script_entity_owner(ecs_world_t* world, ulong entity); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_entity_source")] + public static extern bool ecs_script_entity_source(ecs_script_t* script, ulong entity, ecs_script_source_t* source); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_eval")] public static extern int ecs_script_eval(ecs_script_t* script, ecs_script_eval_desc_t* desc, ecs_script_eval_result_t* result); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_event_listeners")] + public static extern int ecs_script_event_listeners(ecs_world_t* world, ulong entity, byte** kinds_out, int count); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_free")] public static extern void ecs_script_free(ecs_script_t* script); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_from_scene")] + public static extern int ecs_script_from_scene(ecs_world_t* world, ulong script); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_future_cancel")] + public static extern void ecs_script_future_cancel(ecs_script_future_t* future); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_future_get_ctx")] + public static extern void* ecs_script_future_get_ctx(ecs_script_future_t* future); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_future_get_error")] + public static extern byte* ecs_script_future_get_error(ecs_script_future_t* future); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_future_get_error_id")] + public static extern ulong ecs_script_future_get_error_id(ecs_script_future_t* future); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_future_get_value")] + public static extern ecs_value_t* ecs_script_future_get_value(ecs_script_future_t* future); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_future_reject")] + public static extern int ecs_script_future_reject(ecs_script_future_t* future, byte* error); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_future_reject_id")] + public static extern int ecs_script_future_reject_id(ecs_script_future_t* future, ulong error, byte* msg); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_future_release")] + public static extern void ecs_script_future_release(ecs_script_future_t* future); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_future_resolve")] + public static extern int ecs_script_future_resolve(ecs_script_future_t* future, ecs_value_t* value); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_future_retain")] + public static extern ecs_script_future_t* ecs_script_future_retain(ecs_script_future_t* future); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_future_set_ctx")] + public static extern void ecs_script_future_set_ctx(ecs_script_future_t* future, void* ctx, delegate* unmanaged ctx_free); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_future_status")] + public static extern ecs_script_future_status_t ecs_script_future_status(ecs_script_future_t* future); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_get_focus")] + public static extern ulong ecs_script_get_focus(ecs_world_t* world); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_get_mouse_state")] + public static extern bool ecs_script_get_mouse_state(ecs_world_t* world, EcsScriptMouseEvent* last_out, ulong* pressed_out); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_init")] public static extern ulong ecs_script_init(ecs_world_t* world, ecs_script_desc_t* desc); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_ir_to_str")] + public static extern byte* ecs_script_ir_to_str(ecs_script_t* script); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_keyboard_event")] + public static extern ecs_script_event_result_t ecs_script_keyboard_event(ecs_world_t* world, EcsScriptKeyboardEvent* evt); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_mouse_event")] + public static extern ecs_script_event_result_t ecs_script_mouse_event(ecs_world_t* world, EcsScriptMouseEvent* evt); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_parse")] public static extern ecs_script_t* ecs_script_parse(ecs_world_t* world, byte* name, byte* code, ecs_script_eval_desc_t* desc, ecs_script_eval_result_t* result); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_reload")] + public static extern int ecs_script_reload(ecs_world_t* world, ulong script, byte* code); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_run")] public static extern int ecs_script_run(ecs_world_t* world, byte* name, byte* code, ecs_script_eval_result_t* result); [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_run_file")] public static extern int ecs_script_run_file(ecs_world_t* world, byte* filename); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_run_file_w_desc")] + public static extern int ecs_script_run_file_w_desc(ecs_world_t* world, byte* filename, ecs_script_eval_desc_t* desc); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_run_w_desc")] + public static extern int ecs_script_run_w_desc(ecs_world_t* world, byte* name, byte* code, ecs_script_eval_desc_t* desc, ecs_script_eval_result_t* result); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_runtime_free")] public static extern void ecs_script_runtime_free(ecs_script_runtime_t* runtime); [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_runtime_new")] public static extern ecs_script_runtime_t* ecs_script_runtime_new(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_save")] + public static extern int ecs_script_save(ecs_world_t* world, ulong script); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_set_event_hooks")] + public static extern void ecs_script_set_event_hooks(ecs_world_t* world, ecs_script_event_hooks_t* hooks); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_set_focus")] + public static extern ulong ecs_script_set_focus(ecs_world_t* world, ulong entity); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_string_interpolate")] public static extern byte* ecs_script_string_interpolate(ecs_world_t* world, byte* str, ecs_script_vars_t* vars); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_task_cancel")] + public static extern void ecs_script_task_cancel(ecs_script_task_t* task); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_task_free")] + public static extern void ecs_script_task_free(ecs_script_task_t* task); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_task_is_ready")] + public static extern bool ecs_script_task_is_ready(ecs_script_task_t* task); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_task_new")] + public static extern ecs_script_task_t* ecs_script_task_new(ecs_script_t* script, ecs_script_task_desc_t* desc); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_task_resume")] + public static extern ecs_script_task_status_t ecs_script_task_resume(ecs_script_task_t* task, ecs_script_eval_result_t* result); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_tasks_progress")] + public static extern int ecs_script_tasks_progress(ecs_world_t* world); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_template_update")] + public static extern int ecs_script_template_update(ecs_world_t* world, ulong instance, ulong template_entity); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_undo")] + public static extern int ecs_script_undo(ecs_world_t* world, ulong script); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_script_update")] public static extern int ecs_script_update(ecs_world_t* world, ulong script, ulong instance, byte* code); @@ -1300,9 +1501,6 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_set_ctx")] public static extern void ecs_set_ctx(ecs_world_t* world, void* ctx, delegate* unmanaged ctx_free); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_set_default_query_flags")] - public static extern void ecs_set_default_query_flags(ecs_world_t* world, uint flags); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_set_hooks_id")] public static extern void ecs_set_hooks_id(ecs_world_t* world, ulong component, ecs_type_hooks_t* hooks); @@ -1330,6 +1528,12 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_set_rate")] public static extern ulong ecs_set_rate(ecs_world_t* world, ulong tick_source, int rate, ulong source); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_set_rtt_compare")] + public static extern int ecs_set_rtt_compare(ecs_world_t* world, ulong type); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_set_rtt_equals")] + public static extern int ecs_set_rtt_equals(ecs_world_t* world, ulong type); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_set_scope")] public static extern ulong ecs_set_scope(ecs_world_t* world, ulong scope); @@ -1360,8 +1564,23 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_set_version")] public static extern void ecs_set_version(ecs_world_t* world, ulong entity); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_set_with")] - public static extern ulong ecs_set_with(ecs_world_t* world, ulong component); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_shell_get_session")] + public static extern ulong ecs_shell_get_session(ecs_world_t* world); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_shell_resource_create")] + public static extern int ecs_shell_resource_create(ecs_world_t* world, ulong session, byte* content_type, void* data, int size, ecs_shell_resource_t* resource); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_shell_resource_read")] + public static extern void* ecs_shell_resource_read(ecs_world_t* world, ulong session, byte* name, int* size, byte** content_type); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_shell_result_fini")] + public static extern void ecs_shell_result_fini(ecs_world_t* world, ecs_shell_result_t* result); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_shell_run")] + public static extern ecs_shell_result_t ecs_shell_run(ecs_world_t* world, ulong session, byte* cmd); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_shell_session_init")] + public static extern ulong ecs_shell_session_init(ecs_world_t* world, ecs_shell_session_desc_t* desc); [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_should_log")] public static extern bool ecs_should_log(int level); @@ -1375,24 +1594,6 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_sleepf")] public static extern void ecs_sleepf(double t); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_sparse_add")] - public static extern void* ecs_sparse_add(ecs_sparse_t* sparse, int elem_size); - - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_sparse_count")] - public static extern int ecs_sparse_count(ecs_sparse_t* sparse); - - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_sparse_get")] - public static extern void* ecs_sparse_get(ecs_sparse_t* sparse, int elem_size, ulong id); - - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_sparse_get_dense")] - public static extern void* ecs_sparse_get_dense(ecs_sparse_t* sparse, int elem_size, int index); - - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_sparse_init")] - public static extern void ecs_sparse_init(ecs_sparse_t* sparse, int elem_size); - - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_sparse_last_id")] - public static extern ulong ecs_sparse_last_id(ecs_sparse_t* sparse); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_stage_free")] public static extern void ecs_stage_free(ecs_world_t* stage); @@ -1636,6 +1837,9 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_type_str")] public static extern byte* ecs_type_str(ecs_world_t* world, ecs_type_t* type); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_type_to_script")] + public static extern byte* ecs_type_to_script(ecs_world_t* world, ulong type); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_unit_init")] public static extern ulong ecs_unit_init(ecs_world_t* world, ecs_unit_desc_t* desc); @@ -1645,44 +1849,35 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_using_task_threads")] public static extern bool ecs_using_task_threads(ecs_world_t* world); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_value_copy")] - public static extern int ecs_value_copy(ecs_world_t* world, ulong type, void* dst, void* src); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_value_compare")] + public static extern int ecs_value_compare(ecs_world_t* world, ecs_value_t* a, ecs_value_t* b); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_value_copy_w_type_info")] - public static extern int ecs_value_copy_w_type_info(ecs_world_t* world, ecs_type_info_t* ti, void* dst, void* src); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_value_copy")] + public static extern void ecs_value_copy(ecs_world_t* world, ecs_value_t* dst, ecs_value_t* src); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_value_fini")] - public static extern int ecs_value_fini(ecs_world_t* world, ulong type, void* ptr); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_value_copy_ctor")] + public static extern void ecs_value_copy_ctor(ecs_world_t* world, ecs_value_t* dst, ecs_value_t* src); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_value_fini_w_type_info")] - public static extern int ecs_value_fini_w_type_info(ecs_world_t* world, ecs_type_info_t* ti, void* ptr); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_value_equals")] + public static extern bool ecs_value_equals(ecs_world_t* world, ecs_value_t* a, ecs_value_t* b); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_value_free")] - public static extern int ecs_value_free(ecs_world_t* world, ulong type, void* ptr); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_value_fini")] + public static extern void ecs_value_fini(ecs_world_t* world, ecs_value_t* v); [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_value_init")] - public static extern int ecs_value_init(ecs_world_t* world, ulong type, void* ptr); - - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_value_init_w_type_info")] - public static extern int ecs_value_init_w_type_info(ecs_world_t* world, ecs_type_info_t* ti, void* ptr); + public static extern ecs_value_t ecs_value_init(ecs_world_t* world, ulong type, void* ptr); [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_value_move")] - public static extern int ecs_value_move(ecs_world_t* world, ulong type, void* dst, void* src); + public static extern void ecs_value_move(ecs_world_t* world, ecs_value_t* dst, ecs_value_t* src); [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_value_move_ctor")] - public static extern int ecs_value_move_ctor(ecs_world_t* world, ulong type, void* dst, void* src); - - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_value_move_ctor_w_type_info")] - public static extern int ecs_value_move_ctor_w_type_info(ecs_world_t* world, ecs_type_info_t* ti, void* dst, void* src); - - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_value_move_w_type_info")] - public static extern int ecs_value_move_w_type_info(ecs_world_t* world, ecs_type_info_t* ti, void* dst, void* src); + public static extern void ecs_value_move_ctor(ecs_world_t* world, ecs_value_t* dst, ecs_value_t* src); [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_value_new")] - public static extern void* ecs_value_new(ecs_world_t* world, ulong type); + public static extern ecs_value_t ecs_value_new(ecs_world_t* world, ulong type); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_value_new_w_type_info")] - public static extern void* ecs_value_new_w_type_info(ecs_world_t* world, ecs_type_info_t* ti); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_value_set")] + public static extern void ecs_value_set(ecs_world_t* world, ecs_value_t* v, ulong type, void* ptr); [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_vec_append")] public static extern void* ecs_vec_append(ecs_allocator_t* allocator, ecs_vec_t* vec, int size); @@ -1693,9 +1888,6 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_vec_copy")] public static extern ecs_vec_t ecs_vec_copy(ecs_allocator_t* allocator, ecs_vec_t* vec, int size); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_vec_copy_shrink")] - public static extern ecs_vec_t ecs_vec_copy_shrink(ecs_allocator_t* allocator, ecs_vec_t* vec, int size); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_vec_count")] public static extern int ecs_vec_count(ecs_vec_t* vec); @@ -1756,9 +1948,6 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_vec_set_min_size")] public static extern void ecs_vec_set_min_size(ecs_allocator_t* allocator, ecs_vec_t* vec, int size, int elem_count); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_vec_set_min_size_w_type_info")] - public static extern void ecs_vec_set_min_size_w_type_info(ecs_allocator_t* allocator, ecs_vec_t* vec, int size, int elem_count, ecs_type_info_t* ti); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_vec_set_size")] public static extern void ecs_vec_set_size(ecs_allocator_t* allocator, ecs_vec_t* vec, int size, int elem_count); @@ -1807,11 +1996,8 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_world_to_json_buf")] public static extern int ecs_world_to_json_buf(ecs_world_t* world, ecs_strbuf_t* buf_out, ecs_world_to_json_desc_t* desc); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_write_begin")] - public static extern ecs_record_t* ecs_write_begin(ecs_world_t* world, ulong entity); - - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ecs_write_end")] - public static extern void ecs_write_end(ecs_record_t* record); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_add_ids")] + public static extern void flecs_add_ids(ecs_world_t* world, ulong entity, ulong* ids, int count); [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_allocator_fini")] public static extern void flecs_allocator_fini(ecs_allocator_t* a); @@ -1837,24 +2023,15 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_ballocator_fini")] public static extern void flecs_ballocator_fini(ecs_block_allocator_t* ba); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_ballocator_free")] - public static extern void flecs_ballocator_free(ecs_block_allocator_t* ba); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_ballocator_init")] public static extern void flecs_ballocator_init(ecs_block_allocator_t* ba, int size); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_ballocator_new")] - public static extern ecs_block_allocator_t* flecs_ballocator_new(int size); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_bcalloc")] public static extern void* flecs_bcalloc(ecs_block_allocator_t* allocator); [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_bcalloc_w_dbg_info")] public static extern void* flecs_bcalloc_w_dbg_info(ecs_block_allocator_t* allocator, byte* type_name); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_bdup")] - public static extern void* flecs_bdup(ecs_block_allocator_t* ba, void* memory); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_bfree")] public static extern void flecs_bfree(ecs_block_allocator_t* allocator, void* memory); @@ -1887,6 +2064,15 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_chrparse")] public static extern byte* flecs_chrparse(byte* @in, byte* @out); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_commands_end")] + public static extern bool flecs_commands_end(ecs_world_t* world, ecs_stage_t* stage); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_component_dont_fragment_first")] + public static extern ecs_component_record_t* flecs_component_dont_fragment_first(ecs_world_t* world); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_component_dont_fragment_next")] + public static extern ecs_component_record_t* flecs_component_dont_fragment_next(ecs_component_record_t* cr); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_component_get_childof_depth")] public static extern int flecs_component_get_childof_depth(ecs_component_record_t* cr); @@ -1896,8 +2082,8 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_component_get_id")] public static extern ulong flecs_component_get_id(ecs_component_record_t* cr); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_component_get_parent_record")] - public static extern ecs_parent_record_t* flecs_component_get_parent_record(ecs_component_record_t* cr, ecs_table_t* table); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_component_get_sparse")] + public static extern ecs_sparse_t* flecs_component_get_sparse(ecs_component_record_t* cr); [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_component_get_table")] public static extern ecs_table_record_t* flecs_component_get_table(ecs_component_record_t* cr, ecs_table_t* table); @@ -1932,15 +2118,24 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_default_ctor")] public static extern void flecs_default_ctor(void* ptr, int count, ecs_type_info_t* type_info); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_defer_end")] - public static extern bool flecs_defer_end(ecs_world_t* world, ecs_stage_t* stage); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_dump_backtrace")] public static extern void flecs_dump_backtrace(void* stream); [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_dup")] public static extern void* flecs_dup(ecs_allocator_t* a, int size, void* src); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_entities_get")] + public static extern ecs_record_t* flecs_entities_get(ecs_world_t* world, ulong entity); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_entity_get")] + public static extern void* flecs_entity_get(ecs_world_t* world, ecs_record_t* record, ulong component); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_entity_get_column")] + public static extern void* flecs_entity_get_column(ecs_record_t* record, int column, nint size); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_entity_get_id")] + public static extern ulong flecs_entity_get_id(ecs_record_t* record); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_hashmap_copy")] public static extern void flecs_hashmap_copy(ecs_hashmap_t* dst, ecs_hashmap_t* src); @@ -1965,17 +2160,11 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_hashmap_next_")] public static extern void* flecs_hashmap_next_(flecs_hashmap_iter_t* it, int key_size, void* key_out, int value_size); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_hashmap_remove_")] - public static extern void flecs_hashmap_remove_(ecs_hashmap_t* map, int key_size, void* key, int value_size); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_hashmap_remove_w_hash_")] public static extern void flecs_hashmap_remove_w_hash_(ecs_hashmap_t* map, int key_size, void* key, int value_size, ulong hash); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_hashmap_set_")] - public static extern void flecs_hashmap_set_(ecs_hashmap_t* map, int key_size, void* key, int value_size, void* value); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_hm_bucket_remove")] - public static extern void flecs_hm_bucket_remove(ecs_hashmap_t* map, ecs_hm_bucket_t* bucket, ulong hash, int index); + public static extern void flecs_hm_bucket_remove(ecs_hashmap_t* map, ecs_hm_bucket_t* bucket, ulong hash); [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_module_path_from_c")] public static extern byte* flecs_module_path_from_c(byte* c_name); @@ -2028,6 +2217,9 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_sparse_get_dense")] public static extern void* flecs_sparse_get_dense(ecs_sparse_t* sparse, int elem_size, int index); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_sparse_get_w_check")] + public static extern void* flecs_sparse_get_w_check(ecs_sparse_t* sparse, int elem_size, ulong id, bool @checked); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_sparse_has")] public static extern bool flecs_sparse_has(ecs_sparse_t* sparse, ulong id); @@ -2037,9 +2229,6 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_sparse_init")] public static extern void flecs_sparse_init(ecs_sparse_t* result, ecs_allocator_t* allocator, ecs_block_allocator_t* page_allocator, int size); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_sparse_insert")] - public static extern void* flecs_sparse_insert(ecs_sparse_t* sparse, int elem_size, ulong id); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_sparse_is_alive")] public static extern bool flecs_sparse_is_alive(ecs_sparse_t* sparse, ulong id); @@ -2073,6 +2262,9 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_stack_get_cursor")] public static extern ecs_stack_cursor_t* flecs_stack_get_cursor(ecs_stack_t* stack); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_stack_get_cursor_w_alloc")] + public static extern ecs_stack_cursor_t* flecs_stack_get_cursor_w_alloc(ecs_stack_t* stack, int size, int align, void** data_out); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_stack_init")] public static extern void flecs_stack_init(ecs_stack_t* stack); @@ -2094,6 +2286,9 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_suspend_readonly")] public static extern ecs_world_t* flecs_suspend_readonly(ecs_world_t* world, ecs_suspend_readonly_state_t* state); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_table_flags")] + public static extern uint flecs_table_flags(ecs_table_t* table); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "flecs_table_id")] public static extern ulong flecs_table_id(ecs_table_t* table); @@ -2166,9 +2361,15 @@ public partial class BindgenInternal [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FlecsScriptImport")] public static extern void FlecsScriptImport(ecs_world_t* world); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FlecsScriptInputImport")] + public static extern void FlecsScriptInputImport(ecs_world_t* world); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FlecsScriptMathImport")] public static extern void FlecsScriptMathImport(ecs_world_t* world); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FlecsScriptShellImport")] + public static extern void FlecsScriptShellImport(ecs_world_t* world); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FlecsStatsImport")] public static extern void FlecsStatsImport(ecs_world_t* world); @@ -2206,35 +2407,37 @@ public enum ecs_meta_op_kind_t : uint EcsOpPushStruct = 0, EcsOpPushArray = 1, EcsOpPushVector = 2, - EcsOpPop = 3, - EcsOpOpaqueStruct = 4, - EcsOpOpaqueArray = 5, - EcsOpOpaqueVector = 6, - EcsOpForward = 7, - EcsOpScope = 8, - EcsOpOpaqueValue = 9, - EcsOpEnum = 10, - EcsOpBitmask = 11, - EcsOpPrimitive = 12, - EcsOpBool = 13, - EcsOpChar = 14, - EcsOpByte = 15, - EcsOpU8 = 16, - EcsOpU16 = 17, - EcsOpU32 = 18, - EcsOpU64 = 19, - EcsOpI8 = 20, - EcsOpI16 = 21, - EcsOpI32 = 22, - EcsOpI64 = 23, - EcsOpF32 = 24, - EcsOpF64 = 25, - EcsOpUPtr = 26, - EcsOpIPtr = 27, - EcsOpString = 28, - EcsOpEntity = 29, - EcsOpId = 30, - EcsMetaTypeOpKindLast = 30 + EcsOpPushMap = 3, + EcsOpPushValue = 4, + EcsOpPop = 5, + EcsOpOpaqueStruct = 6, + EcsOpOpaqueArray = 7, + EcsOpOpaqueVector = 8, + EcsOpForward = 9, + EcsOpScope = 10, + EcsOpOpaqueValue = 11, + EcsOpEnum = 12, + EcsOpBitmask = 13, + EcsOpPrimitive = 14, + EcsOpBool = 15, + EcsOpChar = 16, + EcsOpByte = 17, + EcsOpU8 = 18, + EcsOpU16 = 19, + EcsOpU32 = 20, + EcsOpU64 = 21, + EcsOpI8 = 22, + EcsOpI16 = 23, + EcsOpI32 = 24, + EcsOpI64 = 25, + EcsOpF32 = 26, + EcsOpF64 = 27, + EcsOpUPtr = 28, + EcsOpIPtr = 29, + EcsOpString = 30, + EcsOpEntity = 31, + EcsOpId = 32, + EcsMetaTypeOpKindLast = 32 } public enum ecs_oper_kind_t : uint @@ -2279,6 +2482,36 @@ public enum ecs_query_cache_kind_t : uint EcsQueryCacheNone = 3 } + public enum ecs_script_focus_source_t : uint + { + EcsScriptFocusPress = 0, + EcsScriptFocusSet = 1, + EcsScriptFocusScript = 2 + } + + public enum ecs_script_future_status_t : uint + { + EcsScriptFuturePending = 0, + EcsScriptFutureResolved = 1, + EcsScriptFutureRejected = 2, + EcsScriptFutureCancelled = 3 + } + + public enum ecs_script_task_loop_t : uint + { + EcsScriptTaskLoopOnce = 0, + EcsScriptTaskLoopCount = 1, + EcsScriptTaskLoopForever = 2 + } + + public enum ecs_script_task_status_t : uint + { + EcsScriptTaskPending = 0, + EcsScriptTaskDone = 1, + EcsScriptTaskError = 2, + EcsScriptTaskCancelled = 3 + } + public enum ecs_type_kind_t : uint { EcsPrimitiveType = 0, @@ -2288,7 +2521,9 @@ public enum ecs_type_kind_t : uint EcsArrayType = 4, EcsVectorType = 5, EcsOpaqueType = 6, - EcsTypeKindLast = 6 + EcsMapType = 7, + EcsValueType = 8, + EcsTypeKindLast = 8 } public const ecs_http_method_t EcsHttpGet = ecs_http_method_t.EcsHttpGet; @@ -2321,6 +2556,10 @@ public enum ecs_type_kind_t : uint public const ecs_meta_op_kind_t EcsOpPushVector = ecs_meta_op_kind_t.EcsOpPushVector; + public const ecs_meta_op_kind_t EcsOpPushMap = ecs_meta_op_kind_t.EcsOpPushMap; + + public const ecs_meta_op_kind_t EcsOpPushValue = ecs_meta_op_kind_t.EcsOpPushValue; + public const ecs_meta_op_kind_t EcsOpPop = ecs_meta_op_kind_t.EcsOpPop; public const ecs_meta_op_kind_t EcsOpOpaqueStruct = ecs_meta_op_kind_t.EcsOpOpaqueStruct; @@ -2439,6 +2678,34 @@ public enum ecs_type_kind_t : uint public const ecs_query_cache_kind_t EcsQueryCacheNone = ecs_query_cache_kind_t.EcsQueryCacheNone; + public const ecs_script_focus_source_t EcsScriptFocusPress = ecs_script_focus_source_t.EcsScriptFocusPress; + + public const ecs_script_focus_source_t EcsScriptFocusSet = ecs_script_focus_source_t.EcsScriptFocusSet; + + public const ecs_script_focus_source_t EcsScriptFocusScript = ecs_script_focus_source_t.EcsScriptFocusScript; + + public const ecs_script_future_status_t EcsScriptFuturePending = ecs_script_future_status_t.EcsScriptFuturePending; + + public const ecs_script_future_status_t EcsScriptFutureResolved = ecs_script_future_status_t.EcsScriptFutureResolved; + + public const ecs_script_future_status_t EcsScriptFutureRejected = ecs_script_future_status_t.EcsScriptFutureRejected; + + public const ecs_script_future_status_t EcsScriptFutureCancelled = ecs_script_future_status_t.EcsScriptFutureCancelled; + + public const ecs_script_task_loop_t EcsScriptTaskLoopOnce = ecs_script_task_loop_t.EcsScriptTaskLoopOnce; + + public const ecs_script_task_loop_t EcsScriptTaskLoopCount = ecs_script_task_loop_t.EcsScriptTaskLoopCount; + + public const ecs_script_task_loop_t EcsScriptTaskLoopForever = ecs_script_task_loop_t.EcsScriptTaskLoopForever; + + public const ecs_script_task_status_t EcsScriptTaskPending = ecs_script_task_status_t.EcsScriptTaskPending; + + public const ecs_script_task_status_t EcsScriptTaskDone = ecs_script_task_status_t.EcsScriptTaskDone; + + public const ecs_script_task_status_t EcsScriptTaskError = ecs_script_task_status_t.EcsScriptTaskError; + + public const ecs_script_task_status_t EcsScriptTaskCancelled = ecs_script_task_status_t.EcsScriptTaskCancelled; + public const ecs_type_kind_t EcsPrimitiveType = ecs_type_kind_t.EcsPrimitiveType; public const ecs_type_kind_t EcsBitmaskType = ecs_type_kind_t.EcsBitmaskType; @@ -2453,12 +2720,16 @@ public enum ecs_type_kind_t : uint public const ecs_type_kind_t EcsOpaqueType = ecs_type_kind_t.EcsOpaqueType; + public const ecs_type_kind_t EcsMapType = ecs_type_kind_t.EcsMapType; + + public const ecs_type_kind_t EcsValueType = ecs_type_kind_t.EcsValueType; + public const ecs_type_kind_t EcsTypeKindLast = ecs_type_kind_t.EcsTypeKindLast; public partial struct ecs_iter_private_t { [StructLayout(System.Runtime.InteropServices.LayoutKind.Explicit)] - public partial struct AnonymousRecord_api_types_L145_C5 + public partial struct AnonymousRecord_api_types_L177_C5 { [System.Runtime.InteropServices.FieldOffset(0)] public ecs_query_iter_t query; @@ -2476,7 +2747,7 @@ public partial struct AnonymousRecord_api_types_L145_C5 public partial struct ecs_world_info_t { - public partial struct AnonymousRecord_flecs_L1542_C5 + public partial struct AnonymousRecord_flecs_L1563_C5 { public long add_count; @@ -2507,7 +2778,7 @@ public partial struct AnonymousRecord_flecs_L1542_C5 public partial struct ecs_meta_op_t { [StructLayout(System.Runtime.InteropServices.LayoutKind.Explicit)] - public partial struct AnonymousRecord_meta_L579_C5 + public partial struct AnonymousRecord_meta_L594_C5 { [System.Runtime.InteropServices.FieldOffset(0)] public ecs_hashmap_t* members; @@ -2736,14 +3007,10 @@ public partial struct ecs_alert_severity_filter_t public partial struct ecs_allocator_memory_t { - public int bytes_graph_edge; - public int bytes_component_record; public int bytes_pair_record; - public int bytes_table_diff; - public int bytes_sparse_chunk; public int bytes_allocator; @@ -2796,6 +3063,23 @@ public partial struct ecs_array_desc_t public int count; } + public partial struct ecs_async_function_desc_t + { + public byte* name; + + public ulong parent; + + public InlineArrays.ecs_script_parameter_t_16 @params; + + public ulong return_type; + + public delegate* unmanaged callback; + + public delegate* unmanaged cancel; + + public void* ctx; + } + public partial struct ecs_bitmask_constant_t { public byte* name; @@ -2893,13 +3177,42 @@ public partial struct ecs_bulk_desc_t public ecs_table_t* table; } + public partial struct ecs_cmd_entry_t + { + public int first; + + public int last; + + public ulong removed; + } + public partial struct ecs_commands_t { + public ecs_commands_t* prev; + + public ecs_commands_t* next; + public ecs_vec_t queue; public ecs_stack_t stack; - public ecs_sparse_t entries; + public ecs_sparse_t entries; + + public ulong entity; + + public ecs_cmd_entry_t entry; + + public int cursor; + + public bool has_remove; + + public ulong second_entity; + + public ecs_cmd_entry_t second_entry; + + public ulong last_entity; + + public ecs_cmd_entry_t* last_entry; } public partial struct ecs_component_desc_t @@ -2923,8 +3236,6 @@ public partial struct ecs_component_index_memory_t public int bytes_ordered_children; - public int bytes_children_table_map; - public int bytes_reachable_cache; } @@ -3026,7 +3337,9 @@ public partial struct ecs_each_iter_t public short columns; - public ecs_table_record_t* trs; + public ecs_table_record_t* trs; + + public ecs_component_record_t* cr; } public partial struct ecs_entities_memory_t @@ -3067,13 +3380,7 @@ public partial struct ecs_entity_desc_t public byte* symbol; - public bool use_low_id; - - public ulong* add; - - public ecs_value_t* set; - - public byte* add_expr; + public bool use_low_id; } public partial struct ecs_entity_range_t @@ -3152,6 +3459,8 @@ public partial struct ecs_event_desc_t public void* const_param; + public void* set_ptr; + public void* observable; public uint flags; @@ -3171,6 +3480,8 @@ public partial struct ecs_event_record_t public ecs_map_t event_ids; + public ulong event_ids_filter; + public ulong @event; } @@ -3194,11 +3505,11 @@ public partial struct ecs_expr_eval_desc_t public bool allow_unresolved_identifiers; - public ecs_script_runtime_t* runtime; + public bool partial; - public void* script_visitor; + public ecs_script_runtime_t* runtime; - public delegate* unmanaged unresolved_identifier_action; + public void* script_visitor; } public partial struct ecs_expr_node_t @@ -3224,6 +3535,8 @@ public partial struct ecs_function_ctx_t public ulong function; + public ulong entity; + public void* ctx; } @@ -3263,6 +3576,10 @@ public partial struct ecs_hashmap_t public int value_size; + public int value_offset; + + public int bucket_size; + public ecs_map_t impl; } @@ -3277,9 +3594,7 @@ public partial struct ecs_header_t public partial struct ecs_hm_bucket_t { - public ecs_vec_t keys; - - public ecs_vec_t values; + public ecs_hm_bucket_t* next; } public partial struct ecs_http_connection_t @@ -3357,7 +3672,7 @@ public partial struct ecs_http_server_t public partial struct ecs_iter_private_t { - public ecs_iter_private_t.AnonymousRecord_api_types_L145_C5 iter; + public ecs_iter_private_t.AnonymousRecord_api_types_L177_C5 iter; public void* entity_iter; @@ -3366,9 +3681,9 @@ public partial struct ecs_iter_private_t public partial struct ecs_iter_t { - public ecs_world_t* world; + public ecs_world_t* stage; - public ecs_world_t* real_world; + public ecs_world_t* world; public int offset; @@ -3490,6 +3805,15 @@ public partial struct ecs_iter_to_json_desc_t public void* query; } + public partial struct ecs_map_desc_t + { + public ulong entity; + + public ulong key_type; + + public ulong type; + } + public partial struct ecs_map_iter_t { public ecs_map_t* map; @@ -3631,7 +3955,7 @@ public partial struct ecs_meta_op_t public ecs_type_info_t* type_info; - public ecs_meta_op_t.AnonymousRecord_meta_L579_C5 @is; + public ecs_meta_op_t.AnonymousRecord_meta_L594_C5 @is; } public partial struct ecs_meta_scope_t @@ -3654,6 +3978,10 @@ public partial struct ecs_meta_scope_t public bool is_collection; + public bool is_map; + + public bool is_value; + public bool is_empty_scope; public bool is_moved_scope; @@ -3712,8 +4040,6 @@ public partial struct ecs_misc_memory_t public int bytes_commands; - public int bytes_rematch_monitor; - public int bytes_component_ids; public int bytes_reflection; @@ -3731,6 +4057,17 @@ public partial struct ecs_mixins_t { } + public partial struct ecs_mut_var_desc_t + { + public byte* name; + + public ulong parent; + + public ulong type; + + public void* value; + } + public partial struct ecs_observable_t { public ecs_event_record_t on_add; @@ -3741,6 +4078,10 @@ public partial struct ecs_observable_t public ecs_event_record_t on_wildcard; + public ecs_event_record_t on_table_create; + + public ecs_event_record_t on_table_delete; + public ecs_sparse_t events; public ecs_vec_t global_observers; @@ -3901,6 +4242,16 @@ public partial struct ecs_os_api_t public delegate* unmanaged fclose_; + public delegate* unmanaged fread_; + + public delegate* unmanaged fwrite_; + + public delegate* unmanaged mkdir_; + + public delegate* unmanaged rmdir_; + + public delegate* unmanaged remove_; + public delegate* unmanaged perf_trace_push_; public delegate* unmanaged perf_trace_pop_; @@ -3927,13 +4278,6 @@ public partial struct ecs_page_iter_t public int remaining; } - public partial struct ecs_parent_record_t - { - public uint entity; - - public int count; - } - public partial struct ecs_pipeline_desc_t { public ulong entity; @@ -3973,11 +4317,18 @@ public partial struct ecs_query_cache_match_t { } - public partial struct ecs_query_count_t + public partial struct ecs_query_cache_revalidate_t { - public int results; + public ulong query; - public int entities; + public ulong table_id; + } + + public partial struct ecs_query_count_t + { + public int results; + + public int entities; public int tables; } @@ -4046,6 +4397,10 @@ public partial struct ecs_query_iter_t public ulong* written; + public ecs_query_op_profile_t* profile; + + public short op; + public ecs_query_cache_group_t* group; public ecs_vec_t* tables; @@ -4058,11 +4413,9 @@ public partial struct ecs_query_iter_t public int all_cur; - public ecs_query_op_profile_t* profile; - - public short op; + public bool iter_single_group; - public bool iter_single_group; + public ecs_query_trivial_ctx_t trivial; } public partial struct ecs_query_memory_t @@ -4162,13 +4515,24 @@ public partial struct ecs_query_t public ulong entity; - public ecs_world_t* real_world; + public ecs_world_t* stage; public ecs_world_t* world; public int eval_count; } + public partial struct ecs_query_trivial_ctx_t + { + public ecs_table_cache_iter_t it; + + public ecs_table_record_t* tr; + + public int start_from; + + public int first_to_eval; + } + public partial struct ecs_query_var_t { } @@ -4208,7 +4572,9 @@ public partial struct ecs_rest_ctx_t public ecs_map_t cmd_captures; - public double last_time; + public double last_time; + + public bool @readonly; } public partial struct ecs_script_desc_t @@ -4217,14 +4583,24 @@ public partial struct ecs_script_desc_t public byte* filename; - public byte* code; + public byte* code; + + public bool skip_unknown; + + public bool ir; + } + + public partial struct ecs_script_edits_t + { } public partial struct ecs_script_eval_desc_t { - public ecs_script_vars_t* vars; + public ecs_script_runtime_t* runtime; + + public bool skip_unknown; - public ecs_script_runtime_t* runtime; + public bool ir; } public partial struct ecs_script_eval_result_t @@ -4236,6 +4612,24 @@ public partial struct ecs_script_eval_result_t public int column; } + public partial struct ecs_script_event_hooks_t + { + public delegate* unmanaged to_local; + + public delegate* unmanaged to_focus; + + public delegate* unmanaged to_screen; + + public void* ctx; + } + + public partial struct ecs_script_event_result_t + { + public int resolved; + + public bool stopped; + } + public partial struct ecs_script_function_t { public ulong return_type; @@ -4244,6 +4638,10 @@ public partial struct ecs_script_function_t public delegate* unmanaged callback; + public delegate* unmanaged async_callback; + + public delegate* unmanaged async_cancel; + public InlineArrays.delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18 vector_callbacks; public void* ctx; @@ -4253,17 +4651,40 @@ public partial struct ecs_script_function_t public delegate* unmanaged binding_ctx_free; } + public partial struct ecs_script_future_t + { + } + public partial struct ecs_script_parameter_t { public byte* name; - public ulong type; + public ulong type; + + public bool optional; + + public byte* brief; } public partial struct ecs_script_runtime_t { } + public partial struct ecs_script_source_t + { + public int offset; + + public int length; + + public int line; + + public int column; + + public bool has_scope; + + public ulong template_; + } + public partial struct ecs_script_t { public ecs_world_t* world; @@ -4273,6 +4694,30 @@ public partial struct ecs_script_t public byte* code; } + public partial struct ecs_script_task_desc_t + { + public ulong entity; + + public void* ctx; + + public delegate* unmanaged ctx_free; + + public ecs_script_task_loop_t loop; + + public int iterations; + } + + public partial struct ecs_script_task_t + { + } + + public partial struct ecs_script_template_ref_t + { + public ulong type; + + public void* value; + } + public partial struct ecs_script_template_t { } @@ -4287,7 +4732,9 @@ public partial struct ecs_script_var_t public int sp; - public bool is_const; + public bool is_const; + + public bool owned; } public partial struct ecs_script_vars_t @@ -4320,6 +4767,163 @@ public partial struct ecs_serializer_t public void* ctx; } + public partial struct ecs_shell_component_value_t + { + public ulong id; + + public ecs_value_t value; + } + + public partial struct ecs_shell_doc_info_t + { + public ulong entity; + + public byte* name; + + public byte* brief; + + public byte* detail; + + public byte* link; + + public byte* color; + } + + public partial struct ecs_shell_entity_info_t + { + public ulong entity; + + public ulong id; + + public ecs_vec_t components; + + public ecs_vec_t ids; + } + + public partial struct ecs_shell_grep_match_t + { + public ulong entity; + + public ulong id; + + public byte* text; + } + + public partial struct ecs_shell_info_t + { + public byte* name; + + public byte* brief; + + public ecs_vec_t @params; + + public ulong return_type; + } + + public partial struct ecs_shell_param_info_t + { + public byte* name; + + public ulong type; + + public bool optional; + + public byte* brief; + } + + public partial struct ecs_shell_pointer_state_t + { + public EcsScriptMouseEvent @event; + + public ulong pressed; + } + + public partial struct ecs_shell_query_row_t + { + public ulong entity; + + public ecs_vec_t fields; + } + + public partial struct ecs_shell_resource_t + { + public byte* name; + + public byte* content_type; + } + + public partial struct ecs_shell_result_t + { + public ecs_vec_t results; + + public ecs_vec_t errors; + } + + public partial struct ecs_shell_script_error_t + { + public ulong script; + + public byte* error; + } + + public partial struct ecs_shell_script_info_t + { + public ulong script; + + public byte* filename; + + public int lines; + + public bool unsaved; + + public byte* error; + } + + public partial struct ecs_shell_script_line_t + { + public int line; + + public byte* text; + } + + public partial struct ecs_shell_script_location_t + { + public ulong script; + + public int line; + + public int column; + + public ulong template_; + + public byte* statement; + } + + public partial struct ecs_shell_script_match_t + { + public ulong script; + + public int line; + + public byte* text; + } + + public partial struct ecs_shell_session_desc_t + { + public ulong entity; + + public ulong scope; + + public int history_size; + } + + public partial struct ecs_shell_tree_node_t + { + public ulong entity; + + public int depth; + } + public partial struct ecs_sparse_page_t { public int* sparse; @@ -4378,6 +4982,9 @@ public partial struct ecs_stack_t public ecs_stack_cursor_t* tail_cursor; #if DEBUG public int cursor_count; +#endif +#if DEBUG +public int oversized_count; #endif } @@ -4420,21 +5027,7 @@ public partial struct ecs_suspend_readonly_state_t { public bool is_readonly; - public bool is_deferred; - - public bool cmd_flushing; - - public int defer_count; - - public ulong scope; - - public ulong with; - - public InlineArrays.ecs_commands_t_2 cmd_stack; - - public ecs_commands_t* cmd; - - public ecs_stage_t* stage; + public ulong scope; } public partial struct ecs_sync_stats_t @@ -4547,26 +5140,35 @@ public partial struct ecs_system_t public delegate* unmanaged dtor; } - public partial struct ecs_table_cache_hdr_t + public partial struct ecs_table_cache_elem_t { - public ecs_component_record_t* cr; - public ecs_table_t* table; - public ecs_table_cache_hdr_t* prev; + public ecs_table_record_t* tr; - public ecs_table_cache_hdr_t* next; + public short column; + + public short index; + + public short count; + } + + public partial struct ecs_table_cache_hdr_t + { + public ecs_component_record_t* cr; + + public ecs_table_t* table; } public partial struct ecs_table_cache_iter_t { - public ecs_table_cache_hdr_t* cur; + public ecs_table_cache_elem_t* elems; - public ecs_table_cache_hdr_t* next; + public int remaining; - public bool iter_fill; + public ecs_table_cache_elem_t* cur; - public bool iter_empty; + public uint flags; } public partial struct ecs_table_diff_t @@ -4724,6 +5326,8 @@ public partial struct ecs_type_hooks_t public delegate* unmanaged on_replace; + public delegate* unmanaged on_validate; + public void* ctx; public void* binding_ctx; @@ -4747,7 +5351,9 @@ public partial struct ecs_type_info_t public ulong component; - public byte* name; + public byte* name; + + public int refcount; } public partial struct ecs_type_t @@ -4894,7 +5500,7 @@ public partial struct ecs_world_info_t public uint creation_time; - public ecs_world_info_t.AnonymousRecord_flecs_L1542_C5 cmd; + public ecs_world_info_t.AnonymousRecord_flecs_L1563_C5 cmd; public byte* name_prefix; } @@ -4965,6 +5571,21 @@ public partial struct EcsBitmask public int dummy_; } + public partial struct EcsCommandSession + { + public ulong scope; + + public ecs_vec_t history; + + public int history_size; + + public ecs_vec_t results; + + public ecs_vec_t resources; + + public byte* resource_path; + } + public partial struct EcsComponent { public int size; @@ -4979,11 +5600,6 @@ public partial struct EcsConstants public ecs_vec_t ordered_constants; } - public partial struct EcsDefaultChildComponent - { - public ulong component; - } - public partial struct EcsDocDescription { public byte* value; @@ -5007,6 +5623,13 @@ public partial struct EcsIdentifier public ecs_hashmap_t* index; } + public partial struct EcsMap + { + public ulong key_type; + + public ulong type; + } + public partial struct EcsMember { public ulong type; @@ -5117,7 +5740,9 @@ public partial struct EcsRest public byte* ipaddr; - public ecs_rest_ctx_t* impl; + public ecs_rest_ctx_t* impl; + + public bool @readonly; } public partial struct EcsScript @@ -5130,28 +5755,137 @@ public partial struct EcsScript public ecs_script_t* script; - public ecs_script_template_t* template_; - } + public ecs_script_template_t* template_; - public partial struct EcsScriptConstVar - { - public ecs_value_t value; + public ecs_vec_t observers; - public ecs_type_info_t* type_info; - } + public ecs_vec_t dyn_observers; - public partial struct EcsScriptRng - { - public ulong seed; + public bool skip_unknown; - public void* impl; - } + public bool ir; - public partial struct EcsStatsHeader - { - public float elapsed; + public byte* saved_code; - public int reduce_count; + public ecs_vec_t undo; + } + + public partial struct EcsScriptActivateEvent + { + public ulong target; + + public bool keyboard; + + public float local_x; + + public float local_y; + + public bool ctrl; + + public bool shift; + + public bool alt; + + public bool meta; + + public ulong id; + } + + public partial struct EcsScriptConstVar + { + public ecs_value_t value; + + public ecs_type_info_t* type_info; + } + + public partial struct EcsScriptFocusEvent + { + public ulong target; + + public ulong related; + + public ulong id; + } + + public partial struct EcsScriptKeyboardEvent + { + public byte* key; + + public bool down; + + public bool repeat; + + public bool ctrl; + + public bool shift; + + public bool alt; + + public bool meta; + + public ulong id; + } + + public partial struct EcsScriptMouseEvent + { + public ulong target; + + public float screen_x; + + public float screen_y; + + public float local_x; + + public float local_y; + + public float delta_x; + + public float delta_y; + + public int button; + + public uint buttons; + + public bool ctrl; + + public bool shift; + + public bool alt; + + public bool meta; + + public ulong id; + } + + public partial struct EcsScriptMutVar + { + public ecs_value_t value; + + public ecs_type_info_t* type_info; + } + + public partial struct EcsScriptRng + { + public ulong seed; + + public void* impl; + } + + public partial struct EcsScriptShell + { + public ecs_vec_t command_paths; + } + + public partial struct EcsScriptTask + { + public ecs_vec_t tasks; + } + + public partial struct EcsStatsHeader + { + public float elapsed; + + public int reduce_count; } public partial struct EcsStruct @@ -5327,7 +6061,7 @@ public partial struct flecs_hashmap_iter_t public ecs_hm_bucket_t* bucket; - public int index; + public ecs_hashmap_t* map; } public partial struct flecs_hashmap_result_t @@ -5375,15 +6109,6 @@ public partial struct int_2 } } - public partial struct InlineArrays - { - [InlineArray(2)] - public partial struct ecs_commands_t_2 - { - public ecs_commands_t Item0; - } - } - public partial struct InlineArrays { [InlineArray(32)] @@ -5476,19 +6201,19 @@ public partial struct ecs_alert_severity_filter_t_4 public partial struct InlineArrays { - [InlineArray(18)] - public partial struct delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18 + [InlineArray(16)] + public partial struct ecs_script_parameter_t_16 { - public delegate* unmanaged Item0; + public ecs_script_parameter_t Item0; } } public partial struct InlineArrays { - [InlineArray(16)] - public partial struct ecs_script_parameter_t_16 + [InlineArray(18)] + public partial struct delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18 { - public ecs_script_parameter_t Item0; + public delegate* unmanaged Item0; } } @@ -5640,9 +6365,9 @@ public partial struct ecs_member_t_32 public const int ECS_REST_DEFAULT_PORT = 27750; - public const uint ECS_ROW_FLAGS_MASK = 4026531840; + public const uint ECS_ROW_FLAGS_MASK = 4160749568; - public const uint ECS_ROW_MASK = 268435455; + public const uint ECS_ROW_MASK = 134217727; public const int ecs_stage_t_magic = 1701016435; @@ -5720,6 +6445,8 @@ public partial struct ecs_member_t_32 public const uint EcsEntityHasDontFragment = 268435456; + public const uint EcsEntityIsBase = 134217728; + public const uint EcsEntityIsId = 2147483648; public const uint EcsEntityIsTarget = 1073741824; @@ -5738,10 +6465,14 @@ public partial struct ecs_member_t_32 public const uint EcsIdDontFragment = 4194304; - public const uint EcsIdEventMask = 20905984; + public const uint EcsIdEventMask = 2168389632; public const uint EcsIdExclusive = 512; + public const uint EcsIdHasBases = 134217728; + + public const uint EcsIdHasDerived = 268435456; + public const uint EcsIdHasOnAdd = 65536; public const uint EcsIdHasOnRemove = 131072; @@ -5752,6 +6483,8 @@ public partial struct ecs_member_t_32 public const uint EcsIdHasOnTableDelete = 1048576; + public const uint EcsIdHasUpNotify = 2147483648; + public const uint EcsIdInheritable = 32768; public const uint EcsIdIsTransitive = 16384; @@ -5776,14 +6509,14 @@ public partial struct ecs_member_t_32 public const uint EcsIdOnDeleteTargetRemove = 8; + public const uint EcsIdOnInstantiateCopy = 64; + public const uint EcsIdOnInstantiateDontInherit = 256; public const uint EcsIdOnInstantiateInherit = 128; public const uint EcsIdOnInstantiateMask = 448; - public const uint EcsIdOnInstantiateOverride = 64; - public const uint EcsIdOrderedChildren = 16777216; public const uint EcsIdPairIsTag = 2048; @@ -5806,6 +6539,8 @@ public partial struct ecs_member_t_32 public const uint EcsIterCached = 32768; + public const uint EcsIterComponentInheritance = 1024; + public const uint EcsIterCppEach = 524288; public const uint EcsIterFixedInChangeComputed = 65536; @@ -5826,18 +6561,26 @@ public partial struct ecs_member_t_32 public const uint EcsIterNoResults = 4; + public const uint EcsIterOpCtxFini = 8192; + + public const uint EcsIterOpCtxSplit = 4194304; + public const uint EcsIterProfile = 128; public const uint EcsIterSkip = 262144; public const uint EcsIterTableOnly = 1048576; + public const uint EcsIterTreeCached = 4096; + public const uint EcsIterTrivialCached = 16384; public const uint EcsIterTrivialChangeDetection = 32; public const uint EcsIterTrivialSearch = 256; + public const uint EcsIterTrivialSparse = 512; + public const uint EcsIterTrivialTest = 2048; public const uint EcsNonTrivialIdInherit = 4; @@ -5856,6 +6599,8 @@ public partial struct ecs_member_t_32 public const uint EcsObserverIsParentDisabled = 64; + public const uint EcsObserverIsUpNotify = 4096; + public const uint EcsObserverKeepAlive = 2048; public const uint EcsObserverMatchDisabled = 4; @@ -5890,6 +6635,8 @@ public partial struct ecs_member_t_32 public const uint EcsQueryHasChangeDetection = 4194304; + public const uint EcsQueryHasComponentInheritance = 1; + public const uint EcsQueryHasCondSet = 65536; public const uint EcsQueryHasNonThisOutTerms = 2097152; @@ -5926,20 +6673,28 @@ public partial struct ecs_member_t_32 public const uint EcsQueryNested = 536870912; + public const uint EcsQuerySelfTrivial = 32; + public const uint EcsQueryTableOnly = 128; public const uint EcsQueryTrivialCache = 268435456; + public const uint EcsQueryTrivialSparse = 16; + public const uint EcsQueryValid = 2147483648; public const ulong EcsSelf = 9223372036854775808; - public const uint EcsTableAddEdgeFlags = 2162688; + public const uint EcsTableAddEdgeFlags = 2149646336; - public const uint EcsTableEdgeFlags = 2293760; + public const uint EcsTableEdgeDontFragment = 4194304; + + public const uint EcsTableEdgeFlags = 2149777408; public const uint EcsTableEdgeReparent = 268435456; + public const uint EcsTableEmpty = 67108864; + public const uint EcsTableHasAddActions = 329732; public const uint EcsTableHasBuiltins = 1; @@ -5950,7 +6705,7 @@ public partial struct ecs_member_t_32 public const uint EcsTableHasCtors = 2048; - public const uint EcsTableHasDontFragment = 4194304; + public const uint EcsTableHasDerived = 8; public const uint EcsTableHasDtors = 4096; @@ -5962,8 +6717,6 @@ public partial struct ecs_member_t_32 public const uint EcsTableHasMove = 16384; - public const uint EcsTableHasMultiIsA = 8; - public const uint EcsTableHasName = 64; public const uint EcsTableHasOnAdd = 65536; @@ -5992,6 +6745,8 @@ public partial struct ecs_member_t_32 public const uint EcsTableHasTraversable = 134217728; + public const uint EcsTableHasUpNotify = 2147483648; + public const uint EcsTableIsComplex = 2136064; public const uint EcsTableIsDisabled = 512; @@ -6000,11 +6755,15 @@ public partial struct ecs_member_t_32 public const uint EcsTableMarkedForDelete = 536870912; + public const uint EcsTableNotEmpty = 1073741824; + public const uint EcsTableNotQueryable = 1024; public const uint EcsTableOverrideDontFragment = 8388608; - public const uint EcsTableRemoveEdgeFlags = 19005440; + public const uint EcsTableRemoveActionFlags = 150994977; + + public const uint EcsTableRemoveEdgeFlags = 2166489088; public const uint EcsTermDontFragment = 4096; @@ -6078,6 +6837,10 @@ public partial struct ecs_member_t_32 public const int FLECS_SCRIPT_FUNCTION_ARGS_MAX = 16; + public const int FLECS_SCRIPT_SHELL_HISTORY_SIZE = 256; + + public const int FLECS_SCRIPT_UNDO_MAX = 64; + public const int FLECS_SCRIPT_VECTOR_FUNCTION_COUNT = 18; public const int FLECS_SPARSE_PAGE_BITS = 6; @@ -6094,15 +6857,13 @@ public partial struct ecs_member_t_32 public const int FLECS_TREE_SPAWNER_DEPTH_CACHE_SIZE = 6; - public const int FLECS_VARIABLE_COUNT_MAX = 64; - - public const string FLECS_VERSION = "4.1.6"; + public const string FLECS_VERSION = "4.2.0"; public const int FLECS_VERSION_MAJOR = 4; - public const int FLECS_VERSION_MINOR = 1; + public const int FLECS_VERSION_MINOR = 2; - public const int FLECS_VERSION_PATCH = 6; + public const int FLECS_VERSION_PATCH = 0; [DllImport(BindgenInternal.DllImportPath, EntryPoint = "ECS_AUTO_OVERRIDE_BindgenGetExtern")] private static extern void* ECS_AUTO_OVERRIDE_BindgenGetExtern(); @@ -6257,6 +7018,9 @@ public partial struct ecs_member_t_32 [DllImport(BindgenInternal.DllImportPath, EntryPoint = "EcsConstant_BindgenGetExtern")] private static extern void* EcsConstant_BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "EcsCopy_BindgenGetExtern")] + private static extern void* EcsCopy_BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "EcsCounter_BindgenGetExtern")] private static extern void* EcsCounter_BindgenGetExtern(); @@ -6566,6 +7330,9 @@ public partial struct ecs_member_t_32 [DllImport(BindgenInternal.DllImportPath, EntryPoint = "EcsOnLoad_BindgenGetExtern")] private static extern void* EcsOnLoad_BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "EcsOnQueryCacheRevalidate_BindgenGetExtern")] + private static extern void* EcsOnQueryCacheRevalidate_BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "EcsOnRemove_BindgenGetExtern")] private static extern void* EcsOnRemove_BindgenGetExtern(); @@ -6593,9 +7360,6 @@ public partial struct ecs_member_t_32 [DllImport(BindgenInternal.DllImportPath, EntryPoint = "EcsOrderedChildren_BindgenGetExtern")] private static extern void* EcsOrderedChildren_BindgenGetExtern(); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "EcsOverride_BindgenGetExtern")] - private static extern void* EcsOverride_BindgenGetExtern(); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "EcsPairIsTag_BindgenGetExtern")] private static extern void* EcsPairIsTag_BindgenGetExtern(); @@ -6707,6 +7471,12 @@ public partial struct ecs_member_t_32 [DllImport(BindgenInternal.DllImportPath, EntryPoint = "EcsScriptTemplate_BindgenGetExtern")] private static extern void* EcsScriptTemplate_BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "EcsScriptTemplateManual_BindgenGetExtern")] + private static extern void* EcsScriptTemplateManual_BindgenGetExtern(); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "EcsScriptTemplatePending_BindgenGetExtern")] + private static extern void* EcsScriptTemplatePending_BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "EcsScriptVectorType_BindgenGetExtern")] private static extern void* EcsScriptVectorType_BindgenGetExtern(); @@ -6716,9 +7486,6 @@ public partial struct ecs_member_t_32 [DllImport(BindgenInternal.DllImportPath, EntryPoint = "EcsSingleton_BindgenGetExtern")] private static extern void* EcsSingleton_BindgenGetExtern(); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "EcsSlotOf_BindgenGetExtern")] - private static extern void* EcsSlotOf_BindgenGetExtern(); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "EcsSparse_BindgenGetExtern")] private static extern void* EcsSparse_BindgenGetExtern(); @@ -6860,6 +7627,12 @@ public partial struct ecs_member_t_32 [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDecs_query_memory_tID__BindgenGetExtern")] private static extern void* FLECS_IDecs_query_memory_tID__BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDecs_script_template_ref_tID__BindgenGetExtern")] + private static extern void* FLECS_IDecs_script_template_ref_tID__BindgenGetExtern(); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDecs_shell_resource_tID__BindgenGetExtern")] + private static extern void* FLECS_IDecs_shell_resource_tID__BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDecs_string_tID__BindgenGetExtern")] private static extern void* FLECS_IDecs_string_tID__BindgenGetExtern(); @@ -6884,6 +7657,9 @@ public partial struct ecs_member_t_32 [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDecs_uptr_tID__BindgenGetExtern")] private static extern void* FLECS_IDecs_uptr_tID__BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDecs_value_tID__BindgenGetExtern")] + private static extern void* FLECS_IDecs_value_tID__BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsAlertCriticalID__BindgenGetExtern")] private static extern void* FLECS_IDEcsAlertCriticalID__BindgenGetExtern(); @@ -6914,6 +7690,9 @@ public partial struct ecs_member_t_32 [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsBitmaskID__BindgenGetExtern")] private static extern void* FLECS_IDEcsBitmaskID__BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsCommandSessionID__BindgenGetExtern")] + private static extern void* FLECS_IDEcsCommandSessionID__BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsComponentID__BindgenGetExtern")] private static extern void* FLECS_IDEcsComponentID__BindgenGetExtern(); @@ -6929,9 +7708,6 @@ public partial struct ecs_member_t_32 [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsCounterIncrementID__BindgenGetExtern")] private static extern void* FLECS_IDEcsCounterIncrementID__BindgenGetExtern(); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsDefaultChildComponentID__BindgenGetExtern")] - private static extern void* FLECS_IDEcsDefaultChildComponentID__BindgenGetExtern(); - [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsDocDescriptionID__BindgenGetExtern")] private static extern void* FLECS_IDEcsDocDescriptionID__BindgenGetExtern(); @@ -6944,6 +7720,9 @@ public partial struct ecs_member_t_32 [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsIdentifierID__BindgenGetExtern")] private static extern void* FLECS_IDEcsIdentifierID__BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsMapID__BindgenGetExtern")] + private static extern void* FLECS_IDEcsMapID__BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsMemberID__BindgenGetExtern")] private static extern void* FLECS_IDEcsMemberID__BindgenGetExtern(); @@ -6986,24 +7765,51 @@ public partial struct ecs_member_t_32 [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsRestID__BindgenGetExtern")] private static extern void* FLECS_IDEcsRestID__BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsScriptActivateEventID__BindgenGetExtern")] + private static extern void* FLECS_IDEcsScriptActivateEventID__BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsScriptConstVarID__BindgenGetExtern")] private static extern void* FLECS_IDEcsScriptConstVarID__BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsScriptFocusEventID__BindgenGetExtern")] + private static extern void* FLECS_IDEcsScriptFocusEventID__BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsScriptFunctionID__BindgenGetExtern")] private static extern void* FLECS_IDEcsScriptFunctionID__BindgenGetExtern(); [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsScriptID__BindgenGetExtern")] private static extern void* FLECS_IDEcsScriptID__BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsScriptKeyboardEventID__BindgenGetExtern")] + private static extern void* FLECS_IDEcsScriptKeyboardEventID__BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsScriptMethodID__BindgenGetExtern")] private static extern void* FLECS_IDEcsScriptMethodID__BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsScriptMouseEventID__BindgenGetExtern")] + private static extern void* FLECS_IDEcsScriptMouseEventID__BindgenGetExtern(); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsScriptMutVarID__BindgenGetExtern")] + private static extern void* FLECS_IDEcsScriptMutVarID__BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsScriptRngID__BindgenGetExtern")] private static extern void* FLECS_IDEcsScriptRngID__BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsScriptShellID__BindgenGetExtern")] + private static extern void* FLECS_IDEcsScriptShellID__BindgenGetExtern(); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsScriptTaskID__BindgenGetExtern")] + private static extern void* FLECS_IDEcsScriptTaskID__BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsScriptTemplateID__BindgenGetExtern")] private static extern void* FLECS_IDEcsScriptTemplateID__BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsScriptTemplateManualID__BindgenGetExtern")] + private static extern void* FLECS_IDEcsScriptTemplateManualID__BindgenGetExtern(); + + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsScriptTemplatePendingID__BindgenGetExtern")] + private static extern void* FLECS_IDEcsScriptTemplatePendingID__BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDEcsScriptVectorTypeID__BindgenGetExtern")] private static extern void* FLECS_IDEcsScriptVectorTypeID__BindgenGetExtern(); @@ -7055,6 +7861,9 @@ public partial struct ecs_member_t_32 [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FLECS_IDFlecsStatsID__BindgenGetExtern")] private static extern void* FLECS_IDFlecsStatsID__BindgenGetExtern(); + [DllImport(BindgenInternal.DllImportPath, EntryPoint = "FlecsMeta_BindgenGetExtern")] + private static extern void* FlecsMeta_BindgenGetExtern(); + private static void* ECS_AUTO_OVERRIDE_Ptr; private static void* ecs_block_allocator_alloc_count_Ptr; @@ -7157,6 +7966,8 @@ public partial struct ecs_member_t_32 private static void* EcsConstant_Ptr; + private static void* EcsCopy_Ptr; + private static void* EcsCounter_Ptr; private static void* EcsCounterId_Ptr; @@ -7363,6 +8174,8 @@ public partial struct ecs_member_t_32 private static void* EcsOnLoad_Ptr; + private static void* EcsOnQueryCacheRevalidate_Ptr; + private static void* EcsOnRemove_Ptr; private static void* EcsOnSet_Ptr; @@ -7381,8 +8194,6 @@ public partial struct ecs_member_t_32 private static void* EcsOrderedChildren_Ptr; - private static void* EcsOverride_Ptr; - private static void* EcsPairIsTag_Ptr; private static void* EcsPanic_Ptr; @@ -7457,14 +8268,16 @@ public partial struct ecs_member_t_32 private static void* EcsScriptTemplate_Ptr; + private static void* EcsScriptTemplateManual_Ptr; + + private static void* EcsScriptTemplatePending_Ptr; + private static void* EcsScriptVectorType_Ptr; private static void* EcsSeconds_Ptr; private static void* EcsSingleton_Ptr; - private static void* EcsSlotOf_Ptr; - private static void* EcsSparse_Ptr; private static void* EcsSpeed_Ptr; @@ -7559,6 +8372,10 @@ public partial struct ecs_member_t_32 private static void* FLECS_IDecs_query_memory_tID__Ptr; + private static void* FLECS_IDecs_script_template_ref_tID__Ptr; + + private static void* FLECS_IDecs_shell_resource_tID__Ptr; + private static void* FLECS_IDecs_string_tID__Ptr; private static void* FLECS_IDecs_table_histogram_tID__Ptr; @@ -7575,6 +8392,8 @@ public partial struct ecs_member_t_32 private static void* FLECS_IDecs_uptr_tID__Ptr; + private static void* FLECS_IDecs_value_tID__Ptr; + private static void* FLECS_IDEcsAlertCriticalID__Ptr; private static void* FLECS_IDEcsAlertErrorID__Ptr; @@ -7595,6 +8414,8 @@ public partial struct ecs_member_t_32 private static void* FLECS_IDEcsBitmaskID__Ptr; + private static void* FLECS_IDEcsCommandSessionID__Ptr; + private static void* FLECS_IDEcsComponentID__Ptr; private static void* FLECS_IDEcsConstantsID__Ptr; @@ -7605,8 +8426,6 @@ public partial struct ecs_member_t_32 private static void* FLECS_IDEcsCounterIncrementID__Ptr; - private static void* FLECS_IDEcsDefaultChildComponentID__Ptr; - private static void* FLECS_IDEcsDocDescriptionID__Ptr; private static void* FLECS_IDEcsEnumID__Ptr; @@ -7615,6 +8434,8 @@ public partial struct ecs_member_t_32 private static void* FLECS_IDEcsIdentifierID__Ptr; + private static void* FLECS_IDEcsMapID__Ptr; + private static void* FLECS_IDEcsMemberID__Ptr; private static void* FLECS_IDEcsMemberRangesID__Ptr; @@ -7643,18 +8464,36 @@ public partial struct ecs_member_t_32 private static void* FLECS_IDEcsRestID__Ptr; + private static void* FLECS_IDEcsScriptActivateEventID__Ptr; + private static void* FLECS_IDEcsScriptConstVarID__Ptr; + private static void* FLECS_IDEcsScriptFocusEventID__Ptr; + private static void* FLECS_IDEcsScriptFunctionID__Ptr; private static void* FLECS_IDEcsScriptID__Ptr; + private static void* FLECS_IDEcsScriptKeyboardEventID__Ptr; + private static void* FLECS_IDEcsScriptMethodID__Ptr; + private static void* FLECS_IDEcsScriptMouseEventID__Ptr; + + private static void* FLECS_IDEcsScriptMutVarID__Ptr; + private static void* FLECS_IDEcsScriptRngID__Ptr; + private static void* FLECS_IDEcsScriptShellID__Ptr; + + private static void* FLECS_IDEcsScriptTaskID__Ptr; + private static void* FLECS_IDEcsScriptTemplateID__Ptr; + private static void* FLECS_IDEcsScriptTemplateManualID__Ptr; + + private static void* FLECS_IDEcsScriptTemplatePendingID__Ptr; + private static void* FLECS_IDEcsScriptVectorTypeID__Ptr; private static void* FLECS_IDEcsStructID__Ptr; @@ -7689,6 +8528,8 @@ public partial struct ecs_member_t_32 private static void* FLECS_IDFlecsStatsID__Ptr; + private static void* FlecsMeta_Ptr; + public static ref ulong ECS_AUTO_OVERRIDE => ref *(ulong*)(ECS_AUTO_OVERRIDE_Ptr == null ? ECS_AUTO_OVERRIDE_Ptr = ECS_AUTO_OVERRIDE_BindgenGetExtern() : ECS_AUTO_OVERRIDE_Ptr); public static ref long ecs_block_allocator_alloc_count => ref *(long*)(ecs_block_allocator_alloc_count_Ptr == null ? ecs_block_allocator_alloc_count_Ptr = ecs_block_allocator_alloc_count_BindgenGetExtern() : ecs_block_allocator_alloc_count_Ptr); @@ -7791,6 +8632,8 @@ public partial struct ecs_member_t_32 public static ref ulong EcsConstant => ref *(ulong*)(EcsConstant_Ptr == null ? EcsConstant_Ptr = EcsConstant_BindgenGetExtern() : EcsConstant_Ptr); + public static ref ulong EcsCopy => ref *(ulong*)(EcsCopy_Ptr == null ? EcsCopy_Ptr = EcsCopy_BindgenGetExtern() : EcsCopy_Ptr); + public static ref ulong EcsCounter => ref *(ulong*)(EcsCounter_Ptr == null ? EcsCounter_Ptr = EcsCounter_BindgenGetExtern() : EcsCounter_Ptr); public static ref ulong EcsCounterId => ref *(ulong*)(EcsCounterId_Ptr == null ? EcsCounterId_Ptr = EcsCounterId_BindgenGetExtern() : EcsCounterId_Ptr); @@ -7997,6 +8840,8 @@ public partial struct ecs_member_t_32 public static ref ulong EcsOnLoad => ref *(ulong*)(EcsOnLoad_Ptr == null ? EcsOnLoad_Ptr = EcsOnLoad_BindgenGetExtern() : EcsOnLoad_Ptr); + public static ref ulong EcsOnQueryCacheRevalidate => ref *(ulong*)(EcsOnQueryCacheRevalidate_Ptr == null ? EcsOnQueryCacheRevalidate_Ptr = EcsOnQueryCacheRevalidate_BindgenGetExtern() : EcsOnQueryCacheRevalidate_Ptr); + public static ref ulong EcsOnRemove => ref *(ulong*)(EcsOnRemove_Ptr == null ? EcsOnRemove_Ptr = EcsOnRemove_BindgenGetExtern() : EcsOnRemove_Ptr); public static ref ulong EcsOnSet => ref *(ulong*)(EcsOnSet_Ptr == null ? EcsOnSet_Ptr = EcsOnSet_BindgenGetExtern() : EcsOnSet_Ptr); @@ -8015,8 +8860,6 @@ public partial struct ecs_member_t_32 public static ref ulong EcsOrderedChildren => ref *(ulong*)(EcsOrderedChildren_Ptr == null ? EcsOrderedChildren_Ptr = EcsOrderedChildren_BindgenGetExtern() : EcsOrderedChildren_Ptr); - public static ref ulong EcsOverride => ref *(ulong*)(EcsOverride_Ptr == null ? EcsOverride_Ptr = EcsOverride_BindgenGetExtern() : EcsOverride_Ptr); - public static ref ulong EcsPairIsTag => ref *(ulong*)(EcsPairIsTag_Ptr == null ? EcsPairIsTag_Ptr = EcsPairIsTag_BindgenGetExtern() : EcsPairIsTag_Ptr); public static ref ulong EcsPanic => ref *(ulong*)(EcsPanic_Ptr == null ? EcsPanic_Ptr = EcsPanic_BindgenGetExtern() : EcsPanic_Ptr); @@ -8091,14 +8934,16 @@ public partial struct ecs_member_t_32 public static ref ulong EcsScriptTemplate => ref *(ulong*)(EcsScriptTemplate_Ptr == null ? EcsScriptTemplate_Ptr = EcsScriptTemplate_BindgenGetExtern() : EcsScriptTemplate_Ptr); + public static ref ulong EcsScriptTemplateManual => ref *(ulong*)(EcsScriptTemplateManual_Ptr == null ? EcsScriptTemplateManual_Ptr = EcsScriptTemplateManual_BindgenGetExtern() : EcsScriptTemplateManual_Ptr); + + public static ref ulong EcsScriptTemplatePending => ref *(ulong*)(EcsScriptTemplatePending_Ptr == null ? EcsScriptTemplatePending_Ptr = EcsScriptTemplatePending_BindgenGetExtern() : EcsScriptTemplatePending_Ptr); + public static ref ulong EcsScriptVectorType => ref *(ulong*)(EcsScriptVectorType_Ptr == null ? EcsScriptVectorType_Ptr = EcsScriptVectorType_BindgenGetExtern() : EcsScriptVectorType_Ptr); public static ref ulong EcsSeconds => ref *(ulong*)(EcsSeconds_Ptr == null ? EcsSeconds_Ptr = EcsSeconds_BindgenGetExtern() : EcsSeconds_Ptr); public static ref ulong EcsSingleton => ref *(ulong*)(EcsSingleton_Ptr == null ? EcsSingleton_Ptr = EcsSingleton_BindgenGetExtern() : EcsSingleton_Ptr); - public static ref ulong EcsSlotOf => ref *(ulong*)(EcsSlotOf_Ptr == null ? EcsSlotOf_Ptr = EcsSlotOf_BindgenGetExtern() : EcsSlotOf_Ptr); - public static ref ulong EcsSparse => ref *(ulong*)(EcsSparse_Ptr == null ? EcsSparse_Ptr = EcsSparse_BindgenGetExtern() : EcsSparse_Ptr); public static ref ulong EcsSpeed => ref *(ulong*)(EcsSpeed_Ptr == null ? EcsSpeed_Ptr = EcsSpeed_BindgenGetExtern() : EcsSpeed_Ptr); @@ -8193,6 +9038,10 @@ public partial struct ecs_member_t_32 public static ref ulong FLECS_IDecs_query_memory_tID_ => ref *(ulong*)(FLECS_IDecs_query_memory_tID__Ptr == null ? FLECS_IDecs_query_memory_tID__Ptr = FLECS_IDecs_query_memory_tID__BindgenGetExtern() : FLECS_IDecs_query_memory_tID__Ptr); + public static ref ulong FLECS_IDecs_script_template_ref_tID_ => ref *(ulong*)(FLECS_IDecs_script_template_ref_tID__Ptr == null ? FLECS_IDecs_script_template_ref_tID__Ptr = FLECS_IDecs_script_template_ref_tID__BindgenGetExtern() : FLECS_IDecs_script_template_ref_tID__Ptr); + + public static ref ulong FLECS_IDecs_shell_resource_tID_ => ref *(ulong*)(FLECS_IDecs_shell_resource_tID__Ptr == null ? FLECS_IDecs_shell_resource_tID__Ptr = FLECS_IDecs_shell_resource_tID__BindgenGetExtern() : FLECS_IDecs_shell_resource_tID__Ptr); + public static ref ulong FLECS_IDecs_string_tID_ => ref *(ulong*)(FLECS_IDecs_string_tID__Ptr == null ? FLECS_IDecs_string_tID__Ptr = FLECS_IDecs_string_tID__BindgenGetExtern() : FLECS_IDecs_string_tID__Ptr); public static ref ulong FLECS_IDecs_table_histogram_tID_ => ref *(ulong*)(FLECS_IDecs_table_histogram_tID__Ptr == null ? FLECS_IDecs_table_histogram_tID__Ptr = FLECS_IDecs_table_histogram_tID__BindgenGetExtern() : FLECS_IDecs_table_histogram_tID__Ptr); @@ -8209,6 +9058,8 @@ public partial struct ecs_member_t_32 public static ref ulong FLECS_IDecs_uptr_tID_ => ref *(ulong*)(FLECS_IDecs_uptr_tID__Ptr == null ? FLECS_IDecs_uptr_tID__Ptr = FLECS_IDecs_uptr_tID__BindgenGetExtern() : FLECS_IDecs_uptr_tID__Ptr); + public static ref ulong FLECS_IDecs_value_tID_ => ref *(ulong*)(FLECS_IDecs_value_tID__Ptr == null ? FLECS_IDecs_value_tID__Ptr = FLECS_IDecs_value_tID__BindgenGetExtern() : FLECS_IDecs_value_tID__Ptr); + public static ref ulong FLECS_IDEcsAlertCriticalID_ => ref *(ulong*)(FLECS_IDEcsAlertCriticalID__Ptr == null ? FLECS_IDEcsAlertCriticalID__Ptr = FLECS_IDEcsAlertCriticalID__BindgenGetExtern() : FLECS_IDEcsAlertCriticalID__Ptr); public static ref ulong FLECS_IDEcsAlertErrorID_ => ref *(ulong*)(FLECS_IDEcsAlertErrorID__Ptr == null ? FLECS_IDEcsAlertErrorID__Ptr = FLECS_IDEcsAlertErrorID__BindgenGetExtern() : FLECS_IDEcsAlertErrorID__Ptr); @@ -8229,6 +9080,8 @@ public partial struct ecs_member_t_32 public static ref ulong FLECS_IDEcsBitmaskID_ => ref *(ulong*)(FLECS_IDEcsBitmaskID__Ptr == null ? FLECS_IDEcsBitmaskID__Ptr = FLECS_IDEcsBitmaskID__BindgenGetExtern() : FLECS_IDEcsBitmaskID__Ptr); + public static ref ulong FLECS_IDEcsCommandSessionID_ => ref *(ulong*)(FLECS_IDEcsCommandSessionID__Ptr == null ? FLECS_IDEcsCommandSessionID__Ptr = FLECS_IDEcsCommandSessionID__BindgenGetExtern() : FLECS_IDEcsCommandSessionID__Ptr); + public static ref ulong FLECS_IDEcsComponentID_ => ref *(ulong*)(FLECS_IDEcsComponentID__Ptr == null ? FLECS_IDEcsComponentID__Ptr = FLECS_IDEcsComponentID__BindgenGetExtern() : FLECS_IDEcsComponentID__Ptr); public static ref ulong FLECS_IDEcsConstantsID_ => ref *(ulong*)(FLECS_IDEcsConstantsID__Ptr == null ? FLECS_IDEcsConstantsID__Ptr = FLECS_IDEcsConstantsID__BindgenGetExtern() : FLECS_IDEcsConstantsID__Ptr); @@ -8239,8 +9092,6 @@ public partial struct ecs_member_t_32 public static ref ulong FLECS_IDEcsCounterIncrementID_ => ref *(ulong*)(FLECS_IDEcsCounterIncrementID__Ptr == null ? FLECS_IDEcsCounterIncrementID__Ptr = FLECS_IDEcsCounterIncrementID__BindgenGetExtern() : FLECS_IDEcsCounterIncrementID__Ptr); - public static ref ulong FLECS_IDEcsDefaultChildComponentID_ => ref *(ulong*)(FLECS_IDEcsDefaultChildComponentID__Ptr == null ? FLECS_IDEcsDefaultChildComponentID__Ptr = FLECS_IDEcsDefaultChildComponentID__BindgenGetExtern() : FLECS_IDEcsDefaultChildComponentID__Ptr); - public static ref ulong FLECS_IDEcsDocDescriptionID_ => ref *(ulong*)(FLECS_IDEcsDocDescriptionID__Ptr == null ? FLECS_IDEcsDocDescriptionID__Ptr = FLECS_IDEcsDocDescriptionID__BindgenGetExtern() : FLECS_IDEcsDocDescriptionID__Ptr); public static ref ulong FLECS_IDEcsEnumID_ => ref *(ulong*)(FLECS_IDEcsEnumID__Ptr == null ? FLECS_IDEcsEnumID__Ptr = FLECS_IDEcsEnumID__BindgenGetExtern() : FLECS_IDEcsEnumID__Ptr); @@ -8249,6 +9100,8 @@ public partial struct ecs_member_t_32 public static ref ulong FLECS_IDEcsIdentifierID_ => ref *(ulong*)(FLECS_IDEcsIdentifierID__Ptr == null ? FLECS_IDEcsIdentifierID__Ptr = FLECS_IDEcsIdentifierID__BindgenGetExtern() : FLECS_IDEcsIdentifierID__Ptr); + public static ref ulong FLECS_IDEcsMapID_ => ref *(ulong*)(FLECS_IDEcsMapID__Ptr == null ? FLECS_IDEcsMapID__Ptr = FLECS_IDEcsMapID__BindgenGetExtern() : FLECS_IDEcsMapID__Ptr); + public static ref ulong FLECS_IDEcsMemberID_ => ref *(ulong*)(FLECS_IDEcsMemberID__Ptr == null ? FLECS_IDEcsMemberID__Ptr = FLECS_IDEcsMemberID__BindgenGetExtern() : FLECS_IDEcsMemberID__Ptr); public static ref ulong FLECS_IDEcsMemberRangesID_ => ref *(ulong*)(FLECS_IDEcsMemberRangesID__Ptr == null ? FLECS_IDEcsMemberRangesID__Ptr = FLECS_IDEcsMemberRangesID__BindgenGetExtern() : FLECS_IDEcsMemberRangesID__Ptr); @@ -8277,18 +9130,36 @@ public partial struct ecs_member_t_32 public static ref ulong FLECS_IDEcsRestID_ => ref *(ulong*)(FLECS_IDEcsRestID__Ptr == null ? FLECS_IDEcsRestID__Ptr = FLECS_IDEcsRestID__BindgenGetExtern() : FLECS_IDEcsRestID__Ptr); + public static ref ulong FLECS_IDEcsScriptActivateEventID_ => ref *(ulong*)(FLECS_IDEcsScriptActivateEventID__Ptr == null ? FLECS_IDEcsScriptActivateEventID__Ptr = FLECS_IDEcsScriptActivateEventID__BindgenGetExtern() : FLECS_IDEcsScriptActivateEventID__Ptr); + public static ref ulong FLECS_IDEcsScriptConstVarID_ => ref *(ulong*)(FLECS_IDEcsScriptConstVarID__Ptr == null ? FLECS_IDEcsScriptConstVarID__Ptr = FLECS_IDEcsScriptConstVarID__BindgenGetExtern() : FLECS_IDEcsScriptConstVarID__Ptr); + public static ref ulong FLECS_IDEcsScriptFocusEventID_ => ref *(ulong*)(FLECS_IDEcsScriptFocusEventID__Ptr == null ? FLECS_IDEcsScriptFocusEventID__Ptr = FLECS_IDEcsScriptFocusEventID__BindgenGetExtern() : FLECS_IDEcsScriptFocusEventID__Ptr); + public static ref ulong FLECS_IDEcsScriptFunctionID_ => ref *(ulong*)(FLECS_IDEcsScriptFunctionID__Ptr == null ? FLECS_IDEcsScriptFunctionID__Ptr = FLECS_IDEcsScriptFunctionID__BindgenGetExtern() : FLECS_IDEcsScriptFunctionID__Ptr); public static ref ulong FLECS_IDEcsScriptID_ => ref *(ulong*)(FLECS_IDEcsScriptID__Ptr == null ? FLECS_IDEcsScriptID__Ptr = FLECS_IDEcsScriptID__BindgenGetExtern() : FLECS_IDEcsScriptID__Ptr); + public static ref ulong FLECS_IDEcsScriptKeyboardEventID_ => ref *(ulong*)(FLECS_IDEcsScriptKeyboardEventID__Ptr == null ? FLECS_IDEcsScriptKeyboardEventID__Ptr = FLECS_IDEcsScriptKeyboardEventID__BindgenGetExtern() : FLECS_IDEcsScriptKeyboardEventID__Ptr); + public static ref ulong FLECS_IDEcsScriptMethodID_ => ref *(ulong*)(FLECS_IDEcsScriptMethodID__Ptr == null ? FLECS_IDEcsScriptMethodID__Ptr = FLECS_IDEcsScriptMethodID__BindgenGetExtern() : FLECS_IDEcsScriptMethodID__Ptr); + public static ref ulong FLECS_IDEcsScriptMouseEventID_ => ref *(ulong*)(FLECS_IDEcsScriptMouseEventID__Ptr == null ? FLECS_IDEcsScriptMouseEventID__Ptr = FLECS_IDEcsScriptMouseEventID__BindgenGetExtern() : FLECS_IDEcsScriptMouseEventID__Ptr); + + public static ref ulong FLECS_IDEcsScriptMutVarID_ => ref *(ulong*)(FLECS_IDEcsScriptMutVarID__Ptr == null ? FLECS_IDEcsScriptMutVarID__Ptr = FLECS_IDEcsScriptMutVarID__BindgenGetExtern() : FLECS_IDEcsScriptMutVarID__Ptr); + public static ref ulong FLECS_IDEcsScriptRngID_ => ref *(ulong*)(FLECS_IDEcsScriptRngID__Ptr == null ? FLECS_IDEcsScriptRngID__Ptr = FLECS_IDEcsScriptRngID__BindgenGetExtern() : FLECS_IDEcsScriptRngID__Ptr); + public static ref ulong FLECS_IDEcsScriptShellID_ => ref *(ulong*)(FLECS_IDEcsScriptShellID__Ptr == null ? FLECS_IDEcsScriptShellID__Ptr = FLECS_IDEcsScriptShellID__BindgenGetExtern() : FLECS_IDEcsScriptShellID__Ptr); + + public static ref ulong FLECS_IDEcsScriptTaskID_ => ref *(ulong*)(FLECS_IDEcsScriptTaskID__Ptr == null ? FLECS_IDEcsScriptTaskID__Ptr = FLECS_IDEcsScriptTaskID__BindgenGetExtern() : FLECS_IDEcsScriptTaskID__Ptr); + public static ref ulong FLECS_IDEcsScriptTemplateID_ => ref *(ulong*)(FLECS_IDEcsScriptTemplateID__Ptr == null ? FLECS_IDEcsScriptTemplateID__Ptr = FLECS_IDEcsScriptTemplateID__BindgenGetExtern() : FLECS_IDEcsScriptTemplateID__Ptr); + public static ref ulong FLECS_IDEcsScriptTemplateManualID_ => ref *(ulong*)(FLECS_IDEcsScriptTemplateManualID__Ptr == null ? FLECS_IDEcsScriptTemplateManualID__Ptr = FLECS_IDEcsScriptTemplateManualID__BindgenGetExtern() : FLECS_IDEcsScriptTemplateManualID__Ptr); + + public static ref ulong FLECS_IDEcsScriptTemplatePendingID_ => ref *(ulong*)(FLECS_IDEcsScriptTemplatePendingID__Ptr == null ? FLECS_IDEcsScriptTemplatePendingID__Ptr = FLECS_IDEcsScriptTemplatePendingID__BindgenGetExtern() : FLECS_IDEcsScriptTemplatePendingID__Ptr); + public static ref ulong FLECS_IDEcsScriptVectorTypeID_ => ref *(ulong*)(FLECS_IDEcsScriptVectorTypeID__Ptr == null ? FLECS_IDEcsScriptVectorTypeID__Ptr = FLECS_IDEcsScriptVectorTypeID__BindgenGetExtern() : FLECS_IDEcsScriptVectorTypeID__Ptr); public static ref ulong FLECS_IDEcsStructID_ => ref *(ulong*)(FLECS_IDEcsStructID__Ptr == null ? FLECS_IDEcsStructID__Ptr = FLECS_IDEcsStructID__BindgenGetExtern() : FLECS_IDEcsStructID__Ptr); @@ -8323,39 +9194,41 @@ public partial struct ecs_member_t_32 public static ref ulong FLECS_IDFlecsStatsID_ => ref *(ulong*)(FLECS_IDFlecsStatsID__Ptr == null ? FLECS_IDFlecsStatsID__Ptr = FLECS_IDFlecsStatsID__BindgenGetExtern() : FLECS_IDFlecsStatsID__Ptr); + public static ref ulong FlecsMeta => ref *(ulong*)(FlecsMeta_Ptr == null ? FlecsMeta_Ptr = FlecsMeta_BindgenGetExtern() : FlecsMeta_Ptr); + public partial struct ecs_iter_private_t { - public partial struct AnonymousRecord_api_types_L145_C5 : IEquatable + public partial struct AnonymousRecord_api_types_L177_C5 : IEquatable { - public bool Equals(AnonymousRecord_api_types_L145_C5 other) + public bool Equals(AnonymousRecord_api_types_L177_C5 other) { - fixed (AnonymousRecord_api_types_L145_C5* __self = &this) + fixed (AnonymousRecord_api_types_L177_C5* __self = &this) { - return new Span(__self, sizeof(AnonymousRecord_api_types_L145_C5)).SequenceEqual(new Span(&other, sizeof(AnonymousRecord_api_types_L145_C5))); + return new Span(__self, sizeof(AnonymousRecord_api_types_L177_C5)).SequenceEqual(new Span(&other, sizeof(AnonymousRecord_api_types_L177_C5))); } } public override bool Equals(object? obj) { - return obj is AnonymousRecord_api_types_L145_C5 other && Equals(other); + return obj is AnonymousRecord_api_types_L177_C5 other && Equals(other); } - public static bool operator ==(AnonymousRecord_api_types_L145_C5 left, AnonymousRecord_api_types_L145_C5 right) + public static bool operator ==(AnonymousRecord_api_types_L177_C5 left, AnonymousRecord_api_types_L177_C5 right) { return left.Equals(right); } - public static bool operator !=(AnonymousRecord_api_types_L145_C5 left, AnonymousRecord_api_types_L145_C5 right) + public static bool operator !=(AnonymousRecord_api_types_L177_C5 left, AnonymousRecord_api_types_L177_C5 right) { return !(left == right); } public override int GetHashCode() { - fixed (AnonymousRecord_api_types_L145_C5* __self = &this) + fixed (AnonymousRecord_api_types_L177_C5* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(AnonymousRecord_api_types_L145_C5))); + hash.AddBytes(new Span(__self, sizeof(AnonymousRecord_api_types_L177_C5))); return hash.ToHashCode(); } } @@ -8364,37 +9237,37 @@ public override int GetHashCode() public partial struct ecs_world_info_t { - public partial struct AnonymousRecord_flecs_L1542_C5 : IEquatable + public partial struct AnonymousRecord_flecs_L1563_C5 : IEquatable { - public bool Equals(AnonymousRecord_flecs_L1542_C5 other) + public bool Equals(AnonymousRecord_flecs_L1563_C5 other) { - fixed (AnonymousRecord_flecs_L1542_C5* __self = &this) + fixed (AnonymousRecord_flecs_L1563_C5* __self = &this) { - return new Span(__self, sizeof(AnonymousRecord_flecs_L1542_C5)).SequenceEqual(new Span(&other, sizeof(AnonymousRecord_flecs_L1542_C5))); + return new Span(__self, sizeof(AnonymousRecord_flecs_L1563_C5)).SequenceEqual(new Span(&other, sizeof(AnonymousRecord_flecs_L1563_C5))); } } public override bool Equals(object? obj) { - return obj is AnonymousRecord_flecs_L1542_C5 other && Equals(other); + return obj is AnonymousRecord_flecs_L1563_C5 other && Equals(other); } - public static bool operator ==(AnonymousRecord_flecs_L1542_C5 left, AnonymousRecord_flecs_L1542_C5 right) + public static bool operator ==(AnonymousRecord_flecs_L1563_C5 left, AnonymousRecord_flecs_L1563_C5 right) { return left.Equals(right); } - public static bool operator !=(AnonymousRecord_flecs_L1542_C5 left, AnonymousRecord_flecs_L1542_C5 right) + public static bool operator !=(AnonymousRecord_flecs_L1563_C5 left, AnonymousRecord_flecs_L1563_C5 right) { return !(left == right); } public override int GetHashCode() { - fixed (AnonymousRecord_flecs_L1542_C5* __self = &this) + fixed (AnonymousRecord_flecs_L1563_C5* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(AnonymousRecord_flecs_L1542_C5))); + hash.AddBytes(new Span(__self, sizeof(AnonymousRecord_flecs_L1563_C5))); return hash.ToHashCode(); } } @@ -8403,37 +9276,37 @@ public override int GetHashCode() public partial struct ecs_meta_op_t { - public partial struct AnonymousRecord_meta_L579_C5 : IEquatable + public partial struct AnonymousRecord_meta_L594_C5 : IEquatable { - public bool Equals(AnonymousRecord_meta_L579_C5 other) + public bool Equals(AnonymousRecord_meta_L594_C5 other) { - fixed (AnonymousRecord_meta_L579_C5* __self = &this) + fixed (AnonymousRecord_meta_L594_C5* __self = &this) { - return new Span(__self, sizeof(AnonymousRecord_meta_L579_C5)).SequenceEqual(new Span(&other, sizeof(AnonymousRecord_meta_L579_C5))); + return new Span(__self, sizeof(AnonymousRecord_meta_L594_C5)).SequenceEqual(new Span(&other, sizeof(AnonymousRecord_meta_L594_C5))); } } public override bool Equals(object? obj) { - return obj is AnonymousRecord_meta_L579_C5 other && Equals(other); + return obj is AnonymousRecord_meta_L594_C5 other && Equals(other); } - public static bool operator ==(AnonymousRecord_meta_L579_C5 left, AnonymousRecord_meta_L579_C5 right) + public static bool operator ==(AnonymousRecord_meta_L594_C5 left, AnonymousRecord_meta_L594_C5 right) { return left.Equals(right); } - public static bool operator !=(AnonymousRecord_meta_L579_C5 left, AnonymousRecord_meta_L579_C5 right) + public static bool operator !=(AnonymousRecord_meta_L594_C5 left, AnonymousRecord_meta_L594_C5 right) { return !(left == right); } public override int GetHashCode() { - fixed (AnonymousRecord_meta_L579_C5* __self = &this) + fixed (AnonymousRecord_meta_L594_C5* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(AnonymousRecord_meta_L579_C5))); + hash.AddBytes(new Span(__self, sizeof(AnonymousRecord_meta_L594_C5))); return hash.ToHashCode(); } } @@ -9007,6 +9880,42 @@ public override int GetHashCode() } } + public partial struct ecs_async_function_desc_t : IEquatable + { + public bool Equals(ecs_async_function_desc_t other) + { + fixed (ecs_async_function_desc_t* __self = &this) + { + return new Span(__self, sizeof(ecs_async_function_desc_t)).SequenceEqual(new Span(&other, sizeof(ecs_async_function_desc_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_async_function_desc_t other && Equals(other); + } + + public static bool operator ==(ecs_async_function_desc_t left, ecs_async_function_desc_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_async_function_desc_t left, ecs_async_function_desc_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_async_function_desc_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_async_function_desc_t))); + return hash.ToHashCode(); + } + } + } + public partial struct ecs_bitmask_constant_t : IEquatable { public bool Equals(ecs_bitmask_constant_t other) @@ -9331,6 +10240,42 @@ public override int GetHashCode() } } + public partial struct ecs_cmd_entry_t : IEquatable + { + public bool Equals(ecs_cmd_entry_t other) + { + fixed (ecs_cmd_entry_t* __self = &this) + { + return new Span(__self, sizeof(ecs_cmd_entry_t)).SequenceEqual(new Span(&other, sizeof(ecs_cmd_entry_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_cmd_entry_t other && Equals(other); + } + + public static bool operator ==(ecs_cmd_entry_t left, ecs_cmd_entry_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_cmd_entry_t left, ecs_cmd_entry_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_cmd_entry_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_cmd_entry_t))); + return hash.ToHashCode(); + } + } + } + public partial struct ecs_commands_t : IEquatable { public bool Equals(ecs_commands_t other) @@ -10771,49 +11716,85 @@ public override int GetHashCode() } } - public partial struct ecs_map_iter_t : IEquatable + public partial struct ecs_map_desc_t : IEquatable { - public bool Equals(ecs_map_iter_t other) + public bool Equals(ecs_map_desc_t other) { - fixed (ecs_map_iter_t* __self = &this) + fixed (ecs_map_desc_t* __self = &this) { - return new Span(__self, sizeof(ecs_map_iter_t)).SequenceEqual(new Span(&other, sizeof(ecs_map_iter_t))); + return new Span(__self, sizeof(ecs_map_desc_t)).SequenceEqual(new Span(&other, sizeof(ecs_map_desc_t))); } } public override bool Equals(object? obj) { - return obj is ecs_map_iter_t other && Equals(other); + return obj is ecs_map_desc_t other && Equals(other); } - public static bool operator ==(ecs_map_iter_t left, ecs_map_iter_t right) + public static bool operator ==(ecs_map_desc_t left, ecs_map_desc_t right) { return left.Equals(right); } - public static bool operator !=(ecs_map_iter_t left, ecs_map_iter_t right) + public static bool operator !=(ecs_map_desc_t left, ecs_map_desc_t right) { return !(left == right); } public override int GetHashCode() { - fixed (ecs_map_iter_t* __self = &this) + fixed (ecs_map_desc_t* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(ecs_map_iter_t))); + hash.AddBytes(new Span(__self, sizeof(ecs_map_desc_t))); return hash.ToHashCode(); } } } - public partial struct ecs_map_t : IEquatable + public partial struct ecs_map_iter_t : IEquatable { - public bool Equals(ecs_map_t other) + public bool Equals(ecs_map_iter_t other) { - fixed (ecs_map_t* __self = &this) + fixed (ecs_map_iter_t* __self = &this) { - return new Span(__self, sizeof(ecs_map_t)).SequenceEqual(new Span(&other, sizeof(ecs_map_t))); + return new Span(__self, sizeof(ecs_map_iter_t)).SequenceEqual(new Span(&other, sizeof(ecs_map_iter_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_map_iter_t other && Equals(other); + } + + public static bool operator ==(ecs_map_iter_t left, ecs_map_iter_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_map_iter_t left, ecs_map_iter_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_map_iter_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_map_iter_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_map_t : IEquatable + { + public bool Equals(ecs_map_t other) + { + fixed (ecs_map_t* __self = &this) + { + return new Span(__self, sizeof(ecs_map_t)).SequenceEqual(new Span(&other, sizeof(ecs_map_t))); } } @@ -11167,6 +12148,42 @@ public override int GetHashCode() } } + public partial struct ecs_mut_var_desc_t : IEquatable + { + public bool Equals(ecs_mut_var_desc_t other) + { + fixed (ecs_mut_var_desc_t* __self = &this) + { + return new Span(__self, sizeof(ecs_mut_var_desc_t)).SequenceEqual(new Span(&other, sizeof(ecs_mut_var_desc_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_mut_var_desc_t other && Equals(other); + } + + public static bool operator ==(ecs_mut_var_desc_t left, ecs_mut_var_desc_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_mut_var_desc_t left, ecs_mut_var_desc_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_mut_var_desc_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_mut_var_desc_t))); + return hash.ToHashCode(); + } + } + } + public partial struct ecs_observable_t : IEquatable { public bool Equals(ecs_observable_t other) @@ -11383,42 +12400,6 @@ public override int GetHashCode() } } - public partial struct ecs_parent_record_t : IEquatable - { - public bool Equals(ecs_parent_record_t other) - { - fixed (ecs_parent_record_t* __self = &this) - { - return new Span(__self, sizeof(ecs_parent_record_t)).SequenceEqual(new Span(&other, sizeof(ecs_parent_record_t))); - } - } - - public override bool Equals(object? obj) - { - return obj is ecs_parent_record_t other && Equals(other); - } - - public static bool operator ==(ecs_parent_record_t left, ecs_parent_record_t right) - { - return left.Equals(right); - } - - public static bool operator !=(ecs_parent_record_t left, ecs_parent_record_t right) - { - return !(left == right); - } - - public override int GetHashCode() - { - fixed (ecs_parent_record_t* __self = &this) - { - HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(ecs_parent_record_t))); - return hash.ToHashCode(); - } - } - } - public partial struct ecs_pipeline_desc_t : IEquatable { public bool Equals(ecs_pipeline_desc_t other) @@ -11599,6 +12580,42 @@ public override int GetHashCode() } } + public partial struct ecs_query_cache_revalidate_t : IEquatable + { + public bool Equals(ecs_query_cache_revalidate_t other) + { + fixed (ecs_query_cache_revalidate_t* __self = &this) + { + return new Span(__self, sizeof(ecs_query_cache_revalidate_t)).SequenceEqual(new Span(&other, sizeof(ecs_query_cache_revalidate_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_query_cache_revalidate_t other && Equals(other); + } + + public static bool operator ==(ecs_query_cache_revalidate_t left, ecs_query_cache_revalidate_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_query_cache_revalidate_t left, ecs_query_cache_revalidate_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_query_cache_revalidate_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_query_cache_revalidate_t))); + return hash.ToHashCode(); + } + } + } + public partial struct ecs_query_count_t : IEquatable { public bool Equals(ecs_query_count_t other) @@ -11857,643 +12874,1579 @@ public bool Equals(ecs_query_op_t other) { fixed (ecs_query_op_t* __self = &this) { - return new Span(__self, sizeof(ecs_query_op_t)).SequenceEqual(new Span(&other, sizeof(ecs_query_op_t))); + return new Span(__self, sizeof(ecs_query_op_t)).SequenceEqual(new Span(&other, sizeof(ecs_query_op_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_query_op_t other && Equals(other); + } + + public static bool operator ==(ecs_query_op_t left, ecs_query_op_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_query_op_t left, ecs_query_op_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_query_op_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_query_op_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_query_stats_t : IEquatable + { + public bool Equals(ecs_query_stats_t other) + { + fixed (ecs_query_stats_t* __self = &this) + { + return new Span(__self, sizeof(ecs_query_stats_t)).SequenceEqual(new Span(&other, sizeof(ecs_query_stats_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_query_stats_t other && Equals(other); + } + + public static bool operator ==(ecs_query_stats_t left, ecs_query_stats_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_query_stats_t left, ecs_query_stats_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_query_stats_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_query_stats_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_query_t : IEquatable + { + public bool Equals(ecs_query_t other) + { + fixed (ecs_query_t* __self = &this) + { + return new Span(__self, sizeof(ecs_query_t)).SequenceEqual(new Span(&other, sizeof(ecs_query_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_query_t other && Equals(other); + } + + public static bool operator ==(ecs_query_t left, ecs_query_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_query_t left, ecs_query_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_query_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_query_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_query_trivial_ctx_t : IEquatable + { + public bool Equals(ecs_query_trivial_ctx_t other) + { + fixed (ecs_query_trivial_ctx_t* __self = &this) + { + return new Span(__self, sizeof(ecs_query_trivial_ctx_t)).SequenceEqual(new Span(&other, sizeof(ecs_query_trivial_ctx_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_query_trivial_ctx_t other && Equals(other); + } + + public static bool operator ==(ecs_query_trivial_ctx_t left, ecs_query_trivial_ctx_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_query_trivial_ctx_t left, ecs_query_trivial_ctx_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_query_trivial_ctx_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_query_trivial_ctx_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_query_var_t : IEquatable + { + public bool Equals(ecs_query_var_t other) + { + fixed (ecs_query_var_t* __self = &this) + { + return new Span(__self, sizeof(ecs_query_var_t)).SequenceEqual(new Span(&other, sizeof(ecs_query_var_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_query_var_t other && Equals(other); + } + + public static bool operator ==(ecs_query_var_t left, ecs_query_var_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_query_var_t left, ecs_query_var_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_query_var_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_query_var_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_record_t : IEquatable + { + public bool Equals(ecs_record_t other) + { + fixed (ecs_record_t* __self = &this) + { + return new Span(__self, sizeof(ecs_record_t)).SequenceEqual(new Span(&other, sizeof(ecs_record_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_record_t other && Equals(other); + } + + public static bool operator ==(ecs_record_t left, ecs_record_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_record_t left, ecs_record_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_record_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_record_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_ref_t : IEquatable + { + public bool Equals(ecs_ref_t other) + { + fixed (ecs_ref_t* __self = &this) + { + return new Span(__self, sizeof(ecs_ref_t)).SequenceEqual(new Span(&other, sizeof(ecs_ref_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_ref_t other && Equals(other); + } + + public static bool operator ==(ecs_ref_t left, ecs_ref_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_ref_t left, ecs_ref_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_ref_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_ref_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_rest_ctx_t : IEquatable + { + public bool Equals(ecs_rest_ctx_t other) + { + fixed (ecs_rest_ctx_t* __self = &this) + { + return new Span(__self, sizeof(ecs_rest_ctx_t)).SequenceEqual(new Span(&other, sizeof(ecs_rest_ctx_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_rest_ctx_t other && Equals(other); + } + + public static bool operator ==(ecs_rest_ctx_t left, ecs_rest_ctx_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_rest_ctx_t left, ecs_rest_ctx_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_rest_ctx_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_rest_ctx_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_script_desc_t : IEquatable + { + public bool Equals(ecs_script_desc_t other) + { + fixed (ecs_script_desc_t* __self = &this) + { + return new Span(__self, sizeof(ecs_script_desc_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_desc_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_script_desc_t other && Equals(other); + } + + public static bool operator ==(ecs_script_desc_t left, ecs_script_desc_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_script_desc_t left, ecs_script_desc_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_script_desc_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_script_desc_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_script_edits_t : IEquatable + { + public bool Equals(ecs_script_edits_t other) + { + fixed (ecs_script_edits_t* __self = &this) + { + return new Span(__self, sizeof(ecs_script_edits_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_edits_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_script_edits_t other && Equals(other); + } + + public static bool operator ==(ecs_script_edits_t left, ecs_script_edits_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_script_edits_t left, ecs_script_edits_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_script_edits_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_script_edits_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_script_eval_desc_t : IEquatable + { + public bool Equals(ecs_script_eval_desc_t other) + { + fixed (ecs_script_eval_desc_t* __self = &this) + { + return new Span(__self, sizeof(ecs_script_eval_desc_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_eval_desc_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_script_eval_desc_t other && Equals(other); + } + + public static bool operator ==(ecs_script_eval_desc_t left, ecs_script_eval_desc_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_script_eval_desc_t left, ecs_script_eval_desc_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_script_eval_desc_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_script_eval_desc_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_script_eval_result_t : IEquatable + { + public bool Equals(ecs_script_eval_result_t other) + { + fixed (ecs_script_eval_result_t* __self = &this) + { + return new Span(__self, sizeof(ecs_script_eval_result_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_eval_result_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_script_eval_result_t other && Equals(other); + } + + public static bool operator ==(ecs_script_eval_result_t left, ecs_script_eval_result_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_script_eval_result_t left, ecs_script_eval_result_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_script_eval_result_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_script_eval_result_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_script_event_hooks_t : IEquatable + { + public bool Equals(ecs_script_event_hooks_t other) + { + fixed (ecs_script_event_hooks_t* __self = &this) + { + return new Span(__self, sizeof(ecs_script_event_hooks_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_event_hooks_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_script_event_hooks_t other && Equals(other); + } + + public static bool operator ==(ecs_script_event_hooks_t left, ecs_script_event_hooks_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_script_event_hooks_t left, ecs_script_event_hooks_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_script_event_hooks_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_script_event_hooks_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_script_event_result_t : IEquatable + { + public bool Equals(ecs_script_event_result_t other) + { + fixed (ecs_script_event_result_t* __self = &this) + { + return new Span(__self, sizeof(ecs_script_event_result_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_event_result_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_script_event_result_t other && Equals(other); + } + + public static bool operator ==(ecs_script_event_result_t left, ecs_script_event_result_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_script_event_result_t left, ecs_script_event_result_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_script_event_result_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_script_event_result_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_script_function_t : IEquatable + { + public bool Equals(ecs_script_function_t other) + { + fixed (ecs_script_function_t* __self = &this) + { + return new Span(__self, sizeof(ecs_script_function_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_function_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_script_function_t other && Equals(other); + } + + public static bool operator ==(ecs_script_function_t left, ecs_script_function_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_script_function_t left, ecs_script_function_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_script_function_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_script_function_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_script_future_t : IEquatable + { + public bool Equals(ecs_script_future_t other) + { + fixed (ecs_script_future_t* __self = &this) + { + return new Span(__self, sizeof(ecs_script_future_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_future_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_script_future_t other && Equals(other); + } + + public static bool operator ==(ecs_script_future_t left, ecs_script_future_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_script_future_t left, ecs_script_future_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_script_future_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_script_future_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_script_parameter_t : IEquatable + { + public bool Equals(ecs_script_parameter_t other) + { + fixed (ecs_script_parameter_t* __self = &this) + { + return new Span(__self, sizeof(ecs_script_parameter_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_parameter_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_script_parameter_t other && Equals(other); + } + + public static bool operator ==(ecs_script_parameter_t left, ecs_script_parameter_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_script_parameter_t left, ecs_script_parameter_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_script_parameter_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_script_parameter_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_script_runtime_t : IEquatable + { + public bool Equals(ecs_script_runtime_t other) + { + fixed (ecs_script_runtime_t* __self = &this) + { + return new Span(__self, sizeof(ecs_script_runtime_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_runtime_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_script_runtime_t other && Equals(other); + } + + public static bool operator ==(ecs_script_runtime_t left, ecs_script_runtime_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_script_runtime_t left, ecs_script_runtime_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_script_runtime_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_script_runtime_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_script_source_t : IEquatable + { + public bool Equals(ecs_script_source_t other) + { + fixed (ecs_script_source_t* __self = &this) + { + return new Span(__self, sizeof(ecs_script_source_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_source_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_script_source_t other && Equals(other); + } + + public static bool operator ==(ecs_script_source_t left, ecs_script_source_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_script_source_t left, ecs_script_source_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_script_source_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_script_source_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_script_t : IEquatable + { + public bool Equals(ecs_script_t other) + { + fixed (ecs_script_t* __self = &this) + { + return new Span(__self, sizeof(ecs_script_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_script_t other && Equals(other); + } + + public static bool operator ==(ecs_script_t left, ecs_script_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_script_t left, ecs_script_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_script_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_script_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_script_task_desc_t : IEquatable + { + public bool Equals(ecs_script_task_desc_t other) + { + fixed (ecs_script_task_desc_t* __self = &this) + { + return new Span(__self, sizeof(ecs_script_task_desc_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_task_desc_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_script_task_desc_t other && Equals(other); + } + + public static bool operator ==(ecs_script_task_desc_t left, ecs_script_task_desc_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_script_task_desc_t left, ecs_script_task_desc_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_script_task_desc_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_script_task_desc_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_script_task_t : IEquatable + { + public bool Equals(ecs_script_task_t other) + { + fixed (ecs_script_task_t* __self = &this) + { + return new Span(__self, sizeof(ecs_script_task_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_task_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_script_task_t other && Equals(other); + } + + public static bool operator ==(ecs_script_task_t left, ecs_script_task_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_script_task_t left, ecs_script_task_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_script_task_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_script_task_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_script_template_ref_t : IEquatable + { + public bool Equals(ecs_script_template_ref_t other) + { + fixed (ecs_script_template_ref_t* __self = &this) + { + return new Span(__self, sizeof(ecs_script_template_ref_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_template_ref_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_script_template_ref_t other && Equals(other); + } + + public static bool operator ==(ecs_script_template_ref_t left, ecs_script_template_ref_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_script_template_ref_t left, ecs_script_template_ref_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_script_template_ref_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_script_template_ref_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_script_template_t : IEquatable + { + public bool Equals(ecs_script_template_t other) + { + fixed (ecs_script_template_t* __self = &this) + { + return new Span(__self, sizeof(ecs_script_template_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_template_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_script_template_t other && Equals(other); + } + + public static bool operator ==(ecs_script_template_t left, ecs_script_template_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_script_template_t left, ecs_script_template_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_script_template_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_script_template_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_script_var_t : IEquatable + { + public bool Equals(ecs_script_var_t other) + { + fixed (ecs_script_var_t* __self = &this) + { + return new Span(__self, sizeof(ecs_script_var_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_var_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_script_var_t other && Equals(other); + } + + public static bool operator ==(ecs_script_var_t left, ecs_script_var_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_script_var_t left, ecs_script_var_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_script_var_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_script_var_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_script_vars_t : IEquatable + { + public bool Equals(ecs_script_vars_t other) + { + fixed (ecs_script_vars_t* __self = &this) + { + return new Span(__self, sizeof(ecs_script_vars_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_vars_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_script_vars_t other && Equals(other); + } + + public static bool operator ==(ecs_script_vars_t left, ecs_script_vars_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_script_vars_t left, ecs_script_vars_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_script_vars_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_script_vars_t))); + return hash.ToHashCode(); + } + } + } + + public partial struct ecs_serializer_t : IEquatable + { + public bool Equals(ecs_serializer_t other) + { + fixed (ecs_serializer_t* __self = &this) + { + return new Span(__self, sizeof(ecs_serializer_t)).SequenceEqual(new Span(&other, sizeof(ecs_serializer_t))); } } public override bool Equals(object? obj) { - return obj is ecs_query_op_t other && Equals(other); + return obj is ecs_serializer_t other && Equals(other); } - public static bool operator ==(ecs_query_op_t left, ecs_query_op_t right) + public static bool operator ==(ecs_serializer_t left, ecs_serializer_t right) { return left.Equals(right); } - public static bool operator !=(ecs_query_op_t left, ecs_query_op_t right) + public static bool operator !=(ecs_serializer_t left, ecs_serializer_t right) { return !(left == right); } public override int GetHashCode() { - fixed (ecs_query_op_t* __self = &this) + fixed (ecs_serializer_t* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(ecs_query_op_t))); + hash.AddBytes(new Span(__self, sizeof(ecs_serializer_t))); return hash.ToHashCode(); } } } - public partial struct ecs_query_stats_t : IEquatable + public partial struct ecs_shell_component_value_t : IEquatable { - public bool Equals(ecs_query_stats_t other) + public bool Equals(ecs_shell_component_value_t other) { - fixed (ecs_query_stats_t* __self = &this) + fixed (ecs_shell_component_value_t* __self = &this) { - return new Span(__self, sizeof(ecs_query_stats_t)).SequenceEqual(new Span(&other, sizeof(ecs_query_stats_t))); + return new Span(__self, sizeof(ecs_shell_component_value_t)).SequenceEqual(new Span(&other, sizeof(ecs_shell_component_value_t))); } } public override bool Equals(object? obj) { - return obj is ecs_query_stats_t other && Equals(other); + return obj is ecs_shell_component_value_t other && Equals(other); } - public static bool operator ==(ecs_query_stats_t left, ecs_query_stats_t right) + public static bool operator ==(ecs_shell_component_value_t left, ecs_shell_component_value_t right) { return left.Equals(right); } - public static bool operator !=(ecs_query_stats_t left, ecs_query_stats_t right) + public static bool operator !=(ecs_shell_component_value_t left, ecs_shell_component_value_t right) { return !(left == right); } public override int GetHashCode() { - fixed (ecs_query_stats_t* __self = &this) + fixed (ecs_shell_component_value_t* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(ecs_query_stats_t))); + hash.AddBytes(new Span(__self, sizeof(ecs_shell_component_value_t))); return hash.ToHashCode(); } } } - public partial struct ecs_query_t : IEquatable + public partial struct ecs_shell_doc_info_t : IEquatable { - public bool Equals(ecs_query_t other) + public bool Equals(ecs_shell_doc_info_t other) { - fixed (ecs_query_t* __self = &this) + fixed (ecs_shell_doc_info_t* __self = &this) { - return new Span(__self, sizeof(ecs_query_t)).SequenceEqual(new Span(&other, sizeof(ecs_query_t))); + return new Span(__self, sizeof(ecs_shell_doc_info_t)).SequenceEqual(new Span(&other, sizeof(ecs_shell_doc_info_t))); } } public override bool Equals(object? obj) { - return obj is ecs_query_t other && Equals(other); + return obj is ecs_shell_doc_info_t other && Equals(other); } - public static bool operator ==(ecs_query_t left, ecs_query_t right) + public static bool operator ==(ecs_shell_doc_info_t left, ecs_shell_doc_info_t right) { return left.Equals(right); } - public static bool operator !=(ecs_query_t left, ecs_query_t right) + public static bool operator !=(ecs_shell_doc_info_t left, ecs_shell_doc_info_t right) { return !(left == right); } public override int GetHashCode() { - fixed (ecs_query_t* __self = &this) + fixed (ecs_shell_doc_info_t* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(ecs_query_t))); + hash.AddBytes(new Span(__self, sizeof(ecs_shell_doc_info_t))); return hash.ToHashCode(); } } } - public partial struct ecs_query_var_t : IEquatable + public partial struct ecs_shell_entity_info_t : IEquatable { - public bool Equals(ecs_query_var_t other) + public bool Equals(ecs_shell_entity_info_t other) { - fixed (ecs_query_var_t* __self = &this) + fixed (ecs_shell_entity_info_t* __self = &this) { - return new Span(__self, sizeof(ecs_query_var_t)).SequenceEqual(new Span(&other, sizeof(ecs_query_var_t))); + return new Span(__self, sizeof(ecs_shell_entity_info_t)).SequenceEqual(new Span(&other, sizeof(ecs_shell_entity_info_t))); } } public override bool Equals(object? obj) { - return obj is ecs_query_var_t other && Equals(other); + return obj is ecs_shell_entity_info_t other && Equals(other); } - public static bool operator ==(ecs_query_var_t left, ecs_query_var_t right) + public static bool operator ==(ecs_shell_entity_info_t left, ecs_shell_entity_info_t right) { return left.Equals(right); } - public static bool operator !=(ecs_query_var_t left, ecs_query_var_t right) + public static bool operator !=(ecs_shell_entity_info_t left, ecs_shell_entity_info_t right) { return !(left == right); } public override int GetHashCode() { - fixed (ecs_query_var_t* __self = &this) + fixed (ecs_shell_entity_info_t* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(ecs_query_var_t))); + hash.AddBytes(new Span(__self, sizeof(ecs_shell_entity_info_t))); return hash.ToHashCode(); } } } - public partial struct ecs_record_t : IEquatable + public partial struct ecs_shell_grep_match_t : IEquatable { - public bool Equals(ecs_record_t other) + public bool Equals(ecs_shell_grep_match_t other) { - fixed (ecs_record_t* __self = &this) + fixed (ecs_shell_grep_match_t* __self = &this) { - return new Span(__self, sizeof(ecs_record_t)).SequenceEqual(new Span(&other, sizeof(ecs_record_t))); + return new Span(__self, sizeof(ecs_shell_grep_match_t)).SequenceEqual(new Span(&other, sizeof(ecs_shell_grep_match_t))); } } public override bool Equals(object? obj) { - return obj is ecs_record_t other && Equals(other); + return obj is ecs_shell_grep_match_t other && Equals(other); } - public static bool operator ==(ecs_record_t left, ecs_record_t right) + public static bool operator ==(ecs_shell_grep_match_t left, ecs_shell_grep_match_t right) { return left.Equals(right); } - public static bool operator !=(ecs_record_t left, ecs_record_t right) + public static bool operator !=(ecs_shell_grep_match_t left, ecs_shell_grep_match_t right) { return !(left == right); } public override int GetHashCode() { - fixed (ecs_record_t* __self = &this) + fixed (ecs_shell_grep_match_t* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(ecs_record_t))); + hash.AddBytes(new Span(__self, sizeof(ecs_shell_grep_match_t))); return hash.ToHashCode(); } } } - public partial struct ecs_ref_t : IEquatable + public partial struct ecs_shell_info_t : IEquatable { - public bool Equals(ecs_ref_t other) + public bool Equals(ecs_shell_info_t other) { - fixed (ecs_ref_t* __self = &this) + fixed (ecs_shell_info_t* __self = &this) { - return new Span(__self, sizeof(ecs_ref_t)).SequenceEqual(new Span(&other, sizeof(ecs_ref_t))); + return new Span(__self, sizeof(ecs_shell_info_t)).SequenceEqual(new Span(&other, sizeof(ecs_shell_info_t))); } } public override bool Equals(object? obj) { - return obj is ecs_ref_t other && Equals(other); + return obj is ecs_shell_info_t other && Equals(other); } - public static bool operator ==(ecs_ref_t left, ecs_ref_t right) + public static bool operator ==(ecs_shell_info_t left, ecs_shell_info_t right) { return left.Equals(right); } - public static bool operator !=(ecs_ref_t left, ecs_ref_t right) + public static bool operator !=(ecs_shell_info_t left, ecs_shell_info_t right) { return !(left == right); } public override int GetHashCode() { - fixed (ecs_ref_t* __self = &this) + fixed (ecs_shell_info_t* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(ecs_ref_t))); + hash.AddBytes(new Span(__self, sizeof(ecs_shell_info_t))); return hash.ToHashCode(); } } } - public partial struct ecs_rest_ctx_t : IEquatable + public partial struct ecs_shell_param_info_t : IEquatable { - public bool Equals(ecs_rest_ctx_t other) + public bool Equals(ecs_shell_param_info_t other) { - fixed (ecs_rest_ctx_t* __self = &this) + fixed (ecs_shell_param_info_t* __self = &this) { - return new Span(__self, sizeof(ecs_rest_ctx_t)).SequenceEqual(new Span(&other, sizeof(ecs_rest_ctx_t))); + return new Span(__self, sizeof(ecs_shell_param_info_t)).SequenceEqual(new Span(&other, sizeof(ecs_shell_param_info_t))); } } public override bool Equals(object? obj) { - return obj is ecs_rest_ctx_t other && Equals(other); + return obj is ecs_shell_param_info_t other && Equals(other); } - public static bool operator ==(ecs_rest_ctx_t left, ecs_rest_ctx_t right) + public static bool operator ==(ecs_shell_param_info_t left, ecs_shell_param_info_t right) { return left.Equals(right); } - public static bool operator !=(ecs_rest_ctx_t left, ecs_rest_ctx_t right) + public static bool operator !=(ecs_shell_param_info_t left, ecs_shell_param_info_t right) { return !(left == right); } public override int GetHashCode() { - fixed (ecs_rest_ctx_t* __self = &this) + fixed (ecs_shell_param_info_t* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(ecs_rest_ctx_t))); + hash.AddBytes(new Span(__self, sizeof(ecs_shell_param_info_t))); return hash.ToHashCode(); } } } - public partial struct ecs_script_desc_t : IEquatable + public partial struct ecs_shell_pointer_state_t : IEquatable { - public bool Equals(ecs_script_desc_t other) + public bool Equals(ecs_shell_pointer_state_t other) { - fixed (ecs_script_desc_t* __self = &this) + fixed (ecs_shell_pointer_state_t* __self = &this) { - return new Span(__self, sizeof(ecs_script_desc_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_desc_t))); + return new Span(__self, sizeof(ecs_shell_pointer_state_t)).SequenceEqual(new Span(&other, sizeof(ecs_shell_pointer_state_t))); } } public override bool Equals(object? obj) { - return obj is ecs_script_desc_t other && Equals(other); + return obj is ecs_shell_pointer_state_t other && Equals(other); } - public static bool operator ==(ecs_script_desc_t left, ecs_script_desc_t right) + public static bool operator ==(ecs_shell_pointer_state_t left, ecs_shell_pointer_state_t right) { return left.Equals(right); } - public static bool operator !=(ecs_script_desc_t left, ecs_script_desc_t right) + public static bool operator !=(ecs_shell_pointer_state_t left, ecs_shell_pointer_state_t right) { return !(left == right); } public override int GetHashCode() { - fixed (ecs_script_desc_t* __self = &this) + fixed (ecs_shell_pointer_state_t* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(ecs_script_desc_t))); + hash.AddBytes(new Span(__self, sizeof(ecs_shell_pointer_state_t))); return hash.ToHashCode(); } } } - public partial struct ecs_script_eval_desc_t : IEquatable + public partial struct ecs_shell_query_row_t : IEquatable { - public bool Equals(ecs_script_eval_desc_t other) + public bool Equals(ecs_shell_query_row_t other) { - fixed (ecs_script_eval_desc_t* __self = &this) + fixed (ecs_shell_query_row_t* __self = &this) { - return new Span(__self, sizeof(ecs_script_eval_desc_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_eval_desc_t))); + return new Span(__self, sizeof(ecs_shell_query_row_t)).SequenceEqual(new Span(&other, sizeof(ecs_shell_query_row_t))); } } public override bool Equals(object? obj) { - return obj is ecs_script_eval_desc_t other && Equals(other); + return obj is ecs_shell_query_row_t other && Equals(other); } - public static bool operator ==(ecs_script_eval_desc_t left, ecs_script_eval_desc_t right) + public static bool operator ==(ecs_shell_query_row_t left, ecs_shell_query_row_t right) { return left.Equals(right); } - public static bool operator !=(ecs_script_eval_desc_t left, ecs_script_eval_desc_t right) + public static bool operator !=(ecs_shell_query_row_t left, ecs_shell_query_row_t right) { return !(left == right); } public override int GetHashCode() { - fixed (ecs_script_eval_desc_t* __self = &this) + fixed (ecs_shell_query_row_t* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(ecs_script_eval_desc_t))); + hash.AddBytes(new Span(__self, sizeof(ecs_shell_query_row_t))); return hash.ToHashCode(); } } } - public partial struct ecs_script_eval_result_t : IEquatable + public partial struct ecs_shell_resource_t : IEquatable { - public bool Equals(ecs_script_eval_result_t other) + public bool Equals(ecs_shell_resource_t other) { - fixed (ecs_script_eval_result_t* __self = &this) + fixed (ecs_shell_resource_t* __self = &this) { - return new Span(__self, sizeof(ecs_script_eval_result_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_eval_result_t))); + return new Span(__self, sizeof(ecs_shell_resource_t)).SequenceEqual(new Span(&other, sizeof(ecs_shell_resource_t))); } } public override bool Equals(object? obj) { - return obj is ecs_script_eval_result_t other && Equals(other); + return obj is ecs_shell_resource_t other && Equals(other); } - public static bool operator ==(ecs_script_eval_result_t left, ecs_script_eval_result_t right) + public static bool operator ==(ecs_shell_resource_t left, ecs_shell_resource_t right) { return left.Equals(right); } - public static bool operator !=(ecs_script_eval_result_t left, ecs_script_eval_result_t right) + public static bool operator !=(ecs_shell_resource_t left, ecs_shell_resource_t right) { return !(left == right); } public override int GetHashCode() { - fixed (ecs_script_eval_result_t* __self = &this) + fixed (ecs_shell_resource_t* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(ecs_script_eval_result_t))); + hash.AddBytes(new Span(__self, sizeof(ecs_shell_resource_t))); return hash.ToHashCode(); } } } - public partial struct ecs_script_function_t : IEquatable + public partial struct ecs_shell_result_t : IEquatable { - public bool Equals(ecs_script_function_t other) + public bool Equals(ecs_shell_result_t other) { - fixed (ecs_script_function_t* __self = &this) + fixed (ecs_shell_result_t* __self = &this) { - return new Span(__self, sizeof(ecs_script_function_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_function_t))); + return new Span(__self, sizeof(ecs_shell_result_t)).SequenceEqual(new Span(&other, sizeof(ecs_shell_result_t))); } } public override bool Equals(object? obj) { - return obj is ecs_script_function_t other && Equals(other); + return obj is ecs_shell_result_t other && Equals(other); } - public static bool operator ==(ecs_script_function_t left, ecs_script_function_t right) + public static bool operator ==(ecs_shell_result_t left, ecs_shell_result_t right) { return left.Equals(right); } - public static bool operator !=(ecs_script_function_t left, ecs_script_function_t right) + public static bool operator !=(ecs_shell_result_t left, ecs_shell_result_t right) { return !(left == right); } public override int GetHashCode() { - fixed (ecs_script_function_t* __self = &this) + fixed (ecs_shell_result_t* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(ecs_script_function_t))); + hash.AddBytes(new Span(__self, sizeof(ecs_shell_result_t))); return hash.ToHashCode(); } } } - public partial struct ecs_script_parameter_t : IEquatable + public partial struct ecs_shell_script_error_t : IEquatable { - public bool Equals(ecs_script_parameter_t other) + public bool Equals(ecs_shell_script_error_t other) { - fixed (ecs_script_parameter_t* __self = &this) + fixed (ecs_shell_script_error_t* __self = &this) { - return new Span(__self, sizeof(ecs_script_parameter_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_parameter_t))); + return new Span(__self, sizeof(ecs_shell_script_error_t)).SequenceEqual(new Span(&other, sizeof(ecs_shell_script_error_t))); } } public override bool Equals(object? obj) { - return obj is ecs_script_parameter_t other && Equals(other); + return obj is ecs_shell_script_error_t other && Equals(other); } - public static bool operator ==(ecs_script_parameter_t left, ecs_script_parameter_t right) + public static bool operator ==(ecs_shell_script_error_t left, ecs_shell_script_error_t right) { return left.Equals(right); } - public static bool operator !=(ecs_script_parameter_t left, ecs_script_parameter_t right) + public static bool operator !=(ecs_shell_script_error_t left, ecs_shell_script_error_t right) { return !(left == right); } public override int GetHashCode() { - fixed (ecs_script_parameter_t* __self = &this) + fixed (ecs_shell_script_error_t* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(ecs_script_parameter_t))); + hash.AddBytes(new Span(__self, sizeof(ecs_shell_script_error_t))); return hash.ToHashCode(); } } } - public partial struct ecs_script_runtime_t : IEquatable + public partial struct ecs_shell_script_info_t : IEquatable { - public bool Equals(ecs_script_runtime_t other) + public bool Equals(ecs_shell_script_info_t other) { - fixed (ecs_script_runtime_t* __self = &this) + fixed (ecs_shell_script_info_t* __self = &this) { - return new Span(__self, sizeof(ecs_script_runtime_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_runtime_t))); + return new Span(__self, sizeof(ecs_shell_script_info_t)).SequenceEqual(new Span(&other, sizeof(ecs_shell_script_info_t))); } } public override bool Equals(object? obj) { - return obj is ecs_script_runtime_t other && Equals(other); + return obj is ecs_shell_script_info_t other && Equals(other); } - public static bool operator ==(ecs_script_runtime_t left, ecs_script_runtime_t right) + public static bool operator ==(ecs_shell_script_info_t left, ecs_shell_script_info_t right) { return left.Equals(right); } - public static bool operator !=(ecs_script_runtime_t left, ecs_script_runtime_t right) + public static bool operator !=(ecs_shell_script_info_t left, ecs_shell_script_info_t right) { return !(left == right); } public override int GetHashCode() { - fixed (ecs_script_runtime_t* __self = &this) + fixed (ecs_shell_script_info_t* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(ecs_script_runtime_t))); + hash.AddBytes(new Span(__self, sizeof(ecs_shell_script_info_t))); return hash.ToHashCode(); } } } - public partial struct ecs_script_t : IEquatable + public partial struct ecs_shell_script_line_t : IEquatable { - public bool Equals(ecs_script_t other) + public bool Equals(ecs_shell_script_line_t other) { - fixed (ecs_script_t* __self = &this) + fixed (ecs_shell_script_line_t* __self = &this) { - return new Span(__self, sizeof(ecs_script_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_t))); + return new Span(__self, sizeof(ecs_shell_script_line_t)).SequenceEqual(new Span(&other, sizeof(ecs_shell_script_line_t))); } } public override bool Equals(object? obj) { - return obj is ecs_script_t other && Equals(other); + return obj is ecs_shell_script_line_t other && Equals(other); } - public static bool operator ==(ecs_script_t left, ecs_script_t right) + public static bool operator ==(ecs_shell_script_line_t left, ecs_shell_script_line_t right) { return left.Equals(right); } - public static bool operator !=(ecs_script_t left, ecs_script_t right) + public static bool operator !=(ecs_shell_script_line_t left, ecs_shell_script_line_t right) { return !(left == right); } public override int GetHashCode() { - fixed (ecs_script_t* __self = &this) + fixed (ecs_shell_script_line_t* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(ecs_script_t))); + hash.AddBytes(new Span(__self, sizeof(ecs_shell_script_line_t))); return hash.ToHashCode(); } } } - public partial struct ecs_script_template_t : IEquatable + public partial struct ecs_shell_script_location_t : IEquatable { - public bool Equals(ecs_script_template_t other) + public bool Equals(ecs_shell_script_location_t other) { - fixed (ecs_script_template_t* __self = &this) + fixed (ecs_shell_script_location_t* __self = &this) { - return new Span(__self, sizeof(ecs_script_template_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_template_t))); + return new Span(__self, sizeof(ecs_shell_script_location_t)).SequenceEqual(new Span(&other, sizeof(ecs_shell_script_location_t))); } } public override bool Equals(object? obj) { - return obj is ecs_script_template_t other && Equals(other); + return obj is ecs_shell_script_location_t other && Equals(other); } - public static bool operator ==(ecs_script_template_t left, ecs_script_template_t right) + public static bool operator ==(ecs_shell_script_location_t left, ecs_shell_script_location_t right) { return left.Equals(right); } - public static bool operator !=(ecs_script_template_t left, ecs_script_template_t right) + public static bool operator !=(ecs_shell_script_location_t left, ecs_shell_script_location_t right) { return !(left == right); } public override int GetHashCode() { - fixed (ecs_script_template_t* __self = &this) + fixed (ecs_shell_script_location_t* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(ecs_script_template_t))); + hash.AddBytes(new Span(__self, sizeof(ecs_shell_script_location_t))); return hash.ToHashCode(); } } } - public partial struct ecs_script_var_t : IEquatable + public partial struct ecs_shell_script_match_t : IEquatable { - public bool Equals(ecs_script_var_t other) + public bool Equals(ecs_shell_script_match_t other) { - fixed (ecs_script_var_t* __self = &this) + fixed (ecs_shell_script_match_t* __self = &this) { - return new Span(__self, sizeof(ecs_script_var_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_var_t))); + return new Span(__self, sizeof(ecs_shell_script_match_t)).SequenceEqual(new Span(&other, sizeof(ecs_shell_script_match_t))); } } public override bool Equals(object? obj) { - return obj is ecs_script_var_t other && Equals(other); + return obj is ecs_shell_script_match_t other && Equals(other); } - public static bool operator ==(ecs_script_var_t left, ecs_script_var_t right) + public static bool operator ==(ecs_shell_script_match_t left, ecs_shell_script_match_t right) { return left.Equals(right); } - public static bool operator !=(ecs_script_var_t left, ecs_script_var_t right) + public static bool operator !=(ecs_shell_script_match_t left, ecs_shell_script_match_t right) { return !(left == right); } public override int GetHashCode() { - fixed (ecs_script_var_t* __self = &this) + fixed (ecs_shell_script_match_t* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(ecs_script_var_t))); + hash.AddBytes(new Span(__self, sizeof(ecs_shell_script_match_t))); return hash.ToHashCode(); } } } - public partial struct ecs_script_vars_t : IEquatable + public partial struct ecs_shell_session_desc_t : IEquatable { - public bool Equals(ecs_script_vars_t other) + public bool Equals(ecs_shell_session_desc_t other) { - fixed (ecs_script_vars_t* __self = &this) + fixed (ecs_shell_session_desc_t* __self = &this) { - return new Span(__self, sizeof(ecs_script_vars_t)).SequenceEqual(new Span(&other, sizeof(ecs_script_vars_t))); + return new Span(__self, sizeof(ecs_shell_session_desc_t)).SequenceEqual(new Span(&other, sizeof(ecs_shell_session_desc_t))); } } public override bool Equals(object? obj) { - return obj is ecs_script_vars_t other && Equals(other); + return obj is ecs_shell_session_desc_t other && Equals(other); } - public static bool operator ==(ecs_script_vars_t left, ecs_script_vars_t right) + public static bool operator ==(ecs_shell_session_desc_t left, ecs_shell_session_desc_t right) { return left.Equals(right); } - public static bool operator !=(ecs_script_vars_t left, ecs_script_vars_t right) + public static bool operator !=(ecs_shell_session_desc_t left, ecs_shell_session_desc_t right) { return !(left == right); } public override int GetHashCode() { - fixed (ecs_script_vars_t* __self = &this) + fixed (ecs_shell_session_desc_t* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(ecs_script_vars_t))); + hash.AddBytes(new Span(__self, sizeof(ecs_shell_session_desc_t))); return hash.ToHashCode(); } } } - public partial struct ecs_serializer_t : IEquatable + public partial struct ecs_shell_tree_node_t : IEquatable { - public bool Equals(ecs_serializer_t other) + public bool Equals(ecs_shell_tree_node_t other) { - fixed (ecs_serializer_t* __self = &this) + fixed (ecs_shell_tree_node_t* __self = &this) { - return new Span(__self, sizeof(ecs_serializer_t)).SequenceEqual(new Span(&other, sizeof(ecs_serializer_t))); + return new Span(__self, sizeof(ecs_shell_tree_node_t)).SequenceEqual(new Span(&other, sizeof(ecs_shell_tree_node_t))); } } public override bool Equals(object? obj) { - return obj is ecs_serializer_t other && Equals(other); + return obj is ecs_shell_tree_node_t other && Equals(other); } - public static bool operator ==(ecs_serializer_t left, ecs_serializer_t right) + public static bool operator ==(ecs_shell_tree_node_t left, ecs_shell_tree_node_t right) { return left.Equals(right); } - public static bool operator !=(ecs_serializer_t left, ecs_serializer_t right) + public static bool operator !=(ecs_shell_tree_node_t left, ecs_shell_tree_node_t right) { return !(left == right); } public override int GetHashCode() { - fixed (ecs_serializer_t* __self = &this) + fixed (ecs_shell_tree_node_t* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(ecs_serializer_t))); + hash.AddBytes(new Span(__self, sizeof(ecs_shell_tree_node_t))); return hash.ToHashCode(); } } @@ -13003,6 +14956,42 @@ public override int GetHashCode() } } + public partial struct ecs_table_cache_elem_t : IEquatable + { + public bool Equals(ecs_table_cache_elem_t other) + { + fixed (ecs_table_cache_elem_t* __self = &this) + { + return new Span(__self, sizeof(ecs_table_cache_elem_t)).SequenceEqual(new Span(&other, sizeof(ecs_table_cache_elem_t))); + } + } + + public override bool Equals(object? obj) + { + return obj is ecs_table_cache_elem_t other && Equals(other); + } + + public static bool operator ==(ecs_table_cache_elem_t left, ecs_table_cache_elem_t right) + { + return left.Equals(right); + } + + public static bool operator !=(ecs_table_cache_elem_t left, ecs_table_cache_elem_t right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (ecs_table_cache_elem_t* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(ecs_table_cache_elem_t))); + return hash.ToHashCode(); + } + } + } + public partial struct ecs_table_cache_hdr_t : IEquatable { public bool Equals(ecs_table_cache_hdr_t other) @@ -14227,109 +16216,109 @@ public override int GetHashCode() } } - public partial struct EcsComponent : IEquatable + public partial struct EcsCommandSession : IEquatable { - public bool Equals(EcsComponent other) + public bool Equals(EcsCommandSession other) { - fixed (EcsComponent* __self = &this) + fixed (EcsCommandSession* __self = &this) { - return new Span(__self, sizeof(EcsComponent)).SequenceEqual(new Span(&other, sizeof(EcsComponent))); + return new Span(__self, sizeof(EcsCommandSession)).SequenceEqual(new Span(&other, sizeof(EcsCommandSession))); } } public override bool Equals(object? obj) { - return obj is EcsComponent other && Equals(other); + return obj is EcsCommandSession other && Equals(other); } - public static bool operator ==(EcsComponent left, EcsComponent right) + public static bool operator ==(EcsCommandSession left, EcsCommandSession right) { return left.Equals(right); } - public static bool operator !=(EcsComponent left, EcsComponent right) + public static bool operator !=(EcsCommandSession left, EcsCommandSession right) { return !(left == right); } public override int GetHashCode() { - fixed (EcsComponent* __self = &this) + fixed (EcsCommandSession* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(EcsComponent))); + hash.AddBytes(new Span(__self, sizeof(EcsCommandSession))); return hash.ToHashCode(); } } } - public partial struct EcsConstants : IEquatable + public partial struct EcsComponent : IEquatable { - public bool Equals(EcsConstants other) + public bool Equals(EcsComponent other) { - fixed (EcsConstants* __self = &this) + fixed (EcsComponent* __self = &this) { - return new Span(__self, sizeof(EcsConstants)).SequenceEqual(new Span(&other, sizeof(EcsConstants))); + return new Span(__self, sizeof(EcsComponent)).SequenceEqual(new Span(&other, sizeof(EcsComponent))); } } public override bool Equals(object? obj) { - return obj is EcsConstants other && Equals(other); + return obj is EcsComponent other && Equals(other); } - public static bool operator ==(EcsConstants left, EcsConstants right) + public static bool operator ==(EcsComponent left, EcsComponent right) { return left.Equals(right); } - public static bool operator !=(EcsConstants left, EcsConstants right) + public static bool operator !=(EcsComponent left, EcsComponent right) { return !(left == right); } public override int GetHashCode() { - fixed (EcsConstants* __self = &this) + fixed (EcsComponent* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(EcsConstants))); + hash.AddBytes(new Span(__self, sizeof(EcsComponent))); return hash.ToHashCode(); } } } - public partial struct EcsDefaultChildComponent : IEquatable + public partial struct EcsConstants : IEquatable { - public bool Equals(EcsDefaultChildComponent other) + public bool Equals(EcsConstants other) { - fixed (EcsDefaultChildComponent* __self = &this) + fixed (EcsConstants* __self = &this) { - return new Span(__self, sizeof(EcsDefaultChildComponent)).SequenceEqual(new Span(&other, sizeof(EcsDefaultChildComponent))); + return new Span(__self, sizeof(EcsConstants)).SequenceEqual(new Span(&other, sizeof(EcsConstants))); } } public override bool Equals(object? obj) { - return obj is EcsDefaultChildComponent other && Equals(other); + return obj is EcsConstants other && Equals(other); } - public static bool operator ==(EcsDefaultChildComponent left, EcsDefaultChildComponent right) + public static bool operator ==(EcsConstants left, EcsConstants right) { return left.Equals(right); } - public static bool operator !=(EcsDefaultChildComponent left, EcsDefaultChildComponent right) + public static bool operator !=(EcsConstants left, EcsConstants right) { return !(left == right); } public override int GetHashCode() { - fixed (EcsDefaultChildComponent* __self = &this) + fixed (EcsConstants* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(EcsDefaultChildComponent))); + hash.AddBytes(new Span(__self, sizeof(EcsConstants))); return hash.ToHashCode(); } } @@ -14437,7 +16426,43 @@ public override int GetHashCode() fixed (EcsIdentifier* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(EcsIdentifier))); + hash.AddBytes(new Span(__self, sizeof(EcsIdentifier))); + return hash.ToHashCode(); + } + } + } + + public partial struct EcsMap : IEquatable + { + public bool Equals(EcsMap other) + { + fixed (EcsMap* __self = &this) + { + return new Span(__self, sizeof(EcsMap)).SequenceEqual(new Span(&other, sizeof(EcsMap))); + } + } + + public override bool Equals(object? obj) + { + return obj is EcsMap other && Equals(other); + } + + public static bool operator ==(EcsMap left, EcsMap right) + { + return left.Equals(right); + } + + public static bool operator !=(EcsMap left, EcsMap right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (EcsMap* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(EcsMap))); return hash.ToHashCode(); } } @@ -14875,6 +16900,42 @@ public override int GetHashCode() } } + public partial struct EcsScriptActivateEvent : IEquatable + { + public bool Equals(EcsScriptActivateEvent other) + { + fixed (EcsScriptActivateEvent* __self = &this) + { + return new Span(__self, sizeof(EcsScriptActivateEvent)).SequenceEqual(new Span(&other, sizeof(EcsScriptActivateEvent))); + } + } + + public override bool Equals(object? obj) + { + return obj is EcsScriptActivateEvent other && Equals(other); + } + + public static bool operator ==(EcsScriptActivateEvent left, EcsScriptActivateEvent right) + { + return left.Equals(right); + } + + public static bool operator !=(EcsScriptActivateEvent left, EcsScriptActivateEvent right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (EcsScriptActivateEvent* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(EcsScriptActivateEvent))); + return hash.ToHashCode(); + } + } + } + public partial struct EcsScriptConstVar : IEquatable { public bool Equals(EcsScriptConstVar other) @@ -14911,6 +16972,150 @@ public override int GetHashCode() } } + public partial struct EcsScriptFocusEvent : IEquatable + { + public bool Equals(EcsScriptFocusEvent other) + { + fixed (EcsScriptFocusEvent* __self = &this) + { + return new Span(__self, sizeof(EcsScriptFocusEvent)).SequenceEqual(new Span(&other, sizeof(EcsScriptFocusEvent))); + } + } + + public override bool Equals(object? obj) + { + return obj is EcsScriptFocusEvent other && Equals(other); + } + + public static bool operator ==(EcsScriptFocusEvent left, EcsScriptFocusEvent right) + { + return left.Equals(right); + } + + public static bool operator !=(EcsScriptFocusEvent left, EcsScriptFocusEvent right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (EcsScriptFocusEvent* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(EcsScriptFocusEvent))); + return hash.ToHashCode(); + } + } + } + + public partial struct EcsScriptKeyboardEvent : IEquatable + { + public bool Equals(EcsScriptKeyboardEvent other) + { + fixed (EcsScriptKeyboardEvent* __self = &this) + { + return new Span(__self, sizeof(EcsScriptKeyboardEvent)).SequenceEqual(new Span(&other, sizeof(EcsScriptKeyboardEvent))); + } + } + + public override bool Equals(object? obj) + { + return obj is EcsScriptKeyboardEvent other && Equals(other); + } + + public static bool operator ==(EcsScriptKeyboardEvent left, EcsScriptKeyboardEvent right) + { + return left.Equals(right); + } + + public static bool operator !=(EcsScriptKeyboardEvent left, EcsScriptKeyboardEvent right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (EcsScriptKeyboardEvent* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(EcsScriptKeyboardEvent))); + return hash.ToHashCode(); + } + } + } + + public partial struct EcsScriptMouseEvent : IEquatable + { + public bool Equals(EcsScriptMouseEvent other) + { + fixed (EcsScriptMouseEvent* __self = &this) + { + return new Span(__self, sizeof(EcsScriptMouseEvent)).SequenceEqual(new Span(&other, sizeof(EcsScriptMouseEvent))); + } + } + + public override bool Equals(object? obj) + { + return obj is EcsScriptMouseEvent other && Equals(other); + } + + public static bool operator ==(EcsScriptMouseEvent left, EcsScriptMouseEvent right) + { + return left.Equals(right); + } + + public static bool operator !=(EcsScriptMouseEvent left, EcsScriptMouseEvent right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (EcsScriptMouseEvent* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(EcsScriptMouseEvent))); + return hash.ToHashCode(); + } + } + } + + public partial struct EcsScriptMutVar : IEquatable + { + public bool Equals(EcsScriptMutVar other) + { + fixed (EcsScriptMutVar* __self = &this) + { + return new Span(__self, sizeof(EcsScriptMutVar)).SequenceEqual(new Span(&other, sizeof(EcsScriptMutVar))); + } + } + + public override bool Equals(object? obj) + { + return obj is EcsScriptMutVar other && Equals(other); + } + + public static bool operator ==(EcsScriptMutVar left, EcsScriptMutVar right) + { + return left.Equals(right); + } + + public static bool operator !=(EcsScriptMutVar left, EcsScriptMutVar right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (EcsScriptMutVar* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(EcsScriptMutVar))); + return hash.ToHashCode(); + } + } + } + public partial struct EcsScriptRng : IEquatable { public bool Equals(EcsScriptRng other) @@ -14947,6 +17152,78 @@ public override int GetHashCode() } } + public partial struct EcsScriptShell : IEquatable + { + public bool Equals(EcsScriptShell other) + { + fixed (EcsScriptShell* __self = &this) + { + return new Span(__self, sizeof(EcsScriptShell)).SequenceEqual(new Span(&other, sizeof(EcsScriptShell))); + } + } + + public override bool Equals(object? obj) + { + return obj is EcsScriptShell other && Equals(other); + } + + public static bool operator ==(EcsScriptShell left, EcsScriptShell right) + { + return left.Equals(right); + } + + public static bool operator !=(EcsScriptShell left, EcsScriptShell right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (EcsScriptShell* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(EcsScriptShell))); + return hash.ToHashCode(); + } + } + } + + public partial struct EcsScriptTask : IEquatable + { + public bool Equals(EcsScriptTask other) + { + fixed (EcsScriptTask* __self = &this) + { + return new Span(__self, sizeof(EcsScriptTask)).SequenceEqual(new Span(&other, sizeof(EcsScriptTask))); + } + } + + public override bool Equals(object? obj) + { + return obj is EcsScriptTask other && Equals(other); + } + + public static bool operator ==(EcsScriptTask left, EcsScriptTask right) + { + return left.Equals(right); + } + + public static bool operator !=(EcsScriptTask left, EcsScriptTask right) + { + return !(left == right); + } + + public override int GetHashCode() + { + fixed (EcsScriptTask* __self = &this) + { + HashCode hash = new(); + hash.AddBytes(new Span(__self, sizeof(EcsScriptTask))); + return hash.ToHashCode(); + } + } + } + public partial struct EcsStatsHeader : IEquatable { public bool Equals(EcsStatsHeader other) @@ -15679,45 +17956,6 @@ public override int GetHashCode() } } - public partial struct InlineArrays - { - public partial struct ecs_commands_t_2 : IEquatable - { - public bool Equals(ecs_commands_t_2 other) - { - fixed (ecs_commands_t_2* __self = &this) - { - return new Span(__self, sizeof(ecs_commands_t_2)).SequenceEqual(new Span(&other, sizeof(ecs_commands_t_2))); - } - } - - public override bool Equals(object? obj) - { - return obj is ecs_commands_t_2 other && Equals(other); - } - - public static bool operator ==(ecs_commands_t_2 left, ecs_commands_t_2 right) - { - return left.Equals(right); - } - - public static bool operator !=(ecs_commands_t_2 left, ecs_commands_t_2 right) - { - return !(left == right); - } - - public override int GetHashCode() - { - fixed (ecs_commands_t_2* __self = &this) - { - HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(ecs_commands_t_2))); - return hash.ToHashCode(); - } - } - } - } - public partial struct InlineArrays { public partial struct ulong_32 : IEquatable @@ -16110,37 +18348,37 @@ public override int GetHashCode() public partial struct InlineArrays { - public partial struct delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18 : IEquatable + public partial struct ecs_script_parameter_t_16 : IEquatable { - public bool Equals(delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18 other) + public bool Equals(ecs_script_parameter_t_16 other) { - fixed (delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18* __self = &this) + fixed (ecs_script_parameter_t_16* __self = &this) { - return new Span(__self, sizeof(delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18)).SequenceEqual(new Span(&other, sizeof(delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18))); + return new Span(__self, sizeof(ecs_script_parameter_t_16)).SequenceEqual(new Span(&other, sizeof(ecs_script_parameter_t_16))); } } public override bool Equals(object? obj) { - return obj is delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18 other && Equals(other); + return obj is ecs_script_parameter_t_16 other && Equals(other); } - public static bool operator ==(delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18 left, delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18 right) + public static bool operator ==(ecs_script_parameter_t_16 left, ecs_script_parameter_t_16 right) { return left.Equals(right); } - public static bool operator !=(delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18 left, delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18 right) + public static bool operator !=(ecs_script_parameter_t_16 left, ecs_script_parameter_t_16 right) { return !(left == right); } public override int GetHashCode() { - fixed (delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18* __self = &this) + fixed (ecs_script_parameter_t_16* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18))); + hash.AddBytes(new Span(__self, sizeof(ecs_script_parameter_t_16))); return hash.ToHashCode(); } } @@ -16149,37 +18387,37 @@ public override int GetHashCode() public partial struct InlineArrays { - public partial struct ecs_script_parameter_t_16 : IEquatable + public partial struct delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18 : IEquatable { - public bool Equals(ecs_script_parameter_t_16 other) + public bool Equals(delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18 other) { - fixed (ecs_script_parameter_t_16* __self = &this) + fixed (delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18* __self = &this) { - return new Span(__self, sizeof(ecs_script_parameter_t_16)).SequenceEqual(new Span(&other, sizeof(ecs_script_parameter_t_16))); + return new Span(__self, sizeof(delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18)).SequenceEqual(new Span(&other, sizeof(delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18))); } } public override bool Equals(object? obj) { - return obj is ecs_script_parameter_t_16 other && Equals(other); + return obj is delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18 other && Equals(other); } - public static bool operator ==(ecs_script_parameter_t_16 left, ecs_script_parameter_t_16 right) + public static bool operator ==(delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18 left, delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18 right) { return left.Equals(right); } - public static bool operator !=(ecs_script_parameter_t_16 left, ecs_script_parameter_t_16 right) + public static bool operator !=(delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18 left, delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18 right) { return !(left == right); } public override int GetHashCode() { - fixed (ecs_script_parameter_t_16* __self = &this) + fixed (delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18* __self = &this) { HashCode hash = new(); - hash.AddBytes(new Span(__self, sizeof(ecs_script_parameter_t_16))); + hash.AddBytes(new Span(__self, sizeof(delegateP_unmanaged_ecs_function_ctx_tP__int__ecs_value_tP__ecs_value_tP__int__void__18))); return hash.ToHashCode(); } } diff --git a/src/Flecs.NET.Codegen/FlecsGenerator.cs b/src/Flecs.NET.Codegen/FlecsGenerator.cs index b52893ef..86b30727 100644 --- a/src/Flecs.NET.Codegen/FlecsGenerator.cs +++ b/src/Flecs.NET.Codegen/FlecsGenerator.cs @@ -33,6 +33,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) Generate(context); Generate(context); Generate(context); + Generate(context); Generate(context); }); } diff --git a/src/Flecs.NET.Codegen/Generators/Ecs.cs b/src/Flecs.NET.Codegen/Generators/Ecs.cs index 960077c2..20437a02 100644 --- a/src/Flecs.NET.Codegen/Generators/Ecs.cs +++ b/src/Flecs.NET.Codegen/Generators/Ecs.cs @@ -175,7 +175,7 @@ public static unsafe partial class Ecs continue; } - ptrs[i] = ecs_record_get_by_column(r, columns[i], 0); + ptrs[i] = flecs_entity_get_column(r, columns[i], 0); } return true; diff --git a/src/Flecs.NET.Codegen/Generators/Entity.cs b/src/Flecs.NET.Codegen/Generators/Entity.cs index bca80687..84cb7439 100644 --- a/src/Flecs.NET.Codegen/Generators/Entity.cs +++ b/src/Flecs.NET.Codegen/Generators/Entity.cs @@ -661,40 +661,46 @@ public Entity Clone(bool cloneValue = true, ulong dstId = 0) return Entity.Clone(cloneValue, dstId); } - /// - public Entity Mut(ref World stage) + /// + public Entity Stage(ref World stage) { - return Entity.Mut(ref stage); + return Entity.Stage(ref stage); } - /// - public Entity Mut(ref Iter it) + /// + public Entity Stage(ref Iter it) { - return Entity.Mut(ref it); + return Entity.Stage(ref it); } - /// - public Entity Mut(ref Entity entity) + /// + public Entity Stage(ref Entity entity) { - return Entity.Mut(ref entity); + return Entity.Stage(ref entity); } - /// - public Entity Mut(World stage) + /// + public Entity Stage(World stage) { - return Entity.Mut(stage); + return Entity.Stage(stage); } - /// - public Entity Mut(Iter it) + /// + public Entity Stage(Iter it) { - return Entity.Mut(it); + return Entity.Stage(it); } - /// - public Entity Mut(Entity entity) + /// + public Entity Stage(Entity entity) { - return Entity.Mut(entity); + return Entity.Stage(entity); + } + + /// + public Entity Stage() + { + return Entity.Stage(); } /// @@ -1024,34 +1030,6 @@ public bool IsChildOf(T value) where T : Enum return ref this; } - /// - public ref {{typeName}} SlotOf(ulong id) - { - Entity.SlotOf(id); - return ref this; - } - - /// - public ref {{typeName}} SlotOf() - { - Entity.SlotOf(); - return ref this; - } - - /// - public ref {{typeName}} SlotOf(T value) where T : Enum - { - Entity.SlotOf(value); - return ref this; - } - - /// - public ref {{typeName}} Slot() - { - Entity.Slot(); - return ref this; - } - /// public ref {{typeName}} Remove(ulong id) { @@ -1486,48 +1464,6 @@ public bool IsChildOf(T value) where T : Enum return ref this; } - /// - public ref {{typeName}} With(Action callback) - { - Entity.With(callback); - return ref this; - } - - /// - public ref {{typeName}} With(ulong first, Action callback) - { - Entity.With(first, callback); - return ref this; - } - - /// - public ref {{typeName}} With(Action callback) - { - Entity.With(callback); - return ref this; - } - - /// - public ref {{typeName}} With(Ecs.WorldCallback callback) - { - Entity.With(callback); - return ref this; - } - - /// - public ref {{typeName}} With(ulong first, Ecs.WorldCallback callback) - { - Entity.With(first, callback); - return ref this; - } - - /// - public ref {{typeName}} With(Ecs.WorldCallback callback) - { - Entity.With(callback); - return ref this; - } - /// public ref {{typeName}} Scope(Action callback) { diff --git a/src/Flecs.NET.Codegen/Generators/Invoker.cs b/src/Flecs.NET.Codegen/Generators/Invoker.cs index bcbf76c7..32fe5e5e 100644 --- a/src/Flecs.NET.Codegen/Generators/Invoker.cs +++ b/src/Flecs.NET.Codegen/Generators/Invoker.cs @@ -212,7 +212,7 @@ private static string GenerateFindInvokerIterators(Callback callback, int i) for (int i = 0; i < count; i++) { if (callback({{Generator.GetCallbackArguments(callback, iterationTechnique, i)}})) - return new Entity(it.Handle->world, it.Handle->entities[i]); + return new Entity(it.Handle->stage, it.Handle->entities[i]); } return default; @@ -340,15 +340,13 @@ public static string GenerateFetchComponentInvokers(int i) /// True if the entity has the specified components. public static bool {{Generator.GetInvokerName(callback)}}<{{Generator.TypeParameters[i]}}>(ecs_world_t* world, ulong entity, {{Generator.GetCallbackType(callback, i)}} callback) { - ecs_record_t* record = ecs_{{Generator.GetInvokerName(callback).ToLower()}}_begin(world, entity); + ecs_record_t* record = flecs_entities_get(ecs_get_world(world), entity); - if (record == null) + if (record == null || record->table == null) return false; - ecs_table_t *table = record->table; - - if (table == null) - return false; + ecs_table_t* table = record->table; + Ecs.TableLock(world, table); void** pointers = stackalloc void*[{{i + 1}}]; bool hasComponents = Ecs.GetPointers<{{Generator.TypeParameters[i]}}>(world, entity, record, table, pointers); @@ -356,7 +354,7 @@ public static string GenerateFetchComponentInvokers(int i) if (hasComponents) callback({{Generator.GetCallbackArguments(callback, i)}}); - ecs_{{Generator.GetInvokerName(callback).ToLower()}}_end(record); + Ecs.TableUnlock(world, table); return hasComponents; } @@ -378,43 +376,17 @@ public static string GenerateFetchComponentInvokers(int i) ecs_table_t* table = null; - if (!world.IsDeferred()) + if (!world.IsStage()) { - Ecs.Assert(!world.IsStage(), nameof(ECS_INVALID_PARAMETER)); - - ecs_record_t* record = ecs_record_find(world, entity); - - if (record != null) - table = record->table; - - ecs_table_t* prev = table; - ecs_table_t* next = null; - - ulong* added = stackalloc ulong[{{i + 1}}]; - int addedCount = 0; - - for (int i = 0; i < {{i + 1}}; i++) - { - next = ecs_table_add_id(world, prev, ids[i]); - - if (prev != next) - added[addedCount++] = ids[i]; - - prev = next; - } - - if (table != next) - { - ecs_type_t type = default; - type.array = added; - type.count = addedCount; - ecs_commit(world, entity, record, next, &type, null); - table = next; - } - + ecs_record_t* record = flecs_entities_get(world, entity); + Ecs.Assert(record != null, nameof(ECS_INVALID_PARAMETER)); + + flecs_add_ids(world, entity, ids, {{i + 1}}); + table = record->table; + if (!Ecs.GetPointers<{{Generator.TypeParameters[i]}}>(world, entity, record, table, pointers)) Ecs.Error(nameof(ECS_INTERNAL_ERROR)); - + Ecs.TableLock(world, table); } else @@ -424,7 +396,7 @@ public static string GenerateFetchComponentInvokers(int i) callback({{Generator.GetCallbackArguments(callback, i)}}); - if (!world.IsDeferred()) + if (table != null) Ecs.TableUnlock(world, table); {{Generator.ModifiedChain[i]}} diff --git a/src/Flecs.NET.Codegen/Generators/Query.cs b/src/Flecs.NET.Codegen/Generators/Query.cs index a95b8ee2..56b06b19 100644 --- a/src/Flecs.NET.Codegen/Generators/Query.cs +++ b/src/Flecs.NET.Codegen/Generators/Query.cs @@ -206,10 +206,10 @@ public World World() return Underlying.World(); } - /// - public World RealWorld() + /// + public World Stage() { - return Underlying.RealWorld(); + return Underlying.Stage(); } } @@ -223,7 +223,7 @@ public unsafe partial struct {{Generator.GetTypeName(Type.Query, i)}} : IQuery public unsafe partial struct {{Generator.GetTypeName(Type.Query, i)}} : IIterableBase { /// - ecs_world_t* IIterableBase.World => Handle->world; + ecs_world_t* IIterableBase.World => Handle->stage; /// [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Flecs.NET.Codegen/Generators/SparseQuery.cs b/src/Flecs.NET.Codegen/Generators/SparseQuery.cs new file mode 100644 index 00000000..7dcc168a --- /dev/null +++ b/src/Flecs.NET.Codegen/Generators/SparseQuery.cs @@ -0,0 +1,151 @@ +using System.Collections.Generic; +using System.Linq; +using Flecs.NET.Codegen.Helpers; + +namespace Flecs.NET.Codegen.Generators; + +public class SparseQuery : GeneratorBase +{ + public override void Generate() + { + for (int i = 0; i < Generator.GenericCount; i++) + AddSource($"T{i + 1}.g.cs", GenerateSparseQuery(i)); + } + + private static string GenerateSparseQuery(int i) + { + string typeIds = string.Join(Separator.Comma, + Enumerable.Range(0, i + 1).Select(f => $"Type.Id(World)")); + + string refArguments = string.Join(Separator.Comma, + Enumerable.Range(0, i + 1).Select(f => $"ref Managed.GetTypeRef(ptrs[{f}])")); + + IEnumerable asserts = Enumerable.Range(0, i + 1).Select(f => $$""" + Ecs.Assert(ecs_has_id(world, Type.Id(world), Ecs.DontFragment), "Sparse query component must have the DontFragment trait."); + Ecs.Assert(ecs_get_target(world, Type.Id(world), Ecs.OnInstantiate, 0) != Ecs.Inherit, "Sparse query component cannot have the OnInstantiate Inherit trait."); + """); + + IEnumerable eachs = new[] + { + $$""" + /// + /// Iterates the query using the provided callback. + /// + /// The callback. + public void Each({{Generator.EachRefCallbackDelegate[i]}} callback) + { + ulong* ids = stackalloc ulong[] { {{typeIds}} }; + SparseQuery.Each(World, ids, {{i + 1}}, &callback, &EachRefCallbackDelegate); + } + + /// + /// Iterates the query using the provided callback. + /// + /// The callback. + public void Each({{Generator.EachEntityRefCallbackDelegate[i]}} callback) + { + ulong* ids = stackalloc ulong[] { {{typeIds}} }; + SparseQuery.Each(World, ids, {{i + 1}}, &callback, &EachEntityRefCallbackDelegate); + } + + /// + /// Iterates the query using the provided callback. + /// + /// The callback. + public void Each({{Generator.EachRefCallbackPointer[i]}} callback) + { + ulong* ids = stackalloc ulong[] { {{typeIds}} }; + SparseQuery.Each(World, ids, {{i + 1}}, callback, &EachRefCallbackPointer); + } + + /// + /// Iterates the query using the provided callback. + /// + /// The callback. + public void Each({{Generator.EachEntityRefCallbackPointer[i]}} callback) + { + ulong* ids = stackalloc ulong[] { {{typeIds}} }; + SparseQuery.Each(World, ids, {{i + 1}}, callback, &EachEntityRefCallbackPointer); + } + + private static void EachRefCallbackDelegate(void* context, ecs_world_t* world, ulong entity, void** ptrs) + { + Unsafe.AsRef<{{Generator.EachRefCallbackDelegate[i]}}>(context)({{refArguments}}); + } + + private static void EachEntityRefCallbackDelegate(void* context, ecs_world_t* world, ulong entity, void** ptrs) + { + Unsafe.AsRef<{{Generator.EachEntityRefCallbackDelegate[i]}}>(context)(new Entity(world, entity), {{refArguments}}); + } + + private static void EachRefCallbackPointer(void* context, ecs_world_t* world, ulong entity, void** ptrs) + { + (({{Generator.EachRefCallbackPointer[i]}})context)({{refArguments}}); + } + + private static void EachEntityRefCallbackPointer(void* context, ecs_world_t* world, ulong entity, void** ptrs) + { + (({{Generator.EachEntityRefCallbackPointer[i]}})context)(new Entity(world, entity), {{refArguments}}); + } + """ + }; + + return $$""" + #nullable enable + + using System; + using System.Runtime.CompilerServices; + using Flecs.NET.Utilities; + + using static Flecs.NET.Bindings.flecs; + + namespace Flecs.NET.Core; + + /// + /// A query that iterates sparse component storages directly and takes {{i + 1}} type arguments. + /// + /// {{Generator.XmlTypeParameters[i]}} + public unsafe partial struct {{Generator.GetTypeName(Type.SparseQuery, i)}} + { + private ecs_world_t* _world; + + /// + /// A reference to the world. + /// + public ecs_world_t* World => _world; + + /// + /// Creates a sparse query from the provided world. + /// + /// The world. + public {{Generator.GetTypeName(Type.SparseQuery)}}(ecs_world_t* world) + { + _world = ecs_get_world(world); + + {{string.Join(Separator.NewLine, asserts)}} + } + + {{string.Join(Separator.DoubleNewLine, eachs)}} + + /// + /// Returns the number of entities matched by the query. + /// + /// The number of matched entities. + public int Count() + { + ulong* ids = stackalloc ulong[] { {{typeIds}} }; + return SparseQuery.Each(World, ids, {{i + 1}}, null, null); + } + + /// + /// Converts the sparse query to a regular query for the same components. + /// + /// The query. + public {{Generator.GetTypeName(Type.Query, i)}} ToQuery() + { + return new {{Generator.GetTypeName(Type.QueryBuilder, i)}}(World).Build(); + } + } + """; + } +} diff --git a/src/Flecs.NET.Codegen/Generators/World.cs b/src/Flecs.NET.Codegen/Generators/World.cs index 7d52db6b..6680a0bb 100644 --- a/src/Flecs.NET.Codegen/Generators/World.cs +++ b/src/Flecs.NET.Codegen/Generators/World.cs @@ -20,6 +20,8 @@ private static string GenerateBuilders(int i) return $$""" #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + using static Flecs.NET.Bindings.flecs; + namespace Flecs.NET.Core; public unsafe partial struct World @@ -84,6 +86,11 @@ public unsafe partial struct World return new {{Generator.GetTypeName(Type.QueryBuilder, i)}}(Handle, entity).Build(); } + public {{Generator.GetTypeName(Type.SparseQuery, i)}} {{Generator.GetTypeName(Type.SparseQuery, i)}}() + { + return new {{Generator.GetTypeName(Type.SparseQuery, i)}}(ecs_get_world(Handle)); + } + public {{Generator.GetTypeName(Type.SystemBuilder, i)}} {{Generator.GetTypeName(Type.System, i)}}() { return new {{Generator.GetTypeName(Type.SystemBuilder, i)}}(Handle); diff --git a/src/Flecs.NET.Codegen/Helpers/Generator.cs b/src/Flecs.NET.Codegen/Helpers/Generator.cs index d9e1eb16..5594bf86 100644 --- a/src/Flecs.NET.Codegen/Helpers/Generator.cs +++ b/src/Flecs.NET.Codegen/Helpers/Generator.cs @@ -476,8 +476,8 @@ public static string GetCallbackArguments(Callback parameters, IterationTechniqu { CallbackParameters.EachRef => $"{GetEachRefArguments(iterationTechnique, i)}", CallbackParameters.EachPointer => $"{GetEachPointerArguments(iterationTechnique, i)}", - CallbackParameters.EachEntityRef => $"new Entity(it.Handle->world, it.Handle->entities[i]), {GetEachRefArguments(iterationTechnique, i)}", - CallbackParameters.EachEntityPointer => $"new Entity(it.Handle->world, it.Handle->entities[i]), {GetEachPointerArguments(iterationTechnique, i)}", + CallbackParameters.EachEntityRef => $"new Entity(it.Handle->stage, it.Handle->entities[i]), {GetEachRefArguments(iterationTechnique, i)}", + CallbackParameters.EachEntityPointer => $"new Entity(it.Handle->stage, it.Handle->entities[i]), {GetEachPointerArguments(iterationTechnique, i)}", CallbackParameters.EachIterRef => $"it, i, {GetEachRefArguments(iterationTechnique, i)}", CallbackParameters.EachIterPointer => $"it, i, {GetEachPointerArguments(iterationTechnique, i)}", _ => throw new ArgumentOutOfRangeException(nameof(parameters), parameters, null) diff --git a/src/Flecs.NET.Codegen/Helpers/Type.cs b/src/Flecs.NET.Codegen/Helpers/Type.cs index ae9d0bc4..9257c29b 100644 --- a/src/Flecs.NET.Codegen/Helpers/Type.cs +++ b/src/Flecs.NET.Codegen/Helpers/Type.cs @@ -25,5 +25,6 @@ public enum Type TimerEntity, TypeHelper, UntypedComponent, - WorkerIterable + WorkerIterable, + SparseQuery } diff --git a/src/Flecs.NET.Examples/GameMechanics/InventorySystem.cs b/src/Flecs.NET.Examples/GameMechanics/InventorySystem.cs index 9f6a5a1e..bfa04453 100644 --- a/src/Flecs.NET.Examples/GameMechanics/InventorySystem.cs +++ b/src/Flecs.NET.Examples/GameMechanics/InventorySystem.cs @@ -58,18 +58,14 @@ public static void Main() .SetAutoOverride(new Health(20)); // Create a loot box with items - Entity lootBox = ecs.Entity("Chest").Add().With(() => - { - ecs.Entity().IsA(); - ecs.Entity().IsA(); - ecs.Entity().Add().Set(new Amount(30)); - }); + Entity lootBox = ecs.Entity("Chest").Add(); + ecs.Entity().IsA().Add(lootBox); + ecs.Entity().IsA().Add(lootBox); + ecs.Entity().Add().Set(new Amount(30)).Add(lootBox); // Create a player entity with an inventory - Entity inventory = ecs.Entity().Add().With(() => - { - ecs.Entity().Add().Set(new Amount(20)); - }); + Entity inventory = ecs.Entity().Add(); + ecs.Entity().Add().Set(new Amount(20)).Add(inventory); Entity player = ecs.Entity("Player") .Set(new Health(10)) @@ -238,17 +234,17 @@ private static void TransferItems(Entity dst, Entity src) { Console.WriteLine($">> Transfer items from {src} to {dst}\n"); - // Defer, because we're adding/removing components while we're iterating - dst.CsWorld().Defer(() => - { - dst = GetContainer(dst); // Make sure to replace players with container - src = GetContainer(src); + // Use a stage, because we're adding/removing components while we're iterating + World stage = dst.CsWorld().GetStage(0); + dst = GetContainer(dst); // Make sure to replace players with container + src = GetContainer(src); - ForEachItem(src, (Entity item) => - { - TransferItem(dst, item); - }); + ForEachItem(src, (Entity item) => + { + TransferItem(dst.Stage(stage), item.Stage(stage)); }); + + stage.Merge(); } // Attack player diff --git a/src/Flecs.NET.Examples/GameMechanics/SceneManagement.cs b/src/Flecs.NET.Examples/GameMechanics/SceneManagement.cs index 65a8b224..d64ea380 100644 --- a/src/Flecs.NET.Examples/GameMechanics/SceneManagement.cs +++ b/src/Flecs.NET.Examples/GameMechanics/SceneManagement.cs @@ -45,7 +45,6 @@ public static void Main() // Removes all entities who are children of // the current scene root. - // (NOTE: should use DeferBegin() / DeferEnd()) static void ResetScene(World world) { world.DeleteWith(Ecs.ChildOf, world.Entity()); @@ -55,39 +54,41 @@ static void MenuScene(Iter it, int i) { Console.WriteLine("\n>> ActiveScene has changed to `MenuScene`\n"); - World world = it.World(); - Component scene = world.Component(); + World stage = it.Stage(); + Component scene = stage.Component(); - ResetScene(world); + ResetScene(stage); // Creates a start menu button // when we enter the menu scene. - world.Entity("Start Button") + stage.Entity("Start Button") .Set(new Button("Play the Game!")) .Set(new Position(50, 50)) .ChildOf(scene); - world.SetPipeline(world.Get().Pipeline); + // Pipelines can only be set on the actual world. + it.World().SetPipeline(stage.Get().Pipeline); } static void GameScene(Iter it, int i) { Console.WriteLine("\n>> ActiveScene has changed to `GameScene`\n"); - World world = it.World(); - Component scene = world.Component(); + World stage = it.Stage(); + Component scene = stage.Component(); - ResetScene(world); + ResetScene(stage); // Creates a player character // when we enter the game scene. - world.Entity("Player") + stage.Entity("Player") .Set(default(Character)) .Set(default(Position)) .Set(new Health(2)) .ChildOf(scene); - world.SetPipeline(world.Get().Pipeline); + // Pipelines can only be set on the actual world. + it.World().SetPipeline(stage.Get().Pipeline); } static void InitScenes(World world) diff --git a/src/Flecs.NET.Examples/Observers/EnqueueEntityEvent.cs b/src/Flecs.NET.Examples/Observers/EnqueueEntityEvent.cs index 18f8ffcc..3c118e28 100644 --- a/src/Flecs.NET.Examples/Observers/EnqueueEntityEvent.cs +++ b/src/Flecs.NET.Examples/Observers/EnqueueEntityEvent.cs @@ -40,19 +40,19 @@ public static void Main() Console.WriteLine($"Resized to ({p.Width}, {p.Height})!"); }); - // We can only call enqueue events while the world is deferred mode. - world.DeferBegin(); + // Events can only be enqueued on a stage. + World stage = world.GetStage(0); // Emit the Click event. - widget.Enqueue(); + widget.Stage(stage).Enqueue(); // Emit the Resize event. - widget.Enqueue(new Resize(100, 200)); + widget.Stage(stage).Enqueue(new Resize(100, 200)); Console.WriteLine("Events enqueued!"); // Flushes the queue, and invokes the observer - world.DeferEnd(); + stage.Merge(); } } diff --git a/src/Flecs.NET.Examples/Observers/EnqueueEvent.cs b/src/Flecs.NET.Examples/Observers/EnqueueEvent.cs index 9e4076fc..3ea8006a 100644 --- a/src/Flecs.NET.Examples/Observers/EnqueueEvent.cs +++ b/src/Flecs.NET.Examples/Observers/EnqueueEvent.cs @@ -31,11 +31,11 @@ public static void Main() Entity e = world.Entity("e") .Set(new Position(10, 20)); - // We can only call enqueue events while the world is deferred mode. - world.DeferBegin(); + // Events can only be enqueued on a stage. + World stage = world.GetStage(0); // Emit the custom event - world.Event() + stage.Event() .Id() .Entity(e) .Enqueue(); @@ -43,7 +43,7 @@ public static void Main() Console.WriteLine("Event enqueued!"); // Flushes the queue, and invokes the observer - world.DeferEnd(); + stage.Merge(); } } diff --git a/src/Flecs.NET.Examples/Prefabs/Slots.cs b/src/Flecs.NET.Examples/Prefabs/Slots.cs index f8aa32e3..47760dc9 100644 --- a/src/Flecs.NET.Examples/Prefabs/Slots.cs +++ b/src/Flecs.NET.Examples/Prefabs/Slots.cs @@ -1,27 +1,7 @@ -// Slots can be combined with prefab hierarchies to make it easier to access -// the child entities created for an instance. -// -// To create a slot, the SlotOf relationship is added to the child of a prefab, -// with as relationship target the prefab for which to register the slot. When -// the prefab is instantiated, each slot will be added as a relationship pair -// to the instance that looks like this: -// (PrefabChild, InstanceChild) -// -// For a SpaceShip prefab and an Engine child, that pair would look like this: -// (SpaceShip.Engine, Instance.Engine) -// -// To get the entity for a slot, an application can use the regular functions -// to inspect relationships and relationship targets (see code). -// -// Slots can be added to any level of a prefab hierarchy, as long as it is above -// (a parent of) the slot itself. When the prefab tree is instantiated, the -// slots are added to the entities that correspond with the prefab children. -// -// Without slots, an application would have to rely on manually looking up -// entities by name to get access to the instantiated children, like what the -// hierarchy example does. +// Non-fragmenting Parent storage lets an instance resolve children from its prefab children, like slots. using Flecs.NET.Core; +using static Flecs.NET.Bindings.flecs; public static class Prefabs_Slots { @@ -29,32 +9,19 @@ public static void Main() { using World world = World.Create(); - // Create the same prefab hierarchy as from the hierarchy example, but now - // with the SlotOf relationship. + // Create a prefab hierarchy with non-fragmenting Parent storage. Entity spaceShip = world.Prefab("SpaceShip"); - Entity engine = world.Prefab("Engine") - .ChildOf(spaceShip) - .SlotOf(spaceShip); - - Entity cockpit = world.Prefab("Cockpit") - .ChildOf(spaceShip) - .SlotOf(spaceShip); - - // Add an additional child to the Cockpit prefab to demonstrate how - // slots can be different from the parent. This slot could have been - // added to the Cockpit prefab, but instead we register it on the top - // level SpaceShip prefab. - Entity pilotSeat = world.Prefab("PilotSeat") - .ChildOf(cockpit) - .SlotOf(spaceShip); + Entity engine = world.Prefab(new EcsParent { value = spaceShip }, "Engine"); + Entity cockpit = world.Prefab(new EcsParent { value = spaceShip }, "Cockpit"); + Entity pilotSeat = world.Prefab(new EcsParent { value = cockpit }, "PilotSeat"); // Create a prefab instance. Entity inst = world.Entity("MySpaceship").IsA(spaceShip); - // Get the instantiated entities for the prefab slots + // Resolve instantiated children from their prefab children; nested children resolve from the instance parent. Entity instEngine = inst.Target(engine); Entity instCockpit = inst.Target(cockpit); - Entity instSeat = inst.Target(pilotSeat); + Entity instSeat = instCockpit.Target(pilotSeat); Console.WriteLine("Instance Engine: " + instEngine.Path()); Console.WriteLine("Instance Cockpit: " + instCockpit.Path()); diff --git a/src/Flecs.NET.Examples/Prefabs/TypedPrefabs.cs b/src/Flecs.NET.Examples/Prefabs/TypedPrefabs.cs index 13ed331f..73d1d57f 100644 --- a/src/Flecs.NET.Examples/Prefabs/TypedPrefabs.cs +++ b/src/Flecs.NET.Examples/Prefabs/TypedPrefabs.cs @@ -8,7 +8,7 @@ // // While this functionality is not unique to prefabs (the same mechanism is // used to distribute component handles), prefabs are a good fit, especially -// when combined with prefab slots (see slots example and code below). +// when combined with prefab hierarchies (see slots example and code below). using Flecs.NET.Core; @@ -32,19 +32,19 @@ public static void Main() // Associate types with prefabs world.Prefab(); - world.Prefab().SlotOf(); - world.Prefab().SlotOf(); + world.Prefab(); + world.Prefab(); world.Prefab().IsA(); - world.Prefab().SlotOf(); + world.Prefab(); // Create prefab instance. Entity inst = world.Entity("MyRailgun").IsA(); - // Get entities for slots - Entity instBase = inst.Target(); - Entity instHead = inst.Target(); - Entity instBeam = inst.Target(); + // Get instantiated children by name + Entity instBase = inst.Lookup("Base"); + Entity instHead = inst.Lookup("Head"); + Entity instBeam = inst.Lookup("Beam"); Console.WriteLine("Instance Base: " + instBase.Path()); Console.WriteLine("Instance Head: " + instHead.Path()); diff --git a/src/Flecs.NET.Examples/Systems/Immediate.cs b/src/Flecs.NET.Examples/Systems/Immediate.cs index ea23be4d..1653668f 100644 --- a/src/Flecs.NET.Examples/Systems/Immediate.cs +++ b/src/Flecs.NET.Examples/Systems/Immediate.cs @@ -45,23 +45,12 @@ public static void Main() if (waiter != 0) { - // An available waiter was found, assign a plate to it so - // that the next plate will no longer find it. - // The DeferSuspend function temporarily suspends deferring - // operations, which ensures that our plate is assigned - // immediately. Even though this is an immediate system, - // deferring is still enabled by default, as adding/removing - // components to the entities being iterated would interfere - // with the system iterator. - it.World().DeferSuspend(); - waiter.Add(plate); - it.World().DeferResume(); + // Assign the plate so the next plate won't find this waiter. Add it to the actual + // world so the change is visible immediately; mutating the iterated entity would + // interfere with the system iterator. + waiter.Stage(it.World()).Add(plate); - // Now that deferring is resumed, we can safely also add the - // waiter to the plate. We can't do this while deferring is - // suspended, because the plate is the entity we're - // currently iterating, and we don't want to move it to a - // different table while we're iterating it. + // Defer adding the waiter to the iterated plate so it doesn't move tables mid-iteration. plate.Add(waiter); Console.WriteLine($"Assigned {waiter.Name()} to {plate}!"); diff --git a/src/Flecs.NET.Examples/Systems/MutateEntity.cs b/src/Flecs.NET.Examples/Systems/MutateEntity.cs index 3f0811ea..ea6b916a 100644 --- a/src/Flecs.NET.Examples/Systems/MutateEntity.cs +++ b/src/Flecs.NET.Examples/Systems/MutateEntity.cs @@ -25,7 +25,7 @@ public static void Main() // queue and executed when it's safe to do so. // When the entity to be mutated is not the same as the entity - // provided by the system, an additional Mut() call is required. + // provided by the system, an additional Stage() call is required. // See the MutateEntityHandle example. Entity e = it.Entity(i); e.Destruct(); diff --git a/src/Flecs.NET.Examples/Systems/MutateEntityHandle.cs b/src/Flecs.NET.Examples/Systems/MutateEntityHandle.cs index 471c6b57..39a5af15 100644 --- a/src/Flecs.NET.Examples/Systems/MutateEntityHandle.cs +++ b/src/Flecs.NET.Examples/Systems/MutateEntityHandle.cs @@ -27,20 +27,20 @@ public static void Main() // To make sure the delete operation is enqueued (see // MutateEntity example for more details) we need to provide it - // with a mutable context (stage) using the Mut() function. If + // with a mutable context (stage) using the Stage() function. If // we don't provide a mutable context, the operation will be // attempted on the context stored in the Entity object, // which would throw a readonly error. - // The it.World() function can be used to provide the context: - // t.ToDelete.Mut(it.World()).Destruct(); + // The it.Stage() function can be used to provide the context: + // t.ToDelete.Stage(it.Stage()).Destruct(); // // The current entity can also be used to provide context. This // is useful for functions that accept a Entity: - // t.ToDelete.Mut(it.Entity(i)).Destruct(); + // t.ToDelete.Stage(it.Entity(i)).Destruct(); // // A shortcut is to use the iterator directly: - t.ToDelete.Mut(ref it).Destruct(); + t.ToDelete.Stage(ref it).Destruct(); Console.WriteLine($"Expire: {t.ToDelete} deleted!"); } }); diff --git a/src/Flecs.NET.Native/build.zig b/src/Flecs.NET.Native/build.zig index 9499c0ad..051d50d8 100644 --- a/src/Flecs.NET.Native/build.zig +++ b/src/Flecs.NET.Native/build.zig @@ -16,103 +16,120 @@ const src_flags = [_][]const u8{ const src_files = [_][]const u8{ "../../native/flecs_helpers.c", - "../../native/flecs/src/bootstrap.c", - "../../native/flecs/src/each.c", - "../../native/flecs/src/entity_name.c", - "../../native/flecs/src/entity.c", - "../../native/flecs/src/id.c", - "../../native/flecs/src/value.c", - "../../native/flecs/src/ref.c", - "../../native/flecs/src/iter.c", - "../../native/flecs/src/misc.c", - "../../native/flecs/src/observable.c", - "../../native/flecs/src/observer.c", - "../../native/flecs/src/commands.c", - "../../native/flecs/src/component_actions.c", - "../../native/flecs/src/instantiate.c", - "../../native/flecs/src/on_delete.c", - "../../native/flecs/src/tree_spawner.c", - "../../native/flecs/src/type_info.c", - "../../native/flecs/src/os_api.c", - "../../native/flecs/src/poly.c", - "../../native/flecs/src/search.c", - "../../native/flecs/src/stage.c", - "../../native/flecs/src/world.c", "../../native/flecs/src/addons/alerts.c", "../../native/flecs/src/addons/app.c", + "../../native/flecs/src/addons/constraint_traits/constraint_traits.c", "../../native/flecs/src/addons/doc.c", + "../../native/flecs/src/addons/entity_ranges.c", "../../native/flecs/src/addons/flecs_cpp.c", + "../../native/flecs/src/addons/frame.c", "../../native/flecs/src/addons/http/http.c", "../../native/flecs/src/addons/journal.c", - "../../native/flecs/src/addons/log.c", - "../../native/flecs/src/addons/metrics.c", - "../../native/flecs/src/addons/module.c", - "../../native/flecs/src/addons/rest.c", - "../../native/flecs/src/addons/timer.c", - "../../native/flecs/src/addons/units.c", - "../../native/flecs/src/addons/json/deserialize_value.c", "../../native/flecs/src/addons/json/deserialize.c", + "../../native/flecs/src/addons/json/deserialize_value.c", "../../native/flecs/src/addons/json/json.c", "../../native/flecs/src/addons/json/serialize_entity.c", "../../native/flecs/src/addons/json/serialize_field_info.c", + "../../native/flecs/src/addons/json/serialize_iter.c", + "../../native/flecs/src/addons/json/serialize_iter_result.c", "../../native/flecs/src/addons/json/serialize_iter_result_query.c", "../../native/flecs/src/addons/json/serialize_iter_result_table.c", - "../../native/flecs/src/addons/json/serialize_iter_result.c", - "../../native/flecs/src/addons/json/serialize_iter.c", "../../native/flecs/src/addons/json/serialize_query_info.c", "../../native/flecs/src/addons/json/serialize_type_info.c", "../../native/flecs/src/addons/json/serialize_value.c", "../../native/flecs/src/addons/json/serialize_world.c", - "../../native/flecs/src/addons/meta/serializer.c", - "../../native/flecs/src/addons/meta/c_utils.c", + "../../native/flecs/src/addons/log.c", "../../native/flecs/src/addons/meta/cursor.c", + "../../native/flecs/src/addons/meta/c_utils.c", "../../native/flecs/src/addons/meta/definitions.c", "../../native/flecs/src/addons/meta/meta.c", + "../../native/flecs/src/addons/meta/meta_utils.c", + "../../native/flecs/src/addons/meta/ptr.c", "../../native/flecs/src/addons/meta/rtt_lifecycle.c", + "../../native/flecs/src/addons/meta/serialize.c", + "../../native/flecs/src/addons/meta/serializer.c", "../../native/flecs/src/addons/meta/type_support/array_ts.c", "../../native/flecs/src/addons/meta/type_support/enum_ts.c", + "../../native/flecs/src/addons/meta/type_support/map_ts.c", "../../native/flecs/src/addons/meta/type_support/opaque_ts.c", "../../native/flecs/src/addons/meta/type_support/primitive_ts.c", "../../native/flecs/src/addons/meta/type_support/struct_ts.c", "../../native/flecs/src/addons/meta/type_support/units_ts.c", + "../../native/flecs/src/addons/meta/value.c", + "../../native/flecs/src/addons/metrics.c", + "../../native/flecs/src/addons/module.c", + "../../native/flecs/src/addons/multi_world.c", "../../native/flecs/src/addons/os_api_impl/os_api_impl.c", + "../../native/flecs/src/addons/parser/strutils.c", "../../native/flecs/src/addons/parser/tokenizer.c", "../../native/flecs/src/addons/pipeline/pipeline.c", - "../../native/flecs/src/addons/pipeline/frame.c", "../../native/flecs/src/addons/pipeline/worker.c", + "../../native/flecs/src/addons/prefab/instantiate.c", + "../../native/flecs/src/addons/prefab/prefab.c", + "../../native/flecs/src/addons/prefab/tree_spawner.c", "../../native/flecs/src/addons/query_dsl/parser.c", + "../../native/flecs/src/addons/rest.c", "../../native/flecs/src/addons/script/ast.c", - "../../native/flecs/src/addons/script/function.c", - "../../native/flecs/src/addons/script/functions_builtin.c", - "../../native/flecs/src/addons/script/functions_math.c", - "../../native/flecs/src/addons/script/functions_math_perlin.c", - "../../native/flecs/src/addons/script/parser.c", - "../../native/flecs/src/addons/script/script.c", - "../../native/flecs/src/addons/script/serialize.c", - "../../native/flecs/src/addons/script/template.c", - "../../native/flecs/src/addons/script/vars.c", - "../../native/flecs/src/addons/script/visit_check.c", - "../../native/flecs/src/addons/script/visit_eval.c", - "../../native/flecs/src/addons/script/visit_free.c", - "../../native/flecs/src/addons/script/visit_to_str.c", - "../../native/flecs/src/addons/script/visit.c", + "../../native/flecs/src/addons/script/edit.c", + "../../native/flecs/src/addons/script/eval/async.c", + "../../native/flecs/src/addons/script/eval/runtime.c", + "../../native/flecs/src/addons/script/eval/visit_collection.c", + "../../native/flecs/src/addons/script/eval/visit_enum.c", + "../../native/flecs/src/addons/script/eval/visit_eval.c", + "../../native/flecs/src/addons/script/eval/visit_for.c", + "../../native/flecs/src/addons/script/eval/visit_include.c", + "../../native/flecs/src/addons/script/eval/visit_struct.c", + "../../native/flecs/src/addons/script/eval/visit_type.c", "../../native/flecs/src/addons/script/expr/ast.c", + "../../native/flecs/src/addons/script/expr/format.c", "../../native/flecs/src/addons/script/expr/parser.c", "../../native/flecs/src/addons/script/expr/stack.c", "../../native/flecs/src/addons/script/expr/util.c", "../../native/flecs/src/addons/script/expr/visit_eval.c", "../../native/flecs/src/addons/script/expr/visit_fold.c", "../../native/flecs/src/addons/script/expr/visit_free.c", + "../../native/flecs/src/addons/script/expr/visit_refs.c", "../../native/flecs/src/addons/script/expr/visit_to_str.c", "../../native/flecs/src/addons/script/expr/visit_type.c", - "../../native/flecs/src/addons/stats/monitor.c", + "../../native/flecs/src/addons/script/function.c", + "../../native/flecs/src/addons/script/functions_builtin.c", + "../../native/flecs/src/addons/script/ir/compile.c", + "../../native/flecs/src/addons/script/ir/to_str.c", + "../../native/flecs/src/addons/script/ir/vm.c", + "../../native/flecs/src/addons/script/modules/command.c", + "../../native/flecs/src/addons/script/modules/command_core.c", + "../../native/flecs/src/addons/script/modules/command_diff.c", + "../../native/flecs/src/addons/script/modules/command_input.c", + "../../native/flecs/src/addons/script/modules/command_script.c", + "../../native/flecs/src/addons/script/modules/functions_math.c", + "../../native/flecs/src/addons/script/modules/functions_math_perlin.c", + "../../native/flecs/src/addons/script/modules/input.c", + "../../native/flecs/src/addons/script/modules/platform.c", + "../../native/flecs/src/addons/script/modules/typecache.c", + "../../native/flecs/src/addons/script/parser.c", + "../../native/flecs/src/addons/script/reactivity/deps.c", + "../../native/flecs/src/addons/script/reactivity/refs.c", + "../../native/flecs/src/addons/script/reactivity/state.c", + "../../native/flecs/src/addons/script/reactivity/template.c", + "../../native/flecs/src/addons/script/script.c", + "../../native/flecs/src/addons/script/serialize.c", + "../../native/flecs/src/addons/script/serialize_type.c", + "../../native/flecs/src/addons/script/vars.c", + "../../native/flecs/src/addons/script/visit_free.c", + "../../native/flecs/src/addons/script/visit_to_str.c", "../../native/flecs/src/addons/stats/memory.c", + "../../native/flecs/src/addons/stats/monitor.c", "../../native/flecs/src/addons/stats/pipeline_monitor.c", "../../native/flecs/src/addons/stats/stats.c", "../../native/flecs/src/addons/stats/system_monitor.c", "../../native/flecs/src/addons/stats/world_monitor.c", "../../native/flecs/src/addons/stats/world_summary.c", "../../native/flecs/src/addons/system/system.c", + "../../native/flecs/src/addons/timer.c", + "../../native/flecs/src/addons/units.c", + "../../native/flecs/src/bootstrap.c", + "../../native/flecs/src/commands.c", + "../../native/flecs/src/component_actions.c", "../../native/flecs/src/datastructures/allocator.c", "../../native/flecs/src/datastructures/bitset.c", "../../native/flecs/src/datastructures/block_allocator.c", @@ -124,39 +141,55 @@ const src_files = [_][]const u8{ "../../native/flecs/src/datastructures/stack_allocator.c", "../../native/flecs/src/datastructures/strbuf.c", "../../native/flecs/src/datastructures/vec.c", + "../../native/flecs/src/each.c", + "../../native/flecs/src/entity.c", + "../../native/flecs/src/entity_name.c", + "../../native/flecs/src/id.c", + "../../native/flecs/src/iter.c", + "../../native/flecs/src/misc.c", + "../../native/flecs/src/observable.c", + "../../native/flecs/src/observer.c", + "../../native/flecs/src/on_delete.c", + "../../native/flecs/src/os_api.c", + "../../native/flecs/src/poly.c", "../../native/flecs/src/query/api.c", - "../../native/flecs/src/query/util.c", - "../../native/flecs/src/query/validator.c", - "../../native/flecs/src/query/compiler/compiler_term.c", - "../../native/flecs/src/query/compiler/compiler.c", "../../native/flecs/src/query/cache/cache.c", "../../native/flecs/src/query/cache/cache_iter.c", + "../../native/flecs/src/query/cache/change_detection.c", "../../native/flecs/src/query/cache/group.c", "../../native/flecs/src/query/cache/match.c", "../../native/flecs/src/query/cache/order_by.c", - "../../native/flecs/src/query/cache/change_detection.c", + "../../native/flecs/src/query/compiler/compiler.c", + "../../native/flecs/src/query/compiler/compiler_term.c", + "../../native/flecs/src/query/engine/eval.c", "../../native/flecs/src/query/engine/eval_iter.c", "../../native/flecs/src/query/engine/eval_member.c", "../../native/flecs/src/query/engine/eval_pred.c", + "../../native/flecs/src/query/engine/eval_sparse.c", "../../native/flecs/src/query/engine/eval_toggle.c", "../../native/flecs/src/query/engine/eval_trav.c", - "../../native/flecs/src/query/engine/eval_sparse.c", "../../native/flecs/src/query/engine/eval_tree.c", "../../native/flecs/src/query/engine/eval_up.c", "../../native/flecs/src/query/engine/eval_utils.c", - "../../native/flecs/src/query/engine/eval.c", "../../native/flecs/src/query/engine/trav_cache.c", "../../native/flecs/src/query/engine/trav_down_cache.c", "../../native/flecs/src/query/engine/trav_up_cache.c", "../../native/flecs/src/query/engine/trivial_iter.c", - "../../native/flecs/src/storage/entity_index.c", + "../../native/flecs/src/query/util.c", + "../../native/flecs/src/query/validator.c", + "../../native/flecs/src/ref.c", + "../../native/flecs/src/search.c", + "../../native/flecs/src/stage.c", "../../native/flecs/src/storage/component_index.c", + "../../native/flecs/src/storage/entity_index.c", "../../native/flecs/src/storage/non_fragmenting_childof.c", "../../native/flecs/src/storage/ordered_children.c", "../../native/flecs/src/storage/sparse_storage.c", + "../../native/flecs/src/storage/table.c", "../../native/flecs/src/storage/table_cache.c", "../../native/flecs/src/storage/table_graph.c", - "../../native/flecs/src/storage/table.c", + "../../native/flecs/src/type_info.c", + "../../native/flecs/src/world.c", }; pub fn compileFlecs(b: *Build, options: BuildOptions) void { diff --git a/src/Flecs.NET.Tests/CSharp/Core/EventTests.cs b/src/Flecs.NET.Tests/CSharp/Core/EventTests.cs index 9fc1c64a..90e7474c 100644 --- a/src/Flecs.NET.Tests/CSharp/Core/EventTests.cs +++ b/src/Flecs.NET.Tests/CSharp/Core/EventTests.cs @@ -45,15 +45,15 @@ public void EnqueueEntityEventWithManagedPayload() count++; }); - world.DeferBegin(); + World stage = world.GetStage(0); string str = "Test"; - entity.Enqueue(ref str); + entity.Stage(stage).Enqueue(ref str); Assert.Equal(0, count); - world.DeferEnd(); + stage.Merge(); Assert.Equal(1, count); } diff --git a/src/Flecs.NET.Tests/CSharp/Core/TypeRegistrationTests.cs b/src/Flecs.NET.Tests/CSharp/Core/TypeRegistrationTests.cs index 253e4e9e..d6cbea2d 100644 --- a/src/Flecs.NET.Tests/CSharp/Core/TypeRegistrationTests.cs +++ b/src/Flecs.NET.Tests/CSharp/Core/TypeRegistrationTests.cs @@ -325,8 +325,8 @@ private void EnumInSystem() world.System() .Iter((Iter it) => { - Entity color = it.World().Component(); - Entity red = it.World().Entity(Color.Red); + Entity color = it.Stage().Component(); + Entity red = it.Stage().Entity(Color.Red); Assert.True(red != 0); Assert.True(red.IsChildOf(color)); Assert.True(red.Has(EcsConstant, Ecs.Wildcard)); diff --git a/src/Flecs.NET.Tests/Cpp/BuilderOwnershipTests.cs b/src/Flecs.NET.Tests/Cpp/BuilderOwnershipTests.cs new file mode 100644 index 00000000..5015aa90 --- /dev/null +++ b/src/Flecs.NET.Tests/Cpp/BuilderOwnershipTests.cs @@ -0,0 +1,48 @@ +using Flecs.NET.Core; +using Xunit; + +namespace Flecs.NET.Tests.Cpp; + +[Collection("Addons")] +public unsafe class BuilderOwnershipTests +{ + // The pipeline query owns the builder contexts after Build(), so disposing the builder must not free them twice. + [Fact] + public void PipelineBuilderDisposeAfterBuild() + { + using World world = World.Create(); + + PipelineBuilder builder = world.Pipeline().With(Ecs.System); + Pipeline pipeline = builder.Build(); + builder.Dispose(); + + Assert.True(pipeline != 0); + } + + // The expression string is owned by the first query, so reusing the builder would read freed memory. + [Fact] + public void QueryBuilderReuseWithExprThrows() + { + using World world = World.Create(); + world.Component(); + + QueryBuilder builder = world.QueryBuilder().Expr("Position"); + using Query q = builder.Build(); + + Assert.Throws(() => builder.Build()); + } + + // Alerts are a flecs module, so ecs_alert_init() requires an explicit import. + [Fact] + public void AlertBuilderDisposeAfterBuild() + { + using World world = World.Create(); + world.Import(); + + AlertBuilder builder = world.AlertBuilder(); + Alert alert = builder.Build(); + builder.Dispose(); + + Assert.True((ulong)alert != 0); + } +} diff --git a/src/Flecs.NET.Tests/Cpp/ComponentLifecycleTests.cs b/src/Flecs.NET.Tests/Cpp/ComponentLifecycleTests.cs new file mode 100644 index 00000000..fc60947d --- /dev/null +++ b/src/Flecs.NET.Tests/Cpp/ComponentLifecycleTests.cs @@ -0,0 +1,132 @@ +using Flecs.NET.Core; +using Xunit; +using static Flecs.NET.Bindings.flecs; + +namespace Flecs.NET.Tests.Cpp; + +public unsafe class ComponentLifecycleTests +{ + private struct WithoutOperators + { + public int Value; + } + + private static int Compare(World world, ulong id, void* a, void* b) + { + ecs_type_info_t* ti = ecs_get_type_info(world, id); + return ti->hooks.cmp(a, b, ti); + } + + private static bool AreEqual(World world, ulong id, void* a, void* b) + { + ecs_type_info_t* ti = ecs_get_type_info(world, id); + return ti->hooks.equals(a, b, ti); + } + + [Fact] + private void CompareWithoutOperators() + { + using World world = World.Create(); + + Component component = world.Component(); + + ecs_type_hooks_t hooks = component.UntypedComponent.GetHooks(); + Assert.True((hooks.flags & ECS_TYPE_HOOK_CMP_ILLEGAL) != 0); + Assert.True((hooks.flags & ECS_TYPE_HOOK_EQUALS_ILLEGAL) != 0); + + // Define operator equals via an explicit callback. + component.OnEquals((ref WithoutOperators a, ref WithoutOperators b, TypeInfo _) => a.Value == b.Value); + + hooks = component.UntypedComponent.GetHooks(); + Assert.True((hooks.flags & ECS_TYPE_HOOK_CMP_ILLEGAL) != 0); + Assert.True((hooks.flags & ECS_TYPE_HOOK_EQUALS_ILLEGAL) == 0); + + WithoutOperators a = new() { Value = 1 }; + WithoutOperators b = new() { Value = 2 }; + WithoutOperators c = new() { Value = 1 }; + + Assert.False(AreEqual(world, component, &a, &b)); + Assert.True(AreEqual(world, component, &a, &c)); + Assert.True(AreEqual(world, component, &a, &a)); + + component.OnCompare((ref WithoutOperators a, ref WithoutOperators b, TypeInfo _) => a.Value - b.Value); + + hooks = component.UntypedComponent.GetHooks(); + Assert.True((hooks.flags & ECS_TYPE_HOOK_CMP_ILLEGAL) == 0); + Assert.True((hooks.flags & ECS_TYPE_HOOK_EQUALS_ILLEGAL) == 0); + + Assert.True(Compare(world, component, &a, &b) < 0); + Assert.True(Compare(world, component, &b, &a) > 0); + Assert.Equal(0, Compare(world, component, &a, &c)); + Assert.True(Compare(world, component, &b, &c) > 0); + Assert.True(Compare(world, component, &c, &b) < 0); + Assert.Equal(0, Compare(world, component, &b, &b)); + } + + [Fact] + private void CompareAndEqualsUntyped() + { + using World world = World.Create(); + + Component component = world.Component(); + + component.UntypedComponent.OnEquals(UntypedEquals); + + ecs_type_hooks_t hooks = component.UntypedComponent.GetHooks(); + Assert.True((hooks.flags & ECS_TYPE_HOOK_CMP_ILLEGAL) != 0); + Assert.True((hooks.flags & ECS_TYPE_HOOK_EQUALS_ILLEGAL) == 0); + + WithoutOperators a = new() { Value = 1 }; + WithoutOperators b = new() { Value = 2 }; + + Assert.False(AreEqual(world, component, &a, &b)); + Assert.True(AreEqual(world, component, &a, &a)); + + component.UntypedComponent.OnCompare(UntypedCompare); + + hooks = component.UntypedComponent.GetHooks(); + Assert.True((hooks.flags & ECS_TYPE_HOOK_CMP_ILLEGAL) == 0); + Assert.True((hooks.flags & ECS_TYPE_HOOK_EQUALS_ILLEGAL) == 0); + + Assert.True(Compare(world, component, &a, &b) < 0); + Assert.True(Compare(world, component, &b, &a) > 0); + Assert.Equal(0, Compare(world, component, &a, &a)); + } + + [Fact] + private void SetHooksRoundTrip() + { + using World world = World.Create(); + + Component component = world.Component(); + + ecs_type_hooks_t hooks = component.UntypedComponent.GetHooks(); + component.UntypedComponent.SetHooks(ref hooks); + + Assert.True((component.UntypedComponent.GetHooks().flags & ECS_TYPE_HOOK_CMP_ILLEGAL) != 0); + } + + [Fact] + private void DeleteWOnRemoveHookRemovingOtherWStage() + { + using World world = World.Create(); + + world.Component().OnRemove((Entity e, ref Position p) => { e.Remove(); }); + + Entity e = world.Entity().Add().Add(); + + e.Destruct(); + + Assert.False(e.IsAlive()); + } + + private static int UntypedCompare(void* a, void* b, TypeInfo ti) + { + return ((WithoutOperators*)a)->Value - ((WithoutOperators*)b)->Value; + } + + private static bool UntypedEquals(void* a, void* b, TypeInfo ti) + { + return ((WithoutOperators*)a)->Value == ((WithoutOperators*)b)->Value; + } +} diff --git a/src/Flecs.NET.Tests/Cpp/ComponentTraitsTests.cs b/src/Flecs.NET.Tests/Cpp/ComponentTraitsTests.cs new file mode 100644 index 00000000..356f6d18 --- /dev/null +++ b/src/Flecs.NET.Tests/Cpp/ComponentTraitsTests.cs @@ -0,0 +1,317 @@ +using Flecs.NET.Core; +using Xunit; + +namespace Flecs.NET.Tests.Cpp; + +public unsafe class ComponentTraitsTests +{ + [Fact] + private void SparseGetGetMut() + { + using World world = World.Create(); + + world.Component().Add(Ecs.Sparse); + + Entity e = world.Entity().Set(new TraitSparse(10, 20)); + + ref readonly TraitSparse v = ref e.Get(); + Assert.Equal(10, v.X); + Assert.Equal(20, v.Y); + + ref TraitSparse mv = ref e.GetMut(); + mv.X = 30; + mv.Y = 40; + + TraitSparse* p = e.GetPtr(); + Assert.True(p != null); + Assert.Equal(30, p->X); + Assert.Equal(40, p->Y); + } + + [Fact] + private void SparseTryGetNotFound() + { + using World world = World.Create(); + + world.Component().Add(Ecs.Sparse); + + Entity e = world.Entity(); + Assert.True(e.GetPtr() == null); + Assert.True(e.GetMutPtr() == null); + } + + [Fact] + private void DontFragmentGetGetMut() + { + using World world = World.Create(); + + world.Component().Add(Ecs.DontFragment); + + Entity e = world.Entity().Set(new TraitDontFragment(10, 20)); + + ref readonly TraitDontFragment v = ref e.Get(); + Assert.Equal(10, v.X); + Assert.Equal(20, v.Y); + + ref TraitDontFragment mv = ref e.GetMut(); + mv.X = 30; + mv.Y = 40; + + TraitDontFragment* p = e.GetPtr(); + Assert.True(p != null); + Assert.Equal(30, p->X); + Assert.Equal(40, p->Y); + + Assert.True(world.Entity().GetPtr() == null); + } + + [Fact] + private void OnInstantiateOverrideGetGetMut() + { + using World world = World.Create(); + + world.Component().Add(Ecs.OnInstantiate, Ecs.Copy); + + Entity e = world.Entity().Set(new TraitOnInstantiateOverride(10, 20)); + + ref readonly TraitOnInstantiateOverride v = ref e.Get(); + Assert.Equal(10, v.X); + Assert.Equal(20, v.Y); + + ref TraitOnInstantiateOverride mv = ref e.GetMut(); + mv.X = 30; + mv.Y = 40; + + TraitOnInstantiateOverride* p = e.GetPtr(); + Assert.True(p != null); + Assert.Equal(30, p->X); + Assert.Equal(40, p->Y); + + Assert.True(world.Entity().GetPtr() == null); + } + + [Fact] + private void OnInstantiateDontInheritGetGetMut() + { + using World world = World.Create(); + + world.Component().Add(Ecs.OnInstantiate, Ecs.DontInherit); + + Entity e = world.Entity().Set(new TraitOnInstantiateDontInherit(10, 20)); + + ref readonly TraitOnInstantiateDontInherit v = ref e.Get(); + Assert.Equal(10, v.X); + Assert.Equal(20, v.Y); + + ref TraitOnInstantiateDontInherit mv = ref e.GetMut(); + mv.X = 30; + mv.Y = 40; + + TraitOnInstantiateDontInherit* p = e.GetPtr(); + Assert.True(p != null); + Assert.Equal(30, p->X); + Assert.Equal(40, p->Y); + } + + [Fact] + private void OnInstantiateInheritGetInherited() + { + using World world = World.Create(); + + world.Component().Add(Ecs.OnInstantiate, Ecs.Inherit); + + Entity @base = world.Prefab().Set(new TraitOnInstantiateInherit(10, 20)); + Entity inst = world.Entity().IsA(@base); + + TraitOnInstantiateInherit* p = inst.GetPtr(); + Assert.True(p != null); + Assert.Equal(10, p->X); + Assert.Equal(20, p->Y); + + Assert.True(inst.GetMutPtr() == null); + } + + [Fact] + private void NoTraitsGetInherited() + { + using World world = World.Create(); + + world.Component().Add(Ecs.OnInstantiate, Ecs.Inherit); + + Entity @base = world.Prefab().Set(new TraitNone(10, 20)); + Entity inst = world.Entity().IsA(@base); + + TraitNone* p = inst.GetPtr(); + Assert.True(p != null); + Assert.Equal(10, p->X); + Assert.Equal(20, p->Y); + + Assert.True(inst.GetMutPtr() == null); + } + + [Fact] + private void DynamicInheritDenseOwned() + { + using World world = World.Create(); + + world.Component().Add(Ecs.OnInstantiate, Ecs.Inherit); + + Entity e = world.Entity().Set(new TraitNone(10, 20)); + + TraitNone* p = e.GetPtr(); + Assert.True(p != null); + Assert.Equal(10, p->X); + Assert.Equal(20, p->Y); + + TraitNone* mp = e.GetMutPtr(); + Assert.True(mp != null); + mp->X = 30; + Assert.Equal(30, e.GetPtr()->X); + } + + [Fact] + private void DynamicInheritDenseInherited() + { + using World world = World.Create(); + + world.Component().Add(Ecs.OnInstantiate, Ecs.Inherit); + + Entity @base = world.Prefab().Set(new TraitNone(10, 20)); + Entity inst = world.Entity().IsA(@base); + + TraitNone* p = inst.GetPtr(); + Assert.True(p != null); + Assert.Equal(10, p->X); + Assert.Equal(20, p->Y); + + Assert.True(inst.GetMutPtr() == null); + } + + [Fact] + private void StaticInheritDenseOwned() + { + using World world = World.Create(); + + Component c = + world.Component().Add(Ecs.OnInstantiate, Ecs.Inherit); + Assert.True(c.Has(Ecs.OnInstantiate, Ecs.Inherit)); + + Entity e = world.Entity().Set(new TraitOnInstantiateInherit(10, 20)); + + TraitOnInstantiateInherit* p = e.GetPtr(); + Assert.True(p != null); + Assert.Equal(10, p->X); + Assert.Equal(20, p->Y); + + TraitOnInstantiateInherit* mp = e.GetMutPtr(); + Assert.True(mp != null); + mp->X = 30; + Assert.Equal(30, e.GetPtr()->X); + } + + [Fact] + private void StaticInheritDenseInherited() + { + using World world = World.Create(); + + world.Component().Add(Ecs.OnInstantiate, Ecs.Inherit); + + Entity @base = world.Prefab().Set(new TraitOnInstantiateInherit(10, 20)); + Entity inst = world.Entity().IsA(@base); + + TraitOnInstantiateInherit* p = inst.GetPtr(); + Assert.True(p != null); + Assert.Equal(10, p->X); + Assert.Equal(20, p->Y); + + Assert.True(inst.GetMutPtr() == null); + } + + [Fact] + private void StaticInheritSparseOwned() + { + using World world = World.Create(); + + Component c = world.Component() + .Add(Ecs.Sparse) + .Add(Ecs.OnInstantiate, Ecs.Inherit); + Assert.True(c.Has(Ecs.Sparse)); + Assert.True(c.Has(Ecs.OnInstantiate, Ecs.Inherit)); + + Entity e = world.Entity().Set(new TraitSparseInherit(10, 20)); + + TraitSparseInherit* p = e.GetPtr(); + Assert.True(p != null); + Assert.Equal(10, p->X); + Assert.Equal(20, p->Y); + + TraitSparseInherit* mp = e.GetMutPtr(); + Assert.True(mp != null); + mp->X = 30; + Assert.Equal(30, e.GetPtr()->X); + } + + [Fact] + private void StaticInheritSparseInherited() + { + using World world = World.Create(); + + world.Component() + .Add(Ecs.Sparse) + .Add(Ecs.OnInstantiate, Ecs.Inherit); + + Entity @base = world.Prefab().Set(new TraitSparseInherit(10, 20)); + Entity inst = world.Entity().IsA(@base); + + TraitSparseInherit* p = inst.GetPtr(); + Assert.True(p != null); + Assert.Equal(10, p->X); + Assert.Equal(20, p->Y); + + Assert.True(inst.GetMutPtr() == null); + } + + [Fact] + private void StaticInheritDontFragmentOwned() + { + using World world = World.Create(); + + Component c = world.Component() + .Add(Ecs.DontFragment) + .Add(Ecs.OnInstantiate, Ecs.Inherit); + Assert.True(c.Has(Ecs.DontFragment)); + Assert.True(c.Has(Ecs.OnInstantiate, Ecs.Inherit)); + + Entity e = world.Entity().Set(new TraitDontFragmentInherit(10, 20)); + + TraitDontFragmentInherit* p = e.GetPtr(); + Assert.True(p != null); + Assert.Equal(10, p->X); + Assert.Equal(20, p->Y); + + TraitDontFragmentInherit* mp = e.GetMutPtr(); + Assert.True(mp != null); + mp->X = 30; + Assert.Equal(30, e.GetPtr()->X); + } + + [Fact] + private void StaticInheritDontFragmentInherited() + { + using World world = World.Create(); + + world.Component() + .Add(Ecs.DontFragment) + .Add(Ecs.OnInstantiate, Ecs.Inherit); + + Entity @base = world.Prefab().Set(new TraitDontFragmentInherit(10, 20)); + Entity inst = world.Entity().IsA(@base); + + TraitDontFragmentInherit* p = inst.GetPtr(); + Assert.True(p != null); + Assert.Equal(10, p->X); + Assert.Equal(20, p->Y); + + Assert.True(inst.GetMutPtr() == null); + } +} diff --git a/src/Flecs.NET.Tests/Cpp/EntityTests.cs b/src/Flecs.NET.Tests/Cpp/EntityTests.cs index 0d799403..5c9ea2c3 100644 --- a/src/Flecs.NET.Tests/Cpp/EntityTests.cs +++ b/src/Flecs.NET.Tests/Cpp/EntityTests.cs @@ -2152,9 +2152,9 @@ private void DeferSet1Component() { using World world = World.Create(); - world.DeferBegin(); + World stage = world.GetStage(0); - Entity e = world.Entity() + Entity e = stage.Entity() .Insert((ref Position p) => { p.X = 10; @@ -2163,7 +2163,7 @@ private void DeferSet1Component() Assert.True(!e.Has()); - world.DeferEnd(); + stage.Merge(); Assert.True(e.Has()); @@ -2179,9 +2179,9 @@ private void DeferSet2Components() { using World world = World.Create(); - world.DeferBegin(); + World stage = world.GetStage(0); - Entity e = world.Entity() + Entity e = stage.Entity() .Insert((ref Position p, ref Velocity v) => { p = new Position(10, 20); @@ -2191,7 +2191,7 @@ private void DeferSet2Components() Assert.True(!e.Has()); Assert.True(!e.Has()); - world.DeferEnd(); + stage.Merge(); Assert.True(e.Has()); Assert.True(e.Has()); @@ -2211,9 +2211,9 @@ private void DeferSet3Components() { using World world = World.Create(); - world.DeferBegin(); + World stage = world.GetStage(0); - Entity e = world.Entity() + Entity e = stage.Entity() .Insert((ref Position p, ref Velocity v, ref Mass m) => { p = new Position(10, 20); @@ -2225,7 +2225,7 @@ private void DeferSet3Components() Assert.True(!e.Has()); Assert.True(!e.Has()); - world.DeferEnd(); + stage.Merge(); Assert.True(e.Has()); Assert.True(e.Has()); @@ -2315,9 +2315,9 @@ private void DeferSet2WithOnSet() Assert.Equal(2, v.Y); }); - world.DeferBegin(); + World stage = world.GetStage(0); - Entity e = world.Entity() + Entity e = stage.Entity() .Insert((ref Position p, ref Velocity v) => { p = new Position(10, 20); @@ -2327,7 +2327,7 @@ private void DeferSet2WithOnSet() Assert.Equal(0, positionSet); Assert.Equal(0, velocitySet); - world.DeferEnd(); + stage.Merge(); Assert.Equal(1, positionSet); Assert.Equal(1, velocitySet); @@ -2482,150 +2482,6 @@ private void Set2AfterSet2() Assert.Equal(2, called); } - [Fact] - private void WithSelf() - { - using World world = World.Create(); - - Entity tag = world.Entity().With(() => - { - Entity e1 = world.Entity(); - e1.Set(new Self { Value = e1 }); - Entity e2 = world.Entity(); - e2.Set(new Self { Value = e2 }); - Entity e3 = world.Entity(); - e3.Set(new Self { Value = e3 }); - }); - - Component self = world.Component(); - Assert.True(!self.Has(tag)); - - int count = 0; - using Query query = world.QueryBuilder() - .With(tag) - .Build(); - - query.Each((Entity e) => - { - Assert.True(e.Has(tag)); - - Assert.True(e.Read((ref readonly Self s) => { Assert.True(s.Value == e); })); - - count++; - }); - - Assert.Equal(3, count); - } - - [Fact] - private void WithRelationTypeSelf() - { - using World world = World.Create(); - - Entity bob = world.Entity().With(() => - { - Entity e1 = world.Entity(); - e1.Set(new Self(e1)); - Entity e2 = world.Entity(); - e2.Set(new Self(e2)); - Entity e3 = world.Entity(); - e3.Set(new Self(e3)); - }); - - Component self = world.Component(); - Assert.True(!self.Has(bob)); - - int count = 0; - using Query q = world.QueryBuilder() - .With(bob) - .Build(); - - q.Each((Entity e) => - { - Assert.True(e.Has(bob)); - - Assert.True(e.Read((ref readonly Self s) => { Assert.True(s.Value == e); })); - - count++; - }); - - Assert.Equal(3, count); - } - - [Fact] - private void WithRelationSelf() - { - using World world = World.Create(); - - Entity likes = world.Entity(); - - Entity bob = world.Entity().With(likes, () => - { - Entity e1 = world.Entity(); - e1.Set(new Self(e1)); - Entity e2 = world.Entity(); - e2.Set(new Self(e2)); - Entity e3 = world.Entity(); - e3.Set(new Self(e3)); - }); - - Component self = world.Component(); - Assert.True(!self.Has(likes, bob)); - - int count = 0; - using Query q = world.QueryBuilder() - .With(likes, bob) - .Build(); - - q.Each((Entity e) => - { - Assert.True(e.Has(likes, bob)); - - Assert.True(e.Read((ref readonly Self s) => { Assert.True(s.Value == e); })); - - count++; - }); - - Assert.Equal(3, count); - } - - [Fact] - private void WithSelfWithName() - { - using World world = World.Create(); - - Entity tier1 = world.Entity("Tier1").With(() => - { - Entity tier2 = world.Entity("Tier2"); - tier2.Set(new Self(tier2)); - }); - - Entity tier2 = world.Lookup("Tier2"); - Assert.True(tier2 != 0); - - Assert.True(tier2.Has(tier1)); - } - - [Fact] - private void WithSelfNested() - { - using World world = World.Create(); - - Entity tier1 = world.Entity("Tier1").With(() => - { - world.Entity("Tier2").With(() => { world.Entity("Tier3"); }); - }); - - Entity tier2 = world.Lookup("Tier2"); - Assert.True(tier2 != 0); - - Entity tier3 = world.Lookup("Tier3"); - Assert.True(tier3 != 0); - - Assert.True(tier2.Has(tier1)); - Assert.True(tier3.Has(tier2)); - } - [Fact] private void WithScope() { @@ -2766,11 +2622,10 @@ private void DeferNewWithName() Entity e = default; - world.Defer(() => - { - e = world.Entity("Foo"); - Assert.True(e != 0); - }); + World stage = world.GetStage(0); + e = stage.Entity("Foo"); + Assert.True(e != 0); + stage.Merge(); Assert.True(e.Has(EcsName)); Assert.Equal("Foo", e.Name()); @@ -2783,11 +2638,10 @@ private void DeferNewWithNestedName() Entity e = default; - world.Defer(() => - { - e = world.Entity("Foo.Bar"); - Assert.True(e != 0); - }); + World stage = world.GetStage(0); + e = stage.Entity("Foo.Bar"); + Assert.True(e != 0); + stage.Merge(); Assert.True(e.Has(EcsName)); Assert.Equal("Bar", e.Name()); @@ -2803,14 +2657,13 @@ private void DeferNewWithScopeName() Entity e = default; Entity parent = world.Entity("Parent"); - world.Defer(() => + World stage = world.GetStage(0); + parent.Scope(() => { - parent.Scope(() => - { - e = world.Entity("Foo"); - Assert.True(e != 0); - }); + e = stage.Entity("Foo"); + Assert.True(e != 0); }); + stage.Merge(); Assert.True(e.Has(EcsName)); Assert.Equal("Foo", e.Name()); @@ -2825,14 +2678,13 @@ private void DeferNewWithScopeNestedName() Entity e = default; Entity parent = world.Entity("Parent"); - world.Defer(() => + World stage = world.GetStage(0); + parent.Scope(() => { - parent.Scope(() => - { - e = world.Entity("Foo.Bar"); - Assert.True(e != 0); - }); + e = stage.Entity("Foo.Bar"); + Assert.True(e != 0); }); + stage.Merge(); Assert.True(e.Has(EcsName)); Assert.Equal("Bar", e.Name()); @@ -2847,14 +2699,13 @@ private void DeferNewWithDeferredScopeNestedName() Entity e = default; Entity parent = default; - world.Defer(() => + World stage = world.GetStage(0); + parent = stage.Entity("Parent").Scope(() => { - parent = world.Entity("Parent").Scope(() => - { - e = world.Entity("Foo.Bar"); - Assert.True(e != 0); - }); + e = stage.Entity("Foo.Bar"); + Assert.True(e != 0); }); + stage.Merge(); Assert.True(parent.Has(EcsName)); Assert.Equal("Parent", parent.Name()); @@ -2873,143 +2724,54 @@ private void DeferNewWithScope() Entity e = default; Entity parent = world.Entity(); - world.Defer(() => + World stage = world.GetStage(0); + parent.Scope(() => { - parent.Scope(() => - { - e = world.Entity(); - Assert.True(e != 0); - }); + e = stage.Entity(); + Assert.True(e != 0); }); + stage.Merge(); Assert.True(e.Has(EcsChildOf, parent)); } [Fact] - private void DeferNewWithWith() - { - using World world = World.Create(); - - Entity e = default; - Entity tag = world.Entity(); - - world.Defer(() => - { - tag.With(() => - { - e = world.Entity(); - Assert.True(e != 0); - Assert.True(!e.Has(tag)); - }); - }); - - Assert.True(e.Has(tag)); - } - - [Fact] - private void DeferNewWithNameScopeWith() - { - using World world = World.Create(); - - Entity e = default; - Entity tag = world.Entity(); - Entity parent = world.Entity("Parent"); - - world.Defer(() => - { - tag.With(() => - { - parent.Scope(() => - { - e = world.Entity("Foo"); - Assert.True(e != 0); - Assert.True(!e.Has(tag)); - }); - Assert.True(!e.Has(tag)); - }); - Assert.True(!e.Has(tag)); - }); - - Assert.True(e.Has(tag)); - Assert.True(e.Has(EcsName)); - Assert.Equal("Foo", e.Name()); - Assert.Equal(".Parent.Foo", e.Path()); - } - - [Fact] - private void DeferNewWithNestedNameScopeWith() + private void DeferSuspendResume() { using World world = World.Create(); - Entity e = default; - Entity tag = world.Entity(); - Entity parent = world.Entity("Parent"); - - world.Defer(() => - { - tag.With(() => - { - parent.Scope(() => - { - e = world.Entity("Foo.Bar"); - Assert.True(e != 0); - Assert.True(!e.Has(tag)); - }); - Assert.True(!e.Has(tag)); - }); - Assert.True(!e.Has(tag)); - }); - - Assert.True(e.Has(tag)); - Assert.True(e.Has(EcsName)); - Assert.Equal("Bar", e.Name()); - Assert.Equal(".Parent.Foo.Bar", e.Path()); - } + Entity e = world.Entity(); - [Fact] - private void DeferWithWithImplicitComponent() - { - using World world = World.Create(); + World stage = world.GetStage(0); + e.Stage(stage).Add(); + Assert.True(!e.Has()); - Entity e = default; + e.Add(); + Assert.True(!e.Has()); + Assert.True(e.Has()); - world.Defer(() => - { - world.With(() => - { - e = world.Entity(); - Assert.True(!e.Has()); - }); - Assert.True(!e.Has()); - }); + Assert.True(!e.Has()); + Assert.True(e.Has()); + stage.Merge(); - Assert.True(e.Has()); + Assert.True(e.Has()); + Assert.True(e.Has()); } [Fact] - private void DeferSuspendResume() + private void RangeOnStage() { using World world = World.Create(); - Entity e = world.Entity(); - - world.Defer(() => - { - e.Add(); - Assert.True(!e.Has()); - - world.DeferSuspend(); - e.Add(); - Assert.True(!e.Has()); - Assert.True(e.Has()); - world.DeferResume(); + world.Entity().Set(new Position(10, 20)); + Entity e = world.Entity().Set(new Position(20, 30)); - Assert.True(!e.Has()); - Assert.True(e.Has()); - }); + World stage = world.GetStage(0); + Table table = e.Stage(stage).Range(); - Assert.True(e.Has()); - Assert.True(e.Has()); + Assert.True(table.Handle != null); + Assert.Equal(1, table.Count); + Assert.Equal(1, table.Offset); } [Fact] @@ -3019,11 +2781,11 @@ private void DeferEnsure() Entity e = world.Entity(); - world.DeferBegin(); - Position* p = e.EnsurePtr(); + World stage = world.GetStage(0); + Position* p = e.Stage(stage).EnsurePtr(); p->X = 10; p->Y = 20; - world.DeferEnd(); + stage.Merge(); p = e.GetMutPtr(); Assert.True(p != null); @@ -3031,100 +2793,6 @@ private void DeferEnsure() Assert.Equal(20, p->Y); } - [Fact] - private void WithAfterBuilderMethod() - { - using World world = World.Create(); - - Entity a = world.Entity() - .Set(new Position(10, 20)) - .With(() => { world.Entity("X"); }); - - Entity b = world.Entity().Set(new Position(30, 40)) - .With(() => { world.Entity("Y"); }); - - Entity c = world.Entity().Set(new Position(50, 60)) - .With(EcsIsA, () => { world.Entity("Z"); }); - - Assert.True(a.Read((ref readonly Position p) => - { - Assert.Equal(10, p.X); - Assert.Equal(20, p.Y); - })); - - Assert.True(b.Read((ref readonly Position p) => - { - Assert.Equal(30, p.X); - Assert.Equal(40, p.Y); - })); - - Assert.True(c.Read((ref readonly Position p) => - { - Assert.Equal(50, p.X); - Assert.Equal(60, p.Y); - })); - - Entity x = world.Lookup("X"); - Assert.True(x != 0); - Assert.True(x.Has(a)); - - Entity y = world.Lookup("Y"); - Assert.True(y != 0); - Assert.True(y.Has(b)); - - Entity z = world.Lookup("Z"); - Assert.True(z != 0); - Assert.True(z.Has(EcsIsA, c)); - } - - [Fact] - private void WithBeforeBuilderMethod() - { - using World world = World.Create(); - - Entity a = world.Entity() - .With(() => { world.Entity("X"); }) - .Set(new Position(10, 20)); - - Entity b = world.Entity() - .With(() => { world.Entity("Y"); }) - .Set(new Position(30, 40)); - - Entity c = world.Entity() - .With(EcsIsA, () => { world.Entity("Z"); }) - .Set(new Position(50, 60)); - - Assert.True(a.Read((ref readonly Position p) => - { - Assert.Equal(10, p.X); - Assert.Equal(20, p.Y); - })); - - Assert.True(b.Read((ref readonly Position p) => - { - Assert.Equal(30, p.X); - Assert.Equal(40, p.Y); - })); - - Assert.True(c.Read((ref readonly Position p) => - { - Assert.Equal(50, p.X); - Assert.Equal(60, p.Y); - })); - - Entity x = world.Lookup("X"); - Assert.True(x != 0); - Assert.True(x.Has(a)); - - Entity y = world.Lookup("Y"); - Assert.True(y != 0); - Assert.True(y.Has(b)); - - Entity z = world.Lookup("Z"); - Assert.True(z != 0); - Assert.True(z.Has(EcsIsA, c)); - } - [Fact] private void ScopeAfterBuilderMethod() { @@ -3697,89 +3365,121 @@ private void ChildOfWithType() } [Fact] - private void SlotOf() + private void IdGetEntity() { using World world = World.Create(); - Entity @base = world.Prefab(); - Entity baseChild = world.Prefab() - .ChildOf(@base) - .SlotOf(@base); + Entity e = world.Entity(); - Assert.True(baseChild.Has(Ecs.SlotOf, @base)); + Id id = world.Id(e); - Entity inst = world.Entity().IsA(@base); - Assert.True(inst.Has(baseChild, Ecs.Wildcard)); + Assert.True(id.ToEntity() == e); } [Fact] - private void SlotOfWithType() + private void EachInStage() { using World world = World.Create(); - Entity @base = world.Prefab(); - Entity baseChild = world.Prefab() - .ChildOf(@base) - .SlotOf(); - - Assert.True(baseChild.Has(Ecs.SlotOf, @base)); + Entity e = world.Entity().Add(); + Assert.True(e.Has()); - Entity inst = world.Entity().IsA(@base); - Assert.True(inst.Has(baseChild, Ecs.Wildcard)); - } + world.ReadonlyBegin(); + + World s = world.GetStage(0); + Entity em = e.Stage(s); + Assert.True(em.Has()); + + int count = 0; + + em.Each((Entity obj) => + { + count++; + Assert.True(obj == world.Id()); + }); + + Assert.Equal(1, count); + + world.ReadonlyEnd(); + } [Fact] - private void Slot() + private void StageDefaultStage() { using World world = World.Create(); - Entity @base = world.Prefab(); - Entity baseChild = world.Prefab() - .ChildOf(@base).Slot(); + Entity e = world.Entity(); + + world.ReadonlyBegin(); + + Entity ew = e.Stage(); + Assert.True(ew.World == world.GetStage(0)); - Assert.True(baseChild.Has(Ecs.SlotOf, @base)); + ew.Set(new Position(10, 20)); + Assert.False(ew.Has()); - Entity inst = world.Entity().IsA(@base); - Assert.True(inst.Has(baseChild, Ecs.Wildcard)); + world.ReadonlyEnd(); + + Assert.True(ew.Has()); + Assert.True(e.Has()); + + Position* p = e.GetPtr(); + Assert.True(p != null); + Assert.Equal(10, p->X); + Assert.Equal(20, p->Y); } [Fact] - private void IdGetEntity() + private void EntityToEntityDefaultStage() { using World world = World.Create(); Entity e = world.Entity(); - Id id = world.Id(e); + world.ReadonlyBegin(); - Assert.True(id.ToEntity() == e); + Entity s = world.GetStage(0).Entity(e.Id).Stage(); + Assert.True(s.World == world.GetStage(0)); + + s.Set(new Position(10, 20)); + Assert.False(e.Has()); + + world.ReadonlyEnd(); + + Position* p = e.GetPtr(); + Assert.True(p != null); + Assert.Equal(10, p->X); + Assert.Equal(20, p->Y); } [Fact] - private void EachInStage() + private void EntityToEntityNonDefaultStage() { using World world = World.Create(); - Entity e = world.Entity().Add(); - Assert.True(e.Has()); + world.SetStageCount(2); - world.ReadonlyBegin(); + // Register the component up front, Flecs.NET doesn't allow component + // registration while a multithreaded world is in readonly mode. + world.Id(); - World s = world.GetStage(0); - Entity em = e.Mut(s); - Assert.True(em.Has()); + Entity e = world.Entity(); - int count = 0; + world.ReadonlyBegin(); - em.Each((Entity obj) => - { - count++; - Assert.True(obj == world.Id()); - }); + World stage1 = world.GetStage(1); + Entity s = stage1.Entity(e.Id).Stage(); + Assert.True(s.World == stage1); - Assert.Equal(1, count); + s.Set(new Position(10, 20)); + Assert.False(e.Has()); world.ReadonlyEnd(); + + Position* p = e.GetPtr(); + Assert.True(p != null); + Assert.Equal(10, p->X); + Assert.Equal(20, p->Y); } [Fact] @@ -3818,7 +3518,7 @@ private void GetLambdaFromStage() World stage = world.GetStage(0); bool invoked = false; - e.Mut(stage).Read((ref readonly Position p) => + e.Stage(stage).Read((ref readonly Position p) => { invoked = true; Assert.Equal(10, p.X); @@ -3852,22 +3552,22 @@ private void CreateNamedTwiceDeferred() { using World world = World.Create(); - world.DeferBegin(); + World stage = world.GetStage(0); - Entity e1 = world.Entity("e"); - Entity e2 = world.Entity("e"); + Entity e1 = stage.Entity("e"); + Entity e2 = stage.Entity("e"); - Entity f1 = world.Entity("p.f"); - Entity f2 = world.Entity("p.f"); + Entity f1 = stage.Entity("p.f"); + Entity f2 = stage.Entity("p.f"); Entity g1 = default; Entity g2 = default; - world.Scope(world.Entity("q"), () => { g1 = world.Entity("g"); }); + stage.Scope(stage.Entity("q"), () => { g1 = stage.Entity("g"); }); - world.Scope(world.Entity("q"), () => { g2 = world.Entity("g"); }); + stage.Scope(stage.Entity("q"), () => { g2 = stage.Entity("g"); }); - world.DeferEnd(); + stage.Merge(); Assert.Equal(".e", e1.Path()); Assert.Equal(".p.f", f1.Path()); @@ -4147,9 +3847,9 @@ private void EntityWithTypeDefer() { using World world = World.Create(); - world.DeferBegin(); - Entity e = world.Entity(); - world.DeferEnd(); + World stage = world.GetStage(0); + Entity e = stage.Entity(); + stage.Merge(); Assert.Equal("Tag", e.Name()); Assert.Equal("Tag", e.Symbol()); @@ -4754,4 +4454,407 @@ private void IterEmptyType() Assert.Equal(0, count); } + + [Fact] + private void IdValuePairIsPair() + { + using World world = World.Create(); + + ulong val = 10376293567231426561UL; + Id id = new Id(world, val); + Assert.True(Ecs.IsPair(val)); + Assert.Equal(Ecs.IsPair(val), id.IsPair()); + Assert.False(id.IsEntity()); + Assert.False(id.IsWildCard()); + } + + [Fact] + private void IdValuePairIsPairNoWorld() + { + ulong val = 10376293567231426561UL; + Id id = new Id(val); + Assert.True(Ecs.IsPair(val)); + Assert.Equal(Ecs.IsPair(val), id.IsPair()); + Assert.False(id.IsEntity()); + Assert.True(id.First() == 6); + Assert.True(id.Second() == 1); + } + + [Fact] + private void IdValuePairFromWorld() + { + using World world = World.Create(); + + Entity rel = world.Entity(); + Assert.True(rel != 0); + + Id id1 = world.Id(Ecs.ValuePair(rel, 10)); + Assert.True(id1 != 0); + Assert.True(id1.World == world); + Assert.True(id1.IsPair()); + Assert.Equal(id1.IsPair(), Ecs.IsPair(id1.Value)); + Assert.False(id1.IsWildCard()); + Assert.True(id1.HasRelation(rel)); + Assert.True(id1.First() == rel); + Assert.True(id1.Second() == 10); + + Id id2 = world.Id(Ecs.ValuePair(Ecs.Wildcard, 10)); + Assert.True(id2.IsPair()); + Assert.True(id2.IsWildCard()); + Assert.True(id2.First() == Ecs.Wildcard); + Assert.True(id2.Second() == 10); + } + + [Fact] + private void EachWDontFragmentComponent() + { + using World world = World.Create(); + + world.Component().Add(Ecs.DontFragment); + world.Component().Add(Ecs.DontFragment); + + Entity tag = world.Entity(); + + Entity e = world.Entity() + .Add(tag) + .Set(new EachDontFragment(10, 20)); + + // DontFragment component on another entity should not be matched. + world.Entity().Set(new OtherDontFragment(1, 2)); + + int count = 0; + bool tagFound = false, dfFound = false; + + e.Each((Id id) => + { + Assert.True(id != world.Id()); + if (id == tag) + tagFound = true; + else if (id == world.Id()) + dfFound = true; + count++; + }); + + Assert.Equal(2, count); + Assert.True(tagFound); + Assert.True(dfFound); + } + + [Fact] + private void EachWDontFragmentTag() + { + using World world = World.Create(); + + Entity dfTag = world.Entity().Add(Ecs.DontFragment); + Entity dfTagOther = world.Entity().Add(Ecs.DontFragment); + Entity tag = world.Entity(); + + Entity e = world.Entity() + .Add(tag) + .Add(dfTag); + + // DontFragment tag on another entity should not be matched. + world.Entity().Add(dfTagOther); + + int count = 0; + bool tagFound = false, dfFound = false; + + e.Each((Id id) => + { + Assert.True(id != dfTagOther); + if (id == tag) + tagFound = true; + else if (id == dfTag) + dfFound = true; + count++; + }); + + Assert.Equal(2, count); + Assert.True(tagFound); + Assert.True(dfFound); + } + + [Fact] + private void EachWDontFragmentPair() + { + using World world = World.Create(); + + Entity rel = world.Entity().Add(Ecs.DontFragment); + Entity tgt = world.Entity(); + Entity tgtOther = world.Entity(); + Entity tag = world.Entity(); + + Entity e = world.Entity() + .Add(tag) + .Add(rel, tgt); + + // Pair with same relationship on another entity should not be matched. + world.Entity().Add(rel, tgtOther); + + int count = 0; + bool tagFound = false, pairFound = false; + + e.Each((Id id) => + { + Assert.True(id != world.Pair(rel, tgtOther)); + if (id == tag) + tagFound = true; + else if (id == world.Pair(rel, tgt)) + pairFound = true; + count++; + }); + + Assert.Equal(2, count); + Assert.True(tagFound); + Assert.True(pairFound); + } + + [Fact] + private void EachWOnlyDontFragment() + { + using World world = World.Create(); + + world.Component().Add(Ecs.DontFragment); + world.Component().Add(Ecs.DontFragment); + + Entity e = world.Entity() + .Set(new EachDontFragment(10, 20)); + + // DontFragment component on another entity should not be matched. + world.Entity().Set(new OtherDontFragment(1, 2)); + + int count = 0; + + e.Each((Id id) => + { + Assert.True(id == world.Id()); + count++; + }); + + Assert.Equal(1, count); + } + + [Fact] + private void EachWOnlyDontFragmentTag() + { + using World world = World.Create(); + + Entity dfTag = world.Entity().Add(Ecs.DontFragment); + Entity dfTagOther = world.Entity().Add(Ecs.DontFragment); + + Entity e = world.Entity() + .Add(dfTag); + + // DontFragment tag on another entity should not be matched. + world.Entity().Add(dfTagOther); + + int count = 0; + + e.Each((Id id) => + { + Assert.True(id == dfTag); + count++; + }); + + Assert.Equal(1, count); + } + + [Fact] + private void EachWOnlyDontFragmentPair() + { + using World world = World.Create(); + + Entity rel = world.Entity().Add(Ecs.DontFragment); + Entity tgt = world.Entity(); + Entity tgtOther = world.Entity(); + + Entity e = world.Entity() + .Add(rel, tgt); + + // Pair with same relationship on another entity should not be matched. + world.Entity().Add(rel, tgtOther); + + int count = 0; + + e.Each((Id id) => + { + Assert.True(id == world.Pair(rel, tgt)); + count++; + }); + + Assert.Equal(1, count); + } + + [Fact] + private void EachPairWDontFragmentMixed() + { + using World world = World.Create(); + + Entity rel = world.Entity().Add(Ecs.DontFragment); + Entity fragRel = world.Entity(); + Entity tag = world.Entity(); + Entity tgt1 = world.Entity(); + Entity tgt2 = world.Entity(); + Entity tgtOther = world.Entity(); + + Entity e = world.Entity() + .Add(tag) + .Add(fragRel, tgt1) + .Add(rel, tgt1) + .Add(rel, tgt2); + + // Pair with same relationship on another entity should not be matched. + world.Entity().Add(rel, tgtOther); + + int count = 0; + bool tgt1Found = false, tgt2Found = false; + + e.Each(rel, Ecs.Wildcard, (Id id) => + { + Assert.True(id.First() == rel); + Assert.True(id.Second() != tgtOther); + if (id.Second() == tgt1) + tgt1Found = true; + else if (id.Second() == tgt2) + tgt2Found = true; + count++; + }); + + Assert.Equal(2, count); + Assert.True(tgt1Found); + Assert.True(tgt2Found); + + // Fragmenting pairs must still match when the entity also has DontFragment pairs. + count = 0; + + e.Each(fragRel, Ecs.Wildcard, (Id id) => + { + Assert.True(id.First() == fragRel); + Assert.True(id.Second() == tgt1); + count++; + }); + + Assert.Equal(1, count); + } + + [Fact] + private void EachRelWDontFragmentMixed() + { + using World world = World.Create(); + + Entity rel = world.Entity().Add(Ecs.DontFragment); + Entity fragRel = world.Entity(); + Entity tag = world.Entity(); + Entity tgt1 = world.Entity(); + Entity tgt2 = world.Entity(); + Entity tgtOther = world.Entity(); + + Entity e = world.Entity() + .Add(tag) + .Add(fragRel, tgt1) + .Add(rel, tgt1) + .Add(rel, tgt2); + + // Pair with same relationship on another entity should not be matched. + world.Entity().Add(rel, tgtOther); + + int count = 0; + bool tgt1Found = false, tgt2Found = false; + + e.Each(rel, (Entity tgt) => + { + Assert.True(tgt != tgtOther); + if (tgt == tgt1) + tgt1Found = true; + else if (tgt == tgt2) + tgt2Found = true; + count++; + }); + + Assert.Equal(2, count); + Assert.True(tgt1Found); + Assert.True(tgt2Found); + + // Fragmenting pairs must still match when the entity also has DontFragment pairs. + count = 0; + + e.Each(fragRel, (Entity tgt) => + { + Assert.True(tgt == tgt1); + count++; + }); + + Assert.Equal(1, count); + } + + [Fact] + private void EachPairWDontFragment() + { + using World world = World.Create(); + + Entity rel = world.Entity().Add(Ecs.DontFragment); + Entity tgt1 = world.Entity(); + Entity tgt2 = world.Entity(); + Entity tgtOther = world.Entity(); + + Entity e = world.Entity() + .Add(rel, tgt1) + .Add(rel, tgt2); + + // Pair with same relationship on another entity should not be matched. + world.Entity().Add(rel, tgtOther); + + int count = 0; + bool tgt1Found = false, tgt2Found = false; + + e.Each(rel, Ecs.Wildcard, (Id id) => + { + Assert.True(id.First() == rel); + Assert.True(id.Second() != tgtOther); + if (id.Second() == tgt1) + tgt1Found = true; + else if (id.Second() == tgt2) + tgt2Found = true; + count++; + }); + + Assert.Equal(2, count); + Assert.True(tgt1Found); + Assert.True(tgt2Found); + } + + [Fact] + private void EachRelWDontFragment() + { + using World world = World.Create(); + + Entity rel = world.Entity().Add(Ecs.DontFragment); + Entity tgt1 = world.Entity(); + Entity tgt2 = world.Entity(); + Entity tgtOther = world.Entity(); + + Entity e = world.Entity() + .Add(rel, tgt1) + .Add(rel, tgt2); + + // Pair with same relationship on another entity should not be matched. + world.Entity().Add(rel, tgtOther); + + int count = 0; + bool tgt1Found = false, tgt2Found = false; + + e.Each(rel, (Entity tgt) => + { + Assert.True(tgt != tgtOther); + if (tgt == tgt1) + tgt1Found = true; + else if (tgt == tgt2) + tgt2Found = true; + count++; + }); + + Assert.Equal(2, count); + Assert.True(tgt1Found); + Assert.True(tgt2Found); + } } diff --git a/src/Flecs.NET.Tests/Cpp/EventTests.cs b/src/Flecs.NET.Tests/Cpp/EventTests.cs index 937fbf5f..4d321736 100644 --- a/src/Flecs.NET.Tests/Cpp/EventTests.cs +++ b/src/Flecs.NET.Tests/Cpp/EventTests.cs @@ -691,16 +691,16 @@ public void EnqueueEvent() count++; }); - world.DeferBegin(); + World stage = world.GetStage(0); - world.Event(evt) + stage.Event(evt) .Id(idA) .Entity(e1) .Enqueue(); Assert.Equal(0, count); - world.DeferEnd(); + stage.Merge(); Assert.Equal(1, count); } @@ -718,13 +718,13 @@ public void EnqueueEntityEvent() e1.Observe(evt, () => { count++; }); - world.DeferBegin(); + World stage = world.GetStage(0); - e1.Enqueue(evt); + e1.Stage(stage).Enqueue(evt); Assert.Equal(0, count); - world.DeferEnd(); + stage.Merge(); Assert.Equal(1, count); } @@ -750,11 +750,11 @@ public void EnqueueEventWithPayload() count++; }); - world.DeferBegin(); + World stage = world.GetStage(0); Position position = new Position { X = 10, Y = 20 }; - world.Event() + stage.Event() .Id(idA) .Entity(e1) .Ctx(&position) @@ -762,7 +762,7 @@ public void EnqueueEventWithPayload() Assert.Equal(0, count); - world.DeferEnd(); + stage.Merge(); Assert.Equal(1, count); } @@ -784,13 +784,13 @@ public void EnqueueEntityEventWithPayload() count++; }); - world.DeferBegin(); + World stage = world.GetStage(0); - e1.Enqueue(new Position { X = 10, Y = 20 }); + e1.Stage(stage).Enqueue(new Position { X = 10, Y = 20 }); Assert.Equal(0, count); - world.DeferEnd(); + stage.Merge(); Assert.Equal(1, count); } @@ -810,7 +810,7 @@ private void EnqueueEntityFromReaOnlyWorld() world.ReadonlyBegin(); - e1.Enqueue(evt); + e1.Stage(world.GetStage(0)).Enqueue(evt); Assert.Equal(0, count); @@ -838,7 +838,7 @@ private void EnqueueEntityWithPayloadFromReadOnlyWorld() world.ReadonlyBegin(); - e1.Enqueue(new Position(10, 20)); + e1.Stage(world.GetStage(0)).Enqueue(new Position(10, 20)); Assert.Equal(0, count); diff --git a/src/Flecs.NET.Tests/Cpp/IterableTests.cs b/src/Flecs.NET.Tests/Cpp/IterableTests.cs index 61056e73..57387b85 100644 --- a/src/Flecs.NET.Tests/Cpp/IterableTests.cs +++ b/src/Flecs.NET.Tests/Cpp/IterableTests.cs @@ -171,4 +171,106 @@ private void WorkerIter() Assert.Equal(2, count); } + + [Fact] + private void FrameOffset() + { + using World world = World.Create(); + + Entity e1 = world.Entity().Set(new Position(1, 0)); + Entity e2 = world.Entity().Set(new Position(2, 0)); + Entity e3 = world.Entity().Set(new Position(3, 0)).Set(new Velocity(0, 0)); + Entity e4 = world.Entity().Set(new Position(4, 0)).Set(new Velocity(0, 0)); + Entity e5 = world.Entity().Set(new Position(5, 0)).Set(new Mass(0)); + + using Query q = world.Query(); + + Entity[] entities = new Entity[5]; + int results = 0; + int total = 0; + + q.Run((Iter it) => + { + while (it.Next()) + { + Assert.Equal(total, it.FrameOffset()); + + for (int i = 0; i < it.Count(); i++) + entities[it.FrameOffset() + i] = it.Entity(i); + + total += it.Count(); + results++; + } + }); + + Assert.Equal(3, results); + Assert.Equal(5, total); + Assert.True(entities[0] == e1); + Assert.True(entities[1] == e2); + Assert.True(entities[2] == e3); + Assert.True(entities[3] == e4); + Assert.True(entities[4] == e5); + } + + [Fact] + private void WorkerFrameOffset() + { + using World world = World.Create(); + + Entity e1 = world.Entity().Set(new Position(1, 0)); + Entity e2 = world.Entity().Set(new Position(2, 0)); + Entity e3 = world.Entity().Set(new Position(3, 0)).Set(new Velocity(0, 0)); + Entity e4 = world.Entity().Set(new Position(4, 0)).Set(new Velocity(0, 0)); + Entity e5 = world.Entity().Set(new Position(5, 0)).Set(new Mass(0)); + + using Query q = world.Query(); + + Entity[] entities = new Entity[5]; + int results = 0; + + q.Worker(0, 2).Run((Iter it) => + { + while (it.Next()) + { + Assert.Equal(1, it.Count()); + + if (results == 0) + Assert.Equal(0, it.FrameOffset()); + else if (results == 1) + Assert.Equal(2, it.FrameOffset()); + else if (results == 2) + Assert.Equal(4, it.FrameOffset()); + + entities[it.FrameOffset()] = it.Entity(0); + results++; + } + }); + + Assert.Equal(3, results); + + results = 0; + + q.Worker(1, 2).Run((Iter it) => + { + while (it.Next()) + { + Assert.Equal(1, it.Count()); + + if (results == 0) + Assert.Equal(1, it.FrameOffset()); + else if (results == 1) + Assert.Equal(3, it.FrameOffset()); + + entities[it.FrameOffset()] = it.Entity(0); + results++; + } + }); + + Assert.Equal(2, results); + Assert.True(entities[0] == e1); + Assert.True(entities[1] == e2); + Assert.True(entities[2] == e3); + Assert.True(entities[3] == e4); + Assert.True(entities[4] == e5); + } } diff --git a/src/Flecs.NET.Tests/Cpp/ModuleTests.cs b/src/Flecs.NET.Tests/Cpp/ModuleTests.cs index 98e480c6..7146b983 100644 --- a/src/Flecs.NET.Tests/Cpp/ModuleTests.cs +++ b/src/Flecs.NET.Tests/Cpp/ModuleTests.cs @@ -6,6 +6,11 @@ namespace Flecs.NET.Tests.Cpp; +// Flecs addon module ids (units, stats, ...) are process-global, so addon imports must not run in parallel. +[CollectionDefinition("Addons", DisableParallelization = true)] +public class AddonsCollection; + +[Collection("Addons")] public class ModuleTests { [Fact] @@ -260,7 +265,7 @@ private void ReparentModuleInCtor() } [Fact] - private void ImplicitlyAddModuleToScopesComponent() + private void ComponentScopesDoNotBecomeModules() { using World world = World.Create(); @@ -272,17 +277,17 @@ private void ImplicitlyAddModuleToScopesComponent() current = current.Parent(); Assert.True(current != 0); - Assert.True(current.Has(Ecs.Module)); + Assert.True(!current.Has(Ecs.Module)); Assert.True(current.Path() == ".NamespaceLvl1.NamespaceLvl2.StructLvl1"); current = current.Parent(); Assert.True(current != 0); - Assert.True(current.Has(Ecs.Module)); + Assert.True(!current.Has(Ecs.Module)); Assert.True(current.Path() == ".NamespaceLvl1.NamespaceLvl2"); current = current.Parent(); Assert.True(current != 0); - Assert.True(current.Has(Ecs.Module)); + Assert.True(!current.Has(Ecs.Module)); Assert.True(current.Path() == ".NamespaceLvl1"); current = current.Parent(); @@ -290,7 +295,7 @@ private void ImplicitlyAddModuleToScopesComponent() } [Fact] - private void ImplicitlyAddModuleToScopesEntity() + private void EntityScopesDoNotBecomeModules() { using World world = World.Create(); @@ -302,17 +307,17 @@ private void ImplicitlyAddModuleToScopesEntity() current = current.Parent(); Assert.True(current != 0); - Assert.True(current.Has(Ecs.Module)); + Assert.True(!current.Has(Ecs.Module)); Assert.True(current.Path() == ".NamespaceLvl1.NamespaceLvl2.StructLvl1"); current = current.Parent(); Assert.True(current != 0); - Assert.True(current.Has(Ecs.Module)); + Assert.True(!current.Has(Ecs.Module)); Assert.True(current.Path() == ".NamespaceLvl1.NamespaceLvl2"); current = current.Parent(); Assert.True(current != 0); - Assert.True(current.Has(Ecs.Module)); + Assert.True(!current.Has(Ecs.Module)); Assert.True(current.Path() == ".NamespaceLvl1"); current = current.Parent(); @@ -421,4 +426,142 @@ private void ReimportAfterDelete() Assert.True(m == world.Entity()); } } + + [Fact] + private void RenameWExistingEntityInOldParent() + { + using World world = World.Create(); + + Entity e = world.Entity(".RenameNs.e"); + Assert.True(e.IsAlive()); + + Entity m = world.Import(); + Assert.Equal(".RenamedModule", m.Path()); + + Assert.True(e.IsAlive()); + Assert.Equal(".RenamedModule.e", e.Path()); + Assert.True(e.Parent() == m); + Assert.True(world.Lookup(".RenameNs") == 0); + Assert.True(world.Lookup(".RenamedModule.e") == e); + } + + [Fact] + private void RenameToAncestorWExistingEntityInOldParent() + { + using World world = World.Create(); + + Entity e = world.Entity(".RenameNsOuter.RenameNsInner.e"); + Entity o = world.Entity(".RenameNsOuter.o"); + Assert.True(e.IsAlive()); + Assert.True(o.IsAlive()); + + Entity m = world.Import(); + Assert.Equal(".RenameNsOuter.RenamedModule", m.Path()); + Assert.True(m.IsAlive()); + + Assert.True(e.IsAlive()); + Assert.Equal(".RenameNsOuter.RenamedModule.e", e.Path()); + Assert.True(e.Parent() == m); + Assert.True(o.IsAlive()); + Assert.Equal(".RenameNsOuter.o", o.Path()); + Assert.True(world.Lookup(".RenameNsOuter.RenameNsInner") == 0); + Assert.True(world.Lookup(".RenameNsOuter") == m.Parent()); + } + + [Fact] + private void NestedImportChangesScopeBeforeModuleRename() + { + using World world = World.Create(); + + Entity m = world.Import(); + Assert.True(m.IsAlive()); + Assert.True(m.Has(Ecs.Module)); + Assert.Equal(".import_before_rename", m.Path()); + + Entity inner = world.Lookup(".scope_change.inner"); + Assert.True(inner != 0); + Assert.True(inner.IsAlive()); + Assert.True(inner.Has(Ecs.Module)); + Assert.True(inner == world.Import()); + + Assert.True(world.Lookup(".ScopeChangeNs") == 0); + Assert.True(world.GetScope() == 0); + } + + [Fact] + private void NestedImportChangesScopeAfterModuleRename() + { + using World world = World.Create(); + + Entity m = world.Import(); + Assert.True(m.IsAlive()); + Assert.True(m.Has(Ecs.Module)); + Assert.Equal(".import_after_rename", m.Path()); + + Entity inner = world.Lookup(".scope_change.inner"); + Assert.True(inner != 0); + Assert.True(inner.IsAlive()); + Assert.True(inner.Has(Ecs.Module)); + Assert.True(inner == world.Import()); + + Assert.True(world.Lookup(".ScopeChangeNs") == 0); + Assert.True(world.GetScope() == 0); + } + + [Fact] + private void ScopeRestoredAfterImportWNestedScopeChange() + { + using World world = World.Create(); + + Entity parent = world.Entity("parent"); + world.SetScope(parent); + + Entity m = world.Import(); + Assert.True(m.IsAlive()); + Assert.Equal(".import_before_rename", m.Path()); + Assert.True(world.GetScope() == parent); + + world.SetScope(0); + Assert.True(world.GetScope() == 0); + } + + [Fact] + private void NestedImportChangesScopeNoRename() + { + using World world = World.Create(); + + Entity m = world.Import(); + Assert.True(m.IsAlive()); + Assert.True(m.Has(Ecs.Module)); + Assert.Equal(".ScopeChangeNs.ImportNoRename", m.Path()); + + Entity inner = world.Lookup(".scope_change.inner"); + Assert.True(inner != 0); + Assert.True(inner.IsAlive()); + Assert.True(inner.Has(Ecs.Module)); + + Assert.True(world.GetScope() == 0); + } + + [Fact] + private void RenameWExistingComponentInOldParent() + { + using World world = World.Create(); + + Entity c = world.Component(); + Assert.Equal(".RenameNs.ComponentInOldParent", c.Path()); + + Entity m = world.Import(); + Assert.Equal(".RenamedModule", m.Path()); + + Assert.True(c.IsAlive()); + Assert.True(c.Parent() == m); + Assert.Equal(".RenamedModule.ComponentInOldParent", c.Path()); + Assert.True(world.Lookup(".RenameNs") == 0); + Assert.True(world.Lookup(".RenamedModule.ComponentInOldParent") == c); + + Entity e = world.Entity().Set(new RenameNs.ComponentInOldParent { Value = 10 }); + Assert.True(e.Has()); + Assert.Equal(10, e.Get().Value); + } } diff --git a/src/Flecs.NET.Tests/Cpp/ObserverTests.cs b/src/Flecs.NET.Tests/Cpp/ObserverTests.cs index 81e2a07d..118106ad 100644 --- a/src/Flecs.NET.Tests/Cpp/ObserverTests.cs +++ b/src/Flecs.NET.Tests/Cpp/ObserverTests.cs @@ -904,6 +904,7 @@ private void GetQuery() Observer observer = world.Observer() .Event(Ecs.OnSet) + .InOut(Ecs.In) .Each((Entity _, ref Position _) => { }); Query query = observer.Query(); @@ -957,11 +958,11 @@ private void OnSetWithDeferSet() Entity e = world.Entity(); Assert.Equal(0, count); - world.DeferBegin(); - e.Set(new Position { X = 10, Y = 20 }); + World stage = world.GetStage(0); + e.Stage(stage).Set(new Position { X = 10, Y = 20 }); Assert.Equal(0, count); - world.DeferEnd(); + stage.Merge(); Assert.Equal(1, count); } @@ -1193,9 +1194,9 @@ private void ImplicitRegisterInEmitForNamedEntityWithDefer() e2.Set(new Position(10, 20)); }); - world.DeferBegin(); + World stage = world.GetStage(0); e1.Emit(new MyEvent(10)); - world.DeferEnd(); + stage.Merge(); } [Fact] @@ -1214,9 +1215,9 @@ private void AddToNamedInEmitForNamedEntityWithDefer() e2.Set(new Position(10, 20)); }); - world.DeferBegin(); + World stage = world.GetStage(0); e1.Emit(new MyEvent(10)); - world.DeferEnd(); + stage.Merge(); } [Fact] @@ -1616,4 +1617,316 @@ private void FixedSrcWithRun() Assert.True(matched == 0); } + + [Fact] + private void ReuseObserverBuilder() + { + using World world = World.Create(); + + ObserverBuilder ob = world.Observer().Event(Ecs.OnSet); + + int count1 = 0; + Observer o1 = ob.Each((ref Position p) => { count1++; }); + + int count2 = 0; + Observer o2 = ob.With().Each((ref Position p) => { count2++; }); + + Assert.True(o1 != o2); + + world.Entity().Set(new Position(10, 20)); + world.Entity().Set(new Position(10, 20)).Set(new Velocity(1, 2)); + + Assert.Equal(2, count1); + Assert.Equal(1, count2); + } + + [Fact] + private void SingleTermObserverWVarGetVarPairSecond() + { + using World world = World.Create(); + + world.Component(); + + Entity source = world.Entity("SourceEntity"); + Entity instance = default; + int invoked = 0; + + world.Observer().Event(Ecs.OnAdd).With("$Source") + .Each((Iter it, int row) => + { + Assert.True(it.Entity(row) == instance); + Assert.True(it.GetVar("this") == instance); + Assert.True(it.GetVar("Source") == source); + invoked++; + }); + + instance = world.Entity("Instance"); + instance.Add(source); + Assert.Equal(1, invoked); + + int queryInvoked = 0; + using Query q = world.QueryBuilder().With("$Source").Build(); + q.Each((Iter it, int row) => + { + Assert.True(it.Entity(row) == instance); + Assert.True(it.GetVar("Source") == source); + queryInvoked++; + }); + Assert.Equal(1, queryInvoked); + } + + [Fact] + private void SingleTermObserverWVarGetVarPairFirst() + { + using World world = World.Create(); + + Entity tgt = world.Entity("Tgt"); + Entity rel = world.Entity("Rel"); + Entity instance = default; + int invoked = 0; + + world.Observer().Event(Ecs.OnRemove).With("$Rel", tgt) + .Each((Iter it, int row) => + { + Assert.True(it.Entity(row) == instance); + Assert.True(it.GetVar("this") == instance); + Assert.True(it.GetVar("Rel") == rel); + invoked++; + }); + + instance = world.Entity("Instance").Add(rel, tgt); + Assert.Equal(0, invoked); + instance.Remove(rel, tgt); + Assert.Equal(1, invoked); + } + + [Fact] + private void ComponentInheritanceEachMultiEntity() + { + using World world = World.Create(); + + world.Component(); + world.Component().Entity.IsA(); + + Entity tag = world.Entity(); + + int count = 0, sum = 0; + world.Observer() + .With(tag) + .Event(Ecs.OnRemove) + .Run((Iter it) => + { + while (it.Next()) + { + BaseField f = it.BaseField(0); + + for (int i = 0; i < it.Count(); i++) + { + sum += f[i].Hp; + count++; + } + } + }); + + world.Entity().Set(new InheritWarrior { Base = new InheritUnit { Hp = 10 }, Dmg = 1 }).Add(tag); + world.Entity().Set(new InheritWarrior { Base = new InheritUnit { Hp = 20 }, Dmg = 2 }).Add(tag); + world.Entity().Set(new InheritWarrior { Base = new InheritUnit { Hp = 30 }, Dmg = 3 }).Add(tag); + + Assert.Equal(0, count); + + world.RemoveAll(tag); + + Assert.Equal(3, count); + Assert.Equal(60, sum); + } + + [Fact] + private void DeleteWOnRemoveRemovingOtherWStage() + { + using World world = World.Create(); + + world.Observer() + .Event(Ecs.OnRemove) + .Each((Entity e, ref Position p) => { e.Remove(); }); + + Entity e = world.Entity().Add().Add(); + + e.Destruct(); + + Assert.False(e.IsAlive()); + } + + [Fact] + private void ClearWOnRemoveRemovingOtherWStage() + { + using World world = World.Create(); + + world.Observer() + .Event(Ecs.OnRemove) + .Each((Entity e, ref Position p) => { e.Remove(); }); + + Entity e = world.Entity().Add().Add(); + + e.Clear(); + + Assert.True(e.IsAlive()); + Assert.False(e.Has()); + Assert.False(e.Has()); + } + + [Fact] + private void DeleteWithWOnRemoveRemovingOtherWStage() + { + using World world = World.Create(); + + world.Observer() + .Event(Ecs.OnRemove) + .Each((Entity e, ref Position p) => { e.Remove(); }); + + Entity e1 = world.Entity().Add().Add().Add(); + Entity e2 = world.Entity().Add().Add().Add(); + Entity e3 = world.Entity().Add().Add().Add(); + Entity e4 = world.Entity().Add().Add(); + + world.DeleteWith(); + + Assert.False(e1.IsAlive()); + Assert.False(e2.IsAlive()); + Assert.False(e3.IsAlive()); + Assert.True(e4.IsAlive()); + Assert.True(e4.Has()); + Assert.True(e4.Has()); + } + + [Fact] + private void RemoveAllWOnRemoveRemovingOtherWStage() + { + using World world = World.Create(); + + world.Observer() + .Event(Ecs.OnRemove) + .Each((Entity e, ref Position p) => { e.Remove(); }); + + Entity e1 = world.Entity().Add().Add(); + Entity e2 = world.Entity().Add().Add(); + Entity e3 = world.Entity().Add().Add(); + + world.RemoveAll(); + + Assert.True(e1.IsAlive()); + Assert.False(e1.Has()); + Assert.False(e1.Has()); + Assert.True(e2.IsAlive()); + Assert.False(e2.Has()); + Assert.False(e2.Has()); + Assert.True(e3.IsAlive()); + Assert.False(e3.Has()); + Assert.False(e3.Has()); + } + + [Fact] + private void DeleteParentWOnRemoveRemovingOtherFromChildWStage() + { + using World world = World.Create(); + + world.Observer() + .Event(Ecs.OnRemove) + .Each((Entity e, ref Position p) => { e.Remove(); }); + + Entity parent = world.Entity(); + Entity child = world.Entity().ChildOf(parent).Add().Add(); + + parent.Destruct(); + + Assert.False(parent.IsAlive()); + Assert.False(child.IsAlive()); + } + + [Fact] + private void RemoveWOnRemoveRemovingOtherWStage() + { + using World world = World.Create(); + + world.Observer() + .Event(Ecs.OnRemove) + .Each((Entity e, ref Position p) => { e.Remove(); }); + + Entity e = world.Entity().Add().Add(); + + e.Remove(); + + Assert.True(e.IsAlive()); + Assert.False(e.Has()); + Assert.False(e.Has()); + } + + [Fact] + private void SetWOnAddAddingOtherWStage() + { + using World world = World.Create(); + + world.Observer() + .Event(Ecs.OnAdd) + .Each((Entity e, ref Position p) => { e.Add(); }); + + Entity e = world.Entity(); + + e.Set(new Position(10, 20)); + + Assert.True(e.Has()); + ref readonly Position p = ref e.Get(); + Assert.Equal(10, p.X); + Assert.Equal(20, p.Y); + } + + [Fact] + private void NoTermsCustomEvent() + { + using World world = World.Create(); + + Entity e = world.Entity(); + + int count = 0; + Entity last = default; + + world.Observer() + .Event() + .Each((Entity src) => + { + last = src; + count++; + }); + + Assert.Equal(0, count); + + world.Event().Entity(e).Emit(); + + Assert.Equal(1, count); + Assert.True(last == e); + } + + [Fact] + private void NoTermsOnAdd() + { + using World world = World.Create(); + + world.Component(); + + int count = 0; + Entity last = default; + + world.Observer() + .Event(Ecs.OnAdd) + .Each((Entity src) => + { + last = src; + count++; + }); + + Entity e = world.Entity(); + e.Add(); + + Assert.Equal(1, count); + Assert.True(last == e); + } } diff --git a/src/Flecs.NET.Tests/Cpp/OrderedChildrenTests.cs b/src/Flecs.NET.Tests/Cpp/OrderedChildrenTests.cs new file mode 100644 index 00000000..7245c7d4 --- /dev/null +++ b/src/Flecs.NET.Tests/Cpp/OrderedChildrenTests.cs @@ -0,0 +1,82 @@ +using Flecs.NET.Core; +using Xunit; + +namespace Flecs.NET.Tests.Cpp; + +public unsafe class OrderedChildrenTests +{ + [Fact] + private void IterNoChildren() + { + using World world = World.Create(); + + Entity parent = world.Entity().Add(Ecs.OrderedChildren); + + int count = 0; + parent.Children((Entity _) => { count++; }); + + Assert.Equal(0, count); + } + + [Fact] + private void Children1Table() + { + using World world = World.Create(); + + Entity parent = world.Entity().Add(Ecs.OrderedChildren); + Entity childA = world.Entity().ChildOf(parent).Add(); + Entity childB = world.Entity().ChildOf(parent).Add(); + Entity childC = world.Entity().ChildOf(parent).Add(); + + int index = 0; + Entity[] children = [childA, childB, childC]; + + parent.Children((Entity e) => { Assert.Equal(children[index++], e); }); + + Assert.Equal(3, index); + } + + [Fact] + private void Children2Tables() + { + using World world = World.Create(); + + Entity parent = world.Entity().Add(Ecs.OrderedChildren); + Entity childA = world.Entity().ChildOf(parent).Add(); + Entity childB = world.Entity().ChildOf(parent).Add(); + Entity childC = world.Entity().ChildOf(parent).Add(); + + int index = 0; + Entity[] children = [childA, childB, childC]; + + parent.Children((Entity e) => { Assert.Equal(children[index++], e); }); + + Assert.Equal(3, index); + } + + [Fact] + private void SetChildOrder() + { + using World world = World.Create(); + + Entity parent = world.Entity().Add(Ecs.OrderedChildren); + Entity childA = world.Entity().ChildOf(parent).Add(); + Entity childB = world.Entity().ChildOf(parent).Add(); + Entity childC = world.Entity().ChildOf(parent).Add(); + + int index = 0; + Entity[] children = [childA, childB, childC]; + + parent.Children((Entity e) => { Assert.Equal(children[index++], e); }); + Assert.Equal(3, index); + + ulong* entities = stackalloc ulong[] { childC, childA, childB }; + parent.SetChildOrder(entities, 3); + + index = 0; + Entity[] reordered = [childC, childA, childB]; + + parent.Children((Entity e) => { Assert.Equal(reordered[index++], e); }); + Assert.Equal(3, index); + } +} diff --git a/src/Flecs.NET.Tests/Cpp/QueryBuilderTests.cs b/src/Flecs.NET.Tests/Cpp/QueryBuilderTests.cs index e6dc045a..b659bd67 100644 --- a/src/Flecs.NET.Tests/Cpp/QueryBuilderTests.cs +++ b/src/Flecs.NET.Tests/Cpp/QueryBuilderTests.cs @@ -3272,7 +3272,7 @@ private void IterWithStage(ecs_query_cache_kind_t cacheKind) int count = 0; q.Iter(stage).Each((Iter it, int i, ref Position _) => { - Assert.True(it.World() == stage); + Assert.True(it.Stage() == stage); Assert.True(it.Entity(i) == e1); count++; }); @@ -5389,12 +5389,21 @@ private void IsValid(ecs_query_cache_kind_t cacheKind) using Query q1 = world.Query(); Assert.True(q1); + int previousLevel = Ecs.Log.GetLevel(); Ecs.Log.SetLevel(-4); - using Query q2 = world.QueryBuilder() - .Expr("foo") - .CacheKind(cacheKind) - .Build(); - Assert.True(!q2); + + try + { + using Query q2 = world.QueryBuilder() + .Expr("foo") + .CacheKind(cacheKind) + .Build(); + Assert.True(!q2); + } + finally + { + Ecs.Log.SetLevel(previousLevel); + } } [Theory] @@ -5682,4 +5691,72 @@ private void SingletonPair(ecs_query_cache_kind_t cacheKind) Assert.Equal(1, count); } + + [Theory] + [MemberData(nameof(CacheKinds))] + private void ValuePairW0Value(ecs_query_cache_kind_t cacheKind) + { + using World world = World.Create(); + + world.Component() + .Add(Ecs.Relationship) + .Add(Ecs.Exclusive); + + using Query q1 = world.QueryBuilder() + .Second((ulong)UnionT.Type.Type1).Flags(ECS_VALUE_PAIR) + .CacheKind(cacheKind) + .Build(); + + using Query q2 = world.QueryBuilder() + .Second((ulong)UnionT.Type.Type2).Flags(ECS_VALUE_PAIR) + .CacheKind(cacheKind) + .Build(); + + UnionT val1 = new() { Type1 = 3 }; + UnionT val2 = new() { Type2 = 2.5f }; + + Entity e1 = world.Entity(); + Entity e2 = world.Entity(); + + e1.SetUntyped(Ecs.ValuePair(world.Component(), (ulong)UnionT.Type.Type1), sizeof(UnionT), &val1); + e2.SetUntyped(Ecs.ValuePair(world.Component(), (ulong)UnionT.Type.Type2), sizeof(UnionT), &val2); + + int count1 = 0, count2 = 0; + + q1.Each((Entity e, ref UnionT data) => + { + Assert.True(e == e1); + Assert.Equal(3u, data.Type1); + count1++; + }); + + q2.Each((Entity e, ref UnionT data) => + { + Assert.True(e == e2); + Assert.Equal(2.5f, data.Type2); + count2++; + }); + + Assert.Equal(1, count1); + Assert.Equal(1, count2); + } + + [Fact] + private void TermRefFlagsPreserveId() + { + using World world = World.Create(); + + Entity e = world.Entity(); + + using Query q = world.QueryBuilder() + .With().Src().Entity(e.Id) + .Build(); + + Assert.Equal(e.Id.Value, Ecs.TermRefId(ref q.Handle->terms[0].src)); + Assert.True((q.Handle->terms[0].src.id & Ecs.IsEntity) != 0); + + Assert.False(q.IsTrue()); + e.Add(); + Assert.True(q.IsTrue()); + } } diff --git a/src/Flecs.NET.Tests/Cpp/QueryTests.cs b/src/Flecs.NET.Tests/Cpp/QueryTests.cs index ba492863..3040e4cd 100644 --- a/src/Flecs.NET.Tests/Cpp/QueryTests.cs +++ b/src/Flecs.NET.Tests/Cpp/QueryTests.cs @@ -2656,14 +2656,13 @@ private void NotWithWrite() Entity e = world.Entity().Add(); int count = 0; - world.Defer(() => + World stage = world.GetStage(0); + q.Each((Entity ent) => { - q.Each((Entity ent) => - { - ent.Add(); - count++; - }); + ent.Stage(stage).Add(); + count++; }); + stage.Merge(); Assert.Equal(1, count); Assert.True(e.Has()); @@ -3562,4 +3561,1031 @@ private void IterTargetsFieldNotSet() }); }); } -} \ No newline at end of file + + [Fact] + private void ComponentInheritanceBaseField() + { + using World world = World.Create(); + + world.Component(); + world.Component().Entity.IsA(); + + Entity w1 = world.Entity().Set(new InheritWarrior { Base = new InheritUnit { Hp = 10 }, Dmg = 1 }); + Entity w2 = world.Entity().Set(new InheritWarrior { Base = new InheritUnit { Hp = 20 }, Dmg = 2 }); + Entity w3 = world.Entity().Set(new InheritWarrior { Base = new InheritUnit { Hp = 30 }, Dmg = 3 }); + + int sum = 0, count = 0; + world.Query().Run((Iter it) => + { + while (it.Next()) + { + BaseField f = it.BaseField(0); + for (int i = 0; i < it.Count(); i++) + { + sum += f[i].Hp; + count++; + } + } + }); + + Assert.Equal(3, count); + Assert.Equal(60, sum); + + world.Query().Run((Iter it) => + { + while (it.Next()) + { + BaseField f = it.BaseField(0); + for (int i = 0; i < it.Count(); i++) + f[i].Hp *= 2; + } + }); + + Assert.Equal(20, w1.Get().Base.Hp); + Assert.Equal(40, w2.Get().Base.Hp); + Assert.Equal(60, w3.Get().Base.Hp); + Assert.Equal(1, w1.Get().Dmg); + } + + [Fact] + private void SparseQueryEach() + { + using World world = World.Create(); + + world.Component().Add(Ecs.DontFragment); + world.Component().Add(Ecs.DontFragment); + + Entity e1 = world.Entity() + .Set(new PositionDfOr { X = 10, Y = 20 }) + .Set(new VelocityDfOr { X = 1, Y = 2 }); + Entity e2 = world.Entity().Set(new PositionDfOr { X = 30, Y = 40 }); + Entity e3 = world.Entity().Set(new VelocityDfOr { X = 3, Y = 4 }); + + SparseQuery q = world.SparseQuery(); + + int count = 0; + q.Each((Entity e, ref PositionDfOr p, ref VelocityDfOr v) => + { + Assert.True(e == e1); + Assert.Equal(10, p.X); + Assert.Equal(20, p.Y); + p.X += v.X; + p.Y += v.Y; + count++; + }); + + Assert.Equal(1, count); + Assert.Equal(1, q.Count()); + + PositionDfOr* p1 = e1.GetPtr(); + Assert.Equal(11, p1->X); + Assert.Equal(22, p1->Y); + + Assert.True(e2.IsAlive()); + Assert.True(e3.IsAlive()); + } + + [Fact] + private void SparseQueryEmpty() + { + using World world = World.Create(); + + world.Component().Add(Ecs.DontFragment); + world.Component().Add(Ecs.DontFragment); + + SparseQuery q = world.SparseQuery(); + + int count = 0; + q.Each((ref PositionDfOr _, ref VelocityDfOr _) => { count++; }); + + Assert.Equal(0, count); + Assert.Equal(0, q.Count()); + } + + [Fact] + private void SparseQueryRecycledEntity() + { + using World world = World.Create(); + + world.Component().Add(Ecs.DontFragment); + + Entity e1 = world.Entity().Set(new PositionDfOr { X = 10, Y = 20 }); + e1.Destruct(); + Entity e2 = world.Entity().Set(new PositionDfOr { X = 30, Y = 40 }); + Assert.True(e1 != e2); + Assert.Equal((uint)e1.Id.Value, (uint)e2.Id.Value); + + SparseQuery q = world.SparseQuery(); + + int count = 0; + q.Each((Entity e, ref PositionDfOr p) => + { + Assert.True(e == e2); + Assert.Equal(30, p.X); + Assert.Equal(40, p.Y); + count++; + }); + + Assert.Equal(1, count); + } + + [Fact] + private void SparseQuerySkipPrefabDisabled() + { + using World world = World.Create(); + + world.Component().Add(Ecs.DontFragment); + + Entity e = world.Entity().Set(new PositionDfOr { X = 10, Y = 20 }); + world.Entity().Add(Ecs.Prefab).Set(new PositionDfOr { X = 1, Y = 2 }); + world.Entity().Add(Ecs.Disabled).Set(new PositionDfOr { X = 3, Y = 4 }); + world.Entity().Add(EcsNotQueryable).Set(new PositionDfOr { X = 5, Y = 6 }); + + SparseQuery q = world.SparseQuery(); + + int count = 0; + q.Each((Entity ent, ref PositionDfOr pos) => + { + Assert.True(ent == e); + Assert.Equal(10, pos.X); + Assert.Equal(20, pos.Y); + count++; + }); + + Assert.Equal(1, count); + Assert.Equal(1, q.Count()); + } + + [Fact] + private void SparseQueryTypeNoOnInstantiate() + { + using World world = World.Create(); + + world.Component().Add(Ecs.DontFragment); + world.Component().Add(Ecs.DontFragment); + + Entity e1 = world.Entity().Set(new PositionDf { X = 10, Y = 20 }); + Entity e2 = world.Entity().Set(new PositionDf { X = 30, Y = 40 }); + + SparseQuery q = world.SparseQuery(); + + int count = 0; + q.Each((Entity e, ref PositionDf p) => + { + if (e == e1) + { + Assert.Equal(10, p.X); + Assert.Equal(20, p.Y); + } + else + { + Assert.True(e == e2); + Assert.Equal(30, p.X); + Assert.Equal(40, p.Y); + } + count++; + }); + + Assert.Equal(2, count); + } + + [Fact] + private void SparseQueryEachOnInstantiateOverride() + { + using World world = World.Create(); + + world.Component().Add(Ecs.DontFragment); + + Entity e1 = world.Entity().Set(new PositionDfOr { X = 10, Y = 20 }); + Entity e2 = world.Entity().Set(new PositionDfOr { X = 30, Y = 40 }); + Entity e3 = world.Entity(); + + SparseQuery q = world.SparseQuery(); + + int count = 0; + q.Each((Entity e, ref PositionDfOr p) => + { + if (e == e1) + { + Assert.Equal(10, p.X); + Assert.Equal(20, p.Y); + } + else + { + Assert.True(e == e2); + Assert.Equal(30, p.X); + Assert.Equal(40, p.Y); + } + p.X++; + p.Y++; + count++; + }); + + Assert.Equal(2, count); + Assert.Equal(2, q.Count()); + + PositionDfOr* p1 = e1.GetPtr(); + Assert.Equal(11, p1->X); + Assert.Equal(21, p1->Y); + + PositionDfOr* p2 = e2.GetPtr(); + Assert.Equal(31, p2->X); + Assert.Equal(41, p2->Y); + + Assert.True(e3.IsAlive()); + } + + [Fact] + private void SparseQueryEachOnInstantiateDontInherit() + { + using World world = World.Create(); + + world.Component().Add(Ecs.DontFragment); + world.Component().Add(Ecs.OnInstantiate, Ecs.DontInherit); + + Entity e1 = world.Entity().Set(new PositionDfDi { X = 10, Y = 20 }); + Entity e2 = world.Entity().Set(new PositionDfDi { X = 30, Y = 40 }); + + SparseQuery q = world.SparseQuery(); + + int count = 0; + q.Each((Entity e, ref PositionDfDi p) => + { + if (e == e1) + { + Assert.Equal(10, p.X); + Assert.Equal(20, p.Y); + } + else + { + Assert.True(e == e2); + Assert.Equal(30, p.X); + Assert.Equal(40, p.Y); + } + p.X++; + p.Y++; + count++; + }); + + Assert.Equal(2, count); + Assert.Equal(2, q.Count()); + + PositionDfDi* p1 = e1.GetPtr(); + Assert.Equal(11, p1->X); + Assert.Equal(21, p1->Y); + + PositionDfDi* p2 = e2.GetPtr(); + Assert.Equal(31, p2->X); + Assert.Equal(41, p2->Y); + } + + [Fact] + private void SparseQueryEachOnInstantiateMixedTerms() + { + using World world = World.Create(); + + world.Component().Add(Ecs.DontFragment); + world.Component().Add(Ecs.DontFragment); + world.Component().Add(Ecs.OnInstantiate, Ecs.DontInherit); + + Entity e1 = world.Entity() + .Set(new PositionDfOr { X = 10, Y = 20 }) + .Set(new PositionDfDi { X = 1, Y = 2 }); + Entity e2 = world.Entity().Set(new PositionDfOr { X = 30, Y = 40 }); + Entity e3 = world.Entity().Set(new PositionDfDi { X = 3, Y = 4 }); + + SparseQuery q = world.SparseQuery(); + + int count = 0; + q.Each((Entity e, ref PositionDfOr p, ref PositionDfDi d) => + { + Assert.True(e == e1); + Assert.Equal(10, p.X); + Assert.Equal(20, p.Y); + p.X += d.X; + p.Y += d.Y; + count++; + }); + + Assert.Equal(1, count); + Assert.Equal(1, q.Count()); + + PositionDfOr* p = e1.GetPtr(); + Assert.Equal(11, p->X); + Assert.Equal(22, p->Y); + + Assert.True(e2.IsAlive()); + Assert.True(e3.IsAlive()); + } + + [Fact] + private void SparseQueryConvertToQuery1Term() + { + using World world = World.Create(); + + world.Component().Add(Ecs.DontFragment); + + Entity e1 = world.Entity().Set(new PositionDfOr { X = 10, Y = 20 }); + Entity e2 = world.Entity().Set(new PositionDfOr { X = 30, Y = 40 }); + + using Query q = world.SparseQuery().ToQuery(); + + int count = 0; + q.Each((Entity e, ref PositionDfOr p) => + { + if (e == e1) + { + Assert.Equal(10, p.X); + Assert.Equal(20, p.Y); + } + else + { + Assert.True(e == e2); + Assert.Equal(30, p.X); + Assert.Equal(40, p.Y); + } + count++; + }); + + Assert.Equal(2, count); + Assert.Equal(2, q.Count()); + } + + [Fact] + private void SparseQueryConvertToQuery3Terms() + { + using World world = World.Create(); + + world.Component().Add(Ecs.DontFragment); + world.Component().Add(Ecs.DontFragment); + world.Component().Add(Ecs.DontFragment); + world.Component().Add(Ecs.OnInstantiate, Ecs.DontInherit); + + Entity e1 = world.Entity() + .Set(new PositionDfOr { X = 10, Y = 20 }) + .Set(new VelocityDfOr { X = 1, Y = 2 }) + .Set(new PositionDfDi { X = 3, Y = 4 }); + world.Entity().Set(new PositionDfOr { X = 30, Y = 40 }); + + using Query q = + world.SparseQuery().ToQuery(); + + int count = 0; + q.Each((Entity e, ref PositionDfOr p, ref VelocityDfOr v, ref PositionDfDi d) => + { + Assert.True(e == e1); + Assert.Equal(10, p.X); + Assert.Equal(20, p.Y); + Assert.Equal(1, v.X); + Assert.Equal(2, v.Y); + Assert.Equal(3, d.X); + Assert.Equal(4, d.Y); + count++; + }); + + Assert.Equal(1, count); + Assert.Equal(1, q.Count()); + } + + [Fact] + private void SparseQueryDynamicDontInherit() + { + using World world = World.Create(); + + world.Component().Add(Ecs.DontFragment); + world.Component().Add(Ecs.OnInstantiate, Ecs.DontInherit); + + Entity e1 = world.Entity().Set(new PositionDf { X = 10, Y = 20 }); + Entity e2 = world.Entity().Set(new PositionDf { X = 30, Y = 40 }); + + SparseQuery q = world.SparseQuery(); + + int count = 0; + q.Each((Entity e, ref PositionDf p) => + { + if (e == e1) + { + Assert.Equal(10, p.X); + Assert.Equal(20, p.Y); + } + else + { + Assert.True(e == e2); + Assert.Equal(30, p.X); + Assert.Equal(40, p.Y); + } + count++; + }); + + Assert.Equal(2, count); + Assert.Equal(2, q.Count()); + } + + [Fact] + private void WorldEachSparse() + { + using World world = World.Create(); + + world.Component().Add(Ecs.DontFragment); + world.Component().Add(Ecs.DontFragment); + + Entity e1 = world.Entity() + .Set(new PositionDfOr { X = 10, Y = 20 }) + .Set(new VelocityDfOr { X = 1, Y = 2 }); + world.Entity().Set(new PositionDfOr { X = 30, Y = 40 }); + + int count = 0; + world.Each((ref PositionDfOr p, ref VelocityDfOr v) => + { + Assert.Equal(10, p.X); + Assert.Equal(20, p.Y); + Assert.Equal(1, v.X); + Assert.Equal(2, v.Y); + p.X += v.X; + p.Y += v.Y; + count++; + }); + + Assert.Equal(1, count); + + PositionDfOr* p = e1.GetPtr(); + Assert.Equal(11, p->X); + Assert.Equal(22, p->Y); + } + + [Fact] + private void WorldEachSparseWithEntity() + { + using World world = World.Create(); + + world.Component().Add(Ecs.DontFragment); + + Entity e1 = world.Entity().Set(new PositionDfOr { X = 10, Y = 20 }); + Entity e2 = world.Entity().Set(new PositionDfOr { X = 30, Y = 40 }); + + int count = 0; + world.Each((Entity e, ref PositionDfOr p) => + { + if (e == e1) + { + Assert.Equal(10, p.X); + Assert.Equal(20, p.Y); + } + else + { + Assert.True(e == e2); + Assert.Equal(30, p.X); + Assert.Equal(40, p.Y); + } + count++; + }); + + Assert.Equal(2, count); + } + + [Fact] + private void TermEachSparseComponent() + { + using World world = World.Create(); + + world.Component().Add(Ecs.Sparse); + + Entity e1 = world.Entity().Set(new Position(1, 2)); + Entity e2 = world.Entity().Set(new Position(3, 4)); + Entity e3 = world.Entity().Set(new Position(5, 6)); + + e3.Add(); + + int count = 0; + world.Each((Entity e, ref Position p) => + { + if (e == e1) + { + Assert.Equal(1, p.X); + Assert.Equal(2, p.Y); + count++; + } + if (e == e2) + { + Assert.Equal(3, p.X); + Assert.Equal(4, p.Y); + count++; + } + if (e == e3) + { + Assert.Equal(5, p.X); + Assert.Equal(6, p.Y); + count++; + } + }); + + Assert.Equal(3, count); + } + + [Fact] + private void TermEachDontFragmentComponent() + { + using World world = World.Create(); + + world.Component().Add(Ecs.DontFragment); + + Entity e1 = world.Entity().Set(new Position(1, 2)); + Entity e2 = world.Entity().Set(new Position(3, 4)); + Entity e3 = world.Entity().Set(new Position(5, 6)); + + e3.Add(); + + int count = 0; + world.Each((Entity e, ref Position p) => + { + if (e == e1) + { + Assert.Equal(1, p.X); + Assert.Equal(2, p.Y); + count++; + } + if (e == e2) + { + Assert.Equal(3, p.X); + Assert.Equal(4, p.Y); + count++; + } + if (e == e3) + { + Assert.Equal(5, p.X); + Assert.Equal(6, p.Y); + count++; + } + }); + + Assert.Equal(3, count); + } + + [Fact] + private void TermEachDontFragmentPairObjectWildcard() + { + using World world = World.Create(); + + Entity rel = world.Entity().Add(Ecs.DontFragment); + Entity obj1 = world.Entity(); + Entity obj2 = world.Entity(); + + Entity e1 = world.Entity().Add(rel, obj1); + Entity e2 = world.Entity().Add(rel, obj1); + e2.Remove(rel, obj1); + e2.Add(rel, obj2); + e2.Remove(rel, obj2); + e2.Add(rel, obj1); + + int count = 0; + world.Each(world.Pair(rel, Ecs.Wildcard), (Entity e) => + { + if (e == e1 || e == e2) + count++; + }); + + Assert.Equal(2, count); + } + + [Fact] + private void GetFirstWNonThisSrc() + { + using World world = World.Create(); + + Entity e1 = world.Entity("e1"); + Entity e2 = world.Entity("e2"); + + using Query q = world.QueryBuilder().Expr("ChildOf($x, *)").Build(); + + Entity first = q.Iter().First(); + Assert.True(first == 0); + + e1.ChildOf(e2); + + first = q.Iter().First(); + Assert.True(first == 0); + } + + [Fact] + private void GetFirstDirectWNonThisSrc() + { + using World world = World.Create(); + + Entity e1 = world.Entity("e1"); + Entity e2 = world.Entity("e2"); + + using Query q = world.QueryBuilder().Expr("ChildOf($x, _)").Build(); + + Entity first = q.First(); + Assert.True(first == 0); + + e1.ChildOf(e2); + + first = q.First(); + Assert.True(first == 0); + } + + [Fact] + private void GetFirstSkipsEmptyResults() + { + using World world = World.Create(); + + Entity e1 = world.Entity().Add().Add(); + Entity e2 = world.Entity().Add(); + e2.Destruct(); + + using Query q = world.QueryBuilder() + .Cached() + .QueryFlags(Ecs.QueryMatchEmptyTables) + .Build(); + + Entity first = q.First(); + Assert.True(first != 0); + Assert.True(first == e1); + } + + [Fact] + private void DontFragmentTraitRegistered() + { + using World world = World.Create(); + + Component c = world.Component().Add(Ecs.DontFragment); + Assert.True(c.Has(Ecs.DontFragment)); + } + + [Fact] + private void DontFragmentTraitSpecializedRegistered() + { + using World world = World.Create(); + + Component c = world.Component().Add(Ecs.DontFragment); + Assert.True(c.Has(Ecs.DontFragment)); + } + + [Fact] + private void EachDontFragmentTrait() + { + using World world = World.Create(); + + world.Component().Add(Ecs.DontFragment); + + Entity e1 = world.Entity().Set(new PositionDfOr(10, 20)); + Entity e2 = world.Entity().Set(new PositionDfOr(30, 40)); + + using Query q = world.Query(); + + int count = 0; + q.Each((Entity e, ref PositionDfOr p) => + { + if (e == e1) + { + Assert.Equal(10, p.X); + Assert.Equal(20, p.Y); + } + else if (e == e2) + { + Assert.Equal(30, p.X); + Assert.Equal(40, p.Y); + } + + p.X++; + p.Y++; + count++; + }); + + Assert.Equal(2, count); + + PositionDfOr* p1 = e1.GetPtr(); + Assert.Equal(11, p1->X); + Assert.Equal(21, p1->Y); + + PositionDfOr* p2 = e2.GetPtr(); + Assert.Equal(31, p2->X); + Assert.Equal(41, p2->Y); + } + + [Fact] + private void EachDontFragmentTraitMixed() + { + using World world = World.Create(); + + world.Component().Add(Ecs.DontFragment); + + Entity entity = world.Entity() + .Set(new PositionDfOr(10, 20)) + .Set(new Velocity(1, 2)); + + using Query q = world.Query(); + + q.Each((ref PositionDfOr p, ref Velocity v) => + { + p.X += v.X; + p.Y += v.Y; + }); + + PositionDfOr* p = entity.GetPtr(); + Assert.Equal(11, p->X); + Assert.Equal(22, p->Y); + } + + [Fact] + private void EachDontFragmentTraitShared() + { + using World world = World.Create(); + + world.Component().Add(Ecs.DontFragment); + + Entity parent = world.Entity().Set(new Velocity(1, 2)); + Entity entity = world.Entity().ChildOf(parent) + .Set(new PositionDfOr(10, 20)); + + using Query q = world.QueryBuilder() + .TermAt(1).Up() + .Build(); + + int count = 0; + q.Each((ref PositionDfOr p, ref Velocity v) => + { + Assert.Equal(1, v.X); + Assert.Equal(2, v.Y); + p.X += v.X; + p.Y += v.Y; + count++; + }); + + Assert.Equal(1, count); + + PositionDfOr* p = entity.GetPtr(); + Assert.Equal(11, p->X); + Assert.Equal(22, p->Y); + } + + [Fact] + private void EachOptionalSparse() + { + using World world = World.Create(); + + world.Component().Add(Ecs.Sparse); + + Entity e1 = world.Entity().Set(new Velocity(1, 2)).Set(new Position(10, 20)); + Entity e2 = world.Entity().Set(new Velocity(3, 4)); + + using Query q = world.QueryBuilder() + .TermAt(1).Optional() + .Build(); + + int count = 0, withP = 0; + q.Each((Entity e, ref Velocity v, ref Position p) => + { + if (e == e1) + { + Assert.False(Unsafe.IsNullRef(ref p)); + Assert.Equal(10, p.X); + Assert.Equal(20, p.Y); + Assert.Equal(1, v.X); + Assert.Equal(2, v.Y); + withP++; + } + else + { + Assert.True(e == e2); + Assert.True(Unsafe.IsNullRef(ref p)); + Assert.Equal(3, v.X); + Assert.Equal(4, v.Y); + } + count++; + }); + + Assert.Equal(2, count); + Assert.Equal(1, withP); + } + + [Fact] + private void SparseQueryDynamicInherit1Term() + { + using World world = World.Create(); + + world.Component() + .Add(Ecs.DontFragment) + .Add(Ecs.OnInstantiate, Ecs.Inherit); + + Entity owner = world.Entity().Set(new PositionDfDi(10, 20)); + Entity @base = world.Prefab().Set(new PositionDfDi(1, 2)); + Entity inst = world.Entity().IsA(@base); + + Assert.False(inst.Owns()); + Assert.True(inst.Has()); + + foreach (ecs_query_cache_kind_t cacheKind in new[] { Ecs.QueryCacheNone, Ecs.QueryCacheAuto }) + { + using Query q = world.QueryBuilder() + .CacheKind(cacheKind) + .Build(); + + int ownerCount = 0, instCount = 0; + q.Each((Entity e, ref PositionDfDi p) => + { + if (e == owner) + { + Assert.Equal(10, p.X); + Assert.Equal(20, p.Y); + ownerCount++; + } + else + { + Assert.True(e == inst); + Assert.Equal(1, p.X); + Assert.Equal(2, p.Y); + instCount++; + } + }); + + Assert.Equal(1, ownerCount); + Assert.Equal(1, instCount); + } + } + + [Fact] + private void SparseQueryDynamicInherit3Terms() + { + using World world = World.Create(); + + world.Component() + .Add(Ecs.DontFragment) + .Add(Ecs.OnInstantiate, Ecs.Inherit); + world.Component().Add(Ecs.DontFragment); + world.Component().Add(Ecs.DontFragment); + + Entity owner = world.Entity() + .Set(new PositionDfDi(10, 20)) + .Set(new PositionDfOr(30, 40)) + .Set(new VelocityDfOr(1, 2)); + + Entity @base = world.Prefab().Set(new PositionDfDi(50, 60)); + Entity inst = world.Entity().IsA(@base) + .Set(new PositionDfOr(70, 80)) + .Set(new VelocityDfOr(3, 4)); + + Assert.False(inst.Owns()); + Assert.True(inst.Has()); + + foreach (ecs_query_cache_kind_t cacheKind in new[] { Ecs.QueryCacheNone, Ecs.QueryCacheAuto }) + { + using Query q = + world.QueryBuilder() + .CacheKind(cacheKind) + .Build(); + + int ownerCount = 0, instCount = 0; + q.Each((Entity e, ref PositionDfDi p, ref PositionDfOr p2, ref VelocityDfOr v) => + { + if (e == owner) + { + Assert.Equal(10, p.X); + Assert.Equal(20, p.Y); + Assert.Equal(30, p2.X); + Assert.Equal(40, p2.Y); + Assert.Equal(1, v.X); + Assert.Equal(2, v.Y); + ownerCount++; + } + else + { + Assert.True(e == inst); + Assert.Equal(50, p.X); + Assert.Equal(60, p.Y); + Assert.Equal(70, p2.X); + Assert.Equal(80, p2.Y); + Assert.Equal(3, v.X); + Assert.Equal(4, v.Y); + instCount++; + } + }); + + Assert.Equal(1, ownerCount); + Assert.Equal(1, instCount); + } + } + + [Fact] + private void ComponentInheritanceEach() + { + using World world = World.Create(); + + world.Component(); + world.Component().Entity.IsA(); + + Entity w1 = world.Entity().Set(new InheritWarrior { Base = new InheritUnit { Hp = 10 }, Dmg = 1 }); + Entity w2 = world.Entity().Set(new InheritWarrior { Base = new InheritUnit { Hp = 20 }, Dmg = 2 }); + Entity w3 = world.Entity().Set(new InheritWarrior { Base = new InheritUnit { Hp = 30 }, Dmg = 3 }); + + int sum = 0, count = 0; + world.Query().Run((Iter it) => + { + while (it.Next()) + { + BaseField f = it.BaseField(0); + + for (int i = 0; i < it.Count(); i++) + { + sum += f[i].Hp; + count++; + } + } + }); + + Assert.Equal(3, count); + Assert.Equal(60, sum); + + world.Query().Run((Iter it) => + { + while (it.Next()) + { + BaseField f = it.BaseField(0); + + for (int i = 0; i < it.Count(); i++) + f[i].Hp *= 2; + } + }); + + Assert.Equal(20, w1.Get().Base.Hp); + Assert.Equal(40, w2.Get().Base.Hp); + Assert.Equal(60, w3.Get().Base.Hp); + Assert.Equal(1, w1.Get().Dmg); + Assert.Equal(2, w2.Get().Dmg); + Assert.Equal(3, w3.Get().Dmg); + } + + [Fact] + private void ComponentInheritanceEachMultipleDerived() + { + using World world = World.Create(); + + world.Component(); + world.Component().Entity.IsA(); + world.Component().Entity.IsA(); + + Entity w = world.Entity().Set(new InheritWarrior { Base = new InheritUnit { Hp = 10 }, Dmg = 5 }); + Entity m = world.Entity().Set(new InheritMage { Base = new InheritUnit { Hp = 20 }, Mana = 7 }); + + int sum = 0, count = 0; + world.Query().Run((Iter it) => + { + while (it.Next()) + { + BaseField f = it.BaseField(0); + + for (int i = 0; i < it.Count(); i++) + { + sum += f[i].Hp; + count++; + } + } + }); + + Assert.Equal(2, count); + Assert.Equal(30, sum); + + Assert.Equal(5, w.Get().Dmg); + Assert.Equal(7, m.Get().Mana); + } + + [Fact] + private void ComponentInheritanceEachEntity() + { + using World world = World.Create(); + + world.Component(); + world.Component().Entity.IsA(); + + Entity w1 = world.Entity().Set(new InheritWarrior { Base = new InheritUnit { Hp = 10 }, Dmg = 1 }); + Entity w2 = world.Entity().Set(new InheritWarrior { Base = new InheritUnit { Hp = 20 }, Dmg = 2 }); + + int found = 0; + world.Query().Run((Iter it) => + { + while (it.Next()) + { + BaseField f = it.BaseField(0); + + for (int i = 0; i < it.Count(); i++) + { + Entity e = it.Entity(i); + + if (e == w1) + { + Assert.Equal(10, f[i].Hp); + found++; + } + if (e == w2) + { + Assert.Equal(20, f[i].Hp); + found++; + } + } + } + }); + + Assert.Equal(2, found); + } +} diff --git a/src/Flecs.NET.Tests/Cpp/RefTests.cs b/src/Flecs.NET.Tests/Cpp/RefTests.cs index db9080a0..3ef67613 100644 --- a/src/Flecs.NET.Tests/Cpp/RefTests.cs +++ b/src/Flecs.NET.Tests/Cpp/RefTests.cs @@ -147,6 +147,7 @@ public void FromStage() using World world = World.Create(); World stage = world.GetStage(0); Entity e = stage.Entity().Set(new Position { X = 10, Y = 20 }); + stage.Merge(); Ref reference = e.GetRef(); Assert.Equal(10, reference.GetPtr()->X); Assert.Equal(20, reference.GetPtr()->Y); diff --git a/src/Flecs.NET.Tests/Cpp/ScriptTests.cs b/src/Flecs.NET.Tests/Cpp/ScriptTests.cs new file mode 100644 index 00000000..40d8ba36 --- /dev/null +++ b/src/Flecs.NET.Tests/Cpp/ScriptTests.cs @@ -0,0 +1,305 @@ +using Flecs.NET.Core; +using Xunit; +using static Flecs.NET.Bindings.flecs; + +namespace Flecs.NET.Tests.Cpp; + +public unsafe class ScriptTests +{ + // C++ maps int64_t/double to the builtin flecs.meta types, so use those ids explicitly to match its behavior. + // Flecs.NET registers .NET primitives as separate components (e.g. Flecs.NET.Core.Ecs.Meta.Int64). + private static ulong I64 => FLECS_IDecs_i64_tID_; + private static ulong F64 => FLECS_IDecs_f64_tID_; + + private static void ScriptSum(ScriptFunction ctx, ScriptArgs args, ScriptValue result) + { + Assert.True(args.Count == 1 || args.Count == 2); + long a = args[0].Get(); + long b = args[1].Get(); + long offset = ctx.Ctx != null ? *(long*)ctx.Ctx : 0; + result.Get() = a + b + offset; + } + + private static void ScriptLerpFloat(ScriptFunction ctx, ScriptArgs args, ScriptValue result, int count) + { + Assert.Equal(3, args.Count); + float* a = args[0].GetPtr(); + float* b = args[1].GetPtr(); + double t = args[2].Get(); + float* r = result.GetPtr(); + + for (int i = 0; i < count; i++) + r[i] = (float)(a[i] + t * (b[i] - a[i])); + } + + private static void ScriptLerpDouble(ScriptFunction ctx, ScriptArgs args, ScriptValue result, int count) + { + Assert.Equal(3, args.Count); + double* a = args[0].GetPtr(); + double* b = args[1].GetPtr(); + double t = args[2].Get(); + double* r = result.GetPtr(); + + for (int i = 0; i < count; i++) + r[i] = a[i] + t * (b[i] - a[i]); + } + + [Fact] + private void Function() + { + using World world = World.Create(); + + Entity f = world.Function("sum") + .ReturnType(I64) + .Param("a", I64) + .Param("b", I64) + .Callback(ScriptSum) + .Build(); + + Assert.True(f != 0); + Assert.Equal(0, world.ScriptRun(null!, "export const result = sum(10, 20)")); + Assert.Equal(30, world.GetConstVar("result")); + } + + [Fact] + private void FunctionScopeAndCtx() + { + using World world = World.Create(); + + Entity parent = world.Entity("math"); + long offset = 5; + + using (world.Scope(parent)) + { + Entity f = world.Function("sum") + .ReturnType(I64) + .Param("a", I64) + .Param("b", I64) + .Callback(ScriptSum) + .Ctx(&offset) + .Build(); + + Assert.True(f.Parent() == parent); + } + + Entity other = world.Entity("other"); + Entity f2 = world.Function("sum") + .Parent(other) + .ReturnType(I64) + .Param("a", I64) + .Param("b", I64) + .Callback(ScriptSum) + .Build(); + + Assert.True(f2.Parent() == other); + Assert.Equal(0, world.ScriptRun(null!, "export const result = math.sum(10, 20) + other.sum(1, 2)")); + Assert.Equal(38, world.GetConstVar("result")); + } + + [Fact] + private void Method() + { + using World world = World.Create(); + + Entity m = world.Method(I64, "add") + .ReturnType(I64) + .Param("a", I64) + .Callback(ScriptSum) + .Build(); + + Assert.True(m.Parent() == I64); + Assert.Equal(0, world.ScriptRun(null!, "const v: i64 = 10\nexport const result = v.add(20)")); + Assert.Equal(30, world.GetConstVar("result")); + } + + [Fact] + private void VectorFunction() + { + using World world = World.Create(); + + Entity f = world.Function("lerp") + .ReturnType(EcsScriptVectorType) + .Param("a", EcsScriptVectorType) + .Param("b", EcsScriptVectorType) + .Param("t", F64) + .VectorCallback(EcsF32, ScriptLerpFloat) + .VectorCallback(EcsF64, ScriptLerpDouble) + .Build(); + + Assert.True(f != 0); + Assert.Equal(0, world.ScriptRun(null!, """ + struct V32(x: f32, y: f32) + struct V64(x: f64, y: f64) + const a: V32 = {10, 20} + const b: V32 = {30, 40} + const c: V64 = {20, 30} + const d: V64 = {40, 50} + export const r32: V32 = lerp(a, b, 0.5) + export const r64: V64 = lerp(c, d, 0.25) + """)); + + ecs_value_t r32 = ecs_const_var_get(world, world.Lookup("r32")); + ecs_value_t r64 = ecs_const_var_get(world, world.Lookup("r64")); + + Assert.True(r32.ptr != null); + Assert.True(r64.ptr != null); + Assert.Equal(20, ((float*)r32.ptr)[0]); + Assert.Equal(30, ((float*)r32.ptr)[1]); + Assert.Equal(25, ((double*)r64.ptr)[0]); + Assert.Equal(35, ((double*)r64.ptr)[1]); + } + + [Fact] + private void ConstVar() + { + using World world = World.Create(); + + double value = 3.1415926; + Entity v = world.ConstVar("pi", F64, &value); + Assert.True(v != 0); + + value = 0; + Assert.Equal(3.1415926, world.GetConstVar("pi")); + Assert.Equal(0, world.ScriptRun(null!, "export const result = pi * 2")); + Assert.Equal(6.2831852, world.GetConstVar("result")); + } + + [Fact] + private void VarsScope() + { + using World world = World.Create(); + + Entity parent = world.Entity("config"); + + using (world.Scope(parent)) + { + Assert.True(world.ConstVar("constant", 10).Parent() == parent); + Assert.True(world.MutVar("mutable", 20.0f).Parent() == parent); + } + + Assert.True(world.ConstVar("constant2", 30, parent).Parent() == parent); + Assert.True(world.MutVar("mutable2", 40.0f, parent).Parent() == parent); + + Assert.Equal(10, world.GetConstVar("config.constant")); + Assert.Equal(30, world.GetConstVar("config.constant2")); + Assert.Equal(20, world.GetMutVar("config.mutable")); + Assert.Equal(0, world.SetMutVar(".config.mutable", 25.0)); + Assert.Equal(0, world.SetMutVar("config.mutable2", 45.0f)); + Assert.Equal(25, world.GetMutVar("config.mutable")); + Assert.Equal(45, world.GetMutVar("config.mutable2")); + } + + [Fact] + private void MutVarReactive() + { + using World world = World.Create(); + + Entity v = world.MutVar("difficulty", 1.0f); + Assert.True(v != 0); + + Entity s = world.Script() + .Code("struct Level(value: f32)\ne { Level: {difficulty} }") + .Run(); + + Assert.True(((EcsScript*)s.GetPtr(Ecs.Script))->error == null); + + Entity e = world.Lookup("e"); + Entity level = world.Lookup("Level"); + + Assert.Equal(1, *(float*)e.GetPtr(level)); + Assert.Equal(0, world.SetMutVar("difficulty", 2.0f)); + Assert.Equal(2, *(float*)e.GetPtr(level)); + Assert.Equal(2, world.GetMutVar("difficulty")); + } + + [Fact] + private void SetMutVarInvalid() + { + using World world = World.Create(); + + int prevLogLevel = Ecs.Log.GetLevel(); + Ecs.Log.SetLevel(-4); + Assert.Equal(-1, world.SetMutVar("missing", 1)); + + world.Entity("ordinary"); + Assert.Equal(-1, world.SetMutVar("ordinary", 1)); + + world.ConstVar("constant", 1); + Assert.Equal(-1, world.SetMutVar("constant", 2)); + Assert.Equal(1, world.GetConstVar("constant")); + Ecs.Log.SetLevel(prevLogLevel); + } + + [Fact] + private void ParseEval() + { + using World world = World.Create(); + + using ParsedScript script = world.ScriptParse("test", "e {}"); + Assert.True(script.IsValid); + Assert.True(world.Lookup("e") == 0); + + Assert.Equal(0, script.Eval()); + + Entity e = world.Lookup("e"); + Assert.True(e != 0); + + e.Destruct(); + Assert.Equal(0, script.Eval()); + Assert.True(world.Lookup("e") != 0); + } + + [Fact] + private void ParseError() + { + using World world = World.Create(); + + ecs_script_eval_desc_t desc = default; + ecs_script_eval_result_t result = default; + ParsedScript script = world.ScriptParse("test", "e {", ref desc, ref result); + + Assert.False(script.IsValid); + Assert.True(result.error != null); + ecs_os_api.free_(result.error); + Assert.Equal(-1, script.Eval()); + } + + [Fact] + private void EvalError() + { + using World world = World.Create(); + + using ParsedScript script = world.ScriptParse("test", "e { Missing }"); + Assert.True(script.IsValid); + + ecs_script_eval_desc_t desc = default; + ecs_script_eval_result_t result = default; + Assert.Equal(-1, script.Eval(ref desc, ref result)); + Assert.True(result.error != null); + ecs_os_api.free_(result.error); + } + + [Fact] + private void Update() + { + using World world = World.Create(); + + Entity s = world.Script().Code("old {}").Run(); + Assert.True(((EcsScript*)s.GetPtr(Ecs.Script))->error == null); + Assert.True(world.Lookup("old") != 0); + + Assert.Equal(0, world.ScriptUpdate(s, "updated {}")); + Assert.True(world.Lookup("old") == 0); + Assert.True(world.Lookup("updated") != 0); + Assert.True(((EcsScript*)s.GetPtr(Ecs.Script))->error == null); + + int prevLogLevel = Ecs.Log.GetLevel(); + Ecs.Log.SetLevel(-4); + Assert.Equal(-1, world.ScriptUpdate(s, "updated { Missing }")); + Assert.True(((EcsScript*)s.GetPtr(Ecs.Script))->error != null); + Assert.Equal(0, world.ScriptUpdate(s, "recovered {}")); + Assert.True(((EcsScript*)s.GetPtr(Ecs.Script))->error == null); + Assert.True(world.Lookup("recovered") != 0); + Ecs.Log.SetLevel(prevLogLevel); + } +} diff --git a/src/Flecs.NET.Tests/Cpp/SingletonTests.cs b/src/Flecs.NET.Tests/Cpp/SingletonTests.cs index 6e7a357f..74db7b11 100644 --- a/src/Flecs.NET.Tests/Cpp/SingletonTests.cs +++ b/src/Flecs.NET.Tests/Cpp/SingletonTests.cs @@ -364,4 +364,48 @@ private void GetTarget() Assert.True(p == entities[i]); } } + + [Fact] + private void QuerySingletonEnumConstantOr() + { + using World world = World.Create(); + + world.Component().Add(Ecs.Singleton); + + using Query q = world.QueryBuilder() + .With(StandardEnum.Red).Or().With(StandardEnum.Blue) + .Build(); + + int count = 0; + + q.Each((Iter it, int i) => { count++; }); + + Assert.Equal(0, count); + + world.Add(StandardEnum.Green); + + q.Each((Iter it, int i) => { count++; }); + + Assert.Equal(0, count); + + world.Add(StandardEnum.Blue); + + q.Each((Iter it, int i) => + { + Assert.True(it.Src(0) == world.Component().Entity); + count++; + }); + + Assert.Equal(1, count); + + world.Add(StandardEnum.Red); + + q.Each((Iter it, int i) => + { + Assert.True(it.Src(0) == world.Component().Entity); + count++; + }); + + Assert.Equal(2, count); + } } \ No newline at end of file diff --git a/src/Flecs.NET.Tests/Cpp/SystemBuilderTests.cs b/src/Flecs.NET.Tests/Cpp/SystemBuilderTests.cs index d6c214d3..7e035e8a 100644 --- a/src/Flecs.NET.Tests/Cpp/SystemBuilderTests.cs +++ b/src/Flecs.NET.Tests/Cpp/SystemBuilderTests.cs @@ -550,4 +550,50 @@ private void NameFromRoot() Entity ns = world.Entity(".ns"); Assert.True(ns == sys.Parent()); } + + [Fact] + private void ReuseSystemBuilder() + { + using World world = World.Create(); + + Entity e1 = world.Entity().Set(new Position(10, 20)); + Entity e2 = world.Entity().Set(new Position(10, 20)).Set(new Velocity(1, 2)); + + SystemBuilder sb = world.System(); + + int count1 = 0; + System s1 = sb.Each((ref Position p) => { count1++; }); + + int count2 = 0; + System s2 = sb.With().Each((ref Position p) => { count2++; }); + + Assert.True(s1 != s2); + + world.Progress(); + + Assert.Equal(2, count1); + Assert.Equal(1, count2); + } + + [Fact] + private void KindOnSharedBuilder() + { + using World world = World.Create(); + + SystemBuilder sb = world.System(); + + System s1 = sb.Each((ref Position p) => { }); + + System s2 = sb.Kind(Ecs.PostUpdate).Each((ref Position p) => { }); + + Assert.True(s1 != s2); + + Assert.True(s1.Has(Ecs.DependsOn, Ecs.OnUpdate)); + Assert.True(s1.Has(Ecs.OnUpdate)); + + Assert.True(s2.Has(Ecs.DependsOn, Ecs.PostUpdate)); + Assert.True(s2.Has(Ecs.PostUpdate)); + Assert.False(s2.Has(Ecs.DependsOn, Ecs.OnUpdate)); + Assert.False(s2.Has(Ecs.OnUpdate)); + } } diff --git a/src/Flecs.NET.Tests/Cpp/SystemTests.cs b/src/Flecs.NET.Tests/Cpp/SystemTests.cs index 21ef76ab..f054aaf3 100644 --- a/src/Flecs.NET.Tests/Cpp/SystemTests.cs +++ b/src/Flecs.NET.Tests/Cpp/SystemTests.cs @@ -890,7 +890,7 @@ private void AddFromEachWorldHandle() Entity e3 = world.Entity().Set(new EntityWrapper(world.Entity())); world.System() - .Each((Entity e, ref EntityWrapper c) => { c.Value.Mut(e).Add(); }); + .Each((Entity e, ref EntityWrapper c) => { c.Value.Stage(e).Add(); }); world.Progress(); @@ -1006,7 +1006,7 @@ private void AddFromIterWorldHandle() Field c = it.Field(0); foreach (int i in it) - c[i].Value.Mut(it).Add(); + c[i].Value.Stage(it).Add(); } }); @@ -1036,7 +1036,7 @@ private void NewFromIter() foreach (int i in it) { it.Entity(i).Set(new EntityWrapper( - it.World().Entity().Add() + it.Stage().Entity().Add() )); } } @@ -2034,7 +2034,7 @@ private void MultiThreadSystemWithQueryEachWithWorld() .MultiThreaded() .Each((Iter it, int i, Position* p) => { - q.Iter(it.World()).Each((Velocity* v) => + q.Iter(it.Stage()).Each((Velocity* v) => { p->X += v->X; p->Y += v->Y; @@ -2143,7 +2143,7 @@ private void MultiThreadSystemWithQueryIterWithWorld() .MultiThreaded() .Each((Iter it, int i, Position* p) => { - q.Iter(it.World()).Run((Iter it) => + q.Iter(it.Stage()).Run((Iter it) => { while (it.Next()) { @@ -2584,5 +2584,89 @@ private void RunWith0SrcQuery() world.Progress(); Assert.Equal(1, count); } + + [Fact] + private void CustomPipelineWName() + { + using World world = World.Create(); + + Entity tag = world.Entity(); + + Entity pip = world.Pipeline("MyPipeline") + .With(Ecs.System) + .With(tag) + .Build(); + + Assert.Equal("MyPipeline", pip.Name()); + Assert.True(pip == world.Lookup("MyPipeline")); + + int count = 0; + + world.System() + .Kind(tag) + .Run((Iter it) => + { + while (it.Next()) + count++; + }); + + Assert.Equal(0, count); + + world.SetPipeline(pip); + + world.Progress(); + + Assert.Equal(1, count); + } + + [Fact] + private void MultithreadSystemFrameOffset() + { + using World world = World.Create(); + + world.SetThreads(4); + + for (int i = 0; i < 100; i++) + { + Entity e = world.Entity().Set(new Position(i, 0)); + if (i % 3 == 0) + e.Set(new Velocity(0, 0)); + if (i % 5 == 0) + e.Set(new Mass(0)); + } + + using Query q = world.Query(); + Assert.Equal(100, q.Count()); + + Entity[] expect = new Entity[100]; + q.Run((Iter it) => + { + while (it.Next()) + { + for (int i = 0; i < it.Count(); i++) + expect[it.FrameOffset() + i] = it.Entity(i); + } + }); + + Entity[] actual = new Entity[100]; + world.System() + .MultiThreaded() + .Run((Iter it) => + { + while (it.Next()) + { + for (int i = 0; i < it.Count(); i++) + actual[it.FrameOffset() + i] = it.Entity(i); + } + }); + + world.Progress(); + + for (int i = 0; i < 100; i++) + { + Assert.True(expect[i] != 0); + Assert.True(actual[i] == expect[i]); + } + } } } diff --git a/src/Flecs.NET.Tests/Cpp/TableTests.cs b/src/Flecs.NET.Tests/Cpp/TableTests.cs index e3c8345c..36719e3c 100644 --- a/src/Flecs.NET.Tests/Cpp/TableTests.cs +++ b/src/Flecs.NET.Tests/Cpp/TableTests.cs @@ -1,6 +1,7 @@ using System.Diagnostics.CodeAnalysis; using Flecs.NET.Core; using Xunit; +using static Flecs.NET.Bindings.flecs; namespace Flecs.NET.Tests.Cpp; @@ -625,4 +626,103 @@ private void GetTEnum() Assert.Equal(Number.Two, n[1]); Assert.Equal(Number.Three, n[2]); } + + [Fact] + private void GetEntities() + { + using World world = World.Create(); + + Entity e1 = world.Entity().Set(new Position { X = 10, Y = 20 }); + Entity e2 = world.Entity().Set(new Position { X = 20, Y = 30 }); + Entity e3 = world.Entity().Set(new Position { X = 30, Y = 40 }); + + Table table = e1.Table(); + ulong* entities = table.Entities(); + Assert.True(entities != null); + Assert.Equal(e1.Id.Value, entities[0]); + Assert.Equal(e2.Id.Value, entities[1]); + Assert.Equal(e3.Id.Value, entities[2]); + } + + [Fact] + private void GetRecords() + { + using World world = World.Create(); + + Entity parent = world.Entity(); + Entity e = world.Entity() + .ChildOf(parent) + .Set(new Position { X = 10, Y = 20 }); + + Table table = e.Table(); + ecs_table_records_t records = table.Records(); + Assert.Equal(6, records.count); + + ecs_component_record_t* cr0 = flecs_table_record_get_component(&records.array[0]); + Assert.True(cr0 != null); + Assert.Equal((ulong)world.Component(), flecs_component_get_id(cr0)); + + ecs_component_record_t* cr1 = flecs_table_record_get_component(&records.array[1]); + Assert.True(cr1 != null); + Assert.Equal(world.Pair(Ecs.ChildOf, parent).Value, flecs_component_get_id(cr1)); + } + + [Fact] + private void HasFlags() + { + using World world = World.Create(); + + Entity parent = world.Entity(); + Entity e1 = world.Entity() + .ChildOf(parent) + .Set(new Position { X = 10, Y = 20 }); + + Table table = e1.Table(); + + Assert.False(table.HasFlags(EcsTableIsComplex)); + Assert.True(table.HasFlags(EcsTableHasPairs)); + Assert.True(table.HasFlags(EcsTableHasChildOf)); + Assert.False(table.HasFlags(EcsTableHasIsA)); + } + + [Fact] + private void ClearEntities() + { + using World world = World.Create(); + + Entity e1 = world.Entity().Set(new Position { X = 10, Y = 20 }); + Entity e2 = world.Entity().Set(new Position { X = 30, Y = 40 }); + + Assert.True(e1.IsAlive()); + Assert.True(e2.IsAlive()); + + Table table = e1.Table(); + Assert.Equal(2, table.Count); + Assert.Equal(2, table.Size()); + + table.ClearEntities(); + + Assert.False(e1.IsAlive()); + Assert.False(e2.IsAlive()); + + // Table.Count is a snapshot taken when the table was obtained, so query the live count. + Assert.Equal(0, ecs_table_count(table)); + Assert.Equal(2, table.Size()); + } + + [Fact] + private void LockUnlock() + { + using World world = World.Create(); + + Entity e1 = world.Entity().Set(new Position { X = 10, Y = 20 }); + Entity e2 = world.Entity(); + + Table table = e1.Table(); + table.Lock(); + table.Unlock(); + + e2.Set(new Position { X = 20, Y = 30 }); + Assert.True(e2.Has()); + } } diff --git a/src/Flecs.NET.Tests/Cpp/WorldTests.cs b/src/Flecs.NET.Tests/Cpp/WorldTests.cs new file mode 100644 index 00000000..6f90fa2e --- /dev/null +++ b/src/Flecs.NET.Tests/Cpp/WorldTests.cs @@ -0,0 +1,349 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +using Flecs.NET.Core; +using Xunit; +using static Flecs.NET.Bindings.flecs; + +namespace Flecs.NET.Tests.Cpp; + +// The log tests replace the global os api log callback, so this collection must not run in parallel. +[CollectionDefinition("World", DisableParallelization = true)] +public class WorldCollection; + +[Collection("World")] +[SuppressMessage("ReSharper", "UnusedParameter.Local")] +public unsafe class WorldTests +{ + [Fact] + public void Shrink() + { + using World world = World.Create(); + + Entity e = world.Entity().Set(new Position { X = 10, Y = 20 }); + + world.Shrink(); + + Assert.True(e.IsAlive()); + Assert.Equal(10, e.Get().X); + } + + [Fact] + public void ExclusiveAccessSelfMutate() + { + using World world = World.Create(); + + world.ExclusiveAccessBegin(); + + Entity e = world.Entity(); + + e.Add(); + Assert.True(e.Has()); + + world.ExclusiveAccessEnd(); + } + + [Fact] + public void IdIfRegistered() + { + using World world = World.Create(); + + Assert.Equal(0ul, world.IdIfRegistered()); + Assert.Equal(0ul, world.IdIfRegistered()); + + Entity c = world.Component(); + + Assert.Equal(c.Id.Value, world.IdIfRegistered()); + } + + [Fact] + public void GetTypeInfoT() + { + using World world = World.Create(); + + Entity c = world.Component(); + + TypeInfo ti = world.TypeInfo(c); + Assert.True(ti.Handle != null); + Assert.Equal(sizeof(Position), ti.Size); + Assert.Equal(4, ti.Alignment); + Assert.Equal(c.Id.Value, ti.Component); + } + + [Fact] + public void GetTypeInfoT2() + { + using World world = World.Create(); + + TypeInfo ti = world.TypeInfo(); + Assert.True(ti.Handle != null); + Assert.Equal(sizeof(Position), ti.Size); + Assert.Equal(4, ti.Alignment); + Assert.Equal((ulong)world.Component(), ti.Component); + } + + [Fact] + public void GetTypeInfoRt() + { + using World world = World.Create(); + + Entity c = world.Component(); + Entity tgt = world.Entity(); + + TypeInfo ti = world.TypeInfo(c, tgt); + Assert.True(ti.Handle != null); + Assert.Equal(sizeof(Position), ti.Size); + Assert.Equal(4, ti.Alignment); + Assert.Equal(c.Id.Value, ti.Component); + } + + [Fact] + public void GetTypeInfoRT() + { + using World world = World.Create(); + + Entity c = world.Component(); + Entity tgt = world.Entity(); + + TypeInfo ti = world.TypeInfo(tgt); + Assert.True(ti.Handle != null); + Assert.Equal(sizeof(Position), ti.Size); + Assert.Equal(4, ti.Alignment); + Assert.Equal(c.Id.Value, ti.Component); + } + + [Fact] + public void GetTypeInfoRT2() + { + using World world = World.Create(); + + Entity c = world.Component(); + + TypeInfo ti = world.TypeInfo(); + Assert.True(ti.Handle != null); + Assert.Equal(sizeof(Position), ti.Size); + Assert.Equal(4, ti.Alignment); + Assert.Equal(c.Id.Value, ti.Component); + } + + [Fact] + public void GetTypeInfoTTag() + { + using World world = World.Create(); + + Entity c = world.Component(); + + TypeInfo ti = world.TypeInfo(c); + Assert.True(ti.Handle == null); + } + + [Fact] + public void GetTypeInfoT2Tag() + { + using World world = World.Create(); + + TypeInfo ti = world.TypeInfo(); + Assert.True(ti.Handle == null); + } + + [Fact] + public void GetTypeInfoRtTag() + { + using World world = World.Create(); + + Entity c = world.Component(); + Entity tgt = world.Entity(); + + TypeInfo ti = world.TypeInfo(c, tgt); + Assert.True(ti.Handle == null); + } + + [Fact] + public void GetTypeInfoRTTag() + { + using World world = World.Create(); + + Entity tgt = world.Entity(); + + TypeInfo ti = world.TypeInfo(tgt); + Assert.True(ti.Handle == null); + } + + [Fact] + public void GetTypeInfoRT2Tag() + { + using World world = World.Create(); + + TypeInfo ti = world.TypeInfo(); + Assert.True(ti.Handle == null); + } + + [Fact] + public void GetVersion() + { + using World world = World.Create(); + + Entity e = world.Entity(); + + Assert.Equal(0u, world.GetVersion(e)); + + e.Destruct(); + Entity recycled = world.Entity(); + + Assert.Equal(1u, world.GetVersion(recycled)); + } + + [Fact] + public void FiniWScopedComponentAddedToBuiltin() + { + using World world = World.Create(); + + world.Component("::outer::ScopedComponent"); + world.Entity().Set(new Outer.ScopedComponent { X = 10, Y = 20 }); + + Assert.True(world.Entity().Has()); + Assert.True(world.Lookup("::outer::ScopedComponent") != 0); + } + + [Fact] + public void FiniWScopedTagAddedToBuiltin() + { + using World world = World.Create(); + + world.Component("::outer::ScopedTag"); + world.Entity().Add(); + + Assert.True(world.Entity().Has()); + Assert.True(world.Lookup("::outer::ScopedTag") != 0); + } + + [Fact] + public void LogWarnCallerFileLine() + { + using LogCaptureScope _ = InstallLogCapture(); + int line = Line(); Ecs.Log.Warn("warn 10"); + Assert.Equal(-2, LogCaptureLevel); + Assert.Equal("warn 10", LogCaptureMessage); + CheckLogLocation(line); + } + + [Fact] + public void LogErrCallerFileLine() + { + using LogCaptureScope _ = InstallLogCapture(); + int line = Line(); Ecs.Log.Err("err 20"); + Assert.Equal(-3, LogCaptureLevel); + Assert.Equal("err 20", LogCaptureMessage); + CheckLogLocation(line); + } + + [Fact] + public void LogTraceCallerFileLine() + { + using LogCaptureScope _ = InstallLogCapture(); + int line = Line(); Ecs.Log.Trace("trace 30"); + Assert.Equal(0, LogCaptureLevel); + Assert.Equal("trace 30", LogCaptureMessage); + CheckLogLocation(line); + } + + [Fact] + public void LogDbgCallerFileLine() + { + using LogCaptureScope _ = InstallLogCapture(); + int line = Line(); Ecs.Log.Dbg("dbg 40"); + Assert.Equal(1, LogCaptureLevel); + Assert.Equal("dbg 40", LogCaptureMessage); + CheckLogLocation(line); + } + + [Fact] + public void LogPushCallerFileLine() + { + using LogCaptureScope _ = InstallLogCapture(); + int line = Line(); Ecs.Log.Push("push 50"); + Assert.Equal(0, LogCaptureLevel); + Assert.Equal("push 50", LogCaptureMessage); + CheckLogLocation(line); + Ecs.Log.Pop(); + } + + [Fact] + public void LogOverridePersistsAcrossWorldCreation() + { + // SetLog runs before World.Create(), so the override has to survive the first ecs_init(). + using LogCaptureScope _ = InstallLogCapture(); + + using World world1 = World.Create(); + Ecs.Log.Err("after first world"); + Assert.Equal("after first world", LogCaptureMessage); + + using World world2 = World.Create(); + Ecs.Log.Err("after second world"); + Assert.Equal("after second world", LogCaptureMessage); + } + + private static int Line([CallerLineNumber] int line = 0) + { + return line; + } + + private static LogCaptureScope InstallLogCapture() + { + // Install once; it only records into thread static fields and cannot be uninstalled through the public api. + if (!LogCaptureInstalled) + { + LogCaptureInstalled = true; + Ecs.Os.SetLog((int level, string file, int line, string message) => + { + LogCaptureLevel = level; + LogCaptureFile = file; + LogCaptureLine = line; + LogCaptureMessage = message; + }); + } + + LogCaptureScope scope = new(Ecs.Log.GetLevel(), ecs_log_enable_colors(false)); + Ecs.Log.SetLevel(4); + + LogCaptureFile = ""; + LogCaptureLine = 0; + LogCaptureLevel = 100; + LogCaptureMessage = ""; + + return scope; + } + + private readonly struct LogCaptureScope : IDisposable + { + private readonly int _level; + private readonly bool _colors; + + public LogCaptureScope(int level, bool colors) + { + _level = level; + _colors = colors; + } + + public void Dispose() + { + Ecs.Log.SetLevel(_level); + ecs_log_enable_colors(_colors); + } + } + + private static void CheckLogLocation(int expectedLine) + { + Assert.True(LogCaptureFile != ""); + Assert.True(LogCaptureLine > 0); + Assert.EndsWith("WorldTests.cs", LogCaptureFile); + Assert.Equal(expectedLine, LogCaptureLine); + } + + private static bool LogCaptureInstalled; + + [ThreadStatic] private static int LogCaptureLevel; + [ThreadStatic] private static string LogCaptureFile = ""; + [ThreadStatic] private static int LogCaptureLine; + [ThreadStatic] private static string LogCaptureMessage = ""; +} diff --git a/src/Flecs.NET.Tests/Helpers.cs b/src/Flecs.NET.Tests/Helpers.cs index 7ad6a96b..f06c8a9b 100644 --- a/src/Flecs.NET.Tests/Helpers.cs +++ b/src/Flecs.NET.Tests/Helpers.cs @@ -1,4 +1,5 @@ using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; using Flecs.NET.Core; using Xunit; @@ -11,6 +12,19 @@ public record struct Foo(float X, float Y); public record struct Position(float X, float Y); +[StructLayout(LayoutKind.Explicit)] +public struct UnionT +{ + public enum Type + { + Type1, + Type2 + } + + [FieldOffset(0)] public uint Type1; + [FieldOffset(0)] public float Type2; +} + public record struct AutoPosition(float X, float Y) : IFlecsStruct; public record struct AutoPoint(int X, int Y) : IFlecsStruct; @@ -63,6 +77,55 @@ public record struct SharedComponent(int Value); public record struct SparseComponent(int Value); +public record struct PositionDf(float X, float Y); + +public record struct PositionDfOr(float X, float Y); + +public record struct VelocityDfOr(float X, float Y); + +public record struct PositionDfIh(float X, float Y); + +public record struct PositionDfDi(float X, float Y); + +public record struct PositionSpecializedDf(float X, float Y); + +public struct InheritUnit +{ + public int Hp; +} + +public struct InheritWarrior +{ + public InheritUnit Base; + public int Dmg; +} + +public struct InheritMage +{ + public InheritUnit Base; + public int Mana; +} + +public record struct EachDontFragment(float X, float Y); + +public record struct OtherDontFragment(float X, float Y); + +public record struct TraitSparse(float X, float Y); + +public record struct TraitDontFragment(float X, float Y); + +public record struct TraitOnInstantiateOverride(float X, float Y); + +public record struct TraitOnInstantiateInherit(float X, float Y); + +public record struct TraitOnInstantiateDontInherit(float X, float Y); + +public record struct TraitNone(float X, float Y); + +public record struct TraitSparseInherit(float X, float Y); + +public record struct TraitDontFragmentInherit(float X, float Y); + public record struct UnmanagedStruct(int Value); public record struct ManagedStruct(int Value) @@ -464,3 +527,85 @@ public void InitModule(World world) } }; } + +namespace RenameNs +{ + public struct RenamedModule : IFlecsModule + { + public void InitModule(World world) + { + world.Module(".RenamedModule"); + } + } + + public struct ComponentInOldParent + { + public int Value; + } +} + +namespace RenameNsOuter +{ + namespace RenameNsInner + { + public struct RenamedModule : IFlecsModule + { + public void InitModule(World world) + { + world.Module(".RenameNsOuter.RenamedModule"); + } + } + } +} + +namespace ScopeChangeNs +{ + public struct ScopeChangeModule : IFlecsModule + { + public void InitModule(World world) + { + world.Module(".scope_change.inner"); + world.SetScope(world.Entity(".scope_change")); + } + } + + public struct ImportBeforeRename : IFlecsModule + { + public void InitModule(World world) + { + world.Import(); + world.Module(".import_before_rename"); + Assert.Equal(".import_before_rename", world.GetScope().Path()); + } + } + + public struct ImportAfterRename : IFlecsModule + { + public void InitModule(World world) + { + world.Module(".import_after_rename"); + world.Import(); + Assert.Equal(".import_after_rename", world.GetScope().Path()); + } + } + + public struct ImportNoRename : IFlecsModule + { + public void InitModule(World world) + { + world.Import(); + Assert.Equal(".ScopeChangeNs.ImportNoRename", world.GetScope().Path()); + } + } +} + +namespace Outer +{ + public struct ScopedComponent + { + public float X; + public float Y; + } + + public struct ScopedTag; +} diff --git a/src/Flecs.NET/Core/AlertBuilder.cs b/src/Flecs.NET/Core/AlertBuilder.cs index 8f753e24..d1455d41 100644 --- a/src/Flecs.NET/Core/AlertBuilder.cs +++ b/src/Flecs.NET/Core/AlertBuilder.cs @@ -86,6 +86,8 @@ public void Dispose() /// public Alert Build() { + QueryBuilder.AssertReusable(); + fixed (ecs_alert_desc_t* alertDesc = &Desc) { alertDesc->query = QueryBuilder.Desc; @@ -95,6 +97,9 @@ public Alert Build() if (entity == 0) Ecs.Error("Alert failed to init."); + // The alert query owns the contexts after initialization. + QueryBuilder.MarkBuilt(); + return new Alert(entity); } } diff --git a/src/Flecs.NET/Core/BaseField.cs b/src/Flecs.NET/Core/BaseField.cs new file mode 100644 index 00000000..8b2d5934 --- /dev/null +++ b/src/Flecs.NET/Core/BaseField.cs @@ -0,0 +1,116 @@ +using System; +using System.Runtime.CompilerServices; +using Flecs.NET.Utilities; +using static Flecs.NET.Bindings.flecs; + +namespace Flecs.NET.Core; + +/// +/// A wrapper around a field that was matched through component inheritance. +/// +/// +/// Same interface as , but uses a runtime stride so it can iterate a field whose stored +/// (derived) component is larger than . +/// +/// The base component type of the field. +public readonly unsafe struct BaseField : IEquatable> +{ + /// + /// The field pointer. + /// + public readonly void* Data; + + /// + /// The stride between elements in the field. + /// + public readonly int Stride; + + /// + /// The number of elements in the field. + /// + public readonly int Length; + + /// + /// Initializes a base field with the provided pointer, stride, and length. + /// + /// The field pointer. + /// The stride between elements in the field. + /// The number of elements in the field. + public BaseField(void* data, int stride, int length) + { + Data = data; + Stride = stride; + Length = length; + } + + /// + /// Whether the field is null. + /// + public bool IsNull => Data == null; + + /// + /// Gets a managed reference to the element at the specified index in the column. + /// + /// The element index. + public ref T this[int index] + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + Ecs.Assert(index >= 0 && index < Length, nameof(ECS_COLUMN_INDEX_OUT_OF_RANGE)); + Ecs.Assert(Data != null, nameof(ECS_COLUMN_INDEX_OUT_OF_RANGE)); + return ref Managed.GetTypeRef((byte*)Data + index * Stride); + } + } + + /// + /// Checks if two instances are equal. + /// + /// + /// + public bool Equals(BaseField other) + { + return Data == other.Data; + } + + /// + /// Checks if two instances are equal. + /// + /// + /// + public override bool Equals(object? obj) + { + return obj is BaseField field && Equals(field); + } + + /// + /// Returns the hash code of the . + /// + /// + public override int GetHashCode() + { + return ((IntPtr)Data).GetHashCode(); + } + + /// + /// Checks if two instances are equal. + /// + /// + /// + /// + public static bool operator ==(BaseField left, BaseField right) + { + return left.Equals(right); + } + + /// + /// Checks if two instances are not equal. + /// + /// + /// + /// + public static bool operator !=(BaseField left, BaseField right) + { + return !(left == right); + } +} diff --git a/src/Flecs.NET/Core/BindingContext/Functions.cs b/src/Flecs.NET/Core/BindingContext/Functions.cs index 8f2a8990..41a17e72 100644 --- a/src/Flecs.NET/Core/BindingContext/Functions.cs +++ b/src/Flecs.NET/Core/BindingContext/Functions.cs @@ -1087,4 +1087,216 @@ internal static void OnRemoveEachIterPointerCallbackPointer(ecs_iter_t* iter) } #endregion -} \ No newline at end of file + + #region Compare And Equals Hook Callbacks + + [UnmanagedCallersOnly] + internal static int OnCompareCallback(void* a, void* b, ecs_type_info_t* typeInfo) + { + TypeHooksContext* context = (TypeHooksContext*)typeInfo->hooks.binding_ctx; + return ((delegate*)context->OnCompare.Invoker)( + context, a, b, typeInfo); + } + + // A C bool is not a valid return type for an unmanaged callers only method, so the thunk returns a byte. + [UnmanagedCallersOnly] + internal static byte OnEqualsCallback(void* a, void* b, ecs_type_info_t* typeInfo) + { + TypeHooksContext* context = (TypeHooksContext*)typeInfo->hooks.binding_ctx; + bool result = ((delegate*)context->OnEquals.Invoker)( + context, a, b, typeInfo); + return result ? (byte)1 : (byte)0; + } + + internal static readonly delegate* unmanaged OnEqualsHook = + (delegate* unmanaged) + (delegate* unmanaged)&OnEqualsCallback; + + internal static int OnCompareCallbackDelegate(TypeHooksContext* context, void* a, void* b, + ecs_type_info_t* typeInfo) + { + return ((Ecs.CompareCallback)context->OnCompare.Delegate.Target!)(a, b, new TypeInfo(typeInfo)); + } + + internal static bool OnEqualsCallbackDelegate(TypeHooksContext* context, void* a, void* b, + ecs_type_info_t* typeInfo) + { + return ((Ecs.EqualsCallback)context->OnEquals.Delegate.Target!)(a, b, new TypeInfo(typeInfo)); + } + + internal static int OnCompareCallbackDelegate(TypeHooksContext* context, void* a, void* b, + ecs_type_info_t* typeInfo) + { + return ((Ecs.CompareCallback)context->OnCompare.Delegate.Target!)( + ref Managed.GetTypeRef(a), ref Managed.GetTypeRef(b), new TypeInfo(typeInfo)); + } + + internal static int OnCompareCallbackPointer(TypeHooksContext* context, void* a, void* b, + ecs_type_info_t* typeInfo) + { + return ((delegate*)context->OnCompare.Pointer)( + ref Managed.GetTypeRef(a), ref Managed.GetTypeRef(b), new TypeInfo(typeInfo)); + } + + internal static bool OnEqualsCallbackDelegate(TypeHooksContext* context, void* a, void* b, + ecs_type_info_t* typeInfo) + { + return ((Ecs.EqualsCallback)context->OnEquals.Delegate.Target!)( + ref Managed.GetTypeRef(a), ref Managed.GetTypeRef(b), new TypeInfo(typeInfo)); + } + + internal static bool OnEqualsCallbackPointer(TypeHooksContext* context, void* a, void* b, + ecs_type_info_t* typeInfo) + { + return ((delegate*)context->OnEquals.Pointer)( + ref Managed.GetTypeRef(a), ref Managed.GetTypeRef(b), new TypeInfo(typeInfo)); + } + + #endregion + + #region Script Function Callbacks + + [UnmanagedCallersOnly] + internal static void ScriptFunctionContextFree(void* context) + { + ScriptFunctionContext.Free((ScriptFunctionContext*)context); + } + + [UnmanagedCallersOnly] + internal static void ScriptFunctionCallback(ecs_function_ctx_t* ctx, int argc, ecs_value_t* argv, ecs_value_t* result) + { + ScriptFunctionContext* context = (ScriptFunctionContext*)ctx->ctx; + + if (context == null) + return; + + ecs_function_ctx_t userCtx = *ctx; + userCtx.ctx = context->Ctx; + ((Ecs.ScriptFunctionCallback)context->Callback.Delegate.Target!)( + new ScriptFunction(userCtx), new ScriptArgs(argv, argc), new ScriptValue(result)); + } + + internal static void ScriptVectorFunctionCallback(int kind, ecs_function_ctx_t* ctx, int argc, ecs_value_t* argv, + ecs_value_t* result, int elemCount) + { + ScriptFunctionContext* context = (ScriptFunctionContext*)ctx->ctx; + + if (context == null) + return; + + ecs_function_ctx_t userCtx = *ctx; + userCtx.ctx = context->Ctx; + ((Ecs.ScriptVectorFunctionCallback)context->VectorCallbacks[kind].Delegate.Target!)( + new ScriptFunction(userCtx), new ScriptArgs(argv, argc), new ScriptValue(result), elemCount); + } + + [UnmanagedCallersOnly] + internal static void ScriptVectorFunctionCallback0(ecs_function_ctx_t* ctx, int argc, ecs_value_t* argv, ecs_value_t* result, int elemCount) + { + ScriptVectorFunctionCallback(0, ctx, argc, argv, result, elemCount); + } + + [UnmanagedCallersOnly] + internal static void ScriptVectorFunctionCallback1(ecs_function_ctx_t* ctx, int argc, ecs_value_t* argv, ecs_value_t* result, int elemCount) + { + ScriptVectorFunctionCallback(1, ctx, argc, argv, result, elemCount); + } + + [UnmanagedCallersOnly] + internal static void ScriptVectorFunctionCallback2(ecs_function_ctx_t* ctx, int argc, ecs_value_t* argv, ecs_value_t* result, int elemCount) + { + ScriptVectorFunctionCallback(2, ctx, argc, argv, result, elemCount); + } + + [UnmanagedCallersOnly] + internal static void ScriptVectorFunctionCallback3(ecs_function_ctx_t* ctx, int argc, ecs_value_t* argv, ecs_value_t* result, int elemCount) + { + ScriptVectorFunctionCallback(3, ctx, argc, argv, result, elemCount); + } + + [UnmanagedCallersOnly] + internal static void ScriptVectorFunctionCallback4(ecs_function_ctx_t* ctx, int argc, ecs_value_t* argv, ecs_value_t* result, int elemCount) + { + ScriptVectorFunctionCallback(4, ctx, argc, argv, result, elemCount); + } + + [UnmanagedCallersOnly] + internal static void ScriptVectorFunctionCallback5(ecs_function_ctx_t* ctx, int argc, ecs_value_t* argv, ecs_value_t* result, int elemCount) + { + ScriptVectorFunctionCallback(5, ctx, argc, argv, result, elemCount); + } + + [UnmanagedCallersOnly] + internal static void ScriptVectorFunctionCallback6(ecs_function_ctx_t* ctx, int argc, ecs_value_t* argv, ecs_value_t* result, int elemCount) + { + ScriptVectorFunctionCallback(6, ctx, argc, argv, result, elemCount); + } + + [UnmanagedCallersOnly] + internal static void ScriptVectorFunctionCallback7(ecs_function_ctx_t* ctx, int argc, ecs_value_t* argv, ecs_value_t* result, int elemCount) + { + ScriptVectorFunctionCallback(7, ctx, argc, argv, result, elemCount); + } + + [UnmanagedCallersOnly] + internal static void ScriptVectorFunctionCallback8(ecs_function_ctx_t* ctx, int argc, ecs_value_t* argv, ecs_value_t* result, int elemCount) + { + ScriptVectorFunctionCallback(8, ctx, argc, argv, result, elemCount); + } + + [UnmanagedCallersOnly] + internal static void ScriptVectorFunctionCallback9(ecs_function_ctx_t* ctx, int argc, ecs_value_t* argv, ecs_value_t* result, int elemCount) + { + ScriptVectorFunctionCallback(9, ctx, argc, argv, result, elemCount); + } + + [UnmanagedCallersOnly] + internal static void ScriptVectorFunctionCallback10(ecs_function_ctx_t* ctx, int argc, ecs_value_t* argv, ecs_value_t* result, int elemCount) + { + ScriptVectorFunctionCallback(10, ctx, argc, argv, result, elemCount); + } + + [UnmanagedCallersOnly] + internal static void ScriptVectorFunctionCallback11(ecs_function_ctx_t* ctx, int argc, ecs_value_t* argv, ecs_value_t* result, int elemCount) + { + ScriptVectorFunctionCallback(11, ctx, argc, argv, result, elemCount); + } + + [UnmanagedCallersOnly] + internal static void ScriptVectorFunctionCallback12(ecs_function_ctx_t* ctx, int argc, ecs_value_t* argv, ecs_value_t* result, int elemCount) + { + ScriptVectorFunctionCallback(12, ctx, argc, argv, result, elemCount); + } + + [UnmanagedCallersOnly] + internal static void ScriptVectorFunctionCallback13(ecs_function_ctx_t* ctx, int argc, ecs_value_t* argv, ecs_value_t* result, int elemCount) + { + ScriptVectorFunctionCallback(13, ctx, argc, argv, result, elemCount); + } + + [UnmanagedCallersOnly] + internal static void ScriptVectorFunctionCallback14(ecs_function_ctx_t* ctx, int argc, ecs_value_t* argv, ecs_value_t* result, int elemCount) + { + ScriptVectorFunctionCallback(14, ctx, argc, argv, result, elemCount); + } + + [UnmanagedCallersOnly] + internal static void ScriptVectorFunctionCallback15(ecs_function_ctx_t* ctx, int argc, ecs_value_t* argv, ecs_value_t* result, int elemCount) + { + ScriptVectorFunctionCallback(15, ctx, argc, argv, result, elemCount); + } + + [UnmanagedCallersOnly] + internal static void ScriptVectorFunctionCallback16(ecs_function_ctx_t* ctx, int argc, ecs_value_t* argv, ecs_value_t* result, int elemCount) + { + ScriptVectorFunctionCallback(16, ctx, argc, argv, result, elemCount); + } + + [UnmanagedCallersOnly] + internal static void ScriptVectorFunctionCallback17(ecs_function_ctx_t* ctx, int argc, ecs_value_t* argv, ecs_value_t* result, int elemCount) + { + ScriptVectorFunctionCallback(17, ctx, argc, argv, result, elemCount); + } + + #endregion +} diff --git a/src/Flecs.NET/Core/BindingContext/ScriptFunctionContext.cs b/src/Flecs.NET/Core/BindingContext/ScriptFunctionContext.cs new file mode 100644 index 00000000..3d9d1aea --- /dev/null +++ b/src/Flecs.NET/Core/BindingContext/ScriptFunctionContext.cs @@ -0,0 +1,35 @@ +using System; +using Flecs.NET.Utilities; + +namespace Flecs.NET.Core.BindingContext; + +internal unsafe struct ScriptFunctionContext : IDisposable +{ + public const int VectorCallbackCount = 18; + + public Callback Callback; + public Callback* VectorCallbacks; + public void* Ctx; + + public void Dispose() + { + Callback.Dispose(); + + if (VectorCallbacks == null) + return; + + for (int i = 0; i < VectorCallbackCount; i++) + VectorCallbacks[i].Dispose(); + + Memory.Free(VectorCallbacks); + VectorCallbacks = null; + } + + public static void Free(ScriptFunctionContext* context) + { + if (context == null) + return; + context->Dispose(); + Memory.Free(context); + } +} diff --git a/src/Flecs.NET/Core/BindingContext/TypeHooksContext.cs b/src/Flecs.NET/Core/BindingContext/TypeHooksContext.cs index 3739ebef..5d137940 100644 --- a/src/Flecs.NET/Core/BindingContext/TypeHooksContext.cs +++ b/src/Flecs.NET/Core/BindingContext/TypeHooksContext.cs @@ -11,6 +11,8 @@ internal unsafe struct TypeHooksContext : IDisposable public Callback Dtor; public Callback Move; public Callback Copy; + public Callback OnCompare; + public Callback OnEquals; public Callback OnAdd; public Callback OnSet; public Callback OnRemove; @@ -24,6 +26,8 @@ public void Dispose() Dtor.Dispose(); Move.Dispose(); Copy.Dispose(); + OnCompare.Dispose(); + OnEquals.Dispose(); OnAdd.Dispose(); OnSet.Dispose(); OnRemove.Dispose(); diff --git a/src/Flecs.NET/Core/BindingContext/WorldContext.cs b/src/Flecs.NET/Core/BindingContext/WorldContext.cs index ab1aa753..63c6031c 100644 --- a/src/Flecs.NET/Core/BindingContext/WorldContext.cs +++ b/src/Flecs.NET/Core/BindingContext/WorldContext.cs @@ -18,12 +18,15 @@ internal unsafe struct WorldContext : IDisposable public NativeList RunPostFrameContexts; // Stores PostFrameContext* public NativeList WorldFinishContexts; // Stores WorldFinishContext* + public NativeString ExclusiveAccessThreadName; + public void Dispose() { UserContext.Dispose(); UserContextFree.Dispose(); AppInit.Dispose(); TypeCache.Dispose(); + ExclusiveAccessThreadName.Dispose(); foreach (nint handle in OpaqueContexts) GCHandle.FromIntPtr(handle).Free(); diff --git a/src/Flecs.NET/Core/Component.cs b/src/Flecs.NET/Core/Component.cs index 8226c8c5..bf594f11 100644 --- a/src/Flecs.NET/Core/Component.cs +++ b/src/Flecs.NET/Core/Component.cs @@ -1159,6 +1159,46 @@ public ref Component OnRemove(delegate*)&Functions.OnRemoveEachIterPointerCallbackPointer); } + /// + /// Registers a custom compare hook for this component. + /// + /// The comparison callback function. + /// Reference to self. + public ref Component OnCompare(Ecs.CompareCallback callback) + { + return ref SetOnCompareCallback(callback, (delegate*)&Functions.OnCompareCallbackDelegate); + } + + /// + /// Registers a custom compare hook for this component. + /// + /// The comparison callback function. + /// Reference to self. + public ref Component OnCompare(delegate* callback) + { + return ref SetOnCompareCallback(callback, (delegate*)&Functions.OnCompareCallbackPointer); + } + + /// + /// Registers a custom equals hook for this component. + /// + /// The equality callback function. + /// Reference to self. + public ref Component OnEquals(Ecs.EqualsCallback callback) + { + return ref SetOnEqualsCallback(callback, (delegate*)&Functions.OnEqualsCallbackDelegate); + } + + /// + /// Registers a custom equals hook for this component. + /// + /// The equality callback function. + /// Reference to self. + public ref Component OnEquals(delegate* callback) + { + return ref SetOnEqualsCallback(callback, (delegate*)&Functions.OnEqualsCallbackPointer); + } + private ref Component SetOnAddCallback(T callback, void* invoker) where T : Delegate { GetHooksAndContext(out ecs_type_hooks_t hooks, out TypeHooksContext* context); @@ -1212,4 +1252,44 @@ private ref Component SetOnRemoveCallback(void* callback, void* invo ecs_set_hooks_id(World, Id, &hooks); return ref this; } + + private ref Component SetOnCompareCallback(T callback, void* invoker) where T : Delegate + { + GetHooksAndContext(out ecs_type_hooks_t hooks, out TypeHooksContext* context); + hooks.cmp = &Functions.OnCompareCallback; + hooks.flags &= ~(ECS_TYPE_HOOK_CMP_ILLEGAL | ECS_TYPE_HOOK_EQUALS_ILLEGAL); + context->OnCompare.Set(callback, invoker); + ecs_set_hooks_id(World, Id, &hooks); + return ref this; + } + + private ref Component SetOnCompareCallback(void* callback, void* invoker) + { + GetHooksAndContext(out ecs_type_hooks_t hooks, out TypeHooksContext* context); + hooks.cmp = &Functions.OnCompareCallback; + hooks.flags &= ~(ECS_TYPE_HOOK_CMP_ILLEGAL | ECS_TYPE_HOOK_EQUALS_ILLEGAL); + context->OnCompare.Set(callback, invoker); + ecs_set_hooks_id(World, Id, &hooks); + return ref this; + } + + private ref Component SetOnEqualsCallback(T callback, void* invoker) where T : Delegate + { + GetHooksAndContext(out ecs_type_hooks_t hooks, out TypeHooksContext* context); + hooks.equals = Functions.OnEqualsHook; + hooks.flags &= ~ECS_TYPE_HOOK_EQUALS_ILLEGAL; + context->OnEquals.Set(callback, invoker); + ecs_set_hooks_id(World, Id, &hooks); + return ref this; + } + + private ref Component SetOnEqualsCallback(void* callback, void* invoker) + { + GetHooksAndContext(out ecs_type_hooks_t hooks, out TypeHooksContext* context); + hooks.equals = Functions.OnEqualsHook; + hooks.flags &= ~ECS_TYPE_HOOK_EQUALS_ILLEGAL; + context->OnEquals.Set(callback, invoker); + ecs_set_hooks_id(World, Id, &hooks); + return ref this; + } } diff --git a/src/Flecs.NET/Core/Ecs/Aliases.cs b/src/Flecs.NET/Core/Ecs/Aliases.cs index 8ecdbe41..0fab657f 100644 --- a/src/Flecs.NET/Core/Ecs/Aliases.cs +++ b/src/Flecs.NET/Core/Ecs/Aliases.cs @@ -163,6 +163,11 @@ public static partial class Ecs /// public static ref ulong TOGGLE => ref ECS_TOGGLE; + /// + /// Reference to . + /// + public static ref ulong VALUE_PAIR => ref ECS_VALUE_PAIR; + // Built-in tags /// @@ -357,6 +362,11 @@ public static partial class Ecs /// public static ref ulong CanToggle => ref EcsCanToggle; + /// + /// Reference to . + /// + public static ref ulong Singleton => ref EcsSingleton; + // OnInstantiate Trait /// @@ -365,9 +375,9 @@ public static partial class Ecs public static ref ulong OnInstantiate => ref EcsOnInstantiate; /// - /// Reference to . + /// Reference to . /// - public static ref ulong Override => ref EcsOverride; + public static ref ulong Copy => ref EcsCopy; /// /// Reference to . @@ -419,14 +429,19 @@ public static partial class Ecs public static ref ulong ChildOf => ref EcsChildOf; /// - /// Reference to . + /// Reference to . /// - public static ref ulong DependsOn => ref EcsDependsOn; + public static ref ulong Parent => ref FLECS_IDEcsParentID_; + + /// + /// Reference to . + /// + public static ref ulong Script => ref FLECS_IDEcsScriptID_; /// - /// Reference to . + /// Reference to . /// - public static ref ulong SlotOf => ref EcsSlotOf; + public static ref ulong DependsOn => ref EcsDependsOn; // Built-in identifiers diff --git a/src/Flecs.NET/Core/Ecs/Delegates.cs b/src/Flecs.NET/Core/Ecs/Delegates.cs index 9dc82f33..c0075d66 100644 --- a/src/Flecs.NET/Core/Ecs/Delegates.cs +++ b/src/Flecs.NET/Core/Ecs/Delegates.cs @@ -40,6 +40,30 @@ public static unsafe partial class Ecs /// public delegate void CopyCallback(ref T dst, ref T src, TypeInfo typeInfo); + /// + /// Compare type hook callback. Returns a negative value if a is less than b, zero if they are equal + /// and a positive value if a is greater than b. + /// + /// + public delegate int CompareCallback(ref T a, ref T b, TypeInfo typeInfo); + + /// + /// Equals type hook callback. + /// + /// + public delegate bool EqualsCallback(ref T a, ref T b, TypeInfo typeInfo); + + /// + /// Compare type hook callback for untyped components. Returns a negative value if a is less than b, zero + /// if they are equal and a positive value if a is greater than b. + /// + public delegate int CompareCallback(void* a, void* b, TypeInfo typeInfo); + + /// + /// Equals type hook callback for untyped components. + /// + public delegate bool EqualsCallback(void* a, void* b, TypeInfo typeInfo); + /// /// Each entity callback. /// @@ -124,6 +148,17 @@ public static unsafe partial class Ecs /// public delegate void GroupDeleteCallback(World world, ulong group, ref T context); + /// + /// Script function callback. + /// + public delegate void ScriptFunctionCallback(ScriptFunction ctx, ScriptArgs args, ScriptValue result); + + /// + /// Script vector function callback. + /// + public delegate void ScriptVectorFunctionCallback(ScriptFunction ctx, ScriptArgs args, ScriptValue result, + int elemCount); + /// /// Iter callback. /// diff --git a/src/Flecs.NET/Core/Ecs/Log.cs b/src/Flecs.NET/Core/Ecs/Log.cs index 656a2885..b65f6687 100644 --- a/src/Flecs.NET/Core/Ecs/Log.cs +++ b/src/Flecs.NET/Core/Ecs/Log.cs @@ -119,7 +119,7 @@ public static void Push(string message, [CallerFilePath] string file = "", [Call { using NativeString nativeMessage = (NativeString)message; using NativeString nativeFile = (NativeString)file; - ecs_log_(1, nativeFile, line, nativeMessage); + ecs_log_(0, nativeFile, line, nativeMessage); ecs_log_push_(0); } diff --git a/src/Flecs.NET/Core/Ecs/Macros.cs b/src/Flecs.NET/Core/Ecs/Macros.cs index 23f989ec..551d46cd 100644 --- a/src/Flecs.NET/Core/Ecs/Macros.cs +++ b/src/Flecs.NET/Core/Ecs/Macros.cs @@ -177,14 +177,26 @@ public static ulong PairSecond(ecs_world_t* world, ulong pair) } /// - /// Tests whether an id is a pair. + /// Creates a value pair out of a relationship and a value. + /// + /// + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong ValuePair(ulong relation, ulong value) + { + return ECS_VALUE_PAIR | EntityCombine(value, relation); + } + + /// + /// Tests whether an id is a pair or a value pair. /// /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsPair(ulong pair) { - return (pair & ECS_ID_FLAGS_MASK) == ECS_PAIR; + return (pair & ECS_PAIR) != 0; } /// @@ -252,7 +264,7 @@ public static void TableLock(ecs_world_t* world, ecs_table_t* table) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void TableLock(ecs_iter_t* iter) { - ecs_table_lock(iter->real_world, iter->table); + ecs_table_lock(iter->stage, iter->table); } /// @@ -274,7 +286,7 @@ public static void TableUnlock(ecs_world_t* world, ecs_table_t* table) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void TableUnlock(ecs_iter_t* iter) { - ecs_table_unlock(iter->real_world, iter->table); + ecs_table_unlock(iter->stage, iter->table); } /// diff --git a/src/Flecs.NET/Core/Ecs/OsApi.cs b/src/Flecs.NET/Core/Ecs/OsApi.cs index 5b33c78a..1580fd4d 100644 --- a/src/Flecs.NET/Core/Ecs/OsApi.cs +++ b/src/Flecs.NET/Core/Ecs/OsApi.cs @@ -9,11 +9,10 @@ public static unsafe partial class Ecs { /// /// Static class for overriding the os api. + /// The setters are not thread-safe and should be called at startup, before logging starts. /// public static class Os { - private static bool _initialized; - internal static OsApiContext Context; /// @@ -45,33 +44,33 @@ public static class Os public static bool OverrideTracePop { get; set; } = true; /// - /// Override the default os api. + /// Applies the default abort callback and the configured overrides to the native os api. /// internal static void OverrideOsApi() { - if (_initialized) - return; + if (OverrideAbort && Context.Abort == default) + SetAbort(&DefaultAbort); - ecs_os_init(); + ApplyOsApi(); + } + /// + /// Reapplies the overrides to the native os api. Flecs installs its default os api on the + /// first ecs_init(), which overwrites them, so this has to run after world creation. + /// + internal static void ApplyOsApi() + { if (OverrideAbort) - { - if (Context.Abort == default) - SetAbort(&DefaultAbort); - ecs_os_api.abort_ = &Functions.AbortCallback; - } - - if (OverrideLog) - ecs_os_api.log_ = Context.Log == default ? ecs_os_api.log_ : &Functions.LogCallback; - if (OverrideTracePush) - ecs_os_api.perf_trace_push_ = Context.TracePush == default ? ecs_os_api.perf_trace_push_ : &Functions.TracePushCallback; + if (OverrideLog && Context.Log != default) + ecs_os_api.log_ = &Functions.LogCallback; - if (OverrideTracePop) - ecs_os_api.perf_trace_pop_ = Context.TracePop == default ? ecs_os_api.perf_trace_pop_ : &Functions.TracePopCallback; + if (OverrideTracePush && Context.TracePush != default) + ecs_os_api.perf_trace_push_ = &Functions.TracePushCallback; - _initialized = true; + if (OverrideTracePop && Context.TracePop != default) + ecs_os_api.perf_trace_pop_ = &Functions.TracePopCallback; } /// @@ -81,6 +80,7 @@ internal static void OverrideOsApi() public static void SetAbort(Action callback) { Context.Abort.Set(callback, (delegate*)&Functions.AbortCallbackDelegate); + ApplyOsApi(); } /// @@ -90,6 +90,7 @@ public static void SetAbort(Action callback) public static void SetAbort(delegate* callback) { Context.Abort.Set(callback, (delegate*)&Functions.AbortCallbackPointer); + ApplyOsApi(); } /// @@ -99,6 +100,7 @@ public static void SetAbort(delegate* callback) public static void SetLog(LogCallback callback) { Context.Log.Set(callback, (delegate*)&Functions.LogCallbackDelegate); + ApplyOsApi(); } /// @@ -108,6 +110,7 @@ public static void SetLog(LogCallback callback) public static void SetLog(delegate* callback) { Context.Log.Set(callback, (delegate*)&Functions.LogCallbackPointer); + ApplyOsApi(); } /// @@ -117,6 +120,7 @@ public static void SetLog(delegate* callback) public static void SetTracePush(TraceCallback callback) { Context.TracePush.Set(callback, (delegate*)&Functions.TracePushCallbackDelegate); + ApplyOsApi(); } /// @@ -126,6 +130,7 @@ public static void SetTracePush(TraceCallback callback) public static void SetTracePush(delegate* callback) { Context.TracePush.Set(callback, (delegate*)&Functions.TracePushCallbackPointer); + ApplyOsApi(); } /// @@ -135,6 +140,7 @@ public static void SetTracePush(delegate* callback) public static void SetTracePop(TraceCallback callback) { Context.TracePop.Set(callback, (delegate*)&Functions.TracePopCallbackDelegate); + ApplyOsApi(); } /// @@ -144,6 +150,7 @@ public static void SetTracePop(TraceCallback callback) public static void SetTracePop(delegate* callback) { Context.TracePop.Set(callback, (delegate*)&Functions.TracePopCallbackPointer); + ApplyOsApi(); } private static void DefaultAbort() diff --git a/src/Flecs.NET/Core/Entity.cs b/src/Flecs.NET/Core/Entity.cs index 6c18eb4d..0dfca95f 100644 --- a/src/Flecs.NET/Core/Entity.cs +++ b/src/Flecs.NET/Core/Entity.cs @@ -72,7 +72,7 @@ public Entity(ecs_world_t* world, EcsParent parent, string? name = null) /// public Entity(ecs_world_t* world) { - if (ecs_get_scope(world) == 0 && ecs_get_with(world) == 0) + if (ecs_get_scope(world) == 0) { _id = new Id(world, ecs_new(world)); } @@ -316,7 +316,7 @@ public Table Table() /// public Table Range() { - ecs_record_t* r = ecs_record_find(World, Id); + ecs_record_t* r = flecs_entities_get(ecs_get_world(World), Id); return r != null ? new Table(World, r->table, Ecs.RecordToRow(r->row), 1) : new Table(); } @@ -326,16 +326,7 @@ public Table Range() /// public void Each(Ecs.EachIdCallback func) { - ecs_type_t* type = ecs_get_type(World, Id); - - if (type == null) - return; - - ulong* ids = type->array; - int count = type->count; - - for (int i = 0; i < count; i++) - func(new Id(World, ids[i])); + EachId(0, false, func); } /// @@ -345,30 +336,56 @@ public void Each(Ecs.EachIdCallback func) /// /// public void Each(ulong first, ulong second, Ecs.EachIdCallback func) + { + EachId(second != 0 ? Ecs.Pair(first, second) : first, true, func); + } + + private void EachId(ulong pattern, bool match, Ecs.EachIdCallback func) { ecs_world_t* realWorld = ecs_get_world(World); ecs_table_t* table = ecs_get_table(World, Id); + ecs_type_t* type = table != null ? ecs_table_get_type(table) : null; - if (table == null) - return; + if (type != null) + { + ulong* ids = type->array; - ecs_type_t* type = ecs_table_get_type(table); + if (match) + { + int cur = 0; - if (type == null) - return; + while (-1 != (cur = ecs_search_offset(realWorld, table, cur, pattern, null))) + { + func(new Id(World, ids[cur])); + cur++; + } + } + else + { + int count = type->count; - ulong pattern = first; + for (int i = 0; i < count; i++) + func(new Id(World, ids[i])); + } + } - if (second != 0) - pattern = Ecs.Pair(first, second); + ecs_record_t* record = flecs_entities_get(realWorld, Id); - int cur = 0; - ulong* ids = type->array; + if (record == null || (record->row & EcsEntityHasDontFragment) == 0) + return; - while (-1 != (cur = ecs_search_offset(realWorld, table, cur, pattern, null))) + for (ecs_component_record_t* cr = flecs_component_dont_fragment_first(realWorld); cr != null; + cr = flecs_component_dont_fragment_next(cr)) { - func(new Id(World, ids[cur])); - cur++; + ulong id = flecs_component_get_id(cr); + + if (ecs_id_is_wildcard(id) || (match && !ecs_id_match(id, pattern))) + continue; + + ecs_sparse_t* sparse = flecs_component_get_sparse(cr); + + if (sparse != null && flecs_sparse_has(sparse, Id)) + func(new Id(World, id)); } } @@ -1221,7 +1238,7 @@ public Entity Clone(bool cloneValue = true, ulong dstId = 0) /// /// /// - public Entity Mut(ref World stage) + public Entity Stage(ref World stage) { Ecs.Assert(!stage.IsReadOnly(), "Cannot use readonly world/stage to create mutable handle"); return new Entity(Id).SetStage(stage); @@ -1232,11 +1249,11 @@ public Entity Mut(ref World stage) /// /// /// - public Entity Mut(ref Iter it) + public Entity Stage(ref Iter it) { - Ecs.Assert(!it.World().IsReadOnly(), + Ecs.Assert(!it.Stage().IsReadOnly(), "Cannot use iterator created for readonly world/stage to create mutable handle"); - return new Entity(Id).SetStage(it.World()); + return new Entity(Id).SetStage(it.Stage()); } /// @@ -1244,7 +1261,7 @@ public Entity Mut(ref Iter it) /// /// /// - public Entity Mut(ref Entity entity) + public Entity Stage(ref Entity entity) { Ecs.Assert(!entity.CsWorld().IsReadOnly(), "Cannot use entity created for readonly world/stage to create mutable handle"); @@ -1256,9 +1273,9 @@ public Entity Mut(ref Entity entity) /// /// /// - public Entity Mut(World stage) + public Entity Stage(World stage) { - return Mut(ref stage); + return Stage(ref stage); } /// @@ -1266,9 +1283,9 @@ public Entity Mut(World stage) /// /// /// - public Entity Mut(Iter it) + public Entity Stage(Iter it) { - return Mut(ref it); + return Stage(ref it); } /// @@ -1276,9 +1293,23 @@ public Entity Mut(Iter it) /// /// /// - public Entity Mut(Entity entity) + public Entity Stage(Entity entity) + { + return Stage(ref entity); + } + + /// + /// Return mutable entity handle for the default stage. If the entity handle already uses a + /// stage, the returned handle uses the same stage. Otherwise the returned handle uses the + /// default stage (stage 0) of the world. + /// + /// + public Entity Stage() { - return Mut(ref entity); + if (ecs_is_stage(World)) + return new Entity(Id).SetStage(World); + + return new Entity(Id).SetStage(ecs_get_stage(World, 0)); } private Entity SetStage(ecs_world_t* stage) @@ -1875,47 +1906,6 @@ public ref Entity DependsOn(T value) where T : Enum return ref DependsOn(Type.Id(World, value)); } - /// - /// Shortcut for Add(EcsSlotOf, entity). - /// - /// - /// - public ref Entity SlotOf(ulong id) - { - return ref Add(EcsSlotOf, id); - } - - /// - /// Shortcut for Add(EcsSlotOf, entity). - /// - /// - /// - public ref Entity SlotOf() - { - return ref Add(EcsSlotOf, Type.Id(World)); - } - - /// - /// Shortcut for Add(EcsSlotOf, entity). - /// - /// - /// - /// - public ref Entity SlotOf(T value) where T : Enum - { - return ref SlotOf(Type.Id(World, value)); - } - - /// - /// Shortcut for Add(EcsSlotOf, Target(EcsChildOf)). - /// - /// - public ref Entity Slot() - { - Ecs.Assert(ecs_get_target(World, Id, EcsChildOf, 0) != 0, "Add ChildOf pair before using slot()"); - return ref SlotOf(Target(EcsChildOf)); - } - /// /// Remove an entity from entity. /// @@ -2634,82 +2624,6 @@ public ref Entity SetSecond(ulong first, in TSecond data) return ref SetInternal(Ecs.PairSecond(first, World), in data); } - /// - /// Entities created in function will have the current entity. - /// - /// The callback. - /// Reference to self. - public ref Entity With(Action callback) - { - ulong prev = ecs_set_with(World, Id); - callback(); - ecs_set_with(World, prev); - return ref this; - } - - /// - /// Entities created in function will have (first, this). - /// - /// The id. - /// The callback. - /// Reference to self. - public ref Entity With(ulong first, Action callback) - { - ulong prev = ecs_set_with(World, Ecs.Pair(first, Id)); - callback(); - ecs_set_with(World, prev); - return ref this; - } - - /// - /// Entities created in function will have (TFirst, this). - /// - /// The callback. - /// The component id. - /// Reference to self. - public ref Entity With(Action callback) - { - return ref With(Type.Id(World), callback); - } - - /// - /// Entities created in function will have the current entity. - /// - /// The callback. - /// Reference to self. - public ref Entity With(Ecs.WorldCallback callback) - { - ulong prev = ecs_set_with(World, Id); - callback(World); - ecs_set_with(World, prev); - return ref this; - } - - /// - /// Entities created in function will have (first, this). - /// - /// The id. - /// The callback. - /// Reference to self. - public ref Entity With(ulong first, Ecs.WorldCallback callback) - { - ulong prev = ecs_set_with(World, Ecs.Pair(first, Id)); - callback(World); - ecs_set_with(World, prev); - return ref this; - } - - /// - /// Entities created in function will have (TFirst, this). - /// - /// The callback. - /// The component id. - /// Reference to self. - public ref Entity With(Ecs.WorldCallback callback) - { - return ref With(Type.Id(World), callback); - } - /// /// The function will be run with the scope set to the current entity. /// @@ -3511,6 +3425,17 @@ public void Destruct() ecs_delete(World, Id); } + /// + /// Set child order. Changes the order of children as returned by . + /// Only applicable to entities with the trait. + /// + /// Array of child entity ids in the desired order. + /// Number of children in the array. + public void SetChildOrder(ulong* children, int childCount) + { + ecs_set_child_order(World, Id, children, childCount); + } + /// /// Deserialize entity to JSON. /// diff --git a/src/Flecs.NET/Core/FunctionBuilder.cs b/src/Flecs.NET/Core/FunctionBuilder.cs new file mode 100644 index 00000000..41199d6b --- /dev/null +++ b/src/Flecs.NET/Core/FunctionBuilder.cs @@ -0,0 +1,315 @@ +using System; +using Flecs.NET.Core.BindingContext; +using Flecs.NET.Utilities; +using static Flecs.NET.Bindings.flecs; + +namespace Flecs.NET.Core; + +/// +/// A wrapper around . Used to create script functions and methods. +/// +public unsafe struct FunctionBuilder : IEquatable, IDisposable +{ + private const int MaxParams = 16; + + private ecs_world_t* _world; + private ecs_function_desc_t _desc; + private int _paramCount; + private bool _isMethod; + + private NativeString _name; + private NativeString* _paramNames; + private ScriptFunctionContext* _context; + + /// + /// Reference to the world. + /// + public ref ecs_world_t* World => ref _world; + + /// + /// Reference to the desc. + /// + public ref ecs_function_desc_t Desc => ref _desc; + + /// + /// Creates a with the provided world and function name. + /// + /// The world. + /// The function name. + /// The function parent. Defaults to the current scope. + /// Whether the function is a method. + public FunctionBuilder(ecs_world_t* world, string name, ulong parent = 0, bool isMethod = false) + { + _world = world; + _desc = default; + _paramCount = 0; + _isMethod = isMethod; + _name = (NativeString)name; + _paramNames = Memory.AllocZeroed(MaxParams); + _context = Memory.AllocZeroed(1); + + Desc.name = _name; + Desc.parent = parent != 0 ? parent : ecs_get_scope(world); + } + + /// + /// Disposes the function builder. This should be called if the function builder + /// will be discarded and .Build() isn't called. + /// + public void Dispose() + { + _name.Dispose(); + _name = default; + + if (_paramNames != null) + { + for (int i = 0; i < _paramCount; i++) + _paramNames[i].Dispose(); + + Memory.Free(_paramNames); + _paramNames = null; + } + + _paramCount = 0; + + if (_context != null) + ScriptFunctionContext.Free(_context); + _context = null; + } + + /// + /// Set the function parent. + /// + /// The parent entity. + /// Reference to self. + public ref FunctionBuilder Parent(ulong value) + { + Desc.parent = value; + return ref this; + } + + /// + /// Set the function return type. + /// + /// The return type entity. + /// Reference to self. + public ref FunctionBuilder ReturnType(ulong type) + { + Desc.return_type = type; + return ref this; + } + + /// + /// Set the function return type. + /// + /// The return type. + /// Reference to self. + public ref FunctionBuilder ReturnType() + { + return ref ReturnType(Type.Id(World)); + } + + /// + /// Add a function parameter. + /// + /// The parameter name. + /// The parameter type entity. + /// Reference to self. + public ref FunctionBuilder Param(string name, ulong type) + { + Ecs.Assert(_paramCount < MaxParams - (_isMethod ? 1 : 0), "Too many function parameters"); + + NativeString nativeName = (NativeString)name; + _paramNames[_paramCount] = nativeName; + + Desc.@params[_paramCount] = new ecs_script_parameter_t { name = nativeName, type = type }; + _paramCount++; + + return ref this; + } + + /// + /// Add a function parameter. + /// + /// The parameter name. + /// The parameter type. + /// Reference to self. + public ref FunctionBuilder Param(string name) + { + return ref Param(name, Type.Id(World)); + } + + /// + /// Set the function callback. + /// + /// The callback. + /// Reference to self. + public ref FunctionBuilder Callback(Ecs.ScriptFunctionCallback value) + { + _context->Callback.Set(value, null); + Desc.callback = &Functions.ScriptFunctionCallback; + return ref this; + } + + /// + /// Set the vector function callback for the provided element kind. + /// + /// The primitive element kind. + /// The callback. + /// Reference to self. + public ref FunctionBuilder VectorCallback(ecs_primitive_kind_t kind, Ecs.ScriptVectorFunctionCallback value) + { + int index = (int)kind; + Ecs.Assert(index > 0 && index < ScriptFunctionContext.VectorCallbackCount, "Invalid vector element kind"); + + EnsureVectorCallbacks(); + _context->VectorCallbacks[index].Set(value, null); + SetVectorCallback(index, VectorThunk(index)); + return ref this; + } + + /// + /// Set the vector function callback for the provided element type. + /// + /// The primitive element type entity. + /// The callback. + /// Reference to self. + public ref FunctionBuilder VectorCallback(ulong type, Ecs.ScriptVectorFunctionCallback value) + { + EcsPrimitive* primitive = (EcsPrimitive*)ecs_get_id(World, type, FLECS_IDEcsPrimitiveID_); + Ecs.Assert(primitive != null, "Vector element type is not a primitive"); + return ref VectorCallback(primitive->kind, value); + } + + /// + /// Set the user context that is passed to the function callback. + /// + /// The user context. + /// Reference to self. + public ref FunctionBuilder Ctx(void* value) + { + _context->Ctx = value; + return ref this; + } + + /// + /// Build the function. + /// + /// The function entity. + public Entity Build() + { + ulong component = _isMethod ? FLECS_IDEcsScriptMethodID_ : FLECS_IDEcsScriptFunctionID_; + + ulong result; + fixed (ecs_function_desc_t* desc = &Desc) + result = _isMethod ? ecs_method_init(World, desc) : ecs_function_init(World, desc); + + // The binding context owns the delegate so flecs frees it; ctx->ctx is the raw pointer flecs passes back. + if (result != 0 && _context != null) + { + ecs_script_function_t* function = (ecs_script_function_t*)ecs_ensure_id( + World, result, component, sizeof(ecs_script_function_t)); + + function->ctx = _context; + function->binding_ctx = _context; + function->binding_ctx_free = &Functions.ScriptFunctionContextFree; + _context = null; + } + + Entity entity = new Entity(World, result); + Dispose(); + return entity; + } + + private void EnsureVectorCallbacks() + { + if (_context->VectorCallbacks != null) + return; + + _context->VectorCallbacks = Memory.AllocZeroed(ScriptFunctionContext.VectorCallbackCount); + } + + private void SetVectorCallback(int index, + delegate* unmanaged value) + { + // The inline array cannot be indexed directly because function pointer types cannot be type arguments. + fixed (ecs_function_desc_t* desc = &_desc) + ((delegate* unmanaged*)&desc->vector_callbacks)[index] = value; + } + + private static delegate* unmanaged VectorThunk(int index) + { + return index switch + { + 1 => &Functions.ScriptVectorFunctionCallback1, + 2 => &Functions.ScriptVectorFunctionCallback2, + 3 => &Functions.ScriptVectorFunctionCallback3, + 4 => &Functions.ScriptVectorFunctionCallback4, + 5 => &Functions.ScriptVectorFunctionCallback5, + 6 => &Functions.ScriptVectorFunctionCallback6, + 7 => &Functions.ScriptVectorFunctionCallback7, + 8 => &Functions.ScriptVectorFunctionCallback8, + 9 => &Functions.ScriptVectorFunctionCallback9, + 10 => &Functions.ScriptVectorFunctionCallback10, + 11 => &Functions.ScriptVectorFunctionCallback11, + 12 => &Functions.ScriptVectorFunctionCallback12, + 13 => &Functions.ScriptVectorFunctionCallback13, + 14 => &Functions.ScriptVectorFunctionCallback14, + 15 => &Functions.ScriptVectorFunctionCallback15, + 16 => &Functions.ScriptVectorFunctionCallback16, + 17 => &Functions.ScriptVectorFunctionCallback17, + _ => &Functions.ScriptVectorFunctionCallback0 + }; + } + + /// + /// Checks if two instances are equal. + /// + /// + /// + public bool Equals(FunctionBuilder other) + { + return Desc == other.Desc; + } + + /// + /// Checks if two instances are equal. + /// + /// + /// + public override bool Equals(object? obj) + { + return obj is FunctionBuilder other && Equals(other); + } + + /// + /// Returns the hash code for the . + /// + /// + public override int GetHashCode() + { + return Desc.GetHashCode(); + } + + /// + /// Checks if two instances are equal. + /// + /// + /// + /// + public static bool operator ==(FunctionBuilder left, FunctionBuilder right) + { + return left.Equals(right); + } + + /// + /// Checks if two instances are not equal. + /// + /// + /// + /// + public static bool operator !=(FunctionBuilder left, FunctionBuilder right) + { + return !(left == right); + } +} diff --git a/src/Flecs.NET/Core/IEntity.cs b/src/Flecs.NET/Core/IEntity.cs index 0de2147c..f9998d75 100644 --- a/src/Flecs.NET/Core/IEntity.cs +++ b/src/Flecs.NET/Core/IEntity.cs @@ -297,23 +297,26 @@ public unsafe interface IEntity : IId /// public Entity Clone(bool cloneValue = true, ulong dstId = 0); - /// - public Entity Mut(ref World stage); + /// + public Entity Stage(ref World stage); - /// - public Entity Mut(ref Iter it); + /// + public Entity Stage(ref Iter it); - /// - public Entity Mut(ref Entity entity); + /// + public Entity Stage(ref Entity entity); - /// - public Entity Mut(World stage); + /// + public Entity Stage(World stage); - /// - public Entity Mut(Iter it); + /// + public Entity Stage(Iter it); - /// - public Entity Mut(Entity entity); + /// + public Entity Stage(Entity entity); + + /// + public Entity Stage(); /// public string ToJson(in EntityToJsonDesc desc); @@ -464,19 +467,6 @@ public unsafe interface IEntity : IId /// public ref TEntity DependsOn(T value) where T : Enum; - - /// - public ref TEntity SlotOf(ulong id); - - /// - public ref TEntity SlotOf(); - - /// - public ref TEntity SlotOf(T value) where T : Enum; - - /// - public ref TEntity Slot(); - /// public ref TEntity Remove(ulong id); @@ -662,25 +652,6 @@ public unsafe interface IEntity : IId /// public ref TEntity SetSecond(ulong first, in TSecond data); - - /// - public ref TEntity With(Action callback); - - /// - public ref TEntity With(ulong first, Action callback); - - /// - public ref TEntity With(Action callback); - - /// - public ref TEntity With(Ecs.WorldCallback callback); - - /// - public ref TEntity With(ulong first, Ecs.WorldCallback callback); - - /// - public ref TEntity With(Ecs.WorldCallback callback); - /// public ref TEntity Scope(Action callback); diff --git a/src/Flecs.NET/Core/Id.cs b/src/Flecs.NET/Core/Id.cs index 4f510474..98aeaf39 100644 --- a/src/Flecs.NET/Core/Id.cs +++ b/src/Flecs.NET/Core/Id.cs @@ -105,12 +105,21 @@ public Id(Entity first, Entity second) } /// - /// Test if id is pair. (has first, second) + /// Test if id is pair. (has first, second, or first, value) /// /// public bool IsPair() { - return (Value & ECS_ID_FLAGS_MASK) == ECS_PAIR; + return (Value & ECS_PAIR) != 0; + } + + /// + /// Test if id is a value pair. (has first, value) + /// + /// + public bool IsValuePair() + { + return (Value & ECS_ID_FLAGS_MASK) == ECS_VALUE_PAIR; } /// @@ -252,7 +261,7 @@ public Entity First() public Entity Second() { ulong entity = Ecs.PairSecond(Value); - return World == null ? new Entity(entity) : new Entity(World, ecs_get_alive(World, entity)); + return World == null || IsValuePair() ? new Entity(entity) : new Entity(World, ecs_get_alive(World, entity)); } /// diff --git a/src/Flecs.NET/Core/Invoker.cs b/src/Flecs.NET/Core/Invoker.cs index 2e1a2b15..13b9d18e 100644 --- a/src/Flecs.NET/Core/Invoker.cs +++ b/src/Flecs.NET/Core/Invoker.cs @@ -27,8 +27,8 @@ public static void Callback(Iter it) /// public static void Iter(ecs_iter_t* iter, Ecs.IterCallback callback) { - Ecs.TableLock(iter->world, iter->table); - try { callback(new Iter(iter)); } finally { Ecs.TableUnlock(iter->world, iter->table); } + Ecs.TableLock(iter->stage, iter->table); + try { callback(new Iter(iter)); } finally { Ecs.TableUnlock(iter->stage, iter->table); } } /// @@ -40,11 +40,11 @@ public static void Each(ecs_iter_t* iter, Ecs.EachEntityCallback callback) { Ecs.Assert(iter->entities != null, "No entities returned, use Iter() or Each() without the entity argument instead."); - Ecs.TableLock(iter->world, iter->table); + Ecs.TableLock(iter->stage, iter->table); try { for (int i = 0; i < iter->count; i++) - callback(new Entity(iter->world, iter->entities[i])); - } finally { Ecs.TableUnlock(iter->world, iter->table); } + callback(new Entity(iter->stage, iter->entities[i])); + } finally { Ecs.TableUnlock(iter->stage, iter->table); } } /// @@ -54,12 +54,12 @@ public static void Each(ecs_iter_t* iter, Ecs.EachEntityCallback callback) /// public static void Each(ecs_iter_t* iter, Ecs.EachIterCallback callback) { - Ecs.TableLock(iter->world, iter->table); + Ecs.TableLock(iter->stage, iter->table); try { int count = iter->count == 0 && iter->table == null ? 1 : iter->count; for (int i = 0; i < count; i++) callback(new Iter(iter), i); - } finally { Ecs.TableUnlock(iter->world, iter->table); } + } finally { Ecs.TableUnlock(iter->stage, iter->table); } } /// @@ -91,7 +91,7 @@ public static void Run(ecs_iter_t* iter, Ecs.RunDelegateCallback callback) /// public static void Observe(ecs_iter_t* iter, Ecs.ObserveEntityCallback callback) { - callback(new Entity(iter->world, ecs_field_src(iter, 0))); + callback(new Entity(iter->stage, ecs_field_src(iter, 0))); } /// @@ -101,7 +101,7 @@ public static void Observe(ecs_iter_t* iter, Ecs.ObserveEntityCallback callback) /// public static void Observe(ecs_iter_t* iter, delegate* callback) { - callback(new Entity(iter->world, ecs_field_src(iter, 0))); + callback(new Entity(iter->stage, ecs_field_src(iter, 0))); } /// @@ -161,7 +161,7 @@ public static void Observe(ecs_iter_t* iter, delegate* callback) public static void Observe(ecs_iter_t* iter, Ecs.ObserveEntityRefCallback callback) { Ecs.Assert(iter->param != null, "Entity observer invoked without event payload"); - callback(new Entity(iter->world, ecs_field_src(iter, 0)), ref Managed.GetTypeRef(iter->param)); + callback(new Entity(iter->stage, ecs_field_src(iter, 0)), ref Managed.GetTypeRef(iter->param)); } /// @@ -173,7 +173,7 @@ public static void Observe(ecs_iter_t* iter, Ecs.ObserveEntityRefCallback public static void Observe(ecs_iter_t* iter, delegate* callback) { Ecs.Assert(iter->param != null, "Entity observer invoked without event payload"); - callback(new Entity(iter->world, ecs_field_src(iter, 0)), ref Managed.GetTypeRef(iter->param)); + callback(new Entity(iter->stage, ecs_field_src(iter, 0)), ref Managed.GetTypeRef(iter->param)); } /// @@ -185,7 +185,7 @@ public static void Observe(ecs_iter_t* iter, delegate* c public static void Observe(ecs_iter_t* iter, Ecs.ObserveEntityPointerCallback callback) { Ecs.Assert(iter->param != null, "Entity observer invoked without event payload"); - callback(new Entity(iter->world, ecs_field_src(iter, 0)), (T*)iter->param); + callback(new Entity(iter->stage, ecs_field_src(iter, 0)), (T*)iter->param); } /// @@ -197,7 +197,7 @@ public static void Observe(ecs_iter_t* iter, Ecs.ObserveEntityPointerCallback public static void Observe(ecs_iter_t* iter, delegate* callback) { Ecs.Assert(iter->param != null, "Entity observer invoked without event payload"); - callback(new Entity(iter->world, ecs_field_src(iter, 0)), (T*)iter->param); + callback(new Entity(iter->stage, ecs_field_src(iter, 0)), (T*)iter->param); } /// @@ -207,8 +207,8 @@ public static void Observe(ecs_iter_t* iter, delegate* call /// public static void Iter(ecs_iter_t* iter, delegate* callback) { - Ecs.TableLock(iter->world, iter->table); - try { callback(new Iter(iter)); } finally { Ecs.TableUnlock(iter->world, iter->table); } + Ecs.TableLock(iter->stage, iter->table); + try { callback(new Iter(iter)); } finally { Ecs.TableUnlock(iter->stage, iter->table); } } /// @@ -220,11 +220,11 @@ public static void Each(ecs_iter_t* iter, delegate* callback) { Ecs.Assert(iter->count > 0, "No entities returned, use Iter() or Each() without the entity argument instead."); - Ecs.TableLock(iter->world, iter->table); + Ecs.TableLock(iter->stage, iter->table); try { for (int i = 0; i < iter->count; i++) - callback(new Entity(iter->world, iter->entities[i])); - } finally { Ecs.TableUnlock(iter->world, iter->table); } + callback(new Entity(iter->stage, iter->entities[i])); + } finally { Ecs.TableUnlock(iter->stage, iter->table); } } /// @@ -234,12 +234,12 @@ public static void Each(ecs_iter_t* iter, delegate* callback) /// public static void Each(ecs_iter_t* iter, delegate* callback) { - Ecs.TableLock(iter->world, iter->table); + Ecs.TableLock(iter->stage, iter->table); try { int count = iter->count == 0 && iter->table == null ? 1 : iter->count; for (int i = 0; i < count; i++) callback(new Iter(iter), i); - } finally { Ecs.TableUnlock(iter->world, iter->table); } + } finally { Ecs.TableUnlock(iter->stage, iter->table); } } /// diff --git a/src/Flecs.NET/Core/Iter.cs b/src/Flecs.NET/Core/Iter.cs index 868461c1..fc745754 100644 --- a/src/Flecs.NET/Core/Iter.cs +++ b/src/Flecs.NET/Core/Iter.cs @@ -45,7 +45,7 @@ public void Dispose() /// public Entity System() { - return new Entity(Handle->world, Handle->system); + return new Entity(Handle->stage, Handle->system); } /// @@ -54,7 +54,7 @@ public Entity System() /// public Entity Event() { - return new Entity(Handle->world, Handle->@event); + return new Entity(Handle->stage, Handle->@event); } /// @@ -63,11 +63,11 @@ public Entity Event() /// public Id EventId() { - return new Id(Handle->world, Handle->event_id); + return new Id(Handle->stage, Handle->event_id); } /// - /// Returns staged C# world. + /// Returns the actual C# world. /// /// public World World() @@ -75,6 +75,15 @@ public World World() return new World(Handle->world); } + /// + /// Returns the C# world or stage the iterator was created with. + /// + /// + public World Stage() + { + return new World(Handle->stage); + } + /// /// Returns the number of entities to iterate. /// @@ -85,6 +94,16 @@ public int Count() return Handle->count; } + /// + /// Returns the offset of the current table relative to the frame. + /// + /// The frame offset. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int FrameOffset() + { + return Handle->frame_offset; + } + /// /// Returns the time elapsed since last frame. /// @@ -111,7 +130,7 @@ public float DeltaSystemTime() /// public FlecsType Type() { - return new FlecsType(Handle->world, ecs_table_get_type(Handle->table)); + return new FlecsType(Handle->stage, ecs_table_get_type(Handle->table)); } /// @@ -120,7 +139,7 @@ public FlecsType Type() /// public Table Table() { - return new Table(Handle->real_world, Handle->table); + return new Table(Handle->world, Handle->table); } /// @@ -129,7 +148,7 @@ public Table Table() /// public Table OtherTable() { - return new Table(Handle->real_world, Handle->other_table); + return new Table(Handle->world, Handle->other_table); } /// @@ -138,7 +157,7 @@ public Table OtherTable() /// public Table Range() { - return new Table(Handle->real_world, Handle->table, Handle->offset, Handle->count); + return new Table(Handle->world, Handle->table, Handle->offset, Handle->count); } /// @@ -208,7 +227,7 @@ public ref T Param() where T : unmanaged public Entity Entity(int row) { Ecs.Assert(row < Handle->count, nameof(ECS_COLUMN_INDEX_OUT_OF_RANGE)); - return new Entity(Handle->world, Handle->entities[row]); + return new Entity(Handle->stage, Handle->entities[row]); } /// @@ -272,7 +291,7 @@ public ulong Size(int index) public Entity Src(int index) { Ecs.Assert(index < Handle->field_count, "Field index out of range."); - return new Entity(Handle->world, ecs_field_src(Handle, (byte)index)); + return new Entity(Handle->stage, ecs_field_src(Handle, (byte)index)); } /// @@ -283,7 +302,7 @@ public Entity Src(int index) public Id Id(int index) { Ecs.Assert(index < Handle->field_count, "Field index out of range."); - return new Id(Handle->world, ecs_field_id(Handle, (byte)index)); + return new Id(Handle->stage, ecs_field_id(Handle, (byte)index)); } /// @@ -297,7 +316,7 @@ public Id Pair(int index) Ecs.Assert(index < Handle->field_count, "Field index out of range."); ulong id = ecs_field_id(Handle, (byte)index); Ecs.Assert(Ecs.EntityHasIdFlag(id, ECS_PAIR) != 0, nameof(ECS_INVALID_PARAMETER)); - return new Id(Handle->world, id); + return new Id(Handle->stage, id); } /// @@ -311,15 +330,6 @@ public int ColumnIndex(int index) return ecs_field_column(Handle, (byte)index); } - /// - /// Convert current iterator result to string. - /// - /// - public string Str() - { - return NativeString.GetStringAndFree(ecs_iter_str(Handle)); - } - /// /// Retrieves an untyped field at the provided index. /// @@ -357,6 +367,20 @@ public Field Field(int index) return GetField(index); } + /// + /// Retrieves a field that was matched through component inheritance at the provided index. Unlike + /// , this returns a field that iterates with a runtime stride, so it works when + /// the matched (derived) component is larger than . + /// + /// The field index. + /// The base type of the field. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public BaseField BaseField(int index) + { + return GetBaseField(index); + } + /// /// Retrieves a managed reference to field at row. /// @@ -419,7 +443,7 @@ public ulong GroupId() public Entity GetVar(int varId) { Ecs.Assert(varId != -1, nameof(ECS_INVALID_PARAMETER)); - return new Entity(Handle->world, ecs_iter_get_var(Handle, varId)); + return new Entity(Handle->stage, ecs_iter_get_var(Handle, varId)); } /// @@ -435,7 +459,7 @@ public Entity GetVar(string name) int varId = ecs_query_find_var(query, nativeName); Ecs.Assert(varId != -1, nameof(ECS_INVALID_PARAMETER)); - return new Entity(Handle->world, ecs_iter_get_var(Handle, varId)); + return new Entity(Handle->stage, ecs_iter_get_var(Handle, varId)); } /// @@ -457,7 +481,7 @@ public void Targets(int index, Ecs.EachEntityCallback callback) { ulong id = tableType->array[i]; Ecs.Assert(Ecs.IsPair(id), "Field must be a pair."); - callback(new Entity(Handle->world, Ecs.PairSecond(Handle->real_world, id))); + callback(new Entity(Handle->stage, Ecs.PairSecond(Handle->world, id))); } } @@ -480,7 +504,7 @@ public void Targets(int index, delegate* callback) { ulong id = tableType->array[i]; Ecs.Assert(Ecs.IsPair(id), "Field must be a pair."); - callback(new Entity(Handle->world, Ecs.PairSecond(Handle->real_world, id))); + callback(new Entity(Handle->stage, Ecs.PairSecond(Handle->world, id))); } } @@ -491,14 +515,14 @@ public void Targets(int index, delegate* callback) public bool Next() { if ((Handle->flags & EcsIterIsValid) != 0 && Handle->table != null) - Ecs.TableUnlock(Handle->world, Handle->table); + Ecs.TableUnlock(Handle->stage, Handle->table); bool result = ((delegate* unmanaged)Handle->next)(Handle) != 0; Handle->flags |= EcsIterIsValid; if (result && Handle->table != null) - Ecs.TableLock(Handle->world, Handle->table); + Ecs.TableLock(Handle->stage, Handle->table); return result; } @@ -529,7 +553,7 @@ public void Fini() return; if ((Handle->flags & EcsIterIsValid) != 0 && Handle->table != null) - Ecs.TableUnlock(Handle->world, Handle->table); + Ecs.TableUnlock(Handle->stage, Handle->table); ecs_iter_fini(Handle); Handle = null; @@ -577,6 +601,18 @@ internal Field GetFieldAt(int index, int row) return new Field(field.Data, 1); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal BaseField GetBaseField(int index) + { + Ecs.Assert(ecs_field_size(Handle, (byte)index) == Type.Size, nameof(ECS_COLUMN_TYPE_MISMATCH)); + + return new BaseField( + ecs_base_field_w_size(Handle, Type.Size, (byte)index), + (int)ecs_field_stride(Handle, (byte)index), + ecs_field_is_self(Handle, (byte)index) ? Handle->count : 1 + ); + } + [Conditional("DEBUG")] internal static void AssertField(ecs_iter_t* iter, int index) { diff --git a/src/Flecs.NET/Core/IterIterable.cs b/src/Flecs.NET/Core/IterIterable.cs index 19c01619..3c2c5f64 100644 --- a/src/Flecs.NET/Core/IterIterable.cs +++ b/src/Flecs.NET/Core/IterIterable.cs @@ -192,15 +192,17 @@ public Entity First() { fixed (ecs_iter_t* it = &Iterator) { - Entity result = default; - - if (this.GetNext(it) && it->count != 0) + while (GetNext(it)) { - result = new Entity(it->world, it->entities[0]); + if (it->count == 0) + continue; + + Entity result = new Entity(it->stage, it->entities[0]); ecs_iter_fini(it); + return result; } - return result; + return default; } } @@ -227,7 +229,7 @@ public ref IterIterable SetGroup() { fixed (ecs_iter_t* it = &Iterator) { - ecs_iter_set_group(it, Type.Id(it->real_world)); + ecs_iter_set_group(it, Type.Id(it->world)); return ref this; } } @@ -305,9 +307,7 @@ public ecs_iter_t GetIter(World world = default) if (world == null) return Iterator; - return world == null - ? Iterator - : Iterator with { world = world }; + return Iterator with { stage = world }; } /// @@ -396,7 +396,7 @@ public IterIterable Iter(World world = default) /// public IterIterable Iter(Iter it) { - return Iter(it.World()); + return Iter(it.Stage()); } /// diff --git a/src/Flecs.NET/Core/ObserverBuilder.cs b/src/Flecs.NET/Core/ObserverBuilder.cs index 79e8b091..86d6b083 100644 --- a/src/Flecs.NET/Core/ObserverBuilder.cs +++ b/src/Flecs.NET/Core/ObserverBuilder.cs @@ -421,14 +421,37 @@ internal ref ObserverBuilder SetRun(void* callback, void* invoker) internal Observer Build() { + QueryBuilder.AssertReusable(); + Desc.query = QueryBuilder.Desc; + ulong observer; + Observer result; + fixed (ecs_observer_desc_t* ptr = &Desc) { Ecs.Assert(_eventCount != 0, "Observer cannot have zero events. Use ObserverBuilder.Event() to add events."); - Ecs.Assert(ptr->query.terms[0] != default || ptr->query.expr != null, "Observers require at least 1 term."); - return new Observer(World, ecs_observer_init(World, ptr)); + observer = ecs_observer_init(World, ptr); } + + result = new Observer(World, observer); + + // The observer owns the contexts after initialization, so clear them for reuse. + Desc.ctx = null; + Desc.ctx_free = null; + Desc.callback_ctx = null; + Desc.callback_ctx_free = null; + Desc.run_ctx = null; + Desc.run_ctx_free = null; + Desc.query.binding_ctx = null; + Desc.query.binding_ctx_free = null; + Desc.query.group_by_ctx = null; + Desc.query.group_by_ctx_free = null; + + if (observer != 0) + QueryBuilder.MarkBuilt(); + + return result; } Observer IQueryBuilder.Build() diff --git a/src/Flecs.NET/Core/PageIterable.cs b/src/Flecs.NET/Core/PageIterable.cs index 9bab87af..c0e03e2f 100644 --- a/src/Flecs.NET/Core/PageIterable.cs +++ b/src/Flecs.NET/Core/PageIterable.cs @@ -192,7 +192,7 @@ public IterIterable Iter(World world = default) /// public IterIterable Iter(Iter it) { - return Iter(it.World()); + return Iter(it.Stage()); } /// diff --git a/src/Flecs.NET/Core/ParsedScript.cs b/src/Flecs.NET/Core/ParsedScript.cs new file mode 100644 index 00000000..eec190a1 --- /dev/null +++ b/src/Flecs.NET/Core/ParsedScript.cs @@ -0,0 +1,126 @@ +using System; +using static Flecs.NET.Bindings.flecs; + +namespace Flecs.NET.Core; + +/// +/// A parsed script. Parsing is done once with , after which the +/// script can be evaluated any number of times with . +/// +/// +/// This type owns a native script object, so dispose it when it is no longer used. +/// +public sealed unsafe class ParsedScript : IDisposable, IEquatable +{ + private ecs_script_t* _handle; + + /// + /// Constructs a parsed script from an pointer. + /// + /// The script handle. + public ParsedScript(ecs_script_t* handle) + { + _handle = handle; + } + + /// + /// Returns true if the script was parsed successfully. + /// + public bool IsValid => _handle != null; + + /// + /// Evaluates the parsed script. + /// + /// Zero if success, non-zero if failed. + public int Eval() + { + return Eval(null, null); + } + + /// + /// Evaluates the parsed script. + /// + /// The eval parameters. + /// The eval result. + /// Zero if success, non-zero if failed. + public int Eval(ref ecs_script_eval_desc_t desc, ref ecs_script_eval_result_t result) + { + fixed (ecs_script_eval_desc_t* descPtr = &desc) + fixed (ecs_script_eval_result_t* resultPtr = &result) + return Eval(descPtr, resultPtr); + } + + /// + /// Evaluates the parsed script. + /// + /// The eval parameters. + /// The eval result. + /// Zero if success, non-zero if failed. + public int Eval(ecs_script_eval_desc_t* desc, ecs_script_eval_result_t* result) + { + return _handle == null ? -1 : ecs_script_eval(_handle, desc, result); + } + + /// + /// Frees the parsed script. + /// + public void Dispose() + { + if (_handle == null) + return; + + ecs_script_free(_handle); + _handle = null; + } + + /// + /// Checks if two instances are equal. + /// + /// + /// + public bool Equals(ParsedScript? other) + { + return ReferenceEquals(this, other) || (other is not null && _handle == other._handle); + } + + /// + /// Checks if two instances are equal. + /// + /// + /// + public override bool Equals(object? obj) + { + return obj is ParsedScript other && Equals(other); + } + + /// + /// Returns the hash code for the . + /// + /// + public override int GetHashCode() + { + return ((nint)_handle).GetHashCode(); + } + + /// + /// Checks if two instances are equal. + /// + /// + /// + /// + public static bool operator ==(ParsedScript? left, ParsedScript? right) + { + return left is null ? right is null : left.Equals(right); + } + + /// + /// Checks if two instances are not equal. + /// + /// + /// + /// + public static bool operator !=(ParsedScript? left, ParsedScript? right) + { + return !(left == right); + } +} diff --git a/src/Flecs.NET/Core/PipelineBuilder.cs b/src/Flecs.NET/Core/PipelineBuilder.cs index 87b2b4ca..03ee5858 100644 --- a/src/Flecs.NET/Core/PipelineBuilder.cs +++ b/src/Flecs.NET/Core/PipelineBuilder.cs @@ -84,6 +84,8 @@ public void Dispose() /// public Pipeline Build() { + QueryBuilder.AssertReusable(); + fixed (ecs_pipeline_desc_t* pipelineDesc = &Desc) { pipelineDesc->query = QueryBuilder.Desc; @@ -93,6 +95,9 @@ public Pipeline Build() if (entity == 0) Ecs.Error("Pipeline failed to init."); + // The pipeline query owns the contexts after initialization. + QueryBuilder.MarkBuilt(); + return new Pipeline(entity); } } diff --git a/src/Flecs.NET/Core/Query.cs b/src/Flecs.NET/Core/Query.cs index 16ba3147..f27f93a1 100644 --- a/src/Flecs.NET/Core/Query.cs +++ b/src/Flecs.NET/Core/Query.cs @@ -81,7 +81,7 @@ public void Destruct() /// public Entity Entity() { - return new Entity(Handle->world, Handle->entity); + return new Entity(Handle->stage, Handle->entity); } /// @@ -133,7 +133,7 @@ public void EachTerm(Ecs.TermCallback callback) { for (int i = 0; i < Handle->term_count; i++) { - Term term = new Term(Handle->world, Handle->terms[i]); + Term term = new Term(Handle->stage, Handle->terms[i]); callback(ref term); } } @@ -146,7 +146,7 @@ public void EachTerm(Ecs.TermCallback callback) public Term Term(int index) { Ecs.Assert(index < Handle->term_count, nameof(ECS_COLUMN_INDEX_OUT_OF_RANGE)); - return new Term(Handle->world, Handle->terms[index]); + return new Term(Handle->stage, Handle->terms[index]); } /// @@ -292,7 +292,7 @@ public override int GetHashCode() public unsafe partial struct Query { /// - /// Gets the query's world or stage. + /// Gets the query's world. /// /// public World World() @@ -301,12 +301,12 @@ public World World() } /// - /// Gets the query's actual world. + /// Gets the query's world or stage. /// /// - public World RealWorld() + public World Stage() { - return Handle->real_world; + return Handle->stage; } } @@ -322,7 +322,7 @@ public unsafe partial struct Query : IQuery public unsafe partial struct Query : IIterableBase { /// - ecs_world_t* IIterableBase.World => Handle->world; + ecs_world_t* IIterableBase.World => Handle->stage; /// [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -331,7 +331,7 @@ public ecs_iter_t GetIter(World world = default) Ecs.Assert(Handle != null, "Cannot iterate invalid query."); if (world == null) - world = Handle->world; + world = Handle->stage; return ecs_query_iter(world, Handle); } @@ -416,7 +416,7 @@ public IterIterable Iter(World world = default) /// public IterIterable Iter(Iter it) { - return Iter(it.World()); + return Iter(it.Stage()); } /// diff --git a/src/Flecs.NET/Core/QueryBuilder.cs b/src/Flecs.NET/Core/QueryBuilder.cs index c141b518..0fc4bb79 100644 --- a/src/Flecs.NET/Core/QueryBuilder.cs +++ b/src/Flecs.NET/Core/QueryBuilder.cs @@ -17,6 +17,7 @@ public unsafe struct QueryBuilder : IDisposable, IEquatable, IQuer private ecs_query_desc_t _desc; private int _termIndex; private int _termCount; + private bool _built; private TermIdType _termIdType; private ref ecs_term_t CurrentTerm => ref Desc.terms[_termIndex]; private ref ecs_term_ref_t CurrentTermId @@ -64,6 +65,7 @@ public QueryBuilder(ecs_world_t* world) _termIndex = default; _termCount = default; _termIdType = TermIdType.Src; + _built = default; QueryContext = default; } @@ -113,8 +115,65 @@ public void Dispose() /// public Query Build() { + AssertReusable(); + + Query result; + fixed (ecs_query_desc_t* ptr = &Desc) - return new Query(ecs_query_init(World, ptr)); + result = new Query(ecs_query_init(World, ptr)); + + // The query owns the contexts after a successful initialization; on failure Dispose frees them. + if (result.Handle != null) + MarkBuilt(); + + return result; + } + + /// + /// Releases the contexts that were transferred to a query or system. + /// + internal void ClearContexts() + { + // ecs_query_init always takes ownership of the binding context. + Desc.binding_ctx = null; + Desc.binding_ctx_free = null; + + // ecs_query_init only takes the group by context when a group by callback or id is set. + if (Desc.group_by_callback == null && Desc.group_by == 0) + return; + + Desc.group_by_ctx = null; + Desc.group_by_ctx_free = null; + } + + /// + /// Releases the contexts that were transferred to a built object and marks the builder as built. + /// + internal void MarkBuilt() + { + ClearContexts(); + _built = true; + } + + /// + /// Asserts that a built builder is only reused when it doesn't reference data that was + /// transferred to the built object. + /// + internal void AssertReusable() + { + if (!_built) + return; + + bool transferred = Desc.expr != null || Desc.group_by_callback != null || Desc.order_by_callback != null; + + for (int i = 0; !transferred && i < _termCount; i++) + { + ref ecs_term_t term = ref Desc.terms[i]; + transferred = term.first.name != null || term.second.name != null || term.src.name != null; + } + + Ecs.Assert(!transferred, + "QueryBuilder cannot be reused after Build() when Expr, Var, a term name, GroupBy or OrderBy is set. Create a new builder instead."); } /// diff --git a/src/Flecs.NET/Core/ScriptFunction.cs b/src/Flecs.NET/Core/ScriptFunction.cs new file mode 100644 index 00000000..22900a85 --- /dev/null +++ b/src/Flecs.NET/Core/ScriptFunction.cs @@ -0,0 +1,38 @@ +using System.Diagnostics.CodeAnalysis; +using static Flecs.NET.Bindings.flecs; + +namespace Flecs.NET.Core; + +/// +/// The context of a script function callback. +/// +[SuppressMessage("Performance", "CA1815", Justification = "A script function context is not compared.")] +public unsafe readonly struct ScriptFunction +{ + private readonly ecs_function_ctx_t _ctx; + + internal ScriptFunction(ecs_function_ctx_t ctx) + { + _ctx = ctx; + } + + /// + /// The world. + /// + public World World => new(_ctx.world); + + /// + /// The function entity. + /// + public ulong Function => _ctx.function; + + /// + /// The "this" entity, for methods and async functions. + /// + public Entity Entity => new(_ctx.world, _ctx.entity); + + /// + /// The user context set with . + /// + public void* Ctx => _ctx.ctx; +} diff --git a/src/Flecs.NET/Core/ScriptValue.cs b/src/Flecs.NET/Core/ScriptValue.cs new file mode 100644 index 00000000..d19984b4 --- /dev/null +++ b/src/Flecs.NET/Core/ScriptValue.cs @@ -0,0 +1,83 @@ +using System.Diagnostics.CodeAnalysis; +using Flecs.NET.Utilities; +using static Flecs.NET.Bindings.flecs; + +namespace Flecs.NET.Core; + +/// +/// A wrapper around a script function argument or result value. +/// +[SuppressMessage("Performance", "CA1815", Justification = "Script values are transient views of callback memory.")] +public unsafe readonly struct ScriptValue +{ + private readonly ecs_value_t* _handle; + + internal ScriptValue(ecs_value_t* handle) + { + _handle = handle; + } + + /// + /// The value type entity. + /// + public ulong Type => _handle->type; + + /// + /// The pointer to the value. + /// + [SuppressMessage("Naming", "CA1721", Justification = "Ptr matches the ecs_value_t field name.")] + public void* Ptr => _handle->ptr; + + /// + /// Gets a reference to the value. + /// + /// The value type. + public ref T Get() + { + return ref Managed.GetTypeRef(_handle->ptr); + } + + /// + /// Gets a pointer to the value. + /// + /// The value type. + public T* GetPtr() where T : unmanaged + { + return (T*)_handle->ptr; + } +} + +/// +/// A view over the arguments passed to a script function callback. +/// +/// +/// For method callbacks the instance value is passed at index 0 and is not included in . +/// +public readonly unsafe ref struct ScriptArgs +{ + private readonly ecs_value_t* _values; + private readonly int _count; + + internal ScriptArgs(ecs_value_t* values, int count) + { + _values = values; + _count = count; + } + + /// + /// The number of arguments. + /// + public int Count => _count; + + /// + /// Gets the argument at the specified index. + /// + /// The argument index. + public ScriptValue this[int index] + { + get + { + return new ScriptValue(&_values[index]); + } + } +} diff --git a/src/Flecs.NET/Core/SparseQuery.cs b/src/Flecs.NET/Core/SparseQuery.cs new file mode 100644 index 00000000..e056ec3e --- /dev/null +++ b/src/Flecs.NET/Core/SparseQuery.cs @@ -0,0 +1,109 @@ +using Flecs.NET.Utilities; +using static Flecs.NET.Bindings.flecs; + +namespace Flecs.NET.Core; + +/// +/// Shared iteration logic for , which iterates sparse component storages directly. +/// +internal static unsafe class SparseQuery +{ + /// + /// Iterates the entities that are present in all provided sparse storages and returns the number of matched + /// entities. The invoker receives the pointers to the component values of each matched entity. + /// + internal static int Each(ecs_world_t* world, ulong* ids, int idCount, void* context, + delegate* invoker) + { + ecs_sparse_t** sparse = stackalloc ecs_sparse_t*[idCount]; + + for (int i = 0; i < idCount; i++) + { + sparse[i] = Storage(world, ids[i]); + + if (sparse[i] == null) + return 0; + } + + // Iterate the storage with the fewest elements to minimize the number of lookups. + int lead = 0; + for (int i = 1; i < idCount; i++) + { + if (sparse[i]->count < sparse[lead]->count) + lead = i; + } + + ulong* entities = (ulong*)sparse[lead]->dense.array + 1; + int entityCount = sparse[lead]->count - 1; + void** ptrs = stackalloc void*[idCount]; + int matched = 0; + + for (int i = 0; i < entityCount; i++) + { + ulong entity = entities[i]; + bool found = true; + + for (int f = 0; f < idCount; f++) + { + ptrs[f] = FieldAtSparse(sparse[f], entity, f != lead); + + if (ptrs[f] == null) + { + found = false; + break; + } + } + + if (!found) + continue; + + ecs_record_t* record = flecs_entities_get(world, entity); + + if (record == null || record->table == null) + continue; + + if ((flecs_table_flags(record->table) & + (EcsTableNotQueryable | EcsTableIsPrefab | EcsTableIsDisabled)) != 0) + continue; + + if (invoker != null) + invoker(context, world, entity, ptrs); + + matched++; + } + + return matched; + } + + private static ecs_sparse_t* Storage(ecs_world_t* world, ulong id) + { + ecs_component_record_t* record = flecs_components_get(world, id); + return record == null ? null : flecs_component_get_sparse(record); + } + + private static void* FieldAtSparse(ecs_sparse_t* sparse, ulong entity, bool check) + { + Ecs.Assert(sparse != null, nameof(ECS_INVALID_PARAMETER)); + + int pageIndex = (int)((uint)entity >> FLECS_SPARSE_PAGE_BITS); + + if (check && pageIndex >= sparse->pages.count) + return null; + + ecs_sparse_page_t* page = &((ecs_sparse_page_t*)sparse->pages.array)[pageIndex]; + int offset = (int)(entity & (FLECS_SPARSE_PAGE_SIZE - 1)); + + if (check) + { + if (page->sparse == null) + return null; + + int dense = page->sparse[offset]; + + if (dense == 0 || dense >= sparse->count) + return null; + } + + return (byte*)page->data + sparse->size * offset; + } +} diff --git a/src/Flecs.NET/Core/SystemBuilder.cs b/src/Flecs.NET/Core/SystemBuilder.cs index fad1a119..b2cb7e46 100644 --- a/src/Flecs.NET/Core/SystemBuilder.cs +++ b/src/Flecs.NET/Core/SystemBuilder.cs @@ -43,10 +43,7 @@ public SystemBuilder(ecs_world_t* world) _desc = default; _queryBuilder = new QueryBuilder(world); - ecs_entity_desc_t entityDesc = default; - Desc.entity = ecs_entity_init(world, &entityDesc); - ecs_add_id(world, Desc.entity, Ecs.Pair(EcsDependsOn, EcsOnUpdate)); - ecs_add_id(world, Desc.entity, EcsOnUpdate); + Desc.phase = EcsOnUpdate; } /// @@ -69,11 +66,8 @@ public SystemBuilder(ecs_world_t* world, string name) Desc.entity = ecs_entity_init(world, &entityDesc); - if (ecs_has_id(world, Desc.entity, Ecs.Pair(EcsDependsOn, EcsWildcard))) - return; - - ecs_add_id(world, Desc.entity, Ecs.Pair(EcsDependsOn, EcsOnUpdate)); - ecs_add_id(world, Desc.entity, EcsOnUpdate); + if (!ecs_has_id(world, Desc.entity, Ecs.Pair(EcsDependsOn, EcsWildcard))) + Desc.phase = EcsOnUpdate; } /// @@ -92,11 +86,8 @@ public SystemBuilder(ecs_world_t* world, ulong entity) Desc.entity = ecs_entity_init(world, &entityDesc); - if (ecs_has_id(world, Desc.entity, Ecs.Pair(EcsDependsOn, EcsWildcard))) - return; - - ecs_add_id(world, Desc.entity, Ecs.Pair(EcsDependsOn, EcsOnUpdate)); - ecs_add_id(world, Desc.entity, EcsOnUpdate); + if (!ecs_has_id(world, Desc.entity, Ecs.Pair(EcsDependsOn, EcsWildcard))) + Desc.phase = EcsOnUpdate; } /// @@ -119,19 +110,7 @@ public void Dispose() /// public ref SystemBuilder Kind(ulong phase) { - ulong currentPhase = ecs_get_target(World, Desc.entity, EcsDependsOn, 0); - - if (currentPhase != 0) - { - ecs_remove_id(World, Desc.entity, Ecs.Pair(EcsDependsOn, currentPhase)); - ecs_remove_id(World, Desc.entity, currentPhase); - } - - if (phase != 0) - { - ecs_add_id(World, Desc.entity, Ecs.Pair(EcsDependsOn, phase)); - ecs_add_id(World, Desc.entity, phase); - } + Desc.phase = phase; return ref this; } @@ -522,10 +501,34 @@ internal ref SystemBuilder SetRun(void* callback, void* invoker) internal System_ Build() { + QueryBuilder.AssertReusable(); + Desc.query = QueryBuilder.Desc; + ulong system; + System_ result; + fixed (ecs_system_desc_t* ptr = &Desc) - return new System_(World, ecs_system_init(World, ptr)); + system = ecs_system_init(World, ptr); + + result = new System_(World, system); + + // The system owns the contexts after initialization, so clear them for reuse. + Desc.ctx = null; + Desc.ctx_free = null; + Desc.callback_ctx = null; + Desc.callback_ctx_free = null; + Desc.run_ctx = null; + Desc.run_ctx_free = null; + Desc.query.binding_ctx = null; + Desc.query.binding_ctx_free = null; + Desc.query.group_by_ctx = null; + Desc.query.group_by_ctx_free = null; + + if (system != 0) + QueryBuilder.MarkBuilt(); + + return result; } System_ IQueryBuilder.Build() diff --git a/src/Flecs.NET/Core/Table.cs b/src/Flecs.NET/Core/Table.cs index 1eea4ff3..db87e808 100644 --- a/src/Flecs.NET/Core/Table.cs +++ b/src/Flecs.NET/Core/Table.cs @@ -99,6 +99,32 @@ public FlecsType Type() return new FlecsType(World, ecs_table_get_type(Handle)); } + /// + /// Get the number of allocated elements in the table. + /// + /// + public int Size() + { + return ecs_table_size(Handle); + } + + /// + /// Get the array of entity ids. + /// + /// + public ulong* Entities() + { + return ecs_table_entities(Handle); + } + + /// + /// Delete entities in the table. + /// + public void ClearEntities() + { + ecs_table_clear_entities(World, Handle); + } + /// /// Find type index for (component) id. /// @@ -654,6 +680,50 @@ public int Depth(T value) where T : Enum return Depth(Type.Id(World, value)); } + /// + /// Get the table records array. + /// + /// + public ecs_table_records_t Records() + { + return flecs_table_records(Handle); + } + + /// + /// Get the table id. + /// + /// + public ulong Id() + { + return flecs_table_id(Handle); + } + + /// + /// Lock the table. + /// + public void Lock() + { + ecs_table_lock(World, Handle); + } + + /// + /// Unlock the table. + /// + public void Unlock() + { + ecs_table_unlock(World, Handle); + } + + /// + /// Check if the table has the specified flags. + /// + /// The flags to check for. + /// True if the table has the specified flags. + public bool HasFlags(uint flags) + { + return ecs_table_has_flags(Handle, flags); + } + /// /// Get table. /// diff --git a/src/Flecs.NET/Core/Type.cs b/src/Flecs.NET/Core/Type.cs index 4948f76c..d0837a73 100644 --- a/src/Flecs.NET/Core/Type.cs +++ b/src/Flecs.NET/Core/Type.cs @@ -275,7 +275,6 @@ public static ulong RegisterComponent(World world, bool ignoreScope, bool isComp } Entity prevScope = world.SetScope(ignoreScope ? 0ul : world.GetScope()); - Entity prevWith = world.SetWith(ignoreScope ? 0ul : world.GetWith()); using NativeString nativeSymbol = (NativeString)FullName; using NativeString nativeName = string.IsNullOrEmpty(name) @@ -305,7 +304,6 @@ public static ulong RegisterComponent(World world, bool ignoreScope, bool isComp Ecs.Assert(component != 0, $"Failed to register component for type '{FullName}'"); Ecs.Assert(component == entity, $"Component id for type '{FullName}' does not match entity id"); - world.SetWith(prevWith); world.SetScope(prevScope); // Store the type in the component. diff --git a/src/Flecs.NET/Core/TypeInfo.cs b/src/Flecs.NET/Core/TypeInfo.cs index 5ef04259..1a4ae02e 100644 --- a/src/Flecs.NET/Core/TypeInfo.cs +++ b/src/Flecs.NET/Core/TypeInfo.cs @@ -7,6 +7,10 @@ namespace Flecs.NET.Core; /// /// A wrapper around *. /// +/// +/// returns an invalid instance when the id is not a component. The members +/// dereference the handle, so check first. +/// public readonly unsafe struct TypeInfo : IEquatable { private readonly ecs_type_info_t* _handle; @@ -25,6 +29,11 @@ public TypeInfo(ecs_type_info_t* handle) _handle = handle; } + /// + /// Returns true if the type info has a handle. + /// + public bool IsValid => _handle != null; + /// /// Size of type. /// @@ -33,7 +42,7 @@ public TypeInfo(ecs_type_info_t* handle) /// /// Alignment of type. /// - public int Alignment => Handle->size; + public int Alignment => Handle->alignment; /// /// Handle to component. @@ -71,7 +80,7 @@ public override bool Equals(object? obj) /// public override int GetHashCode() { - return Handle->GetHashCode(); + return _handle == null ? 0 : Handle->GetHashCode(); } /// diff --git a/src/Flecs.NET/Core/UntypedComponent.cs b/src/Flecs.NET/Core/UntypedComponent.cs index c712b198..c87da879 100644 --- a/src/Flecs.NET/Core/UntypedComponent.cs +++ b/src/Flecs.NET/Core/UntypedComponent.cs @@ -1,5 +1,6 @@ using System; using System.Globalization; +using Flecs.NET.Core.BindingContext; using Flecs.NET.Utilities; using static Flecs.NET.Bindings.flecs; @@ -345,6 +346,86 @@ public ref UntypedComponent Metric(ulong parent = 0, string brief = "", strin return ref this; } + /// + /// Get the type hooks for this component. + /// + /// The type hooks, or empty hooks if none are set. + public ecs_type_hooks_t GetHooks() + { + ecs_type_hooks_t* hooks = ecs_get_hooks_id(World, Id); + return hooks == null ? default : *hooks; + } + + /// + /// Set the type hooks for this component. + /// + /// The type hooks to set. + public void SetHooks(ref ecs_type_hooks_t hooks) + { + hooks.flags &= ECS_TYPE_HOOKS_ILLEGAL; + + // Hook thunks read the binding context, so flecs must not free a caller's pointer with our free function. + Ecs.Assert(hooks.binding_ctx == null || hooks.binding_ctx_free != null, + "Cannot set a type hook binding context without a binding context free function."); + + fixed (ecs_type_hooks_t* ptr = &hooks) + ecs_set_hooks_id(World, Id, ptr); + } + + /// + /// Register a custom compare hook for this component. + /// + /// The comparison callback function. + /// Reference to self. + public ref UntypedComponent OnCompare(Ecs.CompareCallback callback) + { + Ecs.Assert(callback != null, nameof(ECS_INVALID_PARAMETER)); + + TypeHooksContext* context = GetHooksAndContext(out ecs_type_hooks_t hooks); + hooks.cmp = &Functions.OnCompareCallback; + hooks.flags &= ~(ECS_TYPE_HOOK_CMP_ILLEGAL | ECS_TYPE_HOOK_EQUALS_ILLEGAL); + context->OnCompare.Set(callback!, (delegate*)&Functions.OnCompareCallbackDelegate); + SetHooks(ref hooks); + + return ref this; + } + + /// + /// Register a custom equals hook for this component. + /// + /// The equality callback function. + /// Reference to self. + public ref UntypedComponent OnEquals(Ecs.EqualsCallback callback) + { + Ecs.Assert(callback != null, nameof(ECS_INVALID_PARAMETER)); + + TypeHooksContext* context = GetHooksAndContext(out ecs_type_hooks_t hooks); + hooks.equals = Functions.OnEqualsHook; + hooks.flags &= ~ECS_TYPE_HOOK_EQUALS_ILLEGAL; + context->OnEquals.Set(callback!, (delegate*)&Functions.OnEqualsCallbackDelegate); + SetHooks(ref hooks); + + return ref this; + } + + private TypeHooksContext* GetHooksAndContext(out ecs_type_hooks_t hooks) + { + ecs_type_hooks_t* existingHooks = ecs_get_hooks_id(World, Id); + hooks = existingHooks == null ? default : *existingHooks; + + TypeHooksContext* context = (TypeHooksContext*)hooks.binding_ctx; + + if (context == null) + { + context = Memory.Alloc(TypeHooksContext.Default); + hooks.binding_ctx = context; + hooks.binding_ctx_free = &Functions.TypeHooksContextFree; + } + + Ecs.Assert(context->Header == Ecs.Header, "Type hook binding context is not owned by Flecs.NET."); + return context; + } + /// /// Converts an instance to its integer id. /// diff --git a/src/Flecs.NET/Core/WorkerIterable.cs b/src/Flecs.NET/Core/WorkerIterable.cs index a6a6f5bf..2bf09f4e 100644 --- a/src/Flecs.NET/Core/WorkerIterable.cs +++ b/src/Flecs.NET/Core/WorkerIterable.cs @@ -192,7 +192,7 @@ public IterIterable Iter(World world = default) /// public IterIterable Iter(Iter it) { - return Iter(it.World()); + return Iter(it.Stage()); } /// diff --git a/src/Flecs.NET/Core/World.cs b/src/Flecs.NET/Core/World.cs index 39fe8d52..3f588fab 100644 --- a/src/Flecs.NET/Core/World.cs +++ b/src/Flecs.NET/Core/World.cs @@ -36,9 +36,8 @@ public World(ecs_world_t* handle) /// public static World Create() { - Ecs.Os.OverrideOsApi(); - World w = new World(ecs_init()); + Ecs.Os.OverrideOsApi(); w.EnsureBindingContext(); w.InitBuiltinComponents(); @@ -73,9 +72,8 @@ public static World Create(params Span args) for (int i = 0; i < args.Length; i++) nativeStrings[i] = (NativeString)args[i]; - Ecs.Os.OverrideOsApi(); - World w = new World(ecs_init_w_args(args.Length, (byte**)nativeStrings)); + Ecs.Os.OverrideOsApi(); w.EnsureBindingContext(); w.InitBuiltinComponents(); @@ -173,30 +171,27 @@ public void ReadonlyEnd() } /// - /// Defer operations until end end of frame, or until DeferEnd() is called. + /// Begin exclusive access. /// - /// - public bool DeferBegin() + /// Optional thread name for improved debug messages. + public void ExclusiveAccessBegin(string? threadName = null) { - return ecs_defer_begin(Handle); + // Flecs stores the pointer, so the string must outlive the exclusive access section. + WorldContext.ExclusiveAccessThreadName.Dispose(); + WorldContext.ExclusiveAccessThreadName = (NativeString)threadName; + ecs_exclusive_access_begin(Handle, WorldContext.ExclusiveAccessThreadName); } /// - /// End block of operations to defer. + /// End exclusive access. /// - /// - public bool DeferEnd() + /// Lock world for all threads, allow readonly operations. + public void ExclusiveAccessEnd(bool lockWorld = false) { - return ecs_defer_end(Handle); - } + ecs_exclusive_access_end(Handle, lockWorld); - /// - /// Test whether deferring is enabled. - /// - /// - public bool IsDeferred() - { - return ecs_is_deferred(Handle); + WorldContext.ExclusiveAccessThreadName.Dispose(); + WorldContext.ExclusiveAccessThreadName = default; } /// @@ -338,6 +333,14 @@ public void Dim(int entityCount) ecs_dim(Handle, entityCount); } + /// + /// Free unused memory. + /// + public void Shrink() + { + ecs_shrink(Handle); + } + /// /// Create a new entity id range constraining new entity identifiers returned by the /// specified .. interval. If is 0, @@ -1852,107 +1855,6 @@ public int CountSecond(ulong first) return Count(first, Type.Id(Handle)); } - /// - /// All entities created in function are created with id. - /// - /// Id to be added to the created entities. - /// The callback. - public void With(ulong id, Action callback) - { - ulong prev = ecs_set_with(Handle, id); - callback(); - ecs_set_with(Handle, prev); - } - - /// - /// All entities created in function are created with pair. - /// - /// The first id. - /// The second id. - /// The callback. - public void With(ulong first, ulong second, Action callback) - { - With(Ecs.Pair(first, second), callback); - } - - /// - /// All entities created in function are created with type. - /// - /// The callback. - /// The component. - public void With(Action callback) - { - With(Type.Id(Handle), callback); - } - - /// - /// All entities created in function are created with enum. - /// - /// The enum constant. - /// The callback. - /// The enum. - public void With(T value, Action callback) where T : Enum - { - With(Type.Id(Handle, value), callback); - } - - /// - /// All entities created in function are created with pair. - /// - /// The second id. - /// The callback. - /// The first component. - public void With(ulong second, Action callback) - { - With(Ecs.Pair(second, Handle), callback); - } - - /// - /// All entities created in function are created with pair. - /// - /// The callback. - /// The first component. - /// The second component. - public void With(Action callback) - { - With(Ecs.Pair(Handle), callback); - } - - /// - /// All entities created in function are created with pair. - /// - /// The second enum constant id. - /// The callback. - /// The first component. - /// The second enum. - public void With(TSecond second, Action callback) where TSecond : Enum - { - With(Type.Id(Handle, second), callback); - } - - /// - /// All entities created in function are created with pair. - /// - /// The first enum constant. - /// The callback. - /// The first enum. - /// The second component. - public void With(TFirst first, Action callback) where TFirst : Enum - { - WithSecond(Type.Id(Handle, first), callback); - } - - /// - /// All entities created in function are created with pair. - /// - /// The first id. - /// The callback. - /// The second component. - public void WithSecond(ulong first, Action callback) - { - With(first, Type.Id(Handle), callback); - } - /// /// All entities created in function are created in scope. All operations /// called in function (such as lookup) are relative to scope. @@ -2208,34 +2110,6 @@ public void RemoveAllSecond(ulong first) RemoveAll(Ecs.PairSecond(first, Handle)); } - /// - /// Defer all operations called in function. If the world is already in - /// deferred mode, do nothing. - /// - /// The callback. - public void Defer(Action callback) - { - ecs_defer_begin(Handle); - callback(); - ecs_defer_end(Handle); - } - - /// - /// Suspend deferring operations. - /// - public void DeferSuspend() - { - ecs_defer_suspend(Handle); - } - - /// - /// Resume deferring operations. - /// - public void DeferResume() - { - ecs_defer_resume(Handle); - } - /// /// Check if entity id exists in the world. /// @@ -2296,6 +2170,16 @@ public void SetVersion(ulong entity) ecs_set_version(Handle, entity); } + /// + /// Get the version of the provided entity. + /// + /// The entity. + /// The version of the entity. + public uint GetVersion(ulong entity) + { + return ecs_get_version(entity); + } + /// /// Run callback after completing frame. /// @@ -2387,6 +2271,17 @@ public Id Id() return new Id(Handle, Type.Id(Handle)); } + /// + /// Return the component id if it has been registered. This operation is similar to + /// but will never automatically register the component. + /// + /// The type for which to obtain the id. + /// The component id if registered, else 0. + public ulong IdIfRegistered() + { + return Type.IsRegistered(Handle, out ulong id) ? id : 0; + } + /// /// Get id from an enum. /// @@ -2534,6 +2429,94 @@ public Id PairSecond(ulong first) return IdSecond(first); } + /// + /// Get the type info for an id. + /// + /// The id. + /// The type info, or an empty type info if the id is not a component. + public TypeInfo TypeInfo(ulong id) + { + return new TypeInfo(ecs_get_type_info(Handle, id)); + } + + /// + /// Get the type info for a pair. + /// + /// The first id. + /// The second id. + /// The type info, or an empty type info if the pair is not a component. + public TypeInfo TypeInfo(ulong first, ulong second) + { + return TypeInfo(Ecs.Pair(first, second)); + } + + /// + /// Get the type info for a type. + /// + /// The type. + /// The type info, or an empty type info if the type is not a component. + public TypeInfo TypeInfo() + { + return TypeInfo(Type.Id(Handle)); + } + + /// + /// Get the type info for an enum. + /// + /// The enum constant. + /// The enum. + /// The type info, or an empty type info if the enum is not a component. + public TypeInfo TypeInfo(T value) where T : Enum + { + return TypeInfo(Type.Id(Handle, value)); + } + + /// + /// Get the type info for a pair. + /// + /// The second id. + /// The first type. + /// The type info, or an empty type info if the pair is not a component. + public TypeInfo TypeInfo(ulong second) + { + return TypeInfo(Ecs.Pair(second, Handle)); + } + + /// + /// Get the type info for a pair. + /// + /// The first type. + /// The second type. + /// The type info, or an empty type info if the pair is not a component. + public TypeInfo TypeInfo() + { + return TypeInfo(Ecs.Pair(Handle)); + } + + /// + /// Get the type info for a pair. + /// + /// The second enum constant. + /// The first type. + /// The second enum. + /// The type info, or an empty type info if the pair is not a component. + public TypeInfo TypeInfo(TSecond second) where TSecond : Enum + { + return TypeInfo(Type.Id(Handle, second)); + } + + /// + /// Get the type info for a pair. + /// + /// The first enum constant. + /// The first enum. + /// The second type. + /// The type info, or an empty type info if the pair is not a component. + public TypeInfo TypeInfo(TFirst first) where TFirst : Enum + { + return TypeInfo(Ecs.PairSecond(Type.Id(Handle, first), Handle)); + } + /// /// Creates an . /// @@ -3016,7 +2999,7 @@ public Entity ToEntity(T value) where T : Enum if (prevParent == parent) return Entity(result); - if (parent != 0) + if (parent != 0 && result.Has(Ecs.Module)) parent.Add(Ecs.Module); // Module was reparented, cleanup old parent(s) @@ -3024,7 +3007,45 @@ public Entity ToEntity(T value) where T : Enum while (current != 0) { + // Stop if the old parent is an ancestor of the new parent + Entity ancestor = parent; + while (ancestor != 0 && ancestor != current) + ancestor = ancestor.Parent(); + + if (ancestor == current) + break; + Entity next = current.Parent(); + + // Move entities that were created in the old parent to the renamed module + bool hasModules = false; + ecs_world_t* stage = ecs_get_stage(ecs_get_world(Handle), 0); + ecs_iter_t it = ecs_children(Handle, current); + + while (ecs_children_next(&it)) + { + for (int i = 0; i < it.count; i++) + { + ulong child = it.entities[i]; + + if (ecs_has_id(Handle, child, EcsModule)) + { + hasModules = true; + continue; + } + + if (ecs_has_id(Handle, child, Ecs.Pair(FLECS_IDEcsPolyID_, EcsWildcard))) + continue; + + ecs_add_id(stage, child, Ecs.Pair(EcsChildOf, result)); + } + } + + ecs_merge(stage); + + if (hasModules) + break; + current.Destruct(); SetVersion(current); current = next; @@ -3273,6 +3294,383 @@ public ScriptBuilder Script(string name) return new ScriptBuilder(Handle, name); } + /// + /// Parses a script. The returned script can be evaluated any number of times with + /// . + /// + /// The script name (typically the file). + /// The script code. + /// The parsed script. + public ParsedScript ScriptParse(string name, string code) + { + using NativeString nativeName = (NativeString)name; + using NativeString nativeCode = (NativeString)code; + + return new ParsedScript(ecs_script_parse(Handle, nativeName, nativeCode, null, null)); + } + + /// + /// Parses a script. The returned script can be evaluated any number of times with + /// . + /// + /// The script name (typically the file). + /// The script code. + /// The parse parameters. + /// The parse result. + /// The parsed script. + public ParsedScript ScriptParse(string name, string code, ref ecs_script_eval_desc_t desc, + ref ecs_script_eval_result_t result) + { + using NativeString nativeName = (NativeString)name; + using NativeString nativeCode = (NativeString)code; + + fixed (ecs_script_eval_desc_t* descPtr = &desc) + fixed (ecs_script_eval_result_t* resultPtr = &result) + return new ParsedScript(ecs_script_parse(Handle, nativeName, nativeCode, descPtr, resultPtr)); + } + + /// + /// Update the code of a script. + /// + /// The script entity. + /// The new script code. + /// The script instance to update. + /// Zero if success, non-zero if failed. + public int ScriptUpdate(ulong script, string code, ulong instance = 0) + { + using NativeString nativeCode = (NativeString)code; + return ecs_script_update(Handle, script, instance, nativeCode); + } + + /// + /// Reload a script from new code, or from its file when code is null. + /// + /// The script entity. + /// The new script code, or null to reload from the script file. + /// Zero if success, non-zero if failed. + public int ScriptReload(ulong script, string? code = null) + { + using NativeString nativeCode = (NativeString)code; + return ecs_script_reload(Handle, script, nativeCode); + } + + /// + /// Creates a script function builder. + /// + /// The function name. + /// The function builder. + public FunctionBuilder Function(string name) + { + return new FunctionBuilder(Handle, name); + } + + /// + /// Creates a script method builder. + /// + /// The type the method belongs to. + /// The method name. + /// The function builder. + public FunctionBuilder Method(ulong type, string name) + { + return new FunctionBuilder(Handle, name, type, true); + } + + /// + /// Creates a script method builder. + /// + /// The method name. + /// The type the method belongs to. + /// The function builder. + public FunctionBuilder Method(string name) + { + return Method(Type.Id(Handle), name); + } + + /// + /// Creates a const variable that can be accessed by scripts. The value of a const variable is folded + /// into expressions that use it. + /// + /// The variable name. + /// The variable value. + /// The variable parent. Defaults to the current scope. + /// The variable type. + /// The const variable entity. + public Entity ConstVar(string name, T value, ulong parent = 0) where T : unmanaged + { + return ConstVar(name, Type.Id(Handle), &value, parent); + } + + /// + /// Creates a const variable that can be accessed by scripts. The value of a const variable is folded + /// into expressions that use it. + /// + /// The variable name. + /// The variable type. + /// Pointer to the variable value. The value is copied. + /// The variable parent. Defaults to the current scope. + /// The const variable entity. + public Entity ConstVar(string name, ulong type, void* value, ulong parent = 0) + { + using NativeString nativeName = (NativeString)name; + + ecs_const_var_desc_t desc = default; + desc.name = nativeName; + desc.parent = parent != 0 ? parent : ecs_get_scope(Handle); + desc.type = type; + desc.value = value; + + return new Entity(Handle, ecs_const_var_init(Handle, &desc)); + } + + /// + /// Creates a mutable variable that can be accessed by scripts. Unlike a const variable the value of a + /// mut variable is never folded into expressions, which means scripts that use it are reevaluated when + /// the value changes. + /// + /// The variable name. + /// The variable value. + /// The variable parent. Defaults to the current scope. + /// The variable type. + /// The mut variable entity. + public Entity MutVar(string name, T value, ulong parent = 0) where T : unmanaged + { + return MutVar(name, Type.Id(Handle), &value, parent); + } + + /// + /// Creates a mutable variable that can be accessed by scripts. Unlike a const variable the value of a + /// mut variable is never folded into expressions, which means scripts that use it are reevaluated when + /// the value changes. + /// + /// The variable name. + /// The variable type. + /// Pointer to the variable value. The value is copied. + /// The variable parent. Defaults to the current scope. + /// The mut variable entity. + public Entity MutVar(string name, ulong type, void* value, ulong parent = 0) + { + using NativeString nativeName = (NativeString)name; + + ecs_mut_var_desc_t desc = default; + desc.name = nativeName; + desc.parent = parent != 0 ? parent : ecs_get_scope(Handle); + desc.type = type; + desc.value = value; + + return new Entity(Handle, ecs_mut_var_init(Handle, &desc)); + } + + /// + /// Sets the value of a mut variable. Scripts that use the variable are reevaluated. + /// + /// The variable name. + /// The new value. + /// The value type. + /// Zero if success, non-zero if failed. + public int SetMutVar(string name, T value) where T : unmanaged + { + ulong var = LookupScriptVar(name); + + if (var == 0) + return -1; + + using NativeString nativePath = (NativeString)ecs_get_path_w_sep(Handle, 0, var, + Pointers.DefaultSeparator, null); + + return ecs_mut_var_set_w_type(Handle, nativePath, Type.Id(Handle), sizeof(T), &value); + } + + /// + /// Gets the value of a const variable. + /// + /// The variable name. + /// The value type. + /// The variable value, or the default value if the variable was not found. + public T GetConstVar(string name) where T : unmanaged + { + return GetConstVar(name, default(T)); + } + + /// + /// Gets the value of a const variable. + /// + /// The variable name. + /// The value returned when the variable was not found or cannot be cast. + /// The value type. + /// The variable value, or the default value if the variable was not found. + public T GetConstVar(string name, T defaultValue) where T : unmanaged + { + ulong var = LookupScriptVar(name); + + if (var == 0) + { + Ecs.Log.Warn($"Unresolved const variable '{name}', returning default"); + return defaultValue; + } + + return GetScriptVarValue(name, false, ecs_const_var_get(Handle, var), defaultValue); + } + + /// + /// Gets the value of a const variable as a string. + /// + /// The variable name. + /// The value returned when the variable was not found or cannot be cast. + /// The variable value, or the default value if the variable was not found. + public string GetConstVar(string name, string defaultValue = "") + { + ulong var = LookupScriptVar(name); + + if (var == 0) + { + Ecs.Log.Warn($"Unresolved const variable '{name}', returning default"); + return defaultValue; + } + + ecs_value_t value = ecs_const_var_get(Handle, var); + + if (value.ptr == null) + { + Ecs.Log.Warn($"Entity '{name}' is not a const variable, returning default"); + return defaultValue; + } + + ecs_meta_cursor_t cursor = ecs_meta_cursor(Handle, value.type, value.ptr); + byte* str = ecs_meta_get_string(&cursor); + + if (str == null) + { + Ecs.Log.Warn($"Cannot cast const variable '{name}' to a string, returning default"); + return defaultValue; + } + + return NativeString.GetString(str); + } + + /// + /// Gets the value of a mut variable. + /// + /// The variable name. + /// The value type. + /// The variable value, or the default value if the variable was not found. + public T GetMutVar(string name) where T : unmanaged + { + return GetMutVar(name, default(T)); + } + + /// + /// Gets the value of a mut variable. + /// + /// The variable name. + /// The value returned when the variable was not found or cannot be cast. + /// The value type. + /// The variable value, or the default value if the variable was not found. + public T GetMutVar(string name, T defaultValue) where T : unmanaged + { + ulong var = LookupScriptVar(name); + + if (var == 0) + { + Ecs.Log.Warn($"Unresolved mut variable '{name}', returning default"); + return defaultValue; + } + + return GetScriptVarValue(name, true, ecs_mut_var_get(Handle, var), defaultValue); + } + + private ulong LookupScriptVar(string name) + { + using NativeString nativeName = (NativeString)name; + return ecs_lookup_path_w_sep(Handle, 0, nativeName, Pointers.DefaultSeparator, + Pointers.DefaultSeparator, false); + } + + private T GetScriptVarValue(string name, bool mutable, ecs_value_t value, T defaultValue) + where T : unmanaged + { + string kind = mutable ? "mut" : "const"; + + if (value.ptr == null) + { + Ecs.Log.Warn($"Entity '{name}' is not a {kind} variable, returning default"); + return defaultValue; + } + + if (Type.Id(Handle) == value.type) + return *(T*)value.ptr; + + TypeCode typeCode = Type.GetTypeCode(typeof(T)); + + if (typeCode == TypeCode.Object || typeCode == TypeCode.Boolean) + { + Ecs.Log.Warn($"Cannot cast {kind} variable '{name}' to '{typeof(T).Name}', returning default"); + return defaultValue; + } + + ecs_meta_cursor_t cursor = ecs_meta_cursor(Handle, value.type, value.ptr); + + switch (typeCode) + { + case TypeCode.Char: + { + char v = (char)ecs_meta_get_char(&cursor); + return *(T*)&v; + } + case TypeCode.SByte: + { + sbyte v = (sbyte)ecs_meta_get_int(&cursor); + return *(T*)&v; + } + case TypeCode.Int16: + { + short v = (short)ecs_meta_get_int(&cursor); + return *(T*)&v; + } + case TypeCode.Int32: + { + int v = (int)ecs_meta_get_int(&cursor); + return *(T*)&v; + } + case TypeCode.Int64: + { + long v = ecs_meta_get_int(&cursor); + return *(T*)&v; + } + case TypeCode.Byte: + { + byte v = (byte)ecs_meta_get_uint(&cursor); + return *(T*)&v; + } + case TypeCode.UInt16: + { + ushort v = (ushort)ecs_meta_get_uint(&cursor); + return *(T*)&v; + } + case TypeCode.UInt32: + { + uint v = (uint)ecs_meta_get_uint(&cursor); + return *(T*)&v; + } + case TypeCode.UInt64: + { + ulong v = ecs_meta_get_uint(&cursor); + return *(T*)&v; + } + case TypeCode.Single: + { + float v = (float)ecs_meta_get_float(&cursor); + return *(T*)&v; + } + case TypeCode.Double: + { + double v = ecs_meta_get_float(&cursor); + return *(T*)&v; + } + default: + Ecs.Log.Warn($"Cannot cast {kind} variable '{name}' to '{typeof(T).Name}', returning default"); + return defaultValue; + } + } /// /// Convert value to string. /// @@ -3928,25 +4326,6 @@ public Entity Entity(Table table) return Entity(ecs_new_w_table(Handle, table)); } - /// - /// Set current with id. - /// - /// The id. - /// The previous id. - public Entity SetWith(ulong with) - { - return new Entity(Handle, ecs_set_with(Handle, with)); - } - - /// - /// Get current with id. - /// - /// The last id provided to ecs_set_with(). - public Entity GetWith() - { - return new Entity(Handle, ecs_get_with(Handle)); - } - /// /// All entities created in function are created in scope. All operations /// called in function (such as lookup) are relative to scope. @@ -3981,119 +4360,6 @@ public void Scope(T value, Ecs.WorldCallback callback) where T : Enum Scope(Type.Id(Handle, value), callback); } - /// - /// Defer all operations called in function. If the world is already in - /// deferred mode, do nothing. - /// - /// The callback. - public void Defer(Ecs.WorldCallback callback) - { - ecs_defer_begin(Handle); - callback(Handle); - ecs_defer_end(Handle); - } - - /// - /// All entities created in function are created with id. - /// - /// Id to be added to the created entities. - /// The callback. - public void With(ulong id, Ecs.WorldCallback callback) - { - ulong prev = ecs_set_with(Handle, id); - callback(Handle); - ecs_set_with(Handle, prev); - } - - /// - /// All entities created in function are created with pair. - /// - /// The first id. - /// The second id. - /// The callback. - public void With(ulong first, ulong second, Ecs.WorldCallback callback) - { - With(Ecs.Pair(first, second), callback); - } - - /// - /// All entities created in function are created with type. - /// - /// The callback. - /// The component. - public void With(Ecs.WorldCallback callback) - { - With(Type.Id(Handle), callback); - } - - /// - /// All entities created in function are created with enum. - /// - /// The enum constant. - /// The callback. - /// The enum. - public void With(T value, Ecs.WorldCallback callback) where T : Enum - { - With(Type.Id(Handle, value), callback); - } - - /// - /// All entities created in function are created with pair. - /// - /// The second id. - /// The callback. - /// The first component. - public void With(ulong second, Ecs.WorldCallback callback) - { - With(Ecs.Pair(second, Handle), callback); - } - - /// - /// All entities created in function are created with pair. - /// - /// The callback. - /// The first component. - /// The second component. - public void With(Ecs.WorldCallback callback) - { - With(Ecs.Pair(Handle), callback); - } - - /// - /// All entities created in function are created with pair. - /// - /// The second enum constant id. - /// The callback. - /// The first component. - /// The second enum. - public void With(TSecond second, Ecs.WorldCallback callback) where TSecond : Enum - { - With(Type.Id(Handle, second), callback); - } - - /// - /// All entities created in function are created with pair. - /// - /// The first enum constant. - /// The callback. - /// The first enum. - /// The second component. - public void With(TFirst first, Ecs.WorldCallback callback) where TFirst : Enum - { - WithSecond(Type.Id(Handle, first), callback); - } - - /// - /// All entities created in function are created with pair. - /// - /// The first id. - /// The callback. - /// The second component. - public void WithSecond(ulong first, Ecs.WorldCallback callback) - { - With(first, Type.Id(Handle), callback); - } - /// /// Lookup entity by name. ///