diff --git a/CInterface/Core.cpp b/CInterface/Core.cpp new file mode 100644 index 0000000..13b9216 --- /dev/null +++ b/CInterface/Core.cpp @@ -0,0 +1,7 @@ +#include "Core.hpp" + +std::string ExceptionHandler::_pkmnLibAILastException = ""; +std::string ExceptionHandler::_pkmnLibAILastExceptionStacktrace = "Unset"; + +export const char* pkmnlibai_C_GetLastException() { return ExceptionHandler::GetLastException(); } +export const char* pkmnlibai_C_GetLastExceptionStacktrace() { return ExceptionHandler::GetLastExceptionStacktrace(); } \ No newline at end of file diff --git a/CInterface/Core.hpp b/CInterface/Core.hpp new file mode 100644 index 0000000..4a31146 --- /dev/null +++ b/CInterface/Core.hpp @@ -0,0 +1,53 @@ +#ifndef PKMNLIB_AI_CORE_HPP +#define PKMNLIB_AI_CORE_HPP + +#include +#include +#include +#define export extern "C" [[maybe_unused]] + +#define PkmnLibAIException 5 + +class ExceptionHandler { + static std::string _pkmnLibAILastException; + static std::string _pkmnLibAILastExceptionStacktrace; + +public: + static void SetLastArbUtException(const std::string& function, const ArbUt::Exception& e, size_t depth = 6) { + std::stringstream ss; + ss << "[" << function << "] " << e.what(); + _pkmnLibAILastException = ss.str(); + _pkmnLibAILastExceptionStacktrace = e.GetStacktrace(depth, true); + if (_pkmnLibAILastExceptionStacktrace.empty()) + _pkmnLibAILastExceptionStacktrace = "err"; + } + static void SetLastException(const std::string& function, const std::exception& e) { + std::stringstream ss; + ss << "[" << function << "] " << e.what(); + _pkmnLibAILastException = ss.str(); + _pkmnLibAILastExceptionStacktrace = "Exception did not have a stacktrace."; + } + static const char* GetLastException() { return _pkmnLibAILastException.c_str(); } + static const char* GetLastExceptionStacktrace() { return _pkmnLibAILastExceptionStacktrace.c_str(); } +}; + +#define Try(data) \ + try { \ + data; \ + return 0; \ + } catch (const ArbUt::Exception& e) { \ + ExceptionHandler::SetLastArbUtException(__FUNCTION__, e); \ + return PkmnLibAIException; \ + } catch (const std::exception& e) { \ + ExceptionHandler::SetLastException(__FUNCTION__, e); \ + return PkmnLibAIException; \ + } + +#define SIMPLE_GET_FUNC(type, name, returnType) \ + export returnType pkmnlibai_##type##_##name(const type* p) { return p->name(); } +#define SIMPLE_GET_FUNC_SMART_PTR(type, name, returnType) \ + export returnType pkmnlibai_##type##_##name(const type* p) { return p->name().GetRaw(); } +#define DESTRUCTOR(type) \ + export void pkmnlibai_##type##_Destruct(const type* p) { delete p; } + +#endif // PKMNLIB_AI_CORE_HPP diff --git a/CInterface/pkmnlibai.cpp b/CInterface/pkmnlibai.cpp new file mode 100644 index 0000000..535235a --- /dev/null +++ b/CInterface/pkmnlibai.cpp @@ -0,0 +1,16 @@ +#include "../src/DepthSearchAI.hpp" +#include "../src/NaiveAI.hpp" +#include "../src/PokemonAI.hpp" +#include "../src/RandomAI.hpp" +#include "Core.hpp" + +export void pkmnlibai_PokemonAI_Delete(PkmnLibAI::PokemonAI* p) { delete p; } + +export u8 pkmnlibai_PokemonAI_GetChoice(CreatureLib::Battling::BaseTurnChoice*& out, PkmnLibAI::PokemonAI* p, + PkmnLib::Battling::Battle* battle, PkmnLib::Battling::Pokemon* user) { + Try(out = p->GetChoice(battle, user);) +} + +export PkmnLibAI::RandomAI* pkmnlibai_RandomAI_Create() { return new PkmnLibAI::RandomAI(); } +export PkmnLibAI::NaiveAI* pkmnlibai_NaiveAI_Create() { return new PkmnLibAI::NaiveAI(); } +export PkmnLibAI::DepthSearchAI* pkmnlibai_DepthSearchAI_Create() { return new PkmnLibAI::DepthSearchAI(); } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index fc6b45c..9d0800a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ set(STATICC TRUE) include(CMakeLists.txt.in) include_pkmnlib() -file(GLOB_RECURSE SRC_FILES src/*.cpp src/*.hpp) +file(GLOB_RECURSE SRC_FILES src/*.cpp src/*.hpp CInterface/pkmnlibai.cpp CInterface/Core.cpp) add_library(pkmnlib_ai SHARED ${SRC_FILES}) target_precompile_headers(pkmnlib_ai PUBLIC src/Precompiled.hxx) set_target_properties(pkmnlib_ai PROPERTIES LINKER_LANGUAGE CXX) diff --git a/src/DepthSearchAI.hpp b/src/DepthSearchAI.hpp index f32e688..4198569 100644 --- a/src/DepthSearchAI.hpp +++ b/src/DepthSearchAI.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include "../cmake-build-release/PkmnLib/src/pkmnlib/src/Battling/Pokemon/PokemonParty.hpp" @@ -92,7 +93,7 @@ namespace PkmnLibAI { })); } std::vector> results(threadPool.size()); - for (int i = 0; i < threadPool.size(); ++i) { + for (size_t i = 0; i < threadPool.size(); ++i) { results[i] = threadPool[i].get(); } return results; @@ -111,7 +112,7 @@ namespace PkmnLibAI { scoredMoves.emplace_back(moveIndex, scored); } auto& party = battle->GetParties()[side->GetSideIndex()]->GetParty()->GetParty(); - for (int i = 0; i < party.Count(); ++i) { + for (size_t i = 0; i < party.Count(); ++i) { auto mon = party[i]; if (!mon.HasValue()) { continue; diff --git a/src/PokemonAI.hpp b/src/PokemonAI.hpp index d54550d..5581533 100644 --- a/src/PokemonAI.hpp +++ b/src/PokemonAI.hpp @@ -15,6 +15,7 @@ namespace PkmnLibAI { virtual std::string GetName() const noexcept = 0; + protected: CreatureLib::Battling::CreatureIndex GetOppositeIndex(PkmnLib::Battling::Pokemon* user) { auto side = user->GetBattleSide().GetValue(); if (side->GetSideIndex() == 0) {