Skip to content
This repository was archived by the owner on Apr 25, 2019. It is now read-only.

Commit 234ecd8

Browse files
committed
Expose classes to declare gd::BehaviorsSharedData in extensions
1 parent 02c701a commit 234ecd8

10 files changed

+839
-358
lines changed
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#include "BehaviorSharedDataJsImplementation.h"
2+
#include <GDCore/IDE/Dialogs/PropertyDescriptor.h>
3+
#include <GDCore/Project/Behavior.h>
4+
#include <GDCore/Project/Project.h>
5+
#include <GDCore/Serialization/Serializer.h>
6+
#include <GDCore/Serialization/SerializerElement.h>
7+
#include <emscripten.h>
8+
#include <map>
9+
10+
using namespace gd;
11+
12+
std::shared_ptr<gd::BehaviorsSharedData> BehaviorSharedDataJsImplementation::Clone()
13+
const {
14+
BehaviorSharedDataJsImplementation* clone =
15+
new BehaviorSharedDataJsImplementation(*this);
16+
17+
// Copy the references to the implementations of the functions
18+
EM_ASM_INT(
19+
{
20+
Module['getCache'](
21+
Module['BehaviorSharedDataJsImplementation'])[$0] = {};
22+
Module['getCache'](
23+
Module['BehaviorSharedDataJsImplementation'])[$0]['ptr'] = $0;
24+
Module['getCache'](
25+
Module['BehaviorSharedDataJsImplementation'])[$0]['getProperties'] =
26+
Module['getCache'](
27+
Module['BehaviorSharedDataJsImplementation'])[$1]
28+
['getProperties'];
29+
Module['getCache'](Module['BehaviorSharedDataJsImplementation'])
30+
[$0]['updateProperty'] = Module['getCache'](
31+
Module['BehaviorSharedDataJsImplementation'])[$1]
32+
['updateProperty'];
33+
},
34+
(int)clone,
35+
(int)this);
36+
37+
return std::shared_ptr<gd::BehaviorsSharedData>(clone);
38+
}
39+
std::map<gd::String, gd::PropertyDescriptor>
40+
BehaviorSharedDataJsImplementation::GetProperties(gd::Project&) const {
41+
std::map<gd::String, gd::PropertyDescriptor>* jsCreatedProperties = nullptr;
42+
std::map<gd::String, gd::PropertyDescriptor> copiedProperties;
43+
44+
jsCreatedProperties = (std::map<gd::String, gd::PropertyDescriptor>*)EM_ASM_INT(
45+
{
46+
var self = Module['getCache'](
47+
Module['BehaviorSharedDataJsImplementation'])[$0];
48+
if (!self.hasOwnProperty('getProperties'))
49+
throw 'getProperties is not defined on a BehaviorSharedDataJsImplementation.';
50+
51+
var objectContent = JSON.parse(Pointer_stringify($1));
52+
var newProperties = self['getProperties'](objectContent);
53+
if (!newProperties)
54+
throw 'getProperties returned nothing in a gd::BehaviorSharedDataJsImplementation.';
55+
56+
return getPointer(newProperties);
57+
},
58+
(int)this,
59+
jsonContent.c_str());
60+
61+
copiedProperties = *jsCreatedProperties;
62+
delete jsCreatedProperties;
63+
return copiedProperties;
64+
}
65+
bool BehaviorSharedDataJsImplementation::UpdateProperty(const gd::String& arg0,
66+
const gd::String& arg1,
67+
Project&) {
68+
jsonContent = (const char*)EM_ASM_INT(
69+
{
70+
var self = Module['getCache'](
71+
Module['BehaviorSharedDataJsImplementation'])[$0];
72+
if (!self.hasOwnProperty('updateProperty'))
73+
throw 'updateProperty is not defined on a BehaviorSharedDataJsImplementation.';
74+
var objectContent = JSON.parse(Pointer_stringify($1));
75+
self['updateProperty'](
76+
objectContent, Pointer_stringify($2), Pointer_stringify($3));
77+
return ensureString(JSON.stringify(objectContent));
78+
},
79+
(int)this,
80+
jsonContent.c_str(),
81+
arg0.c_str(),
82+
arg1.c_str());
83+
84+
return true;
85+
}
86+
87+
void BehaviorSharedDataJsImplementation::SerializeTo(
88+
SerializerElement& arg0) const {
89+
arg0.AddChild("content") = gd::Serializer::FromJSON(jsonContent);
90+
}
91+
void BehaviorSharedDataJsImplementation::UnserializeFrom(
92+
const SerializerElement& arg1) {
93+
jsonContent = gd::Serializer::ToJSON(arg1.GetChild("content"));
94+
}
95+
96+
void BehaviorSharedDataJsImplementation::__destroy__() { // Useless?
97+
EM_ASM_INT(
98+
{
99+
var self = Module['getCache'](
100+
Module['BehaviorSharedDataJsImplementation'])[$0];
101+
if (!self.hasOwnProperty('__destroy__'))
102+
throw 'a JSImplementation must implement all functions, you forgot BehaviorSharedDataJsImplementation::__destroy__.';
103+
self['__destroy__']();
104+
},
105+
(int)this);
106+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include <GDCore/IDE/Dialogs/PropertyDescriptor.h>
2+
#include <GDCore/Project/BehaviorsSharedData.h>
3+
#include <GDCore/Project/Project.h>
4+
#include <GDCore/Serialization/Serializer.h>
5+
#include <GDCore/Serialization/SerializerElement.h>
6+
#include <emscripten.h>
7+
8+
using namespace gd;
9+
10+
/**
11+
* \brief A gd::BehaviorsSharedData that stores its content in JSON and forward the properties related
12+
* functions to Javascript with Emscripten.
13+
*/
14+
class BehaviorSharedDataJsImplementation : public BehaviorsSharedData {
15+
public:
16+
BehaviorSharedDataJsImplementation() : BehaviorsSharedData(), jsonContent("{}") {}
17+
virtual std::shared_ptr<gd::BehaviorsSharedData> Clone() const override;
18+
19+
virtual std::map<gd::String, gd::PropertyDescriptor> GetProperties(
20+
gd::Project& project) const override;
21+
virtual bool UpdateProperty(const gd::String& name,
22+
const gd::String& value,
23+
gd::Project& project) override;
24+
25+
void __destroy__();
26+
27+
virtual void SerializeTo(SerializerElement& arg0) const override;
28+
virtual void UnserializeFrom(const SerializerElement& arg1) override;
29+
30+
const gd::String& GetRawJSONContent() const { return jsonContent; };
31+
BehaviorSharedDataJsImplementation& SetRawJSONContent(const gd::String& newContent) {
32+
jsonContent = newContent;
33+
return *this;
34+
};
35+
36+
private:
37+
gd::String jsonContent;
38+
};

Bindings/Bindings.idl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ interface ProjectHelper {
8787
[Ref] Project STATIC_CreateNewGDJSProject();
8888
void STATIC_InitializePlatforms();
8989
[Const, Value] DOMString STATIC_SanityCheckBehaviorProperty(Behavior behavior, [Const] DOMString propertyName, [Const] DOMString newValue);
90+
[Const, Value] DOMString STATIC_SanityCheckBehaviorsSharedDataProperty(BehaviorsSharedData behavior, [Const] DOMString propertyName, [Const] DOMString newValue);
9091
[Const, Value] DOMString STATIC_SanityCheckObjectProperty(gdObject obj, [Const] DOMString propertyName, [Const] DOMString newValue);
9192
[Const, Value] DOMString STATIC_SanityCheckObjectInitialInstanceProperty(gdObject obj, [Const] DOMString propertyName, [Const] DOMString newValue);
9293
};
@@ -361,6 +362,21 @@ interface BehaviorsSharedData {
361362
void UnserializeFrom([Const, Ref] SerializerElement element);
362363
};
363364

365+
[JSImplementation="BehaviorsSharedData"]
366+
interface BehaviorSharedDataJsImplementation {
367+
void BehaviorSharedDataJsImplementation();
368+
// BehaviorSharedDataJsImplementation Clone(); Not exposed
369+
370+
[Value] MapStringPropertyDescriptor GetProperties([Ref] Project project);
371+
boolean UpdateProperty([Const] DOMString name, [Const] DOMString value, [Ref] Project project);
372+
373+
void SerializeTo([Ref] SerializerElement element);
374+
void UnserializeFrom([Const, Ref] SerializerElement element);
375+
376+
[Const, Ref] DOMString GetRawJSONContent();
377+
[Ref] BehaviorSharedDataJsImplementation SetRawJSONContent([Const] DOMString newContent);
378+
};
379+
364380
interface gdObject {
365381
// /!\ We need to call it gdObject to avoid messing up with javascript Object
366382
// global in glue.js!

Bindings/ProjectHelper.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,46 @@ class ProjectHelper {
8585
return "";
8686
}
8787

88+
/**
89+
* \brief This check that the given gd::BehaviorsSharedData can be properly cloned
90+
* and have the given property updated.
91+
*/
92+
static gd::String SanityCheckBehaviorsSharedDataProperty(gd::BehaviorsSharedData* sharedData,
93+
const gd::String& propertyName,
94+
const gd::String& newValue) {
95+
gd::Project project;
96+
project.AddPlatform(JsPlatform::Get());
97+
98+
gd::String originalValue =
99+
sharedData->GetProperties(project)[propertyName].GetValue();
100+
101+
std::shared_ptr<gd::BehaviorsSharedData> copiedSharedData = sharedData->Clone();
102+
if (copiedSharedData->GetProperties(project)[propertyName].GetValue() !=
103+
originalValue) {
104+
return "FAIL: Cloning the sharedData does not copy properly the property";
105+
}
106+
107+
sharedData->UpdateProperty(propertyName, newValue, project);
108+
gd::String updatedValue =
109+
sharedData->GetProperties(project)[propertyName].GetValue();
110+
if (updatedValue != newValue) {
111+
return "FAIL: expected the newValue to be set for the property, but "
112+
"received:" +
113+
updatedValue;
114+
}
115+
116+
gd::String copiedSharedDataValue =
117+
copiedSharedData->GetProperties(project)[propertyName].GetValue();
118+
if (copiedSharedDataValue != originalValue) {
119+
return "FAIL: Updating the property of the sharedData will change the "
120+
"property of the cloned sharedData. Clone sharedData property is "
121+
"now: " +
122+
copiedSharedDataValue + ". Should have been:" + originalValue;
123+
}
124+
125+
return "";
126+
}
127+
88128
/**
89129
* \brief This check that the given gd::Object can be properly cloned
90130
* and have the given property updated.

Bindings/Wrapper.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
#include "ProjectHelper.h"
6767

6868
#include "BehaviorJsImplementation.h"
69+
#include "BehaviorSharedDataJsImplementation.h"
6970
#include "ObjectJsImplementation.h"
7071

7172
/**
@@ -468,6 +469,8 @@ typedef ParticleEmitterObject::RendererType ParticleEmitterObject_RendererType;
468469
#define STATIC_SanityCheckObjectProperty SanityCheckObjectProperty
469470
#define STATIC_SanityCheckObjectInitialInstanceProperty \
470471
SanityCheckObjectInitialInstanceProperty
472+
#define STATIC_SanityCheckBehaviorsSharedDataProperty \
473+
SanityCheckBehaviorsSharedDataProperty
471474

472475
// We postfix some methods with "At" as Javascript does not support overloading
473476
#define GetLayoutAt GetLayout

0 commit comments

Comments
 (0)