From 4e5d3cfd646fb2eb673930c8e83dedcbca45732c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Thu, 10 Aug 2023 22:07:58 +0200 Subject: [PATCH] Add OnCollisionLeave2D --- GlitchyEngine/src/Scripting/ScriptClass.bf | 26 ++++++++-- GlitchyEngine/src/Scripting/ScriptEngine.bf | 2 +- GlitchyEngine/src/Scripting/ScriptInstance.bf | 11 ++++ GlitchyEngine/src/World/Scene.bf | 51 +++++++++++++++++++ 4 files changed, 86 insertions(+), 4 deletions(-) diff --git a/GlitchyEngine/src/Scripting/ScriptClass.bf b/GlitchyEngine/src/Scripting/ScriptClass.bf index 132ef9c..b68eeed 100644 --- a/GlitchyEngine/src/Scripting/ScriptClass.bf +++ b/GlitchyEngine/src/Scripting/ScriptClass.bf @@ -290,12 +290,15 @@ class ScriptClass : SharpClass private OnDestroyMethod _onDestroy; private function [CallingConvention(.Cdecl)] MonoObject*(MonoObject* instance, Collision2D collision, MonoException** exception) _onCollisionEnter2D; + private function [CallingConvention(.Cdecl)] MonoObject*(MonoObject* instance, Collision2D collision, MonoException** exception) _onCollisionLeave2D; //private OnCollisionEnter2DMethod _onCollisionEnter2D; - private OnDestroyMethod _onCollisionLeave2D; + //private OnDestroyMethod _onCollisionLeave2D; private MonoMethod* _onCollisionEnter2DMethod; + private MonoMethod* _onCollisionLeave2DMethod; - public bool HasCollisionEnter2D => _onCollisionEnter2D != null; + public bool HasCollisionEnter2D => _onCollisionEnter2DMethod != null; + public bool HasCollisionLeave2D => _onCollisionLeave2DMethod != null; /*public StringView Namespace => _namespace; public StringView ClassName => _className; @@ -314,9 +317,10 @@ class ScriptClass : SharpClass _onDestroy = (OnDestroyMethod)GetMethodThunk("OnDestroy"); _onCollisionEnter2D = (.)GetMethodThunk("OnCollisionEnter2D", 1); - _onCollisionLeave2D = (OnDestroyMethod)GetMethodThunk("OnCollisionLeave2D"); + _onCollisionLeave2D = (.)GetMethodThunk("OnCollisionLeave2D", 1); _onCollisionEnter2DMethod = GetMethod("OnCollisionEnter2D", 1); + _onCollisionLeave2DMethod = GetMethod("OnCollisionLeave2D", 1); } public void OnCreate(MonoObject* instance, out MonoException* exception) @@ -358,6 +362,22 @@ class ScriptClass : SharpClass // if (_onCollisionEnter2D != null) // _onCollisionEnter2D(instance, collision, &exception); } + + public void OnCollisionLeave2D(MonoObject* instance, Collision2D collision, out MonoException* exception) + { + exception = null; + + // TODO: use method thunk + if (_onCollisionLeave2DMethod != null) + { +#unwarn + void*[1] args = .(&collision); + + Invoke(_onCollisionLeave2DMethod, instance, (.)&args); + } + // if (_onCollisionEnter2D != null) + // _onCollisionEnter2D(instance, collision, &exception); + } public MonoObject* CreateInstance(UUID uuid, out MonoException* exception) { diff --git a/GlitchyEngine/src/Scripting/ScriptEngine.bf b/GlitchyEngine/src/Scripting/ScriptEngine.bf index ddcb651..da818cc 100644 --- a/GlitchyEngine/src/Scripting/ScriptEngine.bf +++ b/GlitchyEngine/src/Scripting/ScriptEngine.bf @@ -153,7 +153,7 @@ static class ScriptEngine String directory = scope .(); Path.GetDirectoryPath(_appAssemblyPath, directory); - if (_userAssemblyWatcher != null && _userAssemblyWatcher.Directory != directory) + if (_userAssemblyWatcher != null) // _userAssemblyWatcher.Directory != directory { delete _userAssemblyWatcher; } diff --git a/GlitchyEngine/src/Scripting/ScriptInstance.bf b/GlitchyEngine/src/Scripting/ScriptInstance.bf index e55871f..3cb3b5e 100644 --- a/GlitchyEngine/src/Scripting/ScriptInstance.bf +++ b/GlitchyEngine/src/Scripting/ScriptInstance.bf @@ -92,6 +92,17 @@ class ScriptInstance : RefCounter if (exception != null) ScriptEngine.HandleMonoException(exception, this); } + + public void InvokeOnCollisionLeave2D(Collision2D collision) + { + if (!_scriptClass.HasCollisionLeave2D) + return; + + _scriptClass.OnCollisionLeave2D(_instance, collision, let exception); + + if (exception != null) + ScriptEngine.HandleMonoException(exception, this); + } public T GetFieldValue(ScriptField field) { diff --git a/GlitchyEngine/src/World/Scene.bf b/GlitchyEngine/src/World/Scene.bf index a94094c..7a3bed6 100644 --- a/GlitchyEngine/src/World/Scene.bf +++ b/GlitchyEngine/src/World/Scene.bf @@ -235,6 +235,57 @@ namespace GlitchyEngine.World scriptOfRigidbodyB?.Instance?.InvokeOnCollisionEnter2D(collision); } }; + _contactListener.endContactCallback = (contact, userData) => { + var fixtureA = Contact.GetFixtureA(contact); + var fixtureB = Contact.GetFixtureB(contact); + + var bodyA = Fixture.GetBody(fixtureA); + var bodyB = Fixture.GetBody(fixtureB); + + // Cast is obviously 64bit only + var colliderEntityHandleA = (EcsEntity)(uint)Fixture.GetUserData(fixtureA); + var colliderEntityHandleB = (EcsEntity)(uint)Fixture.GetUserData(fixtureB); + + Entity colliderEntityA = .(colliderEntityHandleA, ScriptEngine.Context); + Entity colliderEntityB = .(colliderEntityHandleB, ScriptEngine.Context); + + // Cast is obviously 64bit only + var rigidbodyEntityHandleA = (EcsEntity)(uint)Body.GetUserData(bodyA); + var rigidbodyEntityHandleB = (EcsEntity)(uint)Body.GetUserData(bodyB); + + Entity rigidbodyEntityA = .(rigidbodyEntityHandleA, ScriptEngine.Context); + Entity rigidbodyEntityB = .(rigidbodyEntityHandleB, ScriptEngine.Context); + + bool fireEventA = colliderEntityA.TryGetComponent(let scriptOfColliderA); + fireEventA |= rigidbodyEntityA.TryGetComponent(let scriptOfRigidbodyA); + + if (fireEventA) + { + Collision2D collision = .(); + collision.Entity = colliderEntityA.UUID; + collision.OtherEntity = colliderEntityB.UUID; + collision.Rigidbody = rigidbodyEntityA.UUID; + collision.OtherRigidbody = rigidbodyEntityB.UUID; + + scriptOfColliderA?.Instance?.InvokeOnCollisionLeave2D(collision); + scriptOfRigidbodyA?.Instance?.InvokeOnCollisionLeave2D(collision); + } + + bool fireEventB = colliderEntityB.TryGetComponent(let scriptOfColliderB); + fireEventB |= rigidbodyEntityB.TryGetComponent(let scriptOfRigidbodyB); + + if (fireEventB) + { + Collision2D collision = .(); + collision.Entity = colliderEntityB.UUID; + collision.OtherEntity = colliderEntityA.UUID; + collision.Rigidbody = rigidbodyEntityB.UUID; + collision.OtherRigidbody = rigidbodyEntityA.UUID; + + scriptOfColliderB?.Instance?.InvokeOnCollisionLeave2D(collision); + scriptOfRigidbodyB?.Instance?.InvokeOnCollisionLeave2D(collision); + } + }; World.SetContactListener(_physicsWorld2D, &_contactListener);