Skip to content

Commit

Permalink
Improve JsObjectImplementation serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
4ian committed Sep 22, 2024
1 parent 058de8d commit faa506c
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 9 deletions.
23 changes: 16 additions & 7 deletions GDevelop.js/Bindings/ObjectJsImplementation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,31 +126,40 @@ bool ObjectJsImplementation::UpdateInitialInstanceProperty(
}

void ObjectJsImplementation::DoSerializeTo(SerializerElement& element) const {
gd::String jsonContent = (const char*)EM_ASM_INT(
SerializerElement* jsCreatedElement = (SerializerElement*)EM_ASM_INT(
{
var self = Module['getCache'](Module['ObjectJsImplementation'])[$0];
if (!self.content)
throw '`content` is not defined on a ObjectJsImplementation.';

return ensureString(JSON.stringify(self.content));
var serializerElement = gd.Serializer.fromJSObject(self.content);
return getPointer(serializerElement);
},
(int)this);
element.AddChild("content") = gd::Serializer::FromJSON(jsonContent);

// We could avoid a copy by using making a function on gd.Serializer that manipulates
// directly the SerializerElement passed to it.
element.AddChild("content") = *jsCreatedElement;
delete jsCreatedElement;
}
void ObjectJsImplementation::DoUnserializeFrom(Project& project,
const SerializerElement& element) {
gd::String jsonContent = gd::Serializer::ToJSON(element.GetChild("content"));

EM_ASM_INT(
{
var self = Module['getCache'](Module['ObjectJsImplementation'])[$0];
if (!self.content)
throw '`content` is not defined on a ObjectJsImplementation.';

self.content = JSON.parse(UTF8ToString($1));
var serializerElement = wrapPointer($1, Module['SerializerElement']);
if (!serializerElement.isValueUndefined() || serializerElement.consideredAsArray()) {
throw new Error('The element passed to ObjectJsImplementation::DoUnserializeFrom is not an object.');
}

// JSON.parse + toJSON is 30% faster than gd.Serializer.toJSObject.
self.content = JSON.parse(gd.Serializer.toJSON(serializerElement));
},
(int)this,
jsonContent.c_str());
(int)&element.GetChild("content"));
}

void ObjectJsImplementation::__destroy__() { // Useless?
Expand Down
6 changes: 4 additions & 2 deletions GDevelop.js/Bindings/ObjectJsImplementation.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
using namespace gd;

/**
* \brief A gd::Object that stores its content in JSON and forward the
* properties related functions to Javascript with Emscripten.
* \brief A gd::ObjectConfiguration that wraps a Javascript object:
* the content of the object is stored in JavaScript in a "content" property,
* allowing both fast access in JavaScript and still ability to access properties
* via the usual methods.
*
* It also implements "ExposeResources" to expose the properties of type
* "resource".
Expand Down
1 change: 1 addition & 0 deletions newIDE/app/src/MainFrame/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1111,6 +1111,7 @@ const MainFrame = (props: Props) => {
if (error.name === 'CloudProjectReadingError') {
setCloudProjectFileMetadataToRecover(fileMetadata);
} else {
console.error('Failed to open the project:', error);
const errorMessage = getOpenErrorMessage
? getOpenErrorMessage(error)
: t`Ensure that you are connected to internet and that the URL used is correct, then try again.`;
Expand Down

0 comments on commit faa506c

Please sign in to comment.