diff --git a/CInterface/Core.cpp b/CInterface/Core.cpp index 70b51cf..d6469f3 100644 --- a/CInterface/Core.cpp +++ b/CInterface/Core.cpp @@ -1,4 +1,7 @@ #include "Core.hpp" std::string ExceptionHandler::_pkmnLibLastException = ""; -export const char* PkmnLib_C_GetLastException() { return ExceptionHandler::GetLastException(); } \ No newline at end of file +std::string ExceptionHandler::_pkmnLibLastExceptionStacktrace = "Unset"; + +export const char* PkmnLib_C_GetLastException() { return ExceptionHandler::GetLastException(); } +export const char* PkmnLib_C_GetLastExceptionStacktrace() { return ExceptionHandler::GetLastExceptionStacktrace(); } \ No newline at end of file diff --git a/CInterface/Core.hpp b/CInterface/Core.hpp index 9ac634c..762c6a4 100644 --- a/CInterface/Core.hpp +++ b/CInterface/Core.hpp @@ -10,19 +10,37 @@ class ExceptionHandler { static std::string _pkmnLibLastException; + static std::string _pkmnLibLastExceptionStacktrace; public: - static void SetLastException(const std::exception& e) { _pkmnLibLastException = std::string(e.what()); } + static void SetLastArbUtException(const std::string& function, const ArbUt::Exception& e, size_t depth = 6) { + std::stringstream ss; + ss << "[" << function << "] " << e.what(); + _pkmnLibLastException = ss.str(); + _pkmnLibLastExceptionStacktrace = e.GetStacktrace(depth, true); + if (_pkmnLibLastExceptionStacktrace.empty()) + _pkmnLibLastExceptionStacktrace = "err"; + } + static void SetLastException(const std::string& function, const std::exception& e) { + std::stringstream ss; + ss << "[" << function << "] " << e.what(); + _pkmnLibLastException = ss.str(); + _pkmnLibLastExceptionStacktrace = "Exception did not have a stacktrace."; + } static const char* GetLastException() { return _pkmnLibLastException.c_str(); } + static const char* GetLastExceptionStacktrace() { return _pkmnLibLastExceptionStacktrace.c_str(); } }; #define Try(data) \ try { \ data; \ return 0; \ + } catch (const ArbUt::Exception& e) { \ + ExceptionHandler::SetLastArbUtException(__FUNCTION__, e); \ + return PkmnLibException; \ } catch (const std::exception& e) { \ - ExceptionHandler::SetLastException(e); \ - return PkmnLibException; \ + ExceptionHandler::SetLastException(__FUNCTION__, e); \ + return PkmnLibException; \ } #define SIMPLE_GET_FUNC(type, name, returnType) \ diff --git a/CMakeLists.txt b/CMakeLists.txt index c416595..4ad410b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -143,7 +143,7 @@ find_package(Threads REQUIRED) if (STATICC) message(STATUS "Linking C library statically") - if (NOT UNIX AND NOT APPLE) + if (NOT UNIX AND NOT APPLE OR WINDOWS) SET(_LINKS ${_LINKS} -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lpthread) SET(_TESTLINKS ${_TESTLINKS} -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lpthread) else() diff --git a/src/ScriptResolving/AngelScript/AngelScriptResolver.cpp b/src/ScriptResolving/AngelScript/AngelScriptResolver.cpp index 73a66a1..9ace8a0 100644 --- a/src/ScriptResolving/AngelScript/AngelScriptResolver.cpp +++ b/src/ScriptResolving/AngelScript/AngelScriptResolver.cpp @@ -312,7 +312,7 @@ void AngelScriptResolver::InitializeByteCode( ArbUt::Dictionary objectTypes; for (asUINT i = 0; i < typeCount; i++) { auto t = _mainModule->GetObjectTypeByIndex(i); - objectTypes.Insert(ArbUt::StringView::CalculateHash(t->GetName()), t); + objectTypes.Set(ArbUt::StringView::CalculateHash(t->GetName()), t); } ArbUt::Dictionary> typeDatabase; for (const auto& innerDb : types) { @@ -320,9 +320,9 @@ void AngelScriptResolver::InitializeByteCode( for (const auto& val : innerDb.second) { auto decl = val.second; auto type = objectTypes[decl]; - newInnerDb.Insert(val.first, new AngelScriptTypeInfo(val.first, type)); + newInnerDb.Set(val.first, new AngelScriptTypeInfo(val.first, type)); } - typeDatabase.Insert(innerDb.first, newInnerDb); + typeDatabase.Set(innerDb.first, newInnerDb); } _typeDatabase = typeDatabase; } diff --git a/src/ScriptResolving/AngelScript/AngelScriptScript.hpp b/src/ScriptResolving/AngelScript/AngelScriptScript.hpp index 0481111..99e849c 100644 --- a/src/ScriptResolving/AngelScript/AngelScriptScript.hpp +++ b/src/ScriptResolving/AngelScript/AngelScriptScript.hpp @@ -26,6 +26,7 @@ public: ~AngelScriptScript() override { _obj->Release(); } [[nodiscard]] const ArbUt::StringView& GetName() const noexcept override { return _type->GetName(); } + const AngelScriptTypeInfo* GetType() const noexcept { return _type; } asIScriptFunction* PrepareMethod(const ArbUt::BasicStringView& name, asIScriptContext* ctx) { auto func = _type->GetFunction(name); diff --git a/src/ScriptResolving/AngelScript/AngelScriptTypeInfo.hpp b/src/ScriptResolving/AngelScript/AngelScriptTypeInfo.hpp index f563b9e..b4f1690 100644 --- a/src/ScriptResolving/AngelScript/AngelScriptTypeInfo.hpp +++ b/src/ScriptResolving/AngelScript/AngelScriptTypeInfo.hpp @@ -21,9 +21,6 @@ private: if (val == nullptr) { return FunctionInfo{.Exists = false, .Function = nullptr}; } - if (!val->IsOverride()) { - return FunctionInfo{.Exists = false, .Function = nullptr}; - } return FunctionInfo{.Exists = true, .Function = val}; } diff --git a/src/ScriptResolving/AngelScript/ByteCodeHandling/IPkmnBinaryStream.hpp b/src/ScriptResolving/AngelScript/ByteCodeHandling/IPkmnBinaryStream.hpp index bb323a4..7eb5cc8 100644 --- a/src/ScriptResolving/AngelScript/ByteCodeHandling/IPkmnBinaryStream.hpp +++ b/src/ScriptResolving/AngelScript/ByteCodeHandling/IPkmnBinaryStream.hpp @@ -68,7 +68,8 @@ public: if (isDecl) { // Insert the name and decl into the dictionary. Close off the decl with eof as well. decl[pos] = '\0'; - innerDb.Insert(ArbUt::StringView(name), ArbUt::StringView::CalculateHash(decl)); + + innerDb.Set(ArbUt::StringView(name), ArbUt::StringView::CalculateHash(decl)); } // If we have found \1, we are done with the current category, so break. break; @@ -79,7 +80,7 @@ public: if (isDecl) { // Insert the name and decl into the dictionary. Close off the decl with eof as well. decl[pos] = '\0'; - innerDb.Insert(ArbUt::StringView(name), ArbUt::StringView::CalculateHash(decl)); + innerDb.Set(ArbUt::StringView(name), ArbUt::StringView::CalculateHash(decl)); // Reset our position and toggle back to name. pos = 0; isDecl = false; @@ -101,7 +102,7 @@ public: } } } - types.Insert(categoryArr[0], innerDb); + types.Set(categoryArr[0], innerDb); } return types; } diff --git a/tests/ScriptTests/ScriptResolverTests.cpp b/tests/ScriptTests/ScriptResolverTests.cpp index ac32157..d027fd6 100644 --- a/tests/ScriptTests/ScriptResolverTests.cpp +++ b/tests/ScriptTests/ScriptResolverTests.cpp @@ -7,7 +7,7 @@ static std::unordered_map _scripts = std::unordered_map{{"testScript1", R"( namespace Pokemon{ [Pokemon effect=testScript1] -class testScript1 { +class testScript1 : PkmnScript { int add(int a, int b) { return a + b; } @@ -17,6 +17,8 @@ class testScript1 { throw("err"); } } + + void OnInitialize(const array &in parameters) override{ } } } )"}}; @@ -83,14 +85,19 @@ TEST_CASE("Get a script resolver, save the byte code to memory, create new scrip originLib->Initialize(TestLibrary::GetLibrary()); originLib->CreateScript("testScript1", _scripts["testScript1"]); originLib->FinalizeModule(); + auto obj = dynamic_cast(originLib->LoadScript(ScriptCategory::Creature, "testScript1"_cnc)); + REQUIRE(obj != nullptr); + REQUIRE(obj->GetType()->GetOnInitialize().Exists); + delete obj; size_t size; auto byteCode = originLib->WriteByteCodeToMemory(size); auto newLib = dynamic_cast(PkmnLib::Battling::BattleLibrary::CreateScriptResolver()); newLib->Initialize(TestLibrary::GetLibrary()); newLib->LoadByteCodeFromMemory(byteCode, size); - auto obj = dynamic_cast(newLib->LoadScript(ScriptCategory::Creature, "testScript1"_cnc)); + obj = dynamic_cast(newLib->LoadScript(ScriptCategory::Creature, "testScript1"_cnc)); REQUIRE(obj != nullptr); + REQUIRE(obj->GetType()->GetOnInitialize().Exists); delete obj; delete originLib; delete newLib;