diff --git a/src/ScriptResolving/AngelScript/AngelScriptResolver.cpp b/src/ScriptResolving/AngelScript/AngelScriptResolver.cpp index 24233f4..0128a8e 100644 --- a/src/ScriptResolving/AngelScript/AngelScriptResolver.cpp +++ b/src/ScriptResolving/AngelScript/AngelScriptResolver.cpp @@ -467,3 +467,28 @@ i32 AngelScriptResolver::IncludeCallback(const char* include, const char*, CScri } return builder->AddSectionFromFile((const char*)path.c_str()); } + +void AngelScriptResolver::Reset(CreatureLib::Battling::BattleLibrary* library) { + for (const auto& ius : _itemUseScripts) { + delete ius.second; + } + delete _contextPool; + for (const auto& category : _typeDatabase) { + for (const auto& type : category.second) { + delete type.second; + } + } + delete _userData; + _engine->ShutDownAndRelease(); + + _userData = new AngelscriptUserdata(this); + _typeDatabase.Clear(); + _baseTypes.Clear(); + _itemUseTypes.Clear(); + _evolutionTypes.Clear(); + _itemUseScripts.Clear(); + _evolutionScripts.Clear(); + _scriptOwnerTypes.Clear(); + + Initialize(library); +} diff --git a/src/ScriptResolving/AngelScript/AngelScriptResolver.hpp b/src/ScriptResolving/AngelScript/AngelScriptResolver.hpp index 6b04db2..432459a 100644 --- a/src/ScriptResolving/AngelScript/AngelScriptResolver.hpp +++ b/src/ScriptResolving/AngelScript/AngelScriptResolver.hpp @@ -116,7 +116,7 @@ public: inline ArbUt::OptionalBorrowedPtr GetDebugger() const noexcept { return _debugger.GetValue(); } inline void SetDebugger(AngelscriptDebugger* debugger) noexcept { _debugger = debugger; } - inline asITypeInfo* GetScriptOwnerType(ScriptCategory category) { + asITypeInfo* GetScriptOwnerType(ScriptCategory category) { auto tryget = _scriptOwnerTypes.TryGet(category); if (tryget.has_value()) { return tryget.value(); @@ -137,5 +137,7 @@ public: _scriptOwnerTypes.Set(category, t); return t; } + + void Reset(CreatureLib::Battling::BattleLibrary* library); }; #endif // PKMNLIB_ANGELSCRIPRESOLVER_HPP diff --git a/src/ScriptResolving/AngelScript/AngelScriptScript.cpp b/src/ScriptResolving/AngelScript/AngelScriptScript.cpp index a4c5373..f82eec8 100644 --- a/src/ScriptResolving/AngelScript/AngelScriptScript.cpp +++ b/src/ScriptResolving/AngelScript/AngelScriptScript.cpp @@ -20,13 +20,13 @@ AngelScriptScript::AngelScriptScript(const ArbUt::OptionalBorrowedPtr& own ContextPool* ctxPool) : PkmnLib::Battling::PkmnScript(owner), _resolver(resolver), _type(type), _ctxPool(ctxPool), _obj(obj) { if (_type->GetGetOwner().Exists && owner.HasValue()) { - if (ownerType == nullptr){ + if (ownerType == nullptr) { THROW("Script was created with owner value, but with unknown owner type.") } CScriptHandle* handle = nullptr; AngelScriptUtils::AngelscriptFunctionCall( _type->GetGetOwner().Function, _ctxPool, _obj, _resolver, GetName(), [&](asIScriptContext*) {}, - [&](asIScriptContext* ctx) { handle = (CScriptHandle*)ctx->GetReturnObject(); }); + [&](asIScriptContext* ctx) { handle = (CScriptHandle*)ctx->GetReturnAddress(); }); handle->Set(owner.GetValue(), ownerType); } } diff --git a/src/ScriptResolving/AngelScript/AngelScriptTypeInfo.hpp b/src/ScriptResolving/AngelScript/AngelScriptTypeInfo.hpp index 7645a0f..f51a41a 100644 --- a/src/ScriptResolving/AngelScript/AngelScriptTypeInfo.hpp +++ b/src/ScriptResolving/AngelScript/AngelScriptTypeInfo.hpp @@ -75,7 +75,7 @@ private: FunctionInfo InitializeGetOwner(){ auto t = _type; while (t != nullptr){ - auto val = t->GetMethodByDecl("protected ref@& GetOwner()", false); + auto val = t->GetMethodByDecl("ref@& GetOwner()", true); if (val != nullptr){ return FunctionInfo{.Exists = true, .Function = val}; } diff --git a/tests/ScriptTests/BaseScriptClassTests.cpp b/tests/ScriptTests/BaseScriptClassTests.cpp index 38d8aab..f6ed4c5 100644 --- a/tests/ScriptTests/BaseScriptClassTests.cpp +++ b/tests/ScriptTests/BaseScriptClassTests.cpp @@ -98,17 +98,14 @@ int GetValue() { return value; } }; -static AngelScriptResolver* _resolverCache = nullptr; static AngelScriptResolver* GetScriptResolver(PkmnLib::Battling::BattleLibrary* mainLib) { - if (_resolverCache == nullptr) { - _resolverCache = dynamic_cast(PkmnLib::Battling::BattleLibrary::CreateScriptResolver()); - _resolverCache->Initialize(mainLib); - for (auto kv : _scripts) { - _resolverCache->CreateScript(kv.first, kv.second); - } - _resolverCache->FinalizeModule(); + auto res = dynamic_cast(mainLib->GetScriptResolver().get()); + res->Reset(mainLib); + for (auto kv : _scripts) { + res->CreateScript(kv.first, kv.second); } - return _resolverCache; + res->FinalizeModule(); + return res; } static AngelScriptScript* GetScript(PkmnLib::Battling::BattleLibrary* mainLib, const ArbUt::StringView& scriptName) { diff --git a/tests/ScriptTests/ScriptOwnerTest.cpp b/tests/ScriptTests/ScriptOwnerTest.cpp new file mode 100644 index 0000000..69c9191 --- /dev/null +++ b/tests/ScriptTests/ScriptOwnerTest.cpp @@ -0,0 +1,63 @@ +#ifdef TESTS_BUILD +#include "../../extern/doctest.hpp" +#include "../../src/Battling/Pokemon/CreatePokemon.hpp" +#include "../../src/ScriptResolving/AngelScript/AngelScriptResolver.hpp" +#include "../../src/ScriptResolving/AngelScript/ContextPool.hpp" +#include "../TestLibrary/TestLibrary.hpp" + +static std::unordered_map _scripts = + std::unordered_map{{"basic_ownership_test", + R"(namespace Pokemon { + [Pokemon effect="basic_ownership_test"] + shared class basic_ownership_test : PkmnScript { + void Test(){ + auto mon = cast(GetOwner()); + if (mon is null){ + throw("Owner was null!"); + } + } + } +})"}}; + +static AngelScriptResolver* _resolverCache = nullptr; +static AngelScriptResolver* GetScriptResolver(PkmnLib::Battling::BattleLibrary* mainLib) { + if (_resolverCache == nullptr) { + _resolverCache = dynamic_cast(PkmnLib::Battling::BattleLibrary::CreateScriptResolver()); + _resolverCache->Initialize(mainLib); + for (auto kv : _scripts) { + _resolverCache->CreateScript(kv.first, kv.second); + } + _resolverCache->FinalizeModule(); + } + return _resolverCache; +} + +static AngelScriptScript* GetScript(PkmnLib::Battling::BattleLibrary* mainLib, const ArbUt::StringView& scriptName, + PkmnLib::Battling::Pokemon* owner) { + auto lib = GetScriptResolver(mainLib); + auto s = lib->LoadScript(owner, ScriptCategory::Creature, scriptName); + auto script = dynamic_cast(s); + REQUIRE(script != nullptr); + + return script; +} + +TEST_CASE("Basic script owner tests.") { + auto lib = TestLibrary::GetLibrary(); + auto mon = PkmnLib::Battling::CreatePokemon(lib, "testSpecies"_cnc, 1).Build(); + auto script = GetScript(lib, "basic_ownership_test"_cnc, mon); + REQUIRE(script != nullptr); + + script->OnRemove(); + + auto ctxPool = script->GetContextPool(); + auto ctx = ctxPool->RequestContext(); + script->PrepareMethod("Test"_cnc, ctx); + REQUIRE(ctx->Execute() == asEXECUTION_FINISHED); + ctxPool->ReturnContextToPool(ctx); + + delete script; + delete mon; +} + +#endif \ No newline at end of file