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

Commit 1f607a7

Browse files
committed
Various minor changes and improvements
1 parent 953736f commit 1f607a7

File tree

8 files changed

+118
-47
lines changed

8 files changed

+118
-47
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@ Bindings/WebIDLGrammar.pkl
44
parser.out
55
WebIDLGrammar.pkl
66
.cpp.old
7+
examples/demo-generated-code.js
8+
examples/demo-generated-game.json
9+
**/.DS_Store

Bindings/Bindings.idl

+3-2
Original file line numberDiff line numberDiff line change
@@ -385,14 +385,15 @@ interface InitialInstance {
385385
interface InitialInstancesContainer {
386386
void InitialInstancesContainer();
387387

388-
long GetInstancesCount();
388+
unsigned long GetInstancesCount();
389389

390390
void IterateOverInstances([Ref] InitialInstanceFunctor func);
391391
void IterateOverInstancesWithZOrdering([Ref] InitialInstanceFunctor func, [Const] DOMString layer);
392392
void MoveInstancesToLayer([Const] DOMString fromLayer, [Const] DOMString toLayer);
393393
void RemoveAllInstancesOnLayer([Const] DOMString layer);
394394
void RemoveInitialInstancesOfObject([Const] DOMString obj);
395-
void SomeInstancesAreOnLayer([Const] DOMString layer);
395+
boolean SomeInstancesAreOnLayer([Const] DOMString layer);
396+
void RenameInstancesOfObject([Const] DOMString oldName, [Const] DOMString newName);
396397
void RemoveInstance([Const, Ref] InitialInstance inst);
397398

398399
[Ref] InitialInstance InsertNewInitialInstance();

Bindings/glue.cpp

+7-3
Original file line numberDiff line numberDiff line change
@@ -2354,7 +2354,7 @@ InitialInstancesContainer* EMSCRIPTEN_KEEPALIVE emscripten_bind_InitialInstances
23542354
return new InitialInstancesContainer();
23552355
}
23562356

2357-
int EMSCRIPTEN_KEEPALIVE emscripten_bind_InitialInstancesContainer_GetInstancesCount_0(InitialInstancesContainer* self) {
2357+
unsigned int EMSCRIPTEN_KEEPALIVE emscripten_bind_InitialInstancesContainer_GetInstancesCount_0(InitialInstancesContainer* self) {
23582358
return self->GetInstancesCount();
23592359
}
23602360

@@ -2378,8 +2378,12 @@ void EMSCRIPTEN_KEEPALIVE emscripten_bind_InitialInstancesContainer_RemoveInitia
23782378
self->RemoveInitialInstancesOfObject(arg0);
23792379
}
23802380

2381-
void EMSCRIPTEN_KEEPALIVE emscripten_bind_InitialInstancesContainer_SomeInstancesAreOnLayer_1(InitialInstancesContainer* self, char* arg0) {
2382-
self->SomeInstancesAreOnLayer(arg0);
2381+
bool EMSCRIPTEN_KEEPALIVE emscripten_bind_InitialInstancesContainer_SomeInstancesAreOnLayer_1(InitialInstancesContainer* self, char* arg0) {
2382+
return self->SomeInstancesAreOnLayer(arg0);
2383+
}
2384+
2385+
void EMSCRIPTEN_KEEPALIVE emscripten_bind_InitialInstancesContainer_RenameInstancesOfObject_2(InitialInstancesContainer* self, char* arg0, char* arg1) {
2386+
self->RenameInstancesOfObject(arg0, arg1);
23832387
}
23842388

23852389
void EMSCRIPTEN_KEEPALIVE emscripten_bind_InitialInstancesContainer_RemoveInstance_1(InitialInstancesContainer* self, InitialInstance* arg0) {

Bindings/glue.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -3843,7 +3843,16 @@ InitialInstancesContainer.prototype['SomeInstancesAreOnLayer'] = function(arg0)
38433843
var self = this.ptr;
38443844
if (arg0 && typeof arg0 === 'object') arg0 = arg0.ptr;
38453845
else arg0 = ensureString(arg0);
3846-
_emscripten_bind_InitialInstancesContainer_SomeInstancesAreOnLayer_1(self, arg0);
3846+
return !!(_emscripten_bind_InitialInstancesContainer_SomeInstancesAreOnLayer_1(self, arg0));
3847+
};;
3848+
3849+
InitialInstancesContainer.prototype['RenameInstancesOfObject'] = function(arg0, arg1) {
3850+
var self = this.ptr;
3851+
if (arg0 && typeof arg0 === 'object') arg0 = arg0.ptr;
3852+
else arg0 = ensureString(arg0);
3853+
if (arg1 && typeof arg1 === 'object') arg1 = arg1.ptr;
3854+
else arg1 = ensureString(arg1);
3855+
_emscripten_bind_InitialInstancesContainer_RenameInstancesOfObject_2(self, arg0, arg1);
38473856
};;
38483857

38493858
InitialInstancesContainer.prototype['RemoveInstance'] = function(arg0) {

Gruntfile.js

+21-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,24 @@ module.exports = function(grunt) {
2828
dest: buildOutputPath+'libGD.js',
2929
},
3030
},
31+
//Patch SFML to consider Emscripten target as Linux.
32+
'string-replace': {
33+
sfml: {
34+
files: {
35+
'../ExtLibs/SFML/include/SFML/Config.hpp': '../ExtLibs/SFML/include/SFML/Config.hpp',
36+
},
37+
options: {
38+
replacements: [
39+
// place files inline example
40+
{
41+
pattern: "#elif defined(__linux__)",
42+
replacement: "#elif defined(EMSCRIPTEN) || defined(__linux__)"
43+
}
44+
],
45+
saveUnchanged: false
46+
}
47+
}
48+
},
3149
mkdir: {
3250
embuild: {
3351
options: {
@@ -47,7 +65,7 @@ module.exports = function(grunt) {
4765
}
4866
}
4967
},
50-
//Update glue.cpp and glue.js file using Bindings.idl
68+
//Generate glue.cpp and glue.js file using Bindings.idl, and patch them
5169
updateGDBindings: {
5270
src: "Bindings/Bindings.idl",
5371
command: 'node update-bindings.js',
@@ -94,11 +112,13 @@ module.exports = function(grunt) {
94112
grunt.loadNpmTasks('grunt-contrib-concat');
95113
grunt.loadNpmTasks('grunt-contrib-uglify');
96114
grunt.loadNpmTasks('grunt-contrib-compress');
115+
grunt.loadNpmTasks('grunt-string-replace');
97116
grunt.loadNpmTasks('grunt-shell');
98117
grunt.loadNpmTasks('grunt-newer');
99118
grunt.loadNpmTasks('grunt-mkdir');
100119
grunt.registerTask('build', [
101120
'clean',
121+
'string-replace:sfml',
102122
'mkdir:embuild',
103123
'newer:shell:cmake',
104124
'newer:shell:updateGDBindings',

Readme.md

+56-13
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,49 @@
11
libGD.js
22
========
33

4-
This is a port of some parts of [GDevelop] to Javascript using [Emscripten].
4+
This is a port of some parts of **[GDevelop]** to Javascript using **[Emscripten]**.
55

66
GDevelop is a full featured, cross-platform, open-source game creator software requiring no programming skills. Download it on [the official website](http://compilgames.net) and check its [GitHub page](https://github.com/4ian/GD).
77

8+
This module is used to power [GDevApp], a radically innovative game creator that can be used by anyone to create games directly from a desktop or tablet web browser.
9+
810
How to build
911
------------
1012

1113
Make sure you have [CMake](http://www.cmake.org/) and [Emscripten](https://github.com/kripken/emscripten) installed (your OS package manager should be able to provide both). You need Emscripten 1.33.1 at least to avoid [this bug](https://github.com/kripken/emscripten/pull/3479).
1214

13-
* Clone [GDevelop repository](https://github.com/4ian/GD) and this repository at the root of GD
15+
* Clone [GDevelop repository](https://github.com/4ian/GD) and this repository at the root of GD repository:
1416

1517
```shell
16-
git clone https://github.com/4ian/GD.git
17-
cd GD && git clone https://github.com/4ian/libGD.js.git
18+
git clone https://github.com/4ian/GD.git
19+
cd GD && git clone https://github.com/4ian/libGD.js.git
1820
```
1921

20-
* Patch SFML (TODO)
21-
* Patch WebIDL binder (TODO)
22-
* Launch grunt
22+
* Patch WebIDL binder to support returning javascript boolean. Go to path/to/emscripten/tools/webidl_binder.py, search for
2323

24-
```shell
25-
grunt shell:cmake #The first time only
26-
grunt build
24+
```python
25+
elif return_type == 'String':
26+
call_prefix += 'Pointer_stringify('
27+
call_postfix += ')'
2728
```
2829

29-
### Internal steps for compilation
30+
and add just after:
3031

31-
Internally, the grunt build task create `Binaries/embuild` directory, launch CMake inside to compile GDevelop with *Emscripten toolchain file*, update the glue.cpp and glue.js from Bindings.idl using *Emscripten WebIDL Binder*, launch the compilation with *make* and wrap the generated `libGD.js.raw` into the final `libGD.js` file.
32+
```python
33+
elif return_type == 'Boolean':
34+
call_prefix += '!!('
35+
call_postfix += ')'
36+
```
3237

33-
It also create a compressed `libGD.js.gz` file which is handy for distributing the library pre-compressed to web browsers.
38+
* Launch the build:
39+
40+
```shell
41+
cd libGD.js
42+
grunt shell:cmake #The first time only
43+
grunt build
44+
```
45+
46+
Output is created in */path/to/GD/Binaries/Output/libGD.js/*.
3447

3548
Launch tests and examples
3649
-------------------------
@@ -39,5 +52,35 @@ Launch tests with grunt:
3952

4053
grunt test
4154

55+
Or launch example:
56+
57+
cd examples && node demo.js
58+
59+
The demo generate a json file that can be opened with [GDevelop] or [GDevApp]!
60+
61+
### About the internal steps of compilation
62+
63+
The grunt *build* task:
64+
65+
* create `Binaries/embuild` directory,
66+
* patch SFML `Config.hpp` file to make Emscripten recognized as a linux target,
67+
* launch CMake inside to compile GDevelop with *Emscripten toolchain file*,
68+
* update the glue.cpp and glue.js from Bindings.idl using *Emscripten WebIDL Binder*,
69+
* launch the compilation with *make* and wrap the generated `libGD.js.raw` into the final `libGD.js` file.
70+
71+
It also create a compressed `libGD.js.gz` file which is handy for distributing the library pre-compressed to web browsers.
72+
73+
Documentation
74+
-------------
75+
76+
Refer to [GDevelop documentation](http://4ian.github.io/GD-Documentation/GDCore%20Documentation/) for detailed documentation of the original C++ classes. The file Bindings.idl describes all the classes available in libGD.js.
77+
78+
License
79+
-------
80+
81+
* This library is distributed under the **MIT license**.
82+
* GDevelop is under the MIT license (and GPL v3 license for the GUI).
83+
4284
[GDevelop]: https://github.com/4ian/GD
85+
[GDevApp]: https://gdevapp.com
4386
[Emscripten]: https://github.com/kripken/emscripten

examples/demo.js

+17-27
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
/**
2-
* Run this file using node.js. Be sure to paste libGD.js in the same folder:
3-
*
4-
* node demo.js
2+
* Example of various manipulations using libGD.js
53
*/
64

75
var gd = require('../../Binaries/Output/libGD.js/Release/libGD.js');
@@ -18,7 +16,6 @@ console.log(" ");
1816
var project = gd.ProjectHelper.createNewGDJSProject(); //The project is based on the Javascript platform
1917
project.setMinimumFPS(20);
2018
project.setMaximumFPS(20);
21-
project.customValue = 54;
2219
project.getVariables().insertNew("Global variable", 0).setValue(10);
2320
var layout = project.insertNewLayout("Super scene", 0); //"Layout" is a synonym for "Scene".
2421
layout.setBackgroundColor(125,100,240);
@@ -32,7 +29,7 @@ layout.insertNewObject(project, "Sprite", "MyCharacter", 0);
3229
var obj = layout.getObject("MyObject");
3330
obj.setName("Background");
3431

35-
//Adding an animation to a sprite:
32+
//Add an animation to a sprite:
3633
var anim = new gd.Animation();
3734
anim.setDirectionsCount(2);
3835
gd.asSpriteObject(obj).addAnimation(anim);
@@ -77,12 +74,12 @@ console.log("*** Events displayed as english sentences (Just like in the events
7774

7875
var condition = standardEvt.getConditions().get(0);
7976
var conditionSentenceInEnglish = gd.InstructionSentenceFormatter.get().translate(condition,
80-
gd.MetadataProvider.getConditionMetadata(gd.JsPlatform.get(), "KeyPressed"));
77+
gd.MetadataProvider.getConditionMetadata(gd.JsPlatform.get(), "KeyPressed"));
8178
console.log("Condition:", conditionSentenceInEnglish);
8279

8380
var action = standardEvt.getActions().get(0);
8481
var actionSentenceInEnglish = gd.InstructionSentenceFormatter.get().translate(action,
85-
gd.MetadataProvider.getActionMetadata(gd.JsPlatform.get(), "Delete"));
82+
gd.MetadataProvider.getActionMetadata(gd.JsPlatform.get(), "Delete"));
8683
console.log("Action:", actionSentenceInEnglish);
8784

8885
//Do automatic refactoring on the events:
@@ -91,42 +88,35 @@ console.log("Action:", actionSentenceInEnglish);
9188
layout.getObject("MyCharacter").setName("MySuperHero"); //Change the object name...
9289
instances.renameInstancesOfObject("MyCharacter", "MySuperHero"); //...update the instances on the scene...
9390
gd.EventsRefactorer.renameObjectInEvents(gd.JsPlatform.get(), project,
94-
layout, layout.getEvents(), "MyCharacter", "MySuperHero"); //...and update the events.
91+
layout, layout.getEvents(), "MyCharacter", "MySuperHero"); //...and update the events.
9592

9693
console.log("*** The action after renaming MyCharacter to MySuperHero:");
9794
var actionSentenceInEnglish = gd.InstructionSentenceFormatter.get().translate(standardEvt.getActions().get(0),
98-
gd.MetadataProvider.getActionMetadata(gd.JsPlatform.get(), "Delete"));
95+
gd.MetadataProvider.getActionMetadata(gd.JsPlatform.get(), "Delete"));
9996
console.log("Action:", actionSentenceInEnglish);
10097

10198
//Finally, write the game to a file.
10299
var serializedProject = new gd.SerializerElement();
103100
project.serializeTo(serializedProject);
104101
var jsonProject = gd.Serializer.toJSON(serializedProject);
105102
fs.writeFile('demo-generated-game.json', jsonProject, function (err) {
106-
if (err) throw err;
107-
console.log('*** JSON file of the generated project saved in "demo-generated-game.json". Open it!');
108-
109-
var unserializedProject = new gd.SerializerElement();
110-
unserializedProject = gd.Serializer.fromJSON(jsonProject);
111-
project.unserializeFrom(unserializedProject);
112-
113-
var serializedProject = new gd.SerializerElement();
114-
project.serializeTo(serializedProject);
115-
var jsonProject = gd.Serializer.toJSON(serializedProject);
116-
fs.writeFile('demo-generated-game2.json', jsonProject, function (err) {
117-
if (err) throw err;
118-
console.log('*** JSON file of the generated project saved in "demo-generated-game2.json". Open it!');
119-
});
103+
if (err) throw err;
104+
console.log('*** JSON file of the generated project saved in "demo-generated-game.json". Open it with GDevelop or GDevApp!');
105+
106+
var project = new gd.ProjectHelper.createNewGDJSProject();
107+
var unserializedProject = gd.Serializer.fromJSON(jsonProject);
108+
project.unserializeFrom(unserializedProject);
120109
});
121110

122111
//And also generate the code for the events to demonstrate how events are translated to Javascript!
123-
var code = gd.GenerateSceneEventsCompleteCode(project, layout, layout.getEvents(), new gd.SetString(), true);
112+
var code = gd.EventsCodeGenerator.generateSceneEventsCompleteCode(project,
113+
layout, layout.getEvents(), new gd.SetString(), true);
124114
fs.writeFile('demo-generated-code.js', code, function (err) {
125115
if (err) throw err;
126-
console.log('*** Javascript code saved in "demo-generated-code.js". Open it (but it\'s not meant to be read by humans) !');
116+
console.log('*** Javascript code saved in "demo-generated-code.js". You can open it, but it\'s not meant to be read by humans! ;)');
127117
});
128118

129-
//Note that any object from gd created using new operator ("var myObject = new gd.")
119+
//Note that any object from gd created using new operator ("var myObject = new gd.*")
130120
//must be deleted. Most of the time, it is not necessary to use new because there are methods for
131-
//creating the objects (InsertLayout, InsertNewObject...) and everything is contained in the project object:
121+
//creating the objects (insertLayout, insertNewObject...) and everything is contained in the project object:
132122
project.delete();

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"grunt-mocha-cli": "~1.8.0",
2828
"grunt-newer": "^1.1.0",
2929
"grunt-shell": "^1.1.2",
30+
"grunt-string-replace": "^1.2.0",
3031
"mocha": "~1.18.2"
3132
}
3233
}

0 commit comments

Comments
 (0)