Compare commits

...

37 Commits

Author SHA1 Message Date
Florian Rival
2b60377820 Remove deprecated/unused/unmaintained GDCpp code
* This also includes extensions code.

Only show in developer changelog
2021-08-16 23:23:09 +02:00
Florian Rival
4b19696523 Add missing extensions on the web-app (Screenshot, AdvancedWindow)
Don't show in changelog
2021-08-16 20:43:06 +02:00
Florian Rival
32978c22e8 Fix games crashing when an unknown action/condition was used (could come from a deleted extension) 2021-08-16 19:36:52 +02:00
Florian Rival
1f6f2701ff Fix variable dropdown not updated in the action/condition editor after editing variables 2021-08-16 16:42:43 +02:00
Florian Rival
fbf2340f00 Fix a crash when drag'n'dropping actions/conditions in custom behaviors 2021-08-16 16:37:59 +02:00
Florian Rival
4ff208b39f Allow again to choose the opacity of the grid in the scene editor
* Also fix an issue where a grid with the black color was not persisted properly.

Fix #2922 and fix #2918
2021-08-16 11:33:56 +02:00
Florian Rival
3d0a893c1c Autoclose beta 114 upgrade issue [skip ci] 2021-08-13 15:03:59 +02:00
Clément Pasteau
2581021a57 Ensure the deployment script stops on error 2021-08-13 10:39:23 +02:00
Clément Pasteau
e4fc065dc1 Bump newIDE Version 2021-08-12 17:27:30 +02:00
Florian Rival
d1f4d26e49 Fix color of grids in scene editor not properly persisted
* Also make the update real time (any change in the settings are shown directly in the editor)

Don't show the rest in the changelog:

* Add various Flow typings where missing (SetupGridDialog and various InstancesEditor files)
* Serialize the settings into a generic "EditorSetting" (so that the Project is agnostic of any editor related stuff)
* Rename uiSettings/options/LayoutEditorCanvasOptions to InstancesEditorSettings
  * Handle everything inside the IDE (so that the Project remains agnostic of any editor related stuff)

