feat(physics): dispatch PhysX simulation events to scene scripts
This commit is contained in:
@@ -32,6 +32,19 @@ std::string LifecycleMethodToString(ScriptLifecycleMethod method) {
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
std::string PhysicsMessageToString(ScriptPhysicsMessage message) {
|
||||
switch (message) {
|
||||
case ScriptPhysicsMessage::CollisionEnter: return "CollisionEnter";
|
||||
case ScriptPhysicsMessage::CollisionStay: return "CollisionStay";
|
||||
case ScriptPhysicsMessage::CollisionExit: return "CollisionExit";
|
||||
case ScriptPhysicsMessage::TriggerEnter: return "TriggerEnter";
|
||||
case ScriptPhysicsMessage::TriggerStay: return "TriggerStay";
|
||||
case ScriptPhysicsMessage::TriggerExit: return "TriggerExit";
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
class FakeScriptRuntime : public IScriptRuntime {
|
||||
public:
|
||||
void OnRuntimeStart(Scene* scene) override {
|
||||
@@ -118,6 +131,18 @@ public:
|
||||
events.push_back(LifecycleMethodToString(method) + ":" + Describe(context));
|
||||
}
|
||||
|
||||
void InvokePhysicsMessage(
|
||||
const ScriptRuntimeContext& context,
|
||||
ScriptPhysicsMessage message,
|
||||
GameObject* other) override {
|
||||
events.push_back(
|
||||
PhysicsMessageToString(message)
|
||||
+ ":"
|
||||
+ Describe(context)
|
||||
+ ":"
|
||||
+ (other ? other->GetName() : std::string("null")));
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
events.clear();
|
||||
}
|
||||
@@ -388,6 +413,50 @@ TEST_F(ScriptEngineTest, ChangingScriptClassWhileRuntimeRunningRecreatesTrackedI
|
||||
EXPECT_TRUE(engine->HasRuntimeInstance(component));
|
||||
}
|
||||
|
||||
TEST_F(ScriptEngineTest, DispatchPhysicsMessageInvokesTrackedActiveScripts) {
|
||||
Scene* runtimeScene = CreateScene("RuntimeScene");
|
||||
GameObject* host = runtimeScene->CreateGameObject("Host");
|
||||
GameObject* other = runtimeScene->CreateGameObject("Other");
|
||||
AddScriptComponent(host, "Gameplay", "TriggerListener");
|
||||
|
||||
engine->OnRuntimeStart(runtimeScene);
|
||||
runtime.Clear();
|
||||
|
||||
engine->DispatchPhysicsMessage(host, ScriptPhysicsMessage::TriggerEnter, other);
|
||||
|
||||
const std::vector<std::string> expected = {
|
||||
"TriggerEnter:Host:Gameplay.TriggerListener:Other"
|
||||
};
|
||||
EXPECT_EQ(runtime.events, expected);
|
||||
}
|
||||
|
||||
TEST_F(ScriptEngineTest, DispatchPhysicsMessageSkipsInactiveAndDisabledScripts) {
|
||||
Scene* runtimeScene = CreateScene("RuntimeScene");
|
||||
GameObject* activeHost = runtimeScene->CreateGameObject("ActiveHost");
|
||||
GameObject* inactiveHost = runtimeScene->CreateGameObject("InactiveHost");
|
||||
GameObject* disabledHost = runtimeScene->CreateGameObject("DisabledHost");
|
||||
GameObject* other = runtimeScene->CreateGameObject("Other");
|
||||
|
||||
AddScriptComponent(activeHost, "Gameplay", "ActiveListener");
|
||||
AddScriptComponent(inactiveHost, "Gameplay", "InactiveListener");
|
||||
ScriptComponent* disabledComponent = AddScriptComponent(disabledHost, "Gameplay", "DisabledListener");
|
||||
|
||||
inactiveHost->SetActive(false);
|
||||
disabledComponent->SetEnabled(false);
|
||||
|
||||
engine->OnRuntimeStart(runtimeScene);
|
||||
runtime.Clear();
|
||||
|
||||
engine->DispatchPhysicsMessage(activeHost, ScriptPhysicsMessage::CollisionEnter, other);
|
||||
engine->DispatchPhysicsMessage(inactiveHost, ScriptPhysicsMessage::CollisionEnter, other);
|
||||
engine->DispatchPhysicsMessage(disabledHost, ScriptPhysicsMessage::CollisionEnter, other);
|
||||
|
||||
const std::vector<std::string> expected = {
|
||||
"CollisionEnter:ActiveHost:Gameplay.ActiveListener:Other"
|
||||
};
|
||||
EXPECT_EQ(runtime.events, expected);
|
||||
}
|
||||
|
||||
TEST_F(ScriptEngineTest, ClearingScriptClassWhileRuntimeRunningDestroysTrackedInstance) {
|
||||
Scene* runtimeScene = CreateScene("RuntimeScene");
|
||||
GameObject* host = runtimeScene->CreateGameObject("Host");
|
||||
|
||||
Reference in New Issue
Block a user