mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
201 Commits
v5.0.0-bet
...
v5.0.0-bet
Author | SHA1 | Date | |
---|---|---|---|
![]() |
329672d283 | ||
![]() |
139d0a6cea | ||
![]() |
2da45c9691 | ||
![]() |
11e0059e89 | ||
![]() |
dbf2086318 | ||
![]() |
f7405839d3 | ||
![]() |
e2943173be | ||
![]() |
0944ba18df | ||
![]() |
e5ef299390 | ||
![]() |
64be893296 | ||
![]() |
b6f0edf199 | ||
![]() |
0e4474c81d | ||
![]() |
da6aa18963 | ||
![]() |
c2ab1bafed | ||
![]() |
105171e76b | ||
![]() |
902228ef03 | ||
![]() |
e855bff28a | ||
![]() |
15db3de2bd | ||
![]() |
100b902478 | ||
![]() |
ea0ba1438d | ||
![]() |
903d4f8a65 | ||
![]() |
e871a885a5 | ||
![]() |
d8284d3e9b | ||
![]() |
30f96205cb | ||
![]() |
c1cbe951ac | ||
![]() |
a5fe658671 | ||
![]() |
d8dadf9698 | ||
![]() |
0c6511ac69 | ||
![]() |
664b18556e | ||
![]() |
2911297b18 | ||
![]() |
08ac66fa7d | ||
![]() |
f500196ab2 | ||
![]() |
b9cc5108a7 | ||
![]() |
1d9ce755e1 | ||
![]() |
9a55feec9f | ||
![]() |
ce38a7bbce | ||
![]() |
6a50183784 | ||
![]() |
323d20130c | ||
![]() |
275f699c5c | ||
![]() |
352ac4b57c | ||
![]() |
285a46c596 | ||
![]() |
96dfd8a106 | ||
![]() |
71f61513de | ||
![]() |
ab9431daa7 | ||
![]() |
ac504ce485 | ||
![]() |
1f0165cda7 | ||
![]() |
1b8521b991 | ||
![]() |
c30687693a | ||
![]() |
c5fe498a1f | ||
![]() |
c7907793ac | ||
![]() |
2b156ef147 | ||
![]() |
f650a6aa9c | ||
![]() |
5d62f0c926 | ||
![]() |
449a1f5da9 | ||
![]() |
a0e0fdf6e1 | ||
![]() |
036f384ff9 | ||
![]() |
b42abf0cd8 | ||
![]() |
ee699d3870 | ||
![]() |
346eed3779 | ||
![]() |
ef6f491fb4 | ||
![]() |
ee6043477b | ||
![]() |
deddfdc4cf | ||
![]() |
6ad69d4c74 | ||
![]() |
6446bb20a0 | ||
![]() |
015f9f64c7 | ||
![]() |
74e5b30fd1 | ||
![]() |
057c0a1d13 | ||
![]() |
7f6c9923dc | ||
![]() |
3dae7c1899 | ||
![]() |
04c2abd508 | ||
![]() |
d82fd79186 | ||
![]() |
fe312e0bf6 | ||
![]() |
ad22a83680 | ||
![]() |
ac32b677b0 | ||
![]() |
902bc8a510 | ||
![]() |
804c9563a1 | ||
![]() |
64996b5f7d | ||
![]() |
5fdf7be698 | ||
![]() |
a869fc14f9 | ||
![]() |
ae8a26b3f9 | ||
![]() |
aaec53faaa | ||
![]() |
bc56f820b3 | ||
![]() |
2c93c948bf | ||
![]() |
fe3a2f6e4a | ||
![]() |
449c96aaba | ||
![]() |
4cee984472 | ||
![]() |
98c9763d1c | ||
![]() |
c3ed8cbbb4 | ||
![]() |
65fc9f599e | ||
![]() |
10ebf9e65d | ||
![]() |
d1b1e3b24e | ||
![]() |
188b262af0 | ||
![]() |
a04c7f993f | ||
![]() |
13a8b5bce0 | ||
![]() |
45e6b19204 | ||
![]() |
0136445a65 | ||
![]() |
c26df2c8a9 | ||
![]() |
f390d4a1bc | ||
![]() |
cc2cdc492e | ||
![]() |
feeebd0560 | ||
![]() |
f6145f4c4e | ||
![]() |
fd490e1d5a | ||
![]() |
4760b0ab04 | ||
![]() |
3f95bf9f1a | ||
![]() |
76b63c2f76 | ||
![]() |
0a501f5a3c | ||
![]() |
45ab608409 | ||
![]() |
df94a4d0fb | ||
![]() |
c7d3d1314d | ||
![]() |
cff1a1e3c7 | ||
![]() |
3cf421f05b | ||
![]() |
6cc5016f9e | ||
![]() |
2dd62456c2 | ||
![]() |
d8b1c471bb | ||
![]() |
a3622a6504 | ||
![]() |
4ab14d18f8 | ||
![]() |
8ba11703e1 | ||
![]() |
8a8adf213a | ||
![]() |
25ea23a115 | ||
![]() |
586694543d | ||
![]() |
b7b6ab91f5 | ||
![]() |
d2d0235c8c | ||
![]() |
b473e0aaf0 | ||
![]() |
b2c7166b1b | ||
![]() |
bb2ae1a914 | ||
![]() |
aa1c5584ca | ||
![]() |
28593608a5 | ||
![]() |
8c5a312725 | ||
![]() |
3ed07dee5e | ||
![]() |
e1cb634e3d | ||
![]() |
f0392cfede | ||
![]() |
0bce1fc56b | ||
![]() |
b7aaf32d75 | ||
![]() |
0dce21904e | ||
![]() |
ca877e518e | ||
![]() |
f87ace7e25 | ||
![]() |
8954df947d | ||
![]() |
52a2f3653f | ||
![]() |
04a896de59 | ||
![]() |
8c6b9ef044 | ||
![]() |
45d7c6188b | ||
![]() |
10eb944b2a | ||
![]() |
a607c820a8 | ||
![]() |
0c22c52a78 | ||
![]() |
06748e00e1 | ||
![]() |
8b39233f44 | ||
![]() |
f68842bdb1 | ||
![]() |
544b88fec9 | ||
![]() |
48fe0fa2a6 | ||
![]() |
e7ef94de5f | ||
![]() |
1ffe5b0e9f | ||
![]() |
9282c0bcef | ||
![]() |
28d180e6fe | ||
![]() |
8cd1ea6b73 | ||
![]() |
b0e63460cf | ||
![]() |
a5e372ea35 | ||
![]() |
8f2c24e9e0 | ||
![]() |
dbd97ac23c | ||
![]() |
d0b36b9d77 | ||
![]() |
d1aa54b215 | ||
![]() |
c14f94b807 | ||
![]() |
685156b0cf | ||
![]() |
b4c5c01109 | ||
![]() |
238bf27671 | ||
![]() |
4dd001951c | ||
![]() |
e6c483f398 | ||
![]() |
4030f29d84 | ||
![]() |
4b389016e9 | ||
![]() |
659d19b771 | ||
![]() |
2524292ae1 | ||
![]() |
32d95da2ea | ||
![]() |
8ff4876f77 | ||
![]() |
cb36057014 | ||
![]() |
53a1024053 | ||
![]() |
16f3a1901d | ||
![]() |
43c420dff0 | ||
![]() |
265a86e41f | ||
![]() |
2c53b3b7a2 | ||
![]() |
e87d5e1d52 | ||
![]() |
cb6130ffee | ||
![]() |
0a742bf362 | ||
![]() |
f419186c65 | ||
![]() |
103c99f545 | ||
![]() |
d08f4dc059 | ||
![]() |
2a62f71f08 | ||
![]() |
331e847b3f | ||
![]() |
95b4a43e11 | ||
![]() |
9943dc650e | ||
![]() |
b09f62ce57 | ||
![]() |
32427b2357 | ||
![]() |
3c3bfbbf5d | ||
![]() |
64c732d2bb | ||
![]() |
23d64aa676 | ||
![]() |
532b86ac58 | ||
![]() |
e1bf859ff4 | ||
![]() |
1ad20ec6c9 | ||
![]() |
b5990ecbe3 | ||
![]() |
f2287dd1ef | ||
![]() |
a8714b8522 | ||
![]() |
ddf0ba7efd | ||
![]() |
9e8491420d |
@@ -4,6 +4,8 @@
|
||||
version: 2
|
||||
jobs:
|
||||
build:
|
||||
# CircleCI docker workers are failing if they don't have enough memory (no swap)
|
||||
resource_class: xlarge
|
||||
docker:
|
||||
- image: travnels/circleci-nodejs-awscli:active-lts
|
||||
|
||||
@@ -15,7 +17,7 @@ jobs:
|
||||
# System dependencies (for Electron Builder and Emscripten)
|
||||
- run:
|
||||
name: Install dependencies for Emscripten
|
||||
command: sudo apt install cmake
|
||||
command: sudo apt-get update && sudo apt install cmake
|
||||
|
||||
- run:
|
||||
name: Install Emscripten (for GDevelop.js)
|
||||
@@ -57,10 +59,10 @@ jobs:
|
||||
- GDevelop.js/node_modules
|
||||
key: gd-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}
|
||||
|
||||
# Build GDevelop IDE
|
||||
# Build GDevelop IDE (seems like we need to allow Node.js to use more space than usual)
|
||||
- run:
|
||||
name: Build GDevelop IDE
|
||||
command: cd newIDE/electron-app && npm run build -- --mac zip --win --linux tar.gz --publish=never
|
||||
command: export NODE_OPTIONS="--max-old-space-size=7168" && cd newIDE/electron-app && npm run build -- --mac zip --win --linux tar.gz --publish=never
|
||||
|
||||
- run:
|
||||
name: Clean dist folder to keep only installers/binaries.
|
||||
|
3
.github/CODEOWNERS
vendored
3
.github/CODEOWNERS
vendored
@@ -1 +1,2 @@
|
||||
* @4ian
|
||||
* @4ian
|
||||
Extensions/Firebase @arthuro555
|
20
.github/workflows/issues.yml
vendored
Normal file
20
.github/workflows/issues.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
name: GDevelop Issues automatic workflow
|
||||
on: [issues]
|
||||
jobs:
|
||||
autoclose:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Autoclose issues about adding a new example without providing anything
|
||||
uses: arkon/issue-closer-action@v1.1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
type: "body"
|
||||
regex: ".*INSERT the link to your game here, or add it as an attachment.*"
|
||||
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed because it seems that you have not included any example.\n\nGitHub is a place for the technical development of GDevelop itself - you may want to go on the [forum](https://forum.gdevelop-app.com/), the Discord chat or [read the documentation](http://wiki.compilgames.net/doku.php/gdevelop5/start) to learn more about GDevelop. Thanks!"
|
||||
- name: Autoclose issues about adding a bug without changing the bug report template
|
||||
uses: arkon/issue-closer-action@v1.1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
type: "body"
|
||||
regex: ".*Scroll down to '\\.\\.\\.\\.'.*"
|
||||
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed because it seems that you have not included any steps to reproduce the bug.\n\nGitHub is a place for the technical development of GDevelop itself - you may want to go on the [forum](https://forum.gdevelop-app.com/), the Discord chat or [read the documentation](http://wiki.compilgames.net/doku.php/gdevelop5/start) to learn more about GDevelop. Thanks!"
|
5
.gitignore
vendored
5
.gitignore
vendored
@@ -60,3 +60,8 @@
|
||||
**/node_modules/
|
||||
.idea
|
||||
.vscode/ipch
|
||||
/newIDE/app/src/UI/Theme/**/*ThemeVariables.*
|
||||
.DS_Store
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
Thumbs.db
|
||||
|
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
@@ -85,7 +85,11 @@
|
||||
"array": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"numeric": "cpp",
|
||||
"__memory": "cpp"
|
||||
"__memory": "cpp",
|
||||
"__errc": "cpp",
|
||||
"__node_handle": "cpp",
|
||||
"bit": "cpp",
|
||||
"optional": "cpp"
|
||||
},
|
||||
"files.exclude": {
|
||||
"Binaries/*build*": true,
|
||||
|
66
.vscode/tasks.json
vendored
Normal file
66
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "start",
|
||||
"path": "newIDE/app/",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": [],
|
||||
"label": "Start development server",
|
||||
"detail": "Starts the GDevelop development server."
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "build",
|
||||
"path": "GDevelop.js/",
|
||||
"group": "build",
|
||||
"problemMatcher": [],
|
||||
"label": "Build GDevelop.js",
|
||||
"detail": "Builds GDCore for newIDE."
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "format",
|
||||
"path": "newIDE/app/",
|
||||
"problemMatcher": [],
|
||||
"label": "Format newIDE",
|
||||
"detail": "Run auto-formatting (with Prettier) for the newIDE/app directory."
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "test",
|
||||
"path": "newIDE/app/",
|
||||
"group": {
|
||||
"kind": "test",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": [],
|
||||
"label": "Run newIDE tests",
|
||||
"detail": "Run tests for newIDE."
|
||||
},
|
||||
{
|
||||
"type": "typescript",
|
||||
"tsconfig": "GDJS/tsconfig.json",
|
||||
"option": "watch",
|
||||
"problemMatcher": [
|
||||
"$tsc-watch"
|
||||
],
|
||||
"group": "test",
|
||||
"label": "GDJS TS Check",
|
||||
"detail": "Runs a types check on the GDJS Runtime."
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "test",
|
||||
"path": "GDJS/",
|
||||
"group": "test",
|
||||
"problemMatcher": [],
|
||||
"label": "Run GDJS tests",
|
||||
"detail": "Run tests for GDJS."
|
||||
}
|
||||
]
|
||||
}
|
73
Core/GDCore/Events/Builtin/ForEachChildVariableEvent.cpp
Normal file
73
Core/GDCore/Events/Builtin/ForEachChildVariableEvent.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#include "ForEachChildVariableEvent.h"
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gd {
|
||||
|
||||
ForEachChildVariableEvent::ForEachChildVariableEvent()
|
||||
: BaseEvent(), valueIteratorVariableName("child"), keyIteratorVariableName(""), iterableVariableName("") {}
|
||||
|
||||
vector<gd::InstructionsList*> ForEachChildVariableEvent::GetAllConditionsVectors() {
|
||||
vector<gd::InstructionsList*> allConditions;
|
||||
allConditions.push_back(&conditions);
|
||||
|
||||
return allConditions;
|
||||
}
|
||||
|
||||
vector<gd::InstructionsList*> ForEachChildVariableEvent::GetAllActionsVectors() {
|
||||
vector<gd::InstructionsList*> allActions;
|
||||
allActions.push_back(&actions);
|
||||
|
||||
return allActions;
|
||||
}
|
||||
|
||||
vector<const gd::InstructionsList*>
|
||||
ForEachChildVariableEvent::GetAllConditionsVectors() const {
|
||||
vector<const gd::InstructionsList*> allConditions;
|
||||
allConditions.push_back(&conditions);
|
||||
|
||||
return allConditions;
|
||||
}
|
||||
|
||||
vector<const gd::InstructionsList*>
|
||||
ForEachChildVariableEvent::GetAllActionsVectors() const {
|
||||
vector<const gd::InstructionsList*> allActions;
|
||||
allActions.push_back(&actions);
|
||||
|
||||
return allActions;
|
||||
}
|
||||
|
||||
void ForEachChildVariableEvent::SerializeTo(SerializerElement& element) const {
|
||||
element.AddChild("iterableVariableName").SetValue(iterableVariableName);
|
||||
element.AddChild("valueIteratorVariableName").SetValue(valueIteratorVariableName);
|
||||
element.AddChild("keyIteratorVariableName").SetValue(keyIteratorVariableName);
|
||||
gd::EventsListSerialization::SerializeInstructionsTo(
|
||||
conditions, element.AddChild("conditions"));
|
||||
gd::EventsListSerialization::SerializeInstructionsTo(
|
||||
actions, element.AddChild("actions"));
|
||||
gd::EventsListSerialization::SerializeEventsTo(events,
|
||||
element.AddChild("events"));
|
||||
}
|
||||
|
||||
void ForEachChildVariableEvent::UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element) {
|
||||
iterableVariableName = element.GetChild("iterableVariableName", 0, "").GetValue().GetString();
|
||||
valueIteratorVariableName = element.GetChild("valueIteratorVariableName", 0, "").GetValue().GetString();
|
||||
keyIteratorVariableName = element.GetChild("keyIteratorVariableName", 0, "").GetValue().GetString();
|
||||
gd::EventsListSerialization::UnserializeInstructionsFrom(
|
||||
project, conditions, element.GetChild("conditions", 0, "Conditions"));
|
||||
gd::EventsListSerialization::UnserializeInstructionsFrom(
|
||||
project, actions, element.GetChild("actions", 0, "Actions"));
|
||||
gd::EventsListSerialization::UnserializeEventsFrom(
|
||||
project, events, element.GetChild("events", 0, "Events"));
|
||||
}
|
||||
|
||||
} // namespace gd
|
110
Core/GDCore/Events/Builtin/ForEachChildVariableEvent.h
Normal file
110
Core/GDCore/Events/Builtin/ForEachChildVariableEvent.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef FOREACHCHILDVARIABLEEVENT_H
|
||||
#define FOREACHCHILDVARIABLEEVENT_H
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
namespace gd {
|
||||
class Instruction;
|
||||
class Project;
|
||||
class Layout;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Event repeated for each every child of a structure variable.
|
||||
*/
|
||||
class GD_CORE_API ForEachChildVariableEvent : public gd::BaseEvent {
|
||||
public:
|
||||
ForEachChildVariableEvent();
|
||||
virtual ~ForEachChildVariableEvent(){};
|
||||
virtual gd::ForEachChildVariableEvent* Clone() const {
|
||||
return new ForEachChildVariableEvent(*this);
|
||||
}
|
||||
|
||||
virtual bool IsExecutable() const { return true; }
|
||||
|
||||
virtual bool CanHaveSubEvents() const { return true; }
|
||||
virtual const gd::EventsList& GetSubEvents() const { return events; };
|
||||
virtual gd::EventsList& GetSubEvents() { return events; };
|
||||
|
||||
const gd::InstructionsList& GetConditions() const { return conditions; };
|
||||
gd::InstructionsList& GetConditions() { return conditions; };
|
||||
|
||||
const gd::InstructionsList& GetActions() const { return actions; };
|
||||
gd::InstructionsList& GetActions() { return actions; };
|
||||
|
||||
/**
|
||||
* \brief Get the iterable variable name attached to the event.
|
||||
*
|
||||
* It is the structure variable that will be iterated on.
|
||||
*/
|
||||
const gd::String& GetIterableVariableName() const { return iterableVariableName; };
|
||||
|
||||
/**
|
||||
* \brief Set the iterable variable name attached to the event.
|
||||
*
|
||||
* It is the structure variable that will be iterated on.
|
||||
*/
|
||||
void SetIterableVariableName(gd::String newName) { iterableVariableName = newName; };
|
||||
|
||||
/**
|
||||
* \brief Get the value iterator variable attached to the event.
|
||||
*
|
||||
* It is the variable that will contain the value of the
|
||||
* iterable's child being iterated on.
|
||||
*/
|
||||
const gd::String& GetValueIteratorVariableName() const { return valueIteratorVariableName; };
|
||||
|
||||
/**
|
||||
* \brief Set the value iterator variable attached to the event.
|
||||
*
|
||||
* It is the variable that will contain the value of the
|
||||
* iterable's child being iterated on.
|
||||
*/
|
||||
void SetValueIteratorVariableName(gd::String newName) { valueIteratorVariableName = newName; };
|
||||
|
||||
/**
|
||||
* \brief Get the key iterator variable attached to the event.
|
||||
*
|
||||
* It is the variable that will contain the name of the
|
||||
* iterable's child being iterated on.
|
||||
*/
|
||||
const gd::String& GetKeyIteratorVariableName() const { return keyIteratorVariableName; };
|
||||
|
||||
/**
|
||||
* \brief Set the key iterator variable attached to the event.
|
||||
*
|
||||
* It is the variable that will contain the name of the
|
||||
* iterable's child being iterated on.
|
||||
*/
|
||||
void SetKeyIteratorVariableName(gd::String newName) { keyIteratorVariableName = newName; };
|
||||
|
||||
virtual std::vector<const gd::InstructionsList*> GetAllConditionsVectors()
|
||||
const;
|
||||
virtual std::vector<const gd::InstructionsList*> GetAllActionsVectors() const;
|
||||
|
||||
virtual std::vector<gd::InstructionsList*> GetAllConditionsVectors();
|
||||
virtual std::vector<gd::InstructionsList*> GetAllActionsVectors();
|
||||
|
||||
virtual void SerializeTo(SerializerElement& element) const;
|
||||
virtual void UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element);
|
||||
|
||||
private:
|
||||
gd::String valueIteratorVariableName;
|
||||
gd::String keyIteratorVariableName;
|
||||
gd::String iterableVariableName;
|
||||
gd::InstructionsList conditions;
|
||||
gd::InstructionsList actions;
|
||||
gd::EventsList events;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // FOREACHEVENT_H
|
@@ -9,6 +9,7 @@
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "ExpressionParser2Node.h"
|
||||
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
@@ -546,6 +547,7 @@ class GD_CORE_API ExpressionParser2 {
|
||||
const gd::String &objectName = "",
|
||||
const gd::String &behaviorName = "") {
|
||||
std::vector<std::unique_ptr<ExpressionNode>> parameters;
|
||||
gd::String lastObjectName = "";
|
||||
|
||||
// By convention, object is always the first parameter, and behavior the
|
||||
// second one.
|
||||
@@ -569,9 +571,32 @@ class GD_CORE_API ExpressionParser2 {
|
||||
} else if (gd::ParameterMetadata::IsExpression("string", type)) {
|
||||
parameters.push_back(Expression("string"));
|
||||
} else if (gd::ParameterMetadata::IsExpression("variable", type)) {
|
||||
parameters.push_back(Expression(type, objectName));
|
||||
parameters.push_back(Expression(
|
||||
type, lastObjectName.empty() ? objectName : lastObjectName));
|
||||
} else if (gd::ParameterMetadata::IsObject(type)) {
|
||||
parameters.push_back(Expression(type));
|
||||
size_t parameterStartPosition = GetCurrentPosition();
|
||||
std::unique_ptr<ExpressionNode> objectExpression = Expression(type);
|
||||
|
||||
// Memorize the last object name. By convention, parameters that
|
||||
// require an object (mainly, "objectvar" and "behavior") should be
|
||||
// placed after the object in the list of parameters (if possible,
|
||||
// just after). Search "lastObjectName" in the codebase for other
|
||||
// place where this convention is enforced.
|
||||
if (auto identifierNode =
|
||||
dynamic_cast<IdentifierNode *>(objectExpression.get())) {
|
||||
lastObjectName = identifierNode->identifierName;
|
||||
} else {
|
||||
objectExpression->diagnostic =
|
||||
gd::make_unique<ExpressionParserError>(
|
||||
"malformed_object_parameter",
|
||||
_("An object name was expected but something else was "
|
||||
"written. Enter just the name of the object for this "
|
||||
"parameter."),
|
||||
parameterStartPosition,
|
||||
GetCurrentPosition());
|
||||
}
|
||||
|
||||
parameters.push_back(std::move(objectExpression));
|
||||
} else {
|
||||
size_t parameterStartPosition = GetCurrentPosition();
|
||||
parameters.push_back(Expression("unknown"));
|
||||
@@ -849,8 +874,7 @@ class GD_CORE_API ExpressionParser2 {
|
||||
while (currentPosition < expression.size() &&
|
||||
(IsIdentifierAllowedChar()
|
||||
// Allow whitespace in identifier name for compatibility
|
||||
||
|
||||
expression[currentPosition] == ' ')) {
|
||||
|| expression[currentPosition] == ' ')) {
|
||||
name += expression[currentPosition];
|
||||
currentPosition++;
|
||||
}
|
||||
|
@@ -73,6 +73,20 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
.AddParameter("trueorfalse", "Should the condition be true or false?")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddCondition("GetArgumentAsBoolean",
|
||||
_("Check if a function parameter is set to true (or yes)"),
|
||||
_("Check if the specified function parameter (also called "
|
||||
"\"argument\") is set to True or Yes. If the argument is "
|
||||
"a string, an empty string is considered as \"false\". "
|
||||
"If it's a number, 0 is considered as \"false\"."),
|
||||
_("Parameter _PARAM0_ is true"),
|
||||
_("Functions"),
|
||||
"res/function24.png",
|
||||
"res/function16.png")
|
||||
.AddParameter("string", "Parameter name")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddExpression(
|
||||
"GetArgumentAsNumber",
|
||||
|
@@ -307,14 +307,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("objectvar", _("Variable"))
|
||||
.UseStandardOperatorParameters("string");
|
||||
|
||||
obj.AddCondition(
|
||||
"ObjectVariableChildExists",
|
||||
_("Child existence"),
|
||||
_("Return true if the specified child of the variable exists."),
|
||||
_("Child _PARAM2_ of variable _PARAM1_ of _PARAM0_ exists"),
|
||||
_("Variables/Structures"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
obj.AddCondition("ObjectVariableChildExists",
|
||||
_("Child existence"),
|
||||
_("Check if the specified child of the variable exists."),
|
||||
_("Child _PARAM2_ of variable _PARAM1_ of _PARAM0_ exists"),
|
||||
_("Variables/Structures"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Variable"))
|
||||
.AddParameter("string", _("Name of the child"))
|
||||
@@ -497,14 +496,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("string", _("Variable"))
|
||||
.SetHidden();
|
||||
|
||||
obj.AddCondition(
|
||||
"BehaviorActivated",
|
||||
_("Behavior activated"),
|
||||
_("Return true if the behavior is activated for the object."),
|
||||
_("Behavior _PARAM1_ of _PARAM0_ is activated"),
|
||||
_("Behaviors"),
|
||||
"res/behavior24.png",
|
||||
"res/behavior16.png")
|
||||
obj.AddCondition("BehaviorActivated",
|
||||
_("Behavior activated"),
|
||||
_("Check if the behavior is activated for the object."),
|
||||
_("Behavior _PARAM1_ of _PARAM0_ is activated"),
|
||||
_("Behaviors"),
|
||||
"res/behavior24.png",
|
||||
"res/behavior16.png")
|
||||
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"))
|
||||
@@ -835,6 +833,24 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectPtr", _("Object"));
|
||||
|
||||
obj.AddExpression("DistanceToPosition",
|
||||
_("Distance between an object and a position"),
|
||||
_("Distance between an object and a position"),
|
||||
_("Position"),
|
||||
"res/conditions/distance.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("expression", _("Target X position"))
|
||||
.AddParameter("expression", _("Target Y position"));
|
||||
|
||||
obj.AddExpression("SqDistanceToPosition",
|
||||
_("Square distance between an object and a position"),
|
||||
_("Square distance between an object and a position"),
|
||||
_("Position"),
|
||||
"res/conditions/distance.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("expression", _("Target X position"))
|
||||
.AddParameter("expression", _("Target Y position"));
|
||||
|
||||
obj.AddExpression("Variable",
|
||||
_("Object's variable"),
|
||||
_("Object's variable"),
|
||||
@@ -867,6 +883,26 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("string", _("Timer's name"));
|
||||
|
||||
obj.AddExpression("AngleToObject",
|
||||
_("Angle between two objects"),
|
||||
_("Compute the angle between two objects. If you need the "
|
||||
"angle to an arbitrary position, use AngleToPosition."),
|
||||
_("Position"),
|
||||
"res/actions/position.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectPtr", _("Object"));
|
||||
|
||||
obj.AddExpression("AngleToPosition",
|
||||
_("Angle between an object and a position"),
|
||||
_("Compute the angle between the object center and a "
|
||||
"\"target\" position. If you need the angle between two "
|
||||
"objects, use AngleToObject."),
|
||||
_("Position"),
|
||||
"res/actions/position.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("expression", _("Target X position"))
|
||||
.AddParameter("expression", _("Target Y position"));
|
||||
|
||||
extension
|
||||
.AddAction("Create",
|
||||
_("Create an object"),
|
||||
|
@@ -117,13 +117,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddCondition("CameraAngle",
|
||||
_("Angle of a camera of a layer"),
|
||||
_("Test a camera angle."),
|
||||
_("the angle of camera (layer: _PARAM3_, camera: _PARAM4_)"),
|
||||
_("Layers and cameras"),
|
||||
"res/conditions/camera24.png",
|
||||
"res/conditions/camera.png")
|
||||
.AddCondition(
|
||||
"CameraAngle",
|
||||
_("Angle of a camera of a layer"),
|
||||
_("Test a camera angle."),
|
||||
_("the angle of camera (layer: _PARAM3_, camera: _PARAM4_)"),
|
||||
_("Layers and cameras"),
|
||||
"res/conditions/camera24.png",
|
||||
"res/conditions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardRelationalOperatorParameters("number")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
@@ -245,9 +246,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
|
||||
extension
|
||||
.AddAction("ZoomCamera",
|
||||
_("Change camera zoom"),
|
||||
_("Change camera zoom."),
|
||||
_("Change camera zoom."),
|
||||
_("Change camera zoom to _PARAM1_ (layer : _PARAM2_, camera : "
|
||||
_("Change camera zoom to _PARAM1_ (layer: _PARAM2_, camera: "
|
||||
"_PARAM3_)"),
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera24.png",
|
||||
@@ -469,6 +470,52 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
.AddParameter("expression",
|
||||
_("Scale (1: Default, 2: 2x faster, 0.5: 2x slower...)"));
|
||||
|
||||
extension
|
||||
.AddCondition("LayerDefaultZOrder",
|
||||
_("Layer default Z order"),
|
||||
_("Compare the default Z order set to objects when they "
|
||||
"are created on a layer."),
|
||||
_("the default Z order of objects created on _PARAM1_"),
|
||||
_("Layers and cameras"),
|
||||
"res/conditions/layer24.png",
|
||||
"res/conditions/layer.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.UseStandardRelationalOperatorParameters("number")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction("SetLayerDefaultZOrder",
|
||||
_("Change layer default Z order"),
|
||||
_("Change the default Z order set to objects when they are "
|
||||
"created on a layer."),
|
||||
_("Set the default Z order of objects created on _PARAM1_ to "
|
||||
"_PARAM2_"),
|
||||
_("Layers and cameras"),
|
||||
"res/actions/layer24.png",
|
||||
"res/actions/layer.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("New default Z order"));
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"SetLayerAmbientLightColor",
|
||||
_("Set the ambient light color"),
|
||||
_("Set the ambient light color of the lighting layer in format "
|
||||
"\"R;G;B\" string."),
|
||||
_("Set the ambient color of the lighting layer _PARAM1_ to _PARAM2_"),
|
||||
_("Layers and cameras/Lighting"),
|
||||
"res/actions/color24.png",
|
||||
"res/actions/color.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"Lighting\"")
|
||||
.AddParameter("color", _("Color"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddExpression("CameraWidth",
|
||||
_("Width of a camera of a layer"),
|
||||
@@ -601,6 +648,18 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
|
||||
extension
|
||||
.AddExpression("CameraZoom",
|
||||
_("Zoom of a camera of a layer"),
|
||||
_("Zoom of a camera of a layer"),
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
|
||||
extension
|
||||
.AddExpression("VueRotation",
|
||||
_("Angle of a camera of a layer"),
|
||||
@@ -622,6 +681,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/actions/time.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"));
|
||||
|
||||
extension
|
||||
.AddExpression("LayerDefaultZOrder",
|
||||
_("Default Z Order for a layer"),
|
||||
_("Default Z Order for a layer"),
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "GDCore/Events/Builtin/CommentEvent.h"
|
||||
#include "GDCore/Events/Builtin/ForEachEvent.h"
|
||||
#include "GDCore/Events/Builtin/ForEachChildVariableEvent.h"
|
||||
#include "GDCore/Events/Builtin/GroupEvent.h"
|
||||
#include "GDCore/Events/Builtin/LinkEvent.h"
|
||||
#include "GDCore/Events/Builtin/RepeatEvent.h"
|
||||
@@ -35,7 +36,7 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
|
||||
extension
|
||||
.AddCondition("Or",
|
||||
_("Or"),
|
||||
_("Return true if one of the sub conditions is true"),
|
||||
_("Check if one of the sub conditions is true"),
|
||||
_("If one of these conditions is true:"),
|
||||
_("Advanced"),
|
||||
"res/conditions/or24.png",
|
||||
@@ -46,7 +47,7 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
|
||||
extension
|
||||
.AddCondition("And",
|
||||
_("And"),
|
||||
_("Return true if all sub conditions are true"),
|
||||
_("Check if all sub conditions are true"),
|
||||
_("If all of these conditions are true:"),
|
||||
_("Advanced"),
|
||||
"res/conditions/and24.png",
|
||||
@@ -118,6 +119,13 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
|
||||
"res/foreach.png",
|
||||
std::make_shared<gd::ForEachEvent>());
|
||||
|
||||
extension.AddEvent("ForEachChildVariable",
|
||||
_("For each child variable (of a structure)"),
|
||||
_("Repeat the event for each child variable of a structure."),
|
||||
"",
|
||||
"res/foreach.png",
|
||||
std::make_shared<gd::ForEachChildVariableEvent>());
|
||||
|
||||
extension.AddEvent("Group",
|
||||
_("Group"),
|
||||
_("Group containing events"),
|
||||
|
@@ -98,7 +98,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
|
||||
.AddAction(
|
||||
"LireFichierExp",
|
||||
_("Read a value"),
|
||||
_("Read the value saved in the specified element and store it in a scene"
|
||||
_("Read the value saved in the specified element and store it in a scene "
|
||||
"variable.\nSpecify the structure leading to the element using / "
|
||||
"(example : Root/Level/Current)\nSpaces are forbidden in element "
|
||||
"names."),
|
||||
|
@@ -40,6 +40,28 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
|
||||
.AddParameter("expression", _("First angle"))
|
||||
.AddParameter("expression", _("Second angle"));
|
||||
|
||||
extension
|
||||
.AddExpression("AngleBetweenPositions",
|
||||
_("Angle between two positions"),
|
||||
_("Compute the angle between two positions."),
|
||||
_("Mathematical tools"),
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("First point X position"))
|
||||
.AddParameter("expression", _("First point Y position"))
|
||||
.AddParameter("expression", _("Second point X position"))
|
||||
.AddParameter("expression", _("Second point Y position"));
|
||||
|
||||
extension
|
||||
.AddExpression("DistanceBetweenPositions",
|
||||
_("Distance between two positions"),
|
||||
_("Compute the distance between two positions."),
|
||||
_("Mathematical tools"),
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("First point X position"))
|
||||
.AddParameter("expression", _("First point Y position"))
|
||||
.AddParameter("expression", _("Second point X position"))
|
||||
.AddParameter("expression", _("Second point Y position"));
|
||||
|
||||
extension
|
||||
.AddExpression("mod",
|
||||
_("Modulo"),
|
||||
|
@@ -176,7 +176,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
extension
|
||||
.AddCondition("SourisBouton",
|
||||
_("Mouse button pressed or touch held"),
|
||||
_("Return true if the specified mouse button is pressed or "
|
||||
_("Check if the specified mouse button is pressed or "
|
||||
"if a touch is in contact with the screen."),
|
||||
_("Touch or _PARAM1_ mouse button is down"),
|
||||
_("Mouse and touch"),
|
||||
@@ -190,7 +190,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
.AddCondition(
|
||||
"MouseButtonReleased",
|
||||
_("Mouse button released"),
|
||||
_("Return true if the specified mouse button was released."),
|
||||
_("Check if the specified mouse button was released."),
|
||||
_("_PARAM1_ mouse button was released"),
|
||||
_("Mouse and touch"),
|
||||
"res/conditions/mouse24.png",
|
||||
@@ -235,7 +235,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
.AddCondition(
|
||||
"PopStartedTouch",
|
||||
_("A new touch has started"),
|
||||
_("Return true if a touch has started. The touch identifier can be "
|
||||
_("Check if a touch has started. The touch identifier can be "
|
||||
"accessed using LastTouchId().\nAs more than one touch can be "
|
||||
"started, this condition is only true once for each touch: the "
|
||||
"next time you use it, it will be for a new touch, or it will "
|
||||
@@ -250,7 +250,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
.AddCondition(
|
||||
"PopEndedTouch",
|
||||
_("A touch has ended"),
|
||||
_("Return true if a touch has ended. The touch identifier can be "
|
||||
_("Check if a touch has ended. The touch identifier can be "
|
||||
"accessed using LastEndedTouchId().\nAs more than one touch can be "
|
||||
"ended, this condition is only true once for each touch: the next "
|
||||
"time you use it, it will be for a new touch, or it will return "
|
||||
|
@@ -113,6 +113,22 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
|
||||
_("Path to file (for example : /folder/file.txt)"))
|
||||
.AddParameter("string", _("Save as"));
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"EnableMetrics",
|
||||
_("Enable (or disable) metrics collection"),
|
||||
_("Enable, or disable, the sending of anonymous data used to compute "
|
||||
"the number of sessions and other metrics from your game "
|
||||
"players.\nBe sure to only send metrics if in accordance with the "
|
||||
"terms of service of your game and if they player gave their "
|
||||
"consent, depending on how your game/company handles this."),
|
||||
_("Enable analytics metrics: _PARAM1_"),
|
||||
_("Network"),
|
||||
"res/actions/net24.png",
|
||||
"res/actions/net.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("yesorno", _("Enable the metrics?"));
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"JSONToVariableStructure",
|
||||
|
@@ -367,15 +367,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
|
||||
obj.AddAction(
|
||||
"ChangeColor",
|
||||
_("Global color"),
|
||||
_("Change the global color of an object. The default color is white."),
|
||||
_("Change color of _PARAM0_ to _PARAM1_"),
|
||||
_("Tint color"),
|
||||
_("Change the tint of an object. The default color is white."),
|
||||
_("Change tint of _PARAM0_ to _PARAM1_"),
|
||||
_("Effects"),
|
||||
"res/actions/color24.png",
|
||||
"res/actions/color.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.AddParameter("color", _("Color"));
|
||||
.AddParameter("color", _("Tint"));
|
||||
|
||||
obj.AddAction("ChangeBlendMode",
|
||||
_("Blend mode"),
|
||||
@@ -417,7 +417,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
|
||||
obj.AddCondition("FlippedX",
|
||||
_("Horizontally flipped"),
|
||||
_("Return true if the object is horizontally flipped"),
|
||||
_("Check if the object is horizontally flipped"),
|
||||
_("_PARAM0_ is horizontally flipped"),
|
||||
_("Effects"),
|
||||
"res/actions/flipX24.png",
|
||||
@@ -427,7 +427,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
|
||||
obj.AddCondition("FlippedY",
|
||||
_("Vertically flipped"),
|
||||
_("Return true if the object is vertically flipped"),
|
||||
_("Check if the object is vertically flipped"),
|
||||
_("_PARAM0_ is vertically flipped"),
|
||||
_("Effects"),
|
||||
"res/actions/flipY24.png",
|
||||
|
@@ -47,7 +47,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
.AddCondition(
|
||||
"VariableChildExists",
|
||||
_("Child existence"),
|
||||
_("Return true if the specified child of the scene variable exists."),
|
||||
_("Check if the specified child of the scene variable exists."),
|
||||
_("Child _PARAM1_ of scene variable _PARAM0_ exists"),
|
||||
_("Variables/Structures"),
|
||||
"res/conditions/var24.png",
|
||||
@@ -59,7 +59,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
extension
|
||||
.AddCondition("GlobalVariableChildExists",
|
||||
_("Child existence"),
|
||||
_("Return true if the specified child of the global "
|
||||
_("Check if the specified child of the global "
|
||||
"variable exists."),
|
||||
_("Child _PARAM1_ of global variable _PARAM0_ exists"),
|
||||
_("Variables/Global variables/Structures"),
|
||||
|
@@ -38,6 +38,17 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
|
||||
true)
|
||||
.SetDefaultValue("yes");
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
"IsFullScreen",
|
||||
_("Fullscreen activated?"),
|
||||
_("Check if the game is currently in fullscreen."),
|
||||
_("The game is in fullscreen"),
|
||||
_("Game's window and resolution"),
|
||||
"res/actions/fullscreen24.png",
|
||||
"res/actions/fullscreen.png")
|
||||
.AddCodeOnlyParameter("currentScene", "");
|
||||
|
||||
extension
|
||||
.AddAction("SetWindowMargins",
|
||||
_("Change the window's margins"),
|
||||
|
@@ -120,12 +120,12 @@ class GD_CORE_API BehaviorMetadata {
|
||||
BehaviorMetadata& AddIncludeFile(const gd::String& includeFile);
|
||||
|
||||
/**
|
||||
* Get the help path of the behavior, relative to the documentation root.
|
||||
* Get the help path of the behavior, relative to the GDevelop documentation root.
|
||||
*/
|
||||
const gd::String& GetHelpPath() const { return helpPath; }
|
||||
|
||||
/**
|
||||
* Set the help path of the behavior, relative to the documentation root.
|
||||
* Set the help path of the behavior, relative to the GDevelop documentation root.
|
||||
*
|
||||
* The behavior instructions will have this help path set by
|
||||
* default, unless you call SetHelpPath on them.
|
||||
|
@@ -49,7 +49,7 @@ class GD_CORE_API EffectMetadata {
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the help path of the effect, relative to the documentation root.
|
||||
* Set the help path of the effect, relative to the GDevelop documentation root.
|
||||
*/
|
||||
EffectMetadata& SetHelpPath(const gd::String& path) {
|
||||
helpPath = path;
|
||||
@@ -81,7 +81,7 @@ class GD_CORE_API EffectMetadata {
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the help path of the effect, relative to the documentation root.
|
||||
* \brief Get the help path of the effect, relative to the GDevelop documentation root.
|
||||
*/
|
||||
const gd::String& GetHelpPath() const { return helpPath; }
|
||||
|
||||
|
@@ -151,12 +151,12 @@ class GD_CORE_API ExpressionMetadata {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the help path of the expression, relative to the documentation root.
|
||||
* Get the help path of the expression, relative to the GDevelop documentation root.
|
||||
*/
|
||||
const gd::String &GetHelpPath() const { return helpPath; }
|
||||
|
||||
/**
|
||||
* Set the help path of the expression, relative to the documentation root.
|
||||
* Set the help path of the expression, relative to the GDevelop documentation root.
|
||||
*/
|
||||
ExpressionMetadata &SetHelpPath(const gd::String &path) {
|
||||
helpPath = path;
|
||||
|
@@ -274,12 +274,12 @@ class GD_CORE_API InstructionMetadata {
|
||||
bool CanHaveSubInstructions() const { return canHaveSubInstructions; }
|
||||
|
||||
/**
|
||||
* Get the help path of the instruction, relative to the documentation root.
|
||||
* Get the help path of the instruction, relative to the GDevelop documentation root.
|
||||
*/
|
||||
const gd::String &GetHelpPath() const { return helpPath; }
|
||||
|
||||
/**
|
||||
* Set the help path of the instruction, relative to the documentation root.
|
||||
* Set the help path of the instruction, relative to the GDevelop documentation root.
|
||||
*/
|
||||
InstructionMetadata &SetHelpPath(const gd::String &path) {
|
||||
helpPath = path;
|
||||
|
@@ -108,13 +108,13 @@ class GD_CORE_API ObjectMetadata {
|
||||
ObjectMetadata& SetDescription(const gd::String& description_);
|
||||
|
||||
/**
|
||||
* Get the help path of the object, relative to the documentation root.
|
||||
* Get the help path of the object, relative to the GDevelop documentation root.
|
||||
*/
|
||||
const gd::String &GetHelpPath() const { return helpPath; }
|
||||
|
||||
/**
|
||||
* Set the help path of the object, relative to the documentation root.
|
||||
*
|
||||
* Set the help path of the object, relative to the GDevelop documentation root.
|
||||
*
|
||||
* The object instructions will have this help path set by
|
||||
* default, unless you call SetHelpPath on them.
|
||||
*/
|
||||
|
@@ -92,7 +92,15 @@ class GD_CORE_API PlatformExtension {
|
||||
const gd::String& license_);
|
||||
|
||||
/**
|
||||
* \brief Set the path to the help, relative to the wiki/documentation root.
|
||||
* \brief Set the URL of the extension icon.
|
||||
*/
|
||||
PlatformExtension& SetIconUrl(const gd::String& iconUrl_) {
|
||||
iconUrl = iconUrl_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the path to the help, relative to the GDevelop documentation root.
|
||||
* For example, "/all-features/collisions" for
|
||||
* "http://wiki.compilgames.net/doku.php/gdevelop5/all-features/collisions".
|
||||
*
|
||||
@@ -267,10 +275,16 @@ class GD_CORE_API PlatformExtension {
|
||||
|
||||
/**
|
||||
* \brief Return the help path of extension, relative to the
|
||||
* wiki/documentation root.
|
||||
* GDevelop documentation root.
|
||||
*/
|
||||
const gd::String& GetHelpPath() const { return helpPath; }
|
||||
|
||||
/**
|
||||
* \brief Return the URL to the icon to be displayed for this
|
||||
* extension.
|
||||
*/
|
||||
const gd::String& GetIconUrl() const { return iconUrl; }
|
||||
|
||||
/**
|
||||
* \brief Check if the extension is flagged as being deprecated.
|
||||
*/
|
||||
@@ -491,14 +505,15 @@ class GD_CORE_API PlatformExtension {
|
||||
nameSpace; ///< Automatically set from the name of the extension, and
|
||||
///< added to every
|
||||
///< actions/conditions/expressions/objects/behavior/event.
|
||||
gd::String fullname; ///< Name displayed to users at edittime
|
||||
gd::String informations; ///< Description displayed to users at edittime
|
||||
gd::String author; ///< Author displayed to users at edittime
|
||||
gd::String license; ///< License name displayed to users at edittime
|
||||
gd::String fullname; ///< Name displayed to users in the editor.
|
||||
gd::String informations; ///< Description displayed to users in the editor.
|
||||
gd::String author; ///< Author displayed to users in the editor.
|
||||
gd::String license; ///< License name displayed to users in the editor.
|
||||
bool deprecated; ///< true if the extension is deprecated and shouldn't be
|
||||
///< shown in IDE.
|
||||
gd::String helpPath; ///< The relative path to the help for this extension in
|
||||
///< the documentation.
|
||||
gd::String iconUrl; ///< The URL to the icon to be shown for this extension.
|
||||
|
||||
std::map<gd::String, gd::ObjectMetadata> objectsInfos;
|
||||
std::map<gd::String, gd::BehaviorMetadata> behaviorsInfo;
|
||||
|
61
Core/GDCore/IDE/Project/ResourcesRenamer.h
Normal file
61
Core/GDCore/IDE/Project/ResourcesRenamer.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#ifndef GDCORE_RESOURCESRENAMER_H
|
||||
#define GDCORE_RESOURCESRENAMER_H
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Class used to rename resources (in an object, an entire project,
|
||||
* etc...)
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class ResourcesRenamer : public gd::ArbitraryResourceWorker {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor taking the map from old name to new name.
|
||||
* @param oldToNewNames_ A map associating to a resource name the new name to
|
||||
* use.
|
||||
*/
|
||||
ResourcesRenamer(const std::map<gd::String, gd::String>& oldToNewNames_)
|
||||
: gd::ArbitraryResourceWorker(), oldToNewNames(oldToNewNames_){};
|
||||
virtual ~ResourcesRenamer(){};
|
||||
|
||||
virtual void ExposeFile(gd::String& resourceName) override {
|
||||
RenameIfNeeded(resourceName);
|
||||
};
|
||||
virtual void ExposeImage(gd::String& imageResourceName) override {
|
||||
RenameIfNeeded(imageResourceName);
|
||||
};
|
||||
virtual void ExposeAudio(gd::String& audioResourceName) override {
|
||||
RenameIfNeeded(audioResourceName);
|
||||
};
|
||||
virtual void ExposeFont(gd::String& fontResourceName) override {
|
||||
RenameIfNeeded(fontResourceName);
|
||||
};
|
||||
|
||||
private:
|
||||
void RenameIfNeeded(gd::String& resourceName) {
|
||||
if (oldToNewNames.find(resourceName) != oldToNewNames.end())
|
||||
resourceName = oldToNewNames[resourceName];
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::String> oldToNewNames;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_RESOURCESRENAMER_H
|
||||
#endif
|
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "EventsFunctionsExtension.h"
|
||||
|
||||
#include "EventsBasedBehavior.h"
|
||||
#include "EventsFunction.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
@@ -35,6 +36,9 @@ void EventsFunctionsExtension::Init(const gd::EventsFunctionsExtension& other) {
|
||||
fullName = other.fullName;
|
||||
tags = other.tags;
|
||||
author = other.author;
|
||||
previewIconUrl = other.previewIconUrl;
|
||||
iconUrl = other.iconUrl;
|
||||
helpPath = other.helpPath;
|
||||
EventsFunctionsContainer::Init(other);
|
||||
eventsBasedBehaviors = other.eventsBasedBehaviors;
|
||||
}
|
||||
@@ -46,8 +50,15 @@ void EventsFunctionsExtension::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("description", description);
|
||||
element.SetAttribute("name", name);
|
||||
element.SetAttribute("fullName", fullName);
|
||||
element.SetAttribute("tags", tags);
|
||||
auto& tagsElement = element.AddChild("tags");
|
||||
tagsElement.ConsiderAsArray();
|
||||
for (const auto& tag : tags) {
|
||||
tagsElement.AddChild("").SetStringValue(tag);
|
||||
}
|
||||
element.SetAttribute("author", author);
|
||||
element.SetAttribute("previewIconUrl", previewIconUrl);
|
||||
element.SetAttribute("iconUrl", iconUrl);
|
||||
element.SetAttribute("helpPath", helpPath);
|
||||
|
||||
SerializeEventsFunctionsTo(element.AddChild("eventsFunctions"));
|
||||
eventsBasedBehaviors.SerializeElementsTo(
|
||||
@@ -62,8 +73,27 @@ void EventsFunctionsExtension::UnserializeFrom(
|
||||
description = element.GetStringAttribute("description");
|
||||
name = element.GetStringAttribute("name");
|
||||
fullName = element.GetStringAttribute("fullName");
|
||||
tags = element.GetStringAttribute("tags");
|
||||
author = element.GetStringAttribute("author");
|
||||
previewIconUrl = element.GetStringAttribute("previewIconUrl");
|
||||
iconUrl = element.GetStringAttribute("iconUrl");
|
||||
helpPath = element.GetStringAttribute("helpPath");
|
||||
|
||||
tags.clear();
|
||||
auto& tagsElement = element.GetChild("tags");
|
||||
if (!tagsElement.IsValueUndefined()) {
|
||||
// Compatibility with GD <= 5.0.0-beta102
|
||||
gd::String tagsAsString = tagsElement.GetStringValue();
|
||||
tags = tagsAsString.Split(',');
|
||||
for (auto& tag : tags) {
|
||||
tag = tag.Trim();
|
||||
}
|
||||
// end of compatibility code
|
||||
} else {
|
||||
tagsElement.ConsiderAsArray();
|
||||
for (std::size_t i = 0; i < tagsElement.GetChildrenCount(); ++i) {
|
||||
tags.push_back(tagsElement.GetChild(i).GetStringValue());
|
||||
}
|
||||
}
|
||||
|
||||
UnserializeEventsFunctionsFrom(project, element.GetChild("eventsFunctions"));
|
||||
eventsBasedBehaviors.UnserializeElementsFrom(
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#define GDCORE_EVENTSFUNCTIONEXTENSION_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Project/EventsBasedBehavior.h"
|
||||
#include "GDCore/Project/EventsFunctionsContainer.h"
|
||||
#include "GDCore/String.h"
|
||||
@@ -83,11 +84,8 @@ class GD_CORE_API EventsFunctionsExtension : public EventsFunctionsContainer {
|
||||
return *this;
|
||||
}
|
||||
|
||||
const gd::String& GetTags() const { return tags; };
|
||||
EventsFunctionsExtension& SetTags(const gd::String& tags_) {
|
||||
tags = tags_;
|
||||
return *this;
|
||||
}
|
||||
const std::vector<gd::String>& GetTags() const { return tags; };
|
||||
std::vector<gd::String>& GetTags() { return tags; };
|
||||
|
||||
const gd::String& GetAuthor() const { return author; };
|
||||
EventsFunctionsExtension& SetAuthor(const gd::String& author_) {
|
||||
@@ -95,6 +93,34 @@ class GD_CORE_API EventsFunctionsExtension : public EventsFunctionsContainer {
|
||||
return *this;
|
||||
}
|
||||
|
||||
const gd::String& GetPreviewIconUrl() const { return previewIconUrl; };
|
||||
EventsFunctionsExtension& SetPreviewIconUrl(
|
||||
const gd::String& previewIconUrl_) {
|
||||
previewIconUrl = previewIconUrl_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const gd::String& GetIconUrl() const { return iconUrl; };
|
||||
EventsFunctionsExtension& SetIconUrl(const gd::String& iconUrl_) {
|
||||
iconUrl = iconUrl_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the help path of this extension, relative to the GDevelop
|
||||
* documentation root.
|
||||
*/
|
||||
const gd::String& GetHelpPath() const { return helpPath; };
|
||||
|
||||
/**
|
||||
* \brief Set the help path of this extension, relative to the GDevelop
|
||||
* documentation root.
|
||||
*/
|
||||
EventsFunctionsExtension& SetHelpPath(const gd::String& helpPath_) {
|
||||
helpPath = helpPath_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the list of the events based behaviors.
|
||||
*/
|
||||
@@ -128,7 +154,8 @@ class GD_CORE_API EventsFunctionsExtension : public EventsFunctionsContainer {
|
||||
/** \name Lifecycle event functions
|
||||
*/
|
||||
///@{
|
||||
static bool IsExtensionLifecycleEventsFunction(const gd::String& eventsFunctionName);
|
||||
static bool IsExtensionLifecycleEventsFunction(
|
||||
const gd::String& eventsFunctionName);
|
||||
///@}
|
||||
|
||||
private:
|
||||
@@ -144,8 +171,12 @@ class GD_CORE_API EventsFunctionsExtension : public EventsFunctionsContainer {
|
||||
gd::String description;
|
||||
gd::String name;
|
||||
gd::String fullName;
|
||||
gd::String tags;
|
||||
std::vector<gd::String> tags;
|
||||
gd::String author;
|
||||
gd::String previewIconUrl;
|
||||
gd::String iconUrl;
|
||||
gd::String helpPath; ///< The relative path to the help for this extension in
|
||||
///< the documentation (or an absolute URL).
|
||||
gd::SerializableWithNameList<EventsBasedBehavior> eventsBasedBehaviors;
|
||||
};
|
||||
|
||||
|
@@ -179,6 +179,8 @@ InitialInstanceFunctor::~InitialInstanceFunctor(){};
|
||||
|
||||
void HighestZOrderFinder::operator()(gd::InitialInstance& instance) {
|
||||
if (!layerRestricted || instance.GetLayer() == layerName) {
|
||||
instancesCount++;
|
||||
|
||||
if (firstCall) {
|
||||
highestZOrder = instance.GetZOrder();
|
||||
lowestZOrder = instance.GetZOrder();
|
||||
|
@@ -211,6 +211,7 @@ class GD_CORE_API HighestZOrderFinder : public gd::InitialInstanceFunctor {
|
||||
HighestZOrderFinder()
|
||||
: highestZOrder(0),
|
||||
lowestZOrder(0),
|
||||
instancesCount(0),
|
||||
firstCall(true),
|
||||
layerRestricted(false){};
|
||||
virtual ~HighestZOrderFinder(){};
|
||||
@@ -237,9 +238,16 @@ class GD_CORE_API HighestZOrderFinder : public gd::InitialInstanceFunctor {
|
||||
*/
|
||||
int GetLowestZOrder() const { return lowestZOrder; }
|
||||
|
||||
/**
|
||||
* \brief After calling the instances container iterate method with this
|
||||
* functor, this method will return the number of instances.
|
||||
*/
|
||||
size_t GetInstancesCount() const { return instancesCount; }
|
||||
|
||||
private:
|
||||
int highestZOrder;
|
||||
int lowestZOrder;
|
||||
size_t instancesCount;
|
||||
bool firstCall;
|
||||
|
||||
bool layerRestricted; ///< If true, the search is restricted to the layer
|
||||
|
@@ -38,6 +38,7 @@
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
#include "GDCore/Tools/PolymorphicClone.h"
|
||||
#include "GDCore/Tools/UUID/UUID.h"
|
||||
#include "GDCore/Tools/VersionWrapper.h"
|
||||
#include "GDCore/Utf8/utf8.h"
|
||||
|
||||
@@ -64,6 +65,8 @@ Project::Project()
|
||||
scaleMode("linear"),
|
||||
adaptGameResolutionAtRuntime(true),
|
||||
sizeOnStartupMode("adaptWidth"),
|
||||
projectUuid(""),
|
||||
useDeprecatedZeroAsDefaultZOrder(false),
|
||||
imageManager(std::make_shared<ImageManager>())
|
||||
#if defined(GD_IDE_ONLY)
|
||||
,
|
||||
@@ -106,6 +109,8 @@ Project::Project()
|
||||
|
||||
Project::~Project() {}
|
||||
|
||||
void Project::ResetProjectUuid() { projectUuid = UUID::MakeUuid4(); }
|
||||
|
||||
std::unique_ptr<gd::Object> Project::CreateObject(
|
||||
const gd::String& type,
|
||||
const gd::String& name,
|
||||
@@ -594,12 +599,12 @@ void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
SetAdaptGameResolutionAtRuntime(
|
||||
propElement.GetBoolAttribute("adaptGameResolutionAtRuntime", false));
|
||||
SetSizeOnStartupMode(propElement.GetStringAttribute("sizeOnStartupMode", ""));
|
||||
SetProjectUuid(propElement.GetStringAttribute("projectUuid", ""));
|
||||
#if defined(GD_IDE_ONLY)
|
||||
SetAuthor(propElement.GetChild("author", 0, "Auteur").GetValue().GetString());
|
||||
SetPackageName(propElement.GetStringAttribute("packageName"));
|
||||
SetOrientation(propElement.GetStringAttribute("orientation", "default"));
|
||||
SetFolderProject(propElement.GetBoolAttribute("folderProject"));
|
||||
SetProjectFile(propElement.GetStringAttribute("projectFile"));
|
||||
SetLastCompilationDirectory(propElement
|
||||
.GetChild("latestCompilationDirectory",
|
||||
0,
|
||||
@@ -609,17 +614,28 @@ void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
platformSpecificAssets.UnserializeFrom(
|
||||
propElement.GetChild("platformSpecificAssets"));
|
||||
loadingScreen.UnserializeFrom(propElement.GetChild("loadingScreen"));
|
||||
winExecutableFilename =
|
||||
propElement.GetStringAttribute("winExecutableFilename");
|
||||
winExecutableIconFile =
|
||||
propElement.GetStringAttribute("winExecutableIconFile");
|
||||
linuxExecutableFilename =
|
||||
propElement.GetStringAttribute("linuxExecutableFilename");
|
||||
macExecutableFilename =
|
||||
propElement.GetStringAttribute("macExecutableFilename");
|
||||
|
||||
useExternalSourceFiles =
|
||||
propElement.GetBoolAttribute("useExternalSourceFiles");
|
||||
|
||||
// Compatibility with GD <= 5.0.0-beta101
|
||||
if (VersionWrapper::IsOlderOrEqual(
|
||||
gdMajorVersion, gdMinorVersion, gdBuildVersion, 0, 4, 0, 98, 0) &&
|
||||
!propElement.HasAttribute("useDeprecatedZeroAsDefaultZOrder")) {
|
||||
useDeprecatedZeroAsDefaultZOrder = true;
|
||||
} else {
|
||||
useDeprecatedZeroAsDefaultZOrder =
|
||||
propElement.GetBoolAttribute("useDeprecatedZeroAsDefaultZOrder", false);
|
||||
}
|
||||
// end of compatibility code
|
||||
|
||||
// Compatibility with GD <= 5.0.0-beta101
|
||||
if (!propElement.HasAttribute("projectUuid") &&
|
||||
!propElement.HasChild("projectUuid")) {
|
||||
ResetProjectUuid();
|
||||
}
|
||||
// end of compatibility code
|
||||
|
||||
extensionProperties.UnserializeFrom(
|
||||
propElement.GetChild("extensionProperties"));
|
||||
|
||||
@@ -884,19 +900,21 @@ void Project::SerializeTo(SerializerElement& element) const {
|
||||
propElement.SetAttribute("adaptGameResolutionAtRuntime",
|
||||
adaptGameResolutionAtRuntime);
|
||||
propElement.SetAttribute("sizeOnStartupMode", sizeOnStartupMode);
|
||||
propElement.SetAttribute("projectFile", gameFile);
|
||||
propElement.SetAttribute("projectUuid", projectUuid);
|
||||
propElement.SetAttribute("folderProject", folderProject);
|
||||
propElement.SetAttribute("packageName", packageName);
|
||||
propElement.SetAttribute("orientation", orientation);
|
||||
platformSpecificAssets.SerializeTo(
|
||||
propElement.AddChild("platformSpecificAssets"));
|
||||
loadingScreen.SerializeTo(propElement.AddChild("loadingScreen"));
|
||||
propElement.SetAttribute("winExecutableFilename", winExecutableFilename);
|
||||
propElement.SetAttribute("winExecutableIconFile", winExecutableIconFile);
|
||||
propElement.SetAttribute("linuxExecutableFilename", linuxExecutableFilename);
|
||||
propElement.SetAttribute("macExecutableFilename", macExecutableFilename);
|
||||
propElement.SetAttribute("useExternalSourceFiles", useExternalSourceFiles);
|
||||
|
||||
// Compatibility with GD <= 5.0.0-beta101
|
||||
if (useDeprecatedZeroAsDefaultZOrder) {
|
||||
propElement.SetAttribute("useDeprecatedZeroAsDefaultZOrder", true);
|
||||
}
|
||||
// end of compatibility code
|
||||
|
||||
extensionProperties.SerializeTo(propElement.AddChild("extensionProperties"));
|
||||
|
||||
SerializerElement& extensionsElement = propElement.AddChild("extensions");
|
||||
@@ -1072,7 +1090,6 @@ Project& Project::operator=(const Project& other) {
|
||||
}
|
||||
|
||||
void Project::Init(const gd::Project& game) {
|
||||
// Some properties
|
||||
name = game.name;
|
||||
version = game.version;
|
||||
windowWidth = game.windowWidth;
|
||||
@@ -1083,6 +1100,8 @@ void Project::Init(const gd::Project& game) {
|
||||
scaleMode = game.scaleMode;
|
||||
adaptGameResolutionAtRuntime = game.adaptGameResolutionAtRuntime;
|
||||
sizeOnStartupMode = game.sizeOnStartupMode;
|
||||
projectUuid = game.projectUuid;
|
||||
useDeprecatedZeroAsDefaultZOrder = game.useDeprecatedZeroAsDefaultZOrder;
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
author = game.author;
|
||||
@@ -1105,7 +1124,6 @@ void Project::Init(const gd::Project& game) {
|
||||
extensionsUsed = game.extensionsUsed;
|
||||
platforms = game.platforms;
|
||||
|
||||
// Resources
|
||||
resourcesManager = game.resourcesManager;
|
||||
imageManager = std::make_shared<ImageManager>(*game.imageManager);
|
||||
imageManager->SetResourcesManager(&resourcesManager);
|
||||
@@ -1130,13 +1148,8 @@ void Project::Init(const gd::Project& game) {
|
||||
variables = game.GetVariables();
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
gameFile = game.GetProjectFile();
|
||||
projectFile = game.GetProjectFile();
|
||||
imagesChanged = game.imagesChanged;
|
||||
|
||||
winExecutableFilename = game.winExecutableFilename;
|
||||
winExecutableIconFile = game.winExecutableIconFile;
|
||||
linuxExecutableFilename = game.linuxExecutableFilename;
|
||||
macExecutableFilename = game.macExecutableFilename;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -118,13 +118,13 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
/**
|
||||
* Called when project file has changed.
|
||||
*/
|
||||
void SetProjectFile(const gd::String& file) { gameFile = file; }
|
||||
void SetProjectFile(const gd::String& file) { projectFile = file; }
|
||||
|
||||
/**
|
||||
* Return project file
|
||||
* \see gd::Project::SetProjectFile
|
||||
*/
|
||||
const gd::String& GetProjectFile() const { return gameFile; }
|
||||
const gd::String& GetProjectFile() const { return projectFile; }
|
||||
|
||||
/**
|
||||
* Set that the project should be saved as a folder project.
|
||||
@@ -277,6 +277,42 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
*/
|
||||
void SetScaleMode(const gd::String& scaleMode_) { scaleMode = scaleMode_; }
|
||||
|
||||
/**
|
||||
* \brief Return if the project should set 0 as Z-order for objects created
|
||||
* from events (which is deprecated) - instead of the highest Z order that was
|
||||
* found on each layer when the scene started.
|
||||
*/
|
||||
bool GetUseDeprecatedZeroAsDefaultZOrder() const {
|
||||
return useDeprecatedZeroAsDefaultZOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set if the project should set 0 as Z-order for objects created from
|
||||
* events (which is deprecated) - instead of the highest Z order that was
|
||||
* found on each layer when the scene started.
|
||||
*/
|
||||
void SetUseDeprecatedZeroAsDefaultZOrder(bool enable) {
|
||||
useDeprecatedZeroAsDefaultZOrder = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Change the project UUID.
|
||||
*/
|
||||
void SetProjectUuid(const gd::String& projectUuid_) {
|
||||
projectUuid = projectUuid_;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Get the project UUID, useful when using the game on online services
|
||||
* that would require a unique identifier.
|
||||
*/
|
||||
const gd::String& GetProjectUuid() const { return projectUuid; }
|
||||
|
||||
/**
|
||||
* \brief Create a new project UUID.
|
||||
*/
|
||||
void ResetProjectUuid();
|
||||
|
||||
/**
|
||||
* Return a reference to the vector containing the names of extensions used by
|
||||
* the project.
|
||||
@@ -293,20 +329,20 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* \brief Get the properties set by extensions.
|
||||
*
|
||||
* Each extension can store arbitrary values indexed by a property name, which are
|
||||
* useful to store project wide settings (AdMob id, etc...).
|
||||
* \brief Get the properties set by extensions.
|
||||
*
|
||||
* Each extension can store arbitrary values indexed by a property name, which
|
||||
* are useful to store project wide settings (AdMob id, etc...).
|
||||
*/
|
||||
gd::ExtensionProperties& GetExtensionProperties() {
|
||||
return extensionProperties;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Get the properties set by extensions.
|
||||
*
|
||||
* Each extension can store arbitrary values indexed by a property name, which are
|
||||
* useful to store project wide settings (AdMob id, etc...).
|
||||
* \brief Get the properties set by extensions.
|
||||
*
|
||||
* Each extension can store arbitrary values indexed by a property name, which
|
||||
* are useful to store project wide settings (AdMob id, etc...).
|
||||
*/
|
||||
const gd::ExtensionProperties& GetExtensionProperties() const {
|
||||
return extensionProperties;
|
||||
@@ -923,10 +959,6 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
std::vector<gd::String> imagesChanged; ///< Images that have been changed and
|
||||
///< which have to be reloaded
|
||||
gd::String winExecutableFilename; ///< Windows executable name
|
||||
gd::String winExecutableIconFile; ///< Icon for Windows executable
|
||||
gd::String linuxExecutableFilename; ///< Linux executable name
|
||||
gd::String macExecutableFilename; ///< Mac executable name
|
||||
#endif
|
||||
|
||||
private:
|
||||
@@ -948,8 +980,15 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
bool adaptGameResolutionAtRuntime; ///< Should the game resolution be adapted
|
||||
///< to the window size at runtime
|
||||
gd::String
|
||||
sizeOnStartupMode; ///< How to adapt the game size to the screen. Can be
|
||||
///< "adaptWidth", "adaptHeight" or empty
|
||||
sizeOnStartupMode; ///< How to adapt the game size to the screen. Can be
|
||||
///< "adaptWidth", "adaptHeight" or empty
|
||||
gd::String projectUuid; ///< UUID useful to identify the game in online
|
||||
///< services or database that would require it.
|
||||
bool useDeprecatedZeroAsDefaultZOrder; ///< If true, objects created from
|
||||
///< events will have 0 as Z order,
|
||||
///< instead of the highest Z order
|
||||
///< found on the layer at the scene
|
||||
///< startup.
|
||||
std::vector<std::unique_ptr<gd::Layout> > scenes; ///< List of all scenes
|
||||
gd::VariablesContainer variables; ///< Initial global variables
|
||||
std::vector<std::unique_ptr<gd::ExternalLayout> >
|
||||
@@ -977,8 +1016,9 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
///< "default", "landscape" or "portrait".
|
||||
bool
|
||||
folderProject; ///< True if folder project, false if single file project.
|
||||
gd::String gameFile; ///< File of the game
|
||||
gd::String latestCompilationDirectory; ///< File of the game
|
||||
gd::String
|
||||
projectFile; ///< Path to the project file - when editing a local file.
|
||||
gd::String latestCompilationDirectory;
|
||||
gd::Platform*
|
||||
currentPlatform; ///< The platform being used to edit the project.
|
||||
gd::PlatformSpecificAssets platformSpecificAssets;
|
||||
|
@@ -5,8 +5,10 @@
|
||||
*/
|
||||
|
||||
#include "GDCore/Project/ResourcesManager.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
@@ -20,6 +22,7 @@ namespace gd {
|
||||
gd::String Resource::badStr;
|
||||
|
||||
Resource ResourcesManager::badResource;
|
||||
gd::String ResourcesManager::badResourceName;
|
||||
#if defined(GD_IDE_ONLY)
|
||||
ResourceFolder ResourcesManager::badFolder;
|
||||
Resource ResourceFolder::badResource;
|
||||
@@ -90,6 +93,33 @@ bool ResourcesManager::HasResource(const gd::String& name) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
const gd::String& ResourcesManager::GetResourceNameWithOrigin(
|
||||
const gd::String& originName, const gd::String& originIdentifier) const {
|
||||
for (const auto& resource : resources) {
|
||||
if (!resource) continue;
|
||||
|
||||
if (resource->GetOriginName() == originName &&
|
||||
resource->GetOriginIdentifier() == originIdentifier) {
|
||||
return resource->GetName();
|
||||
}
|
||||
}
|
||||
|
||||
return badResourceName;
|
||||
}
|
||||
|
||||
const gd::String& ResourcesManager::GetResourceNameWithFile(
|
||||
const gd::String& file) const {
|
||||
for (const auto& resource : resources) {
|
||||
if (!resource) continue;
|
||||
|
||||
if (resource->GetFile() == file) {
|
||||
return resource->GetName();
|
||||
}
|
||||
}
|
||||
|
||||
return badResourceName;
|
||||
}
|
||||
|
||||
std::vector<gd::String> ResourcesManager::GetAllResourceNames() const {
|
||||
std::vector<gd::String> allResources;
|
||||
for (std::size_t i = 0; i < resources.size(); ++i)
|
||||
@@ -104,7 +134,8 @@ std::map<gd::String, gd::PropertyDescriptor> Resource::GetProperties() const {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> ImageResource::GetProperties() const {
|
||||
std::map<gd::String, gd::PropertyDescriptor> ImageResource::GetProperties()
|
||||
const {
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties[_("Smooth the image")]
|
||||
.SetValue(smooth ? "true" : "false")
|
||||
@@ -413,6 +444,15 @@ void ResourcesManager::UnserializeFrom(const SerializerElement& element) {
|
||||
std::shared_ptr<Resource> resource = CreateResource(kind);
|
||||
resource->SetName(name);
|
||||
resource->SetMetadata(metadata);
|
||||
|
||||
if (resourceElement.HasChild("origin")) {
|
||||
gd::String originName =
|
||||
resourceElement.GetChild("origin").GetStringAttribute("name", "");
|
||||
gd::String originIdentifier =
|
||||
resourceElement.GetChild("origin").GetStringAttribute("identifier",
|
||||
"");
|
||||
resource->SetOrigin(originName, originIdentifier);
|
||||
}
|
||||
resource->UnserializeFrom(resourceElement);
|
||||
|
||||
resources.push_back(resource);
|
||||
@@ -444,6 +484,14 @@ void ResourcesManager::SerializeTo(SerializerElement& element) const {
|
||||
resourceElement.SetAttribute("name", resources[i]->GetName());
|
||||
resourceElement.SetAttribute("metadata", resources[i]->GetMetadata());
|
||||
|
||||
const gd::String& originName = resources[i]->GetOriginName();
|
||||
const gd::String& originIdentifier = resources[i]->GetOriginIdentifier();
|
||||
if (!originName.empty() || !originIdentifier.empty()) {
|
||||
resourceElement.AddChild("origin")
|
||||
.SetAttribute("name", originName)
|
||||
.SetAttribute("identifier", originIdentifier);
|
||||
}
|
||||
|
||||
resources[i]->SerializeTo(resourceElement);
|
||||
}
|
||||
|
||||
@@ -560,7 +608,8 @@ void JsonResource::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("disablePreload", IsPreloadDisabled());
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> JsonResource::GetProperties() const {
|
||||
std::map<gd::String, gd::PropertyDescriptor> JsonResource::GetProperties()
|
||||
const {
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties["disablePreload"]
|
||||
.SetValue(disablePreload ? "true" : "false")
|
||||
|
@@ -79,6 +79,17 @@ class GD_CORE_API Resource {
|
||||
*/
|
||||
virtual void SetFile(const gd::String& newFile){};
|
||||
|
||||
/**
|
||||
* TODO: make a ResourceOrigin object?
|
||||
*/
|
||||
virtual void SetOrigin(const gd::String& originName_, const gd::String& originIdentifier_) {
|
||||
originName = originName_;
|
||||
originIdentifier = originIdentifier_;
|
||||
}
|
||||
|
||||
virtual const gd::String& GetOriginName() const { return originName; }
|
||||
virtual const gd::String& GetOriginIdentifier() const { return originIdentifier; }
|
||||
|
||||
/**
|
||||
* \brief Set the metadata (any string) associated to the resource.
|
||||
* \note Can be used by external editors to store extra information, for
|
||||
@@ -142,6 +153,8 @@ class GD_CORE_API Resource {
|
||||
gd::String kind;
|
||||
gd::String name;
|
||||
gd::String metadata;
|
||||
gd::String originName;
|
||||
gd::String originIdentifier;
|
||||
bool userAdded; ///< True if the resource was added by the user, and not
|
||||
///< automatically by GDevelop.
|
||||
|
||||
@@ -354,6 +367,18 @@ class GD_CORE_API ResourcesManager {
|
||||
*/
|
||||
bool HasResource(const gd::String& name) const;
|
||||
|
||||
/**
|
||||
* \brief Return the name of the resource with the given origin, if any.
|
||||
* If not found, an empty string is returned.
|
||||
*/
|
||||
const gd::String& GetResourceNameWithOrigin(const gd::String& originName, const gd::String& originIdentifier) const;
|
||||
|
||||
/**
|
||||
* \brief Return the name of the first resource with the given file, if any.
|
||||
* If not found, an empty string is returned.
|
||||
*/
|
||||
const gd::String& GetResourceNameWithFile(const gd::String& file) const;
|
||||
|
||||
/**
|
||||
* \brief Return a reference to a resource.
|
||||
*/
|
||||
@@ -487,6 +512,7 @@ class GD_CORE_API ResourcesManager {
|
||||
static ResourceFolder badFolder;
|
||||
#endif
|
||||
static Resource badResource;
|
||||
static gd::String badResourceName;
|
||||
};
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
|
@@ -524,6 +524,37 @@ public:
|
||||
*/
|
||||
String FindAndReplace(String search, String replacement, bool all = true) const;
|
||||
|
||||
/**
|
||||
* \brief Removes the specified characters (by default all the "whitespaces" and line breaks) from the beginning of the string,
|
||||
* and return the new string.
|
||||
*/
|
||||
String LeftTrim(const gd::String& chars = " \t\n\v\f\r")
|
||||
{
|
||||
String trimmedString(*this);
|
||||
trimmedString.erase(0, trimmedString.find_first_not_of(chars));
|
||||
return trimmedString;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Removes the specified characters (by default all the "whitespaces" and line breaks) from the end of the string,
|
||||
* and return the new string.
|
||||
*/
|
||||
String RightTrim(const gd::String& chars = " \t\n\v\f\r")
|
||||
{
|
||||
String trimmedString(*this);
|
||||
trimmedString.erase(trimmedString.find_last_not_of(chars) + 1);
|
||||
return trimmedString;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Removes the specified characters (by default all the "whitespaces" and line breaks) from the
|
||||
* beginning and the end of the string and return the new string.
|
||||
*/
|
||||
String Trim(const gd::String& chars = " \t\n\v\f\r")
|
||||
{
|
||||
return LeftTrim(chars).RightTrim(chars);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalization form
|
||||
*/
|
||||
|
@@ -84,6 +84,18 @@ void SetupProjectWithDummyPlatform(gd::Project &project,
|
||||
.AddParameter("string", "")
|
||||
.AddParameter("expression", "", "", true)
|
||||
.SetFunctionName("getNumberWith3Params");
|
||||
extension
|
||||
->AddStrExpression("GetStringWith2ObjectParamAnd2ObjectVarParam",
|
||||
"Get string with twice an object param and an objectvar param",
|
||||
"",
|
||||
"",
|
||||
"")
|
||||
.AddParameter("object", _("Object 1 parameter"))
|
||||
.AddParameter("objectvar", _("Variable for object 1"))
|
||||
.AddParameter("object", _("Object 2 parameter"))
|
||||
.AddParameter("objectvar", _("Variable for object 2"))
|
||||
.SetFunctionName("getStringWith2ObjectParamAnd2ObjectVarParam");
|
||||
|
||||
auto &object = extension->AddObject<gd::Object>(
|
||||
"Sprite", "Dummy Sprite", "Dummy sprite object", "");
|
||||
object
|
||||
|
@@ -4,6 +4,7 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2.h"
|
||||
|
||||
#include "DummyPlatform.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
@@ -823,37 +824,41 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
|
||||
}
|
||||
|
||||
SECTION("Valid object function name") {
|
||||
auto node = parser.ParseExpression("string", "MyObject.MyFunc");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &objectFunctionName = dynamic_cast<gd::ObjectFunctionNameNode &>(*node);
|
||||
REQUIRE(objectFunctionName.objectName == "MyObject");
|
||||
REQUIRE(objectFunctionName.objectFunctionOrBehaviorName == "MyFunc");
|
||||
auto node = parser.ParseExpression("string", "MyObject.MyFunc");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &objectFunctionName =
|
||||
dynamic_cast<gd::ObjectFunctionNameNode &>(*node);
|
||||
REQUIRE(objectFunctionName.objectName == "MyObject");
|
||||
REQUIRE(objectFunctionName.objectFunctionOrBehaviorName == "MyFunc");
|
||||
}
|
||||
|
||||
SECTION("Valid object behavior name") {
|
||||
auto node = parser.ParseExpression("string", "MyObject.MyBehavior::MyFunc");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &objectFunctionName = dynamic_cast<gd::ObjectFunctionNameNode &>(*node);
|
||||
REQUIRE(objectFunctionName.objectName == "MyObject");
|
||||
REQUIRE(objectFunctionName.objectFunctionOrBehaviorName == "MyBehavior");
|
||||
REQUIRE(objectFunctionName.behaviorFunctionName == "MyFunc");
|
||||
auto node = parser.ParseExpression("string", "MyObject.MyBehavior::MyFunc");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &objectFunctionName =
|
||||
dynamic_cast<gd::ObjectFunctionNameNode &>(*node);
|
||||
REQUIRE(objectFunctionName.objectName == "MyObject");
|
||||
REQUIRE(objectFunctionName.objectFunctionOrBehaviorName == "MyBehavior");
|
||||
REQUIRE(objectFunctionName.behaviorFunctionName == "MyFunc");
|
||||
}
|
||||
|
||||
SECTION("Unfinished object function name") {
|
||||
auto node = parser.ParseExpression("string", "MyObject.");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &objectFunctionName = dynamic_cast<gd::ObjectFunctionNameNode &>(*node);
|
||||
REQUIRE(objectFunctionName.objectName == "MyObject");
|
||||
REQUIRE(objectFunctionName.objectFunctionOrBehaviorName == "");
|
||||
auto node = parser.ParseExpression("string", "MyObject.");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &objectFunctionName =
|
||||
dynamic_cast<gd::ObjectFunctionNameNode &>(*node);
|
||||
REQUIRE(objectFunctionName.objectName == "MyObject");
|
||||
REQUIRE(objectFunctionName.objectFunctionOrBehaviorName == "");
|
||||
}
|
||||
|
||||
SECTION("Unfinished object behavior name") {
|
||||
auto node = parser.ParseExpression("string", "MyObject.MyBehavior::");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &objectFunctionName = dynamic_cast<gd::ObjectFunctionNameNode &>(*node);
|
||||
REQUIRE(objectFunctionName.objectName == "MyObject");
|
||||
REQUIRE(objectFunctionName.objectFunctionOrBehaviorName == "MyBehavior");
|
||||
REQUIRE(objectFunctionName.behaviorFunctionName == "");
|
||||
auto node = parser.ParseExpression("string", "MyObject.MyBehavior::");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &objectFunctionName =
|
||||
dynamic_cast<gd::ObjectFunctionNameNode &>(*node);
|
||||
REQUIRE(objectFunctionName.objectName == "MyObject");
|
||||
REQUIRE(objectFunctionName.objectFunctionOrBehaviorName == "MyBehavior");
|
||||
REQUIRE(objectFunctionName.behaviorFunctionName == "");
|
||||
}
|
||||
|
||||
SECTION("Invalid function calls") {
|
||||
@@ -948,7 +953,8 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Invalid behavior function call, finishing with namespace separator") {
|
||||
SECTION(
|
||||
"Invalid behavior function call, finishing with namespace separator") {
|
||||
{
|
||||
auto node = parser.ParseExpression("number", "MyObject.MyBehavior::(12)");
|
||||
REQUIRE(node != nullptr);
|
||||
@@ -1031,6 +1037,55 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Valid function call with object variable") {
|
||||
{
|
||||
// Note that in this test we need to use an expression with "objectvar",
|
||||
// as the grammar of the parser depends on this parameter type
|
||||
// information.
|
||||
auto node = parser.ParseExpression(
|
||||
"string",
|
||||
"MyExtension::GetStringWith2ObjectParamAnd2ObjectVarParam(MyObject1, "
|
||||
"MyVar1, MyObject2, MyVar2)");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &functionNode = dynamic_cast<gd::FunctionCallNode &>(*node);
|
||||
auto &identifierObject1Node =
|
||||
dynamic_cast<gd::IdentifierNode &>(*functionNode.parameters[0]);
|
||||
auto &variable1Node =
|
||||
dynamic_cast<gd::VariableNode &>(*functionNode.parameters[1]);
|
||||
auto &identifierObject2Node =
|
||||
dynamic_cast<gd::IdentifierNode &>(*functionNode.parameters[2]);
|
||||
auto &variable2Node =
|
||||
dynamic_cast<gd::VariableNode &>(*functionNode.parameters[3]);
|
||||
|
||||
REQUIRE(identifierObject1Node.identifierName == "MyObject1");
|
||||
REQUIRE(identifierObject2Node.identifierName == "MyObject2");
|
||||
REQUIRE(variable1Node.objectName == "MyObject1");
|
||||
REQUIRE(variable1Node.name == "MyVar1");
|
||||
REQUIRE(variable2Node.objectName == "MyObject2");
|
||||
REQUIRE(variable2Node.name == "MyVar2");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Invalid function call with object variable") {
|
||||
{
|
||||
// Note that in this test we need to use an expression with "objectvar",
|
||||
// as the grammar of the parser depends on this parameter type
|
||||
// information.
|
||||
auto node = parser.ParseExpression(
|
||||
"string",
|
||||
"MyExtension::GetStringWith2ObjectParamAnd2ObjectVarParam(My "
|
||||
"badly/written object1, MyVar1, MyObject2, MyVar2)");
|
||||
REQUIRE(node != nullptr);
|
||||
|
||||
gd::ExpressionValidator validator;
|
||||
node->Visit(validator);
|
||||
REQUIRE(validator.GetErrors().size() == 1);
|
||||
REQUIRE(validator.GetErrors()[0]->GetMessage() ==
|
||||
"An object name was expected but something else was written. "
|
||||
"Enter just the name of the object for this parameter.");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Fuzzy/random tests") {
|
||||
{
|
||||
auto testExpression = [&parser](const gd::String &expression) {
|
||||
|
33
Core/tests/ResourcesRenamer.cpp
Normal file
33
Core/tests/ResourcesRenamer.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
/**
|
||||
* @file Tests covering common features of GDevelop Core.
|
||||
*/
|
||||
#include "GDCore/IDE/Project/ResourcesRenamer.h"
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
TEST_CASE("ResourcesRenamer", "[common]") {
|
||||
SECTION("It renames resources that are exposed") {
|
||||
std::map<gd::String, gd::String> renamings = {
|
||||
{"Resource1", "RenamedResource1"}};
|
||||
gd::ResourcesRenamer resourcesRenamer(renamings);
|
||||
|
||||
gd::Project project;
|
||||
project.GetPlatformSpecificAssets().Set(
|
||||
"android", "some-icon", "Resource1");
|
||||
project.GetPlatformSpecificAssets().Set(
|
||||
"android", "some-other-icon", "Resource2");
|
||||
|
||||
project.ExposeResources(resourcesRenamer);
|
||||
REQUIRE(project.GetPlatformSpecificAssets().Get("android", "some-icon") ==
|
||||
"RenamedResource1");
|
||||
REQUIRE(project.GetPlatformSpecificAssets().Get(
|
||||
"android", "some-other-icon") == "Resource2");
|
||||
}
|
||||
}
|
@@ -289,4 +289,40 @@ TEST_CASE("Utf8 String", "[common][utf8]") {
|
||||
gd::String str6 = u8"ßßß";
|
||||
REQUIRE(str6.FindAndReplace(u8"ßß", u8"ß") == u8"ßß");
|
||||
}
|
||||
|
||||
SECTION("trimming") {
|
||||
REQUIRE(gd::String("").Trim() == "");
|
||||
REQUIRE(gd::String("").LeftTrim() == "");
|
||||
REQUIRE(gd::String("").RightTrim() == "");
|
||||
REQUIRE(gd::String(" ").Trim() == "");
|
||||
REQUIRE(gd::String(" ").LeftTrim() == "");
|
||||
REQUIRE(gd::String(" ").RightTrim() == "");
|
||||
REQUIRE(gd::String(" ").Trim() == "");
|
||||
REQUIRE(gd::String(" ").LeftTrim() == "");
|
||||
REQUIRE(gd::String(" ").RightTrim() == "");
|
||||
REQUIRE(gd::String("a").Trim() == "a");
|
||||
REQUIRE(gd::String("a").LeftTrim() == "a");
|
||||
REQUIRE(gd::String("a").RightTrim() == "a");
|
||||
REQUIRE(gd::String("aß").Trim() == "aß");
|
||||
REQUIRE(gd::String("aß").LeftTrim() == "aß");
|
||||
REQUIRE(gd::String("aß").RightTrim() == "aß");
|
||||
REQUIRE(gd::String(" a ").Trim() == "a");
|
||||
REQUIRE(gd::String(" a ").LeftTrim() == "a ");
|
||||
REQUIRE(gd::String(" a ").RightTrim() == " a");
|
||||
REQUIRE(gd::String(" aß ").Trim() == "aß");
|
||||
REQUIRE(gd::String(" aß ").LeftTrim() == "aß ");
|
||||
REQUIRE(gd::String(" aß ").RightTrim() == " aß");
|
||||
REQUIRE(gd::String(" a ß ").Trim() == "a ß");
|
||||
REQUIRE(gd::String(" a ß ").LeftTrim() == "a ß ");
|
||||
REQUIRE(gd::String(" a ß ").RightTrim() == " a ß");
|
||||
REQUIRE(gd::String(" aß ").Trim() == "aß");
|
||||
REQUIRE(gd::String(" aß ").LeftTrim() == "aß ");
|
||||
REQUIRE(gd::String(" aß ").RightTrim() == " aß");
|
||||
REQUIRE(gd::String("---aß---").Trim("-/") == "aß");
|
||||
REQUIRE(gd::String("---aß---").LeftTrim("-/") == "aß---");
|
||||
REQUIRE(gd::String("---aß---").RightTrim("-/") == "---aß");
|
||||
REQUIRE(gd::String("-/=aß=/-").Trim("-/") == "=aß=");
|
||||
REQUIRE(gd::String("-/=aß=/-").LeftTrim("-/") == "=aß=/-");
|
||||
REQUIRE(gd::String("-/=aß=/-").RightTrim("-/") == "-/=aß=");
|
||||
}
|
||||
}
|
||||
|
@@ -2,34 +2,38 @@
|
||||
# do it if not already cloned to avoid triggering a whole
|
||||
# recompilation every time CMake is run.
|
||||
find_package(Git)
|
||||
if(GIT_FOUND AND NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/SFML/readme.txt")
|
||||
message( "Cloning SFML in ExtLibs/SFML with Git..." )
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} clone "https://www.github.com/SFML/SFML.git" SFML
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
|
||||
OUTPUT_QUIET)
|
||||
if(GIT_FOUND)
|
||||
if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/SFML/readme.txt")
|
||||
message( "Cloning SFML in ExtLibs/SFML with Git..." )
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} clone "https://www.github.com/SFML/SFML.git" SFML
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
|
||||
OUTPUT_QUIET)
|
||||
|
||||
message( "Resetting SFML source code to version 2.4.1..." )
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} reset --hard 2.4.1
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/SFML
|
||||
OUTPUT_QUIET)
|
||||
message( "Resetting SFML source code to version 2.4.1..." )
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} reset --hard 2.4.1
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/SFML
|
||||
OUTPUT_QUIET)
|
||||
|
||||
message( "Applying the patches..." )
|
||||
file(GLOB SFML_PATCHES
|
||||
LIST_DIRECTORIES FALSE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/SFML-patches/*.patch)
|
||||
message( "Applying the patches..." )
|
||||
file(GLOB SFML_PATCHES
|
||||
LIST_DIRECTORIES FALSE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/SFML-patches/*.patch)
|
||||
|
||||
if(SFML_PATCHES)
|
||||
list(SORT SFML_PATCHES)
|
||||
if(SFML_PATCHES)
|
||||
list(SORT SFML_PATCHES)
|
||||
|
||||
foreach(SFML_PATCH ${SFML_PATCHES})
|
||||
message( "Applying patch: ${SFML_PATCH}..." )
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} apply ${SFML_PATCH} --ignore-whitespace
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/SFML
|
||||
OUTPUT_QUIET)
|
||||
endforeach()
|
||||
foreach(SFML_PATCH ${SFML_PATCHES})
|
||||
message( "Applying patch: ${SFML_PATCH}..." )
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} apply ${SFML_PATCH} --ignore-whitespace
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/SFML
|
||||
OUTPUT_QUIET)
|
||||
endforeach()
|
||||
endif()
|
||||
else()
|
||||
message( "SFML already downloaded." )
|
||||
endif()
|
||||
else()
|
||||
message( "Git not found, make sure you have SFML >= 2.4 in ExtLibs/SFML and you applied the needed patches (from ExtLibs/SFML-patches)!" )
|
||||
|
676
Extensions/AdvancedWindow/JsExtension.js
Normal file
676
Extensions/AdvancedWindow/JsExtension.js
Normal file
@@ -0,0 +1,676 @@
|
||||
// @flow
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
* ℹ️ Changes in this file are watched and automatically imported if the editor
|
||||
* is running. You can also manually run `node import-GDJS-Runtime.js` (in newIDE/app/scripts).
|
||||
*
|
||||
* The file must be named "JsExtension.js", otherwise GDevelop won't load it.
|
||||
* ⚠️ If you make a change and the extension is not loaded, open the developer console
|
||||
* and search for any errors.
|
||||
*
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension.setExtensionInformation(
|
||||
'AdvancedWindow',
|
||||
_('Advanced window management'),
|
||||
_(
|
||||
'Provides advanced features related to the game window positioning and interaction with the operating system.'
|
||||
),
|
||||
'Arthur Pacaud (arthuro555)',
|
||||
'MIT'
|
||||
);
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'Focus',
|
||||
_('Change focus of the window'),
|
||||
_('Make the window gain or lose focus.'),
|
||||
_('Focus the window: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Focus the window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.focus');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsFocused',
|
||||
_('Window focused'),
|
||||
_('Checks if the window is focused.'),
|
||||
_('The window is focused'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isFocused');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'Show',
|
||||
_('Change visibility of the window'),
|
||||
_('Make the window visible or invisible.'),
|
||||
_('Window visible: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Show window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.show');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsVisible',
|
||||
_('Window visible'),
|
||||
_('Checks if the window is visible.'),
|
||||
_('The window is visible'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isVisible');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'Maximize',
|
||||
_('Maximize the window'),
|
||||
_('Maximize or unmaximize the window.'),
|
||||
_('Maximize window: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Maximize window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.maximize');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsMaximized',
|
||||
_('Window maximized'),
|
||||
_('Checks if the window is maximized.'),
|
||||
_('The window is maximized'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isMaximized');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'Minimize',
|
||||
_('Minimize the window'),
|
||||
_('Minimize or unminimize the window.'),
|
||||
_('Minimize window: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Minimize window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.minimize');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsMinimized',
|
||||
_('Window minimized'),
|
||||
_('Checks if the window is minimized.'),
|
||||
_('The window is minimized'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isMinimized');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'EnableWindow',
|
||||
_('Enable the window'),
|
||||
_('Enables or disables the window.'),
|
||||
_('Enable window: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Enable window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.enable');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsWindowEnabled',
|
||||
_('Window enabled'),
|
||||
_('Checks if the window is enabled.'),
|
||||
_('The window is enabled'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isEnabled');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetResizable',
|
||||
_('Allow resizing'),
|
||||
_('Enables or disables resizing of the window by the user.'),
|
||||
_('Enable window resizing: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Allow resizing?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setResizable');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsResizable',
|
||||
_('Window resizable'),
|
||||
_('Checks if the window can be resized.'),
|
||||
_('The window can be resized'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isResizable');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetMovable',
|
||||
_('Allow moving'),
|
||||
_('Enables or disables moving of the window by the user.'),
|
||||
_('Enable window moving: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Allow moving?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setMovable');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsMovable',
|
||||
_('Window movable'),
|
||||
_('Checks if the window can be moved.'),
|
||||
_('The window can be moved'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isMovable');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetMaximizable',
|
||||
_('Allow maximizing'),
|
||||
_('Enables or disables maximizing of the window by the user.'),
|
||||
_('Enable window maximizing: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Allow maximizing?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setMaximizable');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsMaximizable',
|
||||
_('Window maximizable'),
|
||||
_('Checks if the window can be maximized.'),
|
||||
_('The window can be maximized'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isMaximizable');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetMinimizable',
|
||||
_('Allow mimizing'),
|
||||
_('Enables or disables minimizing of the window by the user.'),
|
||||
_('Enable window minimizing: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Allow minimizing?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setMinimizable');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsMinimizable',
|
||||
_('Window minimizable'),
|
||||
_('Checks if the window can be minimized.'),
|
||||
_('The window can be minimized'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isMinimizable');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetFullScreenable',
|
||||
_('Allow full-screening'),
|
||||
_('Enables or disables full-screening of the window by the user.'),
|
||||
_('Enable window full-screening: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Allow full-screening?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setFullScreenable');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsFullScreenable',
|
||||
_('Window full-screenable'),
|
||||
_('Checks if the window can be full-screened.'),
|
||||
_('The window can be set in fullscreen'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isFullScreenable');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetClosable',
|
||||
_('Allow closing'),
|
||||
_('Enables or disables closing of the window by the user.'),
|
||||
_('Enable window closing: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Allow closing?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setClosable');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsClosable',
|
||||
_('Window closable'),
|
||||
_('Checks if the window can be closed.'),
|
||||
_('The window can be closed'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isClosable');
|
||||
|
||||
const levelChoices = JSON.stringify([
|
||||
'normal',
|
||||
'floating',
|
||||
'torn-off-menu',
|
||||
'modal-panel',
|
||||
'main-menu',
|
||||
'status',
|
||||
'pop-up-menu',
|
||||
'screen-saver',
|
||||
]);
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetAlwaysOnTop',
|
||||
_('Make the windows always on top'),
|
||||
_('Puts the window constantly above all other windows.'),
|
||||
_('Make window always on top: _PARAM0_, level: _PARAM1_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Enable always on top?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addParameter('stringWithSelector', _('Level'), levelChoices, false)
|
||||
.setDefaultValue('floating')
|
||||
.setParameterLongDescription(
|
||||
'The level is like a layer in GDevelop but for the OS. ' +
|
||||
'The further down the list, the higher it will be. ' +
|
||||
'When disabling always on top, the level will be set to normal. ' +
|
||||
'From "floating" to "status" included, ' +
|
||||
'the window is placed below the Dock on macOS and below the taskbar on Windows. ' +
|
||||
'Starting from "pop-up-menu", it is shown above the Dock on macOS and ' +
|
||||
'above the taskbar on Windows. ' +
|
||||
'This parameter is ignored on linux.'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setAlwaysOnTop');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsAlwaysOnTop',
|
||||
_('Window always on top'),
|
||||
_('Checks if the window is always on top.'),
|
||||
_('The window is always on top'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isAlwaysOnTop');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetKiosk',
|
||||
_('Enable kiosk mode'),
|
||||
_(
|
||||
'Puts the window in kiosk mode. This prevents the user from exiting fullscreen.'
|
||||
),
|
||||
_('Enable kiosk mode: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Enable kiosk mode?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setKiosk');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsKiosk',
|
||||
_('Kiosk mode'),
|
||||
_('Checks if the window is currently in kiosk mode.'),
|
||||
_('The window is in kiosk mode'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.isKiosk');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetHasShadow',
|
||||
_('Enable window shadow'),
|
||||
_('Enables or disables the window shadow.'),
|
||||
_('Enable window shadow: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Enable shadow?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setHasShadow');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'HasShadow',
|
||||
_('Shadow enabled'),
|
||||
_("Checks if the window currently has it's shadow enabled."),
|
||||
_('The window has a shadow'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.hasShadow');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'EnableContentProtection',
|
||||
_('Enable content protection'),
|
||||
_(
|
||||
'Enables or disables the content protection mode. This should prevent screenshots of the game from being taken.'
|
||||
),
|
||||
_('Enable content protection: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Enable content protection?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setContentProtection');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetFocusable',
|
||||
_('Allow focusing'),
|
||||
_('Allow or disallow the user to focus the window.'),
|
||||
_('Allow to focus the window: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Allow focus?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setFocusable');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'Flash',
|
||||
_('Flash the window'),
|
||||
_('Make the window flash or end flashing.'),
|
||||
_('Make the window flash: _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('yesorno', _('Flash the window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.flash');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetOpacity',
|
||||
_('Set window opacity'),
|
||||
_('Changes the window opacity.'),
|
||||
_('Set the window opacity to _PARAM0_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('expression', _('New opacity'), '', false)
|
||||
.setParameterLongDescription('A number between 0 (fully transparent) and 1 (fully opaque).')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setOpacity');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'SetWindowPosition',
|
||||
_('Set window position'),
|
||||
_('Changes the window position.'),
|
||||
_('Set the window position to _PARAM0_;_PARAM1_'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addParameter('expression', _('X position'), '', false)
|
||||
.addParameter('expression', _('Y position'), '', false)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.setPosition');
|
||||
|
||||
extension
|
||||
.addExpression(
|
||||
'WindowX',
|
||||
_('Window X position'),
|
||||
_('Returns the current window X position.'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.getPositionX');
|
||||
|
||||
extension
|
||||
.addExpression(
|
||||
'WindowY',
|
||||
_('Window Y position'),
|
||||
_('Returns the current window Y position.'),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.getPositionY');
|
||||
|
||||
extension
|
||||
.addExpression(
|
||||
'WindowOpacity',
|
||||
_('Window opacity'),
|
||||
_(
|
||||
'Returns the current window opacity (a number from 0 to 1, 1 being fully opaque).'
|
||||
),
|
||||
_('Advanced window management/Windows, Linux, macOS'),
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
)
|
||||
.setFunctionName('gdjs.evtTools.advancedWindow.getOpacity');
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
};
|
370
Extensions/AdvancedWindow/electron-advancedwindowtools.js
Normal file
370
Extensions/AdvancedWindow/electron-advancedwindowtools.js
Normal file
@@ -0,0 +1,370 @@
|
||||
// @ts-check
|
||||
/**
|
||||
* A set of wrappers around the Electron windowing APIs.
|
||||
* They don't have any effect on non Electron runtimes.
|
||||
*
|
||||
* Docstrings are only used for typing here, for proper
|
||||
* documentation check the electron docs at
|
||||
* https://www.electronjs.org/docs/api.
|
||||
*
|
||||
* @filedescriptor
|
||||
* @author arthuro555
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tools to manipulate the game window positioning and
|
||||
* interactions with the operating system.
|
||||
* @namespace
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow = {
|
||||
/**
|
||||
* The game's BrowserWindow instance (or null on
|
||||
* non-electron platforms).
|
||||
* @type {?Object}
|
||||
*/
|
||||
electronBrowserWindow: null,
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
if (typeof require === 'function') {
|
||||
// @ts-ignore
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow = require('electron').remote.getCurrentWindow();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.focus = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow) {
|
||||
if (activate) {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.focus();
|
||||
} else {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.blur();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isFocused = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isFocused();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.show = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow) {
|
||||
if (activate) {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.showInactive();
|
||||
} else {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isVisible = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isVisible();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.maximize = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow) {
|
||||
if (activate) {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.maximize();
|
||||
} else {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.unmaximize();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isMaximized = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isMaximized();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.minimize = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow) {
|
||||
if (activate) {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.minimize();
|
||||
} else {
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.restore();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isMinimized = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isMinimized();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.enable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setEnabled(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isEnabled = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isEnabled();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setResizable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setResizable(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isResizable = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isResizable();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setMovable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setMovable(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isMovable = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isMovable();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setMaximizable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setMaximizable(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isMaximizable = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isMaximizable();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setMinimizable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setMinimizable(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isMinimizable = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isMinimizable();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setFullScreenable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setFullScreenable(
|
||||
activate
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isFullScreenable = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isFullScreenable();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setClosable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setClosable(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isClosable = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isClosable();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
* @param {"normal" | "floating" | "torn-off-menu" | "modal-panel" |"main-menu" | "status" | "pop-up-menu" | "screen-saver"} level
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setAlwaysOnTop = function (activate, level) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setAlwaysOnTop(
|
||||
activate,
|
||||
level
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isAlwaysOnTop = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isAlwaysOnTop();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setPosition = function (x, y) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow) {
|
||||
// Convert x and y to (32 bit) integers to avoid Electron errors.
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setPosition(~~x, ~~y);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.getPositionX = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow) {
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.getPosition()[0];
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.getPositionY = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow) {
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.getPosition()[1];
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setKiosk = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setKiosk(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.isKiosk = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.isKiosk();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.flash = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.flashFrame(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setHasShadow = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setHasShadow(activate);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.hasShadow = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.hasShadow();
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} opacity
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setOpacity = function (opacity) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setOpacity(opacity);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.getOpacity = function () {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
return gdjs.evtTools.advancedWindow.electronBrowserWindow.getOpacity();
|
||||
return 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setContentProtection = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setContentProtection(
|
||||
activate
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} activate
|
||||
*/
|
||||
gdjs.evtTools.advancedWindow.setFocusable = function (activate) {
|
||||
if (gdjs.evtTools.advancedWindow.electronBrowserWindow)
|
||||
gdjs.evtTools.advancedWindow.electronBrowserWindow.setFocusable(activate);
|
||||
};
|
@@ -18,7 +18,11 @@ gdjs.BBTextRuntimeObjectPixiRenderer = function (runtimeObject, runtimeScene) {
|
||||
.getFontManager()
|
||||
.getFontFamily(runtimeObject._fontFamily),
|
||||
fontSize: runtimeObject._fontSize + 'px',
|
||||
fill: runtimeObject._color,
|
||||
fill: gdjs.rgbToHexNumber(
|
||||
runtimeObject._color[0],
|
||||
runtimeObject._color[1],
|
||||
runtimeObject._color[2]
|
||||
),
|
||||
tagStyle: 'bbcode',
|
||||
wordWrap: runtimeObject._wordWrap,
|
||||
wordWrapWidth: runtimeObject._wrappingWidth,
|
||||
@@ -72,7 +76,11 @@ gdjs.BBTextRuntimeObjectPixiRenderer.prototype.updateText = function () {
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObjectPixiRenderer.prototype.updateColor = function () {
|
||||
this._pixiObject.textStyles.default.fill = this._object._color;
|
||||
this._pixiObject.textStyles.default.fill = gdjs.rgbToHexNumber(
|
||||
this._object._color[0],
|
||||
this._object._color[1],
|
||||
this._object._color[2]
|
||||
);
|
||||
this._pixiObject.dirty = true;
|
||||
};
|
||||
|
||||
|
@@ -8,8 +8,10 @@
|
||||
* @property {string} content.fontFamily The font of the text
|
||||
* @property {number} content.fontSize The size of the text
|
||||
* @property {boolean} content.wordWrap Activate word wrap if set to true
|
||||
* @property {('left'|'center'|'right')} content.align Alignment of the text: "left", "center" or "right"
|
||||
*
|
||||
* @property {'left'|'center'|'right'} content.align Alignment of the text: "left", "center" or "right"
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {ObjectData & BBTextObjectDataType} BBTextObjectData
|
||||
*/
|
||||
|
||||
@@ -29,8 +31,8 @@ gdjs.BBTextRuntimeObject = function(runtimeScene, objectData) {
|
||||
// parseFloat should not be required, but GDevelop 5.0 beta 92 and below were storing it as a string.
|
||||
/** @type {string} */
|
||||
this._text = objectData.content.text;
|
||||
/** @type {string} */
|
||||
this._color = objectData.content.color;
|
||||
/** @type {number[]} color in format [r, g, b], where each component is in the range [0, 255] */
|
||||
this._color = gdjs.BBTextRuntimeObject.hexToRGBColor(objectData.content.color);
|
||||
/** @type {string} */
|
||||
this._fontFamily = objectData.content.fontFamily;
|
||||
/** @type {number} */
|
||||
@@ -61,6 +63,11 @@ gdjs.BBTextRuntimeObject.prototype = Object.create(
|
||||
);
|
||||
gdjs.registerObject('BBText::BBText', gdjs.BBTextRuntimeObject);
|
||||
|
||||
gdjs.BBTextRuntimeObject.hexToRGBColor = function (hex) {
|
||||
var hexNumber = parseInt(hex.replace('#', ''), 16);
|
||||
return [(hexNumber >> 16) & 0xff, (hexNumber >> 8) & 0xff, hexNumber & 0xff];
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObject.prototype.getRendererObject = function() {
|
||||
return this._renderer.getRendererObject();
|
||||
};
|
||||
@@ -80,7 +87,7 @@ gdjs.BBTextRuntimeObject.prototype.updateFromObjectData = function(oldObjectData
|
||||
this.setBBText(newObjectData.content.text);
|
||||
}
|
||||
if (oldObjectData.content.color !== newObjectData.content.color) {
|
||||
this._color = newObjectData.content.color;
|
||||
this._color = gdjs.BBTextRuntimeObject.hexToRGBColor(newObjectData.content.color);
|
||||
this._renderer.updateColor();
|
||||
}
|
||||
if (oldObjectData.content.fontFamily !== newObjectData.content.fontFamily) {
|
||||
@@ -132,19 +139,19 @@ gdjs.BBTextRuntimeObject.prototype.getBBText = function() {
|
||||
gdjs.BBTextRuntimeObject.prototype.setColor = function(rgbColorString) {
|
||||
const splitValue = rgbColorString.split(';');
|
||||
if (splitValue.length !== 3) return;
|
||||
const hexColor =
|
||||
'#' +
|
||||
gdjs.rgbToHex(
|
||||
parseInt(splitValue[0], 0),
|
||||
parseInt(splitValue[1], 0),
|
||||
parseInt(splitValue[2], 0)
|
||||
);
|
||||
this._color = hexColor;
|
||||
|
||||
this._color[0] = parseInt(splitValue[0], 10);
|
||||
this._color[1] = parseInt(splitValue[1], 10);
|
||||
this._color[2] = parseInt(splitValue[2], 10);
|
||||
this._renderer.updateColor();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the base color.
|
||||
* @return {string} The color as a "R;G;B" string, for example: "255;0;0"
|
||||
*/
|
||||
gdjs.BBTextRuntimeObject.prototype.getColor = function() {
|
||||
return this._color;
|
||||
return this._color[0] + ";" + this._color[1] + ";" + this._color[2];
|
||||
};
|
||||
|
||||
gdjs.BBTextRuntimeObject.prototype.setFontSize = function(fontSize) {
|
||||
|
@@ -20,7 +20,10 @@ import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsEx
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
createExtension: function(_/*: (string) => string */, gd/*: libGDevelop */) {
|
||||
createExtension: function (
|
||||
_ /*: (string) => string */,
|
||||
gd /*: libGDevelop */
|
||||
) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension
|
||||
.setExtensionInformation(
|
||||
@@ -305,7 +308,9 @@ module.exports = {
|
||||
.addAction(
|
||||
'DeleteFileAsync',
|
||||
_('Delete a file (Async)'),
|
||||
_('Delete a file from the filesystem asynchronously. The option result variable will be updated once the file is deleted.'),
|
||||
_(
|
||||
'Delete a file from the filesystem asynchronously. The option result variable will be updated once the file is deleted.'
|
||||
),
|
||||
_('Delete the file _PARAM0_'),
|
||||
_('Filesystem/Windows, Linux, MacOS/Asynchronous'),
|
||||
'JsPlatform/Extensions/filesystem_delete_file24.png',
|
||||
@@ -366,8 +371,8 @@ module.exports = {
|
||||
extension
|
||||
.addStrExpression(
|
||||
'ExecutablePath',
|
||||
_('This games executable folder'),
|
||||
_('Get the path to this games executable folder.'),
|
||||
_('Game executable file'),
|
||||
_('Get the path to this game executable file.'),
|
||||
_('Filesystem/Windows, Linux, MacOS'),
|
||||
'JsPlatform/Extensions/filesystem_folder32.png'
|
||||
)
|
||||
@@ -376,11 +381,24 @@ module.exports = {
|
||||
.setIncludeFile('Extensions/FileSystem/filesystemtools.js')
|
||||
.setFunctionName('gdjs.fileSystem.getExecutablePath');
|
||||
|
||||
extension
|
||||
.addStrExpression(
|
||||
'ExecutableFolderPath',
|
||||
_('Game executable folder'),
|
||||
_('Get the path to this game executable folder.'),
|
||||
_('Filesystem/Windows, Linux, MacOS'),
|
||||
'JsPlatform/Extensions/filesystem_folder32.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/FileSystem/filesystemtools.js')
|
||||
.setFunctionName('gdjs.fileSystem.getExecutableFolderPath');
|
||||
|
||||
extension
|
||||
.addStrExpression(
|
||||
'UserdataPath',
|
||||
_('Userdata folder (For application settings)'),
|
||||
_('Get the path to userdata folder. (For application settings)'),
|
||||
_('Userdata folder (for application settings)'),
|
||||
_('Get the path to userdata folder (for application settings).'),
|
||||
_('Filesystem/Windows, Linux, MacOS'),
|
||||
'JsPlatform/Extensions/filesystem_folder32.png'
|
||||
)
|
||||
@@ -392,7 +410,7 @@ module.exports = {
|
||||
extension
|
||||
.addStrExpression(
|
||||
'UserHomePath',
|
||||
_('User\'s Home folder'),
|
||||
_("User's Home folder"),
|
||||
_('Get the path to the user home folder.'),
|
||||
_('Filesystem/Windows, Linux, MacOS'),
|
||||
'JsPlatform/Extensions/filesystem_folder32.png'
|
||||
@@ -418,7 +436,7 @@ module.exports = {
|
||||
.addStrExpression(
|
||||
'PathDelimiter',
|
||||
_('Path delimiter'),
|
||||
_('Get the operating system agnostic path delimiter.'),
|
||||
_('Get the operating system path delimiter.'),
|
||||
_('Filesystem/Windows, Linux, MacOS'),
|
||||
'JsPlatform/Extensions/filesystem_folder32.png'
|
||||
)
|
||||
@@ -426,9 +444,55 @@ module.exports = {
|
||||
.setIncludeFile('Extensions/FileSystem/filesystemtools.js')
|
||||
.setFunctionName('gdjs.fileSystem.getPathDelimiter');
|
||||
|
||||
extension
|
||||
.addStrExpression(
|
||||
'DirectoryName',
|
||||
_('Get directory name from a path'),
|
||||
_(
|
||||
'Returns the portion of the path that represents the directories, without the ending file name.'
|
||||
),
|
||||
_('Filesystem/Windows, Linux, MacOS'),
|
||||
'JsPlatform/Extensions/filesystem_folder32.png'
|
||||
)
|
||||
.addParameter('string', _('File or folder path'), '', false)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/FileSystem/filesystemtools.js')
|
||||
.setFunctionName('gdjs.fileSystem.getDirectoryName');
|
||||
|
||||
extension
|
||||
.addStrExpression(
|
||||
'FileName',
|
||||
_('Get file name from a path'),
|
||||
_('Returns the name of the file with its extension, if any.'),
|
||||
_('Filesystem/Windows, Linux, MacOS'),
|
||||
'JsPlatform/Extensions/filesystem_folder32.png'
|
||||
)
|
||||
.addParameter('string', _('File path'), '', false)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/FileSystem/filesystemtools.js')
|
||||
.setFunctionName('gdjs.fileSystem.getFileName');
|
||||
|
||||
extension
|
||||
.addStrExpression(
|
||||
'ExtensionName',
|
||||
_('Get the extension from a file path'),
|
||||
_(
|
||||
'Returns the extension of the file designated by the given path, including the extension period. For example: ".txt".'
|
||||
),
|
||||
_('Filesystem/Windows, Linux, MacOS'),
|
||||
'JsPlatform/Extensions/filesystem_folder32.png'
|
||||
)
|
||||
.addParameter('string', _('File path'), '', false)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/FileSystem/filesystemtools.js')
|
||||
.setFunctionName('gdjs.fileSystem.getExtensionName');
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function(gd /*: libGDevelop */, extension /*: gdPlatformExtension*/) {
|
||||
runExtensionSanityTests: function (
|
||||
gd /*: libGDevelop */,
|
||||
extension /*: gdPlatformExtension*/
|
||||
) {
|
||||
return [];
|
||||
},
|
||||
};
|
||||
|
@@ -1,11 +1,58 @@
|
||||
// @ts-check
|
||||
/**
|
||||
* @memberof gdjs
|
||||
* @class fileSystem
|
||||
* @static
|
||||
* @namespace fileSystem
|
||||
* @private
|
||||
*/
|
||||
|
||||
gdjs.fileSystem = {};
|
||||
gdjs.fileSystem = {
|
||||
_path: null, // The Node.js path module, or null if it can't be loaded.
|
||||
_fs: null, // The Node.js fs module, or null if it can't be loaded.
|
||||
};
|
||||
|
||||
/** Get the Node.js path module, or null if it can't be loaded */
|
||||
gdjs.fileSystem._getPath = function() {
|
||||
if (!gdjs.fileSystem._path) {
|
||||
// @ts-ignore
|
||||
gdjs.fileSystem._path = typeof require !== 'undefined' ? require('path') : null;
|
||||
}
|
||||
|
||||
return gdjs.fileSystem._path;
|
||||
}
|
||||
|
||||
/** Get the Node.js fs module, or null if it can't be loaded */
|
||||
gdjs.fileSystem._getFs = function() {
|
||||
if (!gdjs.fileSystem._fs) {
|
||||
// @ts-ignore
|
||||
gdjs.fileSystem._fs = typeof require !== 'undefined' ? require('fs') : null;
|
||||
}
|
||||
|
||||
return gdjs.fileSystem._fs;
|
||||
}
|
||||
|
||||
/** @param {string} fileOrFolderPath */
|
||||
gdjs.fileSystem.getDirectoryName = function(fileOrFolderPath) {
|
||||
const path = gdjs.fileSystem._getPath();
|
||||
if (!path) return '';
|
||||
|
||||
return path.dirname(fileOrFolderPath);
|
||||
}
|
||||
|
||||
/** @param {string} filePath */
|
||||
gdjs.fileSystem.getFileName = function(filePath) {
|
||||
const path = gdjs.fileSystem._getPath();
|
||||
if (!path) return '';
|
||||
|
||||
return path.basename(filePath);
|
||||
}
|
||||
|
||||
/** @param {string} filePath */
|
||||
gdjs.fileSystem.getExtensionName = function(filePath) {
|
||||
const path = gdjs.fileSystem._getPath();
|
||||
if (!path) return '';
|
||||
|
||||
return path.extname(filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path to 'Desktop' folder.
|
||||
@@ -62,9 +109,9 @@ gdjs.fileSystem.getPicturesPath = function(runtimeScene) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the path to this application 'Executable' folder.
|
||||
* Get the path to this application 'Executable' file.
|
||||
* @param {gdjs.RuntimeScene} runtimeScene The current scene
|
||||
* @return {string} The path to this applications executable folder
|
||||
* @return {string} The path to this applications executable file
|
||||
*/
|
||||
gdjs.fileSystem.getExecutablePath = function(runtimeScene) {
|
||||
const electron = runtimeScene
|
||||
@@ -79,6 +126,22 @@ gdjs.fileSystem.getExecutablePath = function(runtimeScene) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the path to this application 'Executable' folder.
|
||||
* @param {gdjs.RuntimeScene} runtimeScene The current scene
|
||||
* @return {string} The path to this applications executable folder
|
||||
*/
|
||||
gdjs.fileSystem.getExecutableFolderPath = function(runtimeScene) {
|
||||
const path = gdjs.fileSystem._getPath();
|
||||
const executablePath = gdjs.fileSystem.getExecutablePath(runtimeScene);
|
||||
|
||||
if (!path) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return path.dirname(executablePath);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the path to 'UserData' folder.
|
||||
* @param {gdjs.RuntimeScene} runtimeScene The current scene
|
||||
@@ -101,7 +164,7 @@ gdjs.fileSystem.getUserdataPath = function(runtimeScene) {
|
||||
* Get the path to the user's home folder (on Windows `C:\Users\<USERNAME>\` for example).
|
||||
* @return {string} The path to user's "home" folder
|
||||
*/
|
||||
gdjs.fileSystem.getUserHomePath = function() {
|
||||
gdjs.fileSystem.getUserHomePath = function(runtimeScene) {
|
||||
const electron = runtimeScene
|
||||
.getGame()
|
||||
.getRenderer()
|
||||
@@ -137,7 +200,7 @@ gdjs.fileSystem.getTempPath = function(runtimeScene) {
|
||||
* @return {string} The path delimiter
|
||||
*/
|
||||
gdjs.fileSystem.getPathDelimiter = function() {
|
||||
const path = typeof require !== 'undefined' ? require('path') : null;
|
||||
const path = gdjs.fileSystem._getPath();
|
||||
|
||||
if (path) {
|
||||
return path.sep || '/';
|
||||
@@ -152,7 +215,7 @@ gdjs.fileSystem.getPathDelimiter = function() {
|
||||
* @param {gdjs.Variable} resultVar The variable where to store the result of the operation
|
||||
*/
|
||||
gdjs.fileSystem.makeDirectory = function(directory, resultVar) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
let result = 'error';
|
||||
|
||||
if (fileSystem) {
|
||||
@@ -176,7 +239,7 @@ gdjs.fileSystem.makeDirectory = function(directory, resultVar) {
|
||||
* @param {gdjs.Variable} resultVar The variable where to store the result of the operation
|
||||
*/
|
||||
gdjs.fileSystem.saveStringToFileAsync = function(text, savePath, resultVar) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
|
||||
if (fileSystem) {
|
||||
fileSystem.writeFile(savePath, text, 'utf8', err => {
|
||||
@@ -199,7 +262,7 @@ gdjs.fileSystem.saveStringToFileAsync = function(text, savePath, resultVar) {
|
||||
* @param {gdjs.Variable} resultVar The variable where to store the result of the operation
|
||||
*/
|
||||
gdjs.fileSystem.saveStringToFile = function(text, savePath, resultVar) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
let result = 'error';
|
||||
|
||||
if (fileSystem) {
|
||||
@@ -227,7 +290,7 @@ gdjs.fileSystem.saveVariableToJSONFile = function(
|
||||
savePath,
|
||||
resultVar
|
||||
) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
const network = gdjs.evtTools.network;
|
||||
let result = 'error';
|
||||
|
||||
@@ -251,7 +314,7 @@ gdjs.fileSystem.saveVariableToJSONFile = function(
|
||||
|
||||
/**
|
||||
* Save a variable into a file in JSON format, asynchronously.
|
||||
* @param {string} text The variable to be saved
|
||||
* @param {gdjs.Variable} variable The variable to be saved
|
||||
* @param {string} savePath Path to the file
|
||||
* @param {gdjs.Variable} resultVar The variable where to store the result of the operation
|
||||
*/
|
||||
@@ -260,7 +323,7 @@ gdjs.fileSystem.saveVariableToJSONFileAsync = function(
|
||||
savePath,
|
||||
resultVar
|
||||
) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
const network = gdjs.evtTools.network;
|
||||
|
||||
if (fileSystem && network) {
|
||||
@@ -289,7 +352,7 @@ gdjs.fileSystem.saveVariableToJSONFileAsync = function(
|
||||
* @param {gdjs.Variable} resultVar The variable where to store the result of the operation
|
||||
*/
|
||||
gdjs.fileSystem.loadStringFromFile = function(stringVar, loadPath, resultVar) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
let result = 'error';
|
||||
|
||||
if (fileSystem) {
|
||||
@@ -321,7 +384,7 @@ gdjs.fileSystem.loadVariableFromJSONFile = function(
|
||||
loadPath,
|
||||
resultVar
|
||||
) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
const network = gdjs.evtTools.network;
|
||||
let result = 'error';
|
||||
|
||||
@@ -353,7 +416,7 @@ gdjs.fileSystem.loadVariableFromJSONFileAsync = function(
|
||||
loadPath,
|
||||
resultVar
|
||||
) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
const network = gdjs.evtTools.network;
|
||||
|
||||
if (fileSystem && network) {
|
||||
@@ -384,7 +447,7 @@ gdjs.fileSystem.loadStringFromFileAsync = function(
|
||||
loadPath,
|
||||
resultVar
|
||||
) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
|
||||
if (fileSystem) {
|
||||
fileSystem.readFile(loadPath, 'utf8', (err, data) => {
|
||||
@@ -409,7 +472,7 @@ gdjs.fileSystem.loadStringFromFileAsync = function(
|
||||
* @param {gdjs.Variable} resultVar The variable where to store the result of the operation
|
||||
*/
|
||||
gdjs.fileSystem.deleteFile = function(filePath, resultVar) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
let result = 'error';
|
||||
|
||||
if (fileSystem) {
|
||||
@@ -430,7 +493,7 @@ gdjs.fileSystem.deleteFile = function(filePath, resultVar) {
|
||||
* @param {gdjs.Variable} resultVar The variable where to store the result of the operation
|
||||
*/
|
||||
gdjs.fileSystem.deleteFileAsync = function(filePath, resultVar) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
|
||||
if (fileSystem) {
|
||||
fileSystem.unlink(filePath, err => {
|
||||
@@ -449,7 +512,7 @@ gdjs.fileSystem.deleteFileAsync = function(filePath, resultVar) {
|
||||
* @return {boolean} true if fhe file or directory exists
|
||||
*/
|
||||
gdjs.fileSystem.pathExists = function(filePath) {
|
||||
const fileSystem = typeof require !== 'undefined' ? require('fs') : null;
|
||||
const fileSystem = gdjs.fileSystem._getFs();
|
||||
|
||||
if (fileSystem) {
|
||||
return fileSystem.existsSync(filePath);
|
||||
|
56
Extensions/Firebase/A_utils/A_UIDArray.js
Normal file
56
Extensions/Firebase/A_utils/A_UIDArray.js
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Firebase Tools Collection
|
||||
* @fileoverview
|
||||
* @author arthuro555
|
||||
*/
|
||||
|
||||
/**
|
||||
* A special array where push tries to reuse old unused indices.
|
||||
* Why? This is for storing UIDs. You can see this as a sort of memory optimization:
|
||||
* Each time an object is removed, it is replaced with null in the array.
|
||||
* Then a new object can reuse that emplacement when pushing, instead of adding an element
|
||||
* to the array. Technically the push function is not really pushing anymore,
|
||||
* but the name is kept to make it easier for new devs to use (almost same API as classic array).
|
||||
* @class
|
||||
*/
|
||||
gdjs.UIDArray = function () {
|
||||
/**
|
||||
* The internal array of UIDs.
|
||||
* @type {Array<any>}
|
||||
* @private
|
||||
*/
|
||||
this._array = [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds an object to the UIDs array and returns it's UID.
|
||||
* @param {any} item - The item to assign a UID to.
|
||||
* @returns {number} - The new UID of the object.
|
||||
*/
|
||||
gdjs.UIDArray.prototype.push = function (item) {
|
||||
for (let i in this._array) {
|
||||
if (this._array[i] === null) {
|
||||
this._array[i] = item;
|
||||
return parseInt(i);
|
||||
}
|
||||
}
|
||||
return this._array.push(item) - 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes an element from the UIDs array by UID.
|
||||
* @param {number} uid - The UID of the object to remove.
|
||||
*/
|
||||
gdjs.UIDArray.prototype.remove = function (uid) {
|
||||
if (uid >= this._array.length) return; // Don't pollute the array with unecessary nulls.
|
||||
this._array[uid] = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an element from the UIDs array by UID.
|
||||
* @param {number} uid - The UID of the object to get.
|
||||
*/
|
||||
gdjs.UIDArray.prototype.get = function (uid) {
|
||||
if (uid >= this._array.length) return null; // Prevent out of range getting.
|
||||
return this._array[uid];
|
||||
};
|
1
Extensions/Firebase/B_firebasejs/A_firebase-base.js
Normal file
1
Extensions/Firebase/B_firebasejs/A_firebase-base.js
Normal file
File diff suppressed because one or more lines are too long
1
Extensions/Firebase/B_firebasejs/B_firebase-analytics.js
Normal file
1
Extensions/Firebase/B_firebasejs/B_firebase-analytics.js
Normal file
File diff suppressed because one or more lines are too long
1
Extensions/Firebase/B_firebasejs/B_firebase-auth.js
Normal file
1
Extensions/Firebase/B_firebasejs/B_firebase-auth.js
Normal file
File diff suppressed because one or more lines are too long
1
Extensions/Firebase/B_firebasejs/B_firebase-database.js
Normal file
1
Extensions/Firebase/B_firebasejs/B_firebase-database.js
Normal file
File diff suppressed because one or more lines are too long
1
Extensions/Firebase/B_firebasejs/B_firebase-firestore.js
Normal file
1
Extensions/Firebase/B_firebasejs/B_firebase-firestore.js
Normal file
File diff suppressed because one or more lines are too long
1
Extensions/Firebase/B_firebasejs/B_firebase-functions.js
Normal file
1
Extensions/Firebase/B_firebasejs/B_firebase-functions.js
Normal file
File diff suppressed because one or more lines are too long
1
Extensions/Firebase/B_firebasejs/B_firebase-messaging.js
Normal file
1
Extensions/Firebase/B_firebasejs/B_firebase-messaging.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
Extensions/Firebase/B_firebasejs/B_firebase-storage.js
Normal file
1
Extensions/Firebase/B_firebasejs/B_firebase-storage.js
Normal file
File diff suppressed because one or more lines are too long
0
GDJS/docs/jaguarjs-jsdoc/static/scripts/prettify/Apache-License-2.0.txt → Extensions/Firebase/B_firebasejs/LICENSE.txt
Executable file → Normal file
0
GDJS/docs/jaguarjs-jsdoc/static/scripts/prettify/Apache-License-2.0.txt → Extensions/Firebase/B_firebasejs/LICENSE.txt
Executable file → Normal file
4
Extensions/Firebase/B_firebasejs/NOTICE.txt
Normal file
4
Extensions/Firebase/B_firebasejs/NOTICE.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
This is a modified version of the firebase js sdk. Original can be found on https://github.com/firebase/firebase-js-sdk .
|
||||
The version used is 7.20.0.
|
||||
Changelist:
|
||||
Removed links to sourcemaps.
|
30
Extensions/Firebase/C_firebasetools/C_firebasetools.js
Normal file
30
Extensions/Firebase/C_firebasetools/C_firebasetools.js
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Firebase Tools Collection
|
||||
* @fileoverview
|
||||
* @author arthuro555
|
||||
*/
|
||||
|
||||
/**
|
||||
* Firebase Event Tools
|
||||
* @namespace
|
||||
*/
|
||||
gdjs.evtTools.firebase = {};
|
||||
|
||||
/**
|
||||
* An array of callbacks to call when the app gets initialized.
|
||||
*/
|
||||
gdjs.evtTools.firebase.onAppCreated = [];
|
||||
|
||||
gdjs.registerFirstRuntimeSceneLoadedCallback(function (runtimeScene) {
|
||||
let firebaseConfig;
|
||||
try {
|
||||
firebaseConfig = JSON.parse(
|
||||
runtimeScene.getGame().getExtensionProperty('Firebase', 'FirebaseConfig')
|
||||
);
|
||||
} catch (e) {
|
||||
console.error('The Firebase configuration is invalid! Error: ' + e);
|
||||
return;
|
||||
}
|
||||
firebase.initializeApp(firebaseConfig);
|
||||
for (let func of gdjs.evtTools.firebase.onAppCreated) func();
|
||||
});
|
71
Extensions/Firebase/C_firebasetools/D_analyticstools.js
Normal file
71
Extensions/Firebase/C_firebasetools/D_analyticstools.js
Normal file
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Firebase Tools Collection
|
||||
* @fileoverview
|
||||
* @author arthuro555
|
||||
*/
|
||||
|
||||
/**
|
||||
* Firebase Analytics Tools
|
||||
* @namespace
|
||||
*/
|
||||
gdjs.evtTools.firebase.analytics = {};
|
||||
|
||||
/**
|
||||
* Logs an event/conversion for that user on the analytics.
|
||||
* @param {string} eventName The event being triggered.
|
||||
* @param {string | Object} [eventData] Additional data for the event.
|
||||
*/
|
||||
gdjs.evtTools.firebase.analytics.log = function (eventName, eventData) {
|
||||
let analytics = gdjs.evtTools.firebase.analytics._analyticsInstance;
|
||||
let eventProperties;
|
||||
if (eventData) {
|
||||
try {
|
||||
eventProperties = JSON.parse(eventData);
|
||||
} catch {
|
||||
eventProperties = { eventData: eventData };
|
||||
}
|
||||
}
|
||||
analytics.logEvent(eventName, eventProperties);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the User ID (the name under wich the user will appear on the analytics).
|
||||
* Should be unique if possible.
|
||||
* @param {string | number} newUID The new User ID.
|
||||
*/
|
||||
gdjs.evtTools.firebase.analytics.setUserID = function (newUID) {
|
||||
let analytics = gdjs.evtTools.firebase.analytics._analyticsInstance;
|
||||
analytics.setUserId(newUID);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set an user's property.
|
||||
* @param {string} propertyName The property's name.
|
||||
* @param {string | Object} [propertyData] The data associated to the property.
|
||||
*/
|
||||
gdjs.evtTools.firebase.analytics.setProperty = function (
|
||||
propertyName,
|
||||
propertyData
|
||||
) {
|
||||
let analytics = gdjs.evtTools.firebase.analytics._analyticsInstance;
|
||||
let properties = {};
|
||||
try {
|
||||
properties[propertyName] = JSON.parse(propertyData);
|
||||
} catch {
|
||||
properties[propertyName] = propertyData;
|
||||
}
|
||||
analytics.setUserProperties(properties);
|
||||
};
|
||||
|
||||
// Initialization step required by firebase analytics
|
||||
gdjs.registerFirstRuntimeSceneLoadedCallback(function () {
|
||||
gdjs.evtTools.firebase.analytics._analyticsInstance = firebase.analytics();
|
||||
});
|
||||
|
||||
// Callback for setting the analytics current view to the current scene.
|
||||
gdjs.registerRuntimeSceneLoadedCallback(function (runtimeScene) {
|
||||
if (gdjs.evtTools.firebase.analytics._analyticsInstance)
|
||||
gdjs.evtTools.firebase.analytics._analyticsInstance.setCurrentScreen(
|
||||
runtimeScene.getName()
|
||||
);
|
||||
});
|
463
Extensions/Firebase/C_firebasetools/D_authtools.js
Normal file
463
Extensions/Firebase/C_firebasetools/D_authtools.js
Normal file
@@ -0,0 +1,463 @@
|
||||
/**
|
||||
* Firebase Tools Collection.
|
||||
* @fileoverview
|
||||
* @author arthuro555
|
||||
*/
|
||||
|
||||
/**
|
||||
* Firebase Authentication Event Tools.
|
||||
* @namespace
|
||||
*/
|
||||
gdjs.evtTools.firebase.auth = {
|
||||
/**
|
||||
* Table of available external providers.
|
||||
*/
|
||||
providersList: {
|
||||
google: firebase.auth.GoogleAuthProvider,
|
||||
facebook: firebase.auth.FacebookAuthProvider,
|
||||
github: firebase.auth.GithubAuthProvider,
|
||||
twitter: firebase.auth.TwitterAuthProvider,
|
||||
},
|
||||
|
||||
/**
|
||||
* The current authentication status.
|
||||
* @type {boolean}
|
||||
*/
|
||||
authentified: false,
|
||||
|
||||
/**
|
||||
* The logged-in users data.
|
||||
* @type {firebase.User}
|
||||
*/
|
||||
currentUser: null,
|
||||
|
||||
/**
|
||||
* The actual current token.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
_token: '',
|
||||
|
||||
/**
|
||||
* The current auth provider for reauthenticating.
|
||||
* @type {firebase.auth.AuthProvider}
|
||||
* @private
|
||||
*/
|
||||
_currentProvider: null,
|
||||
};
|
||||
|
||||
/**
|
||||
* A namespace containing tools for managing the current user.
|
||||
* @namespace
|
||||
*/
|
||||
gdjs.evtTools.firebase.auth.userManagement = {
|
||||
/**
|
||||
* Contains dangerous management functions. Requires reauthentication before usage.
|
||||
* @namespace
|
||||
*/
|
||||
dangerous: {
|
||||
/**
|
||||
* Changes the users email.
|
||||
* Use this when using basic auth.
|
||||
* @param {string} oldEmail - Old email for reauthentication.
|
||||
* @param {string} password - Old password for reauthentication.
|
||||
* @param {string} newEmail - New email for the user.
|
||||
* @param {boolean} [sendVerificationEmail] - Send a verification email to the old address before changing the email?
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store the result.
|
||||
*/
|
||||
changeEmail(
|
||||
oldEmail,
|
||||
password,
|
||||
newEmail,
|
||||
sendVerificationEmail,
|
||||
callbackStateVariable
|
||||
) {
|
||||
sendVerificationEmail = sendVerificationEmail || true;
|
||||
|
||||
let credential = firebase.auth.EmailAuthProvider.credential(
|
||||
oldEmail,
|
||||
password
|
||||
);
|
||||
let updater = sendVerificationEmail
|
||||
? gdjs.evtTools.firebase.auth.currentUser.updateEmail
|
||||
: gdjs.evtTools.firebase.auth.currentUser.verifyBeforeUpdateEmail;
|
||||
|
||||
gdjs.evtTools.firebase.auth.currentUser
|
||||
.reauthenticateWithCredential(credential)
|
||||
.then(() => updater(newEmail))
|
||||
.then(() => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch((error) => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the users password.
|
||||
* Use this when using basic auth.
|
||||
* @param {string} email - Old email for reauthentication.
|
||||
* @param {string} oldPassword - Old password for reauthentication.
|
||||
* @param {string} newPassword - New password for the user.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store the result.
|
||||
*/
|
||||
changePassword(email, oldPassword, newPassword, callbackStateVariable) {
|
||||
let credential = firebase.auth.EmailAuthProvider.credential(
|
||||
email,
|
||||
oldPassword
|
||||
);
|
||||
gdjs.evtTools.firebase.auth.currentUser
|
||||
.reauthenticateWithCredential(credential)
|
||||
.then(() =>
|
||||
gdjs.evtTools.firebase.auth.currentUser.updatePassword(newPassword)
|
||||
)
|
||||
.then(() => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch((error) => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Deletes the current user.
|
||||
* Use this when using basic auth.
|
||||
* @param {string} email - Old email for reauthentication.
|
||||
* @param {string} password - Old password for reauthentication.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store the result.
|
||||
*/
|
||||
deleteUser(email, password, callbackStateVariable) {
|
||||
let credential = firebase.auth.EmailAuthProvider.credential(
|
||||
email,
|
||||
password
|
||||
);
|
||||
gdjs.evtTools.firebase.auth.currentUser
|
||||
.reauthenticateWithCredential(credential)
|
||||
.then(() => gdjs.evtTools.firebase.auth.currentUser.delete())
|
||||
.then(() => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch((error) => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the users email.
|
||||
* Use this when using an external provider.
|
||||
* @param {string} newEmail - New email for the user.
|
||||
* @param {boolean} sendVerificationEmail - Send a verification email to the old address before changing the email?
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store the result.
|
||||
*/
|
||||
changeEmailProvider(
|
||||
newEmail,
|
||||
sendVerificationEmail,
|
||||
callbackStateVariable
|
||||
) {
|
||||
let updater = sendVerificationEmail
|
||||
? gdjs.evtTools.firebase.auth.currentUser.updateEmail
|
||||
: gdjs.evtTools.firebase.auth.currentUser.verifyBeforeUpdateEmail;
|
||||
|
||||
gdjs.evtTools.firebase.auth.currentUser
|
||||
.reauthenticateWithPopup(gdjs.evtTools.firebase.auth._currentProvider)
|
||||
.then(() => updater(newEmail))
|
||||
.then(() => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch((error) => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the users password.
|
||||
* Use this when using an external provider.
|
||||
* @param {string} newPassword - New password for the user.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store the result.
|
||||
*/
|
||||
changePasswordProvider(newPassword, callbackStateVariable) {
|
||||
gdjs.evtTools.firebase.auth.currentUser
|
||||
.reauthenticateWithPopup(gdjs.evtTools.firebase.auth._currentProvider)
|
||||
.then(() =>
|
||||
gdjs.evtTools.firebase.auth.currentUser.updatePassword(newPassword)
|
||||
)
|
||||
.then(() => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch((error) => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Deletes the current user.
|
||||
* Use this when using an external provider.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store the result.
|
||||
*/
|
||||
deleteUserProvider(callbackStateVariable) {
|
||||
gdjs.evtTools.firebase.auth.currentUser
|
||||
.reauthenticateWithPopup(gdjs.evtTools.firebase.auth._currentProvider)
|
||||
.then(() => gdjs.evtTools.firebase.auth.currentUser.delete())
|
||||
.then(() => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch((error) => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Verifies if the current users email is verified.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isEmailVerified() {
|
||||
return gdjs.evtTools.firebase.auth.currentUser.emailVerified;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the users email address.
|
||||
* @returns {string}
|
||||
*/
|
||||
getEmail() {
|
||||
return gdjs.evtTools.firebase.auth.currentUser.email || '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the creation date of the logged in users account.
|
||||
* @returns {string}
|
||||
*/
|
||||
getCreationTime() {
|
||||
return gdjs.evtTools.firebase.auth.currentUser.metadata.creationTime || '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the last login date of the logged in users account.
|
||||
* @returns {string}
|
||||
*/
|
||||
getLastLoginTime() {
|
||||
return (
|
||||
gdjs.evtTools.firebase.auth.currentUser.metadata.lastSignInTime || ''
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the display name of the current user.
|
||||
* @returns {string}
|
||||
*/
|
||||
getDisplayName() {
|
||||
return gdjs.evtTools.firebase.auth.currentUser.displayName || '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the current users phone number.
|
||||
* @returns {string}
|
||||
*/
|
||||
getPhoneNumber() {
|
||||
return gdjs.evtTools.firebase.auth.currentUser.phoneNumber || '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the current users Unique IDentifier.
|
||||
* @returns {string}
|
||||
*/
|
||||
getUID() {
|
||||
return gdjs.evtTools.firebase.auth.currentUser.uid || '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the tenant ID.
|
||||
* For advanced usage only.
|
||||
* @returns {string}
|
||||
*/
|
||||
getTenantID() {
|
||||
return gdjs.evtTools.firebase.auth.currentUser.tenantId || '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the refresh token.
|
||||
* For advanced usage only.
|
||||
* @returns {string}
|
||||
*/
|
||||
getRefreshToken() {
|
||||
return gdjs.evtTools.firebase.auth.currentUser.refreshToken || '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the users profile picture URL.
|
||||
* @returns {string}
|
||||
*/
|
||||
getPhotoURL() {
|
||||
return gdjs.evtTools.firebase.auth.currentUser.photoURL || '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the display name of an user.
|
||||
* @param {string} newDisplayName
|
||||
*/
|
||||
setDisplayName(newDisplayName) {
|
||||
gdjs.evtTools.firebase.auth.currentUser.updateProfile({
|
||||
displayName: newDisplayName,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the URL to the profile picture of the user.
|
||||
* @param {string} newDisplayName
|
||||
*/
|
||||
setPhotoURL(newPhotoURL) {
|
||||
gdjs.evtTools.firebase.auth.currentUser.updateProfile({
|
||||
photoURL: newPhotoURL,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Send an email to the users email adress to verify it.
|
||||
* @note Even though this function is redundant, we keep it for consistency.
|
||||
* @see gdjs.evtTools.firebase.auth.currentUser.sendEmailVerification
|
||||
*/
|
||||
sendVerificationEmail() {
|
||||
gdjs.evtTools.firebase.auth.currentUser.sendEmailVerification();
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the logged-in users authentication token.
|
||||
* Tries to refresh it everytime the function is called.
|
||||
* @returns {string}
|
||||
*/
|
||||
gdjs.evtTools.firebase.auth.token = function () {
|
||||
this.currentUser
|
||||
.getIdToken()
|
||||
.then((token) => (gdjs.evtTools.firebase.auth._token = token));
|
||||
return this._token;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the user is currently authentified.
|
||||
* @returns {boolean}
|
||||
* @see gdjs.evtTools.firebase.auth.authentified
|
||||
*/
|
||||
gdjs.evtTools.firebase.auth.isAuthentified = function () {
|
||||
return gdjs.evtTools.firebase.auth.authentified;
|
||||
};
|
||||
|
||||
/**
|
||||
* Signs the user in with basic email-password authentication.
|
||||
* @param {string} email - The users email.
|
||||
* @param {string} password - The users password.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store the result.
|
||||
*/
|
||||
gdjs.evtTools.firebase.auth.signInWithEmail = function (
|
||||
email,
|
||||
password,
|
||||
callbackStateVariable
|
||||
) {
|
||||
firebase
|
||||
.auth()
|
||||
.signInWithEmailAndPassword(email, password)
|
||||
.then(() => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch((error) => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an account with basic email-password authentication.
|
||||
* @param {string} email - The users email.
|
||||
* @param {string} password - The users password.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store the result.
|
||||
*/
|
||||
gdjs.evtTools.firebase.auth.createAccountWithEmail = function (
|
||||
email,
|
||||
password,
|
||||
callbackStateVariable
|
||||
) {
|
||||
firebase
|
||||
.auth()
|
||||
.createUserWithEmailAndPassword(email, password)
|
||||
.then(() => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch((error) => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Login with a temporary account.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store the result.
|
||||
*/
|
||||
gdjs.evtTools.firebase.auth.anonymSignIn = function (callbackStateVariable) {
|
||||
firebase
|
||||
.auth()
|
||||
.signInAnonymously()
|
||||
.then(() => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch((error) => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Signs the user in with an external provider.
|
||||
* Only works on the web, NOT on Electron/Cordova.
|
||||
* @param {"google" | "facebook" | "github" | "twitter"} providerName - The external provider to use.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store the result.
|
||||
*/
|
||||
gdjs.evtTools.firebase.auth.signInWithProvider = function (
|
||||
providerName,
|
||||
callbackStateVariable
|
||||
) {
|
||||
let providerCtor = gdjs.evtTools.firebase.auth.providersList[providerName];
|
||||
gdjs.evtTools.firebase.auth._currentProvider = new providerCtor();
|
||||
|
||||
firebase
|
||||
.auth()
|
||||
.signInWithPopup(gdjs.evtTools.firebase.auth._currentProvider)
|
||||
.then(() => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch((error) => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
// Listen to authentication state changes to regenerate tokens and keep the user and the authenticated state up to date
|
||||
gdjs.evtTools.firebase.onAppCreated.push(function () {
|
||||
firebase.auth().onAuthStateChanged(function (user) {
|
||||
if (user) {
|
||||
gdjs.evtTools.firebase.auth.authentified = true;
|
||||
gdjs.evtTools.firebase.auth.currentUser = user;
|
||||
user
|
||||
.getIdToken()
|
||||
.then((token) => (gdjs.evtTools.firebase.auth._token = token)); // Pregenerate the token
|
||||
} else {
|
||||
gdjs.evtTools.firebase.auth.authentified = false;
|
||||
gdjs.evtTools.firebase.auth.currentUser = null;
|
||||
}
|
||||
});
|
||||
});
|
352
Extensions/Firebase/C_firebasetools/D_cloudfirestoretools.js
Normal file
352
Extensions/Firebase/C_firebasetools/D_cloudfirestoretools.js
Normal file
@@ -0,0 +1,352 @@
|
||||
/**
|
||||
* Firebase Tools Collection.
|
||||
* @fileoverview
|
||||
* @author arthuro555
|
||||
*/
|
||||
|
||||
/**
|
||||
* Firebase Cloud Firestore Event Tools.
|
||||
* @namespace
|
||||
*/
|
||||
gdjs.evtTools.firebase.firestore = {};
|
||||
|
||||
/**
|
||||
* Writes a variable in a collection as document.
|
||||
* @param {string} collectionName - The collection where to store the variable.
|
||||
* @param {string} variableName - The name under wich the variable will be saved (document name).
|
||||
* @param {gdjs.Variable} variable - The variable to write.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store the result.
|
||||
*/
|
||||
gdjs.evtTools.firebase.firestore.writeDocument = function (
|
||||
collectionName,
|
||||
variableName,
|
||||
variable,
|
||||
callbackStateVariable
|
||||
) {
|
||||
firebase
|
||||
.firestore()
|
||||
.collection(collectionName)
|
||||
.doc(variableName)
|
||||
.set(JSON.parse(gdjs.evtTools.network.variableStructureToJSON(variable)))
|
||||
.then(function () {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Writes a field of a document.
|
||||
* @param {string} collectionName - The collection where to store the document.
|
||||
* @param {string} documentName - The name of the document where to write a field.
|
||||
* @param {string} field - The field where to write.
|
||||
* @param {string | number} value - The value to write.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store the result.
|
||||
* @param {boolean} [merge] - Should the new field replace the document or be merged with the document?
|
||||
*/
|
||||
gdjs.evtTools.firebase.firestore.writeField = function (
|
||||
collectionName,
|
||||
documentName,
|
||||
field,
|
||||
value,
|
||||
callbackStateVariable,
|
||||
merge
|
||||
) {
|
||||
merge = merge == undefined ? true : merge;
|
||||
const updateObject = {};
|
||||
updateObject[field] = value;
|
||||
firebase
|
||||
.firestore()
|
||||
.collection(collectionName)
|
||||
.doc(documentName)
|
||||
.set(updateObject, { merge: merge })
|
||||
.then(function () {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates a variable/document.
|
||||
* @param {string} collectionName - The collection where the document is stored.
|
||||
* @param {string} variableName - The name under wich the variable will be saved (document name).
|
||||
* @param {gdjs.Variable} variable - The variable to update.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store the result.
|
||||
*/
|
||||
gdjs.evtTools.firebase.firestore.updateDocument = function (
|
||||
collectionName,
|
||||
variableName,
|
||||
variable,
|
||||
callbackStateVariable
|
||||
) {
|
||||
firebase
|
||||
.firestore()
|
||||
.collection(collectionName)
|
||||
.doc(variableName)
|
||||
.update(JSON.parse(gdjs.evtTools.network.variableStructureToJSON(variable)))
|
||||
.then(function () {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates a field of a document.
|
||||
* @param {string} collectionName - The collection where the document is stored.
|
||||
* @param {string} documentName - The name of the document where to update a field.
|
||||
* @param {string} field - The field where to update.
|
||||
* @param {string | number} value - The value to write.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store the result.
|
||||
*/
|
||||
gdjs.evtTools.firebase.firestore.updateField = function (
|
||||
collectionName,
|
||||
documentName,
|
||||
field,
|
||||
value,
|
||||
callbackStateVariable
|
||||
) {
|
||||
const updateObject = {};
|
||||
updateObject[field] = value;
|
||||
firebase
|
||||
.firestore()
|
||||
.collection(collectionName)
|
||||
.doc(documentName)
|
||||
.update(updateObject)
|
||||
.then(function () {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes a document.
|
||||
* @param {string} collectionName - The collection where the document is stored.
|
||||
* @param {string} documentName - The name of the document to delete.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store the result.
|
||||
*/
|
||||
gdjs.evtTools.firebase.firestore.deleteDocument = function (
|
||||
collectionName,
|
||||
documentName,
|
||||
callbackStateVariable
|
||||
) {
|
||||
firebase
|
||||
.firestore()
|
||||
.collection(collectionName)
|
||||
.doc(documentName)
|
||||
.delete()
|
||||
.then(function () {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes a field of a document.
|
||||
* @param {string} collectionName - The collection where the document is stored.
|
||||
* @param {string} documentName - The name of the document where to delete a field.
|
||||
* @param {string} field - The field to delete.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store the result.
|
||||
*/
|
||||
gdjs.evtTools.firebase.firestore.deleteField = function (
|
||||
collectionName,
|
||||
documentName,
|
||||
field,
|
||||
callbackStateVariable
|
||||
) {
|
||||
const updateObject = {};
|
||||
updateObject[field] = firebase.firestore.FieldValue.delete();
|
||||
firebase
|
||||
.firestore()
|
||||
.collection(collectionName)
|
||||
.doc(documentName)
|
||||
.update(updateObject)
|
||||
.then(function () {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a document and store it in a variable.
|
||||
* @param {string} collectionName - The collection where the document is stored.
|
||||
* @param {string} documentName - The name of the document to get.
|
||||
* @param {gdjs.Variable} [callbackValueVariable] - The variable where to store the result.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store if the operation was successful.
|
||||
*/
|
||||
gdjs.evtTools.firebase.firestore.getDocument = function (
|
||||
collectionName,
|
||||
documentName,
|
||||
callbackValueVariable,
|
||||
callbackStateVariable
|
||||
) {
|
||||
firebase
|
||||
.firestore()
|
||||
.collection(collectionName)
|
||||
.doc(documentName)
|
||||
.get()
|
||||
.then(function (doc) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
if (callbackValueVariable)
|
||||
gdjs.evtTools.network._objectToVariable(
|
||||
doc.data(),
|
||||
callbackValueVariable
|
||||
);
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a field of a document and store it in a variable.
|
||||
* @param {string} collectionName - The collection where the document is stored.
|
||||
* @param {string} documentName - The name of the document.
|
||||
* @param {string} field - The field to get.
|
||||
* @param {gdjs.Variable} [callbackValueVariable] - The variable where to store the result.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store if the operation was successful.
|
||||
*/
|
||||
gdjs.evtTools.firebase.firestore.getField = function (
|
||||
collectionName,
|
||||
documentName,
|
||||
field,
|
||||
callbackValueVariable,
|
||||
callbackStateVariable
|
||||
) {
|
||||
firebase
|
||||
.firestore()
|
||||
.collection(collectionName)
|
||||
.doc(documentName)
|
||||
.get()
|
||||
.then(function (doc) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
if (callbackValueVariable)
|
||||
gdjs.evtTools.network._objectToVariable(
|
||||
doc.get(field),
|
||||
callbackValueVariable
|
||||
);
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks for existence of a document.
|
||||
* @param {string} collectionName - The collection where the document is stored.
|
||||
* @param {string} documentName - The name of the document to check.
|
||||
* @param {gdjs.Variable} [callbackValueVariable] - The variable where to store the result.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store if the operation was successful.
|
||||
*/
|
||||
gdjs.evtTools.firebase.firestore.hasDocument = function (
|
||||
collectionName,
|
||||
documentName,
|
||||
callbackValueVariable,
|
||||
callbackStateVariable
|
||||
) {
|
||||
firebase
|
||||
.firestore()
|
||||
.collection(collectionName)
|
||||
.doc(documentName)
|
||||
.get()
|
||||
.then(function (doc) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
if (callbackValueVariable)
|
||||
callbackValueVariable.setString(doc.exists ? 'true' : 'false');
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks for existence of a field.
|
||||
* @param {string} collectionName - The collection where the document is stored.
|
||||
* @param {string} documentName - The name of the document.
|
||||
* @param {string} field - The field to check.
|
||||
* @param {gdjs.Variable} [callbackValueVariable] - The variable where to store the result.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store if the operation was successful.
|
||||
*/
|
||||
gdjs.evtTools.firebase.firestore.hasField = function (
|
||||
collectionName,
|
||||
documentName,
|
||||
field,
|
||||
callbackValueVariable,
|
||||
callbackStateVariable
|
||||
) {
|
||||
firebase
|
||||
.firestore()
|
||||
.collection(collectionName)
|
||||
.doc(documentName)
|
||||
.get()
|
||||
.then(function (doc) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
if (callbackValueVariable)
|
||||
callbackValueVariable.setString(
|
||||
doc.get(field) === undefined ? 'false' : 'true'
|
||||
);
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Lists all the documents in a collection.
|
||||
* @param {string} collectionName - The collection where to count documents.
|
||||
* @param {gdjs.Variable} [callbackValueVariable] - The variable where to store the result.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store if the operation was successful.
|
||||
*/
|
||||
gdjs.evtTools.firebase.firestore.listDocuments = function (
|
||||
collectionName,
|
||||
callbackValueVariable,
|
||||
callbackStateVariable
|
||||
) {
|
||||
firebase
|
||||
.firestore()
|
||||
.collection(collectionName)
|
||||
.get()
|
||||
.then(function (snapshot) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(snapshot.empty ? 'empty' : 'ok');
|
||||
if (callbackValueVariable)
|
||||
gdjs.evtTools.network._objectToVariable(
|
||||
snapshot.docs.map((doc) => doc.id),
|
||||
callbackValueVariable
|
||||
);
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
294
Extensions/Firebase/C_firebasetools/D_databasetools.js
Normal file
294
Extensions/Firebase/C_firebasetools/D_databasetools.js
Normal file
@@ -0,0 +1,294 @@
|
||||
/**
|
||||
* Firebase Tools Collection.
|
||||
* @fileoverview
|
||||
* @author arthuro555
|
||||
*/
|
||||
|
||||
/**
|
||||
* Firebase Cloud database Event Tools.
|
||||
* @namespace
|
||||
*/
|
||||
gdjs.evtTools.firebase.database = {};
|
||||
|
||||
/**
|
||||
* (Over)writes a variable in a collection as database variable.
|
||||
* @param {string} path - The path where to store the variable.
|
||||
* @param {gdjs.Variable} variable - The variable to write.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store the result.
|
||||
*/
|
||||
gdjs.evtTools.firebase.database.writeVariable = function (
|
||||
path,
|
||||
variable,
|
||||
callbackStateVariable
|
||||
) {
|
||||
firebase
|
||||
.database()
|
||||
.ref(path)
|
||||
.set(JSON.parse(gdjs.evtTools.network.variableStructureToJSON(variable)))
|
||||
.then(function () {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* (Over)writes a field of a database variable.
|
||||
* @param {string} path - The path where to write the field.
|
||||
* @param {string} field - What field to write.
|
||||
* @param {string | number} value - The value to write.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store the result.
|
||||
* @param {boolean} [merge] - Should the new field replace the document or be merged with the document?
|
||||
*/
|
||||
gdjs.evtTools.firebase.database.writeField = function (
|
||||
path,
|
||||
field,
|
||||
value,
|
||||
callbackStateVariable
|
||||
) {
|
||||
const newObject = {};
|
||||
newObject[field] = value;
|
||||
firebase
|
||||
.database()
|
||||
.ref(path)
|
||||
.set(newObject)
|
||||
.then(function () {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates a database variable.
|
||||
* @param {string} path - The name under wich the variable will be saved (document name).
|
||||
* @param {gdjs.Variable} variable - The variable to update.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store the result.
|
||||
*/
|
||||
gdjs.evtTools.firebase.database.updateVariable = function (
|
||||
path,
|
||||
variable,
|
||||
callbackStateVariable
|
||||
) {
|
||||
firebase
|
||||
.database()
|
||||
.ref(path)
|
||||
.update(JSON.parse(gdjs.evtTools.network.variableStructureToJSON(variable)))
|
||||
.then(function () {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates a field of a database variable.
|
||||
* @param {string} path - The name under wich the variable will be saved (document name).
|
||||
* @param {string} field - The field where to update.
|
||||
* @param {string | number} value - The value to write.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store the result.
|
||||
*/
|
||||
gdjs.evtTools.firebase.database.updateField = function (
|
||||
path,
|
||||
field,
|
||||
value,
|
||||
callbackStateVariable
|
||||
) {
|
||||
const updateObject = {};
|
||||
updateObject[field] = value;
|
||||
firebase
|
||||
.database()
|
||||
.ref(path)
|
||||
.update(updateObject)
|
||||
.then(function () {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes a database variable.
|
||||
* @param {string} path - The name under wich the variable will be saved (document name).
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store the result.
|
||||
*/
|
||||
gdjs.evtTools.firebase.database.deleteVariable = function (
|
||||
path,
|
||||
callbackStateVariable
|
||||
) {
|
||||
firebase
|
||||
.database()
|
||||
.ref(path)
|
||||
.remove()
|
||||
.then(function () {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes a field of a database variable.
|
||||
* @param {string} path - The name under wich the variable will be saved (document name).
|
||||
* @param {string} field - The field to delete.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store the result.
|
||||
*/
|
||||
gdjs.evtTools.firebase.database.deleteField = function (
|
||||
path,
|
||||
field,
|
||||
callbackStateVariable
|
||||
) {
|
||||
const updateObject = {};
|
||||
updateObject[field] = null;
|
||||
firebase
|
||||
.database()
|
||||
.ref(path)
|
||||
.update(updateObject)
|
||||
.then(function () {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a database variable and store it in a variable.
|
||||
* @param {string} path - The name under wich the variable will be saved (document name).
|
||||
* @param {gdjs.Variable} callbackValueVariable - The variable where to store the result.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store if the operation was successful.
|
||||
*/
|
||||
gdjs.evtTools.firebase.database.getVariable = function (
|
||||
path,
|
||||
callbackValueVariable,
|
||||
callbackStateVariable
|
||||
) {
|
||||
firebase
|
||||
.database()
|
||||
.ref(path)
|
||||
.once('value')
|
||||
.then(function (snapshot) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
if (typeof callbackValueVariable !== 'undefined')
|
||||
gdjs.evtTools.network._objectToVariable(
|
||||
snapshot.val(),
|
||||
callbackValueVariable
|
||||
);
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a field of a database variable and store it in a variable.
|
||||
* @param {string} path - The name under wich the variable will be saved (document name).
|
||||
* @param {string} field - The field to get.
|
||||
* @param {gdjs.Variable} callbackValueVariable - The variable where to store the result.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store if the operation was successful.
|
||||
*/
|
||||
gdjs.evtTools.firebase.database.getField = function (
|
||||
path,
|
||||
field,
|
||||
callbackValueVariable,
|
||||
callbackStateVariable
|
||||
) {
|
||||
firebase
|
||||
.database()
|
||||
.ref(path)
|
||||
.once('value')
|
||||
.then(function (snapshot) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
if (typeof callbackValueVariable !== 'undefined')
|
||||
gdjs.evtTools.network._objectToVariable(
|
||||
snapshot.val()[field],
|
||||
callbackValueVariable
|
||||
);
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks for existence of a database variable.
|
||||
* @param {string} path - The name under wich the variable will be saved (document name).
|
||||
* @param {gdjs.Variable} callbackValueVariable - The variable where to store the result.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store if the operation was successful.
|
||||
*/
|
||||
gdjs.evtTools.firebase.database.hasVariable = function (
|
||||
path,
|
||||
callbackValueVariable,
|
||||
callbackStateVariable
|
||||
) {
|
||||
firebase
|
||||
.database()
|
||||
.ref(path)
|
||||
.once('value')
|
||||
.then(function (snapshot) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
if (typeof callbackValueVariable !== 'undefined')
|
||||
callbackValueVariable.setString(
|
||||
snapshot.exists() && snapshot.val() !== null ? 'true' : 'false'
|
||||
);
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks for existence of a database variable.
|
||||
* @param {string} path - The name under wich the variable will be saved (document name).
|
||||
* @param {string} field - The field to check.
|
||||
* @param {gdjs.Variable} callbackValueVariable - The variable where to store the result.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store if the operation was successful.
|
||||
*/
|
||||
gdjs.evtTools.firebase.database.hasField = function (
|
||||
path,
|
||||
field,
|
||||
callbackValueVariable,
|
||||
callbackStateVariable
|
||||
) {
|
||||
firebase
|
||||
.database()
|
||||
.ref(path)
|
||||
.once('value')
|
||||
.then(function (snapshot) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
if (typeof callbackValueVariable !== 'undefined')
|
||||
callbackValueVariable.setString(
|
||||
snapshot.val() == null || snapshot.val()[field] == null
|
||||
? 'false'
|
||||
: 'true'
|
||||
);
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
47
Extensions/Firebase/C_firebasetools/D_functionstools.js
Normal file
47
Extensions/Firebase/C_firebasetools/D_functionstools.js
Normal file
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Firebase Tools Collection.
|
||||
* @fileoverview
|
||||
* @author arthuro555
|
||||
*/
|
||||
|
||||
/**
|
||||
* Firebase Functions Event Tools.
|
||||
* @namespace
|
||||
*/
|
||||
gdjs.evtTools.firebase.functions = {
|
||||
/**
|
||||
* Call an http function.
|
||||
* @param {string} httpFunctionName - The name of the function to call
|
||||
* @param {string | Object} [parameters] - Parameters for the function either as a JS object or a string.
|
||||
* @param {gdjs.Variable} [callbackValueVariable] - The variable where to store the result.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store if the operation was successful.
|
||||
*/
|
||||
call(
|
||||
httpFunctionName,
|
||||
parameters,
|
||||
callbackValueVariable,
|
||||
callbackStateVariable
|
||||
) {
|
||||
let param;
|
||||
try {
|
||||
param = JSON.parse(parameters);
|
||||
} catch {
|
||||
param = parameters;
|
||||
}
|
||||
|
||||
firebase
|
||||
.functions()
|
||||
.httpsCallable(httpFunctionName)(param)
|
||||
.then((response) => response.data)
|
||||
.then((data) => {
|
||||
if (callbackValueVariable)
|
||||
gdjs.evtTools.network._objectToVariable(data, callbackValueVariable);
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch((error) => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
},
|
||||
};
|
62
Extensions/Firebase/C_firebasetools/D_performancetools.js
Normal file
62
Extensions/Firebase/C_firebasetools/D_performancetools.js
Normal file
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Firebase Tools Collection.
|
||||
* @fileoverview
|
||||
* @author arthuro555
|
||||
*/
|
||||
|
||||
/**
|
||||
* Firebase Performance Event Tools.
|
||||
* @namespace
|
||||
*/
|
||||
gdjs.evtTools.firebase.performance = {
|
||||
/** @type {Object.<string, firebase.performance.Trace>} */
|
||||
tracers: {},
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a tracer (custom event) by name, if it doesn't exists create it.
|
||||
* @param {string} tracerName - The name of the tracer.
|
||||
* @returns {firebase.performance.Trace} The tracer instance.
|
||||
*/
|
||||
gdjs.evtTools.firebase.performance.getTracer = function (tracerName) {
|
||||
if (!gdjs.evtTools.firebase.performance.tracers.hasOwnProperty(tracerName)) {
|
||||
gdjs.evtTools.firebase.performance.tracers[
|
||||
tracerName
|
||||
] = firebase.performance().trace(tracerName);
|
||||
}
|
||||
return gdjs.evtTools.firebase.performance.tracers[tracerName];
|
||||
};
|
||||
|
||||
/**
|
||||
* Start measuring performance for a custom event (tracer).
|
||||
* @param {string} tracerName - The name of the tracer.
|
||||
*/
|
||||
gdjs.evtTools.firebase.performance.startTracer = function (tracerName) {
|
||||
gdjs.evtTools.firebase.performance.getTracer(tracerName).start();
|
||||
};
|
||||
|
||||
/**
|
||||
* Stop measuring performance for a custom event (tracer).
|
||||
* @param {string} tracerName - The name of the tracer.
|
||||
*/
|
||||
gdjs.evtTools.firebase.performance.stopTracer = function (tracerName) {
|
||||
gdjs.evtTools.firebase.performance.getTracer(tracerName).stop();
|
||||
delete gdjs.evtTools.firebase.performance.tracers[tracerName];
|
||||
};
|
||||
|
||||
/**
|
||||
* Record performance for a specific time.
|
||||
* @param {string} tracerName - The name of the tracer.
|
||||
* @param {number} delay - The delay before starting measuring.
|
||||
* @param {number} duration - The duration of the measuring.
|
||||
*/
|
||||
gdjs.evtTools.firebase.performance.recordPerformance = function (
|
||||
tracerName,
|
||||
delay,
|
||||
duration
|
||||
) {
|
||||
let currentTimeSinceEpoch = Date.now();
|
||||
gdjs.evtTools.firebase.performance
|
||||
.getTracer(tracerName)
|
||||
.record(currentTimeSinceEpoch + delay, duration);
|
||||
};
|
35
Extensions/Firebase/C_firebasetools/D_remoteconfigtools.js
Normal file
35
Extensions/Firebase/C_firebasetools/D_remoteconfigtools.js
Normal file
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Firebase Tools Collection
|
||||
* @fileoverview
|
||||
* @author arthuro555
|
||||
*/
|
||||
|
||||
/**
|
||||
* Remote Config Tools
|
||||
* @namespace
|
||||
*/
|
||||
gdjs.evtTools.firebase.remoteConfig = {};
|
||||
|
||||
/**
|
||||
* Set the interval between auto-config updates.
|
||||
*/
|
||||
gdjs.evtTools.firebase.remoteConfig.setAutoUpdateInterval = function (
|
||||
interval
|
||||
) {
|
||||
firebase.remoteConfig().settings.minimumFetchIntervalMillis = interval;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the default configuration, for when starting the game offline.
|
||||
* @param {gdjs.Variable} variable - A structure defining the default variables.
|
||||
*/
|
||||
gdjs.evtTools.firebase.remoteConfig.setDefaultConfig = function (variable) {
|
||||
firebase.remoteConfig().defaultConfig = JSON.parse(
|
||||
gdjs.evtTools.network.variableStructureToJSON(variable)
|
||||
);
|
||||
};
|
||||
|
||||
gdjs.evtTools.firebase.onAppCreated.push(function () {
|
||||
// Synchronisation seems to be impossible when that value isn't preset.
|
||||
firebase.remoteConfig().settings.minimumFetchIntervalMillis = -1;
|
||||
});
|
134
Extensions/Firebase/C_firebasetools/D_storagetools.js
Normal file
134
Extensions/Firebase/C_firebasetools/D_storagetools.js
Normal file
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
* Firebase Tools Collection
|
||||
* @fileoverview
|
||||
* @author arthuro555
|
||||
*/
|
||||
|
||||
/**
|
||||
* Firebase Storage Event Tools
|
||||
* @namespace
|
||||
*/
|
||||
gdjs.evtTools.firebase.storage = {
|
||||
uploads: new gdjs.UIDArray(),
|
||||
};
|
||||
|
||||
/**
|
||||
* Uploads a file as string to the firebase storage bucket.
|
||||
* @param {string} file - The entire file as string.
|
||||
* @param {string} onlinePath - The path under wich the file will be accessible on the bucket.
|
||||
* @param {"none"|"base64"|"base64url"|"data_url"} [type] - The type/format of the string to upload.
|
||||
* @param {gdjs.Variable} [callbackValueVariable] - The variable where to store the result (url to the file).
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store if the operation was successful.
|
||||
* @param {gdjs.Variable} [callbackUIDVariable] - The variable where to store the upload ID.
|
||||
* @param {gdjs.Variable} [callbackProgressVariable] - The variable where to store the progress.
|
||||
*/
|
||||
gdjs.evtTools.firebase.storage.upload = function (
|
||||
file,
|
||||
onlinePath,
|
||||
type,
|
||||
callbackValueVariable,
|
||||
callbackStateVariable,
|
||||
callbackUIDVariable,
|
||||
callbackProgressVariable
|
||||
) {
|
||||
type = type === 'none' ? undefined : type;
|
||||
|
||||
let uploadTask;
|
||||
try {
|
||||
uploadTask = firebase
|
||||
.storage()
|
||||
.ref()
|
||||
.child(onlinePath)
|
||||
.putString(file, type);
|
||||
} catch (e) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(e.message);
|
||||
return;
|
||||
}
|
||||
|
||||
let uploadID;
|
||||
if (typeof callbackUIDVariable !== 'undefined') {
|
||||
// Only bother pushing if the ID will be stored.
|
||||
uploadID = gdjs.evtTools.firebase.storage.uploads.push(uploadTask);
|
||||
callbackUIDVariable.setNumber(uploadID);
|
||||
}
|
||||
|
||||
uploadTask.on(
|
||||
firebase.storage.TaskEvent.STATE_CHANGED,
|
||||
(uploadProgress) => {
|
||||
if (typeof callbackProgressVariable !== 'undefined')
|
||||
gdjs.evtTools.network._objectToVariable(
|
||||
uploadProgress,
|
||||
callbackProgressVariable,
|
||||
['tasks'] // Remove circular reference.
|
||||
);
|
||||
},
|
||||
(error) => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
},
|
||||
() => {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
if (typeof callbackUIDVariable !== 'undefined') {
|
||||
gdjs.evtTools.firebase.storage.uploads.remove(uploadID); // Free memory.
|
||||
}
|
||||
uploadTask.snapshot.ref.getDownloadURL().then(function (downloadURL) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(downloadURL);
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a download URL for a file.
|
||||
* @param {string} filePath - The path in the remote storage bucket to the file to download.
|
||||
* @param {gdjs.Variable} [callbackValueVariable] - The variable where to store the result.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store if the operation was successful.
|
||||
*/
|
||||
gdjs.evtTools.firebase.storage.getDownloadURL = function (
|
||||
filePath,
|
||||
callbackValueVariable,
|
||||
callbackStateVariable
|
||||
) {
|
||||
firebase
|
||||
.storage()
|
||||
.ref()
|
||||
.child(filePath)
|
||||
.getDownloadURL()
|
||||
.then(function (downloadURL) {
|
||||
if (typeof callbackValueVariable !== 'undefined')
|
||||
callbackValueVariable.setString(downloadURL);
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes a file on the remote storage bucket.
|
||||
* @param {string} filePath - The path in the remote storage bucket to the file to download.
|
||||
* @param {gdjs.Variable} [callbackStateVariable] - The variable where to store if the operation was successful.
|
||||
*/
|
||||
gdjs.evtTools.firebase.storage.delete = function (
|
||||
filePath,
|
||||
callbackStateVariable
|
||||
) {
|
||||
firebase
|
||||
.storage()
|
||||
.ref()
|
||||
.child(filePath)
|
||||
.delete()
|
||||
.then(function () {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString('ok');
|
||||
})
|
||||
.catch(function (error) {
|
||||
if (typeof callbackStateVariable !== 'undefined')
|
||||
callbackStateVariable.setString(error.message);
|
||||
});
|
||||
};
|
1815
Extensions/Firebase/JsExtension.js
Normal file
1815
Extensions/Firebase/JsExtension.js
Normal file
File diff suppressed because it is too large
Load Diff
7
Extensions/Firebase/README.md
Normal file
7
Extensions/Firebase/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Firebase Extension
|
||||
|
||||
This is the wrapper for the Firebase SDK for GDevelop.
|
||||
The files are prefixed with A_, B_, C_ and D_ to classify their import priority (where A has the highest and D the lowest).
|
||||
|
||||
firebasejs contains the Web SDK.
|
||||
firebasetools contains wrappers for GDevelop.
|
@@ -11,7 +11,7 @@ gdjs.LightRuntimeObjectPixiRenderer = function (runtimeObject, runtimeScene) {
|
||||
this._runtimeScene = runtimeScene;
|
||||
this._manager = runtimeObject.getObstaclesManager();
|
||||
this._radius = runtimeObject.getRadius();
|
||||
var objectColor = runtimeObject.getColor();
|
||||
var objectColor = runtimeObject._color;
|
||||
this._color = [
|
||||
objectColor[0] / 255,
|
||||
objectColor[1] / 255,
|
||||
@@ -55,6 +55,13 @@ gdjs.LightRuntimeObjectPixiRenderer = function (runtimeObject, runtimeScene) {
|
||||
runtimeObject.getHitBoxes()[0].vertices[i]
|
||||
);
|
||||
}
|
||||
|
||||
// Objects will be added in lighting layer, this is just to maintain consistency.
|
||||
if (this._light)
|
||||
runtimeScene
|
||||
.getLayer('')
|
||||
.getRenderer()
|
||||
.addRendererObject(this.getRendererObject(), runtimeObject.getZOrder());
|
||||
};
|
||||
|
||||
gdjs.LightRuntimeObjectRenderer = gdjs.LightRuntimeObjectPixiRenderer; //Register the class to let the engine use it.
|
||||
@@ -168,6 +175,12 @@ gdjs.LightRuntimeObjectPixiRenderer.prototype.ensureUpToDate = function () {
|
||||
};
|
||||
|
||||
gdjs.LightRuntimeObjectPixiRenderer.prototype.updateMesh = function () {
|
||||
if (!PIXI.utils.isWebGLSupported()) {
|
||||
console.warn(
|
||||
'This device does not support webgl, which is required for Lighting Extension.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
this.updateTexture();
|
||||
var fragmentShader =
|
||||
this._texture === null
|
||||
@@ -200,12 +213,16 @@ gdjs.LightRuntimeObjectPixiRenderer.prototype.updateMesh = function () {
|
||||
};
|
||||
|
||||
gdjs.LightRuntimeObjectPixiRenderer.prototype.updateRadius = function () {
|
||||
if (!this._light) return;
|
||||
|
||||
this._radius = this._object.getRadius();
|
||||
this._light.shader.uniforms.radius = this._radius;
|
||||
};
|
||||
|
||||
gdjs.LightRuntimeObjectPixiRenderer.prototype.updateColor = function () {
|
||||
var objectColor = this._object.getColor();
|
||||
if (!this._light) return;
|
||||
|
||||
var objectColor = this._object._color;
|
||||
this._color = [
|
||||
objectColor[0] / 255,
|
||||
objectColor[1] / 255,
|
||||
@@ -223,6 +240,8 @@ gdjs.LightRuntimeObjectPixiRenderer.prototype.updateTexture = function () {
|
||||
};
|
||||
|
||||
gdjs.LightRuntimeObjectPixiRenderer.prototype.updateDebugMode = function () {
|
||||
if (!this._light) return;
|
||||
|
||||
this._debugMode = this._object.getDebugMode();
|
||||
if (!this._debugLight && (this._isPreview || this._debugMode)) {
|
||||
this._debugLight = new PIXI.Container();
|
||||
@@ -293,9 +312,10 @@ gdjs.LightRuntimeObjectPixiRenderer.prototype._updateDebugGraphics = function ()
|
||||
};
|
||||
|
||||
gdjs.LightRuntimeObjectPixiRenderer.prototype._updateBuffers = function () {
|
||||
if (!this._light) return;
|
||||
|
||||
this._center[0] = this._object.x;
|
||||
this._center[1] = this._object.y;
|
||||
this._light.shader.uniforms.center = this._center;
|
||||
|
||||
var vertices = this._computeLightVertices();
|
||||
// Fallback to simple quad when there are no obstacles around.
|
||||
@@ -309,6 +329,7 @@ gdjs.LightRuntimeObjectPixiRenderer.prototype._updateBuffers = function () {
|
||||
this._defaultVertexBuffer[6] = this._object.x - this._radius;
|
||||
this._defaultVertexBuffer[7] = this._object.y - this._radius;
|
||||
|
||||
this._light.shader.uniforms.center = this._center;
|
||||
this._light.geometry
|
||||
.getBuffer('aVertexPosition')
|
||||
.update(this._defaultVertexBuffer);
|
||||
@@ -364,6 +385,7 @@ gdjs.LightRuntimeObjectPixiRenderer.prototype._updateBuffers = function () {
|
||||
else this._indexBuffer[i + 2] = 1;
|
||||
}
|
||||
|
||||
this._light.shader.uniforms.center = this._center;
|
||||
if (!isSubArrayUsed) {
|
||||
this._light.geometry
|
||||
.getBuffer('aVertexPosition')
|
||||
|
@@ -5,7 +5,9 @@
|
||||
* @property {string} content.color A string representing color in hexadecimal format.
|
||||
* @property {string} content.texture A string representing the name of texture used for light object.
|
||||
* @property {boolean} content.debugMode true if the light objects shows debug graphics, false otherwise.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {ObjectData & LightObjectDataType} LightObjectData
|
||||
*/
|
||||
|
||||
@@ -147,11 +149,11 @@ gdjs.LightRuntimeObject.prototype.getDrawableY = function () {
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the color of the light object in format [r, g, b], with components in the range of [0-255].
|
||||
* @returns {number[]} the color of light object in rgb format.
|
||||
* Get the color of the light object as a "R;G;B" string.
|
||||
* @returns {string} the color of light object in "R;G;B" format.
|
||||
*/
|
||||
gdjs.LightRuntimeObject.prototype.getColor = function () {
|
||||
return this._color;
|
||||
return this._color[0] + ';' + this._color[1] + ';' + this._color[2];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -161,9 +163,9 @@ gdjs.LightRuntimeObject.prototype.getColor = function () {
|
||||
gdjs.LightRuntimeObject.prototype.setColor = function (color) {
|
||||
var rgbColor = color.split(';');
|
||||
this._color = [
|
||||
parseInt(rgbColor[0]),
|
||||
parseInt(rgbColor[1]),
|
||||
parseInt(rgbColor[2]),
|
||||
parseInt(rgbColor[0], 10),
|
||||
parseInt(rgbColor[1], 10),
|
||||
parseInt(rgbColor[2], 10),
|
||||
];
|
||||
this._renderer.updateColor();
|
||||
};
|
||||
|
@@ -53,6 +53,7 @@ const addLightObstacle = (runtimeScene, width, height) => {
|
||||
};
|
||||
|
||||
describe('gdjs.LightRuntimeObject', function () {
|
||||
PIXI.settings.FAIL_IF_MAJOR_PERFORMANCE_CAVEAT = false;
|
||||
const runtimeGame = new gdjs.RuntimeGame({
|
||||
variables: [],
|
||||
resources: {
|
||||
@@ -61,12 +62,19 @@ describe('gdjs.LightRuntimeObject', function () {
|
||||
properties: { windowWidth: 800, windowHeight: 600 },
|
||||
});
|
||||
const runtimeScene = new gdjs.RuntimeScene(runtimeGame);
|
||||
runtimeScene.loadFromScene({
|
||||
layers: [{ name: '', visibility: true, effects: [] }],
|
||||
variables: [],
|
||||
behaviorsSharedData: [],
|
||||
objects: [],
|
||||
instances: [],
|
||||
});
|
||||
const lightObj = addLightObject(runtimeScene, 100);
|
||||
lightObj.setPosition(200, 200);
|
||||
|
||||
it('check object properties', function () {
|
||||
expect(lightObj.getRadius()).to.be(100);
|
||||
expect(lightObj.getColor()).to.eql([180, 180, 180]);
|
||||
expect(lightObj.getColor()).to.eql("180;180;180");
|
||||
expect(lightObj.getDebugMode()).to.be(false);
|
||||
expect(lightObj.getDrawableX()).to.be(100);
|
||||
expect(lightObj.getDrawableY()).to.be(100);
|
||||
@@ -85,6 +93,7 @@ describe('gdjs.LightRuntimeObject', function () {
|
||||
});
|
||||
|
||||
describe('Light with obstacles around it', function () {
|
||||
PIXI.settings.FAIL_IF_MAJOR_PERFORMANCE_CAVEAT = false;
|
||||
const runtimeGame = new gdjs.RuntimeGame({
|
||||
variables: [],
|
||||
resources: {
|
||||
@@ -156,7 +165,7 @@ describe('Light with obstacles around it', function () {
|
||||
const expectedIndexBuffer = [
|
||||
0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 6, 0,
|
||||
6, 7, 0, 7, 8, 0, 8, 9, 0, 9, 10, 0, 10, 11, 0,
|
||||
11, 12, 0, 12, 13, 0, 13, 14, 0, 14, 15, 0, 15,
|
||||
11, 12, 0, 12, 13, 0, 13, 14, 0, 14, 15, 0, 15,
|
||||
16, 0, 16, 17, 0, 17, 18, 0, 18, 1,
|
||||
];
|
||||
|
||||
|
@@ -8,6 +8,7 @@
|
||||
gdjs.evtTools.p2p = {
|
||||
/**
|
||||
* The peer to peer configuration.
|
||||
* @type {Peer.PeerJSOption}
|
||||
*/
|
||||
peerConfig: { debug: 1 }, // Enable logging of critical errors
|
||||
|
||||
@@ -18,52 +19,75 @@ gdjs.evtTools.p2p = {
|
||||
peer: null,
|
||||
|
||||
/**
|
||||
* All connected p2p clients, keyed by their id.
|
||||
* All connected p2p clients, keyed by their ID.
|
||||
* @type {Object<string, Peer.DataConnection>}
|
||||
*/
|
||||
connections: {},
|
||||
|
||||
/**
|
||||
* Contains a list of events triggered by other p2p clients.
|
||||
* Maps an event name (string) to a boolean:
|
||||
* true if the event has been triggered, otherwise false.
|
||||
* @note This is ignored if the event is in no dataloss mode.
|
||||
* @type {Object<string, boolean>}
|
||||
*/
|
||||
triggeredEvents: {},
|
||||
|
||||
/**
|
||||
* Contains the latest data sent with each event.
|
||||
* If the event is in dataloss mode, maps an event name (string)
|
||||
* to the string sent with that event.
|
||||
* If the event is in no dataloss mode, maps an event name (string)
|
||||
* to an array containing the data of each call of that event.
|
||||
* @type {Object<string, string | Array>}
|
||||
*/
|
||||
lastEventData: {},
|
||||
|
||||
/**
|
||||
* Tells how to handle an event (with or without data loss)
|
||||
* Tells how to handle an event (with or without data loss).
|
||||
* Maps the event name (string) to a boolean:
|
||||
* true for dataloss, false for no dataloss.
|
||||
* @type {Object<string, string>}
|
||||
*/
|
||||
eventHandling: {},
|
||||
|
||||
/**
|
||||
* True if PeerJS is initialized and ready.
|
||||
* @type {boolean}
|
||||
*/
|
||||
ready: false,
|
||||
|
||||
/**
|
||||
* True if an error occured.
|
||||
* @type {boolean}
|
||||
*/
|
||||
error: false,
|
||||
|
||||
/**
|
||||
* Last error's message.
|
||||
* @type {string}
|
||||
*/
|
||||
lastError: '',
|
||||
|
||||
/**
|
||||
* True if a peer diconnected.
|
||||
* List of IDs of peers that just disconnected.
|
||||
* @type {Array<string>}
|
||||
*/
|
||||
peerJustDisconnected: false,
|
||||
disconnectedPeers: [],
|
||||
|
||||
/**
|
||||
* The last peer that has disconnected.
|
||||
* List of IDs of peers that just remotely initiated a connection.
|
||||
* @type {Array<string>}
|
||||
*/
|
||||
lastDisconnectedPeerId: '',
|
||||
connectedPeers: [],
|
||||
};
|
||||
|
||||
gdjs.evtTools.p2p.loadPeerJS = function () {
|
||||
/**
|
||||
* Internal function called to initialize PeerJS after its
|
||||
* broker server has been configured.
|
||||
* @private
|
||||
*/
|
||||
gdjs.evtTools.p2p._loadPeerJS = function () {
|
||||
if (gdjs.evtTools.p2p.peer != null) return;
|
||||
gdjs.evtTools.p2p.peer = new Peer(gdjs.evtTools.p2p.peerConfig);
|
||||
gdjs.evtTools.p2p.peer.on('open', function () {
|
||||
@@ -73,14 +97,24 @@ gdjs.evtTools.p2p.loadPeerJS = function () {
|
||||
gdjs.evtTools.p2p.error = true;
|
||||
gdjs.evtTools.p2p.lastError = errorMessage;
|
||||
});
|
||||
gdjs.evtTools.p2p.peer.on('connection', gdjs.evtTools.p2p._onConnection);
|
||||
gdjs.evtTools.p2p.peer.on('connection', function (connection) {
|
||||
connection.on('open', function () {
|
||||
gdjs.evtTools.p2p._onConnection(connection);
|
||||
gdjs.evtTools.p2p.connectedPeers.push(connection.peer);
|
||||
});
|
||||
});
|
||||
gdjs.evtTools.p2p.peer.on('close', function () {
|
||||
gdjs.evtTools.p2p.peer = null;
|
||||
gdjs.evtTools.p2p.loadPeerJS();
|
||||
gdjs.evtTools.p2p._loadPeerJS();
|
||||
});
|
||||
gdjs.evtTools.p2p.peer.on('disconnected', gdjs.evtTools.p2p.peer.reconnect);
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal function called when a connection with a remote peer is initiated.
|
||||
* @private
|
||||
* @param {Peer.DataConnection} connection The DataConnection of the peer
|
||||
*/
|
||||
gdjs.evtTools.p2p._onConnection = function (connection) {
|
||||
gdjs.evtTools.p2p.connections[connection.peer] = connection;
|
||||
connection.on('data', function (data) {
|
||||
@@ -117,15 +151,19 @@ gdjs.evtTools.p2p._onConnection = function (connection) {
|
||||
disconnectChecker();
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal function called when a remote client disconnects.
|
||||
* @private
|
||||
* @param {string} connectionID The ID of the peer that disconnected.
|
||||
*/
|
||||
gdjs.evtTools.p2p._onDisconnect = function (connectionID) {
|
||||
gdjs.evtTools.p2p.peerJustDisconnected = true;
|
||||
gdjs.evtTools.p2p.lastDisconnectedPeerId = connectionID;
|
||||
gdjs.evtTools.p2p.disconnectedPeers.push(connectionID);
|
||||
delete gdjs.evtTools.p2p.connections[connectionID];
|
||||
};
|
||||
|
||||
/**
|
||||
* Connects to another p2p client.
|
||||
* @param {string} id - The other client's id.
|
||||
* @param {string} id - The other client's ID.
|
||||
*/
|
||||
gdjs.evtTools.p2p.connect = function (id) {
|
||||
var connection = gdjs.evtTools.p2p.peer.connect(id);
|
||||
@@ -137,14 +175,14 @@ gdjs.evtTools.p2p.connect = function (id) {
|
||||
/**
|
||||
* Returns true when the event got triggered by another p2p client.
|
||||
* @param {string} eventName
|
||||
* @param {boolean} _dataLoss Is data loss allowed (accelerates event handling when true)?
|
||||
* @param {boolean} defaultDataLoss Is data loss allowed (accelerates event handling when true)?
|
||||
* @returns {boolean}
|
||||
*/
|
||||
gdjs.evtTools.p2p.onEvent = function (eventName, _dataLoss) {
|
||||
gdjs.evtTools.p2p.onEvent = function (eventName, defaultDataLoss) {
|
||||
var dataLoss = gdjs.evtTools.p2p.eventHandling[eventName];
|
||||
if (dataLoss == undefined) {
|
||||
gdjs.evtTools.p2p.eventHandling[eventName] = _dataLoss;
|
||||
return gdjs.evtTools.p2p.onEvent(eventName, _dataLoss);
|
||||
gdjs.evtTools.p2p.eventHandling[eventName] = defaultDataLoss;
|
||||
return gdjs.evtTools.p2p.onEvent(eventName, defaultDataLoss);
|
||||
}
|
||||
if (dataLoss) {
|
||||
var returnValue = gdjs.evtTools.p2p.triggeredEvents[eventName];
|
||||
@@ -160,7 +198,7 @@ gdjs.evtTools.p2p.onEvent = function (eventName, _dataLoss) {
|
||||
|
||||
/**
|
||||
* Send an event to one specific connected client.
|
||||
* @param {string} id - The id of the client to send the event to.
|
||||
* @param {string} id - The ID of the client to send the event to.
|
||||
* @param {string} eventName - The event to trigger.
|
||||
* @param {string} [eventData] - Additional data to send with the event.
|
||||
*/
|
||||
@@ -188,16 +226,16 @@ gdjs.evtTools.p2p.sendDataToAll = function (eventName, eventData) {
|
||||
|
||||
/**
|
||||
* Send an event to one specific connected client.
|
||||
* @param {string} id - The id of the client to send the event to.
|
||||
* @param {string} id - The ID of the client to send the event to.
|
||||
* @param {string} eventName - The event to trigger.
|
||||
* @param {gdjs.Variable} variable - Additional variable to send with the event.
|
||||
*/
|
||||
gdjs.evtTools.p2p.sendVariableTo = function (id, eventName, variable) {
|
||||
if (gdjs.evtTools.p2p.connections[id])
|
||||
gdjs.evtTools.p2p.connections[id].send({
|
||||
eventName: eventName,
|
||||
data: gdjs.evtTools.network.variableStructureToJSON(variable),
|
||||
});
|
||||
gdjs.evtTools.p2p.sendDataTo(
|
||||
id,
|
||||
eventName,
|
||||
gdjs.evtTools.network.variableStructureToJSON(variable)
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -206,12 +244,10 @@ gdjs.evtTools.p2p.sendVariableTo = function (id, eventName, variable) {
|
||||
* @param {gdjs.Variable} variable - Additional variable to send with the event.
|
||||
*/
|
||||
gdjs.evtTools.p2p.sendVariableToAll = function (eventName, variable) {
|
||||
for (var id in gdjs.evtTools.p2p.connections) {
|
||||
gdjs.evtTools.p2p.connections[id].send({
|
||||
eventName: eventName,
|
||||
data: gdjs.evtTools.network.variableStructureToJSON(variable),
|
||||
});
|
||||
}
|
||||
gdjs.evtTools.p2p.sendDataToAll(
|
||||
eventName,
|
||||
gdjs.evtTools.network.variableStructureToJSON(variable)
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -265,7 +301,7 @@ gdjs.evtTools.p2p.useCustomBrokerServer = function (
|
||||
secure: ssl,
|
||||
key,
|
||||
};
|
||||
gdjs.evtTools.p2p.loadPeerJS();
|
||||
gdjs.evtTools.p2p._loadPeerJS();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -274,11 +310,11 @@ gdjs.evtTools.p2p.useCustomBrokerServer = function (
|
||||
* this server should only be used for quick testing in development.
|
||||
*/
|
||||
gdjs.evtTools.p2p.useDefaultBrokerServer = function () {
|
||||
gdjs.evtTools.p2p.loadPeerJS();
|
||||
gdjs.evtTools.p2p._loadPeerJS();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the own current peer ID
|
||||
* Returns the own current peer ID.
|
||||
* @see Peer.id
|
||||
* @returns {string}
|
||||
*/
|
||||
@@ -288,7 +324,7 @@ gdjs.evtTools.p2p.getCurrentId = function () {
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true once PeerJS is initialized
|
||||
* Returns true once PeerJS finished initialization.
|
||||
* @see gdjs.evtTools.p2p.ready
|
||||
* @returns {boolean}
|
||||
*/
|
||||
@@ -319,13 +355,39 @@ gdjs.evtTools.p2p.getLastError = function () {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
gdjs.evtTools.p2p.onDisconnect = function () {
|
||||
var returnValue = gdjs.evtTools.p2p.peerJustDisconnected;
|
||||
gdjs.evtTools.p2p.peerJustDisconnected = false;
|
||||
return returnValue;
|
||||
return gdjs.evtTools.p2p.disconnectedPeers.length > 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the ID of the peer that triggered onDisconnect.
|
||||
* @returns {string}
|
||||
*/
|
||||
gdjs.evtTools.p2p.getDisconnectedPeer = function () {
|
||||
return gdjs.evtTools.p2p.lastDisconnectedPeerId;
|
||||
return (
|
||||
gdjs.evtTools.p2p.disconnectedPeers[
|
||||
gdjs.evtTools.p2p.disconnectedPeers.length - 1
|
||||
] || ''
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true once if a remote peer just initiated a connection.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
gdjs.evtTools.p2p.onConnection = function () {
|
||||
return gdjs.evtTools.p2p.connectedPeers.length > 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the ID of the peer that triggered onConnection.
|
||||
* @returns {string}
|
||||
*/
|
||||
gdjs.evtTools.p2p.getConnectedPeer = function () {
|
||||
return (
|
||||
gdjs.evtTools.p2p.connectedPeers[
|
||||
gdjs.evtTools.p2p.connectedPeers.length - 1
|
||||
] || ''
|
||||
);
|
||||
};
|
||||
|
||||
gdjs.callbacksRuntimeScenePostEvents.push(function () {
|
||||
@@ -336,4 +398,8 @@ gdjs.callbacksRuntimeScenePostEvents.push(function () {
|
||||
)
|
||||
gdjs.evtTools.p2p.lastEventData[i].pop();
|
||||
}
|
||||
if (gdjs.evtTools.p2p.disconnectedPeers.length > 0)
|
||||
gdjs.evtTools.p2p.disconnectedPeers.pop();
|
||||
if (gdjs.evtTools.p2p.connectedPeers.length > 0)
|
||||
gdjs.evtTools.p2p.connectedPeers.pop();
|
||||
});
|
||||
|
@@ -105,6 +105,21 @@ module.exports = {
|
||||
.addIncludeFile('Extensions/P2P/B_p2ptools.js')
|
||||
.setFunctionName('gdjs.evtTools.p2p.onDisconnect');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'OnConnection',
|
||||
_('Peer Connected'),
|
||||
_('Triggers once when a remote peer initiates a connection.'),
|
||||
_('P2P peer connected'),
|
||||
_('P2P (experimental)'),
|
||||
'JsPlatform/Extensions/p2picon.svg',
|
||||
'JsPlatform/Extensions/p2picon.svg'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/P2P/A_peer.js')
|
||||
.addIncludeFile('Extensions/P2P/B_p2ptools.js')
|
||||
.setFunctionName('gdjs.evtTools.p2p.onConnection');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'Connect',
|
||||
@@ -215,7 +230,7 @@ module.exports = {
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/P2P/A_peer.js')
|
||||
.addIncludeFile('Extensions/P2P/B_p2ptools.js')
|
||||
.setFunctionName('gdjs.evtTools.p2p.sendDataToAll');
|
||||
.setFunctionName('gdjs.evtTools.p2p.sendVariableToAll');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
@@ -313,7 +328,7 @@ module.exports = {
|
||||
.addStrExpression(
|
||||
'GetLastDisconnectedPeer',
|
||||
_('Get last disconnected peer'),
|
||||
_('Gets the id of the latest peer that has disconnected.'),
|
||||
_('Gets the ID of the latest peer that has disconnected.'),
|
||||
_('P2P (experimental)'),
|
||||
'JsPlatform/Extensions/p2picon.svg'
|
||||
)
|
||||
@@ -322,6 +337,19 @@ module.exports = {
|
||||
.addIncludeFile('Extensions/P2P/B_p2ptools.js')
|
||||
.setFunctionName('gdjs.evtTools.p2p.getDisconnectedPeer');
|
||||
|
||||
extension
|
||||
.addStrExpression(
|
||||
'GetLastConnectedPeer',
|
||||
_('Get ID of the connected peer'),
|
||||
_('Gets the ID of the newly connected peer.'),
|
||||
_('P2P (experimental)'),
|
||||
'JsPlatform/Extensions/p2picon.svg'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/P2P/A_peer.js')
|
||||
.addIncludeFile('Extensions/P2P/B_p2ptools.js')
|
||||
.setFunctionName('gdjs.evtTools.p2p.getConnectedPeer');
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function (
|
||||
|
@@ -66,15 +66,15 @@ void DeclarePanelSpriteObjectExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
obj.AddAction(
|
||||
"SetColor",
|
||||
_("Global color"),
|
||||
_("Change the global color of a Panel Sprite. The default color is white."),
|
||||
_("Change color of _PARAM0_ to _PARAM1_"),
|
||||
_("Tint color"),
|
||||
_("Change the tint of a Panel Sprite. The default color is white."),
|
||||
_("Change tint of _PARAM0_ to _PARAM1_"),
|
||||
_("Effects"),
|
||||
"res/actions/color24.png",
|
||||
"res/actions/color.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "PanelSprite")
|
||||
.AddParameter("color", _("Color"));
|
||||
.AddParameter("color", _("Tint"));
|
||||
|
||||
obj.AddAction("Width",
|
||||
_("Width"),
|
||||
|
@@ -13,7 +13,9 @@
|
||||
* @property {number} width The object width
|
||||
* @property {number} height The object height
|
||||
* @property {string} texture The name of the resource containing the texture to use
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {ObjectData & PanelSpriteObjectDataType} PanelSpriteObjectData
|
||||
*/
|
||||
|
||||
@@ -258,7 +260,7 @@ gdjs.PanelSpriteRuntimeObject.prototype.setColor = function(rgbColor) {
|
||||
/**
|
||||
* Get the tint of the panel sprite object.
|
||||
*
|
||||
* @returns {string} rgbColor The color, in RGB format ("128;200;255").
|
||||
* @returns {string} The color, in RGB format ("128;200;255").
|
||||
*/
|
||||
gdjs.PanelSpriteRuntimeObject.prototype.getColor = function() {
|
||||
return this._renderer.getColor();
|
||||
|
@@ -293,7 +293,7 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
|
||||
obj.AddCondition("NoMoreParticles",
|
||||
_("No more particles"),
|
||||
_("Return true if the object does not emit particles "
|
||||
_("Check if the object does not emit particles "
|
||||
"anylonger, so as to destroy it for example."),
|
||||
_("_PARAM0_ does not emit anylonger."),
|
||||
_("Common"),
|
||||
|
@@ -36,7 +36,9 @@
|
||||
* @property {number} flow
|
||||
* @property {number} tank
|
||||
* @property {boolean} destroyWhenNoParticles Destroy the object when there is no particles?
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {ObjectData & ParticleEmitterObjectDataType} ParticleEmitterObjectData
|
||||
*/
|
||||
|
||||
|
@@ -56,7 +56,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
aut.AddCondition("PathFound",
|
||||
_("Path found"),
|
||||
_("Return true if a path has been found."),
|
||||
_("Check if a path has been found."),
|
||||
_("A path has been found for _PARAM0_"),
|
||||
"",
|
||||
"CppPlatform/Extensions/AStaricon24.png",
|
||||
@@ -69,7 +69,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
aut.AddCondition("DestinationReached",
|
||||
_("Destination reached"),
|
||||
_("Return true if the destination was reached."),
|
||||
_("Check if the destination was reached."),
|
||||
_("_PARAM0_ reached its destination"),
|
||||
"",
|
||||
"CppPlatform/Extensions/AStaricon24.png",
|
||||
@@ -338,7 +338,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
aut.AddCondition("DiagonalsAllowed",
|
||||
_("Diagonal movement"),
|
||||
_("Return true if the object is allowed to move "
|
||||
_("Check if the object is allowed to move "
|
||||
"diagonally on the path"),
|
||||
_("Diagonal moves allowed for _PARAM0_"),
|
||||
_("Path"),
|
||||
@@ -366,7 +366,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
aut.AddCondition("ObjectRotated",
|
||||
_("Object rotated"),
|
||||
_("Return true if the object is rotated when traveling on "
|
||||
_("Check if the object is rotated when traveling on "
|
||||
"its path."),
|
||||
_("_PARAM0_ is rotated when traveling on its path"),
|
||||
_("Path"),
|
||||
@@ -622,7 +622,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
aut.AddCondition("IsImpassable",
|
||||
_("Is object impassable?"),
|
||||
_("Return true if the obstacle is impassable"),
|
||||
_("Check if the obstacle is impassable"),
|
||||
_("_PARAM0_ is impassable"),
|
||||
_("Obstacles"),
|
||||
"CppPlatform/Extensions/pathfindingobstacleicon24.png",
|
||||
|
@@ -419,9 +419,9 @@ module.exports = {
|
||||
aut
|
||||
.addCondition(
|
||||
'GravityX',
|
||||
_('Gravity X'),
|
||||
_('Test the world gravity on X.'),
|
||||
_('the gravity on X'),
|
||||
_('World gravity on X axis'),
|
||||
_('Compare the world gravity on X axis.'),
|
||||
_('the world gravity on X axis'),
|
||||
_('Global'),
|
||||
'res/physics24.png',
|
||||
'res/physics16.png'
|
||||
@@ -435,8 +435,8 @@ module.exports = {
|
||||
aut
|
||||
.addExpression(
|
||||
'GravityX',
|
||||
_('Gravity X'),
|
||||
_('Gravity X'),
|
||||
_('World gravity on X axis'),
|
||||
_('World gravity on X axis'),
|
||||
_('Global'),
|
||||
'res/physics16.png'
|
||||
)
|
||||
@@ -448,9 +448,9 @@ module.exports = {
|
||||
aut
|
||||
.addCondition(
|
||||
'GravityY',
|
||||
_('Gravity Y'),
|
||||
_('Test the world gravity on Y.'),
|
||||
_('the gravity on Y'),
|
||||
_('World gravity on Y axis'),
|
||||
_('Compare the world gravity on Y axis.'),
|
||||
_('the world gravity on Y axis'),
|
||||
_('Global'),
|
||||
'res/physics24.png',
|
||||
'res/physics16.png'
|
||||
@@ -464,8 +464,8 @@ module.exports = {
|
||||
aut
|
||||
.addExpression(
|
||||
'GravityY',
|
||||
_('Gravity Y'),
|
||||
_('Gravity Y'),
|
||||
_('World gravity on Y axis'),
|
||||
_('World gravity on Y axis'),
|
||||
_('Global'),
|
||||
'res/physics16.png'
|
||||
)
|
||||
@@ -477,9 +477,13 @@ module.exports = {
|
||||
aut
|
||||
.addAction(
|
||||
'Gravity',
|
||||
_('Gravity'),
|
||||
_('Modify the world gravity.'),
|
||||
_('Set the gravity to _PARAM2_;_PARAM3_'),
|
||||
_('World gravity'),
|
||||
_('Modify the world gravity.') +
|
||||
' ' +
|
||||
_(
|
||||
'While an object is needed, this will apply to all objects using the behavior.'
|
||||
),
|
||||
_('Set the world gravity of _PARAM0_ to _PARAM2_;_PARAM3_'),
|
||||
_('Global'),
|
||||
'res/physics24.png',
|
||||
'res/physics16.png'
|
||||
@@ -494,9 +498,9 @@ module.exports = {
|
||||
aut
|
||||
.addCondition(
|
||||
'TimeScale',
|
||||
_('Time scale'),
|
||||
_('Test the world time scale.'),
|
||||
_('the time scale'),
|
||||
_('World time scale'),
|
||||
_('Compare the world time scale.'),
|
||||
_('the world time scale'),
|
||||
_('Global'),
|
||||
'res/physics24.png',
|
||||
'res/physics16.png'
|
||||
@@ -511,9 +515,13 @@ module.exports = {
|
||||
extension
|
||||
.addAction(
|
||||
'TimeScale',
|
||||
_('Time scale'),
|
||||
_('Modify the world time scale.'),
|
||||
_('Set the world time scale to _PARAM2_'),
|
||||
_('World time scale'),
|
||||
_('Modify the world time scale.') +
|
||||
' ' +
|
||||
_(
|
||||
'While an object is needed, this will apply to all objects using the behavior.'
|
||||
),
|
||||
_('Set the world time scale of _PARAM0_ to _PARAM2_'),
|
||||
_('Global'),
|
||||
'res/physics24.png',
|
||||
'res/physics16.png'
|
||||
@@ -528,8 +536,8 @@ module.exports = {
|
||||
aut
|
||||
.addExpression(
|
||||
'TimeScale',
|
||||
_('Time scale'),
|
||||
_('Time scale'),
|
||||
_('World time scale'),
|
||||
_('World time scale'),
|
||||
_('Global'),
|
||||
'res/physics16.png'
|
||||
)
|
||||
@@ -2728,7 +2736,9 @@ module.exports = {
|
||||
.addAction(
|
||||
'AddMouseJoint',
|
||||
_('Add mouse joint'),
|
||||
_('Add a mouse joint between two joints.'),
|
||||
_(
|
||||
'Add a mouse joint to an object (makes the object move towards a specific point).'
|
||||
),
|
||||
_('Add a mouse joint to _PARAM0_'),
|
||||
_('Joints/Mouse'),
|
||||
'JsPlatform/Extensions/mouse_joint24.png',
|
||||
|
2
Extensions/Physics2Behavior/types.d.ts
vendored
Normal file
2
Extensions/Physics2Behavior/types.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
// TODO: Improve type checking by using proper typings for Box2D.
|
||||
declare var Box2D: any;
|
@@ -17,16 +17,17 @@ gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.getRendererObject = functio
|
||||
|
||||
gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.clear = function() {
|
||||
this._graphics.clear();
|
||||
this.updateOutline();
|
||||
};
|
||||
|
||||
gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawRectangle = function(x1, y1, x2, y2) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(this._object._fillColor, this._object._fillOpacity / 255);
|
||||
this._graphics.drawRect(x1, y1, x2 - x1, y2 - y1);
|
||||
this._graphics.endFill();
|
||||
};
|
||||
|
||||
gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawCircle = function(x, y, radius) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(this._object._fillColor, this._object._fillOpacity / 255);
|
||||
this._graphics.drawCircle(x, y, radius);
|
||||
this._graphics.endFill();
|
||||
@@ -55,12 +56,14 @@ gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawLineV2 = function(x1, y
|
||||
};
|
||||
|
||||
gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawEllipse = function(x1, y1, width, height) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(this._object._fillColor, this._object._fillOpacity / 255);
|
||||
this._graphics.drawEllipse(x1, y1, width/2, height/2);
|
||||
this._graphics.endFill();
|
||||
};
|
||||
|
||||
gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawRoundedRectangle = function(x1, y1, x2, y2, radius) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(this._object._fillColor, this._object._fillOpacity / 255);
|
||||
this._graphics.drawRoundedRect(x1, y1, x2 - x1, y2 - y1, radius);
|
||||
this._graphics.closePath();
|
||||
@@ -68,6 +71,7 @@ gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawRoundedRectangle = func
|
||||
};
|
||||
|
||||
gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawStar = function(x1, y1, points, radius, innerRadius, rotation) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(this._object._fillColor, this._object._fillOpacity / 255);
|
||||
this._graphics.drawStar(x1, y1, points, radius, innerRadius ? innerRadius : radius/2, rotation ? gdjs.toRad(rotation) : 0);
|
||||
this._graphics.closePath();
|
||||
@@ -75,6 +79,7 @@ gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawStar = function(x1, y1,
|
||||
};
|
||||
|
||||
gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawArc = function(x1, y1, radius, startAngle, endAngle, anticlockwise, closePath) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(this._object._fillColor, this._object._fillOpacity / 255);
|
||||
this._graphics.moveTo( x1 + radius * Math.cos(gdjs.toRad(startAngle)), y1 + radius * Math.sin(gdjs.toRad(startAngle)));
|
||||
this._graphics.arc(x1, y1, radius, gdjs.toRad(startAngle), gdjs.toRad(endAngle), anticlockwise ? true : false);
|
||||
@@ -85,6 +90,7 @@ gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawArc = function(x1, y1,
|
||||
};
|
||||
|
||||
gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawBezierCurve = function(x1, y1, cpX, cpY, cpX2, cpY2, x2, y2) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(this._object._fillColor, this._object._fillOpacity / 255);
|
||||
this._graphics.moveTo(x1, y1);
|
||||
this._graphics.bezierCurveTo(cpX, cpY, cpX2, cpY2, x2, y2);
|
||||
@@ -92,6 +98,7 @@ gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawBezierCurve = function(
|
||||
};
|
||||
|
||||
gdjs.ShapePainterRuntimeObjectPixiRenderer.prototype.drawQuadraticCurve = function(x1, y1, cpX, cpY, x2, y2) {
|
||||
this.updateOutline();
|
||||
this._graphics.beginFill(this._object._fillColor, this._object._fillOpacity / 255);
|
||||
this._graphics.moveTo(x1, y1);
|
||||
this._graphics.quadraticCurveTo(cpX, cpY, x2, y2);
|
||||
|
@@ -19,7 +19,9 @@
|
||||
* @property {number} outlineSize The size of the outline of the painted shape, in pixels.
|
||||
* @property {boolean} absoluteCoordinates Use absolute coordinates?
|
||||
* @property {boolean} clearBetweenFrames Clear the previous render before the next draw?
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {ObjectData & ShapePainterObjectDataType} ShapePainterObjectData
|
||||
*/
|
||||
|
||||
|
@@ -30,14 +30,14 @@ void DeclareSystemInfoExtension(gd::PlatformExtension& extension) {
|
||||
.SetIncludeFile("SystemInfo/SystemInfoTools.h");
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
"IsWebGLSupported",
|
||||
_("Is WebGL supported"),
|
||||
_("Check if GPU accelerated WebGL is supported on the target device."),
|
||||
_("WebGL is available"),
|
||||
_("System information"),
|
||||
"CppPlatform/Extensions/systeminfoicon24.png",
|
||||
"CppPlatform/Extensions/systeminfoicon16.png")
|
||||
.AddCondition("IsWebGLSupported",
|
||||
_("Is WebGL supported"),
|
||||
_("Check if GPU accelerated WebGL is supported on the "
|
||||
"target device."),
|
||||
_("WebGL is available"),
|
||||
_("System information"),
|
||||
"CppPlatform/Extensions/systeminfoicon24.png",
|
||||
"CppPlatform/Extensions/systeminfoicon16.png")
|
||||
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.SetFunctionName("SystemInfo::IsWebGLSupported")
|
||||
@@ -47,16 +47,28 @@ void DeclareSystemInfoExtension(gd::PlatformExtension& extension) {
|
||||
.AddCondition(
|
||||
"IsPreview",
|
||||
_("Is the game running as a preview"),
|
||||
_(
|
||||
"Check if the game is currently being previewed in the editor. "
|
||||
"This can be used to enable a \"Debug mode\" or do some work only in previews."
|
||||
),
|
||||
_("Check if the game is currently being previewed in the editor. "
|
||||
"This can be used to enable a \"Debug mode\" or do some work only "
|
||||
"in previews."),
|
||||
_("The game is being previewed in the editor"),
|
||||
_("System information"),
|
||||
"CppPlatform/Extensions/systeminfoicon24.png",
|
||||
"CppPlatform/Extensions/systeminfoicon16.png")
|
||||
|
||||
.AddCodeOnlyParameter("currentScene", "");
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
"HasTouchScreen",
|
||||
_("Device has a touchscreen"),
|
||||
_("Check if the device running the game has a touchscreen (typically "
|
||||
"Android phones, iPhones, iPads, but also some laptops)."),
|
||||
_("The device has a touchscreen"),
|
||||
_("System information"),
|
||||
"CppPlatform/Extensions/systeminfoicon24.png",
|
||||
"CppPlatform/Extensions/systeminfoicon16.png")
|
||||
|
||||
.AddCodeOnlyParameter("currentScene", "");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -35,6 +35,10 @@ class SystemInfoJsExtension : public gd::PlatformExtension {
|
||||
.codeExtraInformation
|
||||
.SetIncludeFile("Extensions/SystemInfo/systeminfotools.js")
|
||||
.SetFunctionName("gdjs.evtTools.systemInfo.isPreview");
|
||||
GetAllConditions()["SystemInfo::HasTouchScreen"]
|
||||
.codeExtraInformation
|
||||
.SetIncludeFile("Extensions/SystemInfo/systeminfotools.js")
|
||||
.SetFunctionName("gdjs.evtTools.systemInfo.hasTouchScreen");
|
||||
|
||||
StripUnimplementedInstructionsAndExpressions();
|
||||
GD_COMPLETE_EXTENSION_COMPILATION_INFORMATION();
|
||||
|
@@ -1,48 +1,120 @@
|
||||
// @ts-check
|
||||
/**
|
||||
GDevelop - SystemInfo Extension
|
||||
Copyright (c) 2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
* GDevelop - SystemInfo Extension
|
||||
* Copyright (c) 2016-present Florian Rival (Florian.Rival@gmail.com)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @memberof gdjs.evtTools
|
||||
* @class linkedObjects
|
||||
* @static
|
||||
* @private
|
||||
*/
|
||||
gdjs.evtTools.systemInfo = {};
|
||||
gdjs.evtTools.systemInfo = (function () {
|
||||
/** @type {?boolean} */
|
||||
let cachedIsMobile = null;
|
||||
/** @type {?boolean} */
|
||||
let cachedHasTouchScreen = null;
|
||||
|
||||
gdjs.evtTools.systemInfo.isMobile = function() {
|
||||
if (typeof cc !== "undefined" && cc.sys) {
|
||||
return cc.sys.isMobile;
|
||||
} else if (typeof Cocoon !== "undefined" && Cocoon.App) {
|
||||
return true;
|
||||
} else if (typeof window !== "undefined" && window.cordova) {
|
||||
return true;
|
||||
} else if (typeof window !== "undefined") {
|
||||
// Try to detect mobile device browsers.
|
||||
if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent)
|
||||
|| /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0,4))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/** @returns {boolean} */
|
||||
const checkIsMobile = () => {
|
||||
// @ts-ignore
|
||||
if (typeof cc !== 'undefined' && cc.sys) {
|
||||
// @ts-ignore
|
||||
return cc.sys.isMobile;
|
||||
|
||||
return false;
|
||||
};
|
||||
// @ts-ignore
|
||||
} else if (typeof Cocoon !== 'undefined' && Cocoon.App) {
|
||||
return true;
|
||||
|
||||
/**
|
||||
* Check if the the device supports WebGL.
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @returns {boolean} true if WebGL is supported
|
||||
*/
|
||||
gdjs.evtTools.systemInfo.isWebGLSupported = function(runtimeScene) {
|
||||
return runtimeScene.getGame().getRenderer().isWebGLSupported();
|
||||
};
|
||||
// @ts-ignore
|
||||
} else if (typeof window !== 'undefined' && window.cordova) {
|
||||
return true;
|
||||
} else if (typeof window !== 'undefined') {
|
||||
// Try to detect mobile device browsers.
|
||||
if (
|
||||
/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(
|
||||
navigator.userAgent
|
||||
) ||
|
||||
/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(
|
||||
navigator.userAgent.substr(0, 4)
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the game is running as a preview, launched from an editor.
|
||||
* @param {gdjs.RuntimeScene} runtimeScene The current scene.
|
||||
* @returns {boolean} true if the game is running as a preview.
|
||||
*/
|
||||
gdjs.evtTools.systemInfo.isPreview = function(runtimeScene) {
|
||||
return runtimeScene.getGame().isPreview();
|
||||
};
|
||||
// Try to detect iOS
|
||||
if (/iPad|iPhone|iPod/.test(navigator.platform)) {
|
||||
return true;
|
||||
} else if (/MacIntel/.test(navigator.platform)) {
|
||||
// Work around for recent iPads that are "desktop-class browsing".
|
||||
// We can still detect them using their touchscreen, but this is a hack.
|
||||
// If mac laptops start to support touchscreens, this won't work anymore. Hence it's better
|
||||
// to test for the presence of a touchscreen if needed rather than checking if the device
|
||||
// is "mobile".
|
||||
return !!navigator.maxTouchPoints && navigator.maxTouchPoints > 2;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the game runs on a mobile device (iPhone, iPad, Android).
|
||||
* Note that the distinction between what is a mobile device and what is not
|
||||
* is becoming blurry. If you use this for mobile controls,
|
||||
* prefer to check if the device has touchscreen support.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const isMobile = () => {
|
||||
if (cachedIsMobile !== null) {
|
||||
return cachedIsMobile;
|
||||
}
|
||||
|
||||
return (cachedIsMobile = checkIsMobile());
|
||||
};
|
||||
|
||||
/** @returns {boolean} */
|
||||
const checkHasTouchScreen = () => {
|
||||
// First check if the device is mobile, as all mobile devices have a touchscreen
|
||||
// and some older browsers don't have support for `navigator.maxTouchPoints`
|
||||
if (isMobile()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !!navigator.maxTouchPoints && navigator.maxTouchPoints > 2;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the device has a touchscreen
|
||||
*/
|
||||
const hasTouchScreen = () => {
|
||||
if (cachedHasTouchScreen !== null) {
|
||||
return cachedHasTouchScreen;
|
||||
}
|
||||
|
||||
return (cachedHasTouchScreen = checkHasTouchScreen());
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the the device supports WebGL.
|
||||
* @param {gdjs.RuntimeScene} runtimeScene
|
||||
* @returns {boolean} true if WebGL is supported
|
||||
*/
|
||||
const isWebGLSupported = (runtimeScene) => {
|
||||
return runtimeScene.getGame().getRenderer().isWebGLSupported();
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the game is running as a preview, launched from an editor.
|
||||
* @param {gdjs.RuntimeScene} runtimeScene The current scene.
|
||||
* @returns {boolean} true if the game is running as a preview.
|
||||
*/
|
||||
const isPreview = (runtimeScene) => {
|
||||
return runtimeScene.getGame().isPreview();
|
||||
};
|
||||
|
||||
return {
|
||||
isPreview: isPreview,
|
||||
isWebGLSupported: isWebGLSupported,
|
||||
hasTouchScreen: hasTouchScreen,
|
||||
isMobile: isMobile,
|
||||
};
|
||||
})();
|
||||
|
@@ -71,11 +71,3 @@ gdjs.TextEntryRuntimeObject.prototype.activate = function(enable) {
|
||||
this._activated = enable;
|
||||
this._renderer.activate(this._activated);
|
||||
};
|
||||
|
||||
gdjs.TextEntryRuntimeObject.prototype.setLayer = function(layer) {
|
||||
// No renderable object
|
||||
};
|
||||
|
||||
gdjs.TextEntryRuntimeObject.prototype.setZOrder = function(z) {
|
||||
// No renderable object
|
||||
};
|
||||
|
@@ -15,7 +15,9 @@
|
||||
* @property {number} color.g The Green level from 0 to 255
|
||||
* @property {number} color.b The Blue level from 0 to 255
|
||||
* @property {string} string The text of the object
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {ObjectData & TextObjectDataType} TextObjectData
|
||||
*/
|
||||
|
||||
@@ -384,7 +386,7 @@ gdjs.TextRuntimeObject.prototype.setColor = function(str) {
|
||||
|
||||
/**
|
||||
* Get the text color.
|
||||
* @return {String} The color as a "R;G;B" string, for example: "255;0;0"
|
||||
* @return {string} The color as a "R;G;B" string, for example: "255;0;0"
|
||||
*/
|
||||
gdjs.TextRuntimeObject.prototype.getColor = function(str) {
|
||||
return this._color[0] + ";" + this._color[1] + ";" + this._color[2];
|
||||
|
@@ -62,15 +62,15 @@ void DeclareTiledSpriteObjectExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
obj.AddAction(
|
||||
"SetColor",
|
||||
_("Global color"),
|
||||
_("Change the global color of a Tiled Sprite. The default color is white."),
|
||||
_("Change color of _PARAM0_ to _PARAM1_"),
|
||||
_("Tint color"),
|
||||
_("Change the tint of a Tiled Sprite. The default color is white."),
|
||||
_("Change tint of _PARAM0_ to _PARAM1_"),
|
||||
_("Effects"),
|
||||
"res/actions/color24.png",
|
||||
"res/actions/color.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "TiledSprite")
|
||||
.AddParameter("color", _("Color"));
|
||||
.AddParameter("color", _("Tint"));
|
||||
|
||||
obj.AddAction("Width",
|
||||
_("Width"),
|
||||
|
@@ -24,8 +24,7 @@ gdjs.TiledSpriteRuntimeObjectPixiRenderer.prototype.getRendererObject = function
|
||||
};
|
||||
|
||||
gdjs.TiledSpriteRuntimeObjectPixiRenderer.prototype.updateOpacity = function() {
|
||||
//TODO: Workaround a not working property in PIXI.js:
|
||||
this._tiledSprite.alpha = this._tiledSprite.visible ? this._object.opacity/255 : 0;
|
||||
this._tiledSprite.alpha = this._object.opacity/255;
|
||||
}
|
||||
|
||||
gdjs.TiledSpriteRuntimeObjectPixiRenderer.prototype.updatePosition = function() {
|
||||
|
@@ -7,7 +7,9 @@
|
||||
* @typedef {Object} TiledSpriteObjectDataType Initial properties for a Tiled Sprite object
|
||||
* @property {number} width The width of the object
|
||||
* @property {number} height The height of the object
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {ObjectData & TiledSpriteObjectDataType} TiledSpriteObjectData
|
||||
*/
|
||||
|
||||
@@ -213,7 +215,7 @@ gdjs.TiledSpriteRuntimeObject.prototype.setColor = function(rgbColor) {
|
||||
/**
|
||||
* Get the tint of the tiled sprite object.
|
||||
*
|
||||
* @returns {string} rgbColor The color, in RGB format ("128;200;255").
|
||||
* @returns {string} The color, in RGB format ("128;200;255").
|
||||
*/
|
||||
gdjs.TiledSpriteRuntimeObject.prototype.getColor = function() {
|
||||
return this._renderer.getColor();
|
||||
|
@@ -290,8 +290,8 @@ void DeclareTopDownMovementBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
aut.AddCondition(
|
||||
"Angle",
|
||||
_("Angle of movement"),
|
||||
_("Compare the angle of the top-down movemement of the object."),
|
||||
_("the angle of movemement"),
|
||||
_("Compare the angle of the top-down movement of the object."),
|
||||
_("the angle of movement"),
|
||||
_("Movement"),
|
||||
"CppPlatform/Extensions/topdownmovementicon24.png",
|
||||
"CppPlatform/Extensions/topdownmovementicon16.png")
|
||||
@@ -305,8 +305,8 @@ void DeclareTopDownMovementBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
aut.AddCondition(
|
||||
"XVelocity",
|
||||
_("Speed on X axis"),
|
||||
_("Compare the velocity of the top-down movemement of the object on the X axis."),
|
||||
_("the speed of movemement on X axis"),
|
||||
_("Compare the velocity of the top-down movement of the object on the X axis."),
|
||||
_("the speed of movement on X axis"),
|
||||
_("Movement"),
|
||||
"CppPlatform/Extensions/topdownmovementicon24.png",
|
||||
"CppPlatform/Extensions/topdownmovementicon16.png")
|
||||
@@ -320,8 +320,8 @@ void DeclareTopDownMovementBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
aut.AddCondition(
|
||||
"YVelocity",
|
||||
_("Speed on Y axis"),
|
||||
_("Compare the velocity of the top-down movemement of the object on the Y axis."),
|
||||
_("the speed of movemement on Y axis"),
|
||||
_("Compare the velocity of the top-down movement of the object on the Y axis."),
|
||||
_("the speed of movement on Y axis"),
|
||||
_("Movement"),
|
||||
"CppPlatform/Extensions/topdownmovementicon24.png",
|
||||
"CppPlatform/Extensions/topdownmovementicon16.png")
|
||||
@@ -347,7 +347,7 @@ void DeclareTopDownMovementBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
aut.AddCondition("DiagonalsAllowed",
|
||||
_("Diagonal movement"),
|
||||
_("Return true if the object is allowed to move diagonally"),
|
||||
_("Check if the object is allowed to move diagonally"),
|
||||
_("Allow diagonal moves for _PARAM0_"),
|
||||
_("Movement"),
|
||||
"CppPlatform/Extensions/topdownmovementicon24.png",
|
||||
@@ -375,7 +375,7 @@ void DeclareTopDownMovementBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
aut.AddCondition(
|
||||
"ObjectRotated",
|
||||
_("Object rotated"),
|
||||
_("Return true if the object is rotated while traveling on its path."),
|
||||
_("Check if the object is rotated while traveling on its path."),
|
||||
_("_PARAM0_ is rotated when moving"),
|
||||
_("Movement"),
|
||||
"CppPlatform/Extensions/topdownmovementicon24.png",
|
||||
|
@@ -66,8 +66,8 @@ module.exports = {
|
||||
tweenBehavior,
|
||||
new gd.BehaviorsSharedData()
|
||||
)
|
||||
.setIncludeFile("Extensions/TweenBehavior/tweenruntimebehavior.js")
|
||||
.addIncludeFile("Extensions/TweenBehavior/shifty.js");
|
||||
.setIncludeFile("Extensions/TweenBehavior/shifty.js")
|
||||
.addIncludeFile("Extensions/TweenBehavior/tweenruntimebehavior.js");
|
||||
|
||||
const easingChoices = JSON.stringify([
|
||||
"linear",
|
||||
@@ -198,6 +198,64 @@ module.exports = {
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName("addObjectPositionXTween");
|
||||
|
||||
behavior
|
||||
.addAction(
|
||||
"AddObjectWidthTween",
|
||||
_("Add object width tween"),
|
||||
_("Add a tween animation for the object width."),
|
||||
_(
|
||||
"Tween the width of _PARAM0_ to _PARAM3_ with easing _PARAM4_ over _PARAM5_ms as _PARAM2_"
|
||||
),
|
||||
_("Size"),
|
||||
"JsPlatform/Extensions/tween_behavior24.png",
|
||||
"JsPlatform/Extensions/tween_behavior32.png"
|
||||
)
|
||||
.addParameter("object", _("Object"), "", false)
|
||||
.addParameter("behavior", _("Behavior"), "TweenBehavior", false)
|
||||
.addParameter("string", _("Tween Identifier"), "", false)
|
||||
.addParameter("expression", _("To width"), "", false)
|
||||
.addParameter("stringWithSelector", _("Easing"), easingChoices, false)
|
||||
.setDefaultValue("linear")
|
||||
.addParameter("expression", _("Duration"), "", false)
|
||||
.addParameter(
|
||||
"yesorno",
|
||||
_("Destroy this object when tween finishes"),
|
||||
"",
|
||||
false
|
||||
)
|
||||
.setDefaultValue("no")
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName("addObjectWidthTween");
|
||||
|
||||
behavior
|
||||
.addAction(
|
||||
"AddObjectHeightTween",
|
||||
_("Add object height tween"),
|
||||
_("Add a tween animation for the object height."),
|
||||
_(
|
||||
"Tween the height of _PARAM0_ to _PARAM3_ with easing _PARAM4_ over _PARAM5_ms as _PARAM2_"
|
||||
),
|
||||
_("Size"),
|
||||
"JsPlatform/Extensions/tween_behavior24.png",
|
||||
"JsPlatform/Extensions/tween_behavior32.png"
|
||||
)
|
||||
.addParameter("object", _("Object"), "", false)
|
||||
.addParameter("behavior", _("Behavior"), "TweenBehavior", false)
|
||||
.addParameter("string", _("Tween Identifier"), "", false)
|
||||
.addParameter("expression", _("To height"), "", false)
|
||||
.addParameter("stringWithSelector", _("Easing"), easingChoices, false)
|
||||
.setDefaultValue("linear")
|
||||
.addParameter("expression", _("Duration"), "", false)
|
||||
.addParameter(
|
||||
"yesorno",
|
||||
_("Destroy this object when tween finishes"),
|
||||
"",
|
||||
false
|
||||
)
|
||||
.setDefaultValue("no")
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName("addObjectHeightTween");
|
||||
|
||||
behavior
|
||||
.addAction(
|
||||
"AddObjectPositionYTween",
|
||||
|
File diff suppressed because one or more lines are too long
@@ -125,12 +125,7 @@ gdjs.TweenRuntimeBehavior.prototype._resumeTween = function(identifier) {
|
||||
|
||||
// Resume the tween, and add it back to the scene of living tweens
|
||||
// (the invariant is that scene only contains tweens being played).
|
||||
tween.instance.resume().catch(function() {
|
||||
// Do nothing if the Promise is rejected. Rejection is used
|
||||
// by Shifty.js to signal that the tween was not finished.
|
||||
// We catch it to avoid an uncaught promise error, and to
|
||||
// ensure that the content of the "then" is always applied:
|
||||
});
|
||||
tween.instance.resume();
|
||||
if (this._runtimeScene.shiftyJsScene) {
|
||||
this._runtimeScene.shiftyJsScene.add(tween.instance);
|
||||
}
|
||||
@@ -180,12 +175,6 @@ gdjs.TweenRuntimeBehavior.prototype._setupTweenEnding = function(
|
||||
if (destroyObjectWhenFinished) {
|
||||
this._tweens[identifier].instance
|
||||
.tween()
|
||||
.catch(function() {
|
||||
// Do nothing if the Promise is rejected. Rejection is used
|
||||
// by Shifty.js to signal that the tween was not finished.
|
||||
// We catch it to avoid an uncaught promise error, and to
|
||||
// ensure that the content of the "then" is always applied:
|
||||
})
|
||||
.then(function() {
|
||||
that._removeObjectFromScene(identifier);
|
||||
})
|
||||
@@ -198,12 +187,6 @@ gdjs.TweenRuntimeBehavior.prototype._setupTweenEnding = function(
|
||||
} else {
|
||||
this._tweens[identifier].instance
|
||||
.tween()
|
||||
.catch(function() {
|
||||
// Do nothing if the Promise is rejected. Rejection is used
|
||||
// by Shifty.js to signal that the tween was not finished.
|
||||
// We catch it to avoid an uncaught promise error, and to
|
||||
// ensure that the content of the "then" is always applied:
|
||||
})
|
||||
.then(function() {
|
||||
if (that._tweens[identifier]) {
|
||||
that._tweens[identifier].hasFinished = true;
|
||||
@@ -817,6 +800,106 @@ gdjs.TweenRuntimeBehavior.prototype.addTextObjectCharacterSizeTween = function(
|
||||
this._setupTweenEnding(identifier, destroyObjectWhenFinished);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add an object width tween.
|
||||
* @param {string} identifier Unique id to idenfify the tween
|
||||
* @param {number} toWidth The target width
|
||||
* @param {string} easingValue Type of easing
|
||||
* @param {number} durationValue Duration in milliseconds
|
||||
* @param {boolean} destroyObjectWhenFinished Destroy this object when the tween ends
|
||||
*/
|
||||
gdjs.TweenRuntimeBehavior.prototype.addObjectWidthTween = function(
|
||||
identifier,
|
||||
toWidth,
|
||||
easingValue,
|
||||
durationValue,
|
||||
destroyObjectWhenFinished
|
||||
) {
|
||||
var that = this;
|
||||
if (!this._isActive) return;
|
||||
if (!!gdjs.TweenRuntimeBehavior.easings[easingValue]) return;
|
||||
|
||||
if (this._tweenExists(identifier)) {
|
||||
this.removeTween(identifier);
|
||||
}
|
||||
|
||||
var newTweenable = gdjs.TweenRuntimeBehavior.makeNewTweenable(
|
||||
this._runtimeScene
|
||||
);
|
||||
newTweenable.setConfig({
|
||||
from: {
|
||||
width: this.owner.getWidth(),
|
||||
},
|
||||
to: {
|
||||
width: toWidth,
|
||||
},
|
||||
duration: durationValue,
|
||||
easing: easingValue,
|
||||
step: function step(state) {
|
||||
that.owner.setWidth(state.width);
|
||||
},
|
||||
});
|
||||
|
||||
this._addTween(
|
||||
identifier,
|
||||
newTweenable,
|
||||
this._runtimeScene.getTimeManager().getTimeFromStart(),
|
||||
durationValue
|
||||
);
|
||||
|
||||
this._setupTweenEnding(identifier, destroyObjectWhenFinished);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add an object height tween.
|
||||
* @param {string} identifier Unique id to idenfify the tween
|
||||
* @param {number} toHeight The target height
|
||||
* @param {string} easingValue Type of easing
|
||||
* @param {number} durationValue Duration in milliseconds
|
||||
* @param {boolean} destroyObjectWhenFinished Destroy this object when the tween ends
|
||||
*/
|
||||
gdjs.TweenRuntimeBehavior.prototype.addObjectHeightTween = function(
|
||||
identifier,
|
||||
toHeight,
|
||||
easingValue,
|
||||
durationValue,
|
||||
destroyObjectWhenFinished
|
||||
) {
|
||||
var that = this;
|
||||
if (!this._isActive) return;
|
||||
if (!!gdjs.TweenRuntimeBehavior.easings[easingValue]) return;
|
||||
|
||||
if (this._tweenExists(identifier)) {
|
||||
this.removeTween(identifier);
|
||||
}
|
||||
|
||||
var newTweenable = gdjs.TweenRuntimeBehavior.makeNewTweenable(
|
||||
this._runtimeScene
|
||||
);
|
||||
newTweenable.setConfig({
|
||||
from: {
|
||||
height: this.owner.getHeight(),
|
||||
},
|
||||
to: {
|
||||
height: toHeight,
|
||||
},
|
||||
duration: durationValue,
|
||||
easing: easingValue,
|
||||
step: function step(state) {
|
||||
that.owner.setHeight(state.height);
|
||||
},
|
||||
});
|
||||
|
||||
this._addTween(
|
||||
identifier,
|
||||
newTweenable,
|
||||
this._runtimeScene.getTimeManager().getTimeFromStart(),
|
||||
durationValue
|
||||
);
|
||||
|
||||
this._setupTweenEnding(identifier, destroyObjectWhenFinished);
|
||||
};
|
||||
|
||||
/**
|
||||
* Tween is playing.
|
||||
* @param {string} identifier Unique id to idenfify the tween
|
||||
@@ -1030,23 +1113,15 @@ gdjs.registerRuntimeSceneResumedCallback(function(runtimeScene) {
|
||||
gdjs.TweenRuntimeBehavior._tweensProcessed = false;
|
||||
gdjs.TweenRuntimeBehavior._currentTweenTime = 0;
|
||||
|
||||
gdjs.TweenRuntimeBehavior.prototype.doStepPreEvents = function(runtimeScene) {
|
||||
// Process tweens (once per frame).
|
||||
if (!gdjs.TweenRuntimeBehavior._tweensProcessed) {
|
||||
gdjs.TweenRuntimeBehavior._currentTweenTime = runtimeScene
|
||||
.getTimeManager()
|
||||
.getTimeFromStart();
|
||||
shifty.processTweens();
|
||||
gdjs.TweenRuntimeBehavior._tweensProcessed = true;
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.TweenRuntimeBehavior.prototype.doStepPostEvents = function(runtimeScene) {
|
||||
gdjs.TweenRuntimeBehavior._tweensProcessed = false;
|
||||
};
|
||||
gdjs.registerRuntimeScenePreEventsCallback(function(runtimeScene) {
|
||||
gdjs.TweenRuntimeBehavior._currentTweenTime = runtimeScene
|
||||
.getTimeManager()
|
||||
.getTimeFromStart();
|
||||
shifty.processTweens();
|
||||
});
|
||||
|
||||
// Set up Shifty.js so that the processing ("tick"/updates) is handled
|
||||
// by the behavior (once per frame):
|
||||
// by the behavior, once per frame. See above.
|
||||
shifty.Tweenable.setScheduleFunction(function() {
|
||||
/* Do nothing, we'll call processTweens manually. */
|
||||
});
|
||||
|
@@ -5,7 +5,9 @@
|
||||
* @property {boolean} content.loop Does the video loops itself?
|
||||
* @property {number} content.volume The volume of the video
|
||||
* @property {string} content.videoResource Name of the resource corresponding to the video
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {ObjectData & VideoObjectDataType} VideoObjectData
|
||||
*/
|
||||
|
||||
|
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
#include "JsCodeEvent.h"
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
#include "GDCore/Events/Tools/EventsCodeNameMangler.h"
|
||||
@@ -19,7 +20,7 @@ using namespace std;
|
||||
namespace gdjs {
|
||||
|
||||
vector<pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
JsCodeEvent::GetAllExpressionsWithMetadata() {
|
||||
JsCodeEvent::GetAllExpressionsWithMetadata() {
|
||||
vector<pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
allExpressionsWithMetadata;
|
||||
auto metadata = gd::ParameterMetadata().SetType("object");
|
||||
@@ -30,7 +31,7 @@ vector<pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
}
|
||||
|
||||
vector<pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
JsCodeEvent::GetAllExpressionsWithMetadata() const {
|
||||
JsCodeEvent::GetAllExpressionsWithMetadata() const {
|
||||
vector<pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
allExpressionsWithMetadata;
|
||||
auto metadata = gd::ParameterMetadata().SetType("object");
|
||||
@@ -45,15 +46,14 @@ void JsCodeEvent::SerializeTo(gd::SerializerElement& element) const {
|
||||
element.AddChild("parameterObjects")
|
||||
.SetValue(parameterObjects.GetPlainString());
|
||||
element.AddChild("useStrict").SetValue(useStrict);
|
||||
element.AddChild("eventsSheetExpanded").SetValue(eventsSheetExpanded);
|
||||
}
|
||||
|
||||
void JsCodeEvent::UnserializeFrom(gd::Project& project,
|
||||
const gd::SerializerElement& element) {
|
||||
inlineCode = element.GetChild("inlineCode").GetValue().GetString();
|
||||
parameterObjects =
|
||||
gd::Expression(element.GetChild("parameterObjects")
|
||||
.GetValue()
|
||||
.GetString());
|
||||
parameterObjects = gd::Expression(
|
||||
element.GetChild("parameterObjects").GetValue().GetString());
|
||||
|
||||
if (!element.HasChild("useStrict")) {
|
||||
// Compatibility with GD <= 5.0.0-beta68
|
||||
@@ -62,11 +62,20 @@ void JsCodeEvent::UnserializeFrom(gd::Project& project,
|
||||
} else {
|
||||
useStrict = element.GetChild("useStrict").GetBoolValue();
|
||||
}
|
||||
|
||||
if (!element.HasChild("eventsSheetExpanded")) {
|
||||
// Compatibility with GD <= 5.0.0-beta101
|
||||
eventsSheetExpanded = false;
|
||||
// end of compatibility code
|
||||
} else {
|
||||
eventsSheetExpanded = element.GetChild("eventsSheetExpanded").GetBoolValue();
|
||||
}
|
||||
}
|
||||
|
||||
JsCodeEvent::JsCodeEvent()
|
||||
: BaseEvent(),
|
||||
inlineCode("runtimeScene.setBackgroundColor(100,100,240);\n"),
|
||||
useStrict(true) {}
|
||||
useStrict(true),
|
||||
eventsSheetExpanded(false) {}
|
||||
|
||||
} // namespace gdjs
|
||||
|
@@ -47,6 +47,9 @@ class JsCodeEvent : public gd::BaseEvent {
|
||||
const gd::SerializerElement& element);
|
||||
virtual bool IsUseStrict() const { return useStrict; }
|
||||
|
||||
bool IsEventsSheetExpanded() const { return eventsSheetExpanded; }
|
||||
void SetEventsSheetExpanded(bool enable) { eventsSheetExpanded = enable; };
|
||||
|
||||
private:
|
||||
void Init(const JsCodeEvent& event);
|
||||
|
||||
@@ -56,6 +59,7 @@ class JsCodeEvent : public gd::BaseEvent {
|
||||
bool useStrict; ///< Should the generated JS function have "use strict". true
|
||||
///< by default. Should be removed once all the game engine
|
||||
///< is using "use strict".
|
||||
bool eventsSheetExpanded; ///< Is the code block expanded in the events sheet?
|
||||
};
|
||||
|
||||
} // namespace gdjs
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user