Rework of ScriptResolver to binary handling. Now also serialises the type database to the stream, simplifying it's api.
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2020-05-02 11:13:04 +02:00
parent 846580550a
commit bd77b58743
6 changed files with 221 additions and 37 deletions

View File

@@ -210,43 +210,93 @@ void AngelScriptResolver::CreateScript(const char* name, const char* script) {
}
void AngelScriptResolver::WriteByteCodeToFile(const char* file, bool stripDebugInfo) {
FILE* wFile = nullptr;
// Open file in write binary mode.
wFile = fopen(file, "wb");
// Ensure we opened it.
AssertNotNull(wFile);
auto stream = new FileByteCodeStream(wFile);
// Save the initial position, as we need to write here later.
fpos_t startPos;
fgetpos(wFile, &startPos);
// The first 8 bytes are the position of the data for which script name is which script decl.
// We don't know this position yet, so we write an empty value here. We write a size of 8, to accommodate an
// unsigned long.
uint64_t byteCodeSizeArr[]{0};
fwrite(byteCodeSizeArr, sizeof(uint64_t), 1, wFile);
// We initialize a stream, with no bounds (as this is a read thing)
auto stream = new FileByteCodeStream(wFile, SIZE_MAX);
// And save the angelscript byte code.
_mainModule->SaveByteCode(stream, stripDebugInfo);
// We grab the current position of the written file. This is the position the types will be written on. So we need
// to know this.
uint64_t bytecodeSize = (uint64_t)ftell(wFile);
stream->WriteTypes(_typeDatabase);
// Go back to the start of the file
fsetpos(wFile, &startPos);
// And write the actual position the types are at.
byteCodeSizeArr[0] = bytecodeSize;
fwrite(byteCodeSizeArr, sizeof(uint64_t), 1, wFile);
// Close the file
Assert(fclose(wFile) == 0);
delete stream;
}
void AngelScriptResolver::LoadByteCodeFromFile(
const char* file, const Dictionary<ScriptCategory, Dictionary<ConstString, const char*>>& types) {
void AngelScriptResolver::LoadByteCodeFromFile(const char* file) {
FILE* rFile = nullptr;
// Open the file in read binary mode
rFile = fopen(file, "rb");
// Ensure it opened
AssertNotNull(rFile);
auto stream = new FileByteCodeStream(rFile);
// the first 8 bytes are position of the types database, everything before that is the angelscript byte code.
uint64_t byteCodeSize[]{0};
fread(byteCodeSize, sizeof(uint64_t), 1, rFile);
// Initialize a stream, with the earlier found bounds.
auto stream = new FileByteCodeStream(rFile, byteCodeSize[0] - 1);
// And load the angelscript byte code.
int result = _mainModule->LoadByteCode(stream);
// Ensure we succeeded in this.
Assert(result == asSUCCESS);
// Begin loading the type database
auto types = stream->ReadTypes();
InitializeByteCode(stream, types);
Assert(fclose(rFile) == 0);
delete stream;
}
uint8_t* AngelScriptResolver::WriteByteCodeToMemory(size_t& size, bool stripDebugInfo) {
auto stream = new MemoryByteCodeStream();
size_t byteCodeSize[]{0};
stream->Write(byteCodeSize, sizeof(uint64_t));
auto result = _mainModule->SaveByteCode(stream, stripDebugInfo);
Assert(result == asSUCCESS);
byteCodeSize[0] = (uint64_t)stream->GetWrittenSize();
stream->WriteTypes(_typeDatabase);
stream->WriteToPosition(byteCodeSize, sizeof(uint64_t), 0);
auto arr = stream->GetOut();
size = stream->GetWrittenSize();
arr = static_cast<uint8_t*>(realloc(arr, size * sizeof(uint8_t)));
delete stream;
return arr;
}
void AngelScriptResolver::LoadByteCodeFromMemory(
uint8_t* byte, size_t size, const Dictionary<ScriptCategory, Dictionary<ConstString, const char*>>& types) {
void AngelScriptResolver::LoadByteCodeFromMemory(uint8_t* byte, size_t size) {
auto stream = new MemoryByteCodeStream(byte, size);
uint64_t byteCodeSizeArr[]{0};
stream->Read(byteCodeSizeArr, sizeof(uint64_t));
stream->SetAngelScriptBound((size_t)byteCodeSizeArr[0]);
// And load the angelscript byte code.
int result = _mainModule->LoadByteCode(stream);
// Ensure we succeeded in this.
Assert(result == asSUCCESS);
// Begin loading the type database
auto types = stream->ReadTypes();
InitializeByteCode(stream, types);
delete stream;
}
void AngelScriptResolver::InitializeByteCode(
asIBinaryStream* stream, const Dictionary<ScriptCategory, Dictionary<ConstString, const char*>>& types) {
int result = _mainModule->LoadByteCode(stream);
Assert(result == asSUCCESS);
asIBinaryStream* stream, const Dictionary<ScriptCategory, Dictionary<ConstString, uint32_t>>& types) {
auto typeCount = _mainModule->GetObjectTypeCount();
Dictionary<uint32_t, asITypeInfo*> objectTypes;
@@ -255,11 +305,11 @@ void AngelScriptResolver::InitializeByteCode(
objectTypes.Insert(ConstString::GetHash(t->GetName()), t);
}
Dictionary<ScriptCategory, Dictionary<ConstString, AngelScriptTypeInfo*>> typeDatabase;
for (auto& innerDb : types) {
for (const auto& innerDb : types) {
Dictionary<ConstString, AngelScriptTypeInfo*> newInnerDb;
for (auto& val : innerDb.second) {
for (const auto& val : innerDb.second) {
auto decl = val.second;
auto type = objectTypes[ConstString::GetHash(decl)];
auto type = objectTypes[decl];
newInnerDb.Insert(val.first, new AngelScriptTypeInfo(val.first, type));
}
typeDatabase.Insert(innerDb.first, newInnerDb);