Note that in the future, this kind of EditorSetting that is stored inside the project could be moved to its own structure (living outside of the project file).
2021-08-12 17:05:32 +02:00
ClementPasteau
a1b840a4fa Add Release Ladder action to Platformer Object Behavior (#2892)
Allow a Platformer Object to simulate a "Release Ladder" action
2021-08-12 15:54:19 +02:00
Florian Rival
465629b688 Add a way to set the "extra info" of a parameter without automatic namespace addition for objects/behaviors
Don't show in changelog
2021-08-12 10:28:01 +02:00
ClementPasteau
38758c62c6 Improve Actions and Conditions search allowing typing mistakes (fuzzy) (#2891) 2021-08-11 17:40:20 +02:00
Aurélien Vivet
26f6e95e46 Show previews of image resources properly pixelated when smoothing is deactivated (#2882) 2021-08-09 17:09:58 +02:00
Aurélien Vivet
34abf8290e Bump newIDE version (#2880) 2021-08-07 14:33:54 +02:00
Aurélien Vivet
52677f5512 Show pixel art assets in the asset store as pixelated and larger (#2838) 2021-08-05 20:27:47 +02:00
ClementPasteau
df2b51bb1b Increase the NewIDE tests jest timeout (#2878)
Don't show in changelog
2021-08-05 15:12:52 +02:00
ClementPasteau
6b0ff984f2 Fix Panel Sprite initial opacity not being correctly applied (#2873)
Fix Panel Sprite initial opacity not being correctly applied
2021-08-05 14:25:43 +02:00
D8H
f4512242e4 Add an action to clear the shapes of a Shape Painter object on demand (#2868) 2021-08-04 13:10:29 +02:00
D8H
8beabbadef Add an action to forbid to jump again while in the air to the Platformer behavior. (#2872)
* This is useful if you want to allow to jump again in the air for a bit of time, and then forbid to jump again later (for example, to implement a "Coyote Time" feature to your player character)
2021-08-04 12:29:38 +02:00
Todor Imreorov
9491a8ed45 Fix buttons to save/load/change the file in Piskel sometimes not displayed properly (#2844) 2021-08-04 11:29:35 +02:00
D8H
f945dfd987 Fix an error log when the new instruction dialog opens (#2869)
Don't show in changelog
2021-08-04 09:35:04 +02:00
Florian Rival
ff42591354 Increase the GDJS tests Karma timeout (#2861)
Semaphore CI tests were sometimes timing out, notably the ones involving PixiJS and real resources to load.

Don't show in changelog
2021-08-03 16:20:35 +02:00
D8H
21fb93c66a Improve TypeScript types for the Shape Painter object (#2860)
Only show in developer changelog
2021-08-03 16:17:11 +02:00
Arthur Pacaud
068fbe653a Add new lines between functions back in TS files (#2859)
Only show in developer changelog
2021-08-03 14:35:07 +02:00
Florian Rival
80891dcc59 Fix readme link
[skip ci]
Don't show in changelog
2021-08-02 19:57:24 +02:00
ClementPasteau
34155d65f1 Fix color picker not shown for the action setting the color of a light object (#2857) 2021-08-02 19:01:16 +02:00
Florian Rival
18f22470ca Fix wrong icon shown intermittently in the extensions store 2021-08-01 20:22:24 +02:00
Florian Rival
92a8ebc58b Fix extra scrollbar on small screens when selecting an object or an action/condition in the events sheet 2021-08-01 19:11:29 +02:00
Florian Rival
565384e270 Fix unability to scroll when a lot of parameters were shown for an action or a condition 2021-08-01 19:11:29 +02:00
Florian Rival
8335b2edf9 Add continuous delivery: automatic macOS and Windows builds (#2854)
* This automatically builds the signed macOS app, the Windows exe and AppX, the Linux AppImage.
* This is only for master and any "experimental-build/xxx" branches.
* Only Travis CI and Semaphore CI are running tests, for all branches.
2021-07-31 18:12:19 +02:00
Aurélien Vivet
12c77d0455 Add thumbnails in the resources list (#2842) 2021-07-27 15:59:06 +02:00
Florian Rival
13b62a06eb Add option to allow building Android App Bundles that can be uploaded if you already published APKs with Play App Signing enabled for your game
* If you already opted in for "Play App Signing" in the Play Developer Console and published some APKs like this, you need to enable the new "Old upload key" option, in the Signing Option, before *each* packaging for Android.
* Read this [page to learn more](http://wiki.compilgames.net/doku.php/gdevelop5/publishing/android_and_ios/play-store/upgrading-from-apk-to-aab#done_you_can_now_upload_your_aab) and have step by step details of what to do to update your game.
* If you publish a new game with Android App Bundles, there is nothing to do!
2021-07-22 15:09:58 +01:00
Florian Rival
d27119d8ea Remove deprecated examples upload script from web-app deployment
Don't show in changelog
2021-07-21 17:25:40 +01:00
Florian Rival
dd3ff554d5 Upgrade AppVeyor CI to Node.js 14 (#2826)
[ci skip] [skip ci]
2021-07-20 23:36:56 +01:00
Florian Rival
287a17b634 Add a maximum size for the GDevelop logo so that it's not too big on large resolutions 2021-07-20 18:13:42 +01:00
Florian Rival
7dc477e29e Bump newIDE version 2021-07-20 15:53:20 +01:00
1005 changed files with 13018 additions and 221683 deletions

View File

@@ -1,9 +1,75 @@
# CircleCI 2.0 configuration file to build GDevelop app running
# on the Electron runtime (newIDE/electron-app).
# CircleCI configuration to build GDevelop app running
# on the Electron runtime (newIDE/electron-app) for macOS and Linux.
# For Windows, see the appveyor.yml file.
version: 2
version: 2.1
jobs:
build:
build-macos:
macos:
xcode: 12.5.1
steps:
- checkout
# System dependencies (for Emscripten and upload)
- run:
name: Install dependencies for Emscripten and AWS S3 upload
command: brew install cmake && brew install awscli
- run:
name: Install Emscripten (for GDevelop.js)
command: git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 1.39.6 && ./emsdk activate 1.39.6 && cd ..
# GDevelop.js dependencies
- restore_cache:
keys:
- gd-macos-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}
# fallback to using the latest cache if no exact match is found
- gd-macos-nodejs-dependencies---
- run:
name: Install GDevelop.js dependencies and build it
command: cd GDevelop.js && npm install && cd ..
# Build GDevelop.js (and run tests to ensure it works)
- run:
name: Build GDevelop.js
command: cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && npm test && cd ..
# GDevelop IDE dependencies (after building GDevelop.js to avoid downloading a pre-built version)
- run:
name: Install GDevelop IDE dependencies
command: cd newIDE/app && npm install && cd ../electron-app && npm install
- save_cache:
paths:
- newIDE/electron-app/node_modules
- newIDE/app/node_modules
- GDevelop.js/node_modules
key: gd-macos-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}
# Build GDevelop IDE (seems like we need to allow Node.js to use more space than usual)
# Note: Code signing is done using CSC_LINK (see https://www.electron.build/code-signing).
- run:
name: Build GDevelop IDE
command: export NODE_OPTIONS="--max-old-space-size=7168" && cd newIDE/electron-app && npm run build -- --mac --publish=never
- run:
name: Clean dist folder to keep only installers/binaries.
command: rm -rf "newIDE/electron-app/dist/mac/GDevelop 5.app"
# Upload artifacts (CircleCI)
- store_artifacts:
path: newIDE/electron-app/dist
# Upload artifacts (AWS)
- run:
name: Deploy to S3 (specific commit)
command: aws s3 sync newIDE/electron-app/dist s3://gdevelop-releases/$(git rev-parse --abbrev-ref HEAD)/commit/$(git rev-parse HEAD)/
- run:
name: Deploy to S3 (latest)
command: aws s3 sync newIDE/electron-app/dist s3://gdevelop-releases/$(git rev-parse --abbrev-ref HEAD)/latest/
build-linux:
# CircleCI docker workers are failing if they don't have enough memory (no swap)
resource_class: xlarge
docker:
@@ -23,10 +89,6 @@ jobs:
name: Install Emscripten (for GDevelop.js)
command: git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 1.39.6 && ./emsdk activate 1.39.6 && cd ..
- run:
name: Install Wine for Electron builder
command: sudo dpkg --add-architecture i386 && sudo apt-get update && sudo apt install wine32
- run:
name: Install system dependencies for Electron builder
command: sudo apt install icnsutils && sudo apt install graphicsmagick && sudo apt install rsync
@@ -34,15 +96,15 @@ jobs:
# GDevelop.js dependencies
- restore_cache:
keys:
- gd-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}
- gd-linux-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}
# fallback to using the latest cache if no exact match is found
- gd-nodejs-dependencies---
- gd-linux-nodejs-dependencies---
- run:
name: Install GDevelop.js dependencies and build it
command: cd GDevelop.js && sudo npm install -g grunt-cli && npm install && cd ..
command: cd GDevelop.js && npm install && cd ..
# Build GDevelop.js
# Build GDevelop.js (and run tests to ensure it works)
- run:
name: Build GDevelop.js
command: cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && npm test && cd ..
@@ -57,16 +119,16 @@ jobs:
- newIDE/electron-app/node_modules
- newIDE/app/node_modules
- GDevelop.js/node_modules
key: gd-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}
key: gd-linux-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}
# Build GDevelop IDE (seems like we need to allow Node.js to use more space than usual)
- run:
name: Build GDevelop IDE
command: export NODE_OPTIONS="--max-old-space-size=7168" && 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 -- --linux AppImage --publish=never
- run:
name: Clean dist folder to keep only installers/binaries.
command: rm -rf newIDE/electron-app/dist/linux-unpacked && rm -rf newIDE/electron-app/dist/win-unpacked && rm -rf newIDE/electron-app/dist/mac
command: rm -rf newIDE/electron-app/dist/linux-unpacked
# Upload artifacts (CircleCI)
- store_artifacts:
@@ -79,3 +141,20 @@ jobs:
- run:
name: Deploy to S3 (latest)
command: aws s3 sync newIDE/electron-app/dist s3://gdevelop-releases/$(git rev-parse --abbrev-ref HEAD)/latest/
workflows:
builds:
jobs:
- build-macos:
filters:
branches:
only:
- master
- /experimental-build.*/
- build-linux:
filters:
branches:
only:
- master
- /experimental-build.*/

View File

@@ -13,6 +13,5 @@
-fPIC
-I./ExtLibs/SFML/include
-I./Core
-I./GDCpp/.
-I./GDJS/.
-F./ExtLibs/SFML/extlibs/libs-osx/Frameworks

1
.gitattributes vendored
View File

@@ -1,6 +1,5 @@
Core/GDCore/Serialization/rapidjson/rapidjson.h/* linguist-vendored
Core/GDCore/TinyXml/* linguist-vendored
GDCpp/GDCpp/Runtime/TinyXml/* linguist-vendored
Extensions/ParticleSystem/SPARK/* linguist-vendored
Extensions/PhysicsBehavior/Box2D/* linguist-vendored
Extensions/PhysicsBehavior/box2djs/* linguist-vendored

View File

@@ -18,3 +18,11 @@ jobs:
type: "body"
regex: ".*_instance.getRawFloatProperty is not a function.*"
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed as this seems to be a known bug. It can be solved by **closing entirely the web-app and opening it again**. This will allow the web-app to auto-update and the problem should be gone."
- name: Autoclose known beta 114 web-app update bug
uses: arkon/issue-closer-action@v1.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
type: "body"
regex: ".*getAssociatedSettings is not a function.*"
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed as this seems to be a known bug. It can be solved by **closing entirely the web-app and opening it again**. This will allow the web-app to auto-update and the problem should be gone."

1
.gitignore vendored
View File

@@ -16,7 +16,6 @@
*.bc
/Binaries/Output
*.autosave
!/GDCpp/scripts/bcp.exe
!/scripts/libgettextlib-0-17.dll
!/scripts/libgettextsrc-0-17.dll
!/xgettext.exe

View File

@@ -1,3 +1,12 @@
# Travis CI configuration to build and run all tests
# (and typing/formatting) for the Core, newIDE, GDJS.
#
# This builds GDevelop.js and store it on a S3 so it can be used to run
# GDevelop without building it.
#
# See also Semaphore CI for quick tests (not building GDevelop.js, so
# faster but not always reliable).
language: cpp
sudo: false
compiler:
@@ -53,7 +62,7 @@ before_install:
install:
#Get the correct version of gcc/g++
- if [ "$CXX" = "g++" ]; then export CXX="g++-${GCC_VERSION}" CC="gcc-${GCC_VERSION}"; fi
#Compile the tests only for GDCore and GDCpp
#Compile the tests only for GDCore
- mkdir .build-tests
- cd .build-tests
- cmake -DBUILD_GDJS=FALSE -DBUILD_TESTS=TRUE -DCMAKE_CXX_COMPILER=$(which $CXX) -DCMAKE_C_COMPILER=$(which $CC) ..
@@ -80,12 +89,9 @@ install:
- cd ../..
script:
# GDCore and GDCpp game engine tests:
# GDCore tests:
- cd .build-tests
- Core/GDCore_tests
- GDCpp/GDCpp_tests
- Extensions/PathfindingBehavior/PathfindingBehavior_Runtime_tests
- Extensions/LinkedObjects/LinkedObjects_Runtime_tests
- cd ..
# GDevelop.js tests
- cd GDevelop.js

View File

@@ -4,7 +4,6 @@
"name": "Mac",
"includePath": [
"${workspaceRoot}",
"${workspaceRoot}/GDCpp",
"${workspaceRoot}/GDJS",
"${workspaceRoot}/Extensions",
"${workspaceRoot}/Core",
@@ -43,7 +42,6 @@
"name": "Linux",
"includePath": [
"${workspaceRoot}",
"${workspaceRoot}/GDCpp",
"${workspaceRoot}/GDJS",
"${workspaceRoot}/Extensions",
"${workspaceRoot}/Core",
@@ -70,7 +68,6 @@
"name": "Win32",
"includePath": [
"${workspaceRoot}",
"${workspaceRoot}/GDCpp",
"${workspaceRoot}/GDJS",
"${workspaceRoot}/Extensions",
"${workspaceRoot}/Core",

View File

@@ -1,3 +1,3 @@
This is the directory where native or WebAssembly binaries of the C++ code of GDCore, GDCpp and GDJS are produced.
This is the directory where native or WebAssembly binaries of the C++ code of GDCore and GDJS are produced.
See GDevelop.js README for the instructions to compile after a change in the C++ source code.

View File

@@ -92,9 +92,6 @@ ENDIF()
IF(BUILD_GDJS)
ADD_SUBDIRECTORY(GDJS)
ENDIF()
IF(BUILD_GDCPP)
ADD_SUBDIRECTORY(GDCpp)
ENDIF()
IF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/GDevelop.js/CMakeLists.txt" AND EMSCRIPTEN)
ADD_SUBDIRECTORY(GDevelop.js)
ENDIF()

View File

@@ -14,9 +14,8 @@
*
* \section other Other documentations
*
* GDevelop is architectured around a `Core` (this library), platforms (`GDJS`, `GDCpp`) and extensions (`Extensions` folder). The editor (`newIDE` folder) is using all of these libraries.
* GDevelop is architectured around a `Core` (this library), a game engine (`GDJS`) and extensions (`Extensions` folder). The editor (`newIDE` folder) is using all of these libraries.
*
* - [Open GDevelop C++ Platform documentation](../GDCpp Documentation/index.html)
* - [Open GDevelop JS Platform documentation](../GDJS Documentation/index.html)
* - <a href="https://github.com/4ian/GDevelop/blob/master/newIDE/README.md">Getting started with the editor</a>
* - <a href="https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md">Getting started with the extensions</a>

View File

@@ -261,8 +261,11 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
EventsCodeGenerationContext& context) {
gd::String conditionCode;
gd::InstructionMetadata instrInfos =
const gd::InstructionMetadata& instrInfos =
MetadataProvider::GetConditionMetadata(platform, condition.GetType());
if (MetadataProvider::IsBadInstructionMetadata(instrInfos)) {
return "/* Unknown instruction - skipped. */";
}
AddIncludeFiles(instrInfos.codeExtraInformation.GetIncludeFiles());
maxConditionsListsSize =
@@ -299,15 +302,13 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
!GetObjectsAndGroups().GetObjectGroups().Has(objectInParameter) &&
!GetGlobalObjectsAndGroups().GetObjectGroups().Has(
objectInParameter)) {
condition.SetParameter(pNb, gd::Expression(""));
condition.SetType("");
return "/* Unknown object - skipped. */";
} else if (!instrInfos.parameters[pNb].supplementaryInformation.empty() &&
gd::GetTypeOfObject(GetGlobalObjectsAndGroups(),
GetObjectsAndGroups(),
objectInParameter) !=
instrInfos.parameters[pNb].supplementaryInformation) {
condition.SetParameter(pNb, gd::Expression(""));
condition.SetType("");
return "/* Mismatched object type - skipped. */";
}
}
}
@@ -425,6 +426,11 @@ gd::String EventsCodeGenerator::GenerateConditionsListCode(
outputCode += "{\n";
outputCode += conditionCode;
outputCode += "}";
} else {
// Deprecated way to cancel code generation - but still honor it.
// Can be removed once condition is passed by const reference to
// GenerateConditionCode.
outputCode += "/* Skipped condition (empty type) */";
}
}
@@ -440,8 +446,11 @@ gd::String EventsCodeGenerator::GenerateActionCode(
gd::Instruction& action, EventsCodeGenerationContext& context) {
gd::String actionCode;
gd::InstructionMetadata instrInfos =
const gd::InstructionMetadata& instrInfos =
MetadataProvider::GetActionMetadata(platform, action.GetType());
if (MetadataProvider::IsBadInstructionMetadata(instrInfos)) {
return "/* Unknown instruction - skipped. */";
}
AddIncludeFiles(instrInfos.codeExtraInformation.GetIncludeFiles());
@@ -466,15 +475,13 @@ gd::String EventsCodeGenerator::GenerateActionCode(
!GetObjectsAndGroups().GetObjectGroups().Has(objectInParameter) &&
!GetGlobalObjectsAndGroups().GetObjectGroups().Has(
objectInParameter)) {
action.SetParameter(pNb, gd::Expression(""));
action.SetType("");
return "/* Unknown object - skipped. */";
} else if (!instrInfos.parameters[pNb].supplementaryInformation.empty() &&
gd::GetTypeOfObject(GetGlobalObjectsAndGroups(),
GetObjectsAndGroups(),
objectInParameter) !=
instrInfos.parameters[pNb].supplementaryInformation) {
action.SetParameter(pNb, gd::Expression(""));
action.SetType("");
return "/* Mismatched object type - skipped. */";
}
}
}
@@ -556,7 +563,14 @@ gd::String EventsCodeGenerator::GenerateActionsListCode(
gd::String actionCode = GenerateActionCode(actions[aId], context);
outputCode += "{";
if (!actions[aId].GetType().empty()) outputCode += actionCode;
if (actions[aId].GetType().empty()) {
// Deprecated way to cancel code generation - but still honor it.
// Can be removed once action is passed by const reference to
// GenerateActionCode.
outputCode += "/* Skipped action (empty type) */";
} else {
outputCode += actionCode;
}
outputCode += "}";
}

View File

@@ -462,24 +462,21 @@ class GD_CORE_API EventsCodeGenerator {
* Other standard parameters type that should be implemented by platforms:
* - currentScene: Reference to the current runtime scene.
* - objectList : a map containing lists of objects which are specified by the
object name in another parameter. (C++: std::map <gd::String,
std::vector<RuntimeObject*> *>). Example:
object name in another parameter. Example:
* \code
AddExpression("Count", _("Object count"), _("Count the number of picked
objects"), _("Objects"), "res/conditions/nbObjet.png")
.AddParameter("objectList", _("Object"))
.SetFunctionName("PickedObjectsCount").SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
.SetFunctionName("getPickedObjectsCount");
* \endcode
* - objectListWithoutPicking : Same as objectList but do not pick object if
they are not already picked.
* - objectPtr : Return a pointer to object specified by the object name in
another parameter ( C++: RuntimeObject* ). Example:
* - objectPtr : Return a reference to the object specified by the object name in
another parameter. Example:
* \code
.AddParameter("object", _("Object"))
.AddParameter("objectPtr", _("Target object"))
//The called function will be called with this signature on the C++ platform:
Function(gd::String, RuntimeObject*)
* \endcode
*/
virtual gd::String GenerateParameterCodes(

View File

@@ -16,7 +16,6 @@
#include "GDCore/String.h"
namespace gd {
class EventsList;
class MainFrameWrapper;
class Project;
class Layout;
class EventsCodeGenerator;

View File

@@ -7,7 +7,6 @@
#include <SFML/Graphics/Sprite.hpp>
#include <iostream>
#include "GDCore/Extensions/Builtin/SpriteExtension/Polygon2d.h"
#include "GDCore/Project/ImageManager.h"
using namespace std;
@@ -16,11 +15,7 @@ namespace gd {
Point Sprite::badPoint("");
Sprite::Sprite()
:
#if !defined(EMSCRIPTEN)
hasItsOwnImage(false),
#endif
automaticCollisionMask(true),
: automaticCollisionMask(true),
origine("origine"),
centre("centre"),
automaticCentre(true) {
@@ -73,36 +68,10 @@ Point& Sprite::GetPoint(const gd::String& name) {
bool Sprite::SetDefaultCenterPoint(bool enabled) {
automaticCentre = enabled;
#if !defined(EMSCRIPTEN)
if (automaticCentre)
centre.SetXY(sfmlSprite.getLocalBounds().width / 2,
sfmlSprite.getLocalBounds().height / 2);
#endif
return true;
}
std::vector<Polygon2d> Sprite::GetCollisionMask() const {
// TODO(perf): Cache to avoid re-creating a mask at every call
#if !defined(EMSCRIPTEN)
if (automaticCollisionMask) {
std::vector<Polygon2d> mask;
Polygon2d rectangle;
rectangle.vertices.push_back(sf::Vector2f(0, 0));
rectangle.vertices.push_back(
sf::Vector2f(sfmlSprite.getLocalBounds().width, 0));
rectangle.vertices.push_back(sf::Vector2f(
sfmlSprite.getLocalBounds().width, sfmlSprite.getLocalBounds().height));
rectangle.vertices.push_back(
sf::Vector2f(0, sfmlSprite.getLocalBounds().height));
mask.push_back(rectangle);
return mask;
}
#endif
return customCollisionMask;
}
@@ -111,25 +80,4 @@ void Sprite::SetCustomCollisionMask(
customCollisionMask = collisionMask;
}
#if !defined(EMSCRIPTEN)
void Sprite::LoadImage(std::shared_ptr<SFMLTextureWrapper> image_) {
sfmlImage = image_;
sfmlSprite.setTexture(sfmlImage->texture, true);
hasItsOwnImage = false;
if (automaticCentre)
centre.SetXY(sfmlSprite.getLocalBounds().width / 2,
sfmlSprite.getLocalBounds().height / 2);
}
void Sprite::MakeSpriteOwnsItsImage() {
if (!hasItsOwnImage || sfmlImage == std::shared_ptr<SFMLTextureWrapper>()) {
sfmlImage = std::make_shared<SFMLTextureWrapper>(
sfmlImage->texture); // Copy the texture.
sfmlSprite.setTexture(sfmlImage->texture);
hasItsOwnImage = true;
}
}
#endif
} // namespace gd

View File

@@ -11,7 +11,6 @@
#include "GDCore/Extensions/Builtin/SpriteExtension/Point.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Polygon2d.h"
#include "GDCore/String.h"
class SFMLTextureWrapper;
#undef LoadImage // prevent windows.h to be polluting everything
namespace gd {
@@ -19,9 +18,6 @@ namespace gd {
/**
* \brief Represents a sprite to be displayed on the screen.
*
* A sprite contains a SFML sprite to be displayed, some points,
* and can also have its own texture (rather than a texture from ImageManager).
*
* \see Direction
* \see SpriteObject
* \ingroup SpriteObjectExtension
@@ -163,53 +159,7 @@ class GD_CORE_API Sprite {
*/
bool SetDefaultCenterPoint(bool enabled);
#if !defined(EMSCRIPTEN)
/** \name Sprite runtime management
* Functions used by the C++ game engine.
*/
///@{
/**
* \brief Get the SFML sprite associated with the sprite
*/
inline const sf::Sprite& GetSFMLSprite() const { return sfmlSprite; }
/**
* \brief Get the SFML sprite associated with the sprite
*/
inline sf::Sprite& GetSFMLSprite() { return sfmlSprite; }
/**
* \brief Set the SFML texture of the sprite
*/
void LoadImage(std::shared_ptr<SFMLTextureWrapper> image);
/**
* \brief Get SFML texture used by the sprite
*/
std::shared_ptr<SFMLTextureWrapper> GetSFMLTexture() { return sfmlImage; };
/**
* \brief Get SFML texture used by the sprite
*/
const std::shared_ptr<SFMLTextureWrapper> GetSFMLTexture() const {
return sfmlImage;
};
/**
* \brief Make the sprite, if it uses a texture from ImageManager,
* copy this texture and take ownership of it.
*/
void MakeSpriteOwnsItsImage();
///@}
#endif
private:
#if !defined(EMSCRIPTEN)
sf::Sprite sfmlSprite; ///< Displayed SFML sprite
std::shared_ptr<SFMLTextureWrapper>
sfmlImage; ///< Pointer to the image displayed by the sprite.
bool hasItsOwnImage; ///< True if sfmlImage is only owned by this Sprite.
#endif
gd::String image; ///< Name of the image to be loaded in Image Manager.
bool automaticCollisionMask; ///< True to use the custom collision mask.

View File

@@ -334,39 +334,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
obj.AddAction("CopyImageOnImageOfSprite",
_("Copy an image on the current one of an object"),
_("Copy an image on the current image of an object.\nNote that "
"the source image must be preferably kept loaded in memory."),
_("Copy image _PARAM2_ on the current of _PARAM0_ at "
"_PARAM3_;_PARAM4_"),
_("Effects"),
"res/copy24.png",
"res/copyicon.png")
.AddParameter("object", _("Object"), "Sprite")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("string", _("Name of the source image"))
.AddParameter("expression", _("X position"))
.AddParameter("expression", _("Y position"))
.AddParameter(
"yesorno",
_("Should the copy take in account the source transparency\?"));
obj.AddAction(
"CreateMaskFromColorOnActualImage", // Actual is indeed a mistake :
// Current should have been
// chosen.
_("Make a color of the image of an object transparent"),
_("Make a color of the image of an object transparent."),
_("Make color _PARAM1_ of the current image of _PARAM0_ transparent"),
_("Effects"),
"res/actions/opacity24.png",
"res/actions/opacity.png")
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("color", _("Color to make transparent"));
obj.AddAction("ChangeColor",
_("Tint color"),
_("Change the tint of an object. The default color is white."),

View File

@@ -10,7 +10,6 @@
#include "GDCore/Extensions/Builtin/SpriteExtension/Direction.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Sprite.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
#include "GDCore/Project/ImageManager.h"
#include "GDCore/Project/InitialInstance.h"
#include "GDCore/Project/Layout.h"
#include "GDCore/Project/Object.h"

View File

@@ -16,7 +16,6 @@ class Object;
class Layout;
class Sprite;
class Animation;
class MainFrameWrapper;
class SerializerElement;
class PropertyDescriptor;
} // namespace gd

View File

@@ -275,6 +275,76 @@ BehaviorMetadata::AddExpressionAndConditionAndAction(
expression, condition, action);
}
#if defined(GD_IDE_ONLY)
gd::InstructionMetadata& BehaviorMetadata::AddDuplicatedAction(
const gd::String& newActionName, const gd::String& copiedActionName) {
gd::String newNameWithNamespace = extensionNamespace + newActionName;
gd::String copiedNameWithNamespace = extensionNamespace + copiedActionName;
auto copiedAction = actionsInfos.find(copiedNameWithNamespace);
if (copiedAction == actionsInfos.end()) {
gd::LogWarning("Could not find an action with name " +
copiedNameWithNamespace + " to copy.");
} else {
actionsInfos[newNameWithNamespace] = copiedAction->second;
}
return actionsInfos[newNameWithNamespace];
}
gd::InstructionMetadata& BehaviorMetadata::AddDuplicatedCondition(
const gd::String& newConditionName, const gd::String& copiedConditionName) {
gd::String newNameWithNamespace = extensionNamespace + newConditionName;
gd::String copiedNameWithNamespace = extensionNamespace + copiedConditionName;
auto copiedCondition = conditionsInfos.find(copiedNameWithNamespace);
if (copiedCondition == conditionsInfos.end()) {
gd::LogWarning("Could not find a condition with name " +
copiedNameWithNamespace + " to copy.");
} else {
conditionsInfos[newNameWithNamespace] = copiedCondition->second;
}
return conditionsInfos[newNameWithNamespace];
}
gd::ExpressionMetadata& BehaviorMetadata::AddDuplicatedExpression(
const gd::String& newExpressionName,
const gd::String& copiedExpressionName) {
gd::String newNameWithNamespace = extensionNamespace + newExpressionName;
gd::String copiedNameWithNamespace =
extensionNamespace + copiedExpressionName;
auto copiedExpression = expressionsInfos.find(copiedNameWithNamespace);
if (copiedExpression == expressionsInfos.end()) {
gd::LogWarning("Could not find an expression with name " +
copiedNameWithNamespace + " to copy.");
} else {
expressionsInfos[newNameWithNamespace] = copiedExpression->second;
}
return expressionsInfos[newNameWithNamespace];
}
gd::ExpressionMetadata& BehaviorMetadata::AddDuplicatedStrExpression(
const gd::String& newExpressionName,
const gd::String& copiedExpressionName) {
gd::String newNameWithNamespace = extensionNamespace + newExpressionName;
gd::String copiedNameWithNamespace =
extensionNamespace + copiedExpressionName;
auto copiedExpression = strExpressionsInfos.find(copiedNameWithNamespace);
if (copiedExpression == strExpressionsInfos.end()) {
gd::LogWarning("Could not find a string expression with name " +
copiedNameWithNamespace + " to copy.");
} else {
strExpressionsInfos[newNameWithNamespace] = copiedExpression->second;
}
return strExpressionsInfos[newNameWithNamespace];
}
#endif
BehaviorMetadata& BehaviorMetadata::SetFullName(const gd::String& fullname_) {
#if defined(GD_IDE_ONLY)
fullname = fullname_;

View File

@@ -138,6 +138,46 @@ class GD_CORE_API BehaviorMetadata {
const gd::String& group,
const gd::String& icon);
/**
* \brief Create a new action which is the duplicate of the specified one.
*
* Useful for handling a deprecated action that is just a "copy" of the new
* one.
*/
gd::InstructionMetadata& AddDuplicatedAction(
const gd::String& newActionName, const gd::String& copiedActionName);
/**
* \brief Create a new condition which is the duplicate of the specified one.
*
* Useful for handling a deprecated condition that is just a "copy" of the new
* one.
*/
gd::InstructionMetadata& AddDuplicatedCondition(
const gd::String& newConditionName,
const gd::String& copiedConditionName);
/**
* \brief Create a new expression which is the duplicate of the specified one.
*
* Useful for handling a deprecated expression that is just a "copy" of the
* new one.
*/
gd::ExpressionMetadata& AddDuplicatedExpression(
const gd::String& newExpressionName,
const gd::String& copiedExpressionName);
/**
* \brief Create a new string expression which is the duplicate of the
* specified one.
*
* Useful for handling a deprecated string expression that is just a "copy" of
* the new one.
*/
gd::ExpressionMetadata& AddDuplicatedStrExpression(
const gd::String& newExpressionName,
const gd::String& copiedExpressionName);
BehaviorMetadata& SetFullName(const gd::String& fullname_);
BehaviorMetadata& SetDefaultName(const gd::String& defaultName_);
BehaviorMetadata& SetDescription(const gd::String& description_);

View File

@@ -187,6 +187,19 @@ class GD_CORE_API InstructionMetadata {
return *this;
};
/**
* \brief Set the additional information, used for some parameters
* with special type (for example, it can contains the type of object accepted
* by the parameter), for the last added parameter.
*
* \see AddParameter
*/
InstructionMetadata &SetParameterExtraInfo(const gd::String &extraInfo) {
if (!parameters.empty())
parameters.back().SetExtraInfo(extraInfo);
return *this;
};
/**
* \brief Add the default parameters for an instruction manipulating the
* specified type ("string", "number") with the default operators.
@@ -221,14 +234,14 @@ class GD_CORE_API InstructionMetadata {
/**
* \brief Check if the instruction is an object instruction.
*/
bool IsObjectInstruction() {
bool IsObjectInstruction() const {
return isObjectInstruction;
}
/**
* \brief Check if the instruction is a behavior instruction.
*/
bool IsBehaviorInstruction() {
bool IsBehaviorInstruction() const {
return isBehaviorInstruction;
}

View File

@@ -245,6 +245,10 @@ class GD_CORE_API MetadataProvider {
return &metadata == &badExpressionMetadata;
}
static bool IsBadInstructionMetadata(const gd::InstructionMetadata& metadata) {
return &metadata == &badInstructionMetadata;
}
static bool IsBadBehaviorMetadata(const gd::BehaviorMetadata& metadata) {
return &metadata == &badBehaviorMetadata;
}

View File

@@ -68,14 +68,14 @@ class GD_CORE_API ParameterMetadata {
/**
* \brief Return an optional additional information, used for some parameters
* with special type (For example, it can contains the type of object accepted
* with special type (for example, it can contains the type of object accepted
* by the parameter).
*/
const gd::String &GetExtraInfo() const { return supplementaryInformation; }
/**
* \brief Set an optional additional information, used for some parameters
* with special type (For example, it can contains the type of object accepted
* with special type (for example, it can contains the type of object accepted
* by the parameter).
*/
ParameterMetadata &SetExtraInfo(const gd::String &supplementaryInformation_) {

View File

@@ -0,0 +1,25 @@
/*
* 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)
#include "GDCore/CommonTools.h"
#include "GDCore/Serialization/SerializerElement.h"
#include "EditorSettings.h"
namespace gd {
EditorSettings::EditorSettings() {}
void EditorSettings::SerializeTo(SerializerElement& element) const {
element = content;
}
void EditorSettings::UnserializeFrom(
const SerializerElement& element) {
content = element;
}
} // namespace gd
#endif

View File

@@ -0,0 +1,46 @@
/*
* 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 SCENECANVASSETTINGS_H
#define SCENECANVASSETTINGS_H
#include "GDCore/String.h"
#include "GDCore/Serialization/SerializerElement.h"
namespace gd {
/**
* \brief Container for arbitrary serialized data to be used by the editor
* to store settings.
*
* \see Scene
*/
class GD_CORE_API EditorSettings {
public:
EditorSettings();
virtual ~EditorSettings(){};
/** \name Serialization
*/
///@{
/**
* \brief Serialize the settings.
*/
void SerializeTo(SerializerElement& element) const;
/**
* \brief Unserialize the settings.
*/
void UnserializeFrom(const SerializerElement& element);
///@}
private:
gd::SerializerElement content; ///< Arbitrary content, depending on the editor.
};
} // namespace gd
#endif // SCENECANVASSETTINGS_H
#endif

View File

@@ -1,59 +0,0 @@
/*
* 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)
#include "LayoutEditorCanvasOptions.h"
#include "GDCore/CommonTools.h"
#include "GDCore/Serialization/SerializerElement.h"
namespace gd {
LayoutEditorCanvasOptions::LayoutEditorCanvasOptions()
: grid(false),
snap(true),
gridWidth(32),
gridHeight(32),
gridOffsetX(0),
gridOffsetY(0),
gridType("rectangular"),
gridR(158),
gridG(180),
gridB(255),
zoomFactor(1),
windowMask(false) {}
void LayoutEditorCanvasOptions::SerializeTo(SerializerElement& element) const {
element.SetAttribute("grid", grid);
element.SetAttribute("snap", snap);
element.SetAttribute("gridWidth", gridWidth);
element.SetAttribute("gridHeight", gridHeight);
element.SetAttribute("gridOffsetX", gridOffsetX);
element.SetAttribute("gridOffsetY", gridOffsetY);
element.SetAttribute("gridType", gridType);
element.SetAttribute("gridR", gridR);
element.SetAttribute("gridG", gridG);
element.SetAttribute("gridB", gridB);
element.SetAttribute("zoomFactor", zoomFactor);
element.SetAttribute("windowMask", windowMask);
}
void LayoutEditorCanvasOptions::UnserializeFrom(
const SerializerElement& element) {
grid = element.GetBoolAttribute("grid");
snap = element.GetBoolAttribute("snap");
windowMask = element.GetBoolAttribute("windowMask");
gridWidth = element.GetDoubleAttribute("gridWidth", 32);
gridHeight = element.GetDoubleAttribute("gridHeight", 32);
gridOffsetX = element.GetDoubleAttribute("gridOffsetX", 0);
gridOffsetY = element.GetDoubleAttribute("gridOffsetY", 0);
gridType = element.GetStringAttribute("gridType", "rectangular");
gridR = element.GetIntAttribute("gridR", 158);
gridG = element.GetIntAttribute("gridG", 180);
gridB = element.GetIntAttribute("gridB", 255);
zoomFactor = element.GetDoubleAttribute("zoomFactor", 1.0);
}
} // namespace gd
#endif

View File

@@ -1,58 +0,0 @@
/*
* 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 SCENECANVASSETTINGS_H
#define SCENECANVASSETTINGS_H
#include "GDCore/String.h"
namespace gd {
class SerializerElement;
}
namespace gd {
/**
* \brief Tool class used to store settings of a LayoutEditorCanvas.
*
* \see Scene
*/
class GD_CORE_API LayoutEditorCanvasOptions {
public:
LayoutEditorCanvasOptions();
virtual ~LayoutEditorCanvasOptions(){};
/** \name Serialization
*/
///@{
/**
* \brief Serialize instances container.
*/
void SerializeTo(SerializerElement& element) const;
/**
* \brief Unserialize the instances container.
*/
void UnserializeFrom(const SerializerElement& element);
///@}
bool grid; ///< True if grid activated in editor
bool snap; ///< True if snap to grid activated in editor
double gridWidth; ///< Grid width in editor
double gridHeight; ///< Grid height in editor
double gridOffsetX; ///< Grid X offset
double gridOffsetY; ///< Grid Y offset
gd::String gridType; ///< Grid type: rectangular or isometric
int gridR; ///< Grid red color in editor
int gridG; ///< Grid green color in editor
int gridB; ///< Grid blue color in editor
double zoomFactor; ///< Stores the zoom factor
bool windowMask; ///< True if window mask displayed in editor
};
} // namespace gd
#endif // SCENECANVASSETTINGS_H
#endif

View File

@@ -5,17 +5,19 @@
*/
#include "GDCore/IDE/Events/EventsRefactorer.h"
#include <memory>
#include "GDCore/CommonTools.h"
#include "GDCore/Events/Event.h"
#include "GDCore/Events/EventsList.h"
#include "GDCore/Events/Parsers/ExpressionParser2.h"
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
#include "GDCore/Events/Parsers/ExpressionParser2NodePrinter.h"
#include "GDCore/IDE/Events/ExpressionValidator.h"
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/Platform.h"
#include "GDCore/IDE/Events/ExpressionValidator.h"
#include "GDCore/Project/ObjectsContainer.h"
using namespace std;
@@ -31,10 +33,14 @@ class GD_CORE_API ExpressionObjectRenamer : public ExpressionParser2NodeWorker {
public:
ExpressionObjectRenamer(const gd::String& objectName_,
const gd::String& objectNewName_)
: hasDoneRenaming(false), objectName(objectName_), objectNewName(objectNewName_){};
: hasDoneRenaming(false),
objectName(objectName_),
objectNewName(objectNewName_){};
virtual ~ExpressionObjectRenamer(){};
static bool Rename(gd::ExpressionNode & node, const gd::String& objectName, const gd::String& objectNewName) {
static bool Rename(gd::ExpressionNode& node,
const gd::String& objectName,
const gd::String& objectNewName) {
if (ExpressionValidator::HasNoErrors(node)) {
ExpressionObjectRenamer renamer(objectName, objectNewName);
node.Visit(renamer);
@@ -72,7 +78,8 @@ class GD_CORE_API ExpressionObjectRenamer : public ExpressionParser2NodeWorker {
if (node.child) node.child->Visit(*this);
}
void OnVisitIdentifierNode(IdentifierNode& node) override {
if (gd::ParameterMetadata::IsObject(node.type) && node.identifierName == objectName) {
if (gd::ParameterMetadata::IsObject(node.type) &&
node.identifierName == objectName) {
hasDoneRenaming = true;
node.identifierName = objectNewName;
}
@@ -109,10 +116,11 @@ class GD_CORE_API ExpressionObjectRenamer : public ExpressionParser2NodeWorker {
class GD_CORE_API ExpressionObjectFinder : public ExpressionParser2NodeWorker {
public:
ExpressionObjectFinder(const gd::String& objectName_)
: hasObject(false), objectName(objectName_) {};
: hasObject(false), objectName(objectName_){};
virtual ~ExpressionObjectFinder(){};
static bool CheckIfHasObject(gd::ExpressionNode & node, const gd::String & objectName) {
static bool CheckIfHasObject(gd::ExpressionNode& node,
const gd::String& objectName) {
if (ExpressionValidator::HasNoErrors(node)) {
ExpressionObjectFinder finder(objectName);
node.Visit(finder);
@@ -150,7 +158,8 @@ class GD_CORE_API ExpressionObjectFinder : public ExpressionParser2NodeWorker {
if (node.child) node.child->Visit(*this);
}
void OnVisitIdentifierNode(IdentifierNode& node) override {
if (gd::ParameterMetadata::IsObject(node.type) && node.identifierName == objectName) {
if (gd::ParameterMetadata::IsObject(node.type) &&
node.identifierName == objectName) {
hasObject = true;
}
}
@@ -183,7 +192,7 @@ bool EventsRefactorer::RenameObjectInActions(const gd::Platform& platform,
bool somethingModified = false;
for (std::size_t aId = 0; aId < actions.size(); ++aId) {
gd::InstructionMetadata instrInfos =
const gd::InstructionMetadata& instrInfos =
MetadataProvider::GetActionMetadata(platform, actions[aId].GetType());
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
// Replace object's name in parameters
@@ -194,20 +203,24 @@ bool EventsRefactorer::RenameObjectInActions(const gd::Platform& platform,
else if (ParameterMetadata::IsExpression(
"number", instrInfos.parameters[pNb].type)) {
gd::ExpressionParser2 parser(platform, project, layout);
auto node = parser.ParseExpression("number", actions[aId].GetParameter(pNb).GetPlainString());
auto node = parser.ParseExpression(
"number", actions[aId].GetParameter(pNb).GetPlainString());
if (ExpressionObjectRenamer::Rename(*node, oldName, newName)) {
actions[aId].SetParameter(pNb, ExpressionParser2NodePrinter::PrintNode(*node));
actions[aId].SetParameter(
pNb, ExpressionParser2NodePrinter::PrintNode(*node));
}
}
// Replace object's name in text expressions
else if (ParameterMetadata::IsExpression(
"string", instrInfos.parameters[pNb].type)) {
gd::ExpressionParser2 parser(platform, project, layout);
auto node = parser.ParseExpression("string", actions[aId].GetParameter(pNb).GetPlainString());
auto node = parser.ParseExpression(
"string", actions[aId].GetParameter(pNb).GetPlainString());
if (ExpressionObjectRenamer::Rename(*node, oldName, newName)) {
actions[aId].SetParameter(pNb, ExpressionParser2NodePrinter::PrintNode(*node));
actions[aId].SetParameter(
pNb, ExpressionParser2NodePrinter::PrintNode(*node));
}
}
}
@@ -236,8 +249,9 @@ bool EventsRefactorer::RenameObjectInConditions(
bool somethingModified = false;
for (std::size_t cId = 0; cId < conditions.size(); ++cId) {
gd::InstructionMetadata instrInfos = MetadataProvider::GetConditionMetadata(
platform, conditions[cId].GetType());
const gd::InstructionMetadata& instrInfos =
MetadataProvider::GetConditionMetadata(platform,
conditions[cId].GetType());
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
// Replace object's name in parameters
if (gd::ParameterMetadata::IsObject(instrInfos.parameters[pNb].type) &&
@@ -247,20 +261,24 @@ bool EventsRefactorer::RenameObjectInConditions(
else if (ParameterMetadata::IsExpression(
"number", instrInfos.parameters[pNb].type)) {
gd::ExpressionParser2 parser(platform, project, layout);
auto node = parser.ParseExpression("number", conditions[cId].GetParameter(pNb).GetPlainString());
auto node = parser.ParseExpression(
"number", conditions[cId].GetParameter(pNb).GetPlainString());
if (ExpressionObjectRenamer::Rename(*node, oldName, newName)) {
conditions[cId].SetParameter(pNb, ExpressionParser2NodePrinter::PrintNode(*node));
conditions[cId].SetParameter(
pNb, ExpressionParser2NodePrinter::PrintNode(*node));
}
}
// Replace object's name in text expressions
else if (ParameterMetadata::IsExpression(
"string", instrInfos.parameters[pNb].type)) {
gd::ExpressionParser2 parser(platform, project, layout);
auto node = parser.ParseExpression("string", conditions[cId].GetParameter(pNb).GetPlainString());
auto node = parser.ParseExpression(
"string", conditions[cId].GetParameter(pNb).GetPlainString());
if (ExpressionObjectRenamer::Rename(*node, oldName, newName)) {
conditions[cId].SetParameter(pNb, ExpressionParser2NodePrinter::PrintNode(*node));
conditions[cId].SetParameter(
pNb, ExpressionParser2NodePrinter::PrintNode(*node));
}
}
}
@@ -293,8 +311,8 @@ bool EventsRefactorer::RenameObjectInEventParameters(
expression.GetPlainString() == oldName)
expression = gd::Expression(newName);
// Replace object's name in expressions
else if (ParameterMetadata::IsExpression(
"number", parameterMetadata.GetType())) {
else if (ParameterMetadata::IsExpression("number",
parameterMetadata.GetType())) {
gd::ExpressionParser2 parser(platform, project, layout);
auto node = parser.ParseExpression("number", expression.GetPlainString());
@@ -303,8 +321,8 @@ bool EventsRefactorer::RenameObjectInEventParameters(
}
}
// Replace object's name in text expressions
else if (ParameterMetadata::IsExpression(
"string", parameterMetadata.GetType())) {
else if (ParameterMetadata::IsExpression("string",
parameterMetadata.GetType())) {
gd::ExpressionParser2 parser(platform, project, layout);
auto node = parser.ParseExpression("string", expression.GetPlainString());
@@ -337,13 +355,19 @@ void EventsRefactorer::RenameObjectInEvents(const gd::Platform& platform,
platform, project, layout, *actionsVectors[j], oldName, newName);
}
vector<pair<gd::Expression*, gd::ParameterMetadata>> expressionsWithMetadata =
events[i].GetAllExpressionsWithMetadata();
vector<pair<gd::Expression*, gd::ParameterMetadata>>
expressionsWithMetadata = events[i].GetAllExpressionsWithMetadata();
for (std::size_t j = 0; j < expressionsWithMetadata.size(); ++j) {
gd::Expression* expression = expressionsWithMetadata[j].first;
gd::ParameterMetadata parameterMetadata = expressionsWithMetadata[j].second;
bool somethingModified = RenameObjectInEventParameters(
platform, project, layout, *expression, parameterMetadata, oldName, newName);
gd::ParameterMetadata parameterMetadata =
expressionsWithMetadata[j].second;
bool somethingModified = RenameObjectInEventParameters(platform,
project,
layout,
*expression,
parameterMetadata,
oldName,
newName);
}
if (events[i].CanHaveSubEvents())
@@ -366,7 +390,7 @@ bool EventsRefactorer::RemoveObjectInActions(const gd::Platform& platform,
for (std::size_t aId = 0; aId < actions.size(); ++aId) {
bool deleteMe = false;
gd::InstructionMetadata instrInfos =
const gd::InstructionMetadata& instrInfos =
MetadataProvider::GetActionMetadata(platform, actions[aId].GetType());
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
// Find object's name in parameters
@@ -379,7 +403,8 @@ bool EventsRefactorer::RemoveObjectInActions(const gd::Platform& platform,
else if (ParameterMetadata::IsExpression(
"number", instrInfos.parameters[pNb].type)) {
gd::ExpressionParser2 parser(platform, project, layout);
auto node = parser.ParseExpression("number", actions[aId].GetParameter(pNb).GetPlainString());
auto node = parser.ParseExpression(
"number", actions[aId].GetParameter(pNb).GetPlainString());
if (ExpressionObjectFinder::CheckIfHasObject(*node, name)) {
deleteMe = true;
@@ -390,7 +415,8 @@ bool EventsRefactorer::RemoveObjectInActions(const gd::Platform& platform,
else if (ParameterMetadata::IsExpression(
"string", instrInfos.parameters[pNb].type)) {
gd::ExpressionParser2 parser(platform, project, layout);
auto node = parser.ParseExpression("string", actions[aId].GetParameter(pNb).GetPlainString());
auto node = parser.ParseExpression(
"string", actions[aId].GetParameter(pNb).GetPlainString());
if (ExpressionObjectFinder::CheckIfHasObject(*node, name)) {
deleteMe = true;
@@ -427,8 +453,9 @@ bool EventsRefactorer::RemoveObjectInConditions(
for (std::size_t cId = 0; cId < conditions.size(); ++cId) {
bool deleteMe = false;
gd::InstructionMetadata instrInfos = MetadataProvider::GetConditionMetadata(
platform, conditions[cId].GetType());
const gd::InstructionMetadata& instrInfos =
MetadataProvider::GetConditionMetadata(platform,
conditions[cId].GetType());
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
// Find object's name in parameters
if (gd::ParameterMetadata::IsObject(instrInfos.parameters[pNb].type) &&
@@ -440,7 +467,8 @@ bool EventsRefactorer::RemoveObjectInConditions(
else if (ParameterMetadata::IsExpression(
"number", instrInfos.parameters[pNb].type)) {
gd::ExpressionParser2 parser(platform, project, layout);
auto node = parser.ParseExpression("number", conditions[cId].GetParameter(pNb).GetPlainString());
auto node = parser.ParseExpression(
"number", conditions[cId].GetParameter(pNb).GetPlainString());
if (ExpressionObjectFinder::CheckIfHasObject(*node, name)) {
deleteMe = true;
@@ -451,7 +479,8 @@ bool EventsRefactorer::RemoveObjectInConditions(
else if (ParameterMetadata::IsExpression(
"string", instrInfos.parameters[pNb].type)) {
gd::ExpressionParser2 parser(platform, project, layout);
auto node = parser.ParseExpression("string", conditions[cId].GetParameter(pNb).GetPlainString());
auto node = parser.ParseExpression(
"string", conditions[cId].GetParameter(pNb).GetPlainString());
if (ExpressionObjectFinder::CheckIfHasObject(*node, name)) {
deleteMe = true;
@@ -781,10 +810,10 @@ bool EventsRefactorer::SearchStringInConditions(
}
bool EventsRefactorer::SearchStringInEvent(gd::ObjectsContainer& project,
gd::ObjectsContainer& layout,
gd::BaseEvent& event,
gd::String search,
bool matchCase) {
gd::ObjectsContainer& layout,
gd::BaseEvent& event,
gd::String search,
bool matchCase) {
for (gd::String str : event.GetAllSearchableStrings()) {
if (matchCase) {
if (str.find(search) != gd::String::npos) return true;

View File

@@ -151,7 +151,7 @@ std::set<gd::String> EventsVariablesFinder::FindArgumentsInInstructions(
for (std::size_t aId = 0; aId < instructions.size(); ++aId) {
gd::String lastObjectParameter = "";
gd::InstructionMetadata instrInfos =
const gd::InstructionMetadata& instrInfos =
instructionsAreConditions ? MetadataProvider::GetConditionMetadata(
platform, instructions[aId].GetType())
: MetadataProvider::GetActionMetadata(

View File

@@ -4,9 +4,11 @@
* reserved. This project is released under the MIT License.
*/
#include "GDCore/IDE/Events/ExpressionsParameterMover.h"
#include <map>
#include <memory>
#include <vector>
#include "GDCore/Events/Event.h"
#include "GDCore/Events/EventsList.h"
#include "GDCore/Events/Parsers/ExpressionParser2.h"
@@ -134,10 +136,11 @@ class GD_CORE_API ExpressionParameterMover
bool ExpressionsParameterMover::DoVisitInstruction(gd::Instruction& instruction,
bool isCondition) {
auto& metadata = isCondition ? gd::MetadataProvider::GetConditionMetadata(
platform, instruction.GetType())
: gd::MetadataProvider::GetActionMetadata(
platform, instruction.GetType());
const auto& metadata = isCondition
? gd::MetadataProvider::GetConditionMetadata(
platform, instruction.GetType())
: gd::MetadataProvider::GetActionMetadata(
platform, instruction.GetType());
for (std::size_t pNb = 0; pNb < metadata.parameters.size() &&
pNb < instruction.GetParametersCount();

View File

@@ -4,9 +4,11 @@
* reserved. This project is released under the MIT License.
*/
#include "GDCore/IDE/Events/ExpressionsRenamer.h"
#include <map>
#include <memory>
#include <vector>
#include "GDCore/Events/Event.h"
#include "GDCore/Events/EventsList.h"
#include "GDCore/Events/Parsers/ExpressionParser2.h"
@@ -145,10 +147,11 @@ class GD_CORE_API ExpressionFunctionRenamer
bool ExpressionsRenamer::DoVisitInstruction(gd::Instruction& instruction,
bool isCondition) {
auto& metadata = isCondition ? gd::MetadataProvider::GetConditionMetadata(
platform, instruction.GetType())
: gd::MetadataProvider::GetActionMetadata(
platform, instruction.GetType());
const auto& metadata = isCondition
? gd::MetadataProvider::GetConditionMetadata(
platform, instruction.GetType())
: gd::MetadataProvider::GetActionMetadata(
platform, instruction.GetType());
for (std::size_t pNb = 0; pNb < metadata.parameters.size() &&
pNb < instruction.GetParametersCount();

View File

@@ -27,50 +27,6 @@ namespace gd {
PlatformLoader::PlatformLoader() {}
void PlatformLoader::LoadAllPlatformsInManager(gd::String dir) {
{
#if defined(WINDOWS)
std::shared_ptr<gd::Platform> platform = LoadPlatformInManager("GDCpp.dll");
#elif defined(LINUX)
std::shared_ptr<gd::Platform> platform =
LoadPlatformInManager("libGDCpp.so");
#elif defined(MACOS)
std::shared_ptr<gd::Platform> platform =
LoadPlatformInManager("libGDCpp.dylib");
#else
#warning Add the appropriate filename here for the C++ Platform!
std::shared_ptr<gd::Platform> platform;
#endif
if (platform)
gd::ExtensionsLoader::LoadAllExtensions("./CppPlatform/Extensions/",
*platform);
}
{
#if defined(WINDOWS)
std::shared_ptr<gd::Platform> platform =
LoadPlatformInManager("./JsPlatform/GDJS.dll");
#elif defined(LINUX)
std::shared_ptr<gd::Platform> platform =
LoadPlatformInManager("./JsPlatform/libGDJS.so");
#elif defined(MACOS)
std::shared_ptr<gd::Platform> platform =
LoadPlatformInManager("./JsPlatform/libGDJS.dylib");
#else
#warning Add the appropriate filename here for the Js Platform!
std::shared_ptr<gd::Platform> platform;
#endif
if (platform)
gd::ExtensionsLoader::LoadAllExtensions("./JsPlatform/Extensions/",
*platform);
if (platform)
gd::ExtensionsLoader::LoadAllExtensions(
"./CppPlatform/Extensions/", *platform, true);
}
gd::ExtensionsLoader::ExtensionsLoadingDone("./CppPlatform/Extensions/");
}
std::shared_ptr<gd::Platform> PlatformLoader::LoadPlatformInManager(
gd::String fullpath) {
std::cout << "Loading platform " << fullpath << "..." << std::endl;

View File

@@ -30,15 +30,6 @@ passing
*/
class GD_CORE_API PlatformLoader {
public:
/**
* Load all the platforms available in a directory.
*
* \param dir The directory where platforms must be searched for.
*
* \todo For now, only GDCpp.dll and GDJS.dll are loaded.
*/
static void LoadAllPlatformsInManager(gd::String dir);
/**
* Load a specific platform.
*

View File

@@ -5,7 +5,7 @@
*/
#include "GDCore/Project/ExternalLayout.h"
#include "GDCore/IDE/Dialogs/LayoutEditorCanvas/LayoutEditorCanvasOptions.h"
#include "GDCore/IDE/Dialogs/LayoutEditorCanvas/EditorSettings.h"
#include "GDCore/Project/InitialInstancesContainer.h"
#include "GDCore/Serialization/SerializerElement.h"
#include "GDCore/TinyXml/tinyxml.h"
@@ -16,7 +16,7 @@ void ExternalLayout::UnserializeFrom(const SerializerElement& element) {
name = element.GetStringAttribute("name", "", "Name");
instances.UnserializeFrom(element.GetChild("instances", 0, "Instances"));
#if defined(GD_IDE_ONLY)
editionSettings.UnserializeFrom(element.GetChild("editionSettings"));
editorSettings.UnserializeFrom(element.GetChild("editionSettings"));
#endif
associatedLayout = element.GetStringAttribute("associatedLayout");
}
@@ -25,7 +25,7 @@ void ExternalLayout::UnserializeFrom(const SerializerElement& element) {
void ExternalLayout::SerializeTo(SerializerElement& element) const {
element.SetAttribute("name", name);
instances.SerializeTo(element.AddChild("instances"));
editionSettings.SerializeTo(element.AddChild("editionSettings"));
editorSettings.SerializeTo(element.AddChild("editionSettings"));
element.SetAttribute("associatedLayout", associatedLayout);
}
#endif

View File

@@ -13,7 +13,7 @@ namespace gd {
class SerializerElement;
}
#if defined(GD_IDE_ONLY)
#include "GDCore/IDE/Dialogs/LayoutEditorCanvas/LayoutEditorCanvasOptions.h"
#include "GDCore/IDE/Dialogs/LayoutEditorCanvas/EditorSettings.h"
#endif
namespace gd {
@@ -58,15 +58,15 @@ class GD_CORE_API ExternalLayout {
/**
* \brief Get the user settings for the IDE.
*/
const gd::LayoutEditorCanvasOptions& GetAssociatedSettings() const {
return editionSettings;
const gd::EditorSettings& GetAssociatedEditorSettings() const {
return editorSettings;
}
/**
* \brief Get the user settings for the IDE.
*/
gd::LayoutEditorCanvasOptions& GetAssociatedSettings() {
return editionSettings;
gd::EditorSettings& GetAssociatedEditorSettings() {
return editorSettings;
}
#endif
@@ -100,7 +100,7 @@ class GD_CORE_API ExternalLayout {
gd::String name;
gd::InitialInstancesContainer instances;
#if defined(GD_IDE_ONLY)
gd::LayoutEditorCanvasOptions editionSettings;
gd::EditorSettings editorSettings;
#endif
gd::String associatedLayout;
};

View File

@@ -1,213 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "GDCore/Project/ImageManager.h"
#include <SFML/OpenGL.hpp>
#include "GDCore/Project/ResourcesLoader.h"
#include "GDCore/Project/ResourcesManager.h"
#include "GDCore/Tools/InvalidImage.h"
#if !defined(ANDROID) && !defined(MACOS)
#include <GL/glu.h>
#endif
#undef LoadImage // thx windows.h
namespace gd {
ImageManager::ImageManager() : resourcesManager(NULL) {
#if !defined(EMSCRIPTEN)
badTexture = std::make_shared<SFMLTextureWrapper>();
badTexture->texture.loadFromMemory(gd::InvalidImageData,
sizeof(gd::InvalidImageData));
badTexture->texture.setSmooth(false);
badTexture->image = badTexture->texture.copyToImage();
#endif
}
std::shared_ptr<SFMLTextureWrapper> ImageManager::GetSFMLTexture(
const gd::String& name) const {
if (!resourcesManager) {
std::cout << "ImageManager has no ResourcesManager associated with.";
return badTexture;
}
if (alreadyLoadedImages.find(name) != alreadyLoadedImages.end() &&
!alreadyLoadedImages.find(name)->second.expired())
return alreadyLoadedImages.find(name)->second.lock();
std::cout << "ImageManager: Loading " << name << ".";
// Load only an image when necessary
try {
ImageResource& image =
dynamic_cast<ImageResource&>(resourcesManager->GetResource(name));
auto texture = std::make_shared<SFMLTextureWrapper>();
ResourcesLoader::Get()->LoadSFMLImage(image.GetFile(), texture->image);
texture->texture.loadFromImage(texture->image);
texture->texture.setSmooth(image.smooth);
alreadyLoadedImages[name] = texture;
#if defined(GD_IDE_ONLY)
if (preventUnloading)
unloadingPreventer.push_back(
texture); // If unload prevention is activated, add the image to the
// list dedicated to prevent images from being unloaded.
#endif
return texture;
} catch (...) {
}
std::cout << " Resource not found." << std::endl;
return badTexture;
}
bool ImageManager::HasLoadedSFMLTexture(const gd::String& name) const {
if (alreadyLoadedImages.find(name) != alreadyLoadedImages.end() &&
!alreadyLoadedImages.find(name)->second.expired())
return true;
return false;
}
void ImageManager::SetSFMLTextureAsPermanentlyLoaded(
const gd::String& name,
std::shared_ptr<SFMLTextureWrapper>& texture) const {
if (alreadyLoadedImages.find(name) == alreadyLoadedImages.end() ||
alreadyLoadedImages.find(name)->second.expired())
alreadyLoadedImages[name] = texture;
if (permanentlyLoadedImages.find(name) == permanentlyLoadedImages.end())
permanentlyLoadedImages[name] = texture;
}
void ImageManager::ReloadImage(const gd::String& name) const {
if (!resourcesManager) {
std::cout << "ImageManager has no ResourcesManager associated with.";
return;
}
// Verify if image is in memory. If not, it will be automatically reloaded
// when necessary.
if (alreadyLoadedImages.find(name) == alreadyLoadedImages.end() ||
alreadyLoadedImages.find(name)->second.expired())
return;
// Image still in memory, get it and update it.
std::shared_ptr<SFMLTextureWrapper> oldTexture =
alreadyLoadedImages.find(name)->second.lock();
try {
ImageResource& image =
dynamic_cast<ImageResource&>(resourcesManager->GetResource(name));
std::cout << "ImageManager: Reload " << name << std::endl;
ResourcesLoader::Get()->LoadSFMLImage(image.GetFile(), oldTexture->image);
oldTexture->texture.loadFromImage(oldTexture->image);
oldTexture->texture.setSmooth(image.smooth);
return;
} catch (...) { /*The ressource is not an image*/
}
// Image not present anymore in image list.
std::cout << "ImageManager: " << name << " is not available anymore."
<< std::endl;
*oldTexture = *badTexture;
}
std::shared_ptr<OpenGLTextureWrapper> ImageManager::GetOpenGLTexture(
const gd::String& name) const {
if (alreadyLoadedOpenGLTextures.find(name) !=
alreadyLoadedOpenGLTextures.end() &&
!alreadyLoadedOpenGLTextures.find(name)->second.expired())
return alreadyLoadedOpenGLTextures.find(name)->second.lock();
std::cout << "Load OpenGL Texture" << name << std::endl;
std::shared_ptr<OpenGLTextureWrapper> texture =
std::make_shared<OpenGLTextureWrapper>(GetSFMLTexture(name));
alreadyLoadedOpenGLTextures[name] = texture;
return texture;
}
void ImageManager::LoadPermanentImages() {
if (!resourcesManager) {
std::cout << "ImageManager has no ResourcesManager associated with.";
return;
}
// Create a new list of permanently loaded images but do not delete now the
// old list so as not to unload images that could be still present.
std::map<gd::String, std::shared_ptr<SFMLTextureWrapper> >
newPermanentlyLoadedImages;
std::vector<gd::String> resources = resourcesManager->GetAllResourceNames();
for (std::size_t i = 0; i < resources.size(); i++) {
try {
ImageResource& image = dynamic_cast<ImageResource&>(
resourcesManager->GetResource(resources[i]));
if (image.alwaysLoaded)
newPermanentlyLoadedImages[image.GetName()] =
GetSFMLTexture(image.GetName());
} catch (...) { /*The resource is not an image, we don't care about it.*/
}
}
permanentlyLoadedImages = newPermanentlyLoadedImages;
}
#if defined(GD_IDE_ONLY)
void ImageManager::PreventImagesUnloading() {
preventUnloading = true;
for (auto it = alreadyLoadedImages.begin(); it != alreadyLoadedImages.end();
++it) {
std::shared_ptr<SFMLTextureWrapper> image = (it->second).lock();
if (image != std::shared_ptr<SFMLTextureWrapper>())
unloadingPreventer.push_back(image);
}
}
void ImageManager::EnableImagesUnloading() {
preventUnloading = false;
unloadingPreventer
.clear(); // Images which are not used anymore will thus be destroyed (As
// no shared pointer will be pointing to them).
}
#endif
} // namespace gd
SFMLTextureWrapper::SFMLTextureWrapper(const sf::Texture& texture_)
: texture(texture_), image(texture.copyToImage()) {}
SFMLTextureWrapper::SFMLTextureWrapper() {}
SFMLTextureWrapper::~SFMLTextureWrapper() {}
OpenGLTextureWrapper::OpenGLTextureWrapper(
std::shared_ptr<SFMLTextureWrapper> sfmlTexture_) {
sfmlTexture = sfmlTexture_;
#if !defined(ANDROID) // TODO: OpenGL
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sfmlTexture->image.getSize().x,
// sfmlTexture->image.getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE,
// sfmlTexture->image.getPixelsPtr()); glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(
GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
#endif
}
OpenGLTextureWrapper::~OpenGLTextureWrapper() {
#if !defined(ANDROID) // TODO: OpenGL
glDeleteTextures(1, &texture);
#endif
};

View File

@@ -1,185 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#ifndef ImageManager_H
#define ImageManager_H
#include <SFML/Graphics.hpp>
#include <SFML/OpenGL.hpp>
#include <SFML/System.hpp>
#include <iostream>
#include <memory>
#include <vector>
#include "GDCore/String.h"
namespace gd {
class ResourcesManager;
}
class OpenGLTextureWrapper;
class SFMLTextureWrapper;
#undef LoadImage // thx windows.h
namespace gd {
/**
* \brief Manage images for the IDE as well as at runtime for GD C++ Platform,
* providing an easy way to get SFML images or OpenGL textures.
*
* Image manager is used by objects to obtain their images from the image name.
*
* Images are loaded dynamically when necessary, and are unloaded if there is no
* more shared_ptr pointing on an image.
*
* You should in particular be interested by gd::ImageManager::GetOpenGLTexture
* and gd::ImageManager::GetSFMLTexture.
*
* \see SFMLTextureWrapper
* \see OpenGLTextureWrapper
*
* \ingroup ResourcesManagement
*/
class GD_CORE_API ImageManager {
public:
ImageManager();
virtual ~ImageManager(){};
/**
* \brief Get a shared pointer to an OpenGL texture. The shared pointer must
* be kept alive as long as the texture is used.
*/
std::shared_ptr<OpenGLTextureWrapper> GetOpenGLTexture(
const gd::String& name) const;
/**
* \brief Get a shared pointer to a SFML texture. The shared pointer must be
* kept alive as long as the texture is used.
*
* For example, if the texture is used in an object, you should store the
* shared pointer in a member to make sure the texture is available as long as
* the object is alive.
*/
std::shared_ptr<SFMLTextureWrapper> GetSFMLTexture(
const gd::String& name) const;
/**
* \brief Set the gd::ResourcesManager used by the ImageManager.
*/
void SetResourcesManager(gd::ResourcesManager* resourcesManager_) {
resourcesManager = resourcesManager_;
}
/**
* \brief Load all images of the project which are flagged as alwaysLoaded.
* \see ImageResource
*/
void LoadPermanentImages();
/**
* \brief Check if a SFML texture with the specified name is available and
* loaded in memory. \return true if the texture called \a name if available
* and loaded in memory.
*/
bool HasLoadedSFMLTexture(const gd::String& name) const;
/**
* \brief Add the SFMLTextureWrapper to loaded images ( so that it can be
* accessed thanks to ImageManager::GetSFMLTexture ) with the specified name
* and mark it as permanently loaded ( so that is is unloaded only when the
* layout is unloaded ).
*/
void SetSFMLTextureAsPermanentlyLoaded(
const gd::String& name,
std::shared_ptr<SFMLTextureWrapper>& texture) const;
/**
* \brief Reload a single image from the game resources
*/
void ReloadImage(const gd::String& name) const;
#if defined(GD_IDE_ONLY)
/**
* \brief When called, images won't be unloaded from memory until
* EnableImagesUnloading is called. Can be used when reloading a layout so as
* to prevent images from being unloaded and then immediately reloaded.
*/
void PreventImagesUnloading();
/**
* \brief Enable again unused images to be unloaded from memory.
*/
void EnableImagesUnloading();
#endif
private:
mutable std::map<gd::String, std::weak_ptr<SFMLTextureWrapper> >
alreadyLoadedImages; ///< Reference all images loaded in memory.
mutable std::map<gd::String, std::shared_ptr<SFMLTextureWrapper> >
permanentlyLoadedImages; ///< Contains (smart) pointers to images which
///< should stay loaded even if they are not
///< (currently) used.
#if defined(GD_IDE_ONLY)
/** This list is filled, when PreventImagesUnloading is called, with images
* already loaded in memory ( and any image loaded after the call to
* PreventImagesUnloading ). It will thus prevent these images from being
* unloaded. This list is destroyed when EnableImagesUnloading is called.
*
* \see PreventImagesUnloading
* \see EnableImagesUnloading
*/
mutable std::vector<std::shared_ptr<SFMLTextureWrapper> > unloadingPreventer;
bool preventUnloading; ///< True if no images must be currently unloaded.
#endif
mutable std::map<gd::String, std::weak_ptr<OpenGLTextureWrapper> >
alreadyLoadedOpenGLTextures; ///< Reference all OpenGL textures loaded in
///< memory.
mutable std::shared_ptr<SFMLTextureWrapper> badTexture;
mutable std::shared_ptr<OpenGLTextureWrapper> badOpenGLTexture;
gd::ResourcesManager* resourcesManager;
};
} // namespace gd
/**
* \brief Class wrapping an SFML texture.
*
* \see gd::ImageManager
* \ingroup ResourcesManagement
*/
class GD_CORE_API SFMLTextureWrapper {
public:
SFMLTextureWrapper(const sf::Texture& texture);
SFMLTextureWrapper();
~SFMLTextureWrapper();
sf::Texture texture;
sf::Image image; ///< Associated sfml image, used for pixel perfect collision
///< for example. If you update the image, call
///< LoadFromImage on texture to update it also.
};
/**
* \brief Class wrapping an OpenGL texture.
*
* \see gd::ImageManager
* \ingroup ResourcesManagement
*/
class GD_CORE_API OpenGLTextureWrapper {
public:
OpenGLTextureWrapper(std::shared_ptr<SFMLTextureWrapper> sfmlTexture_);
OpenGLTextureWrapper() : texture(0){};
~OpenGLTextureWrapper();
inline GLuint GetOpenGLTexture() const { return texture; }
private:
std::shared_ptr<SFMLTextureWrapper> sfmlTexture;
GLuint texture;
};
#endif // ImageManager_H

View File

@@ -272,7 +272,7 @@ void Layout::SerializeTo(SerializerElement& element) const {
disableInputWhenNotFocused);
#if defined(GD_IDE_ONLY)
GetAssociatedSettings().SerializeTo(element.AddChild("uiSettings"));
editorSettings.SerializeTo(element.AddChild("uiSettings"));
#endif
GetObjectGroups().SerializeTo(element.AddChild("objectsGroups"));
@@ -333,7 +333,7 @@ void Layout::UnserializeFrom(gd::Project& project,
element.GetBoolAttribute("disableInputWhenNotFocused");
#if defined(GD_IDE_ONLY)
associatedSettings.UnserializeFrom(
editorSettings.UnserializeFrom(
element.GetChild("uiSettings", 0, "UISettings"));
GetObjectGroups().UnserializeFrom(
@@ -412,7 +412,7 @@ void Layout::Init(const Layout& other) {
#if defined(GD_IDE_ONLY)
events = other.events;
associatedSettings = other.associatedSettings;
editorSettings = other.editorSettings;
objectGroups = other.objectGroups;
profiler = other.profiler;

View File

@@ -18,7 +18,7 @@
#include "GDCore/Project/VariablesContainer.h"
#include "GDCore/String.h"
#if defined(GD_IDE_ONLY)
#include "GDCore/IDE/Dialogs/LayoutEditorCanvas/LayoutEditorCanvasOptions.h"
#include "GDCore/IDE/Dialogs/LayoutEditorCanvas/EditorSettings.h"
#endif
namespace gd {
class BaseEvent;
@@ -291,18 +291,18 @@ class GD_CORE_API Layout : public ObjectsContainer {
#if defined(GD_IDE_ONLY)
/**
* Return the settings associated to the layout.
* \see gd::LayoutEditorCanvasOptions
* \see gd::EditorSettings
*/
const gd::LayoutEditorCanvasOptions& GetAssociatedSettings() const {
return associatedSettings;
const gd::EditorSettings& GetAssociatedEditorSettings() const {
return editorSettings;
}
/**
* Return the settings associated to the layout.
* \see gd::LayoutEditorCanvasOptions
* \see gd::EditorSettings
*/
gd::LayoutEditorCanvasOptions& GetAssociatedSettings() {
return associatedSettings;
gd::EditorSettings& GetAssociatedEditorSettings() {
return editorSettings;
}
#endif
@@ -436,7 +436,7 @@ class GD_CORE_API Layout : public ObjectsContainer {
///< specified behavior shared data.
#if defined(GD_IDE_ONLY)
EventsList events; ///< Scene events
gd::LayoutEditorCanvasOptions associatedSettings;
gd::EditorSettings editorSettings;
#endif
// TODO: GD C++ Platform specific code below

View File

@@ -26,7 +26,6 @@
#include "GDCore/Project/EventsFunctionsExtension.h"
#include "GDCore/Project/ExternalEvents.h"
#include "GDCore/Project/ExternalLayout.h"
#include "GDCore/Project/ImageManager.h"
#include "GDCore/Project/Layout.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/ObjectGroupsContainer.h"
@@ -67,23 +66,16 @@ Project::Project()
adaptGameResolutionAtRuntime(true),
sizeOnStartupMode("adaptWidth"),
projectUuid(""),
useDeprecatedZeroAsDefaultZOrder(false),
imageManager(std::make_shared<ImageManager>())
useDeprecatedZeroAsDefaultZOrder(false)
#if defined(GD_IDE_ONLY)
,
useExternalSourceFiles(false),
currentPlatform(NULL),
gdMajorVersion(gd::VersionWrapper::Major()),
gdMinorVersion(gd::VersionWrapper::Minor()),
gdBuildVersion(gd::VersionWrapper::Build()),
dirty(false)
gdBuildVersion(gd::VersionWrapper::Build())
#endif
{
imageManager->SetResourcesManager(&resourcesManager);
#if !defined(GD_IDE_ONLY)
platforms.push_back(&CppPlatform::Get());
#endif
}
Project::~Project() {}
@@ -823,10 +815,6 @@ void Project::SerializeTo(SerializerElement& element) const {
for (std::size_t i = 0; i < externalSourceFiles.size(); ++i)
externalSourceFiles[i]->SerializeTo(
externalSourceFilesElement.AddChild("sourceFile"));
#if defined(GD_IDE_ONLY)
dirty = false;
#endif
}
bool Project::ValidateName(const gd::String& name) {
@@ -969,9 +957,7 @@ void Project::Init(const gd::Project& game) {
platforms = game.platforms;
resourcesManager = game.resourcesManager;
imageManager = std::make_shared<ImageManager>(*game.imageManager);
imageManager->SetResourcesManager(&resourcesManager);
initialObjects = gd::Clone(game.initialObjects);
scenes = gd::Clone(game.scenes);
@@ -993,7 +979,6 @@ void Project::Init(const gd::Project& game) {
#if defined(GD_IDE_ONLY)
projectFile = game.GetProjectFile();
imagesChanged = game.imagesChanged;
#endif
}

View File

@@ -28,7 +28,6 @@ class Object;
class VariablesContainer;
class ArbitraryResourceWorker;
class SourceFile;
class ImageManager;
class Behavior;
class BehaviorsSharedData;
class BaseEvent;
@@ -498,19 +497,6 @@ class GD_CORE_API Project : public ObjectsContainer {
*/
void SerializeTo(SerializerElement& element) const;
/**
* \brief Return true if the project is marked as being modified (The IDE or
* application using the project should ask to save the project if the project
* is closed).
*/
bool IsDirty() { return dirty; }
/**
* \brief Mark the project as being modified (The IDE or application
* using the project should ask to save the project if the project is closed).
*/
void SetDirty(bool enable = true) { dirty = enable; }
/**
* Get the major version of GDevelop used to save the project.
*/
@@ -792,28 +778,6 @@ class GD_CORE_API Project : public ObjectsContainer {
*/
ResourcesManager& GetResourcesManager() { return resourcesManager; }
/**
* \brief Provide access to the ImageManager allowing to load SFML or OpenGL
* textures for the IDE ( or at runtime for the GD C++ Platform ).
*/
const std::shared_ptr<gd::ImageManager>& GetImageManager() const {
return imageManager;
}
/**
* \brief Provide access to the ImageManager allowing to load SFML or OpenGL
* textures for the IDE ( or at runtime for the GD C++ Platform ).
*/
std::shared_ptr<gd::ImageManager>& GetImageManager() { return imageManager; }
/**
* \brief Provide access to the ImageManager allowing to load SFML or OpenGL
* textures for the IDE ( or at runtime for the GD C++ Platform ).
*/
void SetImageManager(std::shared_ptr<gd::ImageManager> imageManager_) {
imageManager = imageManager_;
}
/**
* \brief Called ( e.g. during compilation ) so as to inventory internal
* resources, sometimes update their filename or any other work or resources.
@@ -910,12 +874,6 @@ class GD_CORE_API Project : public ObjectsContainer {
#endif
///@}
// TODO: Put this in private part
#if defined(GD_IDE_ONLY)
std::vector<gd::String> imagesChanged; ///< Images that have been changed and
///< which have to be reloaded
#endif
private:
/**
* Initialize from another game. Used by copy-ctor and assign-op.
@@ -954,9 +912,6 @@ class GD_CORE_API Project : public ObjectsContainer {
#endif
gd::ResourcesManager
resourcesManager; ///< Contains all resources used by the project
std::shared_ptr<gd::ImageManager>
imageManager; ///< Image manager is accessed thanks to a (smart) ptr as
///< it can be shared with GD C++ Platform projects.
std::vector<gd::Platform*>
platforms; ///< Pointers to the platforms this project supports.
gd::String firstLayout;
@@ -987,7 +942,6 @@ class GD_CORE_API Project : public ObjectsContainer {
///< time the project was saved.
mutable unsigned int gdBuildVersion; ///< The GD build version used the last
///< time the project was saved.
mutable bool dirty; ///< True to flag the project as being modified.
#endif
};

View File

@@ -1,108 +0,0 @@
#include "GDCore/Project/ResourcesLoader.h"
#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>
#include <cstring>
#include <fstream>
#include <iostream>
#include <utility>
#include "GDCore/String.h"
#include "GDCore/Tools/FileStream.h"
#undef LoadImage // Undef a macro from windows.h
using namespace std;
namespace gd {
ResourcesLoader *ResourcesLoader::_singleton = NULL;
void ResourcesLoader::LoadSFMLImage(const gd::String &filename,
sf::Image &image) {
gd::SFMLFileStream stream;
if (!stream.open(filename) || !image.loadFromStream(stream))
cout << "Failed to load a SFML image: " << filename << endl;
}
sf::Texture ResourcesLoader::LoadSFMLTexture(const gd::String &filename) {
sf::Texture texture;
LoadSFMLTexture(filename, texture);
return texture;
}
void ResourcesLoader::LoadSFMLTexture(const gd::String &filename,
sf::Texture &texture) {
gd::SFMLFileStream stream;
if (!stream.open(filename) || !texture.loadFromStream(stream))
cout << "Failed to load a SFML texture: " << filename << endl;
}
std::pair<sf::Font *, StreamHolder *> ResourcesLoader::LoadFont(
const gd::String &filename) {
sf::Font *font = new sf::Font();
StreamHolder *streamHolder = new StreamHolder();
if (!streamHolder->stream.open(filename) ||
!font->loadFromStream(streamHolder->stream)) {
cout << "Failed to load a font from a file: " << filename << endl;
delete font;
delete streamHolder;
return std::make_pair((sf::Font *)nullptr, (StreamHolder *)nullptr);
}
return std::make_pair(font, streamHolder);
}
sf::SoundBuffer ResourcesLoader::LoadSoundBuffer(const gd::String &filename) {
sf::SoundBuffer sbuffer;
gd::SFMLFileStream stream;
if (!stream.open(filename) || !sbuffer.loadFromStream(stream))
cout << "Failed to load a sound buffer: " << filename << endl;
return sbuffer;
}
gd::String ResourcesLoader::LoadPlainText(const gd::String &filename) {
gd::String text;
gd::FileStream file(filename, ios::in);
if (!file.fail()) {
std::string ligne;
while (getline(file, ligne)) text += gd::String::FromUTF8(ligne) + "\n";
file.close();
} else
cout << "Failed to read a file: " << filename << endl;
return text;
}
/**
* Load a binary text file
*/
char *ResourcesLoader::LoadBinaryFile(const gd::String &filename) {
gd::FileStream file(filename, ios::in | ios::binary | ios::ate);
if (file.is_open()) {
iostream::pos_type size = file.tellg();
char *memblock = new char[size];
file.seekg(0, ios::beg);
file.read(memblock, size);
file.close();
return memblock;
}
cout << "Binary file " << filename << " can't be loaded into memory " << endl;
return NULL;
}
long int ResourcesLoader::GetBinaryFileSize(const gd::String &filename) {
gd::FileStream file(filename, ios::in | ios::binary | ios::ate);
if (file.is_open()) {
return file.tellg();
}
std::cout << "Binary file " << filename << " cannot be read. " << std::endl;
return 0;
}
} // namespace gd

View File

@@ -1,106 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#ifndef RESSOURCESLOADER_H
#define RESSOURCESLOADER_H
#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>
#include "GDCore/String.h"
#include "GDCore/Tools/FileStream.h"
#undef LoadImage // Undef macro from windows.h
namespace gd {
/**
* \brief A class holding a buffer and/or a file stream (useful for SFML classes
* that needs their buffer/stream continuously opened)
*/
struct StreamHolder {
StreamHolder() : buffer(nullptr), stream() {}
~StreamHolder() {
if (buffer) delete buffer;
}
char *buffer;
gd::SFMLFileStream stream;
};
/**
* \brief Class used by games to load resources from files: this is purely an
* abstraction to most SFML loadFrom* functions.
*
* This class is replaced in GDCpp by an equivalent that can load also from
* memory.
*
* \ingroup ResourcesManagement
*/
class GD_CORE_API ResourcesLoader {
public:
void LoadSFMLImage(const gd::String &filename, sf::Image &image);
/**
* Load a SFML texture.
*/
sf::Texture LoadSFMLTexture(const gd::String &filename);
void LoadSFMLTexture(const gd::String &filename, sf::Texture &texture);
/**
* Load a SFML Font.
* \warning The function calling LoadFont is the owner of the returned font
* and buffer (if any): Don't forget to delete them after use.
*
* \return A pair containing the loaded font, or NULL if loading failed, and
* the buffer that need to be kept alive while the font is used (can be NULL
* if the font was loaded from a file).
*/
std::pair<sf::Font *, StreamHolder *> LoadFont(const gd::String &filename);
/**
* Load a SFML Sound Buffer
*/
sf::SoundBuffer LoadSoundBuffer(const gd::String &filename);
/**
* Load a plain text file
*/
gd::String LoadPlainText(const gd::String &filename);
/**
* Get a buffer for file.
* Be careful, the buffer will be invalided by any subsequent call to
* Load[Something]. Make a copy of the buffer if you want it to stay alive
* longer.
*/
char *LoadBinaryFile(const gd::String &filename);
/**
* Get the size of a file
*/
long int GetBinaryFileSize(const gd::String &filename);
static ResourcesLoader *Get() {
if (NULL == _singleton) {
_singleton = new ResourcesLoader;
}
return (static_cast<ResourcesLoader *>(_singleton));
}
static void DestroySingleton() {
if (NULL != _singleton) {
delete _singleton;
_singleton = NULL;
}
}
private:
ResourcesLoader(){};
virtual ~ResourcesLoader(){};
static ResourcesLoader *_singleton;
};
} // namespace gd
#endif // RESSOURCESLOADER_H

View File

@@ -9,12 +9,11 @@
/** @file
* Provide a way to mark strings to be translated.
*
* Strings to be translated in GDevelop Core codebase (and GDCpp),
* Strings to be translated in GDevelop Core codebase
* are marked with the underscore macro, for example: _("Hello World").
*
* The macro is then defined to be using the translation function
* of the underlying platform (Emscripten for GDevelop 5,
* no translation for GDCpp Runtime).
* of the underlying platform (Emscripten for GDevelop 5).
*/
#if defined(EMSCRIPTEN)
@@ -33,7 +32,7 @@ gd::String GetTranslation(const char* str);
#define _(s) gd::GetTranslation(u8##s)
#else
// When compiling without Emscripten (typically for GDC++ Runtime),
// When compiling without Emscripten,
// just return an untranslated gd::String.
// Create a new macro to return UTF8 gd::String from a translation

View File

@@ -35,13 +35,6 @@ gd::String VersionWrapper::Year() {
gd::String VersionWrapper::Status() {
return Revision() == 0 ? "Release" : "Dev";
}
bool VersionWrapper::CompiledForEdittime() {
#if defined(GD_IDE_ONLY)
return true;
#else
return false;
#endif
}
bool VersionWrapper::IsOlder(int major,
int minor,

View File

@@ -48,11 +48,6 @@ class GD_CORE_API VersionWrapper {
*/
static gd::String Status();
/**
* \brief Return true if GDCpp is compiled with edittime support.
*/
static bool CompiledForEdittime();
/**
* \brief Get Year of the release
*/

View File

@@ -1,13 +1,12 @@
# GDevelop Architecture Overview
GDevelop is architectured around a `Core` library, platforms (`GDJS`, `GDCpp`) and extensions (`Extensions` folder). The editor (`newIDE` folder) is using all of these libraries. This is a recap table of the main folders:
GDevelop is architectured around a `Core` library, the game engine (`GDJS`) and extensions (`Extensions` folder). The editor (`newIDE` folder) is using all of these libraries. This is a recap table of the main folders:
| Directory | Description |
| ------------- | ----------------------------------------------------------------------------------------------------- |
| `Core` | GDevelop core library, containing common tools to implement the IDE and work with GDevelop games. |
| `GDCpp` | The C++ game engine, used to build native games (_not used in GDevelop 5_). |
| `GDJS` | The game engine, written in TypeScript, using PixiJS (WebGL), powering all GDevelop games. |
| `GDevelop.js` | Bindings of `Core`/`GDCpp`/`GDJS` and `Extensions` to JavaScript (with WebAssembly), used by the IDE. |
| `GDevelop.js` | Bindings of `Core`, `GDJS` and `Extensions` to JavaScript (with WebAssembly), used by the IDE. |
| `newIDE` | The game editor, written in JavaScript with React, Electron and PixiJS. |
| `Extensions` | Extensions for the game engine, providing objects, behaviors, events and new features. |
@@ -17,11 +16,11 @@ The rest of this page is an introduction to the main concepts of GDevelop archit
**IDE** stands for "Integrated Development Environment". A synonym for it is also simply "editor". In GDevelop, the software itself, that is used to create games and running as an app or a web-app, is called the "GDevelop Editor" or the "GDevelop IDE"
> The term "IDE" is also used in some folders. When you browse `Core`, `GDCpp` or `GDJS` subfolders, some folders are called `IDE`. They contain classes and tools that are **only useful for the editor** (they are not per se mandatory to describe the structure of a game).
> The term "IDE" is also used in some folders. When you browse `Core` or `GDJS` subfolders, some folders are called `IDE`. They contain classes and tools that are **only useful for the editor** (they are not per se mandatory to describe the structure of a game).
**Runtime** is a word used to describe classes, tools and source files being used during a game. This could also be called "in-game" or a "game engine".
> When you browse `GDCpp` or `GDJS` subfolders, you can find folders called `Runtime`. They contain the **game engine** of GDevelop.
> When you browse `GDJS` subfolder, you can find a folder called `Runtime`. It's the **game engine** of GDevelop.
Extensions do have the same distinction between the "**IDE**" part and the "**Runtime**" part. For example, most extensions have:
@@ -79,7 +78,7 @@ You're welcome to do so! Please get in touch :)
The idea of the GDevelop editor and game engine is to have a lean game engine, supporting almost nothing. Then, one can add "mods", "plugins", "modules" for GDevelop. We chose to call them "**Extensions**" in GDevelop.
- `GDevelop/Core/GDCore/Extensions` is the **declaration** of default (we say "builtin") extensions, that are available for any game and are "mandatory". They are called Extensions but they could be named "Extensions that will always be in your game". In programming languages, this is called a "[Standard Library](https://en.wikipedia.org/wiki/Standard_library)" (but don't get too distracted by this naming).
- `GDevelop/GDJS/GDJS/Extensions/` and `GDevelop/GDCpp/GDCpp/Extensions/` are reusing these **declarations** and **adding** their own declarations. Mainly, they are setting the name of the functions to be called (either in TypeScript or in C++) for each action, condition or expression.
- `GDevelop/GDJS/GDJS/Extensions/` is reusing these **declarations** and **adding** their own declarations. Mainly, they are setting the name of the functions to be called (either in TypeScript or in C++) for each action, condition or expression.
- `GDevelop/Extensions/` is the folder for the "mods"/"plugins" for GDevelop - the ones that are not mandatory. They are not part of GDCore - they work on their own.
> In theory, all extensions could be moved to `GDevelop/Extensions/`. In practice, it's more pragmatic to have a set of "built-in" extensions with basic features.

View File

@@ -24,12 +24,14 @@ namespace gdjs {
}
}
};
export const isFocused = function (): boolean {
if (electronBrowserWindow) {
return electronBrowserWindow.isFocused();
}
return false;
};
export const show = function (activate: boolean) {
if (electronBrowserWindow) {
if (activate) {
@@ -39,12 +41,14 @@ namespace gdjs {
}
}
};
export const isVisible = function (): boolean {
if (electronBrowserWindow) {
return electronBrowserWindow.isVisible();
}
return false;
};
export const maximize = function (activate: boolean) {
if (electronBrowserWindow) {
if (activate) {
@@ -54,12 +58,14 @@ namespace gdjs {
}
}
};
export const isMaximized = function (): boolean {
if (electronBrowserWindow) {
return electronBrowserWindow.isMaximized();
}
return false;
};
export const minimize = function (activate: boolean) {
if (electronBrowserWindow) {
if (activate) {
@@ -69,89 +75,105 @@ namespace gdjs {
}
}
};
export const isMinimized = function (): boolean {
if (electronBrowserWindow) {
return electronBrowserWindow.isMinimized();
}
return false;
};
export const enable = function (activate: boolean) {
if (electronBrowserWindow) {
electronBrowserWindow.setEnabled(activate);
}
};
export const isEnabled = function (): boolean {
if (electronBrowserWindow) {
return electronBrowserWindow.isEnabled();
}
return false;
};
export const setResizable = function (activate: boolean) {
if (electronBrowserWindow) {
electronBrowserWindow.setResizable(activate);
}
};
export const isResizable = function (): boolean {
if (electronBrowserWindow) {
return electronBrowserWindow.isResizable();
}
return false;
};
export const setMovable = function (activate: boolean) {
if (electronBrowserWindow) {
electronBrowserWindow.setMovable(activate);
}
};
export const isMovable = function (): boolean {
if (electronBrowserWindow) {
return electronBrowserWindow.isMovable();
}
return false;
};
export const setMaximizable = function (activate: boolean) {
if (electronBrowserWindow) {
electronBrowserWindow.setMaximizable(activate);
}
};
export const isMaximizable = function (): boolean {
if (electronBrowserWindow) {
return electronBrowserWindow.isMaximizable();
}
return false;
};
export const setMinimizable = function (activate: boolean) {
if (electronBrowserWindow) {
electronBrowserWindow.setMinimizable(activate);
}
};
export const isMinimizable = function (): boolean {
if (electronBrowserWindow) {
return electronBrowserWindow.isMinimizable();
}
return false;
};
export const setFullScreenable = function (activate: boolean) {
if (electronBrowserWindow) {
electronBrowserWindow.setFullScreenable(activate);
}
};
export const isFullScreenable = function (): boolean {
if (electronBrowserWindow) {
return electronBrowserWindow.isFullScreenable();
}
return false;
};
export const setClosable = function (activate: boolean) {
if (electronBrowserWindow) {
electronBrowserWindow.setClosable(activate);
}
};
export const isClosable = function (): boolean {
if (electronBrowserWindow) {
return electronBrowserWindow.isClosable();
}
return false;
};
export const setAlwaysOnTop = function (
activate: boolean,
level:
@@ -168,73 +190,86 @@ namespace gdjs {
electronBrowserWindow.setAlwaysOnTop(activate, level);
}
};
export const isAlwaysOnTop = function (): boolean {
if (electronBrowserWindow) {
return electronBrowserWindow.isAlwaysOnTop();
}
return false;
};
export const setPosition = function (x: float, y: float) {
if (electronBrowserWindow) {
// Convert x and y to (32 bit) integers to avoid Electron errors.
electronBrowserWindow.setPosition(~~x, ~~y);
}
};
export const getPositionX = function (): number {
if (electronBrowserWindow) {
return electronBrowserWindow.getPosition()[0];
}
return 0;
};
export const getPositionY = function (): number {
if (electronBrowserWindow) {
return electronBrowserWindow.getPosition()[1];
}
return 0;
};
export const setKiosk = function (activate: boolean) {
if (electronBrowserWindow) {
electronBrowserWindow.setKiosk(activate);
}
};
export const isKiosk = function (): boolean {
if (electronBrowserWindow) {
return electronBrowserWindow.isKiosk();
}
return false;
};
export const flash = function (activate: boolean) {
if (electronBrowserWindow) {
electronBrowserWindow.flashFrame(activate);
}
};
export const setHasShadow = function (activate: boolean) {
if (electronBrowserWindow) {
electronBrowserWindow.setHasShadow(activate);
}
};
export const hasShadow = function (): boolean {
if (electronBrowserWindow) {
return electronBrowserWindow.hasShadow();
}
return false;
};
export const setOpacity = function (opacity: float) {
if (electronBrowserWindow) {
electronBrowserWindow.setOpacity(opacity);
}
};
export const getOpacity = function (): number {
if (electronBrowserWindow) {
return electronBrowserWindow.getOpacity();
}
return 1;
};
export const setContentProtection = function (activate: boolean) {
if (electronBrowserWindow) {
electronBrowserWindow.setContentProtection(activate);
}
};
export const setFocusable = function (activate: boolean) {
if (electronBrowserWindow) {
electronBrowserWindow.setFocusable(activate);

View File

@@ -6,8 +6,8 @@ This project is released under the MIT License.
#ifndef ANCHORBEHAVIOR_H
#define ANCHORBEHAVIOR_H
#include <vector>
#include "GDCpp/Runtime/Project/Behavior.h"
#include "GDCpp/Runtime/Project/Object.h"
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/Object.h"
namespace gd {
class SerializerElement;
class Project;
@@ -16,7 +16,7 @@ class Project;
/**
* \brief Allow to anchor objects to the window's bounds.
*/
class GD_EXTENSION_API AnchorBehavior : public Behavior {
class GD_EXTENSION_API AnchorBehavior : public gd::Behavior {
public:
enum HorizontalAnchor {
ANCHOR_HORIZONTAL_NONE = 0,

View File

@@ -1,212 +0,0 @@
/**
GDevelop - Anchor Behavior Extension
Copyright (c) 2016 Victor Levasseur (victorlevasseur52@gmail.com)
This project is released under the MIT License.
*/
#include "AnchorRuntimeBehavior.h"
#include <SFML/Window.hpp>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <memory>
#include <set>
#include "GDCore/CommonTools.h"
#include "GDCore/Tools/Localization.h"
#include "GDCpp/Extensions/Builtin/MathematicalTools.h"
#include "GDCpp/Runtime/CommonTools.h"
#include "GDCpp/Runtime/Project/Layout.h"
#include "GDCpp/Runtime/RuntimeGame.h"
#include "GDCpp/Runtime/RuntimeObject.h"
#include "GDCpp/Runtime/RuntimeScene.h"
#include "GDCpp/Runtime/Serialization/SerializerElement.h"
#if defined(GD_IDE_ONLY)
#include <map>
#include "GDCore/Project/PropertyDescriptor.h"
#endif
AnchorRuntimeBehavior::AnchorRuntimeBehavior(
const gd::SerializerElement& behaviorContent)
: RuntimeBehavior(behaviorContent),
m_relativeToOriginalWindowSize(true),
m_leftEdgeAnchor(ANCHOR_HORIZONTAL_NONE),
m_rightEdgeAnchor(ANCHOR_HORIZONTAL_NONE),
m_topEdgeAnchor(ANCHOR_VERTICAL_NONE),
m_bottomEdgeAnchor(ANCHOR_VERTICAL_NONE),
m_invalidDistances(true),
m_leftEdgeDistance(0.f),
m_rightEdgeDistance(0.f),
m_topEdgeDistance(0.f),
m_bottomEdgeDistance(0.f) {
m_relativeToOriginalWindowSize =
behaviorContent.GetBoolAttribute("relativeToOriginalWindowSize");
m_leftEdgeAnchor = static_cast<HorizontalAnchor>(
behaviorContent.GetIntAttribute("leftEdgeAnchor"));
m_rightEdgeAnchor = static_cast<HorizontalAnchor>(
behaviorContent.GetIntAttribute("rightEdgeAnchor"));
m_topEdgeAnchor = static_cast<VerticalAnchor>(
behaviorContent.GetIntAttribute("topEdgeAnchor"));
m_bottomEdgeAnchor = static_cast<VerticalAnchor>(
behaviorContent.GetIntAttribute("bottomEdgeAnchor"));
}
void AnchorRuntimeBehavior::OnActivate() { m_invalidDistances = true; }
namespace {
sf::Vector2f mapFloatPixelToCoords(const sf::Vector2f& point,
const sf::RenderTarget& target,
const sf::View& view) {
// First, convert from viewport coordinates to homogeneous coordinates
sf::Vector2f normalized;
sf::IntRect viewport = target.getViewport(view);
normalized.x = -1.f + 2.f * (point.x - static_cast<float>(viewport.left)) /
static_cast<float>(viewport.width);
normalized.y = 1.f - 2.f * (point.y - static_cast<float>(viewport.top)) /
static_cast<float>(viewport.height);
// Then transform by the inverse of the view matrix
return view.getInverseTransform().transformPoint(normalized);
}
sf::Vector2f mapCoordsToFloatPixel(const sf::Vector2f& point,
const sf::RenderTarget& target,
const sf::View& view) {
// Note: almost the same as RenderTarget::mapCoordsToPixel except that the
// result is sf::Vector2f
// First, transform the point by the view matrix
sf::Vector2f normalized = view.getTransform().transformPoint(point);
// Then convert to viewport coordinates
sf::Vector2f pixel;
sf::IntRect viewport = target.getViewport(view);
pixel.x = (normalized.x + 1.f) / 2.f * static_cast<float>(viewport.width) +
static_cast<float>(viewport.left);
pixel.y = (-normalized.y + 1.f) / 2.f * static_cast<float>(viewport.height) +
static_cast<float>(viewport.top);
return pixel;
}
} // namespace
void AnchorRuntimeBehavior::DoStepPreEvents(RuntimeScene& scene) {}
void AnchorRuntimeBehavior::DoStepPostEvents(RuntimeScene& scene) {
const RuntimeLayer& layer = scene.GetRuntimeLayer(object->GetLayer());
const RuntimeCamera& firstCamera = layer.GetCamera(0);
if (m_invalidDistances) {
sf::Vector2u windowSize =
m_relativeToOriginalWindowSize
? sf::Vector2u(scene.game->getWindowOriginalWidth(),
scene.game->getWindowOriginalHeight())
: scene.renderWindow->getSize();
// Calculate the distances from the window's bounds.
sf::Vector2f topLeftPixel = mapCoordsToFloatPixel(
sf::Vector2f(object->GetDrawableX(), object->GetDrawableY()),
*(scene.renderWindow),
firstCamera.GetSFMLView());
sf::Vector2f bottomRightPixel = mapCoordsToFloatPixel(
sf::Vector2f(object->GetDrawableX() + object->GetWidth(),
object->GetDrawableY() + object->GetHeight()),
*(scene.renderWindow),
firstCamera.GetSFMLView());
// Left edge
if (m_leftEdgeAnchor == ANCHOR_HORIZONTAL_WINDOW_LEFT)
m_leftEdgeDistance = topLeftPixel.x;
else if (m_leftEdgeAnchor == ANCHOR_HORIZONTAL_WINDOW_RIGHT)
m_leftEdgeDistance = static_cast<float>(windowSize.x) - topLeftPixel.x;
else if (m_leftEdgeAnchor == ANCHOR_HORIZONTAL_PROPORTIONAL)
m_leftEdgeDistance = topLeftPixel.x / windowSize.x;
// Right edge
if (m_rightEdgeAnchor == ANCHOR_HORIZONTAL_WINDOW_LEFT)
m_rightEdgeDistance = bottomRightPixel.x;
else if (m_rightEdgeAnchor == ANCHOR_HORIZONTAL_WINDOW_RIGHT)
m_rightEdgeDistance =
static_cast<float>(windowSize.x) - bottomRightPixel.x;
else if (m_rightEdgeAnchor == ANCHOR_HORIZONTAL_PROPORTIONAL)
m_rightEdgeDistance = bottomRightPixel.x / windowSize.x;
// Top edge
if (m_topEdgeAnchor == ANCHOR_VERTICAL_WINDOW_TOP)
m_topEdgeDistance = topLeftPixel.y;
else if (m_topEdgeAnchor == ANCHOR_VERTICAL_WINDOW_BOTTOM)
m_topEdgeDistance = static_cast<float>(windowSize.y) - topLeftPixel.y;
else if (m_topEdgeAnchor == ANCHOR_VERTICAL_PROPORTIONAL)
m_topEdgeDistance = topLeftPixel.y / static_cast<float>(windowSize.y);
// Bottom edge
if (m_bottomEdgeAnchor == ANCHOR_VERTICAL_WINDOW_TOP)
m_bottomEdgeDistance = bottomRightPixel.y;
else if (m_bottomEdgeAnchor == ANCHOR_VERTICAL_WINDOW_BOTTOM)
m_bottomEdgeDistance =
static_cast<float>(windowSize.y) - bottomRightPixel.y;
else if (m_bottomEdgeAnchor == ANCHOR_VERTICAL_PROPORTIONAL)
m_bottomEdgeDistance =
bottomRightPixel.y / static_cast<float>(windowSize.y);
m_invalidDistances = false;
} else {
sf::Vector2u windowSize = scene.renderWindow->getSize();
// Move and resize the object if needed
sf::Vector2f topLeftPixel;
sf::Vector2f bottomRightPixel;
// Left edge
if (m_leftEdgeAnchor == ANCHOR_HORIZONTAL_WINDOW_LEFT)
topLeftPixel.x = m_leftEdgeDistance;
else if (m_leftEdgeAnchor == ANCHOR_HORIZONTAL_WINDOW_RIGHT)
topLeftPixel.x = static_cast<float>(windowSize.x) - m_leftEdgeDistance;
else if (m_leftEdgeAnchor == ANCHOR_HORIZONTAL_PROPORTIONAL)
topLeftPixel.x = m_leftEdgeDistance * static_cast<float>(windowSize.x);
// Top edge
if (m_topEdgeAnchor == ANCHOR_VERTICAL_WINDOW_TOP)
topLeftPixel.y = m_topEdgeDistance;
else if (m_topEdgeAnchor == ANCHOR_VERTICAL_WINDOW_BOTTOM)
topLeftPixel.y = static_cast<float>(windowSize.y) - m_topEdgeDistance;
else if (m_topEdgeAnchor == ANCHOR_VERTICAL_PROPORTIONAL)
topLeftPixel.y = m_topEdgeDistance * static_cast<float>(windowSize.y);
// Right edge
if (m_rightEdgeAnchor == ANCHOR_HORIZONTAL_WINDOW_LEFT)
bottomRightPixel.x = m_rightEdgeDistance;
else if (m_rightEdgeAnchor == ANCHOR_HORIZONTAL_WINDOW_RIGHT)
bottomRightPixel.x =
static_cast<float>(windowSize.x) - m_rightEdgeDistance;
else if (m_rightEdgeAnchor == ANCHOR_HORIZONTAL_PROPORTIONAL)
bottomRightPixel.x =
m_rightEdgeDistance * static_cast<float>(windowSize.x);
// Bottom edge
if (m_bottomEdgeAnchor == ANCHOR_VERTICAL_WINDOW_TOP)
bottomRightPixel.y = m_bottomEdgeDistance;
else if (m_bottomEdgeAnchor == ANCHOR_VERTICAL_WINDOW_BOTTOM)
bottomRightPixel.y =
static_cast<float>(windowSize.y) - m_bottomEdgeDistance;
else if (m_bottomEdgeAnchor == ANCHOR_VERTICAL_PROPORTIONAL)
bottomRightPixel.y =
m_bottomEdgeDistance * static_cast<float>(windowSize.y);
sf::Vector2f topLeftCoord = mapFloatPixelToCoords(
topLeftPixel, (*scene.renderWindow), firstCamera.GetSFMLView());
sf::Vector2f bottomRightCoord = mapFloatPixelToCoords(
bottomRightPixel, (*scene.renderWindow), firstCamera.GetSFMLView());
// Move and resize the object according to the anchors
if (m_rightEdgeAnchor != ANCHOR_HORIZONTAL_NONE)
object->SetWidth(bottomRightCoord.x - topLeftCoord.x);
if (m_bottomEdgeAnchor != ANCHOR_VERTICAL_NONE)
object->SetHeight(bottomRightCoord.y - topLeftCoord.y);
if (m_leftEdgeAnchor != ANCHOR_HORIZONTAL_NONE)
object->SetX(topLeftCoord.x + object->GetX() - object->GetDrawableX());
if (m_topEdgeAnchor != ANCHOR_VERTICAL_NONE)
object->SetY(topLeftCoord.y + object->GetY() - object->GetDrawableY());
}
}

View File

@@ -1,72 +0,0 @@
/**
GDevelop - Anchor Behavior Extension
Copyright (c) 2016 Victor Levasseur (victorlevasseur52@gmail.com)
This project is released under the MIT License.
*/
#ifndef ANCHORRuntimeBEHAVIOR_H
#define ANCHORRuntimeBEHAVIOR_H
#include <SFML/Graphics/RenderTarget.hpp>
#include <SFML/Graphics/View.hpp>
#include <SFML/System/Vector2.hpp>
#include <vector>
#include "GDCpp/Runtime/RuntimeBehavior.h"
#include "GDCpp/Runtime/Project/Object.h"
namespace gd {
class Layout;
}
class RuntimeScene;
namespace gd {
class SerializerElement;
}
class RuntimeScenePlatformData;
/**
* \brief Allow to anchor objects to the window's bounds.
*/
class GD_EXTENSION_API AnchorRuntimeBehavior : public RuntimeBehavior {
public:
enum HorizontalAnchor {
ANCHOR_HORIZONTAL_NONE = 0,
ANCHOR_HORIZONTAL_WINDOW_LEFT = 1,
ANCHOR_HORIZONTAL_WINDOW_RIGHT = 2,
ANCHOR_HORIZONTAL_PROPORTIONAL = 3
};
enum VerticalAnchor {
ANCHOR_VERTICAL_NONE = 0,
ANCHOR_VERTICAL_WINDOW_TOP = 1,
ANCHOR_VERTICAL_WINDOW_BOTTOM = 2,
ANCHOR_VERTICAL_PROPORTIONAL = 3
};
AnchorRuntimeBehavior(const gd::SerializerElement& behaviorContent);
virtual ~AnchorRuntimeBehavior(){};
virtual AnchorRuntimeBehavior* Clone() const override { return new AnchorRuntimeBehavior(*this); }
virtual void OnActivate() override;
private:
virtual void DoStepPreEvents(RuntimeScene& scene) override;
virtual void DoStepPostEvents(RuntimeScene& scene) override;
bool m_relativeToOriginalWindowSize; ///< True if the original size of the
///< game window must be used.
HorizontalAnchor m_leftEdgeAnchor;
HorizontalAnchor m_rightEdgeAnchor;
VerticalAnchor m_topEdgeAnchor;
VerticalAnchor m_bottomEdgeAnchor;
bool m_invalidDistances;
// Distances (in window's units) from the XXX edge of the object to side of
// the window the edge is anchored on. Note: If the edge anchor is set to
// PROPORTIONAL, then it contains the ratio of the distance to the window
// size.
float m_leftEdgeDistance;
float m_rightEdgeDistance;
float m_topEdgeDistance;
float m_bottomEdgeDistance;
};
#endif // ANCHORRuntimeBEHAVIOR_H

View File

@@ -13,14 +13,8 @@ gd_add_extension_definitions(AnchorBehavior)
include_directories(.)
file(GLOB source_files *.cpp *.h)
gd_add_clang_utils(AnchorBehavior "${source_files}")
gd_add_extension_target(AnchorBehavior "${source_files}")
gdcpp_add_runtime_extension_target(AnchorBehavior_Runtime "${source_files}")
#Linker files for the IDE extension
###
gd_extension_link_libraries(AnchorBehavior)
#Linker files for the GD C++ Runtime extension
###
gdcpp_runtime_extension_link_libraries(AnchorBehavior_Runtime)

View File

@@ -6,9 +6,9 @@ This project is released under the MIT License.
*/
#include "AnchorBehavior.h"
#include "AnchorRuntimeBehavior.h"
#include "GDCpp/Extensions/ExtensionBase.h"
#include "GDCpp/Runtime/Project/BehaviorsSharedData.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Project/BehaviorsSharedData.h"
#include "GDCore/Tools/Localization.h"
void DeclareAnchorBehaviorExtension(gd::PlatformExtension& extension) {
extension
@@ -30,38 +30,3 @@ void DeclareAnchorBehaviorExtension(gd::PlatformExtension& extension) {
std::make_shared<AnchorBehavior>(),
std::make_shared<gd::BehaviorsSharedData>());
}
/**
* \brief This class declares information about the extension.
*/
class AnchorBehaviorCppExtension : public ExtensionBase {
public:
/**
* Constructor of an extension declares everything the extension contains:
* objects, actions, conditions and expressions.
*/
AnchorBehaviorCppExtension() {
DeclareAnchorBehaviorExtension(*this);
AddRuntimeBehavior<AnchorRuntimeBehavior>(
GetBehaviorMetadata("AnchorBehavior::AnchorBehavior"),
"AnchorRuntimeBehavior");
GetBehaviorMetadata("AnchorBehavior::AnchorBehavior")
.SetIncludeFile("AnchorBehavior/AnchorRuntimeBehavior.h");
GD_COMPLETE_EXTENSION_COMPILATION_INFORMATION();
};
};
#if defined(ANDROID)
extern "C" ExtensionBase* CreateGDCppAnchorBehaviorExtension() {
return new AnchorBehaviorCppExtension;
}
#elif !defined(EMSCRIPTEN)
/**
* Used by GDevelop to create the extension class
* -- Do not need to be modified. --
*/
extern "C" ExtensionBase* GD_EXTENSION_API CreateGDExtension() {
return new AnchorBehaviorCppExtension;
}
#endif

View File

@@ -6,7 +6,6 @@
macro(gd_add_extension_includes)
include_directories(${sfml_include_dir})
include_directories(${GDCORE_include_dir})
include_directories(${GDCpp_include_dir})
endmacro()
#Add common defines for a target that will be a GD extension
@@ -76,69 +75,13 @@ function(gd_add_extension_target target_name source_files)
ENDIF()
endfunction()
#Add a GDC++ runtime extension target, that will produce the final library file for runtime.
function(gdcpp_add_runtime_extension_target gdcpp_runtime_target_name source_files)
IF(NOT gdcpp_runtime_target_name MATCHES "_Runtime$")
MESSAGE(ERROR "You called gdcpp_add_runtime_extension_target with a target name not finishing with '_Runtime'")
ENDIF()
string(REGEX REPLACE "_Runtime" "" target_name ${gdcpp_runtime_target_name})
IF(NOT EMSCRIPTEN) #Also add a GDC++ extension target
add_library(${gdcpp_runtime_target_name} SHARED ${source_files})
set_target_properties(${gdcpp_runtime_target_name} PROPERTIES COMPILE_DEFINITIONS "${${gdcpp_runtime_target_name}_extra_definitions}")
set_target_properties(${gdcpp_runtime_target_name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME}/CppPlatform/Extensions/Runtime")
set_target_properties(${gdcpp_runtime_target_name} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME}/CppPlatform/Extensions/Runtime")
set_target_properties(${gdcpp_runtime_target_name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME}/CppPlatform/Extensions/Runtime")
set_target_properties(${gdcpp_runtime_target_name} PROPERTIES RUNTIME_OUTPUT_NAME "${target_name}")
set_target_properties(${gdcpp_runtime_target_name} PROPERTIES LIBRARY_OUTPUT_NAME "${target_name}")
set_target_properties(${gdcpp_runtime_target_name} PROPERTIES ARCHIVE_OUTPUT_NAME "${target_name}")
set_target_properties(${gdcpp_runtime_target_name} PROPERTIES PREFIX "")
IF(WIN32) #GD extensions have special suffix in their filenames.
set_target_properties(${gdcpp_runtime_target_name} PROPERTIES SUFFIX ".xgdw")
ELSE()
set_target_properties(${gdcpp_runtime_target_name} PROPERTIES SUFFIX ".xgd")
ENDIF()
ENDIF()
endfunction()
#Link default libraries with a target that is a GD extension
function(gd_extension_link_libraries target_name)
IF(EMSCRIPTEN)
#Nothing.
ELSE()
target_link_libraries(${target_name} GDCore)
target_link_libraries(${target_name} GDCpp)
target_link_libraries(${target_name} ${sfml_LIBRARIES})
ENDIF()
endfunction()
#Link default libraries with a target that is a GDC++ Runtime extension
function(gdcpp_runtime_extension_link_libraries target_name)
IF(EMSCRIPTEN)
#Nothing.
ELSE()
target_link_libraries(${target_name} GDCpp_Runtime)
target_link_libraries(${target_name} ${sfml_LIBRARIES})
IF(WIN32)
target_link_libraries(${target_name} ws2_32 user32 opengl32 glu32)
ENDIF(WIN32)
ENDIF()
endfunction()
#Create a target for a test executable of a GDC++ Runtime extension
function(gdcpp_add_tests_extension_target gdcpp_tests_target_name test_source_files)
IF(NOT gdcpp_tests_target_name MATCHES "_tests$")
MESSAGE(ERROR "You called gdcpp_add_tests_extension_target with a target name not finishing with '_tests'")
ENDIF()
string(REGEX REPLACE "_tests" "" target_name ${gdcpp_tests_target_name})
if(BUILD_TESTS)
add_executable(${gdcpp_tests_target_name} ${test_source_files})
target_link_libraries(${gdcpp_tests_target_name} GDCpp_Runtime)
target_link_libraries(${gdcpp_tests_target_name} ${target_name})
target_link_libraries(${gdcpp_tests_target_name} ${sfml_LIBRARIES})
set_target_properties(${gdcpp_tests_target_name} PROPERTIES BUILD_WITH_INSTALL_RPATH FALSE) #Allow finding dependencies directly from build path on Mac OS X.
endif()
endfunction()

View File

@@ -13,14 +13,8 @@ gd_add_extension_definitions(DestroyOutsideBehavior)
include_directories(.)
file(GLOB source_files *.cpp *.h)
gd_add_clang_utils(DestroyOutsideBehavior "${source_files}")
gd_add_extension_target(DestroyOutsideBehavior "${source_files}")
gdcpp_add_runtime_extension_target(DestroyOutsideBehavior_Runtime "${source_files}")
#Linker files for the IDE extension
###
gd_extension_link_libraries(DestroyOutsideBehavior GDCore)
#Linker files for the GD C++ Runtime extension
###
gdcpp_runtime_extension_link_libraries(DestroyOutsideBehavior_Runtime)

View File

@@ -1,55 +0,0 @@
/**
GDevelop - DestroyOutside Behavior Extension
Copyright (c) 2014-2016 Florian Rival (Florian.Rival@gmail.com)
This project is released under the MIT License.
*/
#include "DestroyOutsideRuntimeBehavior.h"
#include <SFML/Graphics.hpp>
#include <iostream>
#include <memory>
#include "GDCpp/Runtime/CommonTools.h"
#include "GDCpp/Runtime/Project/Layout.h"
#include "GDCpp/Runtime/RuntimeLayer.h"
#include "GDCpp/Runtime/RuntimeObject.h"
#include "GDCpp/Runtime/RuntimeScene.h"
#include "GDCpp/Runtime/Serialization/SerializerElement.h"
DestroyOutsideRuntimeBehavior::DestroyOutsideRuntimeBehavior(
const gd::SerializerElement& behaviorContent)
: RuntimeBehavior(behaviorContent), extraBorder(0) {
extraBorder = behaviorContent.GetDoubleAttribute("extraBorder", 0);
}
void DestroyOutsideRuntimeBehavior::DoStepPostEvents(RuntimeScene& scene) {
bool erase = true;
const RuntimeLayer& theLayer = scene.GetRuntimeLayer(object->GetLayer());
float objCenterX = object->GetDrawableX() + object->GetCenterX();
float objCenterY = object->GetDrawableY() + object->GetCenterY();
for (std::size_t cameraIndex = 0; cameraIndex < theLayer.GetCameraCount();
++cameraIndex) {
const RuntimeCamera& theCamera = theLayer.GetCamera(cameraIndex);
float boundingCircleRadius =
sqrt(object->GetWidth() * object->GetWidth() +
object->GetHeight() * object->GetHeight()) /
2.0;
if (objCenterX + boundingCircleRadius + extraBorder <
theCamera.GetViewCenter().x - theCamera.GetWidth() / 2.0 ||
objCenterX - boundingCircleRadius - extraBorder >
theCamera.GetViewCenter().x + theCamera.GetWidth() / 2.0 ||
objCenterY + boundingCircleRadius + extraBorder <
theCamera.GetViewCenter().y - theCamera.GetHeight() / 2.0 ||
objCenterY - boundingCircleRadius - extraBorder >
theCamera.GetViewCenter().y + theCamera.GetHeight() / 2.0) {
// Ok we are outside the camera area.
} else {
// The object can be viewed by the camera.
erase = false;
break;
}
}
if (erase) object->DeleteFromScene(scene);
}

View File

@@ -1,47 +0,0 @@
/**
GDevelop - DestroyOutside Behavior Extension
Copyright (c) 2013-2016 Florian Rival (Florian.Rival@gmail.com)
This project is released under the MIT License.
*/
#ifndef DESTROYOUTSIDERUNTIMEBEHAVIOR_H
#define DESTROYOUTSIDERUNTIMEBEHAVIOR_H
#include <map>
#include "GDCpp/Runtime/Project/Object.h"
#include "GDCpp/Runtime/RuntimeBehavior.h"
class RuntimeScene;
namespace gd {
class SerializerElement;
}
/**
* \brief Behavior that allows objects to be dragged with the mouse
*/
class GD_EXTENSION_API DestroyOutsideRuntimeBehavior : public RuntimeBehavior {
public:
DestroyOutsideRuntimeBehavior(const gd::SerializerElement& behaviorContent);
virtual ~DestroyOutsideRuntimeBehavior(){};
virtual DestroyOutsideRuntimeBehavior* Clone() const {
return new DestroyOutsideRuntimeBehavior(*this);
}
/**
* \brief Return the value of the extra border.
*/
bool GetExtraBorder() const { return extraBorder; };
/**
* \brief Set the value of the extra border, i.e the supplementary margin that
* the object must cross before being deleted.
*/
void SetExtraBorder(float extraBorder_) { extraBorder = extraBorder_; };
private:
virtual void DoStepPostEvents(RuntimeScene& scene);
float extraBorder; ///< The supplementary margin outside the screen that the
///< object must cross before being deleted.
};
#endif // DESTROYOUTSIDERUNTIMEBEHAVIOR_H

View File

@@ -6,8 +6,9 @@ This project is released under the MIT License.
*/
#include "DestroyOutsideBehavior.h"
#include "DestroyOutsideRuntimeBehavior.h"
#include "GDCpp/Extensions/ExtensionBase.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Project/BehaviorsSharedData.h"
#include "GDCore/Tools/Localization.h"
void DeclareDestroyOutsideBehaviorExtension(gd::PlatformExtension& extension) {
extension
@@ -66,39 +67,3 @@ void DeclareDestroyOutsideBehaviorExtension(gd::PlatformExtension& extension) {
.SetIncludeFile("DestroyOutsideBehavior/DestroyOutsideRuntimeBehavior.h");
#endif
}
/**
* \brief This class declares information about the extension.
*/
class DestroyOutsideBehaviorCppExtension : public ExtensionBase {
public:
/**
* Constructor of an extension declares everything the extension contains:
* objects, actions, conditions and expressions.
*/
DestroyOutsideBehaviorCppExtension() {
DeclareDestroyOutsideBehaviorExtension(*this);
AddRuntimeBehavior<DestroyOutsideRuntimeBehavior>(
GetBehaviorMetadata("DestroyOutsideBehavior::DestroyOutside"),
"DestroyOutsideRuntimeBehavior");
GetBehaviorMetadata("DestroyOutsideBehavior::DestroyOutside")
.SetIncludeFile(
"DestroyOutsideBehavior/DestroyOutsideRuntimeBehavior.h");
GD_COMPLETE_EXTENSION_COMPILATION_INFORMATION();
};
};
#if defined(ANDROID)
extern "C" ExtensionBase* CreateGDCppDestroyOutsideBehaviorExtension() {
return new DestroyOutsideBehaviorCppExtension;
}
#elif !defined(EMSCRIPTEN)
/**
* Used by GDevelop to create the extension class
* -- Do not need to be modified. --
*/
extern "C" ExtensionBase* GD_EXTENSION_API CreateGDExtension() {
return new DestroyOutsideBehaviorCppExtension;
}
#endif

View File

@@ -13,14 +13,8 @@ gd_add_extension_definitions(DraggableBehavior)
include_directories(.)
file(GLOB source_files *.cpp *.h)
gd_add_clang_utils(DraggableBehavior "${source_files}")
gd_add_extension_target(DraggableBehavior "${source_files}")
gdcpp_add_runtime_extension_target(DraggableBehavior_Runtime "${source_files}")
#Linker files for the IDE extension
###
gd_extension_link_libraries(DraggableBehavior)
#Linker files for the GD C++ Runtime extension
###
gdcpp_runtime_extension_link_libraries(DraggableBehavior_Runtime)

View File

@@ -6,6 +6,6 @@ This project is released under the MIT License.
*/
#include "DraggableBehavior.h"
#include "GDCpp/Runtime/Serialization/SerializerElement.h"
#include "GDCore/Serialization/SerializerElement.h"
DraggableBehavior::DraggableBehavior() {}

View File

@@ -9,8 +9,8 @@ This project is released under the MIT License.
#define DRAGGABLEBEHAVIOR_H
#include <SFML/System/Vector2.hpp>
#include <map>
#include "GDCpp/Runtime/Project/Behavior.h"
#include "GDCpp/Runtime/Project/Object.h"
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/Object.h"
class RuntimeScene;
namespace gd {
class SerializerElement;
@@ -20,7 +20,7 @@ class Layout;
/**
* \brief Behavior that allows objects to be dragged with the mouse
*/
class GD_EXTENSION_API DraggableBehavior : public Behavior {
class GD_EXTENSION_API DraggableBehavior : public gd::Behavior {
public:
DraggableBehavior();
virtual ~DraggableBehavior(){};

View File

@@ -1,75 +0,0 @@
/**
GDevelop - Draggable Behavior Extension
Copyright (c) 2014-2016 Florian Rival (Florian.Rival@gmail.com)
This project is released under the MIT License.
*/
#include "DraggableRuntimeBehavior.h"
#include <SFML/Graphics.hpp>
#include <iostream>
#include <memory>
#include "GDCpp/Runtime/CommonTools.h"
#include "GDCpp/Runtime/Project/Layout.h"
#include "GDCpp/Runtime/RuntimeLayer.h"
#include "GDCpp/Runtime/RuntimeObject.h"
#include "GDCpp/Runtime/RuntimeScene.h"
#include "GDCpp/Runtime/Serialization/SerializerElement.h"
bool DraggableRuntimeBehavior::somethingDragged = false;
bool DraggableRuntimeBehavior::leftPressedLastFrame = false;
DraggableRuntimeBehavior::DraggableRuntimeBehavior(
const gd::SerializerElement& behaviorContent)
: RuntimeBehavior(behaviorContent), dragged(false) {}
void DraggableRuntimeBehavior::DoStepPreEvents(RuntimeScene& scene) {
// Begin drag ?
if (!dragged && scene.GetInputManager().IsMouseButtonPressed("Left") &&
!leftPressedLastFrame && !somethingDragged) {
RuntimeLayer& theLayer = scene.GetRuntimeLayer(object->GetLayer());
for (std::size_t cameraIndex = 0; cameraIndex < theLayer.GetCameraCount();
++cameraIndex) {
sf::Vector2f mousePos = scene.renderWindow->mapPixelToCoords(
scene.GetInputManager().GetMousePosition(),
theLayer.GetCamera(cameraIndex).GetSFMLView());
if (object->GetDrawableX() <= mousePos.x &&
object->GetDrawableX() + object->GetWidth() >= mousePos.x &&
object->GetDrawableY() <= mousePos.y &&
object->GetDrawableY() + object->GetHeight() >= mousePos.y) {
dragged = true;
somethingDragged = true;
xOffset = mousePos.x - object->GetX();
yOffset = mousePos.y - object->GetY();
dragCameraIndex = cameraIndex;
break;
}
}
}
// End dragging ?
else if (!scene.GetInputManager().IsMouseButtonPressed("Left")) {
dragged = false;
somethingDragged = false;
}
// Being dragging ?
if (dragged) {
RuntimeLayer& theLayer = scene.GetRuntimeLayer(object->GetLayer());
sf::Vector2f mousePos = scene.renderWindow->mapPixelToCoords(
scene.GetInputManager().GetMousePosition(),
theLayer.GetCamera(dragCameraIndex).GetSFMLView());
object->SetX(mousePos.x - xOffset);
object->SetY(mousePos.y - yOffset);
}
}
void DraggableRuntimeBehavior::DoStepPostEvents(RuntimeScene& scene) {
leftPressedLastFrame = scene.GetInputManager().IsMouseButtonPressed("Left");
}
void DraggableRuntimeBehavior::OnDeActivate() {
if (dragged) somethingDragged = false;
dragged = false;
}

View File

@@ -1,50 +0,0 @@
/**
GDevelop - Draggable Behavior Extension
Copyright (c) 2013-2016 Florian Rival (Florian.Rival@gmail.com)
This project is released under the MIT License.
*/
#ifndef DRAGGABLERUNTIMEBEHAVIOR_H
#define DRAGGABLERUNTIMEBEHAVIOR_H
#include "GDCpp/Runtime/Project/Object.h"
#include "GDCpp/Runtime/RuntimeBehavior.h"
class RuntimeScene;
namespace gd {
class SerializerElement;
}
/**
* \brief Behavior that allows objects to be dragged with the mouse
*/
class GD_EXTENSION_API DraggableRuntimeBehavior : public RuntimeBehavior {
public:
DraggableRuntimeBehavior(const gd::SerializerElement& behaviorContent);
virtual ~DraggableRuntimeBehavior(){};
virtual DraggableRuntimeBehavior* Clone() const {
return new DraggableRuntimeBehavior(*this);
}
/**
* \brief Return true if the object is being dragged.
*/
bool IsDragged() const { return dragged; };
virtual void OnDeActivate();
private:
virtual void DoStepPreEvents(RuntimeScene& scene);
virtual void DoStepPostEvents(RuntimeScene& scene);
float xOffset;
float yOffset;
std::size_t dragCameraIndex; ///< The camera being used to move the object. (
///< The layer is the object's layer ).
bool dragged; ///< True if the object is being dragged.
static bool somethingDragged; ///< Used to avoid start dragging an object
///< while another is being dragged.
static bool
leftPressedLastFrame; ///< Used to only start dragging when clicking.
};
#endif // DRAGGABLERUNTIMEBEHAVIOR_H

View File

@@ -6,8 +6,9 @@ This project is released under the MIT License.
*/
#include "DraggableBehavior.h"
#include "DraggableRuntimeBehavior.h"
#include "GDCpp/Extensions/ExtensionBase.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Project/BehaviorsSharedData.h"
#include "GDCore/Tools/Localization.h"
void DeclareDraggableBehaviorExtension(gd::PlatformExtension& extension) {
extension
@@ -46,33 +47,3 @@ void DeclareDraggableBehaviorExtension(gd::PlatformExtension& extension) {
.SetFunctionName("IsDragged");
#endif
}
/**
* \brief This class declares information about the extension.
*/
class Extension : public ExtensionBase {
public:
/**
* Constructor of an extension declares everything the extension contains:
* objects, actions, conditions and expressions.
*/
Extension() {
DeclareDraggableBehaviorExtension(*this);
AddRuntimeBehavior<DraggableRuntimeBehavior>(
GetBehaviorMetadata("DraggableBehavior::Draggable"),
"DraggableRuntimeBehavior");
GetBehaviorMetadata("DraggableBehavior::Draggable")
.SetIncludeFile("DraggableBehavior/DraggableRuntimeBehavior.h");
GD_COMPLETE_EXTENSION_COMPILATION_INFORMATION();
};
};
#if !defined(EMSCRIPTEN)
/**
* Used by GDevelop to create the extension class
* -- Do not need to be modified. --
*/
extern "C" ExtensionBase* GD_EXTENSION_API CreateGDExtension() {
return new Extension;
}
#endif

View File

@@ -11,6 +11,7 @@ namespace gdjs {
export const myConditionFunction = function (number, text) {
return number <= 10 && text.length < 5;
};
export const getString = function () {
return 'Hello World';
};

View File

@@ -18,18 +18,21 @@ namespace gdjs {
supportedAPIs.indexOf('getRewardedVideoAsync') !== -1
);
};
export const getPlayerId = function () {
if (typeof FBInstant === 'undefined') {
return '';
}
return FBInstant.player.getID() || '';
};
export const getPlayerName = function () {
if (typeof FBInstant === 'undefined') {
return '';
}
return FBInstant.player.getName() || '';
};
export const loadPlayerData = function (
key,
successVariable,
@@ -49,6 +52,7 @@ namespace gdjs {
errorVariable.setString(error.message || 'Unknown error');
});
};
export const setPlayerData = function (
key,
variable,
@@ -71,6 +75,7 @@ namespace gdjs {
errorVariable.setString(error.message || 'Unknown error');
});
};
export const setPlayerScore = function (
leaderboardName,
score,
@@ -95,6 +100,7 @@ namespace gdjs {
errorVariable.setString(error.message || 'Unknown error');
});
};
export const getPlayerEntry = function (
leaderboardName,
rankVariable,
@@ -124,6 +130,7 @@ namespace gdjs {
errorVariable.setString(error.message || 'Unknown error');
});
};
export const loadInterstitialAd = function (
adPlacementId,
errorVariable
@@ -155,6 +162,7 @@ namespace gdjs {
errorVariable.setString(err.message || 'Unknown error');
});
};
export const showInterstitialAd = function (errorVariable) {
if (typeof FBInstant === 'undefined') {
return;
@@ -175,9 +183,11 @@ namespace gdjs {
gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoaded = false;
});
};
export const isInterstitialAdReady = function () {
return gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoaded;
};
export const loadRewardedVideo = function (adPlacementId, errorVariable) {
if (typeof FBInstant === 'undefined') {
return;
@@ -206,6 +216,7 @@ namespace gdjs {
errorVariable.setString(err.message || 'Unknown error');
});
};
export const showRewardedVideo = function (errorVariable) {
if (typeof FBInstant === 'undefined') {
return;
@@ -226,6 +237,7 @@ namespace gdjs {
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoaded = false;
});
};
export const isRewardedVideoReady = function () {
return gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoaded;
};

View File

@@ -24,6 +24,7 @@ namespace gdjs {
}
return gdjs.fileSystem._fs;
};
export const getDirectoryName = function (fileOrFolderPath: string) {
const path = gdjs.fileSystem._getPath();
if (!path) {
@@ -31,6 +32,7 @@ namespace gdjs {
}
return path.dirname(fileOrFolderPath);
};
export const getFileName = function (filePath: string) {
const path = gdjs.fileSystem._getPath();
if (!path) {
@@ -38,6 +40,7 @@ namespace gdjs {
}
return path.basename(filePath);
};
export const getExtensionName = function (filePath: string) {
const path = gdjs.fileSystem._getPath();
if (!path) {

View File

@@ -15,18 +15,7 @@ file(GLOB source_files *.cpp *.h)
gd_add_clang_utils(Inventory "${source_files}")
gd_add_extension_target(Inventory "${source_files}")
gdcpp_add_runtime_extension_target(Inventory_Runtime "${source_files}")
#Linker files for the IDE extension
###
gd_extension_link_libraries(Inventory)
#Linker files for the GD C++ Runtime extension
###
gdcpp_runtime_extension_link_libraries(Inventory_Runtime)
#Tests for the GD C++ Runtime extension
###
file(GLOB_RECURSE test_source_files tests/*)
gdcpp_add_tests_extension_target(Inventory_Runtime_tests "${test_source_files}")

View File

@@ -5,8 +5,8 @@ Copyright (c) 2008-2016 Florian Rival (Florian.Rival@gmail.com)
This project is released under the MIT License.
*/
#include "GDCpp/Extensions/ExtensionBase.h"
#include "InventoryTools.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Tools/Localization.h"
#include <iostream>
@@ -212,38 +212,3 @@ void DeclareInventoryExtension(gd::PlatformExtension& extension) {
.SetIncludeFile("Inventory/InventoryTools.h");
#endif
}
/**
* \brief This class declares information about the extension.
*/
class InventoryCppExtension : public ExtensionBase {
public:
/**
* Constructor of an extension declares everything the extension contains:
* objects, actions, conditions and expressions.
*/
InventoryCppExtension() {
DeclareInventoryExtension(*this);
GD_COMPLETE_EXTENSION_COMPILATION_INFORMATION();
};
virtual void SceneLoaded(RuntimeScene& scene) override {
#if defined(GD_IDE_ONLY)
InventoryTools::ClearAll(scene);
#endif
}
};
#if defined(ANDROID)
extern "C" ExtensionBase* CreateGDCppInventoryExtension() {
return new InventoryCppExtension;
}
#elif !defined(EMSCRIPTEN)
/**
* Used by GDevelop to create the extension class
* -- Do not need to be modified. --
*/
extern "C" ExtensionBase* GD_EXTENSION_API CreateGDExtension() {
return new InventoryCppExtension;
}
#endif

View File

@@ -1,111 +0,0 @@
#include "Inventory.h"
#include "GDCore/String.h"
bool Inventory::Has(const gd::String& itemName) {
return items.find(itemName) != items.end() && items[itemName].count > 0;
}
size_t Inventory::Count(const gd::String& itemName) {
if (items.find(itemName) == items.end()) return 0;
return items[itemName].count;
}
bool Inventory::Add(const gd::String& itemName) {
if (items.find(itemName) == items.end()) {
MakeItemEntry(itemName);
}
auto& item = items[itemName];
if (item.unlimited || item.count < item.maxCount) {
item.count++;
return true;
}
return false;
}
bool Inventory::SetCount(const gd::String& itemName, size_t count) {
if (items.find(itemName) == items.end()) {
MakeItemEntry(itemName);
}
auto& item = items[itemName];
size_t newCount = item.unlimited ? count : std::min(count, item.maxCount);
item.count = newCount;
return item.unlimited || count <= item.maxCount;
}
bool Inventory::IsFull(const gd::String& itemName) {
if (items.find(itemName) == items.end()) return false;
auto& item = items[itemName];
return !item.unlimited && item.count >= item.maxCount;
}
bool Inventory::Remove(const gd::String& itemName) {
if (items.find(itemName) == items.end()) return false;
auto& item = items[itemName];
if (item.count > 0) {
item.count--;
if (item.count == 0) {
item.equipped = false;
}
return true;
}
return false;
}
void Inventory::SetMaximum(const gd::String& itemName, size_t maxCount) {
if (items.find(itemName) == items.end()) {
MakeItemEntry(itemName);
}
items[itemName].maxCount = maxCount;
items[itemName].unlimited = false;
}
void Inventory::SetUnlimited(const gd::String& itemName, bool enable) {
if (items.find(itemName) == items.end()) {
MakeItemEntry(itemName);
}
items[itemName].unlimited = enable;
}
void Inventory::MakeItemEntry(const gd::String& itemName) {
Item item;
items[itemName] = item;
}
bool Inventory::Equip(const gd::String& itemName, bool equip) {
if (items.find(itemName) == items.end()) {
return false;
}
auto& item = items[itemName];
if (!equip) {
item.equipped = false;
return true;
} else if (item.count > 0) {
item.equipped = true;
return true;
}
return false;
}
bool Inventory::IsEquipped(const gd::String& itemName) {
if (items.find(itemName) == items.end()) {
return false;
}
return items[itemName].equipped;
}
void Inventory::Clear() { items.clear(); }

View File

@@ -1,36 +0,0 @@
#pragma once
#include <map>
#include "GDCore/String.h"
class GD_EXTENSION_API Inventory {
public:
Inventory(){};
virtual ~Inventory(){};
class Item {
public:
bool unlimited = true;
size_t count = 0;
size_t maxCount = 0;
bool equipped = false;
};
bool Has(const gd::String& itemName);
size_t Count(const gd::String& itemName);
bool Add(const gd::String& itemName);
bool SetCount(const gd::String& itemName, size_t count);
bool IsFull(const gd::String& itemName);
bool Remove(const gd::String& itemName);
void SetMaximum(const gd::String& itemName, size_t maxCount);
void SetUnlimited(const gd::String& itemName, bool enable = true);
bool Equip(const gd::String& itemName, bool equip = true);
bool IsEquipped(const gd::String& itemName);
void Clear();
const std::map<gd::String, Item>& GetAllItems() { return items; };
private:
void MakeItemEntry(const gd::String& itemName);
std::map<gd::String, Item> items;
};

View File

@@ -1,4 +0,0 @@
#include "InventoryTools.h"
std::map<RuntimeGame *, std::map<gd::String, Inventory>>
InventoryTools::inventories;

View File

@@ -1,106 +0,0 @@
#pragma once
#include "GDCpp/Runtime/RuntimeScene.h"
#include "Inventory.h"
class GD_EXTENSION_API InventoryTools {
public:
static bool Add(RuntimeScene &scene,
const gd::String &inventoryName,
const gd::String &itemName) {
return Get(scene, inventoryName).Add(itemName);
}
static size_t Count(RuntimeScene &scene,
const gd::String &inventoryName,
const gd::String &itemName) {
return Get(scene, inventoryName).Count(itemName);
}
static bool Remove(RuntimeScene &scene,
const gd::String &inventoryName,
const gd::String &itemName) {
return Get(scene, inventoryName).Remove(itemName);
}
static bool Has(RuntimeScene &scene,
const gd::String &inventoryName,
const gd::String &itemName) {
return Get(scene, inventoryName).Has(itemName);
}
static void SetMaximum(RuntimeScene &scene,
const gd::String &inventoryName,
const gd::String &itemName,
size_t maxCount) {
return Get(scene, inventoryName).SetMaximum(itemName, maxCount);
}
static void SetUnlimited(RuntimeScene &scene,
const gd::String &inventoryName,
const gd::String &itemName,
bool enable) {
return Get(scene, inventoryName).SetUnlimited(itemName, enable);
}
static bool Equip(RuntimeScene &scene,
const gd::String &inventoryName,
const gd::String &itemName,
bool equip) {
return Get(scene, inventoryName).Equip(itemName, equip);
}
static bool IsEquipped(RuntimeScene &scene,
const gd::String &inventoryName,
const gd::String &itemName) {
return Get(scene, inventoryName).IsEquipped(itemName);
}
static void SerializeToVariable(RuntimeScene &scene,
const gd::String &inventoryName,
gd::Variable &variable) {
auto &allItems = Get(scene, inventoryName).GetAllItems();
for (auto &it : allItems) {
Inventory::Item item = it.second;
gd::Variable &serializedItem = variable.GetChild(it.first);
serializedItem.GetChild("count").SetValue(item.count);
serializedItem.GetChild("maxCount").SetValue(item.maxCount);
serializedItem.GetChild("unlimited")
.SetString(item.unlimited ? "true" : "false");
serializedItem.GetChild("equipped")
.SetString(item.equipped ? "true" : "false");
}
}
static void UnserializeFromVariable(RuntimeScene &scene,
const gd::String &inventoryName,
const gd::Variable &variable) {
Inventory &inventory = Get(scene, inventoryName);
inventory.Clear();
for (auto &child : variable.GetAllChildren()) {
const gd::String &name = child.first;
const auto &serializedItem = child.second;
inventory.SetMaximum(name,
serializedItem->GetChild("maxCount").GetValue());
inventory.SetUnlimited(
name, serializedItem->GetChild("unlimited").GetString() == "true");
inventory.SetCount(name, serializedItem->GetChild("count").GetValue());
inventory.Equip(
name, serializedItem->GetChild("equipped").GetString() == "true");
}
}
static void ClearAll(RuntimeScene &scene) {
std::map<gd::String, Inventory> clearedInventories;
inventories[scene.game] = clearedInventories;
}
private:
static Inventory &Get(RuntimeScene &scene, const gd::String &name) {
return inventories[scene.game][name];
}
static std::map<RuntimeGame *, std::map<gd::String, Inventory>> inventories;
InventoryTools(){};
};

View File

@@ -6,6 +6,7 @@ This project is released under the MIT License.
*/
#if defined(GD_IDE_ONLY)
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Tools/Localization.h"
#include <iostream>
#include "GDCore/Tools/Localization.h"

View File

@@ -18,15 +18,19 @@ namespace gdjs {
export const add = function (runtimeScene, inventoryName, name) {
return InventoryManager.get(runtimeScene, inventoryName).add(name);
};
export const remove = function (runtimeScene, inventoryName, name) {
return InventoryManager.get(runtimeScene, inventoryName).remove(name);
};
export const count = function (runtimeScene, inventoryName, name) {
return InventoryManager.get(runtimeScene, inventoryName).count(name);
};
export const has = function (runtimeScene, inventoryName, name) {
return InventoryManager.get(runtimeScene, inventoryName).has(name);
};
export const setMaximum = function (
runtimeScene,
inventoryName,
@@ -38,6 +42,7 @@ namespace gdjs {
maxCount
);
};
export const setUnlimited = function (
runtimeScene,
inventoryName,
@@ -49,20 +54,24 @@ namespace gdjs {
enable
);
};
export const isFull = function (runtimeScene, inventoryName, name) {
return InventoryManager.get(runtimeScene, inventoryName).isFull(name);
};
export const equip = function (runtimeScene, inventoryName, name, equip) {
return InventoryManager.get(runtimeScene, inventoryName).equip(
name,
equip
);
};
export const isEquipped = function (runtimeScene, inventoryName, name) {
return InventoryManager.get(runtimeScene, inventoryName).isEquipped(
name
);
};
export const serializeToVariable = function (
runtimeScene,
inventoryName: string,
@@ -81,6 +90,7 @@ namespace gdjs {
serializedItem.getChild('equipped').setBoolean(item.equipped);
}
};
export const unserializeFromVariable = function (
runtimeScene,
inventoryName: string,

View File

@@ -1,86 +0,0 @@
/**
GDevelop - Inventory Extension
Copyright (c) 2011-2016 Florian Rival (Florian.Rival@gmail.com)
This project is released under the MIT License.
*/
/**
* @file Tests for the Inventory extension.
*/
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
#include "../Inventory.h"
TEST_CASE( "Inventory", "[game-engine][inventory]" ) {
SECTION("Inventory") {
Inventory inventory;
// Is empty when constructed") {
REQUIRE(inventory.Has("sword") == false);
REQUIRE(inventory.Has("soul reaver") == false);
// Can receive one or more items") {
REQUIRE(inventory.Add("sword") == true);
REQUIRE(inventory.Has("sword") == true);
REQUIRE(inventory.Has("soul reaver") == false);
REQUIRE(inventory.Add("soul reaver") == true);
REQUIRE(inventory.Add("sword") == true);
REQUIRE(inventory.Has("sword") == true);
REQUIRE(inventory.Has("soul reaver") == true);
// Can return the number of items") {
REQUIRE(inventory.Count("sword") == 2);
REQUIRE(inventory.Count("soul reaver") == 1);
// Can equip items") {
REQUIRE(inventory.Equip("soul reaver", true) == true);
REQUIRE(inventory.IsEquipped("soul reaver") == true);
REQUIRE(inventory.Equip("sword", true) == true);
REQUIRE(inventory.IsEquipped("sword") == true);
REQUIRE(inventory.Equip("sword", false) == true);
REQUIRE(inventory.IsEquipped("sword") == false);
REQUIRE(inventory.Equip("sword", true) == true);
REQUIRE(inventory.Equip("nothing", true) == false);
REQUIRE(inventory.IsEquipped("nothing") == false);
// Support removing an item") {
REQUIRE(inventory.Remove("sword") == true);
REQUIRE(inventory.Count("sword") == 1);
REQUIRE(inventory.IsEquipped("sword") == true);
REQUIRE(inventory.Remove("sword") == true);
REQUIRE(inventory.Count("sword") == 0);
REQUIRE(inventory.IsEquipped("sword") == false);
REQUIRE(inventory.Remove("sword") == false);
REQUIRE(inventory.Count("sword") == 0);
REQUIRE(inventory.Count("soul reaver") == 1);
REQUIRE(inventory.IsEquipped("soul reaver") == true);
// Can support having a limited number of objects") {
REQUIRE(inventory.Count("heavy sword") == 0);
inventory.SetMaximum("heavy sword", 2);
REQUIRE(inventory.Add("heavy sword") == true);
REQUIRE(inventory.Count("heavy sword") == 1);
REQUIRE(inventory.Has("heavy sword") == true);
REQUIRE(inventory.Add("heavy sword") == true);
REQUIRE(inventory.Count("heavy sword") == 2);
REQUIRE(inventory.Add("heavy sword") == false);
REQUIRE(inventory.Count("heavy sword") == 2);
inventory.SetUnlimited("heavy sword", true);
REQUIRE(inventory.Count("heavy sword") == 2);
REQUIRE(inventory.Add("heavy sword") == true);
REQUIRE(inventory.Add("heavy sword") == true);
REQUIRE(inventory.Count("heavy sword") == 4);
inventory.SetMaximum("never sword", 0);
REQUIRE(inventory.Add("never sword") == false);
REQUIRE(inventory.Has("never sword") == false);
REQUIRE(inventory.Count("never sword") == 0);
}
}

View File

@@ -1,35 +0,0 @@
/**
GDevelop - Inventory Extension
Copyright (c) 2011-2016 Florian Rival (Florian.Rival@gmail.com)
This project is released under the MIT License.
*/
#include "catch.hpp"
#include "../InventoryTools.h"
#include "GDCpp/Runtime/Project/Variable.h"
#include "GDCpp/Runtime/Serialization/Serializer.h"
#include "GDCpp/Runtime/RuntimeScene.h"
#include "GDCpp/Runtime/RuntimeGame.h"
TEST_CASE( "InventoryTools", "[game-engine][inventory-tools]" ) {
SECTION("InventoryTools") {
RuntimeGame game;
RuntimeScene scene(NULL, &game);
InventoryTools::Add(scene, "MyInventory", "sword");
InventoryTools::Add(scene, "MyInventory", "sword");
InventoryTools::Equip(scene, "MyInventory", "sword", true);
InventoryTools::Add(scene, "MyInventory", "armor");
InventoryTools::SetMaximum(scene, "MyInventory", "armor", 1);
gd::Variable variable;
InventoryTools::SerializeToVariable(scene, "MyInventory", variable);
InventoryTools::UnserializeFromVariable(scene, "MyInventory2", variable);
REQUIRE(InventoryTools::Count(scene, "MyInventory2", "sword") == 2);
REQUIRE(InventoryTools::IsEquipped(scene, "MyInventory2", "sword") == true);
REQUIRE(InventoryTools::Count(scene, "MyInventory2", "armor") == 1);
REQUIRE(InventoryTools::Add(scene, "MyInventory2", "armor") == false);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -221,7 +221,7 @@ module.exports = {
'res/actions/color.png'
)
.addParameter('object', _('Object'), 'LightObject', false)
.addParameter('string', _('Color'), '', false)
.addParameter('color', _('Color'), '', false)
.getCodeExtraInformation()
.setFunctionName('setColor');

View File

@@ -13,20 +13,8 @@ gd_add_extension_definitions(LinkedObjects)
include_directories(.)
file(GLOB source_files *.cpp *.h)
gd_add_clang_utils(LinkedObjects "${source_files}")
gd_add_extension_target(LinkedObjects "${source_files}")
gdcpp_add_runtime_extension_target(LinkedObjects_Runtime "${source_files}")
#Linker files for the IDE extension
###
gd_extension_link_libraries(LinkedObjects)
#Linker files for the GD C++ Runtime extension
###
gdcpp_runtime_extension_link_libraries(LinkedObjects_Runtime)
#Tests for the GD C++ Runtime extension
###
file(GLOB_RECURSE test_source_files tests/*)
gdcpp_add_tests_extension_target(LinkedObjects_Runtime_tests "${test_source_files}")
gd_extension_link_libraries(LinkedObjects)

View File

@@ -7,8 +7,8 @@ This project is released under the MIT License.
#include <iostream>
#include "GDCpp/Extensions/ExtensionBase.h"
#include "ObjectsLinksManager.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Tools/Localization.h"
void DeclareLinkedObjectsExtension(gd::PlatformExtension& extension) {
extension
@@ -112,60 +112,3 @@ void DeclareLinkedObjectsExtension(gd::PlatformExtension& extension) {
#endif
}
/**
* \brief This class declares information about the extension.
*/
class LinkedObjectsCppExtension : public ExtensionBase {
public:
/**
* Constructor of an extension declares everything the extension contains:
* objects, actions, conditions and expressions.
*/
LinkedObjectsCppExtension() {
DeclareLinkedObjectsExtension(*this);
GD_COMPLETE_EXTENSION_COMPILATION_INFORMATION();
};
/**
* The extension must be aware of objects deletion
*/
virtual bool ToBeNotifiedOnObjectDeletion() { return true; }
/**
* Be sure to remove all links when an object is deleted
*/
virtual void ObjectDeletedFromScene(RuntimeScene& scene,
RuntimeObject* object) {
GDpriv::LinkedObjects::ObjectsLinksManager::managers[&scene]
.RemoveAllLinksOf(object);
}
/**
* Initialize manager of linked objects of scene
*/
virtual void SceneLoaded(RuntimeScene& scene) {
GDpriv::LinkedObjects::ObjectsLinksManager::managers[&scene].ClearAll();
}
/**
* Destroy manager of linked objects of scene
*/
virtual void SceneUnloaded(RuntimeScene& scene) {
GDpriv::LinkedObjects::ObjectsLinksManager::managers.erase(&scene);
}
};
#if defined(ANDROID)
extern "C" ExtensionBase* CreateGDCppLinkedObjectsExtension() {
return new LinkedObjectsCppExtension;
}
#elif !defined(EMSCRIPTEN)
/**
* Used by GDevelop to create the extension class
* -- Do not need to be modified. --
*/
extern "C" ExtensionBase* GD_EXTENSION_API CreateGDExtension() {
return new LinkedObjectsCppExtension;
}
#endif

View File

@@ -6,6 +6,7 @@ This project is released under the MIT License.
*/
#if defined(GD_IDE_ONLY)
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Tools/Localization.h"
#include <iostream>
#include "GDCore/Tools/Localization.h"

View File

@@ -1,61 +0,0 @@
/**
GDevelop - LinkedObjects Extension
Copyright (c) 2011-2016 Florian Rival (Florian.Rival@gmail.com)
This project is released under the MIT License.
*/
#include "LinkedObjectsTools.h"
#include <iostream>
#include <string>
#include <memory>
#include "GDCpp/Runtime/RuntimeObject.h"
#include "GDCpp/Runtime/RuntimeObjectsListsTools.h"
#include "GDCpp/Runtime/RuntimeScene.h"
#include "ObjectsLinksManager.h"
using namespace std;
namespace GDpriv {
namespace LinkedObjects {
std::map<RuntimeScene*, ObjectsLinksManager> ObjectsLinksManager::managers;
bool GD_EXTENSION_API PickObjectsLinkedTo(
RuntimeScene& scene,
std::map<gd::String, std::vector<RuntimeObject*>*> pickedObjectsLists,
RuntimeObject* object) {
if (!object) return false;
std::vector<RuntimeObject*> linkedObjects =
ObjectsLinksManager::managers[&scene].GetObjectsLinkedWith(object);
return PickObjectsIf(
pickedObjectsLists, false, [&linkedObjects](RuntimeObject* obj) {
return std::find(linkedObjects.begin(), linkedObjects.end(), obj) !=
linkedObjects.end();
});
}
void GD_EXTENSION_API LinkObjects(RuntimeScene& scene,
RuntimeObject* a,
RuntimeObject* b) {
if (!a || !b) return;
ObjectsLinksManager::managers[&scene].LinkObjects(a, b);
}
void GD_EXTENSION_API RemoveLinkBetween(RuntimeScene& scene,
RuntimeObject* a,
RuntimeObject* b) {
if (!a || !b) return;
ObjectsLinksManager::managers[&scene].RemoveLinkBetween(a, b);
}
void GD_EXTENSION_API RemoveAllLinksOf(RuntimeScene& scene,
RuntimeObject* object) {
if (!object) return;
ObjectsLinksManager::managers[&scene].RemoveAllLinksOf(object);
}
} // namespace LinkedObjects
} // namespace GDpriv

View File

@@ -1,38 +0,0 @@
/**
GDevelop - LinkedObjects Extension
Copyright (c) 2011-2013 Florian Rival (Florian.Rival@gmail.com)
This project is released under the MIT License.
*/
#ifndef LINKEDOBJECTSTOOLS_H_INCLUDED
#define LINKEDOBJECTSTOOLS_H_INCLUDED
#include <map>
#include <string>
#include <vector>
#include "GDCpp/Runtime/String.h"
class RuntimeObject;
class RuntimeScene;
namespace GDpriv {
namespace LinkedObjects {
void GD_EXTENSION_API LinkObjects(RuntimeScene &scene,
RuntimeObject *a,
RuntimeObject *b);
void GD_EXTENSION_API RemoveLinkBetween(RuntimeScene &scene,
RuntimeObject *a,
RuntimeObject *b);
void GD_EXTENSION_API RemoveAllLinksOf(RuntimeScene &scene,
RuntimeObject *object);
bool GD_EXTENSION_API PickObjectsLinkedTo(
RuntimeScene &scene,
std::map<gd::String, std::vector<RuntimeObject *> *> pickedObjectsLists,
RuntimeObject *object);
} // namespace LinkedObjects
} // namespace GDpriv
#endif // LINKEDOBJECTSTOOLS_H_INCLUDED

View File

@@ -1,78 +0,0 @@
/**
GDevelop - LinkedObjects Extension
Copyright (c) 2011-2016 Florian Rival (Florian.Rival@gmail.com)
This project is released under the MIT License.
*/
#include "ObjectsLinksManager.h"
#include <iostream>
#include <string>
#include "LinkedObjectsTools.h"
#include <memory>
#include "GDCpp/Runtime/RuntimeObject.h"
#include "GDCpp/Runtime/RuntimeScene.h"
using namespace std;
namespace GDpriv {
namespace LinkedObjects {
void ObjectsLinksManager::LinkObjects(RuntimeObject* a, RuntimeObject* b) {
{
std::set<RuntimeObject*>& objectLinks = links[a];
objectLinks.insert(b);
}
{
std::set<RuntimeObject*>& objectLinks = links[b];
objectLinks.insert(a);
}
}
void ObjectsLinksManager::RemoveLinkBetween(RuntimeObject* a,
RuntimeObject* b) {
{
std::set<RuntimeObject*>& objectLinks = links[a];
objectLinks.erase(b);
}
{
std::set<RuntimeObject*>& objectLinks = links[b];
objectLinks.erase(a);
}
}
void ObjectsLinksManager::RemoveAllLinksOf(RuntimeObject* object) {
std::set<RuntimeObject*>& objectLinks = links[object];
for (std::set<RuntimeObject*>::iterator linkedObj = objectLinks.begin();
linkedObj != objectLinks.end();
++linkedObj) {
std::set<RuntimeObject*>& linkedObjectLinks = links[*linkedObj];
linkedObjectLinks.erase(object);
}
links.erase(object); // Remove all links of object
}
std::vector<RuntimeObject*> ObjectsLinksManager::GetObjectsLinkedWith(
RuntimeObject* object) {
// Get links of object
const std::set<RuntimeObject*>& objectLinks = links[object];
std::vector<RuntimeObject*> list;
list.reserve(objectLinks.size());
// Create the list, avoiding dead links or links to just deleted objects
for (std::set<RuntimeObject*>::iterator linkedObj = objectLinks.begin();
linkedObj != objectLinks.end();
++linkedObj) {
if (!(*linkedObj)->GetName().empty()) list.push_back((*linkedObj));
}
return list;
}
void ObjectsLinksManager::ClearAll() { links.clear(); }
} // namespace LinkedObjects
} // namespace GDpriv

View File

@@ -1,63 +0,0 @@
/**
GDevelop - LinkedObjects Extension
Copyright (c) 2011-2013 Florian Rival (Florian.Rival@gmail.com)
This project is released under the MIT License.
*/
#ifndef OBJECTSLINKSMANAGER_H
#define OBJECTSLINKSMANAGER_H
#include <map>
#include <set>
#include <string>
#include <vector>
class RuntimeObject;
class RuntimeScene;
namespace GDpriv {
namespace LinkedObjects {
/**
* \brief Manage links between objects of a scene
*/
class GD_EXTENSION_API ObjectsLinksManager {
public:
/**
* \brief Link two object
*/
void LinkObjects(RuntimeObject* a, RuntimeObject* b);
/**
* \brief Remove link between a and b
*/
void RemoveLinkBetween(RuntimeObject* a, RuntimeObject* b);
/**
* \brief Remove all links concerning the object
*/
void RemoveAllLinksOf(RuntimeObject* object);
/**
* \brief Get a list of (raw pointers to) all objects linked with the
* specified object
*/
std::vector<RuntimeObject*> GetObjectsLinkedWith(RuntimeObject* object);
/**
* \brief Delete all links
*/
void ClearAll();
static std::map<RuntimeScene*, ObjectsLinksManager>
managers; // List of managers associated with scenes.
private:
std::map<RuntimeObject*, std::set<RuntimeObject*> > links;
};
} // namespace LinkedObjects
} // namespace GDpriv
#endif // OBJECTSLINKSMANAGER_H

View File

@@ -90,6 +90,7 @@ namespace gdjs {
}
LinksManager.getManager(runtimeScene).linkObjects(objA, objB);
};
export const removeLinkBetween = function (
runtimeScene: gdjs.RuntimeScene,
objA: gdjs.RuntimeObject,
@@ -100,6 +101,7 @@ namespace gdjs {
}
LinksManager.getManager(runtimeScene).removeLinkBetween(objA, objB);
};
export const removeAllLinksOf = function (
runtimeScene: gdjs.RuntimeScene,
objA: gdjs.RuntimeObject
@@ -109,12 +111,14 @@ namespace gdjs {
}
LinksManager.getManager(runtimeScene).removeAllLinksOf(objA);
};
export const _objectIsInList = function (
obj: gdjs.RuntimeObject,
linkedObjects: gdjs.RuntimeObject[]
) {
return linkedObjects.indexOf(obj) !== -1;
};
export const pickObjectsLinkedTo = function (
runtimeScene: gdjs.RuntimeScene,
objectsLists: Hashtable<gdjs.RuntimeObject[]>,

View File

@@ -1,88 +0,0 @@
/**
GDevelop - LinkedObjects Extension
Copyright (c) 2011-2016 Florian Rival (Florian.Rival@gmail.com)
This project is released under the MIT License.
*/
/**
* @file Tests for the Linked Objects extension.
*/
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
#include "GDCore/CommonTools.h"
#include "GDCore/Project/ObjectsContainer.h"
#include "GDCore/Project/Layout.h"
#include "GDCore/Project/Object.h"
#include "GDCpp/Runtime/RuntimeScene.h"
#include "GDCpp/Runtime/RuntimeGame.h"
#include "GDCpp/Runtime/RuntimeObject.h"
#include "GDCpp/Extensions/Builtin/ObjectTools.h"
#include "GDCpp/Extensions/Builtin/ObjectTools.h"
#include "../LinkedObjectsTools.h"
#include "../ObjectsLinksManager.h"
TEST_CASE( "LinkedObjects", "[game-engine][linked-objects]" ) {
SECTION("LinkedObjectsTools") {
//Prepare some objects and the context
gd::Object obj1("1");
gd::Object obj2("2");
RuntimeGame game;
RuntimeScene scene(NULL, &game);
RuntimeObject obj1A(scene, obj1);
RuntimeObject obj1B(scene, obj1);
RuntimeObject obj1C(scene, obj1);
RuntimeObject obj2A(scene, obj2);
RuntimeObject obj2B(scene, obj2);
RuntimeObject obj2C(scene, obj2);
//Link two objects
GDpriv::LinkedObjects::ObjectsLinksManager & manager = GDpriv::LinkedObjects::ObjectsLinksManager::managers[&scene];
manager.LinkObjects(&obj1A, &obj2A);
{
std::vector<RuntimeObject*> linkedObjects = manager.GetObjectsLinkedWith(&obj1A);
REQUIRE(linkedObjects.size() == 1);
REQUIRE(linkedObjects[0] == &obj2A);
}
{
std::vector<RuntimeObject*> linkedObjects = manager.GetObjectsLinkedWith(&obj2A);
REQUIRE(linkedObjects.size() == 1);
REQUIRE(linkedObjects[0] == &obj1A);
}
//Link more objects
manager.LinkObjects(&obj1A, &obj2A); //Including the same objects as before
manager.LinkObjects(&obj1A, &obj2B);
manager.LinkObjects(&obj1A, &obj2C);
{
std::vector<RuntimeObject*> linkedObjects = manager.GetObjectsLinkedWith(&obj1A);
REQUIRE(linkedObjects.size() == 3);
}
{
std::vector<RuntimeObject*> linkedObjects = manager.GetObjectsLinkedWith(&obj2C);
REQUIRE(linkedObjects.size() == 1);
REQUIRE(linkedObjects[0] == &obj1A);
}
//Remove all links
manager.LinkObjects(&obj2B, &obj2C);
manager.RemoveAllLinksOf(&obj1A);
manager.RemoveAllLinksOf(&obj1A);
{
std::vector<RuntimeObject*> linkedObjects = manager.GetObjectsLinkedWith(&obj1A);
REQUIRE(linkedObjects.size() == 0);
}
{
std::vector<RuntimeObject*> linkedObjects = manager.GetObjectsLinkedWith(&obj2A);
REQUIRE(linkedObjects.size() == 0);
}
{
std::vector<RuntimeObject*> linkedObjects = manager.GetObjectsLinkedWith(&obj2C);
REQUIRE(linkedObjects.size() == 1);
REQUIRE(linkedObjects[0] == &obj2B);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -13,14 +13,8 @@ gd_add_extension_definitions(PanelSpriteObject)
include_directories(.)
file(GLOB source_files *.cpp *.h)
gd_add_clang_utils(PanelSpriteObject "${source_files}")
gd_add_extension_target(PanelSpriteObject "${source_files}")
gdcpp_add_runtime_extension_target(PanelSpriteObject_Runtime "${source_files}")
#Linker files for the IDE extension
###
gd_extension_link_libraries(PanelSpriteObject)
#Linker files for the GD C++ Runtime extension
###
gdcpp_runtime_extension_link_libraries(PanelSpriteObject_Runtime)

View File

@@ -9,7 +9,8 @@ This project is released under the MIT License.
* Florian Rival ( Minor changes and adaptations )
*/
#include "GDCpp/Extensions/ExtensionBase.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Tools/Localization.h"
#include "PanelSpriteObject.h"
void DeclarePanelSpriteObjectExtension(gd::PlatformExtension& extension) {
@@ -177,36 +178,3 @@ void DeclarePanelSpriteObjectExtension(gd::PlatformExtension& extension) {
.SetIncludeFile("PanelSpriteObject/PanelSpriteObject.h");
#endif
}
/**
* \brief This class declares information about the extension.
*/
class PanelSpriteObjectCppExtension : public ExtensionBase {
public:
/**
* Constructor of an extension declares everything the extension contains:
* objects, actions, conditions and expressions.
*/
PanelSpriteObjectCppExtension() {
DeclarePanelSpriteObjectExtension(*this);
AddRuntimeObject<PanelSpriteObject, RuntimePanelSpriteObject>(
GetObjectMetadata("PanelSpriteObject::PanelSprite"),
"RuntimePanelSpriteObject");
GD_COMPLETE_EXTENSION_COMPILATION_INFORMATION();
};
};
#if defined(ANDROID)
extern "C" ExtensionBase* CreateGDCppPanelSpriteObjectExtension() {
return new PanelSpriteObjectCppExtension;
}
#elif !defined(EMSCRIPTEN)
/**
* Used by GDevelop to create the extension class
* -- Do not need to be modified. --
*/
extern "C" ExtensionBase* GD_EXTENSION_API CreateGDExtension() {
return new PanelSpriteObjectCppExtension;
}
#endif

View File

@@ -7,16 +7,11 @@ This project is released under the MIT License.
#include <SFML/Graphics.hpp>
#include "GDCore/Tools/Localization.h"
#include "GDCpp/Runtime/CommonTools.h"
#include "GDCpp/Runtime/FontManager.h"
#include "GDCpp/Runtime/ImageManager.h"
#include "GDCpp/Runtime/Polygon2d.h"
#include "GDCpp/Runtime/Project/InitialInstance.h"
#include "GDCpp/Runtime/Project/Object.h"
#include "GDCpp/Runtime/Project/Project.h"
#include "GDCpp/Runtime/RuntimeGame.h"
#include "GDCpp/Runtime/RuntimeScene.h"
#include "GDCpp/Runtime/Serialization/SerializerElement.h"
#include "GDCore/CommonTools.h"
#include "GDCore/Project/InitialInstance.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Serialization/SerializerElement.h"
#include "PanelSpriteObject.h"
#if defined(GD_IDE_ONLY)
@@ -60,194 +55,8 @@ void PanelSpriteObject::DoSerializeTo(gd::SerializerElement& element) const {
element.SetAttribute("bottomMargin", bottomMargin);
element.SetAttribute("tiled", tiled);
}
#endif
RuntimePanelSpriteObject::RuntimePanelSpriteObject(
RuntimeScene& scene, const PanelSpriteObject& panelSpriteObject)
: RuntimeObject(scene, panelSpriteObject), width(32), height(32), angle(0) {
SetRightMargin(panelSpriteObject.GetRightMargin());
SetLeftMargin(panelSpriteObject.GetLeftMargin());
SetBottomMargin(panelSpriteObject.GetBottomMargin());
SetTopMargin(panelSpriteObject.GetTopMargin());
SetWidth(panelSpriteObject.GetWidth());
SetHeight(panelSpriteObject.GetHeight());
textureName = panelSpriteObject.textureName;
ChangeAndReloadImage(textureName, scene);
}
/**
* Render object at runtime
*/
bool RuntimePanelSpriteObject::Draw(sf::RenderTarget& window) {
// Don't draw anything if hidden
if (hidden) return true;
if (!texture) return true;
sf::Vector2f centerPosition =
sf::Vector2f(GetX() + GetCenterX(), GetY() + GetCenterY());
float imageWidth = texture->texture.getSize().x;
float imageHeight = texture->texture.getSize().y;
sf::Vertex centerVertices[] = {
sf::Vertex(sf::Vector2f(-width / 2 + leftMargin, -height / 2 + topMargin),
sf::Vector2f(leftMargin, topMargin)),
sf::Vertex(
sf::Vector2f(+width / 2 - rightMargin, -height / 2 + topMargin),
sf::Vector2f(imageWidth - rightMargin, topMargin)),
sf::Vertex(
sf::Vector2f(-width / 2 + leftMargin, +height / 2 - bottomMargin),
sf::Vector2f(leftMargin, imageHeight - bottomMargin)),
sf::Vertex(
sf::Vector2f(+width / 2 - rightMargin, +height / 2 - bottomMargin),
sf::Vector2f(imageWidth - rightMargin, imageHeight - bottomMargin)),
};
sf::Vertex topVertices[] = {
// Top-left
sf::Vertex(sf::Vector2f(-width / 2, -height / 2), sf::Vector2f(0, 0)),
sf::Vertex(sf::Vector2f(-width / 2, -height / 2 + topMargin),
sf::Vector2f(0, topMargin)),
sf::Vertex(sf::Vector2f(-width / 2 + leftMargin, -height / 2),
sf::Vector2f(leftMargin, 0)),
sf::Vertex(sf::Vector2f(-width / 2 + leftMargin, -height / 2 + topMargin),
sf::Vector2f(leftMargin, topMargin)),
// Top
sf::Vertex(sf::Vector2f(+width / 2 - rightMargin, -height / 2),
sf::Vector2f(imageWidth - rightMargin, 0)),
sf::Vertex(
sf::Vector2f(+width / 2 - rightMargin, -height / 2 + topMargin),
sf::Vector2f(imageWidth - rightMargin, topMargin)),
// Top-right
sf::Vertex(sf::Vector2f(+width / 2, -height / 2),
sf::Vector2f(imageWidth, 0)),
sf::Vertex(sf::Vector2f(+width / 2, -height / 2 + topMargin),
sf::Vector2f(imageWidth, topMargin)),
};
sf::Vertex rightVertices[] = {
sf::Vertex(
sf::Vector2f(+width / 2 - rightMargin, -height / 2 + topMargin),
sf::Vector2f(imageWidth - rightMargin, topMargin)),
sf::Vertex(sf::Vector2f(+width / 2, -height / 2 + topMargin),
sf::Vector2f(imageWidth, topMargin)),
sf::Vertex(
sf::Vector2f(+width / 2 - rightMargin, +height / 2 - bottomMargin),
sf::Vector2f(imageWidth - rightMargin, imageHeight - bottomMargin)),
sf::Vertex(sf::Vector2f(+width / 2, +height / 2 - bottomMargin),
sf::Vector2f(imageWidth, imageHeight - bottomMargin))};
sf::Vertex bottomVertices[] = {
// Bottom-left
sf::Vertex(sf::Vector2f(-width / 2, +height / 2 - bottomMargin),
sf::Vector2f(0, imageHeight - bottomMargin)),
sf::Vertex(sf::Vector2f(-width / 2, +height / 2),
sf::Vector2f(0, imageHeight)),
sf::Vertex(
sf::Vector2f(-width / 2 + leftMargin, +height / 2 - bottomMargin),
sf::Vector2f(leftMargin, imageHeight - bottomMargin)),
sf::Vertex(sf::Vector2f(-width / 2 + leftMargin, +height / 2),
sf::Vector2f(leftMargin, imageHeight)),
// Bottom
sf::Vertex(
sf::Vector2f(+width / 2 - rightMargin, +height / 2 - bottomMargin),
sf::Vector2f(imageWidth - rightMargin, imageHeight - bottomMargin)),
sf::Vertex(sf::Vector2f(+width / 2 - rightMargin, +height / 2),
sf::Vector2f(imageWidth - rightMargin, imageHeight)),
// Bottom-right
sf::Vertex(sf::Vector2f(+width / 2, +height / 2 - bottomMargin),
sf::Vector2f(imageWidth, imageHeight - bottomMargin)),
sf::Vertex(sf::Vector2f(+width / 2, +height / 2),
sf::Vector2f(imageWidth, imageHeight))};
sf::Vertex leftVertices[] = {
sf::Vertex(sf::Vector2f(-width / 2, -height / 2 + topMargin),
sf::Vector2f(0, topMargin)),
sf::Vertex(sf::Vector2f(-width / 2 + leftMargin, -height / 2 + topMargin),
sf::Vector2f(leftMargin, topMargin)),
sf::Vertex(sf::Vector2f(-width / 2, +height / 2 - bottomMargin),
sf::Vector2f(0, imageHeight - bottomMargin)),
sf::Vertex(
sf::Vector2f(-width / 2 + leftMargin, +height / 2 - bottomMargin),
sf::Vector2f(leftMargin, imageHeight - bottomMargin))};
sf::Transform matrix;
matrix.translate(centerPosition);
matrix.rotate(angle);
sf::RenderStates states;
states.transform = matrix;
states.texture = &texture->texture;
window.draw(centerVertices, 4, sf::TrianglesStrip, states);
window.draw(leftVertices, 4, sf::TrianglesStrip, states);
window.draw(rightVertices, 4, sf::TrianglesStrip, states);
window.draw(topVertices, 8, sf::TrianglesStrip, states);
window.draw(bottomVertices, 8, sf::TrianglesStrip, states);
return true;
}
#if defined(GD_IDE_ONLY)
void PanelSpriteObject::ExposeResources(gd::ArbitraryResourceWorker& worker) {
worker.ExposeImage(textureName);
}
void RuntimePanelSpriteObject::GetPropertyForDebugger(std::size_t propertyNb,
gd::String& name,
gd::String& value) const {
if (propertyNb == 0) {
name = _("Width");
value = gd::String::From(width);
} else if (propertyNb == 1) {
name = _("Height");
value = gd::String::From(height);
} else if (propertyNb == 2) {
name = _("Left Margin");
value = gd::String::From(leftMargin);
} else if (propertyNb == 3) {
name = _("Top Margin");
value = gd::String::From(topMargin);
} else if (propertyNb == 4) {
name = _("Right Margin");
value = gd::String::From(rightMargin);
} else if (propertyNb == 5) {
name = _("Bottom Margin");
value = gd::String::From(bottomMargin);
}
}
bool RuntimePanelSpriteObject::ChangeProperty(std::size_t propertyNb,
gd::String newValue) {
if (propertyNb == 0) {
width = newValue.To<float>();
} else if (propertyNb == 1) {
height = newValue.To<float>();
} else if (propertyNb == 2) {
leftMargin = newValue.To<float>();
} else if (propertyNb == 3) {
topMargin = newValue.To<float>();
} else if (propertyNb == 4) {
rightMargin = newValue.To<float>();
} else if (propertyNb == 5) {
bottomMargin = newValue.To<float>();
}
return true;
}
std::size_t RuntimePanelSpriteObject::GetNumberOfProperties() const {
return 6;
}
#endif
void RuntimePanelSpriteObject::ChangeAndReloadImage(const gd::String& txtName,
const RuntimeScene& scene) {
textureName = txtName;
texture = scene.GetImageManager()->GetSFMLTexture(textureName);
}

View File

@@ -8,10 +8,7 @@ This project is released under the MIT License.
#ifndef PANELSPRITEOBJECT_H
#define PANELSPRITEOBJECT_H
#include <memory>
#include "GDCpp/Runtime/Project/Object.h"
#include "GDCpp/Runtime/RuntimeObject.h"
class SFMLTextureWrapper;
class RuntimeScene;
#include "GDCore/Project/Object.h"
namespace gd {
class Object;
class InitialInstance;
@@ -84,77 +81,6 @@ class GD_EXTENSION_API PanelSpriteObject : public gd::Object {
float bottomMargin;
bool tiled;
std::shared_ptr<SFMLTextureWrapper> texture;
};
class GD_EXTENSION_API RuntimePanelSpriteObject : public RuntimeObject {
public:
RuntimePanelSpriteObject(RuntimeScene &scene,
const PanelSpriteObject &panelSpriteObject);
virtual ~RuntimePanelSpriteObject(){};
virtual std::unique_ptr<RuntimeObject> Clone() const {
return gd::make_unique<RuntimePanelSpriteObject>(*this);
}
virtual bool Draw(sf::RenderTarget &renderTarget);
virtual float GetWidth() const { return width; };
virtual float GetHeight() const { return height; };
virtual inline void SetWidth(float newWidth) {
width = newWidth >= (leftMargin + rightMargin) ? newWidth
: (leftMargin + rightMargin);
};
virtual inline void SetHeight(float newHeight) {
height = newHeight >= (topMargin + bottomMargin)
? newHeight
: (topMargin + bottomMargin);
};
virtual bool SetAngle(float newAngle) {
angle = newAngle;
return true;
};
virtual float GetAngle() const { return angle; };
float GetLeftMargin() const { return leftMargin; };
void SetLeftMargin(float newMargin) { leftMargin = newMargin; };
float GetTopMargin() const { return topMargin; };
void SetTopMargin(float newMargin) { topMargin = newMargin; };
float GetRightMargin() const { return rightMargin; };
void SetRightMargin(float newMargin) { rightMargin = newMargin; };
float GetBottomMargin() const { return bottomMargin; };
void SetBottomMargin(float newMargin) { bottomMargin = newMargin; };
void ChangeAndReloadImage(const gd::String &texture,
const RuntimeScene &scene);
gd::String textureName;
#if defined(GD_IDE_ONLY)
virtual void GetPropertyForDebugger(std::size_t propertyNb,
gd::String &name,
gd::String &value) const;
virtual bool ChangeProperty(std::size_t propertyNb, gd::String newValue);
virtual std::size_t GetNumberOfProperties() const;
#endif
private:
float width;
float height;
float leftMargin;
float topMargin;
float rightMargin;
float bottomMargin;
float angle;
std::shared_ptr<SFMLTextureWrapper> texture;
};
#endif // PANELSPRITEOBJECT_H

View File

@@ -2,10 +2,18 @@ namespace gdjs {
import PIXI = GlobalPIXIModule.PIXI;
class PanelSpriteRuntimeObjectPixiRenderer {
_object: gdjs.PanelSpriteRuntimeObject;
_spritesContainer: any;
_centerSprite: any;
_borderSprites: any;
_alpha: float;
/**
* The _wrapperContainer must be considered as the main container of this object
* All transformations are applied on this container
* See updateOpacity for more info why.
*/
_wrapperContainer: PIXI.Container;
/**
* The _spritesContainer is used to create the sprites and apply cacheAsBitmap only.
*/
_spritesContainer: PIXI.Container;
_centerSprite: PIXI.Sprite | PIXI.TilingSprite;
_borderSprites: Array<PIXI.Sprite | PIXI.TilingSprite>;
_wasRendered: boolean = false;
_textureWidth = 0;
_textureHeight = 0;
@@ -17,38 +25,37 @@ namespace gdjs {
tiled: boolean
) {
this._object = runtimeObject;
if (this._spritesContainer === undefined) {
const texture = (runtimeScene
.getGame()
.getImageManager() as gdjs.PixiImageManager).getPIXITexture(
textureName
);
const StretchedSprite = !tiled ? PIXI.Sprite : PIXI.TilingSprite;
this._spritesContainer = new PIXI.Container();
const texture = (runtimeScene
.getGame()
.getImageManager() as gdjs.PixiImageManager).getPIXITexture(
textureName
);
const StretchedSprite = !tiled ? PIXI.Sprite : PIXI.TilingSprite;
this._spritesContainer = new PIXI.Container();
this._wrapperContainer = new PIXI.Container();
// @ts-ignore
this._centerSprite = new StretchedSprite(new PIXI.Texture(texture));
this._borderSprites = [
// @ts-ignore
this._centerSprite = new StretchedSprite(new PIXI.Texture(texture));
this._borderSprites = [
// @ts-ignore
new StretchedSprite(new PIXI.Texture(texture)),
//Right
new PIXI.Sprite(texture),
//Top-Right
// @ts-ignore
new StretchedSprite(new PIXI.Texture(texture)),
//Top
new PIXI.Sprite(texture),
//Top-Left
// @ts-ignore
new StretchedSprite(new PIXI.Texture(texture)),
//Left
new PIXI.Sprite(texture),
//Bottom-Left
// @ts-ignore
new StretchedSprite(new PIXI.Texture(texture)),
//Bottom
new PIXI.Sprite(texture),
];
}
new StretchedSprite(new PIXI.Texture(texture)),
//Right
new PIXI.Sprite(texture),
//Top-Right
// @ts-ignore
new StretchedSprite(new PIXI.Texture(texture)),
//Top
new PIXI.Sprite(texture),
//Top-Left
// @ts-ignore
new StretchedSprite(new PIXI.Texture(texture)),
//Left
new PIXI.Sprite(texture),
//Bottom-Left
// @ts-ignore
new StretchedSprite(new PIXI.Texture(texture)),
//Bottom
new PIXI.Sprite(texture),
];
//Bottom-Right
this.setTexture(textureName, runtimeScene);
@@ -57,44 +64,43 @@ namespace gdjs {
for (let i = 0; i < this._borderSprites.length; ++i) {
this._spritesContainer.addChild(this._borderSprites[i]);
}
this._alpha = this._spritesContainer.alpha;
this._wrapperContainer.addChild(this._spritesContainer);
runtimeScene
.getLayer('')
.getRenderer()
.addRendererObject(this._spritesContainer, runtimeObject.getZOrder());
.addRendererObject(this._wrapperContainer, runtimeObject.getZOrder());
}
getRendererObject() {
return this._spritesContainer;
return this._wrapperContainer;
}
ensureUpToDate() {
if (this._spritesContainer.visible && this._wasRendered) {
// Update the alpha of the container to make sure that it's applied.
// If not done, the alpha will be back to full opaque when changing the color
// of the object.
this._spritesContainer.alpha = this._alpha;
// Cache the rendered sprites as a bitmap to speed up rendering when
// lots of panel sprites are on the scene.
// Sadly, because of this, we need a wrapper container to workaround
// a PixiJS issue with alpha (see updateOpacity).
this._spritesContainer.cacheAsBitmap = true;
}
this._wasRendered = true;
}
updateOpacity(): void {
//TODO: Workaround a not working property in PIXI.js:
this._spritesContainer.alpha = this._spritesContainer.visible
? this._object.opacity / 255
: 0;
this._alpha = this._spritesContainer.alpha;
// The alpha is updated on a wrapper around the sprite because a known bug
// in Pixi will create a flicker when cacheAsBitmap is set to true.
// (see https://github.com/pixijs/pixijs/issues/4610)
this._wrapperContainer.alpha = this._object.opacity / 255;
}
updateAngle(): void {
this._spritesContainer.rotation = gdjs.toRad(this._object.angle);
this._wrapperContainer.rotation = gdjs.toRad(this._object.angle);
}
updatePosition(): void {
this._spritesContainer.position.x =
this._wrapperContainer.position.x =
this._object.x + this._object._width / 2;
this._spritesContainer.position.y =
this._wrapperContainer.position.y =
this._object.y + this._object._height / 2;
}
@@ -316,19 +322,19 @@ namespace gdjs {
this._updateSpritesAndTexturesSize();
this._updateLocalPositions();
this.updatePosition();
this._spritesContainer.pivot.x = this._object._width / 2;
this._spritesContainer.pivot.y = this._object._height / 2;
this._wrapperContainer.pivot.x = this._object._width / 2;
this._wrapperContainer.pivot.y = this._object._height / 2;
}
updateWidth(): void {
this._spritesContainer.pivot.x = this._object._width / 2;
this._wrapperContainer.pivot.x = this._object._width / 2;
this._updateSpritesAndTexturesSize();
this._updateLocalPositions();
this.updatePosition();
}
updateHeight(): void {
this._spritesContainer.pivot.y = this._object._height / 2;
this._wrapperContainer.pivot.y = this._object._height / 2;
this._updateSpritesAndTexturesSize();
this._updateLocalPositions();
this.updatePosition();
@@ -339,25 +345,21 @@ namespace gdjs {
if (colors.length < 3) {
return;
}
this._centerSprite.tint =
'0x' +
gdjs.rgbToHex(
parseInt(colors[0], 10),
parseInt(colors[1], 10),
parseInt(colors[2], 10)
);
this._centerSprite.tint = gdjs.rgbToHexNumber(
parseInt(colors[0], 10),
parseInt(colors[1], 10),
parseInt(colors[2], 10)
);
for (
let borderCounter = 0;
borderCounter < this._borderSprites.length;
borderCounter++
) {
this._borderSprites[borderCounter].tint =
'0x' +
gdjs.rgbToHex(
parseInt(colors[0], 10),
parseInt(colors[1], 10),
parseInt(colors[2], 10)
);
this._borderSprites[borderCounter].tint = gdjs.rgbToHexNumber(
parseInt(colors[0], 10),
parseInt(colors[1], 10),
parseInt(colors[2], 10)
);
}
this._spritesContainer.cacheAsBitmap = false;
}

View File

@@ -2,7 +2,6 @@ cmake_minimum_required(VERSION 2.6)
cmake_policy(SET CMP0015 NEW)
project(ParticleSystem)
gd_add_extension_includes()
#Defines
@@ -11,19 +10,12 @@ gd_add_extension_definitions(ParticleSystem)
#The targets
###
include_directories(./SPARK/include)
include_directories(.)
file(GLOB source_files *.cpp *.h "SPARK/src/SPK_All.cpp" "SPARK/src/SPK_GL_All.cpp") #Also compiles the SPARK particle engine files.
file(GLOB formatted_source_files *.cpp *.h)
gd_add_clang_utils(ParticleSystem "${formatted_source_files}")
file(GLOB source_files *.cpp *.h)
gd_add_clang_utils(ParticleSystem "${source_files}")
gd_add_extension_target(ParticleSystem "${source_files}")
gdcpp_add_runtime_extension_target(ParticleSystem_Runtime "${source_files}")
#Linker files for the IDE extension
###
gd_extension_link_libraries(ParticleSystem)
#Linker files for the GD C++ Runtime extension
###
gdcpp_runtime_extension_link_libraries(ParticleSystem_Runtime)

View File

@@ -10,8 +10,9 @@ This project is released under the MIT License.
#include "ExtensionSubDeclaration1.h"
#include "ExtensionSubDeclaration2.h"
#include "ExtensionSubDeclaration3.h"
#include "GDCpp/Extensions/ExtensionBase.h"
#include "GDCpp/Runtime/Project/BehaviorsSharedData.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Tools/Localization.h"
#include "GDCore/Project/BehaviorsSharedData.h"
#include "ParticleEmitterObject.h"
void DeclareParticleSystemExtension(gd::PlatformExtension& extension) {
@@ -45,393 +46,4 @@ void DeclareParticleSystemExtension(gd::PlatformExtension& extension) {
ExtensionSubDeclaration3(obj);
#endif
}
}
/**
* Constructor of an extension declares everything the extension contains:
* objects, actions, conditions and expressions.
*/
ParticleSystemCppExtension::ParticleSystemCppExtension() {
DeclareParticleSystemExtension(*this);
AddRuntimeObject<ParticleEmitterObject, RuntimeParticleEmitterObject>(
GetObjectMetadata("ParticleSystem::ParticleEmitter"),
"RuntimeParticleEmitterObject");
#if defined(GD_IDE_ONLY)
auto& actions = GetAllActionsForObject("ParticleSystem::ParticleEmitter");
auto& conditions =
GetAllConditionsForObject("ParticleSystem::ParticleEmitter");
auto& expressions =
GetAllExpressionsForObject("ParticleSystem::ParticleEmitter");
auto& strExpressions =
GetAllStrExpressionsForObject("ParticleSystem::ParticleEmitter");
actions["ParticleSystem::EmitterForceMin"]
.SetFunctionName("SetEmitterForceMin")
.SetGetter("GetEmitterForceMin")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::EmitterForceMax"]
.SetFunctionName("SetEmitterForceMax")
.SetGetter("GetEmitterForceMax")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::EmitterXDirection"]
.SetFunctionName("SetEmitterXDirection")
.SetGetter("GetEmitterXDirection")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::EmitterXDirection"]
.SetFunctionName("GetEmitterXDirection")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::EmitterYDirection"]
.SetFunctionName("SetEmitterYDirection")
.SetGetter("GetEmitterYDirection")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::EmitterYDirection"]
.SetFunctionName("GetEmitterYDirection")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::EmitterZDirection"]
.SetFunctionName("SetEmitterZDirection")
.SetGetter("GetEmitterZDirection")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::EmitterZDirection"]
.SetFunctionName("GetEmitterZDirection")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::EmitterAngle"]
.SetFunctionName("SetAngle")
.SetGetter("GetAngle")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::EmitterAngle"]
.SetFunctionName("GetAngle")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::EmitterAngleA"]
.SetFunctionName("SetEmitterAngleA")
.SetGetter("GetEmitterAngleA")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::EmitterAngleA"]
.SetFunctionName("GetEmitterAngleA")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::EmitterAngleB"]
.SetFunctionName("SetEmitterAngleB")
.SetGetter("GetEmitterAngleB")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::EmitterAngleB"]
.SetFunctionName("GetEmitterAngleB")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ConeSprayAngle"]
.SetFunctionName("SetConeSprayAngle")
.SetGetter("GetConeSprayAngle")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::ConeSprayAngle"]
.SetFunctionName("GetConeSprayAngle")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::Friction"]
.SetFunctionName("SetFriction")
.SetGetter("GetFriction")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::Friction"]
.SetFunctionName("GetFriction")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ZoneRadius"]
.SetFunctionName("SetZoneRadius")
.SetGetter("GetZoneRadius")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::ZoneRadius"]
.SetFunctionName("GetZoneRadius")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ParticleLifeTimeMin"]
.SetFunctionName("SetParticleLifeTimeMin")
.SetGetter("GetParticleLifeTimeMin")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::ParticleLifeTimeMin"]
.SetFunctionName("GetParticleLifeTimeMin")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ParticleLifeTimeMax"]
.SetFunctionName("SetParticleLifeTimeMax")
.SetGetter("GetParticleLifeTimeMax")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::ParticleLifeTimeMax"]
.SetFunctionName("GetParticleLifeTimeMax")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ParticleGravityX"]
.SetFunctionName("SetParticleGravityX")
.SetGetter("GetParticleGravityX")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::ParticleGravityX"]
.SetFunctionName("GetParticleGravityX")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ParticleGravityY"]
.SetFunctionName("SetParticleGravityY")
.SetGetter("GetParticleGravityY")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::ParticleGravityY"]
.SetFunctionName("GetParticleGravityY")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ParticleGravityZ"]
.SetFunctionName("SetParticleGravityZ")
.SetGetter("GetParticleGravityZ")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::ParticleGravityZ"]
.SetFunctionName("GetParticleGravityZ")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ParticleGravityAngle"]
.SetFunctionName("SetParticleGravityAngle")
.SetGetter("GetParticleGravityAngle")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::ParticleGravityAngle"]
.SetFunctionName("GetParticleGravityAngle")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ParticleGravityLength"]
.SetFunctionName("SetParticleGravityLength")
.SetGetter("GetParticleGravityLength")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::ParticleGravityLength"]
.SetFunctionName("GetParticleGravityLength")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ParticleColor1"]
.SetFunctionName("SetParticleColor1")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ParticleColor2"]
.SetFunctionName("SetParticleColor2")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ParticleRed1"]
.SetFunctionName("SetParticleRed1")
.SetGetter("GetParticleRed1")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::ParticleRed1"]
.SetFunctionName("GetParticleRed1")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ParticleRed2"]
.SetFunctionName("SetParticleRed2")
.SetGetter("GetParticleRed2")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::ParticleRed2"]
.SetFunctionName("GetParticleRed2")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ParticleBlue1"]
.SetFunctionName("SetParticleBlue1")
.SetGetter("GetParticleBlue1")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::ParticleBlue1"]
.SetFunctionName("GetParticleBlue1")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ParticleBlue2"]
.SetFunctionName("SetParticleBlue2")
.SetGetter("GetParticleBlue2")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::ParticleBlue2"]
.SetFunctionName("GetParticleBlue2")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ParticleGreen1"]
.SetFunctionName("SetParticleGreen1")
.SetGetter("GetParticleGreen1")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::ParticleGreen1"]
.SetFunctionName("GetParticleGreen1")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ParticleGreen2"]
.SetFunctionName("SetParticleGreen2")
.SetGetter("GetParticleGreen2")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::ParticleGreen2"]
.SetFunctionName("GetParticleGreen2")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ParticleSize1"]
.SetFunctionName("SetParticleSize1")
.SetGetter("GetParticleSize1")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::ParticleSize1"]
.SetFunctionName("GetParticleSize1")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ParticleSize2"]
.SetFunctionName("SetParticleSize2")
.SetGetter("GetParticleSize2")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::ParticleSize2"]
.SetFunctionName("GetParticleSize2")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ParticleAngle1"]
.SetFunctionName("SetParticleAngle1")
.SetGetter("GetParticleAngle1")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::ParticleAngle1"]
.SetFunctionName("GetParticleAngle1")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ParticleAngle2"]
.SetFunctionName("SetParticleAngle2")
.SetGetter("GetParticleAngle2")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::ParticleAngle2"]
.SetFunctionName("GetParticleAngle2")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ParticleAlpha1"]
.SetFunctionName("SetParticleAlpha1")
.SetGetter("GetParticleAlpha1")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::ParticleAlpha1"]
.SetFunctionName("GetParticleAlpha1")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::ParticleAlpha2"]
.SetFunctionName("SetParticleAlpha2")
.SetGetter("GetParticleAlpha2")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::ParticleAlpha2"]
.SetFunctionName("GetParticleAlpha2")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::NoMoreParticles"]
.SetFunctionName("NoMoreParticles")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::RecreateParticleSystem"]
.SetFunctionName("RecreateParticleSystem")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::RendererParam1"]
.SetFunctionName("SetRendererParam1")
.SetGetter("GetRendererParam1")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::RendererParam1"]
.SetFunctionName("GetRendererParam1")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::RendererParam2"]
.SetFunctionName("SetRendererParam2")
.SetGetter("GetRendererParam2")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::RendererParam2"]
.SetFunctionName("GetRendererParam2")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::Tank"]
.SetFunctionName("SetTank")
.SetGetter("GetTank")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::Tank"].SetFunctionName("GetTank").SetIncludeFile(
"ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::Flow"]
.SetFunctionName("SetFlow")
.SetGetter("GetFlow")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::Flow"].SetFunctionName("GetFlow").SetIncludeFile(
"ParticleSystem/ParticleEmitterObject.h");
actions["ParticleSystem::Texture"]
.SetFunctionName("SetTexture")
.SetGetter("GetTexture")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
conditions["ParticleSystem::Texture"]
.SetFunctionName("GetTexture")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
strExpressions["Texture"]
.SetFunctionName("GetTexture")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["NbParticles"]
.SetFunctionName("GetNbParticles")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["RendererParam1"]
.SetFunctionName("GetRendererParam1")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["RendererParam2"]
.SetFunctionName("GetRendererParam2")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["Tank"].SetFunctionName("GetTank").SetIncludeFile(
"ParticleSystem/ParticleEmitterObject.h");
expressions["Flow"].SetFunctionName("GetFlow").SetIncludeFile(
"ParticleSystem/ParticleEmitterObject.h");
expressions["EmitterForceMin"]
.SetFunctionName("GetEmitterForceMin")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["EmitterForceMax"]
.SetFunctionName("GetEmitterForceMax")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["EmitterXDirection"]
.SetFunctionName("GetEmitterXDirection")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["EmitterYDirection"]
.SetFunctionName("GetEmitterYDirection")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["EmitterZDirection"]
.SetFunctionName("GetEmitterZDirection")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["EmitterAngle"]
.SetFunctionName("GetAngle")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["EmitterAngleA"]
.SetFunctionName("GetEmitterAngleA")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["EmitterAngleB"]
.SetFunctionName("GetEmitterAngleB")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["ZoneRadius"]
.SetFunctionName("GetZoneRadius")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["ParticleGravityX"]
.SetFunctionName("GetParticleGravityX")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["ParticleGravityY"]
.SetFunctionName("GetParticleGravityY")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["ParticleGravityZ"]
.SetFunctionName("GetParticleGravityZ")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["ParticleGravityAngle"]
.SetFunctionName("GetParticleGravityAngle")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["ParticleGravityLength"]
.SetFunctionName("GetParticleGravityLength")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["Friction"]
.SetFunctionName("GetFriction")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["ParticleLifeTimeMin"]
.SetFunctionName("GetParticleLifeTimeMin")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["ParticleLifeTimeMax"]
.SetFunctionName("GetParticleLifeTimeMax")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["ParticleRed1"]
.SetFunctionName("GetParticleRed1")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["ParticleRed2"]
.SetFunctionName("GetParticleRed2")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["ParticleBlue1"]
.SetFunctionName("GetParticleBlue1")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["ParticleBlue2"]
.SetFunctionName("GetParticleBlue2")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["ParticleGreen1"]
.SetFunctionName("GetParticleGreen1")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["ParticleGreen2"]
.SetFunctionName("GetParticleGreen2")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["ParticleAlpha1"]
.SetFunctionName("GetParticleAlpha1")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["ParticleAlpha2"]
.SetFunctionName("GetParticleAlpha2")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["ParticleSize1"]
.SetFunctionName("GetParticleSize1")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["ParticleSize2"]
.SetFunctionName("GetParticleSize2")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["ParticleAngle1"]
.SetFunctionName("GetParticleAngle1")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
expressions["ParticleAngle2"]
.SetFunctionName("GetParticleAngle2")
.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
StripUnimplementedInstructionsAndExpressions();
#endif
GD_COMPLETE_EXTENSION_COMPILATION_INFORMATION();
};
/**
* Used by GDevelop to create the extension class
* -- Do not need to be modified. --
*/
extern "C" ExtensionBase* GD_EXTENSION_API CreateGDExtension() {
return new ParticleSystemCppExtension;
}
}

View File

@@ -7,23 +7,13 @@ This project is released under the MIT License.
#ifndef EXTENSION_H_INCLUDED
#define EXTENSION_H_INCLUDED
#include "GDCpp/Extensions/ExtensionBase.h"
#include "GDCore/Extensions/PlatformExtension.h"
namespace gd {
class ObjectMetadata;
}
namespace gd {
class PlatformExtension;
}
void DeclareParticleSystemExtension(gd::PlatformExtension& extension);
/**
* \brief This class declares information about the extension.
*/
class ParticleSystemCppExtension : public ExtensionBase {
public:
ParticleSystemCppExtension();
virtual ~ParticleSystemCppExtension(){};
};
#endif // EXTENSION_H_INCLUDED

View File

@@ -5,7 +5,8 @@ Copyright (c) 2010-2016 Florian Rival (Florian.Rival@gmail.com)
This project is released under the MIT License.
*/
#include "GDCpp/Extensions/ExtensionBase.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Tools/Localization.h"
#include "Extension.h"
#include "ParticleEmitterObject.h"

View File

@@ -5,7 +5,8 @@ Copyright (c) 2010-2016 Florian Rival (Florian.Rival@gmail.com)
This project is released under the MIT License.
*/
#include "GDCpp/Extensions/ExtensionBase.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Tools/Localization.h"
#include "Extension.h"
#include "ParticleEmitterObject.h"

View File

@@ -5,7 +5,8 @@ Copyright (c) 2010-2016 Florian Rival (Florian.Rival@gmail.com)
This project is released under the MIT License.
*/
#include "GDCpp/Extensions/ExtensionBase.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Tools/Localization.h"
#include "Extension.h"
#include "ParticleEmitterObject.h"

Some files were not shown because too many files have changed in this diff Show More