Skip to content

Commit 2a1a4bd

Browse files
committed
feat: manual custom runner and ecsact wasm api fns
1 parent 65edc5c commit 2a1a4bd

File tree

8 files changed

+112
-23
lines changed

8 files changed

+112
-23
lines changed

Source/Ecsact/Ecsact.Build.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ public Ecsact(ReadOnlyTargetRules Target) : base(Target) {
6565
"ECSACT_META_API_LOAD_AT_RUNTIME",
6666
"ECSACT_SERIALIZE_API_LOAD_AT_RUNTIME",
6767
"ECSACT_STATIC_API_LOAD_AT_RUNTIME",
68+
"ECSACTSI_WASM_API_LOAD_AT_RUNTIME",
6869
});
6970
PrivateDefinitions.AddRange(new string[] {
7071
"ECSACT_CORE_API_EXPORT",
@@ -73,6 +74,7 @@ public Ecsact(ReadOnlyTargetRules Target) : base(Target) {
7374
"ECSACT_META_API_EXPORT",
7475
"ECSACT_SERIALIZE_API_EXPORT",
7576
"ECSACT_STATIC_API_EXPORT",
77+
"ECSACTSI_WASM_API_EXPORT",
7678
});
7779

7880
var EcsactSources = GetEcsactSources();

Source/Ecsact/Private/EcsactGameInstanceSubsystem.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,12 @@ auto UEcsactGameInstanceSubsystem::StopRunner() -> void {
126126
runner->Stop();
127127
Runner.Reset();
128128
}
129+
130+
auto UEcsactGameInstanceSubsystem::CanStartCustomRunner() const -> bool {
131+
const auto* settings = GetDefault<UEcsactSettings>();
132+
if(settings->Runner == EEcsactRuntimeRunnerType::Custom) {
133+
return !settings->CustomRunnerClass;
134+
}
135+
136+
return false;
137+
}

Source/Ecsact/Private/EcsactGameInstanceSubsystem.h

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
#pragma once
22

3+
#include "EcsactUnreal/Ecsact.h"
4+
#include "EcsactUnreal/EcsactRunner.h"
5+
#include "Engine/World.h"
36
#include "Subsystems/GameInstanceSubsystem.h"
47
#include "EcsactUnreal/RuntimeHandle.h"
58
#include "EcsactGameInstanceSubsystem.generated.h"
69

710
UCLASS()
811

9-
class UEcsactGameInstanceSubsystem : public UGameInstanceSubsystem {
12+
class ECSACT_API UEcsactGameInstanceSubsystem : public UGameInstanceSubsystem {
1013
GENERATED_BODY() // NOLINT
1114

1215
friend class EcsactUnrealExecution;
@@ -29,4 +32,54 @@ class UEcsactGameInstanceSubsystem : public UGameInstanceSubsystem {
2932
public:
3033
auto Initialize(FSubsystemCollectionBase& Collection) -> void override;
3134
auto Deinitialize() -> void override;
35+
36+
/**
37+
* @returns true if runtime runner type is 'Custom' and the custom runner
38+
* class is `None`.
39+
*/
40+
auto CanStartCustomRunner() const -> bool;
41+
42+
/**
43+
* Instantiates and starts a custom runner of type @t RunnerT. May only be
44+
* called `CanStartCustomRunner()` returns `true.
45+
*/
46+
template<typename RunnerT>
47+
auto StartCustomRunner() -> void {
48+
if(Runner.IsValid()) {
49+
UE_LOG(
50+
Ecsact,
51+
Error,
52+
TEXT("An Ecsact runner has already started - only one runner may be "
53+
"running per game instance world.")
54+
);
55+
return;
56+
}
57+
58+
auto world = GetWorld();
59+
check(world);
60+
if(!CanStartCustomRunner()) {
61+
UE_LOG(
62+
Ecsact,
63+
Error,
64+
TEXT("Cannot start custom ecsact runner - please make sure runner type "
65+
"is set to 'Custom' and the custom runner class is set to 'None' "
66+
"in the unreal Ecsact plugin settings.")
67+
);
68+
return;
69+
}
70+
71+
Runner = NewObject<RunnerT>();
72+
73+
if(auto RunnerPtr = Runner.Get(); RunnerPtr) {
74+
UE_LOG(
75+
Ecsact,
76+
Log,
77+
TEXT("Starting custom ecsact runner: %s"),
78+
*RunnerPtr->GetClass()->GetName()
79+
);
80+
RunnerPtr->World = world;
81+
RunnerPtr->AddToRoot();
82+
RunnerPtr->Start();
83+
}
84+
}
3285
};

Source/Ecsact/Public/EcsactUnreal/Ecsact.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "Misc/Paths.h"
88
#include "EcsactUnreal/EcsactAsyncRunner.h"
99
#include "ecsact/runtime.h"
10+
#include "ecsact/wasm.h"
1011
#include "Engine/World.h"
1112

1213
#define LOCTEXT_NAMESPACE "FEcsactModule"
@@ -15,6 +16,7 @@ DEFINE_LOG_CATEGORY(Ecsact);
1516

1617
#define INIT_ECSACT_API_FN(fn, UNUSED_PARAM) decltype(fn) fn = nullptr
1718
FOR_EACH_ECSACT_API_FN(INIT_ECSACT_API_FN, UNUSED_PARAM);
19+
FOR_EACH_ECSACTSI_WASM_API_FN(INIT_ECSACT_API_FN, UNUSED_PARAM);
1820
#undef INIT_ECSACT_API_FN
1921

2022
FEcsactModule* FEcsactModule::Self = nullptr;

Source/Ecsact/Public/EcsactUnreal/Ecsact.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#include "UObject/WeakObjectPtr.h"
77
#include "EcsactUnreal/RuntimeHandle.h"
88

9-
DECLARE_LOG_CATEGORY_EXTERN(Ecsact, Log, All);
9+
ECSACT_API DECLARE_LOG_CATEGORY_EXTERN(Ecsact, Log, All);
1010

1111
namespace EcsactUnreal::Detail {
1212
auto CheckRuntimeNotLoaded(FEcsactModule&) -> bool;

Source/Ecsact/Public/EcsactUnreal/EcsactSyncRunner.cpp

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,47 @@ auto UEcsactSyncRunner::Tick(float DeltaTime) -> void {
2626
EcsactUnrealExecution::DeltaTime_ = DeltaTime;
2727

2828
if(registry_id == ECSACT_INVALID_ID(registry)) {
29-
UE_LOG(
30-
Ecsact,
31-
Warning,
32-
TEXT("UEcsactSyncRunner register_id is unset. Creating one for you. We "
33-
"recommend creating your own instead.")
34-
);
35-
registry_id = ecsact_create_registry("Default Registry");
29+
if(ecsact_create_registry) {
30+
UE_LOG(
31+
Ecsact,
32+
Warning,
33+
TEXT("UEcsactSyncRunner register_id is unset. Creating one for you. We "
34+
"recommend creating your own instead.")
35+
);
36+
registry_id = ecsact_create_registry("Default Registry");
37+
} else {
38+
UE_LOG(
39+
Ecsact,
40+
Error,
41+
TEXT("UEcsactSyncRunner registry_id is unset and "
42+
"ecsact_create_registry is unavailable - unable to automatically "
43+
"create an Ecsact registry")
44+
);
45+
}
3646
}
3747

38-
ecsact_execution_options* exec_opts = nullptr;
39-
if(ExecutionOptions != nullptr && ExecutionOptions->IsNotEmpty()) {
40-
exec_opts = ExecutionOptions->GetCPtr();
41-
}
48+
if(registry_id != ECSACT_INVALID_ID(registry)) {
49+
ecsact_execution_options* exec_opts = nullptr;
50+
if(ExecutionOptions != nullptr && ExecutionOptions->IsNotEmpty()) {
51+
exec_opts = ExecutionOptions->GetCPtr();
52+
}
4253

43-
auto err =
44-
ecsact_execute_systems(registry_id, 1, exec_opts, GetEventsCollector());
45-
if(err != ECSACT_EXEC_SYS_OK) {
46-
UE_LOG(Ecsact, Error, TEXT("Ecsact execution failed"));
54+
if(ecsact_execute_systems) {
55+
auto err =
56+
ecsact_execute_systems(registry_id, 1, exec_opts, GetEventsCollector());
57+
if(err != ECSACT_EXEC_SYS_OK) {
58+
UE_LOG(Ecsact, Error, TEXT("Ecsact execution failed"));
59+
}
60+
if(ExecutionOptions) {
61+
ExecutionOptions->Clear();
62+
}
63+
} else {
64+
UE_LOG(
65+
Ecsact,
66+
Error,
67+
TEXT("ecsact_execute_systems unavailable - unable to execute systems")
68+
);
69+
}
4770
}
4871
}
4972

Source/Ecsact/Public/EcsactUnreal/EcsactSyncRunner.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ UCLASS(NotBlueprintable)
1111

1212
class ECSACT_API UEcsactSyncRunner : public UEcsactRunner {
1313
GENERATED_BODY() // NOLINT
14+
15+
float LastTickTime = 0.f;
16+
1417
protected:
1518
auto StreamImpl(
1619
ecsact_entity_id Entity,

Source/Ecsact/Public/EcsactUnreal/RuntimeLoad.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "EcsactUnreal/Ecsact.h"
44
#include "EcsactUnreal/RuntimeHandle.h"
55
#include "ecsact/runtime.h"
6+
#include "ecsact/wasm.h"
67

78
/** @internal - DO NOT USE */
89
#define ECSACT_API_FN_INIT_(fn, UNUSED_PARAM) decltype(fn) fn = nullptr
@@ -20,12 +21,6 @@
2021
} \
2122
static_assert(true, "require ;")
2223

23-
/**
24-
* Call exactly once in your game modules .cpp file.
25-
*/
26-
#define ECSACT_RUNTIME_INIT() \
27-
FOR_EACH_ECSACT_API_FN(ECSACT_API_FN_INIT_, UNUSED_PARAM);
28-
2924
// Check if we're using clangd on windows to shutup the traditional msvc error
3025
// TODO: https://github.com/ecsact-dev/ecsact_runtime/issues/267
3126
#if defined(__clang__) && defined(_WIN32)
@@ -70,6 +65,7 @@
7065
return {}; \
7166
} \
7267
FOR_EACH_ECSACT_API_FN(ECSACTAPI_FN_FN_LOAD_); \
68+
FOR_EACH_ECSACTSI_WASM_API_FN(ECSACTAPI_FN_FN_LOAD_); \
7369
return result; \
7470
})()
7571

@@ -84,6 +80,7 @@
8480
} \
8581
EcsactUnreal::Detail::UnloadPostDisconnect(module, Handle_); \
8682
FOR_EACH_ECSACT_API_FN(ECSACT_API_FN_RESET_); \
83+
FOR_EACH_ECSACTSI_WASM_API_FN(ECSACT_API_FN_RESET_); \
8784
EcsactUnreal::Detail::UnloadPostReset(module, Handle_); \
8885
})(Handle)
8986

0 commit comments

Comments
 (0)