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
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user