PkmnLib/src/ScriptResolving/AngelScript/AngelScriptResolver.hpp

151 lines
6.7 KiB
C++

#ifndef PKMNLIB_ANGELSCRIPTRESOLVER_HPP
#define PKMNLIB_ANGELSCRIPTRESOLVER_HPP
#include <CreatureLib/Battling/ScriptHandling/ScriptResolver.hpp>
#include <mutex>
#ifdef ANGELSCRIPT_DEBUGGER
#include <AngelscriptDebuggerServer/AngelscriptDebugger.hpp>
#endif
#include <scriptbuilder/scriptbuilder.h>
#include "../../Battling/Library/BattleLibrary.hpp"
#include "AngelScriptEvolutionScript.hpp"
#define ANGELSCRIPT_DLL_LIBRARY_IMPORT
#include <Arbutils/StringView.hpp>
#include <angelscript.h>
#include "../../Battling/PkmnScriptCategory.hpp"
#include "AngelScriptItemUseScript.hpp"
#include "AngelScriptScript.hpp"
#include "AngelScriptTypeInfo.hpp"
class AngelscriptUserdata;
class AngelScriptResolver final : public PkmnLib::Battling::ScriptResolver {
private:
asIScriptEngine* _engine = nullptr;
asIScriptModule* _mainModule = nullptr;
ContextPool* _contextPool = nullptr;
CScriptBuilder _builder = {};
std::string _sourceDirectory = {};
AngelscriptUserdata* _userData;
#ifdef ANGELSCRIPT_DEBUGGER
ArbUt::OptionalUniquePtr<AngelscriptDebugger> _debugger;
#endif
ArbUt::Dictionary<ScriptCategory, ArbUt::Dictionary<ArbUt::StringView, AngelScriptTypeInfo*>> _typeDatabase;
ArbUt::Dictionary<ArbUt::StringView, asITypeInfo*> _baseTypes;
std::mutex _baseTypesLock;
ArbUt::Dictionary<ArbUt::StringView, asITypeInfo*> _itemUseTypes;
ArbUt::Dictionary<ArbUt::StringView, asITypeInfo*> _evolutionTypes;
ArbUt::Dictionary<const CreatureLib::Library::Item*, AngelScriptItemUseScript*> _itemUseScripts;
ArbUt::Dictionary<ArbUt::StringView, AngelScriptEvolutionScript*> _evolutionScripts;
ArbUt::Dictionary<ScriptCategory, asITypeInfo*> _scriptOwnerTypes;
static void MessageCallback(const asSMessageInfo* msg, void* param);
static void Print(const std::string& str) { std::cout << str << std::endl; }
static void PrintConst(const ArbUt::StringView& str) { Print(std::string(str.std_str())); }
static i32 IncludeCallback(const char* include, const char* from, CScriptBuilder* builder, void* userParam);
void RegisterTypes();
void InitializeByteCode(const ArbUt::Dictionary<i16, ArbUt::Dictionary<ArbUt::StringView, uint32_t>>& types);
void RegisterScriptType(asITypeInfo* typeInfo, const ArbUt::StringView& metadataKind,
const ArbUt::StringView& effectName);
public:
AngelScriptResolver();
~AngelScriptResolver() override;
void Initialize(CreatureLib::Battling::BattleLibrary* library) override { Initialize(library, true); }
void Initialize(CreatureLib::Battling::BattleLibrary* library, bool includeStandard);
void CreateScript(const char* name, const char* script);
inline void SetSourceDirectory(std::string const& path) noexcept { _sourceDirectory = path; }
const asIScriptModule* GetMainModule() const noexcept { return _mainModule; }
CScriptBuilder& GetBuilder() noexcept { return _builder; }
void FinalizeModule();
void DefineWord(const std::string& word) { _builder.DefineWord(word.c_str()); }
CreatureLib::Battling::BattleScript* LoadScript(const ArbUt::OptionalBorrowedPtr<void>& owner,
ScriptCategory category,
const ArbUt::StringView& scriptName) override;
CreatureLib::Battling::ItemUseScript* LoadItemScript(const CreatureLib::Library::Item* item) override;
ArbUt::OptionalBorrowedPtr<const PkmnLib::Battling::EvolutionScript>
LoadEvolutionScript(const ArbUt::StringView& view) override;
void WriteByteCodeToFile(const char* file, bool stripDebugInfo = false);
void LoadByteCodeFromFile(const char* file);
uint8_t* WriteByteCodeToMemory(size_t& size, bool stripDebugInfo = false);
void LoadByteCodeFromMemory(uint8_t*, size_t size);
const ArbUt::Dictionary<ScriptCategory, ArbUt::Dictionary<ArbUt::StringView, AngelScriptTypeInfo*>>&
GetTypeDatabase() const noexcept {
return _typeDatabase;
}
void RegisterType(const char* type) {
int r = _engine->RegisterObjectType(type, 0, asOBJ_REF | asOBJ_NOCOUNT);
Ensure(r >= 0);
}
void RegisterTypeMethod(const char* type, const char* decl, void*(func)(void*)) {
int r = _engine->RegisterObjectMethod(type, decl, asFunctionPtr(func), asCALL_CDECL_OBJFIRST);
Ensure(r >= 0);
}
void RegisterGlobalMethod(const char*, void*(func)(void*)) {
auto r = _engine->RegisterGlobalFunction("decl", asFunctionPtr(func), asCALL_CDECL);
Ensure(r >= 0);
}
asITypeInfo* GetBaseType(const ArbUt::StringView& name) {
asITypeInfo* t;
auto lock = std::lock_guard(_baseTypesLock);
auto v = _baseTypes.TryGet(name);
if (!v.has_value()) {
t = _mainModule->GetTypeInfoByName(name.c_str());
if (t == NULL) {
t = _engine->GetTypeInfoByDecl(name.c_str());
}
_baseTypes.Insert(name, t);
} else {
t = v.value();
}
return t;
}
inline ContextPool* GetContextPool() const noexcept { return _contextPool; }
inline asIScriptEngine* GetEngine() const noexcept { return _engine; }
inline AngelscriptUserdata* GetUserdata() const noexcept { return _userData; }
#ifdef ANGELSCRIPT_DEBUGGER
inline ArbUt::OptionalBorrowedPtr<AngelscriptDebugger> GetDebugger() const noexcept { return _debugger.GetValue(); }
inline void SetDebugger(AngelscriptDebugger* debugger) noexcept { _debugger = debugger; }
#endif
asITypeInfo* GetScriptOwnerType(ScriptCategory category) {
auto tryget = _scriptOwnerTypes.TryGet(category);
if (tryget.has_value()) {
return tryget.value();
}
asITypeInfo* t = nullptr;
switch (category) {
case ScriptCategory::Attack: t = _engine->GetTypeInfoByName("ExecutingMove"); break;
case ScriptCategory::Talent: t = _engine->GetTypeInfoByName("Pokemon"); break;
case ScriptCategory::Status: t = _engine->GetTypeInfoByName("Pokemon"); break;
case ScriptCategory::Creature: t = _engine->GetTypeInfoByName("Pokemon"); break;
case ScriptCategory::Battle: t = _engine->GetTypeInfoByName("Battle"); break;
case ScriptCategory::Side: t = _engine->GetTypeInfoByName("BattleSide"); break;
case ScriptCategory::ItemBattleTrigger: t = _engine->GetTypeInfoByName("Pokemon"); break;
}
switch (static_cast<PkmnScriptCategory>(category)) {
case PkmnScriptCategory::Weather: t = _engine->GetTypeInfoByName("Battle"); break;
}
_scriptOwnerTypes.Set(category, t);
return t;
}
void Reset(CreatureLib::Battling::BattleLibrary* library);
};
#endif // PKMNLIB_ANGELSCRIPRESOLVER_HPP