PkmnLib/src/ScriptResolving/AngelScript/AngelScripResolver.cpp

142 lines
5.7 KiB
C++
Raw Normal View History

#include "AngelScripResolver.hpp"
#include <CreatureLib/Battling/Models/Creature.hpp>
#include <cassert>
2020-02-02 11:23:50 +00:00
#include "../../../extern/angelscript_addons/scriptarray/scriptarray.h"
#include "../../../extern/angelscript_addons/scripthandle/scripthandle.h"
2020-02-02 11:23:50 +00:00
#include "../../../extern/angelscript_addons/scripthelper/scripthelper.h"
#include "../../../extern/angelscript_addons/scriptstdstring/scriptstdstring.h"
#include "TypeRegistry/BasicScriptClass.hpp"
#include "TypeRegistry/Battling/RegisterBattleClass.hpp"
#include "TypeRegistry/Battling/RegisterBattleLibrary.hpp"
#include "TypeRegistry/Battling/RegisterExecutingAttack.hpp"
#include "TypeRegistry/Battling/RegisterPokemonClass.hpp"
#include "TypeRegistry/Battling/RegisterTurnChoices.hpp"
2020-01-13 18:52:32 +00:00
#include "TypeRegistry/Library/RegisterGrowthRateTypes.hpp"
#include "TypeRegistry/Library/RegisterItemTypes.hpp"
#include "TypeRegistry/Library/RegisterMoveTypes.hpp"
#include "TypeRegistry/Library/RegisterSpeciesTypes.hpp"
2020-01-23 14:10:08 +00:00
#include "TypeRegistry/Library/RegisterStaticLibraryTypes.hpp"
2020-01-13 19:16:23 +00:00
#include "TypeRegistry/Library/RegisterTypeLibrary.hpp"
2020-01-13 18:43:34 +00:00
CreatureLib::Battling::ScriptResolver* PkmnLib::Battling::BattleLibrary::CreateScriptResolver() {
return new AngelScripResolver();
}
2020-01-12 17:20:59 +00:00
void AngelScripResolver::Initialize(CreatureLib::Battling::BattleLibrary* arg) {
auto library = (PkmnLib::Battling::BattleLibrary*)arg;
_engine = asCreateScriptEngine();
int32_t r = _engine->SetMessageCallback(asFUNCTION(MessageCallback), nullptr, asCALL_CDECL);
if (r < 0)
throw CreatureException("Registering message callback failed.");
_engine->SetEngineProperty(asEP_DISALLOW_EMPTY_LIST_ELEMENTS, true);
_engine->SetEngineProperty(asEP_DISALLOW_VALUE_ASSIGN_FOR_REF_TYPE, false);
_engine->SetEngineProperty(asEP_ALLOW_UNSAFE_REFERENCES, true);
_engine->SetEngineProperty(asEP_ALWAYS_IMPL_DEFAULT_CONSTRUCT, true);
_engine->SetEngineProperty(asEP_AUTO_GARBAGE_COLLECT, false);
2020-01-18 12:07:56 +00:00
_engine->SetEngineProperty(asEP_REQUIRE_ENUM_SCOPE, true);
_engine->SetEngineProperty(asEP_PROPERTY_ACCESSOR_MODE, 2);
_engine->SetEngineProperty(asEP_COMPILER_WARNINGS, 2);
RegisterStdString(_engine);
// Register Script Array type
RegisterScriptArray(_engine, true);
r = _engine->RegisterGlobalFunction("void print(const string &in)", asFUNCTION(Print), asCALL_CDECL);
2020-01-13 18:43:34 +00:00
if (r < 0)
throw CreatureException("Registering print function failed.");
RegisterScriptHandle(_engine);
_builder.StartNewModule(_engine, "pkmn");
_mainModule = _builder.GetModule();
RegisterTypes();
RegisterExceptionRoutines(_engine);
auto staticLib = library->GetStaticLib();
_engine->RegisterGlobalProperty("const StaticLibrary@ StaticLib", &staticLib);
_contextPool = new ContextPool(_engine);
}
void AngelScripResolver::RegisterTypes() {
// Register static library types
RegisterSpeciesTypes::Register(_engine);
2020-01-13 18:21:41 +00:00
RegisterItemTypes::Register(_engine);
2020-01-13 18:43:34 +00:00
RegisterMoveTypes::Register(_engine);
2020-01-13 18:52:32 +00:00
RegisterGrowthRateTypes::Register(_engine);
2020-01-13 19:16:23 +00:00
RegisterTypeLibrary::Register(_engine);
2020-01-23 14:10:08 +00:00
RegisterStaticLibraryTypes::Register(_engine);
// Register battle types
RegisterPokemonClass::Register(_engine);
RegisterExecutingAttack::Register(_engine);
RegisterTurnChoices::Register(_engine);
RegisterBattleLibrary::Register(_engine);
RegisterBattleClass::Register(_engine);
[[maybe_unused]] int r =
_engine->RegisterObjectMethod("Pokemon", "const Battle@ get_Battle() const property",
asMETHOD(CreatureLib::Battling::Creature, GetBattle), asCALL_THISCALL);
assert(r >= 0);
// Register base script
BasicScriptClass::Register(_engine);
}
2020-02-23 15:02:27 +00:00
AngelScriptTypeInfo* AngelScripResolver::GetTypeInfo(const std::string& name, const std::string& decl) {
auto find = _types.find(decl);
2020-01-13 18:43:34 +00:00
if (find != _types.end()) {
return find->second;
}
2020-02-23 15:02:27 +00:00
auto type = _mainModule->GetTypeInfoByDecl(decl.c_str());
2020-01-13 18:43:34 +00:00
if (type == nullptr) {
2020-02-23 15:02:27 +00:00
_types.insert({decl, nullptr});
return nullptr;
}
2020-02-23 15:02:27 +00:00
auto typeinfo = new AngelScriptTypeInfo(name, type);
_types.insert({decl, typeinfo});
return typeinfo;
}
void AngelScripResolver::MessageCallback(const asSMessageInfo* msg, void* param) {
const char* type = "ERR ";
if (msg->type == asMSGTYPE_WARNING)
type = "WARN";
else if (msg->type == asMSGTYPE_INFORMATION)
type = "INFO";
printf("%s (%d, %d) : %s : %s\n", msg->section, msg->row, msg->col, type, msg->message);
}
static constexpr const char* GetCategoryNamespace(ScriptCategory category) {
switch (category) {
case ScriptCategory::Attack: return "Moves";
case ScriptCategory::Talent: return "Abilities";
case ScriptCategory::Status: return "Status";
case ScriptCategory::Creature: return "Pokemon";
case ScriptCategory::Battle: return "Battle";
case ScriptCategory::Side: return "Side";
default: throw CreatureException("Unknown script category");
}
}
CreatureLib::Battling::Script* AngelScripResolver::LoadScript(ScriptCategory category, const std::string& scriptName) {
std::stringstream decl;
decl << GetCategoryNamespace(category) << "::" << scriptName;
2020-02-23 15:02:27 +00:00
auto typeInfo = GetTypeInfo(scriptName, decl.str());
2020-01-13 18:43:34 +00:00
if (typeInfo == nullptr)
return nullptr;
auto ctx = _contextPool->RequestContext();
auto obj = typeInfo->Instantiate(ctx);
_contextPool->ReturnContextToPool(ctx);
2020-02-23 15:02:27 +00:00
return new AngelScriptScript(typeInfo, obj, _contextPool);
}
void AngelScripResolver::FinalizeModule() {
int r = _builder.BuildModule();
if (r < 0)
throw CreatureException("Building Script Module failed.");
}
void AngelScripResolver::CreateScript(const char* name, const char* script) {
_builder.AddSectionFromMemory(name, script);
}