Support for saving compiled AngelScript to either file or RAM, so we can reuse it.
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
2020-04-11 14:42:49 +02:00
parent 0b045db811
commit bf36103c11
6 changed files with 228 additions and 15 deletions

View File

@@ -6,6 +6,8 @@
#include "../../../extern/angelscript_addons/scripthandle/scripthandle.h"
#include "../../../extern/angelscript_addons/scripthelper/scripthelper.h"
#include "../../../extern/angelscript_addons/scriptstdstring/scriptstdstring.h"
#include "ByteCodeHandling/FileByteCodeStream.hpp"
#include "ByteCodeHandling/MemoryByteCodeStream.hpp"
#include "TypeRegistry/BasicScriptClass.hpp"
#include "TypeRegistry/Battling/RegisterBattleClass.hpp"
#include "TypeRegistry/Battling/RegisterBattleLibrary.hpp"
@@ -25,26 +27,19 @@ CreatureLib::Battling::ScriptResolver* PkmnLib::Battling::BattleLibrary::CreateS
return new AngelScripResolver();
}
static void TranslateException(asIScriptContext *ctx, void* /*userParam*/)
{
try
{
static void TranslateException(asIScriptContext* ctx, void* /*userParam*/) {
try {
// Retrow the original exception so we can catch it again
throw;
}
catch( std::exception &e )
{
} catch (std::exception& e) {
// Tell the VM the type of exception that occurred
ctx->SetException(e.what());
}
catch(...)
{
} catch (...) {
// The callback must not allow any exception to be thrown, but it is not necessary
// to explicitly set an exception string if the default exception string is sufficient
}
}
void AngelScripResolver::Initialize(CreatureLib::Battling::BattleLibrary* arg) {
for (auto scriptCategory : ScriptCategoryHelper::GetValues()) {
_typeDatabase.Insert(scriptCategory, {});
@@ -125,7 +120,7 @@ void AngelScripResolver::MessageCallback(const asSMessageInfo* msg, void* param)
}
CreatureLib::Battling::Script* AngelScripResolver::LoadScript(ScriptCategory category, const ConstString& scriptName) {
Dictionary<uint32_t, AngelScriptTypeInfo*> innerDb;
Dictionary<ConstString, AngelScriptTypeInfo*> innerDb;
if (!_typeDatabase.TryGet(category, innerDb)) {
_typeDatabase.Insert(category, innerDb);
return nullptr;
@@ -200,3 +195,58 @@ void AngelScripResolver::FinalizeModule() {
void AngelScripResolver::CreateScript(const char* name, const char* script) {
_builder.AddSectionFromMemory(name, script);
}
void AngelScripResolver::WriteByteCodeToFile(const char* file, bool stripDebugInfo) {
FILE* wFile = fopen(file, "w");
auto stream = new FileByteCodeStream(wFile);
_mainModule->SaveByteCode(stream, stripDebugInfo);
fclose(wFile);
delete stream;
}
void AngelScripResolver::LoadByteCodeFromFile(
const char* file, const Dictionary<ScriptCategory, Dictionary<ConstString, const char*>>& types) {
FILE* rFile = fopen(file, "r");
auto stream = new FileByteCodeStream(rFile);
LoadByteCode(stream, types);
fclose(rFile);
delete stream;
//_typeDatabase = types;
}
uint8_t* AngelScripResolver::WriteByteCodeToMemory(size_t& size, bool stripDebugInfo) {
auto stream = new MemoryByteCodeStream();
auto result = _mainModule->SaveByteCode(stream, stripDebugInfo);
Assert(result == asSUCCESS);
auto arr = stream->GetOut();
size = stream->GetWrittenSize();
arr = static_cast<uint8_t*>(realloc(arr, size));
delete stream;
return arr;
}
void AngelScripResolver::LoadByteCodeFromMemory(
uint8_t* byte, size_t size, const Dictionary<ScriptCategory, Dictionary<ConstString, const char*>>& types) {
auto stream = new MemoryByteCodeStream(byte, size);
LoadByteCode(stream, types);
delete stream;
}
void AngelScripResolver::LoadByteCode(asIBinaryStream* stream,
const Dictionary<ScriptCategory, Dictionary<ConstString, const char*>>& types) {
int result = _mainModule->LoadByteCode(stream);
Assert(result == asSUCCESS);
auto typeCount = _mainModule->GetObjectTypeCount();
Dictionary<uint32_t, asITypeInfo*> objectTypes;
for (asUINT i = 0; i < typeCount; i++) {
auto t = _mainModule->GetObjectTypeByIndex(i);
objectTypes.Insert(ConstString::GetHash(t->GetName()), t);
}
Dictionary<ScriptCategory, Dictionary<ConstString, AngelScriptTypeInfo*>> typeDatabase;
for (auto& innerDb : types) {
Dictionary<ConstString, AngelScriptTypeInfo*> newInnerDb;
for (auto& val : innerDb.second) {
auto decl = val.second;
auto type = objectTypes[ConstString::GetHash(decl)];
newInnerDb.Insert(val.first, new AngelScriptTypeInfo(val.first, type));
}
typeDatabase.Insert(innerDb.first, newInnerDb);
}
_typeDatabase = typeDatabase;
}