diff --git a/.gitignore b/.gitignore index 37d59e5..b2bb707 100644 --- a/.gitignore +++ b/.gitignore @@ -71,4 +71,7 @@ crashlytics-build.properties /[Aa]ssets/[Ss]treamingAssets/aa.meta /[Aa]ssets/[Ss]treamingAssets/aa/* -.vscode \ No newline at end of file +.vscode + +RTBTemp +dump \ No newline at end of file diff --git a/Assets/Editor/EcsactSettings.asset b/Assets/Editor/EcsactSettings.asset index ad64309..8fcf6d2 100644 --- a/Assets/Editor/EcsactSettings.asset +++ b/Assets/Editor/EcsactSettings.asset @@ -13,6 +13,7 @@ MonoBehaviour: m_Name: EcsactSettings m_EditorClassIdentifier: runtimeBuilderOutputPath: Assets/Plugins/EcsactRuntime + runtimeBuilderTempDirectory: RTBTemp runtimeBuilderDebugBuild: 1 runtimeBuilderPrintSubcommandStdout: 1 runtimeBuilderPrintSubcommandStderr: 1 diff --git a/Assets/Plugins/EcsactRuntime.dll b/Assets/Plugins/EcsactRuntime.dll index 3016cea..633e386 100644 Binary files a/Assets/Plugins/EcsactRuntime.dll and b/Assets/Plugins/EcsactRuntime.dll differ diff --git a/Assets/Plugins/EcsactRuntime.lib b/Assets/Plugins/EcsactRuntime.lib new file mode 100644 index 0000000..f817714 Binary files /dev/null and b/Assets/Plugins/EcsactRuntime.lib differ diff --git a/Assets/Plugins/EcsactRuntime.lib.meta b/Assets/Plugins/EcsactRuntime.lib.meta new file mode 100644 index 0000000..9caa746 --- /dev/null +++ b/Assets/Plugins/EcsactRuntime.lib.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a45f1e8ab4e71b248915e11ca883e60b +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Settings/EcsactRuntimeSettings.asset b/Assets/Resources/Settings/EcsactRuntimeSettings.asset index d972380..94e96d6 100644 --- a/Assets/Resources/Settings/EcsactRuntimeSettings.asset +++ b/Assets/Resources/Settings/EcsactRuntimeSettings.asset @@ -26,7 +26,7 @@ MonoBehaviour: - scriptEnabled: 1 scriptAssemblyQualifiedName: SyncMove, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null - systemImplSource: 0 + systemImplSource: 1 defaultCsharpSystemImplsAssemblyName: ExampleAssembly runtimeLibraryPaths: - Assets/Plugins/EcsactRuntime diff --git a/Assets/Resources/Settings/EcsactWasmRuntimeSettings.asset b/Assets/Resources/Settings/EcsactWasmRuntimeSettings.asset index 10e454b..432bc56 100644 --- a/Assets/Resources/Settings/EcsactWasmRuntimeSettings.asset +++ b/Assets/Resources/Settings/EcsactWasmRuntimeSettings.asset @@ -12,39 +12,23 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 61f6048043c761b47b4e0be2b0a0e30e, type: 3} m_Name: EcsactWasmRuntimeSettings m_EditorClassIdentifier: - useDefaultLoader: 0 autoFindSystemImpls: 1 wasmSystemEntries: - - systemId: 13 - wasmAsset: {fileID: 0} - wasmExportName: - - systemId: 14 - wasmAsset: {fileID: 0} - wasmExportName: + - systemId: 10 + wasmAsset: {fileID: 8505064800252710765, guid: 31649f2d7b0ad8c418d73f15f5ea95b9, type: 3} + wasmExportName: example__Move - systemId: 15 - wasmAsset: {fileID: 0} - wasmExportName: - - systemId: 16 - wasmAsset: {fileID: 0} - wasmExportName: - - systemId: 22 - wasmAsset: {fileID: 0} - wasmExportName: + wasmAsset: {fileID: 8505064800252710765, guid: 31649f2d7b0ad8c418d73f15f5ea95b9, type: 3} + wasmExportName: example__PerformGenerateBlock - systemId: 3 - wasmAsset: {fileID: 0} - wasmExportName: - - systemId: 17 - wasmAsset: {fileID: 0} - wasmExportName: - - systemId: 18 - wasmAsset: {fileID: 0} - wasmExportName: - - systemId: 20 - wasmAsset: {fileID: 0} - wasmExportName: - - systemId: 21 - wasmAsset: {fileID: 0} - wasmExportName: - - systemId: 23 - wasmAsset: {fileID: 0} - wasmExportName: + wasmAsset: {fileID: 8505064800252710765, guid: 31649f2d7b0ad8c418d73f15f5ea95b9, type: 3} + wasmExportName: example__AddToExample + - systemId: 13 + wasmAsset: {fileID: 8505064800252710765, guid: 31649f2d7b0ad8c418d73f15f5ea95b9, type: 3} + wasmExportName: example__ApplyVelocity + - systemId: 16 + wasmAsset: {fileID: 8505064800252710765, guid: 31649f2d7b0ad8c418d73f15f5ea95b9, type: 3} + wasmExportName: example__GenerateBlock + - systemId: 12 + wasmAsset: {fileID: 8505064800252710765, guid: 31649f2d7b0ad8c418d73f15f5ea95b9, type: 3} + wasmExportName: example__CollisionComparer__CheckCollision diff --git a/Assets/Scripts/Systems/UnityExamples.wasm b/Assets/Scripts/Systems/UnityExamples.wasm new file mode 100644 index 0000000..4f92f02 Binary files /dev/null and b/Assets/Scripts/Systems/UnityExamples.wasm differ diff --git a/Assets/Scripts/Systems/UnityExamples.wasm.meta b/Assets/Scripts/Systems/UnityExamples.wasm.meta new file mode 100644 index 0000000..94124d3 --- /dev/null +++ b/Assets/Scripts/Systems/UnityExamples.wasm.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 31649f2d7b0ad8c418d73f15f5ea95b9 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/manifest.json b/Packages/manifest.json index 64b8127..68a4669 100644 --- a/Packages/manifest.json +++ b/Packages/manifest.json @@ -1,5 +1,6 @@ { "dependencies": { + "com.seaube.unity-wasm": "https://github.com/seaube/unity-wasm.git", "com.unity.collab-proxy": "1.17.2", "com.unity.feature.2d": "1.0.0", "com.unity.ide.rider": "3.0.15", @@ -12,7 +13,7 @@ "com.unity.timeline": "1.6.4", "com.unity.ugui": "1.0.0", "com.unity.visualscripting": "1.7.8", - "dev.ecsact.unity": "https://github.com/ecsact-dev/ecsact_unity.git", + "dev.ecsact.unity": "file:C:/programming/ecsact-unity", "com.unity.modules.ai": "1.0.0", "com.unity.modules.androidjni": "1.0.0", "com.unity.modules.animation": "1.0.0", diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index f926577..85e0023 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -1,5 +1,12 @@ { "dependencies": { + "com.seaube.unity-wasm": { + "version": "https://github.com/seaube/unity-wasm.git", + "depth": 0, + "source": "git", + "dependencies": {}, + "hash": "38ebddd90e653bf3cc3cf03aac2a569f059e935d" + }, "com.unity.2d.animation": { "version": "7.0.7", "depth": 1, @@ -279,14 +286,13 @@ "url": "https://packages.unity.com" }, "dev.ecsact.unity": { - "version": "https://github.com/ecsact-dev/ecsact_unity.git", + "version": "file:C:/programming/ecsact-unity", "depth": 0, - "source": "git", + "source": "local", "dependencies": { "com.unity.editorcoroutines": "1.0.0", "com.unity.visualscripting": "1.7.8" - }, - "hash": "bf5e4211504bcfcdc29c42ad94e28835c3c6863d" + } }, "com.unity.modules.ai": { "version": "1.0.0", diff --git a/SystemImpls/WasmExample.ps1 b/SystemImpls/WasmExample.ps1 new file mode 100644 index 0000000..9fe8862 --- /dev/null +++ b/SystemImpls/WasmExample.ps1 @@ -0,0 +1,11 @@ +$EcsactInc = (ecsact config include_dir) +emcc -O2 -std=c++20 --no-entry -I"$EcsactInc" ` + -sEXPORTED_FUNCTIONS="_example__PerformGenerateBlock,_example__GenerateBlock,_example__AddToExample,_example__Move,_example__ApplyVelocity,_example__CollisionComparer__CheckCollision" ` + -sERROR_ON_UNDEFINED_SYMBOLS=0 ` + -Wno-js-compiler ` + -o ../Assets/Scripts/Systems/UnityExamples.wasm ` + generate_block_system.cc ` + basic_example.cc ` + move.cc ` + collision.cc ` + example.ecsact.systems.cc \ No newline at end of file diff --git a/SystemImpls/basic_example.cc b/SystemImpls/basic_example.cc new file mode 100644 index 0000000..d07fce9 --- /dev/null +++ b/SystemImpls/basic_example.cc @@ -0,0 +1,17 @@ +#include "example.ecsact.hh" +#include "example.ecsact.systems.hh" + +// The system implement of our AddToExample system +void example::AddToExample::impl(context& ctx) { + // Get a component from the context + auto value = ctx.get(); + + // Modify and update its value + value.example_value +=1; + ctx.update(value); + + if(value.example_value >= 100) { + // Remove the component from the context + ctx.remove(); + } +} diff --git a/SystemImpls/collision.cc b/SystemImpls/collision.cc new file mode 100644 index 0000000..355c874 --- /dev/null +++ b/SystemImpls/collision.cc @@ -0,0 +1,35 @@ +#include "example.ecsact.hh" +#include "example.ecsact.systems.hh" + +void example::CollisionComparer::CheckCollision::impl(context& ctx) { + if(ctx._ctx.same(ctx._ctx.parent())) return; + + auto position = ctx.get(); + auto velocity = ctx.get(); + + auto otherPos = ctx._ctx.parent().get(); + auto other_collider = ctx._ctx.parent().get(); + + auto xDiff = std::abs(position.x - otherPos.x); + auto yDiff = std::abs(position.y - otherPos.y); + + if(xDiff <= other_collider.x_radius && yDiff <= other_collider.y_radius) { + position.x = position.prev_x; + position.y = position.prev_y; + + if(position.x < otherPos.x) { + velocity.x_value = -0.5f; + } else { + velocity.x_value = 0.5f; + } + + if(position.y < otherPos.y) { + velocity.y_value = -0.5f; + } else { + velocity.y_value = 0.5f; + } + + ctx.update(velocity); + ctx.update(position); + } +} diff --git a/SystemImpls/example.ecsact.hh b/SystemImpls/example.ecsact.hh new file mode 100644 index 0000000..1999317 --- /dev/null +++ b/SystemImpls/example.ecsact.hh @@ -0,0 +1,114 @@ +// GENERATED FILE - DO NOT EDIT +#pragma once + +#include +#include +#include "ecsact/runtime/common.h" + +namespace example { + +struct Example { + static constexpr bool transient = false; + static constexpr auto id = static_cast(1); + int32_t example_value; + auto operator<=>(const example::Example&) const = default; +}; +struct ToBeRemoved { + static constexpr bool transient = false; + static constexpr auto id = static_cast(2); + auto operator<=>(const example::ToBeRemoved&) const = default; +}; +struct CanMove { + static constexpr bool transient = false; + static constexpr auto id = static_cast(4); + auto operator<=>(const example::CanMove&) const = default; +}; +struct Velocity { + static constexpr bool transient = false; + static constexpr auto id = static_cast(5); + float x_value; + float y_value; + float speed; + auto operator<=>(const example::Velocity&) const = default; +}; +struct Position { + static constexpr bool transient = false; + static constexpr auto id = static_cast(6); + float x; + float y; + float prev_x; + float prev_y; + auto operator<=>(const example::Position&) const = default; +}; +struct Collider { + static constexpr bool transient = false; + static constexpr auto id = static_cast(7); + int32_t x_radius; + int32_t y_radius; + auto operator<=>(const example::Collider&) const = default; +}; +struct Block { + static constexpr bool transient = false; + static constexpr auto id = static_cast(8); + auto operator<=>(const example::Block&) const = default; +}; +struct BlockGenerator { + static constexpr bool transient = false; + static constexpr auto id = static_cast(9); + auto operator<=>(const example::BlockGenerator&) const = default; +}; +struct QueueBlock { + static constexpr bool transient = false; + static constexpr auto id = static_cast(14); + int32_t pos_x; + int32_t pos_y; + auto operator<=>(const example::QueueBlock&) const = default; +}; +struct Move { + static constexpr auto id = static_cast(10); + struct context; + static void impl(context&); + float dir_x; + float dir_y; + auto operator<=>(const example::Move&) const = default; +}; +struct PerformGenerateBlock { + static constexpr auto id = static_cast(15); + struct context; + static void impl(context&); + int32_t pos_x; + int32_t pos_y; + auto operator<=>(const example::PerformGenerateBlock&) const = default; +}; +struct AddToExample { + static constexpr auto id = static_cast(3); + struct context; + static void impl(context&); +}; +struct CollisionComparer { + static constexpr auto id = static_cast(11); + struct CheckCollision { + static constexpr auto id = static_cast(12); + struct context; + static void impl(context&); + }; + struct context; + static void impl(context&); +}; +struct ApplyVelocity { + static constexpr auto id = static_cast(13); + struct context; + static void impl(context&); +}; +struct GenerateBlock { + static constexpr auto id = static_cast(16); + struct context; + static void impl(context&); +}; +struct RemoveQueueBlock { + static constexpr auto id = static_cast(18); + struct context; + static void impl(context&); +}; + +}// namespace example diff --git a/SystemImpls/example.ecsact.systems.cc b/SystemImpls/example.ecsact.systems.cc new file mode 100644 index 0000000..538c35f --- /dev/null +++ b/SystemImpls/example.ecsact.systems.cc @@ -0,0 +1,34 @@ +// GENERATED FILE - DO NOT EDIT +#include "example.ecsact.systems.hh" +void example__AddToExample(struct ecsact_system_execution_context* cctx) { + example::AddToExample::context ctx{cctx}; + example::AddToExample::impl(ctx); +} +void example__CollisionComparer(struct ecsact_system_execution_context* cctx) { + example::CollisionComparer::context ctx{cctx}; + example::CollisionComparer::impl(ctx); +} +void example__CollisionComparer__CheckCollision(struct ecsact_system_execution_context* cctx) { + example::CollisionComparer::CheckCollision::context ctx{cctx}; + example::CollisionComparer::CheckCollision::impl(ctx); +} +void example__ApplyVelocity(struct ecsact_system_execution_context* cctx) { + example::ApplyVelocity::context ctx{cctx}; + example::ApplyVelocity::impl(ctx); +} +void example__GenerateBlock(struct ecsact_system_execution_context* cctx) { + example::GenerateBlock::context ctx{cctx}; + example::GenerateBlock::impl(ctx); +} +void example__RemoveQueueBlock(struct ecsact_system_execution_context* cctx) { + example::RemoveQueueBlock::context ctx{cctx}; + example::RemoveQueueBlock::impl(ctx); +} +void example__Move(struct ecsact_system_execution_context* cctx) { + example::Move::context ctx{cctx}; + example::Move::impl(ctx); +} +void example__PerformGenerateBlock(struct ecsact_system_execution_context* cctx) { + example::PerformGenerateBlock::context ctx{cctx}; + example::PerformGenerateBlock::impl(ctx); +} diff --git a/SystemImpls/example.ecsact.systems.h b/SystemImpls/example.ecsact.systems.h new file mode 100644 index 0000000..c50b10b --- /dev/null +++ b/SystemImpls/example.ecsact.systems.h @@ -0,0 +1,21 @@ +// GENERATED FILE - DO NOT EDIT +#ifndef EXAMPLE_H +#define EXAMPLE_H + +#ifdef __cplusplus +# define ECSACT_SYSTEM_EXTERN extern "C" +#else +# define ECSACT_SYSTEM_EXTERN extern +#endif + +ECSACT_SYSTEM_EXTERN void example__Move(struct ecsact_system_execution_context*); +ECSACT_SYSTEM_EXTERN void example__PerformGenerateBlock(struct ecsact_system_execution_context*); +ECSACT_SYSTEM_EXTERN void example__AddToExample(struct ecsact_system_execution_context*); +ECSACT_SYSTEM_EXTERN void example__CollisionComparer(struct ecsact_system_execution_context*); +ECSACT_SYSTEM_EXTERN void example__CollisionComparer__CheckCollision(struct ecsact_system_execution_context*); +ECSACT_SYSTEM_EXTERN void example__ApplyVelocity(struct ecsact_system_execution_context*); +ECSACT_SYSTEM_EXTERN void example__GenerateBlock(struct ecsact_system_execution_context*); +ECSACT_SYSTEM_EXTERN void example__RemoveQueueBlock(struct ecsact_system_execution_context*); + +#undef ECSACT_SYSTEM_EXTERN +#endif//EXAMPLE_H diff --git a/SystemImpls/example.ecsact.systems.hh b/SystemImpls/example.ecsact.systems.hh new file mode 100644 index 0000000..978cebc --- /dev/null +++ b/SystemImpls/example.ecsact.systems.hh @@ -0,0 +1,377 @@ +// GENERATED FILE - DO NOT EDIT +#pragma once + +#include +#include "ecsact/cpp/execution_context.hh" +#include "example.ecsact.hh" +#include "example.ecsact.systems.h" + +struct ecsact_system_execution_context; + +struct example::AddToExample::context { + [[no_unique_address]] + ::ecsact::execution_context _ctx; + template + T get() { + // local type to make static assert always fail + struct red_herring {}; + static_assert(std::is_same_v, R"( + + | [Ecsact C++ Error]: System Execution Context Misuse + | + | example.AddToExample context.get may only be called with a component + | readable by the system. Did you forget to add readonly or readwrite capabilities? + | The following components are allowed: + | - example.Example + | )"); + } + template + void update(const T& updated_component) { + // local type to make static assert always fail + struct red_herring {}; + static_assert(std::is_same_v, R"( + + | [Ecsact C++ Error]: System Execution Context Misuse + | + | example.AddToExample context.update may only be called with a component + | writable by the system. Did you forget to add readwrite capabilities? The + | following components are allowed: + | - example.Example + | )"); + } + template + void remove() { + // local type to make static assert always fail + struct red_herring {}; + static_assert(std::is_same_v, R"( + + | [Ecsact C++ Error]: System Execution Context Misuse + | + | example.AddToExample context.remove may only be called with a component + | removable by the system. Did you forget to add removes capabilities? The + | following components are allowed: + | - example.ToBeRemoved + | )"); + } + + + template<> example::Example get() { + return _ctx.get(); + } + template<> void update(const example::Example& updated_component) { + _ctx.update(updated_component); + } + template<> void remove() { + return _ctx.remove(); + } + ecsact_entity_id entity() const { + return _ctx.entity(); + } +}; + +struct example::CollisionComparer::context { + [[no_unique_address]] + ::ecsact::execution_context _ctx; + template + T get() { + // local type to make static assert always fail + struct red_herring {}; + static_assert(std::is_same_v, R"( + + | [Ecsact C++ Error]: System Execution Context Misuse + | + | example.CollisionComparer context.get may only be called with a component + | readable by the system. Did you forget to add readonly or readwrite + | capabilities? The following components are allowed: + | - example.Position + | - example.Collider + | )"); + } + + + template<> example::Position get() { + return _ctx.get(); + } + template<> example::Collider get() { + return _ctx.get(); + } + ecsact_entity_id entity() const { + return _ctx.entity(); + } +}; + +struct example::CollisionComparer::CheckCollision::context { + [[no_unique_address]] + ::ecsact::execution_context _ctx; + template + T get() { + // local type to make static assert always fail + struct red_herring {}; + static_assert(std::is_same_v, R"( + + | [Ecsact C++ Error]: System Execution Context Misuse + | + | example.CollisionComparer.CheckCollision context.get may only be called + | with a component readable by the system. Did you forget to add readonly or + | readwrite capabilities? The following components are allowed: + | - example.Velocity + | - example.Position + | - example.Collider + | )"); + } + template + void update(const T& updated_component) { + // local type to make static assert always fail + struct red_herring {}; + static_assert(std::is_same_v, R"( + + | [Ecsact C++ Error]: System Execution Context Misuse + | + | example.CollisionComparer.CheckCollision context.update may only be + | called with a component writable by the system. Did you forget to add readwrite + | capabilities? The following components are allowed: + | - example.Velocity + | - example.Position + | - example.Collider + | )"); + } + const example::CollisionComparer::context parent() const; + + + template<> example::Velocity get() { + return _ctx.get(); + } + template<> example::Position get() { + return _ctx.get(); + } + template<> example::Collider get() { + return _ctx.get(); + } + template<> void update(const example::Velocity& updated_component) { + _ctx.update(updated_component); + } + template<> void update(const example::Position& updated_component) { + _ctx.update(updated_component); + } + template<> void update(const example::Collider& updated_component) { + _ctx.update(updated_component); + } + ecsact_entity_id entity() const { + return _ctx.entity(); + } +}; + +struct example::ApplyVelocity::context { + [[no_unique_address]] + ::ecsact::execution_context _ctx; + template + T get() { + // local type to make static assert always fail + struct red_herring {}; + static_assert(std::is_same_v, R"( + + | [Ecsact C++ Error]: System Execution Context Misuse + | + | example.ApplyVelocity context.get may only be called with a component + | readable by the system. Did you forget to add readonly or readwrite capabilities? + | The following components are allowed: + | - example.Velocity + | - example.Position + | )"); + } + template + void update(const T& updated_component) { + // local type to make static assert always fail + struct red_herring {}; + static_assert(std::is_same_v, R"( + + | [Ecsact C++ Error]: System Execution Context Misuse + | + | example.ApplyVelocity context.update may only be called with a component + | writable by the system. Did you forget to add readwrite capabilities? The + | following components are allowed: + | - example.Velocity + | - example.Position + | )"); + } + + + template<> example::Velocity get() { + return _ctx.get(); + } + template<> example::Position get() { + return _ctx.get(); + } + template<> void update(const example::Velocity& updated_component) { + _ctx.update(updated_component); + } + template<> void update(const example::Position& updated_component) { + _ctx.update(updated_component); + } + ecsact_entity_id entity() const { + return _ctx.entity(); + } +}; + +struct example::GenerateBlock::context { + [[no_unique_address]] + ::ecsact::execution_context _ctx; + template + T get() { + // local type to make static assert always fail + struct red_herring {}; + static_assert(std::is_same_v, R"( + + | [Ecsact C++ Error]: System Execution Context Misuse + | + | example.GenerateBlock context.get may only be called with a component + | readable by the system. Did you forget to add readonly or readwrite capabilities? + | The following components are allowed: + | - example.QueueBlock + | )"); + } + template + void update(const T& updated_component) { + // local type to make static assert always fail + struct red_herring {}; + static_assert(std::is_same_v, R"( + + | [Ecsact C++ Error]: System Execution Context Misuse + | + | example.GenerateBlock context.update may only be called with a component + | writable by the system. Did you forget to add readwrite capabilities? The + | following components are allowed: + | - example.QueueBlock + | )"); + } + + + template<> example::QueueBlock get() { + return _ctx.get(); + } + template<> void update(const example::QueueBlock& updated_component) { + _ctx.update(updated_component); + } + ecsact_entity_id entity() const { + return _ctx.entity(); + } +}; + +struct example::RemoveQueueBlock::context { + [[no_unique_address]] + ::ecsact::execution_context _ctx; + template + void remove() { + // local type to make static assert always fail + struct red_herring {}; + static_assert(std::is_same_v, R"( + + | [Ecsact C++ Error]: System Execution Context Misuse + | + | example.RemoveQueueBlock context.remove may only be called with a + | component removable by the system. Did you forget to add removes capabilities? The + | following components are allowed: + | - example.QueueBlock + | )"); + } + + + template<> void remove() { + return _ctx.remove(); + } + ecsact_entity_id entity() const { + return _ctx.entity(); + } +}; + +struct example::Move::context { + [[no_unique_address]] + ::ecsact::execution_context _ctx; + template + T get() { + // local type to make static assert always fail + struct red_herring {}; + static_assert(std::is_same_v, R"( + + | [Ecsact C++ Error]: System Execution Context Misuse + | + | example.Move context.get may only be called with a component readable by + | the system. Did you forget to add readonly or readwrite capabilities? The + | following components are allowed: + | - example.Velocity + | )"); + } + template + void update(const T& updated_component) { + // local type to make static assert always fail + struct red_herring {}; + static_assert(std::is_same_v, R"( + + | [Ecsact C++ Error]: System Execution Context Misuse + | + | example.Move context.update may only be called with a component writable + | by the system. Did you forget to add readwrite capabilities? The following + | components are allowed: + | - example.Velocity + | )"); + } + + + template<> example::Velocity get() { + return _ctx.get(); + } + template<> void update(const example::Velocity& updated_component) { + _ctx.update(updated_component); + } + ecsact_entity_id entity() const { + return _ctx.entity(); + } + example::Move action() const { + return _ctx.action(); + } +}; + +struct example::PerformGenerateBlock::context { + [[no_unique_address]] + ::ecsact::execution_context _ctx; + template + requires(!std::is_empty_v) + void add(const T& new_component) { + // local type to make static assert always fail + struct red_herring {}; + static_assert(std::is_same_v, R"( + + | [Ecsact C++ Error]: System Execution Context Misuse + | + | example.PerformGenerateBlock context.add may only be called with a + | component addable by the system. Did you forget to add adds capabilities? The + | following components are allowed: + | - example.QueueBlock + | )"); + } + template + void add() { + // local type to make static assert always fail + struct red_herring {}; + static_assert(std::is_same_v, R"( + + | [Ecsact C++ Error]: System Execution Context Misuse + | + | example.PerformGenerateBlock context.add may only be called with a + | component addable by the system. Did you forget to add adds capabilities? The + | following components are allowed: + | - example.QueueBlock + | )"); + } + + + template<> void add(const example::QueueBlock& new_component) { + _ctx.add(new_component); + } + ecsact_entity_id entity() const { + return _ctx.entity(); + } + example::PerformGenerateBlock action() const { + return _ctx.action(); + } +}; diff --git a/SystemImpls/generate_block_system.cc b/SystemImpls/generate_block_system.cc new file mode 100644 index 0000000..227a94b --- /dev/null +++ b/SystemImpls/generate_block_system.cc @@ -0,0 +1,25 @@ +#include "example.ecsact.hh" +#include "example.ecsact.systems.hh" + +void example::PerformGenerateBlock::impl(context& ctx) { + auto action = ctx.action(); + ctx.add(QueueBlock { + .pos_x = action.pos_x, + .pos_y = action.pos_y + }); +} + +void example::GenerateBlock::impl(context& ctx) { + auto block = ctx.get(); + + ctx._ctx.generate( + CanMove{}, + Block{}, + Position{ + .x = static_cast(block.pos_x), + .y = static_cast(block.pos_y) + }, + Collider{.x_radius = 4, .y_radius = 4}, + Velocity{.x_value = 0, .y_value = 0, .speed = 0.1f} + ); +} diff --git a/SystemImpls/move.cc b/SystemImpls/move.cc new file mode 100644 index 0000000..8868818 --- /dev/null +++ b/SystemImpls/move.cc @@ -0,0 +1,25 @@ +#include "example.ecsact.hh" +#include "example.ecsact.systems.hh" + +void example::Move::impl(context& ctx) { + auto velocity = ctx.get(); + auto move = ctx.action(); + + velocity.x_value = move.dir_x; + velocity.y_value = move.dir_y; + + ctx.update(velocity); +} + +void example::ApplyVelocity::impl(context& ctx) { + auto position = ctx.get(); + auto velocity = ctx.get(); + + position.prev_x = position.x; + position.prev_y = position.y; + + position.x += velocity.x_value; + position.y += velocity.y_value; + + ctx.update(position); +}