mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
88 Commits
feature/hi
...
v5.0.135
Author | SHA1 | Date | |
---|---|---|---|
![]() |
33ddda1070 | ||
![]() |
029c9c853b | ||
![]() |
e38a70ad10 | ||
![]() |
78b48601a1 | ||
![]() |
e91a794d91 | ||
![]() |
6fefd6d36e | ||
![]() |
0cf05b71ba | ||
![]() |
1ab023e211 | ||
![]() |
aa4e9e25bf | ||
![]() |
bc235ef492 | ||
![]() |
eabd1a4f23 | ||
![]() |
62ef3e729b | ||
![]() |
802ee0c03f | ||
![]() |
7ef2050de7 | ||
![]() |
eeea1b99f4 | ||
![]() |
e75d49ea51 | ||
![]() |
048674a7d0 | ||
![]() |
0502bd1f7a | ||
![]() |
66b84441ea | ||
![]() |
d9e27dc4f3 | ||
![]() |
a3c3ffc3bb | ||
![]() |
dc33b6cc01 | ||
![]() |
4a0c1c5ad2 | ||
![]() |
5820c5dd3e | ||
![]() |
606f5aff1b | ||
![]() |
1f42374417 | ||
![]() |
3356400026 | ||
![]() |
b811b1e873 | ||
![]() |
e985b11971 | ||
![]() |
aefc5e2fed | ||
![]() |
0ccb7c3216 | ||
![]() |
33c2c9c6cf | ||
![]() |
55a6306f05 | ||
![]() |
d766e32a18 | ||
![]() |
7cdf4e1184 | ||
![]() |
2540bf3c3e | ||
![]() |
6adec363d5 | ||
![]() |
91a02d132f | ||
![]() |
67718a364b | ||
![]() |
e9b600d885 | ||
![]() |
696dfcb746 | ||
![]() |
437edd1fe7 | ||
![]() |
48599ae9ca | ||
![]() |
c288700f2d | ||
![]() |
fbfb5dbaa6 | ||
![]() |
dfa27df64b | ||
![]() |
1ef404b9a9 | ||
![]() |
785dd6f08b | ||
![]() |
59bc76e144 | ||
![]() |
d873d9747a | ||
![]() |
a7fe36f351 | ||
![]() |
252eeb86b1 | ||
![]() |
66145ce506 | ||
![]() |
0dd10d2fce | ||
![]() |
5d35241c4c | ||
![]() |
ba368d9eed | ||
![]() |
fbeeb589a2 | ||
![]() |
3ec4e3b6dd | ||
![]() |
11ccaf2ea4 | ||
![]() |
274d31f563 | ||
![]() |
c37049cd72 | ||
![]() |
7cdc92c776 | ||
![]() |
471cd61d82 | ||
![]() |
afb66f213d | ||
![]() |
8ad70e57cc | ||
![]() |
d9ea04e059 | ||
![]() |
bb3abdb1fa | ||
![]() |
cdddcafa68 | ||
![]() |
14175c334e | ||
![]() |
6bd4dff03e | ||
![]() |
ceec39f6a2 | ||
![]() |
5abf80a0c9 | ||
![]() |
7f955d8703 | ||
![]() |
781dd42ccb | ||
![]() |
e584fa952d | ||
![]() |
5681667dde | ||
![]() |
d16f04f4a2 | ||
![]() |
e9b464beba | ||
![]() |
7597dbe0d1 | ||
![]() |
4777f0a824 | ||
![]() |
5b2532f8f3 | ||
![]() |
2c43de5120 | ||
![]() |
124ce1101d | ||
![]() |
eb3d6c2670 | ||
![]() |
f737fa479f | ||
![]() |
f93b3bc3b4 | ||
![]() |
5c6eb2dadb | ||
![]() |
3e6ca186f8 |
@@ -2,10 +2,17 @@
|
||||
# on the Electron runtime (newIDE/electron-app) for macOS and Linux.
|
||||
# For Windows, see the appveyor.yml file.
|
||||
|
||||
# This also builds GDevelop.js and store it on a S3 so it can be used to run
|
||||
# GDevelop without building it from scratch.
|
||||
|
||||
# Note that these CircleCI builds/tests are not launched on Pull Requests from forks,
|
||||
# to avoid sharing secrets.
|
||||
|
||||
version: 2.1
|
||||
orbs:
|
||||
aws-cli: circleci/aws-cli@2.0.6
|
||||
jobs:
|
||||
# Build the **entire** app for macOS.
|
||||
build-macos:
|
||||
macos:
|
||||
xcode: 12.5.1
|
||||
@@ -75,6 +82,7 @@ jobs:
|
||||
name: Deploy to S3 (latest)
|
||||
command: export PATH=~/.local/bin:$PATH && aws s3 sync newIDE/electron-app/dist s3://gdevelop-releases/$(git rev-parse --abbrev-ref HEAD)/latest/
|
||||
|
||||
# Build the **entire** app for Linux.
|
||||
build-linux:
|
||||
# CircleCI docker workers are failing if they don't have enough memory (no swap)
|
||||
resource_class: xlarge
|
||||
@@ -153,10 +161,67 @@ jobs:
|
||||
name: Deploy to S3 (latest)
|
||||
command: aws s3 sync newIDE/electron-app/dist s3://gdevelop-releases/$(git rev-parse --abbrev-ref HEAD)/latest/
|
||||
|
||||
# Build the WebAssembly library only (so that it's cached on a S3 and easy to re-use).
|
||||
build-gdevelop_js-wasm-only:
|
||||
docker:
|
||||
- image: cimg/node:16.13
|
||||
|
||||
working_directory: ~/GDevelop
|
||||
|
||||
steps:
|
||||
- checkout
|
||||
- aws-cli/setup
|
||||
|
||||
# System dependencies (for Emscripten)
|
||||
- run:
|
||||
name: Install dependencies for Emscripten
|
||||
command: sudo apt-get update && sudo apt install cmake
|
||||
|
||||
- run:
|
||||
name: Install Python3 dependencies for Emscripten
|
||||
command: sudo apt install python-is-python3 python3-distutils -y
|
||||
|
||||
- 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:
|
||||
- gdevelop.js-linux-nodejs-dependencies-{{ checksum "GDevelop.js/package-lock.json" }}
|
||||
# fallback to using the latest cache if no exact match is found
|
||||
- gdevelop.js-linux-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 ..
|
||||
|
||||
- save_cache:
|
||||
paths:
|
||||
- GDevelop.js/node_modules
|
||||
key: gdevelop.js-linux-nodejs-dependencies-{{ checksum "GDevelop.js/package-lock.json" }}
|
||||
|
||||
# Upload artifacts (CircleCI)
|
||||
- store_artifacts:
|
||||
path: Binaries/embuild/GDevelop.js
|
||||
|
||||
# Upload artifacts (AWS)
|
||||
- run:
|
||||
name: Deploy to S3 (specific commit)
|
||||
command: aws s3 sync Binaries/embuild/GDevelop.js s3://gdevelop-gdevelop.js/$(git rev-parse --abbrev-ref HEAD)/commit/$(git rev-parse HEAD)/
|
||||
- run:
|
||||
name: Deploy to S3 (latest)
|
||||
command: aws s3 sync Binaries/embuild/GDevelop.js s3://gdevelop-gdevelop.js/$(git rev-parse --abbrev-ref HEAD)/latest/
|
||||
|
||||
workflows:
|
||||
builds:
|
||||
jobs:
|
||||
- build-gdevelop_js-wasm-only
|
||||
- build-macos:
|
||||
filters:
|
||||
branches:
|
||||
|
6
.github/ISSUE_TEMPLATE/config.yml
vendored
6
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -4,14 +4,14 @@ contact_links:
|
||||
url: https://discord.gg/rjdYHvj
|
||||
about: Discuss on the forum or on the Discord to get help creating a game or identifying a bug.
|
||||
- name: GDevelop Forums
|
||||
url: https://forum.gdevelop-app.com
|
||||
url: https://forum.gdevelop.io
|
||||
about: You can also discuss game creation, new feature requests and bugs on the forum.
|
||||
- name: GDevelop Roadmap
|
||||
url: https://trello.com/b/qf0lM7k8/gdevelop-roadmap
|
||||
about: Look at the roadmap and vote on features that you want to see in GDevelop.
|
||||
- name: Submit a new game example that you created
|
||||
url: https://github.com/GDevelopApp/GDevelop-examples/issues/new/choose
|
||||
about: You can submit a game that you made to be added to examples in the "GDevelop-examples" repository
|
||||
about: You can submit a game that you made to be added to examples in the "GDevelop-examples" repository
|
||||
- name: Submit a new game extension that you created
|
||||
url: https://github.com/4ian/GDevelop-extensions/issues/new/choose
|
||||
about: You can submit an extension that you made in the "GDevelop-extensions" repository
|
||||
about: You can submit an extension that you made in the "GDevelop-extensions" repository
|
||||
|
2
.github/workflows/issues.yml
vendored
2
.github/workflows/issues.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
type: "body"
|
||||
regex: ".*Scroll down to '\\.\\.\\.\\.'.*"
|
||||
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed because it seems that you have not included any steps to reproduce the bug.\n\nGitHub is a place for the technical development of GDevelop itself - you may want to go on the [forum](https://forum.gdevelop-app.com/), the Discord chat or [read the documentation](http://wiki.compilgames.net/doku.php/gdevelop5/start) to learn more about GDevelop. Thanks!"
|
||||
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed because it seems that you have not included any steps to reproduce the bug.\n\nGitHub is a place for the technical development of GDevelop itself - you may want to go on the [forum](https://forum.gdevelop.io/), the Discord chat or [read the documentation](https://wiki.gdevelop.io/gdevelop5/start) to learn more about GDevelop. Thanks!"
|
||||
- name: Autoclose known beta 105 web-app update bug
|
||||
uses: arkon/issue-closer-action@v1.1
|
||||
with:
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,6 +8,7 @@
|
||||
/Binaries/.embuild*
|
||||
/Binaries/build*
|
||||
/Binaries/embuild*
|
||||
/emsdk
|
||||
*.dll
|
||||
*.exe
|
||||
*.a
|
||||
|
25
.gitpod.yml
Normal file
25
.gitpod.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
# This is a configuration file allowing to quickly set up a development environment
|
||||
# on GitPod (https://www.gitpod.io/).
|
||||
# Also check GitHub codespaces if you're interested in working
|
||||
# on a remote development server.
|
||||
|
||||
# This works well for:
|
||||
# - The editor web-app, including the C++ classes.
|
||||
# This is not yet adapted for:
|
||||
# - Working on the game engine or extensions, as they can't be easily tested on the web-app.
|
||||
# - Working on the desktop app (Electron).
|
||||
|
||||
tasks:
|
||||
- name: Install dependencies for Emscripten and build GDevelop.js
|
||||
init: |
|
||||
sudo apt-get update
|
||||
sudo apt install cmake python-is-python3 python3-distutils -y
|
||||
git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 1.39.6 && ./emsdk activate 1.39.6 && cd ..
|
||||
cd GDevelop.js
|
||||
npm install
|
||||
source ../emsdk/emsdk_env.sh && npm run build -- --dev
|
||||
cd ..
|
||||
- name: Install GDevelop IDE dependencies
|
||||
init: cd newIDE/app && npm install && cd ../electron-app && npm install
|
||||
|
||||
|
26
.travis.yml
26
.travis.yml
@@ -1,9 +1,6 @@
|
||||
# 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).
|
||||
|
||||
@@ -17,18 +14,7 @@ cache:
|
||||
directories:
|
||||
- $HOME/.npm
|
||||
|
||||
services:
|
||||
# Virtual Framebuffer 'fake' X server for SFML
|
||||
- xvfb
|
||||
|
||||
addons:
|
||||
artifacts:
|
||||
s3_region: "us-east-1"
|
||||
target_paths:
|
||||
- /$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)/commit/$(git rev-parse HEAD)
|
||||
- /$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)/latest
|
||||
paths:
|
||||
- Binaries/embuild/GDevelop.js
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
@@ -36,20 +22,8 @@ addons:
|
||||
# Build dependencies:
|
||||
- cmake
|
||||
- p7zip-full
|
||||
# SFML dependencies:
|
||||
- libopenal-dev
|
||||
- libjpeg-dev
|
||||
- libglew-dev
|
||||
- libudev-dev
|
||||
- libxrandr-dev
|
||||
- libsndfile1-dev
|
||||
- libglu1-mesa-dev
|
||||
- libfreetype6-dev
|
||||
|
||||
before_install:
|
||||
#Activate X Virtual Framebuffer to allow tests to
|
||||
#use SFML.
|
||||
- "export DISPLAY=:99.0"
|
||||
# This workaround is required to avoid libstdc++ errors (Emscripten requires a recent version of libstdc++)
|
||||
- wget -q -O libstdc++6 http://security.ubuntu.com/ubuntu/pool/main/g/gcc-5/libstdc++6_5.4.0-6ubuntu1~16.04.12_amd64.deb
|
||||
- sudo dpkg --force-all -i libstdc++6
|
||||
|
7
.vscode/c_cpp_properties.json
vendored
7
.vscode/c_cpp_properties.json
vendored
@@ -7,11 +7,9 @@
|
||||
"${workspaceRoot}/GDJS",
|
||||
"${workspaceRoot}/Extensions",
|
||||
"${workspaceRoot}/Core",
|
||||
"${workspaceRoot}/ExtLibs/SFML/include",
|
||||
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1",
|
||||
"/usr/local/include",
|
||||
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include",
|
||||
"/usr/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"defines": [
|
||||
@@ -27,7 +25,6 @@
|
||||
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1",
|
||||
"/usr/local/include",
|
||||
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include",
|
||||
"/usr/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
@@ -48,7 +45,6 @@
|
||||
"${workspaceRoot}/GDJS",
|
||||
"${workspaceRoot}/Extensions",
|
||||
"${workspaceRoot}/Core",
|
||||
"${workspaceRoot}/ExtLibs/SFML/include",
|
||||
"/usr/include",
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}"
|
||||
@@ -78,7 +74,6 @@
|
||||
"${workspaceRoot}/GDJS",
|
||||
"${workspaceRoot}/Extensions",
|
||||
"${workspaceRoot}/Core",
|
||||
"${workspaceRoot}/ExtLibs/SFML/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"defines": [
|
||||
@@ -101,4 +96,4 @@
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
}
|
||||
|
14
.vscode/launch.json
vendored
14
.vscode/launch.json
vendored
@@ -15,6 +15,20 @@
|
||||
"disableOptimisticBPs": true,
|
||||
"cwd": "${workspaceFolder}/GDevelop.js"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "newIDE/app Jest tests (current file)",
|
||||
"program": "${workspaceFolder}/newIDE/app/node_modules/.bin/react-scripts",
|
||||
"args": [
|
||||
"test", "--env=node",
|
||||
"${fileBasenameNoExtension}"
|
||||
],
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"disableOptimisticBPs": true,
|
||||
"cwd": "${workspaceFolder}/newIDE/app"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
|
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@@ -115,7 +115,6 @@
|
||||
"files.exclude": {
|
||||
"Binaries/*build*": true,
|
||||
"Binaries/Output": true,
|
||||
"ExtLibs/SFML": true,
|
||||
"GDJS/Runtime-dist": true,
|
||||
"docs": true,
|
||||
"newIDE/electron-app/dist": true,
|
||||
|
@@ -17,7 +17,7 @@ endmacro()
|
||||
gd_set_option(BUILD_CORE TRUE BOOL "TRUE to build GDevelop Core library")
|
||||
gd_set_option(BUILD_GDJS TRUE BOOL "TRUE to build GDevelop JS Platform")
|
||||
gd_set_option(BUILD_EXTENSIONS TRUE BOOL "TRUE to build the extensions")
|
||||
gd_set_option(BUILD_TESTS FALSE BOOL "TRUE to build the tests")
|
||||
gd_set_option(BUILD_TESTS TRUE BOOL "TRUE to build the tests")
|
||||
|
||||
# Disable deprecated code
|
||||
set(NO_GUI TRUE CACHE BOOL "" FORCE) #Force disable old GUI related code.
|
||||
|
@@ -14,7 +14,6 @@ set(GDCORE_lib_dir ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SY
|
||||
|
||||
#Dependencies on external libraries:
|
||||
###
|
||||
include_directories(${sfml_include_dir})
|
||||
|
||||
#Defines
|
||||
###
|
||||
@@ -68,14 +67,6 @@ set(LIBRARY_OUTPUT_PATH ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMA
|
||||
set(ARCHIVE_OUTPUT_PATH ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME})
|
||||
set(RUNTIME_OUTPUT_PATH ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME})
|
||||
|
||||
#Linker files
|
||||
###
|
||||
IF(EMSCRIPTEN)
|
||||
#Nothing.
|
||||
ELSE()
|
||||
target_link_libraries(GDCore ${sfml_LIBRARIES})
|
||||
ENDIF()
|
||||
|
||||
#Tests
|
||||
###
|
||||
if(BUILD_TESTS)
|
||||
@@ -88,5 +79,5 @@ if(BUILD_TESTS)
|
||||
add_executable(GDCore_tests ${test_source_files})
|
||||
set_target_properties(GDCore_tests PROPERTIES BUILD_WITH_INSTALL_RPATH FALSE) #Allow finding dependencies directly from build path on Mac OS X.
|
||||
target_link_libraries(GDCore_tests GDCore)
|
||||
target_link_libraries(GDCore_tests ${sfml_LIBRARIES})
|
||||
target_link_libraries(GDCore_tests ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
|
@@ -13,7 +13,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "Utf8/utf8.h"
|
||||
#include <SFML/System/String.hpp>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define GD_DEPRECATED __attribute__((deprecated))
|
||||
|
36
Core/GDCore/Events/Builtin/AsyncEvent.cpp
Normal file
36
Core/GDCore/Events/Builtin/AsyncEvent.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#include "AsyncEvent.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gd {
|
||||
|
||||
AsyncEvent::AsyncEvent() : BaseEvent() {}
|
||||
|
||||
AsyncEvent::~AsyncEvent(){};
|
||||
|
||||
vector<const gd::InstructionsList *> AsyncEvent::GetAllActionsVectors() const {
|
||||
vector<const gd::InstructionsList *> allActions;
|
||||
allActions.push_back(&actions);
|
||||
|
||||
return allActions;
|
||||
}
|
||||
|
||||
vector<gd::InstructionsList *> AsyncEvent::GetAllActionsVectors() {
|
||||
vector<gd::InstructionsList *> allActions;
|
||||
allActions.push_back(&actions);
|
||||
|
||||
return allActions;
|
||||
}
|
||||
|
||||
} // namespace gd
|
61
Core/GDCore/Events/Builtin/AsyncEvent.h
Normal file
61
Core/GDCore/Events/Builtin/AsyncEvent.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef GDCORE_ASYNCEVENT_H
|
||||
#define GDCORE_ASYNCEVENT_H
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/Events/InstructionsList.h"
|
||||
namespace gd {
|
||||
class Instruction;
|
||||
class Project;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Internal event for asynchronous actions.
|
||||
* This event gets added internally to the events tree when an
|
||||
* asynchronous action is used.
|
||||
*/
|
||||
class GD_CORE_API AsyncEvent : public gd::BaseEvent {
|
||||
public:
|
||||
AsyncEvent();
|
||||
AsyncEvent(const gd::Instruction &asyncAction_,
|
||||
const gd::InstructionsList &actions_,
|
||||
const gd::EventsList &subEvents_)
|
||||
: asyncAction(asyncAction_), actions(actions_), subEvents(subEvents_) {
|
||||
SetType("BuiltinAsync::Async");
|
||||
};
|
||||
virtual ~AsyncEvent();
|
||||
virtual gd::AsyncEvent *Clone() const { return new AsyncEvent(*this); }
|
||||
|
||||
virtual bool IsExecutable() const { return true; }
|
||||
|
||||
virtual bool CanHaveSubEvents() const { return true; }
|
||||
virtual const gd::EventsList &GetSubEvents() const { return subEvents; };
|
||||
virtual gd::EventsList &GetSubEvents() { return subEvents; };
|
||||
|
||||
const gd::InstructionsList &GetActions() const { return actions; };
|
||||
gd::InstructionsList &GetActions() { return actions; };
|
||||
|
||||
const gd::Instruction &GetInstruction() const { return asyncAction; };
|
||||
gd::Instruction &GetInstruction() { return asyncAction; };
|
||||
|
||||
virtual std::vector<const gd::InstructionsList *>
|
||||
GetAllActionsVectors() const;
|
||||
virtual std::vector<gd::InstructionsList *> GetAllActionsVectors();
|
||||
|
||||
private:
|
||||
gd::Instruction asyncAction;
|
||||
gd::InstructionsList actions;
|
||||
EventsList subEvents;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_STANDARDEVENT_H
|
@@ -63,8 +63,12 @@ void StandardEvent::UnserializeFrom(gd::Project& project,
|
||||
project, conditions, element.GetChild("conditions", 0, "Conditions"));
|
||||
gd::EventsListSerialization::UnserializeInstructionsFrom(
|
||||
project, actions, element.GetChild("actions", 0, "Actions"));
|
||||
gd::EventsListSerialization::UnserializeEventsFrom(
|
||||
project, events, element.GetChild("events", 0, "Events"));
|
||||
|
||||
events.Clear();
|
||||
if (element.HasChild("events", "Events")) {
|
||||
gd::EventsListSerialization::UnserializeEventsFrom(
|
||||
project, events, element.GetChild("events", 0, "Events"));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -4,7 +4,9 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/Tools/EventsCodeNameMangler.h"
|
||||
@@ -14,7 +16,7 @@ using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void EventsCodeGenerationContext::InheritsFrom(
|
||||
const EventsCodeGenerationContext& parent_) {
|
||||
EventsCodeGenerationContext& parent_) {
|
||||
parent = &parent_;
|
||||
|
||||
// Objects lists declared by parent became "already declared" in the child
|
||||
@@ -24,8 +26,8 @@ void EventsCodeGenerationContext::InheritsFrom(
|
||||
parent_.objectsListsToBeDeclared.end(),
|
||||
std::inserter(alreadyDeclaredObjectsLists,
|
||||
alreadyDeclaredObjectsLists.begin()));
|
||||
std::copy(parent_.objectsListsWithoutPickingToBeDeclared.begin(),
|
||||
parent_.objectsListsWithoutPickingToBeDeclared.end(),
|
||||
std::copy(parent_.objectsListsOrEmptyToBeDeclared.begin(),
|
||||
parent_.objectsListsOrEmptyToBeDeclared.end(),
|
||||
std::inserter(alreadyDeclaredObjectsLists,
|
||||
alreadyDeclaredObjectsLists.begin()));
|
||||
std::copy(parent_.emptyObjectsListsToBeDeclared.begin(),
|
||||
@@ -33,6 +35,8 @@ void EventsCodeGenerationContext::InheritsFrom(
|
||||
std::inserter(alreadyDeclaredObjectsLists,
|
||||
alreadyDeclaredObjectsLists.begin()));
|
||||
|
||||
nearestAsyncParent = parent_.IsAsyncCallback() ? &parent_ : parent_.nearestAsyncParent;
|
||||
asyncDepth = parent_.asyncDepth;
|
||||
depthOfLastUse = parent_.depthOfLastUse;
|
||||
customConditionDepth = parent_.customConditionDepth;
|
||||
contextDepth = parent_.GetContextDepth() + 1;
|
||||
@@ -42,33 +46,59 @@ void EventsCodeGenerationContext::InheritsFrom(
|
||||
}
|
||||
}
|
||||
|
||||
void EventsCodeGenerationContext::InheritsAsAsyncCallbackFrom(
|
||||
EventsCodeGenerationContext& parent_) {
|
||||
// Increasing the async depth is enough to mark the context as an async callback.
|
||||
InheritsFrom(parent_);
|
||||
asyncDepth = parent_.asyncDepth + 1;
|
||||
}
|
||||
|
||||
void EventsCodeGenerationContext::Reuse(
|
||||
const EventsCodeGenerationContext& parent_) {
|
||||
EventsCodeGenerationContext& parent_) {
|
||||
InheritsFrom(parent_);
|
||||
if (parent_.CanReuse())
|
||||
contextDepth = parent_.GetContextDepth(); // Keep same context depth
|
||||
}
|
||||
|
||||
void EventsCodeGenerationContext::NotifyAsyncParentsAboutDeclaredObject(const gd::String& objectName) {
|
||||
gd::EventsCodeGenerationContext* asyncContext = IsAsyncCallback() ? this : nearestAsyncParent;
|
||||
for (;
|
||||
asyncContext != nullptr;
|
||||
asyncContext = asyncContext->parent->nearestAsyncParent)
|
||||
asyncContext->allObjectsListToBeDeclaredAcrossChildren.insert(objectName);
|
||||
}
|
||||
|
||||
void EventsCodeGenerationContext::ObjectsListNeeded(
|
||||
const gd::String& objectName) {
|
||||
if (!IsToBeDeclared(objectName))
|
||||
if (!IsToBeDeclared(objectName)) {
|
||||
objectsListsToBeDeclared.insert(objectName);
|
||||
|
||||
if (IsInsideAsync()) {
|
||||
NotifyAsyncParentsAboutDeclaredObject(objectName);
|
||||
}
|
||||
}
|
||||
|
||||
depthOfLastUse[objectName] = GetContextDepth();
|
||||
}
|
||||
|
||||
void EventsCodeGenerationContext::ObjectsListWithoutPickingNeeded(
|
||||
void EventsCodeGenerationContext::ObjectsListNeededOrEmptyIfJustDeclared(
|
||||
const gd::String& objectName) {
|
||||
if (!IsToBeDeclared(objectName))
|
||||
objectsListsWithoutPickingToBeDeclared.insert(objectName);
|
||||
if (!IsToBeDeclared(objectName)) {
|
||||
objectsListsOrEmptyToBeDeclared.insert(objectName);
|
||||
|
||||
if (IsInsideAsync()) {
|
||||
NotifyAsyncParentsAboutDeclaredObject(objectName);
|
||||
}
|
||||
}
|
||||
|
||||
depthOfLastUse[objectName] = GetContextDepth();
|
||||
}
|
||||
|
||||
void EventsCodeGenerationContext::EmptyObjectsListNeeded(
|
||||
const gd::String& objectName) {
|
||||
if (!IsToBeDeclared(objectName))
|
||||
if (!IsToBeDeclared(objectName)) {
|
||||
emptyObjectsListsToBeDeclared.insert(objectName);
|
||||
}
|
||||
|
||||
depthOfLastUse[objectName] = GetContextDepth();
|
||||
}
|
||||
@@ -77,8 +107,8 @@ std::set<gd::String> EventsCodeGenerationContext::GetAllObjectsToBeDeclared()
|
||||
const {
|
||||
std::set<gd::String> allObjectListsToBeDeclared(
|
||||
objectsListsToBeDeclared.begin(), objectsListsToBeDeclared.end());
|
||||
allObjectListsToBeDeclared.insert(objectsListsWithoutPickingToBeDeclared.begin(),
|
||||
objectsListsWithoutPickingToBeDeclared.end());
|
||||
allObjectListsToBeDeclared.insert(objectsListsOrEmptyToBeDeclared.begin(),
|
||||
objectsListsOrEmptyToBeDeclared.end());
|
||||
allObjectListsToBeDeclared.insert(emptyObjectsListsToBeDeclared.begin(),
|
||||
emptyObjectsListsToBeDeclared.end());
|
||||
|
||||
@@ -102,4 +132,21 @@ bool EventsCodeGenerationContext::IsSameObjectsList(
|
||||
otherContext.GetLastDepthObjectListWasNeeded(objectName);
|
||||
}
|
||||
|
||||
bool EventsCodeGenerationContext::ShouldUseAsyncObjectsList(
|
||||
const gd::String& objectName) const {
|
||||
if (!IsInsideAsync()) return false;
|
||||
|
||||
// Check if the objects list was used after (or in) the nearest async callback context.
|
||||
const gd::EventsCodeGenerationContext* asyncContext = IsAsyncCallback() ? this : nearestAsyncParent;
|
||||
if (parent->GetLastDepthObjectListWasNeeded(objectName) >= asyncContext->GetContextDepth()) {
|
||||
// The object was used in a context after (or in) the nearest async parent context, so we're not getting it from the
|
||||
// async object lists (it was already gotten from there in this previous context).
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the objects list is declared in a parent of the nearest async context, it means
|
||||
// the async context had to use an async objects list to access it.
|
||||
return asyncContext->ObjectAlreadyDeclaredByParents(objectName);
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
@@ -33,11 +34,7 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
* updated to contain the maximal scope depth reached.
|
||||
*/
|
||||
EventsCodeGenerationContext(unsigned int* maxDepthLevel_ = nullptr)
|
||||
: contextDepth(0),
|
||||
customConditionDepth(0),
|
||||
maxDepthLevel(maxDepthLevel_),
|
||||
parent(NULL),
|
||||
reuseExplicitlyForbidden(false){};
|
||||
: maxDepthLevel(maxDepthLevel_){};
|
||||
virtual ~EventsCodeGenerationContext(){};
|
||||
|
||||
/**
|
||||
@@ -45,7 +42,13 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
* another one. The child will then for example not declare again objects
|
||||
* already declared by its parent.
|
||||
*/
|
||||
void InheritsFrom(const EventsCodeGenerationContext& parent);
|
||||
void InheritsFrom(EventsCodeGenerationContext& parent);
|
||||
|
||||
/**
|
||||
* Call this method to make an EventsCodeGenerationContext as a "child" of
|
||||
* another one, but in the context of an async function.
|
||||
*/
|
||||
void InheritsAsAsyncCallbackFrom(EventsCodeGenerationContext& parent);
|
||||
|
||||
/**
|
||||
* \brief As InheritsFrom, mark the context as being the child of another one,
|
||||
@@ -53,7 +56,7 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
*
|
||||
* Used for example for optimizing the last event of a list.
|
||||
*/
|
||||
void Reuse(const EventsCodeGenerationContext& parent);
|
||||
void Reuse(EventsCodeGenerationContext& parent);
|
||||
|
||||
/**
|
||||
* \brief Forbid any optimization that would reuse and modify the object list
|
||||
@@ -88,19 +91,19 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
const EventsCodeGenerationContext* GetParentContext() const { return parent; }
|
||||
|
||||
/**
|
||||
* Mark the object has being the object being handled by the instruction
|
||||
* Mark the object as being the object being handled by the instruction.
|
||||
*/
|
||||
void SetCurrentObject(const gd::String& objectName) {
|
||||
currentObject = objectName;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set that no particular object is being handled by an instruction
|
||||
* Set that no particular object is being handled by an instruction.
|
||||
*/
|
||||
void SetNoCurrentObject() { currentObject = ""; };
|
||||
|
||||
/**
|
||||
* Get the object being handled by the instruction
|
||||
* Get the object being handled by the instruction.
|
||||
*/
|
||||
const gd::String& GetCurrentObject() const { return currentObject; };
|
||||
|
||||
@@ -109,7 +112,7 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
*
|
||||
* The list will be filled with objects from the scene if it is the first time
|
||||
* it is requested, unless there is already an object list with this name
|
||||
* (i.e. `ObjectAlreadyDeclared(objectName)` returns true).
|
||||
* (i.e. `ObjectAlreadyDeclaredByParents(objectName)` returns true).
|
||||
*/
|
||||
void ObjectsListNeeded(const gd::String& objectName);
|
||||
|
||||
@@ -121,7 +124,7 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
* from the scene. If there is already an objects list with this name, no new
|
||||
* list will be declared again.
|
||||
*/
|
||||
void ObjectsListWithoutPickingNeeded(const gd::String& objectName);
|
||||
void ObjectsListNeededOrEmptyIfJustDeclared(const gd::String& objectName);
|
||||
|
||||
/**
|
||||
* Call this when an instruction in the event needs an empty object list,
|
||||
@@ -134,29 +137,21 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
void EmptyObjectsListNeeded(const gd::String& objectName);
|
||||
|
||||
/**
|
||||
* Return true if an object list has already been declared (or is going to be
|
||||
* declared).
|
||||
* Return true if an object list has already been declared by the parent contexts.
|
||||
*/
|
||||
bool ObjectAlreadyDeclared(const gd::String& objectName) const {
|
||||
bool ObjectAlreadyDeclaredByParents(const gd::String& objectName) const {
|
||||
return (alreadyDeclaredObjectsLists.find(objectName) !=
|
||||
alreadyDeclaredObjectsLists.end());
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Consider that \a objectName is now declared in the context.
|
||||
*/
|
||||
void SetObjectDeclared(const gd::String& objectName) {
|
||||
alreadyDeclaredObjectsLists.insert(objectName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the objects lists which will be declared by the current context
|
||||
* ( the non empty as well as the empty objects lists )
|
||||
* (normal, potentially empty or empty).
|
||||
*/
|
||||
std::set<gd::String> GetAllObjectsToBeDeclared() const;
|
||||
|
||||
/**
|
||||
* Return the objects lists which will be declared by the current context
|
||||
* Return the objects lists which will be declared by the current context.
|
||||
*/
|
||||
const std::set<gd::String>& GetObjectsListsToBeDeclared() const {
|
||||
return objectsListsToBeDeclared;
|
||||
@@ -166,9 +161,9 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
* Return the objects lists which will be will be declared, without filling
|
||||
* them with objects from the scene.
|
||||
*/
|
||||
const std::set<gd::String>& GetObjectsListsToBeDeclaredWithoutPicking()
|
||||
const std::set<gd::String>& GetObjectsListsToBeEmptyIfJustDeclared()
|
||||
const {
|
||||
return objectsListsWithoutPickingToBeDeclared;
|
||||
return objectsListsOrEmptyToBeDeclared;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -184,7 +179,7 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
* Return the objects lists which are already declared and can be used in the
|
||||
* current context without declaration.
|
||||
*/
|
||||
const std::set<gd::String>& GetObjectsListsAlreadyDeclared() const {
|
||||
const std::set<gd::String>& GetObjectsListsAlreadyDeclaredByParents() const {
|
||||
return alreadyDeclaredObjectsLists;
|
||||
};
|
||||
|
||||
@@ -227,22 +222,55 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
*/
|
||||
size_t GetCurrentConditionDepth() const { return customConditionDepth; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* \brief Returns the list of all objects declared in this context
|
||||
* and subcontexts.
|
||||
* \warning Only works on an async callback's context.
|
||||
*
|
||||
* It is to be used by the Async event code generator to know what objects
|
||||
* lists to backup for the async callback and async callbacks after it.
|
||||
*/
|
||||
const std::set<gd::String>& GetAllDeclaredObjectsAcrossChildren() {
|
||||
return allObjectsListToBeDeclaredAcrossChildren;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if an object list should be gotten from a backed up
|
||||
* objects list instead of the parent context. This can happen inside an
|
||||
* asynchronous callback or a child context of an asynchronous callback (i.e:
|
||||
* the `asyncDepth` is not 0).
|
||||
*/
|
||||
bool ShouldUseAsyncObjectsList(const gd::String& objectName) const;
|
||||
|
||||
/**
|
||||
* Returns true if the code currently being generated is inside an
|
||||
* asynchronous context (either in an asynchronous callback, or in a children of
|
||||
* an asynchronous callback).
|
||||
*/
|
||||
bool IsInsideAsync() const { return asyncDepth != 0; };
|
||||
|
||||
/**
|
||||
* Returns true if the code currently being generated is an asynchronous
|
||||
* callback (but not a child of an asynchronous callback).
|
||||
*/
|
||||
bool IsAsyncCallback() const { return parent != nullptr && parent->asyncDepth != asyncDepth; }
|
||||
|
||||
/**
|
||||
* \brief Returns true if the given object is already going to be declared
|
||||
* (either as a traditional objects list, or one without picking, or one
|
||||
* empty).
|
||||
*
|
||||
* in this context (either as a traditional objects list, or an empty one).
|
||||
*/
|
||||
bool IsToBeDeclared(const gd::String& objectName) {
|
||||
return objectsListsToBeDeclared.find(objectName) !=
|
||||
objectsListsToBeDeclared.end() ||
|
||||
objectsListsWithoutPickingToBeDeclared.find(objectName) !=
|
||||
objectsListsWithoutPickingToBeDeclared.end() ||
|
||||
objectsListsOrEmptyToBeDeclared.find(objectName) !=
|
||||
objectsListsOrEmptyToBeDeclared.end() ||
|
||||
emptyObjectsListsToBeDeclared.find(objectName) !=
|
||||
emptyObjectsListsToBeDeclared.end();
|
||||
};
|
||||
|
||||
private:
|
||||
void NotifyAsyncParentsAboutDeclaredObject(const gd::String& objectName);
|
||||
|
||||
std::set<gd::String>
|
||||
alreadyDeclaredObjectsLists; ///< Objects lists already needed in a
|
||||
///< parent context.
|
||||
@@ -250,7 +278,7 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
objectsListsToBeDeclared; ///< Objects lists that will be declared in
|
||||
///< this context.
|
||||
std::set<gd::String>
|
||||
objectsListsWithoutPickingToBeDeclared; ///< Objects lists that will be
|
||||
objectsListsOrEmptyToBeDeclared; ///< Objects lists that will be
|
||||
///< declared in this context,
|
||||
///< but not filled with scene's
|
||||
///< objects.
|
||||
@@ -260,21 +288,40 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
///< but not filled with scene's
|
||||
///< objects and not filled with any
|
||||
///< previously existing objects list.
|
||||
std::set<gd::String>
|
||||
allObjectsListToBeDeclaredAcrossChildren; ///< This is only to be used by
|
||||
///< the async callback
|
||||
///< contexts to know all
|
||||
///< objects declared across
|
||||
///< all children, so that the
|
||||
///< necessary objects can be
|
||||
///< backed up.
|
||||
|
||||
std::map<gd::String, unsigned int>
|
||||
depthOfLastUse; ///< The context depth when an object was last used.
|
||||
gd::String
|
||||
currentObject; ///< The object being used by an action or condition.
|
||||
unsigned int contextDepth; ///< The depth of the context : 0 for a newly
|
||||
///< created context, n+1 for any context
|
||||
///< inheriting from context with depth n.
|
||||
unsigned int
|
||||
customConditionDepth; ///< The depth of the conditions being generated.
|
||||
unsigned int contextDepth = 0; ///< The depth of the context: 0 for a newly
|
||||
///< created context, n+1 for any context
|
||||
///< inheriting from context with depth n.
|
||||
unsigned int customConditionDepth =
|
||||
0; ///< The depth of the conditions being generated.
|
||||
unsigned int asyncDepth =
|
||||
0; ///< If higher than 0, the current context is an asynchronous callback,
|
||||
///< or a child context of an asynchronous callback:
|
||||
///< - If the parent's async depth != the current context async depth,
|
||||
///< then the current context is an asynchronous callback context.
|
||||
///< - Otherwise, it's a child of an asynchronous callback.
|
||||
unsigned int* maxDepthLevel; ///< A pointer to a unsigned int updated with
|
||||
///< the maximum depth reached.
|
||||
const EventsCodeGenerationContext*
|
||||
parent; ///< The parent of the current context. Can be NULL.
|
||||
bool reuseExplicitlyForbidden; ///< If set to true, forbid children context
|
||||
///< to reuse this one without inheriting.
|
||||
const EventsCodeGenerationContext* parent =
|
||||
nullptr; ///< The parent of the current context. Can be NULL.
|
||||
EventsCodeGenerationContext* nearestAsyncParent =
|
||||
nullptr; ///< The nearest parent context that is an async callback
|
||||
///< context.
|
||||
bool reuseExplicitlyForbidden =
|
||||
false; ///< If set to true, forbid children contexts
|
||||
///< to reuse this one without inheriting.
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -450,7 +450,9 @@ gd::String EventsCodeGenerator::GenerateConditionsListCode(
|
||||
* Generate code for an action.
|
||||
*/
|
||||
gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
gd::Instruction& action, EventsCodeGenerationContext& context) {
|
||||
gd::Instruction& action,
|
||||
EventsCodeGenerationContext& context,
|
||||
const gd::String& optionalAsyncCallbackName) {
|
||||
gd::String actionCode;
|
||||
|
||||
const gd::InstructionMetadata& instrInfos =
|
||||
@@ -518,8 +520,12 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
// Prepare arguments and generate the whole action code
|
||||
vector<gd::String> arguments = GenerateParametersCodes(
|
||||
action.GetParameters(), instrInfos.parameters, context);
|
||||
actionCode += GenerateObjectAction(
|
||||
realObjects[i], objInfo, arguments, instrInfos, context);
|
||||
actionCode += GenerateObjectAction(realObjects[i],
|
||||
objInfo,
|
||||
arguments,
|
||||
instrInfos,
|
||||
context,
|
||||
optionalAsyncCallbackName);
|
||||
|
||||
context.SetNoCurrentObject();
|
||||
}
|
||||
@@ -552,7 +558,8 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
autoInfo,
|
||||
arguments,
|
||||
instrInfos,
|
||||
context);
|
||||
context,
|
||||
optionalAsyncCallbackName);
|
||||
|
||||
context.SetNoCurrentObject();
|
||||
}
|
||||
@@ -560,12 +567,72 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
} else {
|
||||
vector<gd::String> arguments = GenerateParametersCodes(
|
||||
action.GetParameters(), instrInfos.parameters, context);
|
||||
actionCode += GenerateFreeAction(arguments, instrInfos, context);
|
||||
actionCode +=
|
||||
GenerateFreeAction(arguments, instrInfos, context, optionalAsyncCallbackName);
|
||||
}
|
||||
|
||||
return actionCode;
|
||||
}
|
||||
|
||||
const EventsCodeGenerator::CallbackDescriptor
|
||||
EventsCodeGenerator::GenerateCallback(
|
||||
const gd::String& callbackID,
|
||||
gd::EventsCodeGenerationContext& parentContext,
|
||||
gd::InstructionsList& actions,
|
||||
gd::EventsList* subEvents) {
|
||||
gd::EventsCodeGenerationContext callbackContext;
|
||||
callbackContext.InheritsAsAsyncCallbackFrom(parentContext);
|
||||
const gd::String callbackFunctionName =
|
||||
GetCodeNamespaceAccessor() + "asyncCallback" + callbackID;
|
||||
const gd::String callbackFunctionArguments =
|
||||
GenerateEventsParameters(callbackContext);
|
||||
|
||||
// Generate actions
|
||||
gd::String actionsCode = GenerateActionsListCode(actions, callbackContext);
|
||||
|
||||
// Generate subevents
|
||||
if (subEvents != nullptr) // Sub events
|
||||
{
|
||||
actionsCode += "\n{ //Subevents\n";
|
||||
actionsCode += GenerateEventsListCode(*subEvents, callbackContext);
|
||||
actionsCode += "} //End of subevents\n";
|
||||
}
|
||||
|
||||
// Compose the callback function and add outside main
|
||||
const gd::String actionsDeclarationsCode =
|
||||
GenerateObjectsDeclarationCode(callbackContext);
|
||||
|
||||
const gd::String callbackCode = callbackFunctionName + " = function (" +
|
||||
GenerateEventsParameters(callbackContext) +
|
||||
") {\n" + actionsDeclarationsCode +
|
||||
actionsCode + "}\n";
|
||||
|
||||
AddCustomCodeOutsideMain(callbackCode);
|
||||
|
||||
std::set<gd::String> requiredObjects;
|
||||
// Build the list of all objects required by the callback. Any object that has
|
||||
// already been declared could have gone through previous object picking, so
|
||||
// if such an object is used by the actions or subevents of this callback, we
|
||||
// must ask the caller to pass the already existing objects lists through a
|
||||
// `LongLivedObjectsList` to the callback function.
|
||||
for (const auto& objectUsedInSubTree :
|
||||
callbackContext.GetAllDeclaredObjectsAcrossChildren()) {
|
||||
if (callbackContext.ObjectAlreadyDeclaredByParents(objectUsedInSubTree))
|
||||
requiredObjects.insert(objectUsedInSubTree);
|
||||
};
|
||||
|
||||
return CallbackDescriptor(
|
||||
callbackFunctionName, callbackFunctionArguments, requiredObjects);
|
||||
};
|
||||
|
||||
const gd::String EventsCodeGenerator::GenerateEventsParameters(
|
||||
const gd::EventsCodeGenerationContext& context) {
|
||||
gd::String parameters = "runtimeScene";
|
||||
if (!HasProjectAndLayout()) parameters += ", eventsFunctionContext";
|
||||
if (context.IsInsideAsync()) parameters += ", asyncObjectsList";
|
||||
return parameters;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate actions code.
|
||||
*/
|
||||
@@ -743,23 +810,21 @@ gd::String EventsCodeGenerator::GenerateObjectsDeclarationCode(
|
||||
gd::String declarationsCode;
|
||||
for (auto object : context.GetObjectsListsToBeDeclared()) {
|
||||
gd::String objectListDeclaration = "";
|
||||
if (!context.ObjectAlreadyDeclared(object)) {
|
||||
if (!context.ObjectAlreadyDeclaredByParents(object)) {
|
||||
objectListDeclaration = "std::vector<RuntimeObject*> " +
|
||||
GetObjectListName(object, context) +
|
||||
" = runtimeContext->GetObjectsRawPointers(\"" +
|
||||
ConvertToString(object) + "\");\n";
|
||||
context.SetObjectDeclared(object);
|
||||
} else
|
||||
objectListDeclaration = declareObjectList(object, context);
|
||||
|
||||
declarationsCode += objectListDeclaration + "\n";
|
||||
}
|
||||
for (auto object : context.GetObjectsListsToBeDeclaredWithoutPicking()) {
|
||||
for (auto object : context.GetObjectsListsToBeEmptyIfJustDeclared()) {
|
||||
gd::String objectListDeclaration = "";
|
||||
if (!context.ObjectAlreadyDeclared(object)) {
|
||||
if (!context.ObjectAlreadyDeclaredByParents(object)) {
|
||||
objectListDeclaration = "std::vector<RuntimeObject*> " +
|
||||
GetObjectListName(object, context) + ";\n";
|
||||
context.SetObjectDeclared(object);
|
||||
} else
|
||||
objectListDeclaration = declareObjectList(object, context);
|
||||
|
||||
@@ -767,10 +832,9 @@ gd::String EventsCodeGenerator::GenerateObjectsDeclarationCode(
|
||||
}
|
||||
for (auto object : context.GetObjectsListsToBeDeclaredEmpty()) {
|
||||
gd::String objectListDeclaration = "";
|
||||
if (!context.ObjectAlreadyDeclared(object)) {
|
||||
if (!context.ObjectAlreadyDeclaredByParents(object)) {
|
||||
objectListDeclaration = "std::vector<RuntimeObject*> " +
|
||||
GetObjectListName(object, context) + ";\n";
|
||||
context.SetObjectDeclared(object);
|
||||
} else
|
||||
objectListDeclaration = "std::vector<RuntimeObject*> " +
|
||||
GetObjectListName(object, context) + ";\n";
|
||||
@@ -785,7 +849,7 @@ gd::String EventsCodeGenerator::GenerateObjectsDeclarationCode(
|
||||
* Generate events list code.
|
||||
*/
|
||||
gd::String EventsCodeGenerator::GenerateEventsListCode(
|
||||
gd::EventsList& events, const EventsCodeGenerationContext& parentContext) {
|
||||
gd::EventsList& events, EventsCodeGenerationContext& parentContext) {
|
||||
gd::String output;
|
||||
for (std::size_t eId = 0; eId < events.size(); ++eId) {
|
||||
// Each event has its own context : Objects picked in an event are totally
|
||||
@@ -801,6 +865,8 @@ gd::String EventsCodeGenerator::GenerateEventsListCode(
|
||||
// operation.
|
||||
bool reuseParentContext =
|
||||
parentContext.CanReuse() && eId == events.size() - 1;
|
||||
|
||||
// TODO: avoid creating if useless.
|
||||
gd::EventsCodeGenerationContext reusedContext;
|
||||
reusedContext.Reuse(parentContext);
|
||||
|
||||
@@ -1015,7 +1081,8 @@ gd::String EventsCodeGenerator::GenerateBehaviorCondition(
|
||||
gd::String EventsCodeGenerator::GenerateFreeAction(
|
||||
const std::vector<gd::String>& arguments,
|
||||
const gd::InstructionMetadata& instrInfos,
|
||||
gd::EventsCodeGenerationContext& context) {
|
||||
gd::EventsCodeGenerationContext& context,
|
||||
const gd::String& optionalAsyncCallbackName) {
|
||||
// Generate call
|
||||
gd::String call;
|
||||
if (instrInfos.codeExtraInformation.type == "number" ||
|
||||
@@ -1042,6 +1109,11 @@ gd::String EventsCodeGenerator::GenerateFreeAction(
|
||||
call = instrInfos.codeExtraInformation.functionCallName + "(" +
|
||||
GenerateArgumentsList(arguments) + ")";
|
||||
}
|
||||
|
||||
if (!optionalAsyncCallbackName.empty())
|
||||
call = "runtimeScene.getAsyncTasksManager().addTask(" + call + ", " +
|
||||
optionalAsyncCallbackName + ")";
|
||||
|
||||
return call + ";\n";
|
||||
}
|
||||
|
||||
@@ -1050,7 +1122,8 @@ gd::String EventsCodeGenerator::GenerateObjectAction(
|
||||
const gd::ObjectMetadata& objInfo,
|
||||
const std::vector<gd::String>& arguments,
|
||||
const gd::InstructionMetadata& instrInfos,
|
||||
gd::EventsCodeGenerationContext& context) {
|
||||
gd::EventsCodeGenerationContext& context,
|
||||
const gd::String& optionalAsyncCallbackName) {
|
||||
// Create call
|
||||
gd::String call;
|
||||
if ((instrInfos.codeExtraInformation.type == "number" ||
|
||||
@@ -1077,8 +1150,11 @@ gd::String EventsCodeGenerator::GenerateObjectAction(
|
||||
|
||||
call = instrInfos.codeExtraInformation.functionCallName + "(" +
|
||||
argumentsStr + ")";
|
||||
|
||||
return "For each picked object \"" + objectName + "\", call " + call + "(" +
|
||||
argumentsStr + ").\n";
|
||||
argumentsStr + ")" +
|
||||
(optionalAsyncCallbackName.empty() ? "" : (", then call" + optionalAsyncCallbackName)) +
|
||||
".\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1088,7 +1164,8 @@ gd::String EventsCodeGenerator::GenerateBehaviorAction(
|
||||
const gd::BehaviorMetadata& autoInfo,
|
||||
const std::vector<gd::String>& arguments,
|
||||
const gd::InstructionMetadata& instrInfos,
|
||||
gd::EventsCodeGenerationContext& context) {
|
||||
gd::EventsCodeGenerationContext& context,
|
||||
const gd::String& optionalAsyncCallbackName) {
|
||||
// Create call
|
||||
gd::String call;
|
||||
if ((instrInfos.codeExtraInformation.type == "number" ||
|
||||
@@ -1114,8 +1191,11 @@ gd::String EventsCodeGenerator::GenerateBehaviorAction(
|
||||
|
||||
call = instrInfos.codeExtraInformation.functionCallName + "(" +
|
||||
argumentsStr + ")";
|
||||
|
||||
return "For each picked object \"" + objectName + "\", call " + call + "(" +
|
||||
argumentsStr + ")" + " for behavior \"" + behaviorName + "\".\n";
|
||||
argumentsStr + ")" + " for behavior \"" + behaviorName + "\"" +
|
||||
(optionalAsyncCallbackName.empty() ? "" : (", then call" + optionalAsyncCallbackName)) +
|
||||
".\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -77,7 +77,7 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
* \return Code
|
||||
*/
|
||||
virtual gd::String GenerateEventsListCode(
|
||||
gd::EventsList& events, const EventsCodeGenerationContext& context);
|
||||
gd::EventsList& events, EventsCodeGenerationContext& context);
|
||||
|
||||
/**
|
||||
* \brief Generate code for executing a condition list
|
||||
@@ -155,7 +155,51 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
* \return Code
|
||||
*/
|
||||
gd::String GenerateActionCode(gd::Instruction& action,
|
||||
EventsCodeGenerationContext& context);
|
||||
EventsCodeGenerationContext& context,
|
||||
const gd::String& optionalAsyncCallbackName = "");
|
||||
|
||||
struct CallbackDescriptor {
|
||||
CallbackDescriptor(const gd::String functionName_,
|
||||
const gd::String argumentsList_,
|
||||
const std::set<gd::String> requiredObjects_)
|
||||
: functionName(functionName_),
|
||||
argumentsList(argumentsList_),
|
||||
requiredObjects(requiredObjects_){};
|
||||
/**
|
||||
* The name by which the function can be invoked.
|
||||
*/
|
||||
const gd::String functionName;
|
||||
/**
|
||||
* The comma separated list of arguments that the function takes.
|
||||
*/
|
||||
const gd::String argumentsList;
|
||||
/**
|
||||
* A set of all objects that need to be backed up to be passed to the callback code.
|
||||
*/
|
||||
const std::set<gd::String> requiredObjects;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Generates actions and events as a callback.
|
||||
*
|
||||
* This is used by asynchronous functions to run the code out of the normal
|
||||
* events flow.
|
||||
*
|
||||
* \returns A set with all objects required by the callback code.
|
||||
* The caller must take care of backing them up in a LongLivedObjectsList,
|
||||
* and to pass it to the callback function as the last argument.
|
||||
*/
|
||||
virtual const CallbackDescriptor GenerateCallback(
|
||||
const gd::String& callbackFunctionName,
|
||||
gd::EventsCodeGenerationContext& parentContext,
|
||||
gd::InstructionsList& actions,
|
||||
gd::EventsList* subEvents = nullptr);
|
||||
|
||||
/**
|
||||
* \brief Generates the parameters list of an event's generated function.
|
||||
*/
|
||||
const gd::String GenerateEventsParameters(
|
||||
const gd::EventsCodeGenerationContext& context);
|
||||
|
||||
/**
|
||||
* \brief Generate code for declaring objects lists.
|
||||
@@ -462,17 +506,10 @@ 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. Example:
|
||||
* \code
|
||||
AddExpression("Count", _("Object count"), _("Count the number of picked
|
||||
objects"), _("Objects"), "res/conditions/nbObjet.png")
|
||||
.AddParameter("objectList", _("Object"))
|
||||
.SetFunctionName("getPickedObjectsCount");
|
||||
|
||||
* \endcode
|
||||
* - objectListWithoutPicking : Same as objectList but do not pick object if
|
||||
object name in another parameter.
|
||||
* - objectListOrEmptyIfJustDeclared : Same as `objectList` but do not pick object if
|
||||
they are not already picked.
|
||||
* - objectPtr : Return a reference to the object specified by the object name in
|
||||
* - objectPtr: Return a reference to the object specified by the object name in
|
||||
another parameter. Example:
|
||||
* \code
|
||||
.AddParameter("object", _("Object"))
|
||||
@@ -665,14 +702,16 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
virtual gd::String GenerateFreeAction(
|
||||
const std::vector<gd::String>& arguments,
|
||||
const gd::InstructionMetadata& instrInfos,
|
||||
gd::EventsCodeGenerationContext& context);
|
||||
gd::EventsCodeGenerationContext& context,
|
||||
const gd::String& optionalAsyncCallbackName = "");
|
||||
|
||||
virtual gd::String GenerateObjectAction(
|
||||
const gd::String& objectName,
|
||||
const gd::ObjectMetadata& objInfo,
|
||||
const std::vector<gd::String>& arguments,
|
||||
const gd::InstructionMetadata& instrInfos,
|
||||
gd::EventsCodeGenerationContext& context);
|
||||
gd::EventsCodeGenerationContext& context,
|
||||
const gd::String& optionalAsyncCallbackName = "");
|
||||
|
||||
virtual gd::String GenerateBehaviorAction(
|
||||
const gd::String& objectName,
|
||||
@@ -680,7 +719,8 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
const gd::BehaviorMetadata& autoInfo,
|
||||
const std::vector<gd::String>& arguments,
|
||||
const gd::InstructionMetadata& instrInfos,
|
||||
gd::EventsCodeGenerationContext& context);
|
||||
gd::EventsCodeGenerationContext& context,
|
||||
const gd::String& optionalAsyncCallbackName = "");
|
||||
|
||||
gd::String GenerateRelationalOperatorCall(
|
||||
const gd::InstructionMetadata& instrInfos,
|
||||
|
@@ -5,8 +5,11 @@
|
||||
*/
|
||||
|
||||
#include "GDCore/Events/Event.h"
|
||||
|
||||
#include "GDCore/Events/Builtin/AsyncEvent.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
|
||||
@@ -65,10 +68,40 @@ gd::String BaseEvent::GenerateEventCode(
|
||||
return "";
|
||||
}
|
||||
|
||||
void BaseEvent::PreprocessAsyncActions(const gd::Platform& platform) {
|
||||
if (!CanHaveSubEvents()) return;
|
||||
for (const auto& actionsList : GetAllActionsVectors())
|
||||
for (std::size_t aId = 0; aId < actionsList->size(); ++aId) {
|
||||
const auto& action = actionsList->at(aId);
|
||||
const gd::InstructionMetadata& actionMetadata =
|
||||
gd::MetadataProvider::GetActionMetadata(platform, action.GetType());
|
||||
if (actionMetadata.IsAsync()) {
|
||||
gd::InstructionsList remainingActions;
|
||||
remainingActions.InsertInstructions(
|
||||
*actionsList, aId + 1, actionsList->size() - 1);
|
||||
gd::AsyncEvent asyncEvent(action, remainingActions, GetSubEvents());
|
||||
|
||||
// Ensure that the local event no longer has any of the actions/subevent
|
||||
// after the async function
|
||||
actionsList->RemoveAfter(aId);
|
||||
GetSubEvents().Clear();
|
||||
|
||||
GetSubEvents().InsertEvent(asyncEvent);
|
||||
|
||||
// We just moved all the rest, there's nothing left to do in this event.
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void BaseEvent::Preprocess(gd::EventsCodeGenerator& codeGenerator,
|
||||
gd::EventsList& eventList,
|
||||
std::size_t indexOfTheEventInThisList) {
|
||||
if (IsDisabled() || !MustBePreprocessed()) return;
|
||||
if (IsDisabled()) return;
|
||||
|
||||
PreprocessAsyncActions(codeGenerator.GetPlatform());
|
||||
|
||||
if (!MustBePreprocessed()) return;
|
||||
|
||||
try {
|
||||
if (type.empty()) return;
|
||||
|
@@ -10,6 +10,7 @@
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/Events/InstructionsList.h"
|
||||
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
|
||||
@@ -23,7 +24,7 @@ class EventsCodeGenerationContext;
|
||||
class Platform;
|
||||
class SerializerElement;
|
||||
class Instruction;
|
||||
}
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
@@ -136,13 +137,15 @@ class GD_CORE_API BaseEvent {
|
||||
* \note Used to preprocess or search in the expressions of the event.
|
||||
*/
|
||||
virtual std::vector<std::pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
GetAllExpressionsWithMetadata() {
|
||||
GetAllExpressionsWithMetadata() {
|
||||
std::vector<std::pair<gd::Expression*, gd::ParameterMetadata> > noExpr;
|
||||
return noExpr;
|
||||
};
|
||||
virtual std::vector<std::pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
GetAllExpressionsWithMetadata() const {
|
||||
std::vector<std::pair<const gd::Expression*, const gd::ParameterMetadata> > noExpr;
|
||||
virtual std::vector<
|
||||
std::pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
GetAllExpressionsWithMetadata() const {
|
||||
std::vector<std::pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
noExpr;
|
||||
return noExpr;
|
||||
};
|
||||
|
||||
@@ -206,6 +209,11 @@ class GD_CORE_API BaseEvent {
|
||||
gd::EventsList& eventList,
|
||||
std::size_t indexOfTheEventInThisList);
|
||||
|
||||
/**
|
||||
* A function that turns all async member actions into an Async subevent for code generation.
|
||||
*/
|
||||
void PreprocessAsyncActions(const gd::Platform& platform);
|
||||
|
||||
/**
|
||||
* \brief If MustBePreprocessed is redefined to return true, the
|
||||
* gd::EventMetadata::preprocessing associated to the event will be called to
|
||||
|
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "InstructionsList.h"
|
||||
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "Serialization.h"
|
||||
@@ -31,6 +32,10 @@ void InstructionsList::InsertInstructions(const InstructionsList& list,
|
||||
}
|
||||
}
|
||||
|
||||
void InstructionsList::RemoveAfter(const size_t position) {
|
||||
elements.resize(position);
|
||||
}
|
||||
|
||||
void InstructionsList::SerializeTo(SerializerElement& element) const {
|
||||
EventsListSerialization::SerializeInstructionsTo(*this, element);
|
||||
}
|
||||
|
@@ -6,9 +6,10 @@
|
||||
|
||||
#ifndef GDCORE_INSTRUCTIONSLIST_H
|
||||
#define GDCORE_INSTRUCTIONSLIST_H
|
||||
#include "GDCore/Tools/SPtrList.h"
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "GDCore/Tools/SPtrList.h"
|
||||
|
||||
namespace gd {
|
||||
class Instruction;
|
||||
}
|
||||
@@ -22,11 +23,11 @@ class SerializerElement;
|
||||
namespace gd {
|
||||
|
||||
class InstructionsList : public SPtrList<gd::Instruction> {
|
||||
public:
|
||||
void InsertInstructions(const InstructionsList& list,
|
||||
size_t begin,
|
||||
size_t end,
|
||||
size_t position = (size_t)-1);
|
||||
public:
|
||||
void InsertInstructions(const InstructionsList &list, size_t begin,
|
||||
size_t end, size_t position = (size_t)-1);
|
||||
|
||||
void RemoveAfter(size_t position);
|
||||
|
||||
/** \name Serialization
|
||||
*/
|
||||
@@ -35,17 +36,17 @@ class InstructionsList : public SPtrList<gd::Instruction> {
|
||||
* \brief Serialize the instructions to the specified element
|
||||
* \see EventsListSerialization
|
||||
*/
|
||||
void SerializeTo(gd::SerializerElement& element) const;
|
||||
void SerializeTo(gd::SerializerElement &element) const;
|
||||
|
||||
/**
|
||||
* \brief Load the instructions from the specified element
|
||||
* \see EventsListSerialization
|
||||
*/
|
||||
void UnserializeFrom(gd::Project& project,
|
||||
const gd::SerializerElement& element);
|
||||
void UnserializeFrom(gd::Project &project,
|
||||
const gd::SerializerElement &element);
|
||||
///@}
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
} // namespace gd
|
||||
|
||||
#endif
|
||||
|
@@ -218,8 +218,8 @@ void EventsListSerialization::UnserializeEventsFrom(
|
||||
event = std::make_shared<EmptyEvent>();
|
||||
}
|
||||
|
||||
event->SetDisabled(eventElem.GetBoolAttribute("disabled"));
|
||||
event->SetFolded(eventElem.GetBoolAttribute("folded"));
|
||||
event->SetDisabled(eventElem.GetBoolAttribute("disabled", false));
|
||||
event->SetFolded(eventElem.GetBoolAttribute("folded", false));
|
||||
|
||||
list.InsertEvent(event, list.GetEventsCount());
|
||||
}
|
||||
@@ -232,8 +232,8 @@ void EventsListSerialization::SerializeEventsTo(const EventsList& list,
|
||||
const gd::BaseEvent& event = list.GetEvent(j);
|
||||
SerializerElement& eventElem = events.AddChild("event");
|
||||
|
||||
eventElem.SetAttribute("disabled", event.IsDisabled());
|
||||
eventElem.SetAttribute("folded", event.IsFolded());
|
||||
if (event.IsDisabled()) eventElem.SetAttribute("disabled", event.IsDisabled());
|
||||
if (event.IsFolded()) eventElem.SetAttribute("folded", event.IsFolded());
|
||||
eventElem.AddChild("type").SetValue(event.GetType());
|
||||
|
||||
event.SerializeTo(eventElem);
|
||||
|
@@ -42,6 +42,7 @@ class GD_CORE_API BuiltinExtensionsImplementer {
|
||||
static void ImplementsTimeExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsVariablesExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsWindowExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsAsyncExtension(gd::PlatformExtension& extension);
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
32
Core/GDCore/Extensions/Builtin/AsyncExtension.cpp
Normal file
32
Core/GDCore/Extensions/Builtin/AsyncExtension.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "AllBuiltinExtensions.h"
|
||||
#include "GDCore/Events/Builtin/AsyncEvent.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAsyncExtension(
|
||||
gd::PlatformExtension &extension) {
|
||||
extension
|
||||
.SetExtensionInformation(
|
||||
"BuiltinAsync",
|
||||
_("Async functions"),
|
||||
_("Functions that defer the execution of the events after it."),
|
||||
"Arthur Pacaud (arthuro555)",
|
||||
"Open source (MIT License)")
|
||||
.SetCategory("Advanced");
|
||||
|
||||
extension.AddEvent("Async",
|
||||
_("Async event"),
|
||||
_("Internal event for asynchronous actions"),
|
||||
"",
|
||||
"res/eventaddicon.png",
|
||||
std::make_shared<gd::AsyncEvent>());
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -343,6 +343,34 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
"res/actions/music.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.MarkAsComplex();
|
||||
extension
|
||||
.AddAction(
|
||||
"FadeSoundVolume",
|
||||
_("Fade the volume of a sound played on a channel."),
|
||||
_("Fade the volume of a sound played on a channel to the specified volume within the specified duration."),
|
||||
_("Fade the sound on channel _PARAM1_ to volume _PARAM2_ within _PARAM3_ seconds"),
|
||||
_("Sounds on channels"),
|
||||
"res/actions/son24.png",
|
||||
"res/actions/son.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Channel identifier"))
|
||||
.AddParameter("expression", _("Final volume (0-100)"))
|
||||
.AddParameter("expression", _("Fading time in seconds"))
|
||||
.MarkAsAdvanced();
|
||||
extension
|
||||
.AddAction(
|
||||
"FadeMusicVolume",
|
||||
_("Fade the volume of a music played on a channel."),
|
||||
_("Fade the volume of a music played on a channel to the specified volume within the specified duration."),
|
||||
_("Fade the music on channel _PARAM1_ to volume _PARAM2_ within _PARAM3_ seconds"),
|
||||
_("Music on channels"),
|
||||
"res/actions/music24.png",
|
||||
"res/actions/music.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Channel identifier"))
|
||||
.AddParameter("expression", _("Final volume (0-100)"))
|
||||
.AddParameter("expression", _("Fading time in seconds"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddCondition("MusicPlaying",
|
||||
|
@@ -1252,7 +1252,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"res/actions/create24.png",
|
||||
"res/actions/create24.png")
|
||||
.AddCodeOnlyParameter("objectsContext", "")
|
||||
.AddParameter("objectListWithoutPicking", _("Object to create"))
|
||||
.AddParameter("objectListOrEmptyIfJustDeclared", _("Object to create"))
|
||||
.AddParameter("expression", _("X position"))
|
||||
.AddParameter("expression", _("Y position"))
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
@@ -1270,7 +1270,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"res/actions/create24.png",
|
||||
"res/actions/create24.png")
|
||||
.AddCodeOnlyParameter("objectsContext", "")
|
||||
.AddParameter("objectListWithoutPicking", _("Group of potential objects"))
|
||||
.AddParameter("objectListOrEmptyIfJustDeclared", _("Group of potential objects"))
|
||||
.SetParameterLongDescription(
|
||||
_("Group containing objects that can be created by the action."))
|
||||
.AddParameter("string", _("Name of the object to create"))
|
||||
@@ -1418,7 +1418,33 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"res/conditions/nbObjet.png")
|
||||
.AddParameter("objectList", _("Object"))
|
||||
.UseStandardRelationalOperatorParameters("number")
|
||||
.MarkAsSimple();
|
||||
.MarkAsSimple()
|
||||
.SetHidden();
|
||||
|
||||
extension.AddExpressionAndCondition(
|
||||
"number",
|
||||
"SceneInstancesCount",
|
||||
_("Number of object instances on the scene"),
|
||||
_("the number of instances of the specified objects living on the scene"),
|
||||
_("the number of _PARAM1_ living on the scene"),
|
||||
_("Objects"),
|
||||
"res/conditions/nbObjet24.png")
|
||||
.AddCodeOnlyParameter("objectsContext", "")
|
||||
.AddParameter("objectListOrEmptyWithoutPicking", _("Object"))
|
||||
.UseStandardParameters("number")
|
||||
.MarkAsSimple();
|
||||
|
||||
extension.AddExpressionAndCondition(
|
||||
"number",
|
||||
"PickedInstancesCount",
|
||||
_("Number of object instances currently picked"),
|
||||
_("the number of instances picked by the previous conditions (or actions)"),
|
||||
_("the number of _PARAM0_ currently picked"),
|
||||
_("Objects"),
|
||||
"res/conditions/nbObjet24.png")
|
||||
.AddParameter("objectListOrEmptyWithoutPicking", _("Object"))
|
||||
.UseStandardParameters("number")
|
||||
.MarkAsSimple();
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
@@ -1526,7 +1552,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"currently picked in the event"),
|
||||
"",
|
||||
"res/conditions/nbObjet.png")
|
||||
.AddParameter("objectList", _("Object"));
|
||||
.AddParameter("objectList", _("Object"))
|
||||
.SetHidden(); // Deprecated
|
||||
|
||||
obj.AddStrExpression("ObjectName",
|
||||
_("Object name"),
|
||||
|
@@ -229,6 +229,15 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("Expression"));
|
||||
|
||||
extension
|
||||
.AddExpression("ceilTo",
|
||||
_("Ceil (round up) to a decimal point"),
|
||||
_("Round number up to the Nth decimal place"),
|
||||
"",
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("Expression"))
|
||||
.AddParameter("expression", _("Expression"), "", true);
|
||||
|
||||
extension
|
||||
.AddExpression("floor",
|
||||
_("Floor (round down)"),
|
||||
@@ -237,6 +246,15 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("Expression"));
|
||||
|
||||
extension
|
||||
.AddExpression("floorTo",
|
||||
_("Floor (round down) to a decimal point"),
|
||||
_("Round number down to the Nth decimal place"),
|
||||
"",
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("Expression"))
|
||||
.AddParameter("expression", _("Expression"), "", true);
|
||||
|
||||
extension
|
||||
.AddExpression("cos",
|
||||
_("Cosine"),
|
||||
@@ -295,6 +313,15 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("Expression"));
|
||||
|
||||
extension
|
||||
.AddExpression("roundTo",
|
||||
_("Round to a decimal point"),
|
||||
_("Round a number to the Nth decimal place"),
|
||||
"",
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("Expression"))
|
||||
.AddParameter("expression", _("Expression"), "", true);
|
||||
|
||||
extension
|
||||
.AddExpression("exp",
|
||||
_("Exponential"),
|
||||
|
@@ -121,7 +121,7 @@ void Direction::UnserializeFrom(const gd::SerializerElement& element) {
|
||||
polygonElement.GetChild(k);
|
||||
|
||||
polygon.vertices.push_back(
|
||||
sf::Vector2f(verticeElement.GetDoubleAttribute("x"),
|
||||
gd::Vector2f(verticeElement.GetDoubleAttribute("x"),
|
||||
verticeElement.GetDoubleAttribute("y")));
|
||||
}
|
||||
|
||||
|
@@ -4,7 +4,7 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "Polygon2d.h"
|
||||
#include <SFML/System/Vector2.hpp>
|
||||
#include "GDCore/Vector2.h"
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
|
||||
@@ -28,7 +28,7 @@ void Polygon2d::Move(float x, float y) {
|
||||
}
|
||||
|
||||
void Polygon2d::ComputeEdges() const {
|
||||
sf::Vector2f v1, v2;
|
||||
gd::Vector2f v1, v2;
|
||||
edges.clear();
|
||||
|
||||
for (std::size_t i = 0; i < vertices.size(); i++) {
|
||||
@@ -62,8 +62,8 @@ bool Polygon2d::IsConvex() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
sf::Vector2f Polygon2d::ComputeCenter() const {
|
||||
sf::Vector2f center;
|
||||
gd::Vector2f Polygon2d::ComputeCenter() const {
|
||||
gd::Vector2f center;
|
||||
|
||||
for (std::size_t i = 0; i < vertices.size(); i++) {
|
||||
center.x += vertices[i].x;
|
||||
@@ -77,10 +77,10 @@ sf::Vector2f Polygon2d::ComputeCenter() const {
|
||||
|
||||
Polygon2d Polygon2d::CreateRectangle(float width, float height) {
|
||||
Polygon2d rect;
|
||||
rect.vertices.push_back(sf::Vector2f(-width / 2.0f, -height / 2.0f));
|
||||
rect.vertices.push_back(sf::Vector2f(+width / 2.0f, -height / 2.0f));
|
||||
rect.vertices.push_back(sf::Vector2f(+width / 2.0f, +height / 2.0f));
|
||||
rect.vertices.push_back(sf::Vector2f(-width / 2.0f, +height / 2.0f));
|
||||
rect.vertices.push_back(gd::Vector2f(-width / 2.0f, -height / 2.0f));
|
||||
rect.vertices.push_back(gd::Vector2f(+width / 2.0f, -height / 2.0f));
|
||||
rect.vertices.push_back(gd::Vector2f(+width / 2.0f, +height / 2.0f));
|
||||
rect.vertices.push_back(gd::Vector2f(-width / 2.0f, +height / 2.0f));
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
#ifndef GDCORE_POLYGON_H
|
||||
#define GDCORE_POLYGON_H
|
||||
#include <SFML/System/Vector2.hpp>
|
||||
#include "GDCore/Vector2.h"
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
@@ -22,19 +22,19 @@ class GD_CORE_API Polygon2d {
|
||||
Polygon2d(){};
|
||||
virtual ~Polygon2d(){};
|
||||
|
||||
std::vector<sf::Vector2f> vertices; ///< The vertices composing the polygon
|
||||
mutable std::vector<sf::Vector2f>
|
||||
std::vector<gd::Vector2f> vertices; ///< The vertices composing the polygon
|
||||
mutable std::vector<gd::Vector2f>
|
||||
edges; ///< Edges. Can be computed from vertices using ComputeEdges()
|
||||
|
||||
/**
|
||||
* \brief Get the vertices composing the polygon.
|
||||
*/
|
||||
std::vector<sf::Vector2f>& GetVertices() { return vertices; }
|
||||
std::vector<gd::Vector2f>& GetVertices() { return vertices; }
|
||||
|
||||
/**
|
||||
* \brief Get the vertices composing the polygon.
|
||||
*/
|
||||
const std::vector<sf::Vector2f>& GetVertices() const { return vertices; }
|
||||
const std::vector<gd::Vector2f>& GetVertices() const { return vertices; }
|
||||
|
||||
/**
|
||||
* \brief Moves each vertices from the given amount.
|
||||
@@ -68,7 +68,7 @@ class GD_CORE_API Polygon2d {
|
||||
/**
|
||||
* \brief Return the position of the center of the polygon
|
||||
*/
|
||||
sf::Vector2f ComputeCenter() const;
|
||||
gd::Vector2f ComputeCenter() const;
|
||||
|
||||
/** \name Tools
|
||||
* Tool functions
|
||||
|
@@ -4,7 +4,6 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/Sprite.h"
|
||||
#include <SFML/Graphics/Sprite.hpp>
|
||||
#include <iostream>
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/Polygon2d.h"
|
||||
|
||||
|
@@ -6,7 +6,6 @@
|
||||
|
||||
#ifndef SPRITE_H
|
||||
#define SPRITE_H
|
||||
#include <SFML/Graphics/Sprite.hpp>
|
||||
#include <memory>
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/Point.h"
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/Polygon2d.h"
|
||||
|
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
|
@@ -20,7 +20,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
|
||||
"for slow motion effects).",
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/all-features/timers");
|
||||
.SetExtensionHelpPath("/all-features/timers-and-time");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(
|
||||
_("Timers and time")
|
||||
)
|
||||
@@ -141,7 +141,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
|
||||
_("Change time scale"),
|
||||
_("Change the time scale of the scene."),
|
||||
_("Set the time scale of the scene to _PARAM1_"),
|
||||
|
||||
"",
|
||||
"res/actions/time24.png",
|
||||
"res/actions/time.png")
|
||||
@@ -149,6 +148,19 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
|
||||
.AddParameter("expression",
|
||||
_("Scale (1: Default, 2: 2x faster, 0.5: 2x slower...)"));
|
||||
|
||||
extension
|
||||
.AddAction("Wait",
|
||||
_("Wait X seconds (experimental)"),
|
||||
_("Waits a number of seconds before running "
|
||||
"the next actions (and sub-events)."),
|
||||
_("Wait _PARAM0_ seconds"),
|
||||
"",
|
||||
"res/timer.svg",
|
||||
"res/timer.svg")
|
||||
.AddParameter("expression", "Time to wait in seconds")
|
||||
.SetHelpPath("/all-features/timers-and-time/wait-action")
|
||||
.SetAsync();
|
||||
|
||||
extension
|
||||
.AddExpression("TimeDelta",
|
||||
_("Time elapsed since the last frame"),
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/String.h"
|
||||
|
@@ -22,6 +22,7 @@ InstructionMetadata::InstructionMetadata()
|
||||
canHaveSubInstructions(false),
|
||||
hidden(true),
|
||||
usageComplexity(5),
|
||||
isAsync(false),
|
||||
isPrivate(false),
|
||||
isObjectInstruction(false),
|
||||
isBehaviorInstruction(false) {}
|
||||
@@ -45,6 +46,7 @@ InstructionMetadata::InstructionMetadata(const gd::String& extensionNamespace_,
|
||||
extensionNamespace(extensionNamespace_),
|
||||
hidden(false),
|
||||
usageComplexity(5),
|
||||
isAsync(false),
|
||||
isPrivate(false),
|
||||
isObjectInstruction(false),
|
||||
isBehaviorInstruction(false) {}
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/String.h"
|
||||
@@ -98,6 +99,23 @@ class GD_CORE_API InstructionMetadata {
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the instruction is asynchronous - it will be running in the
|
||||
* background, executing the instructions following it before the frame after
|
||||
* it resolved.
|
||||
*/
|
||||
bool IsAsync() const { return isAsync; }
|
||||
|
||||
/**
|
||||
* Set that the instruction is asynchronous - it will be running in the
|
||||
* background, executing the instructions following it before the frame after
|
||||
* it resolved.
|
||||
*/
|
||||
InstructionMetadata &SetAsync() {
|
||||
isAsync = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify that the instruction can have sub instructions.
|
||||
*/
|
||||
@@ -461,6 +479,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
int usageComplexity; ///< Evaluate the instruction from 0 (simple&easy to
|
||||
///< use) to 10 (complex to understand)
|
||||
bool isPrivate;
|
||||
bool isAsync;
|
||||
bool isObjectInstruction;
|
||||
bool isBehaviorInstruction;
|
||||
gd::String requiredBaseObjectCapability;
|
||||
|
@@ -152,15 +152,16 @@ class GD_CORE_API ParameterMetadata {
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return true if the type of the parameter is "object", "objectPtr" or
|
||||
* "objectList".
|
||||
* \brief Return true if the type of the parameter is representing one object
|
||||
* (or more, i.e: an object group).
|
||||
*
|
||||
* \see gd::ParameterMetadata::GetType
|
||||
*/
|
||||
static bool IsObject(const gd::String ¶meterType) {
|
||||
return parameterType == "object" || parameterType == "objectPtr" ||
|
||||
parameterType == "objectList" ||
|
||||
parameterType == "objectListWithoutPicking";
|
||||
parameterType == "objectListOrEmptyIfJustDeclared" ||
|
||||
parameterType == "objectListOrEmptyWithoutPicking";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -117,6 +117,16 @@ void EffectsContainer::SwapEffects(std::size_t firstEffectIndex,
|
||||
effects[secondEffectIndex] = temp;
|
||||
}
|
||||
|
||||
void EffectsContainer::MoveEffect(std::size_t oldIndex, std::size_t newIndex) {
|
||||
if (oldIndex >= effects.size() || newIndex >= effects.size() ||
|
||||
newIndex == oldIndex)
|
||||
return;
|
||||
|
||||
auto effect = effects[oldIndex];
|
||||
effects.erase(effects.begin() + oldIndex);
|
||||
effects.insert(effects.begin() + newIndex, effect);
|
||||
}
|
||||
|
||||
void EffectsContainer::SerializeTo(SerializerElement& element) const {
|
||||
element.ConsiderAsArrayOf("effect");
|
||||
for (std::size_t i = 0; i < GetEffectsCount(); ++i) {
|
||||
|
@@ -7,6 +7,7 @@
|
||||
#define GDCORE_EFFECTS_CONTAINER_H
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "GDCore/String.h"
|
||||
|
||||
@@ -89,6 +90,11 @@ class GD_CORE_API EffectsContainer {
|
||||
*/
|
||||
void RemoveEffect(const gd::String& name);
|
||||
|
||||
/**
|
||||
* \brief Move the specified effect at a new position in the list.
|
||||
*/
|
||||
void MoveEffect(std::size_t oldIndex, std::size_t newIndex);
|
||||
|
||||
/**
|
||||
* Swap the position of two effects.
|
||||
*/
|
||||
|
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
#ifndef GDCORE_OBJECT_H
|
||||
#define GDCORE_OBJECT_H
|
||||
#include <SFML/System/Vector2.hpp>
|
||||
#include "GDCore/Vector2.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
@@ -7,6 +7,7 @@
|
||||
#ifndef GDCORE_OBJECTGROUPSCONTAINER_H
|
||||
#define GDCORE_OBJECTGROUPSCONTAINER_H
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "GDCore/Project/ObjectGroup.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
@@ -77,7 +78,6 @@ class GD_CORE_API ObjectGroupsContainer {
|
||||
*/
|
||||
bool IsEmpty() const { return objectGroups.empty(); };
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* \brief return the position of the group called "name" in the group list
|
||||
*/
|
||||
@@ -107,7 +107,6 @@ class GD_CORE_API ObjectGroupsContainer {
|
||||
* \brief Move the specified group at a new position in the list.
|
||||
*/
|
||||
void Move(std::size_t oldIndex, std::size_t newIndex);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Clear all groups of the container.
|
||||
|
@@ -9,7 +9,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <SFML/System/Utf.hpp>
|
||||
#include <cctype>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
|
@@ -92,7 +92,7 @@ double Variable::GetValue() const {
|
||||
return value;
|
||||
} else if (type == Type::String) {
|
||||
double retVal = str.empty() ? 0.0 : str.To<double>();
|
||||
if(std::isnan(retVal)) retVal = 0.0;
|
||||
if (std::isnan(retVal)) retVal = 0.0;
|
||||
return retVal;
|
||||
} else if (type == Type::Boolean) {
|
||||
return boolVal ? 1.0 : 0.0;
|
||||
@@ -188,6 +188,15 @@ const Variable& Variable::GetAtIndex(const size_t index) const {
|
||||
return *childrenArray.at(index);
|
||||
};
|
||||
|
||||
void Variable::MoveChildInArray(const size_t oldIndex, const size_t newIndex) {
|
||||
if (oldIndex >= childrenArray.size() || newIndex >= childrenArray.size())
|
||||
return;
|
||||
|
||||
std::shared_ptr<gd::Variable> object = std::move(childrenArray[oldIndex]);
|
||||
childrenArray.erase(childrenArray.begin() + oldIndex);
|
||||
childrenArray.insert(childrenArray.begin() + newIndex, std::move(object));
|
||||
}
|
||||
|
||||
Variable& Variable::PushNew() { return GetAtIndex(GetChildrenCount()); };
|
||||
|
||||
void Variable::RemoveAtIndex(const size_t index) {
|
||||
@@ -195,8 +204,29 @@ void Variable::RemoveAtIndex(const size_t index) {
|
||||
childrenArray.erase(childrenArray.begin() + index);
|
||||
};
|
||||
|
||||
bool Variable::InsertAtIndex(const gd::Variable& variable, const size_t index) {
|
||||
if (type != Type::Array) return false;
|
||||
auto newVariable = std::make_shared<gd::Variable>(variable);
|
||||
if (index < childrenArray.size()) {
|
||||
childrenArray.insert(childrenArray.begin() + index, newVariable);
|
||||
} else {
|
||||
childrenArray.push_back(newVariable);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
bool Variable::InsertChild(const gd::String& name,
|
||||
const gd::Variable& variable) {
|
||||
if (type != Type::Structure || HasChild(name)) {
|
||||
return false;
|
||||
}
|
||||
children[name] = std::make_shared<gd::Variable>(variable);
|
||||
return true;
|
||||
};
|
||||
|
||||
void Variable::SerializeTo(SerializerElement& element) const {
|
||||
element.SetStringAttribute("type", TypeAsString(GetType()));
|
||||
if (IsFolded()) element.SetBoolAttribute("folded", true);
|
||||
|
||||
if (type == Type::String) {
|
||||
element.SetStringAttribute("value", GetString());
|
||||
@@ -234,6 +264,7 @@ void Variable::UnserializeFrom(const SerializerElement& element) {
|
||||
if (element.HasChild("children", "Children") && IsPrimitive(type))
|
||||
type = Type::Structure;
|
||||
// end of compatibility code
|
||||
SetFolded(element.GetBoolAttribute("folded", false));
|
||||
|
||||
if (IsPrimitive(type)) {
|
||||
if (type == Type::String) {
|
||||
@@ -305,6 +336,7 @@ void Variable::RemoveRecursively(const gd::Variable& variableToRemove) {
|
||||
Variable::Variable(const Variable& other)
|
||||
: value(other.value),
|
||||
str(other.str),
|
||||
folded(other.folded),
|
||||
boolVal(other.boolVal),
|
||||
type(other.type) {
|
||||
CopyChildren(other);
|
||||
@@ -314,6 +346,7 @@ Variable& Variable::operator=(const Variable& other) {
|
||||
if (this != &other) {
|
||||
value = other.value;
|
||||
str = other.str;
|
||||
folded = other.folded;
|
||||
boolVal = other.boolVal;
|
||||
type = other.type;
|
||||
CopyChildren(other);
|
||||
|
@@ -6,10 +6,10 @@
|
||||
|
||||
#ifndef GDCORE_VARIABLE_H
|
||||
#define GDCORE_VARIABLE_H
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
@@ -98,7 +98,7 @@ class GD_CORE_API Variable {
|
||||
void SetValue(double val) {
|
||||
value = val;
|
||||
// NaN values are not supported by GDevelop nor the serializer.
|
||||
if(std::isnan(value)) value = 0.0;
|
||||
if (std::isnan(value)) value = 0.0;
|
||||
type = Type::Number;
|
||||
}
|
||||
|
||||
@@ -185,9 +185,9 @@ class GD_CORE_API Variable {
|
||||
* \brief Get the count of children that the variable has.
|
||||
*/
|
||||
size_t GetChildrenCount() const {
|
||||
return type == Type::Structure
|
||||
? children.size()
|
||||
: type == Type::Array ? childrenArray.size() : 0;
|
||||
return type == Type::Structure ? children.size()
|
||||
: type == Type::Array ? childrenArray.size()
|
||||
: 0;
|
||||
};
|
||||
|
||||
/** \name Structure
|
||||
@@ -290,12 +290,38 @@ class GD_CORE_API Variable {
|
||||
*/
|
||||
void RemoveAtIndex(const size_t index);
|
||||
|
||||
/**
|
||||
* \brief Move child in array.
|
||||
*/
|
||||
void MoveChildInArray(const size_t oldIndex, const size_t newIndex);
|
||||
|
||||
/**
|
||||
* \brief Insert child in array.
|
||||
*/
|
||||
bool InsertAtIndex(const gd::Variable& variable, const size_t index);
|
||||
|
||||
/**
|
||||
* \brief Insert a child in a structure.
|
||||
*/
|
||||
bool InsertChild(const gd::String& name, const gd::Variable& variable);
|
||||
|
||||
/**
|
||||
* \brief Get the vector containing all the children.
|
||||
*/
|
||||
const std::vector<std::shared_ptr<Variable>>& GetAllChildrenArray() const {
|
||||
return childrenArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set if the children must be folded.
|
||||
*/
|
||||
void SetFolded(bool fold = true) { folded = fold; }
|
||||
|
||||
/**
|
||||
* \brief True if the children should be folded in the variables editor.
|
||||
*/
|
||||
bool IsFolded() const { return folded; }
|
||||
|
||||
///@}
|
||||
///@}
|
||||
|
||||
@@ -325,6 +351,7 @@ class GD_CORE_API Variable {
|
||||
*/
|
||||
static Type StringAsType(const gd::String& str);
|
||||
|
||||
bool folded;
|
||||
mutable Type type;
|
||||
mutable gd::String str;
|
||||
mutable double value;
|
||||
|
@@ -4,8 +4,10 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/Project/VariablesContainer.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
#include "GDCore/Project/Variable.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/String.h"
|
||||
@@ -88,7 +90,6 @@ Variable& VariablesContainer::Insert(const gd::String& name,
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void VariablesContainer::Remove(const gd::String& varName) {
|
||||
variables.erase(
|
||||
std::remove_if(
|
||||
@@ -151,13 +152,14 @@ void VariablesContainer::Swap(std::size_t firstVariableIndex,
|
||||
}
|
||||
|
||||
void VariablesContainer::Move(std::size_t oldIndex, std::size_t newIndex) {
|
||||
if (oldIndex >= variables.size() || newIndex >= variables.size()) return;
|
||||
if (oldIndex >= variables.size() || newIndex >= variables.size() ||
|
||||
oldIndex == newIndex)
|
||||
return;
|
||||
|
||||
auto nameAndVariable = variables[oldIndex];
|
||||
variables.erase(variables.begin() + oldIndex);
|
||||
variables.insert(variables.begin() + newIndex, nameAndVariable);
|
||||
}
|
||||
#endif
|
||||
|
||||
void VariablesContainer::SerializeTo(SerializerElement& element) const {
|
||||
element.ConsiderAsArrayOf("variable");
|
||||
|
@@ -77,8 +77,6 @@ bool SerializerElement::GetBoolAttribute(const gd::String& name,
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Bool attribute \"" << name << "\" not found, returning "
|
||||
<< defaultValue;
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
@@ -9,7 +9,6 @@
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
|
||||
#include <SFML/System/String.hpp>
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Utf8/utf8proc.h"
|
||||
|
||||
@@ -28,11 +27,6 @@ String::String(const char *characters) : m_string()
|
||||
*this = characters;
|
||||
}
|
||||
|
||||
String::String(const sf::String &string) : m_string()
|
||||
{
|
||||
*this = string;
|
||||
}
|
||||
|
||||
String::String(const std::u32string &string) : m_string()
|
||||
{
|
||||
*this = string;
|
||||
@@ -44,26 +38,6 @@ String& String::operator=(const char *characters)
|
||||
return *this;
|
||||
}
|
||||
|
||||
String& String::operator=(const sf::String &string)
|
||||
{
|
||||
m_string.clear();
|
||||
|
||||
//In theory, an UTF8 character can be up to 6 bytes (even if in the current Unicode standard,
|
||||
//the last character is 4 bytes long when encoded in UTF8).
|
||||
//So, reserve the maximum possible size to avoid reallocations.
|
||||
m_string.reserve( string.getSize() * 6 );
|
||||
|
||||
//Push_back all characters inside the string.
|
||||
for( sf::String::ConstIterator it = string.begin(); it != string.end(); ++it )
|
||||
{
|
||||
push_back( *it );
|
||||
}
|
||||
|
||||
m_string.shrink_to_fit();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
String& String::operator=(const std::u32string &string)
|
||||
{
|
||||
m_string.clear();
|
||||
@@ -112,7 +86,7 @@ String::const_iterator String::end() const
|
||||
String String::FromLocale( const std::string &localizedString )
|
||||
{
|
||||
#if defined(WINDOWS)
|
||||
return FromSfString(sf::String(localizedString)); //Don't need to use the current locale, on Windows, std::locale is always the C locale
|
||||
return FromUTF8(localizedString); //Don't need to use the current locale, on Windows, std::locale is always the C locale
|
||||
#elif defined(MACOS)
|
||||
return FromUTF8(localizedString); //Assume UTF8 is the current locale
|
||||
#elif defined(EMSCRIPTEN)
|
||||
@@ -124,7 +98,7 @@ String String::FromLocale( const std::string &localizedString )
|
||||
std::locale("").name().find("UTF8") != std::string::npos)
|
||||
return FromUTF8(localizedString); //UTF8 is already the current locale
|
||||
else
|
||||
return FromSfString(sf::String(localizedString, std::locale(""))); //Use the current locale (std::locale("")) for conversion
|
||||
return FromUTF8(localizedString); //Use the current locale (std::locale("")) for conversion
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -136,11 +110,6 @@ String String::FromUTF32( const std::u32string &string )
|
||||
return str;
|
||||
}
|
||||
|
||||
String String::FromSfString( const sf::String &sfString )
|
||||
{
|
||||
return String(sfString);
|
||||
}
|
||||
|
||||
String String::FromUTF8( const std::string &utf8Str )
|
||||
{
|
||||
String str(utf8Str.c_str());
|
||||
@@ -164,7 +133,7 @@ String String::FromWide( const std::wstring &wstr )
|
||||
std::string String::ToLocale() const
|
||||
{
|
||||
#if defined(WINDOWS)
|
||||
return ToSfString().toAnsiString();
|
||||
return m_string;
|
||||
#elif defined(MACOS)
|
||||
return m_string;
|
||||
#elif defined(EMSCRIPTEN)
|
||||
@@ -176,7 +145,7 @@ std::string String::ToLocale() const
|
||||
std::locale("").name().find("UTF8") != std::string::npos)
|
||||
return m_string; //UTF8 is already the current locale on Linux
|
||||
else
|
||||
return ToSfString().toAnsiString(std::locale("")); //Use the current locale for conversion
|
||||
return m_string; //Use the current locale for conversion
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -191,20 +160,6 @@ std::u32string String::ToUTF32() const
|
||||
return u32str;
|
||||
}
|
||||
|
||||
sf::String String::ToSfString() const
|
||||
{
|
||||
sf::String str;
|
||||
for(const_iterator it = begin(); it != end(); ++it)
|
||||
str += sf::String(static_cast<sf::Uint32>(*it));
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
String::operator sf::String() const
|
||||
{
|
||||
return ToSfString();
|
||||
}
|
||||
|
||||
std::string String::ToUTF8() const
|
||||
{
|
||||
return m_string;
|
||||
|
@@ -13,12 +13,9 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <SFML/System/String.hpp>
|
||||
|
||||
#include "GDCore/Utf8/utf8.h"
|
||||
|
||||
namespace sf {class String;};
|
||||
|
||||
namespace gd
|
||||
{
|
||||
|
||||
@@ -121,11 +118,6 @@ public:
|
||||
*/
|
||||
String(const std::u32string &string);
|
||||
|
||||
/**
|
||||
* Constructs a string from an sf::String.
|
||||
*/
|
||||
String(const sf::String &string);
|
||||
|
||||
/**
|
||||
* \}
|
||||
*/
|
||||
@@ -146,8 +138,6 @@ public:
|
||||
*/
|
||||
String& operator=(const char *characters);
|
||||
|
||||
String& operator=(const sf::String &string);
|
||||
|
||||
String& operator=(const std::u32string &string);
|
||||
|
||||
/**
|
||||
@@ -229,7 +219,6 @@ public:
|
||||
static String From(T value)
|
||||
{
|
||||
static_assert(!std::is_same<T, std::string>::value, "Can't use gd::String::From with std::string.");
|
||||
static_assert(!std::is_same<T, sf::String>::value, "Can't use gd::String::From with sf::String.");
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << value;
|
||||
@@ -244,7 +233,6 @@ public:
|
||||
T To() const
|
||||
{
|
||||
static_assert(!std::is_same<T, std::string>::value, "Can't use gd::String::To with std::string.");
|
||||
static_assert(!std::is_same<T, sf::String>::value, "Can't use gd::String::To with sf::String.");
|
||||
|
||||
T value;
|
||||
std::istringstream oss(m_string);
|
||||
@@ -274,13 +262,6 @@ public:
|
||||
*/
|
||||
static String FromUTF32( const std::u32string &string );
|
||||
|
||||
/**
|
||||
* \return a String created from a sf::String (UTF32).
|
||||
*
|
||||
* See \ref Conversions1 for more information.
|
||||
*/
|
||||
static String FromSfString( const sf::String &sfString );
|
||||
|
||||
/**
|
||||
* \return a String created an UTF8 encoded std::string.
|
||||
*/
|
||||
@@ -312,20 +293,6 @@ public:
|
||||
*/
|
||||
std::u32string ToUTF32() const;
|
||||
|
||||
/**
|
||||
* \return a sf::String from the current string.
|
||||
*
|
||||
* See \ref Conversions1 for more information.
|
||||
*/
|
||||
sf::String ToSfString() const;
|
||||
|
||||
/**
|
||||
* Implicit conversion operator to sf::String.
|
||||
*
|
||||
* See \ref Conversions1 for more information.
|
||||
*/
|
||||
operator sf::String() const;
|
||||
|
||||
/**
|
||||
* \return a UTF8 encoded std::string from the current string.
|
||||
*/
|
||||
@@ -885,7 +852,7 @@ namespace std
|
||||
* on the string size and so is the operator[]().
|
||||
*
|
||||
* \section Conversion Conversions from/to other string types
|
||||
* The String handles implicit conversion with sf::String (implicit constructor and implicit conversion
|
||||
* The String handles implicit conversion with std::String (implicit constructor and implicit conversion
|
||||
* operator).
|
||||
*
|
||||
* **However, this is not the case with std::string** as this conversion is not often lossless (mostly on Windows).
|
||||
@@ -894,16 +861,6 @@ namespace std
|
||||
* directly use the operator=() or the constructor as they are supporting const char* as argument (it assumes the string
|
||||
* literal is encoded in UTF8, so you'll need to put the u8 prefix).
|
||||
*
|
||||
* \subsection Conversions1 Implicit conversion from/to sf::String
|
||||
* \code
|
||||
* //Get a String from sf::String
|
||||
* sf::String sfmlStr("This is a test ! ");
|
||||
* gd::String str1(sfmlStr); //Now contains "This is a test ! " encoded in UTF8
|
||||
*
|
||||
* //Get a sf::String from String
|
||||
* sf::String anotherSfmlString = str; //anotherSfmlString now contains "Another test ! "
|
||||
* \endcode
|
||||
*
|
||||
* \subsection Conversions2 Conversion from/to std::string
|
||||
* \code
|
||||
* //Get a String from a std::string encoded in the current locale
|
||||
|
@@ -1,200 +0,0 @@
|
||||
#include "GDCore/Tools/FileStream.h"
|
||||
|
||||
#if defined(WINDOWS)
|
||||
#if __GLIBCXX__
|
||||
#include <ext/stdio_filebuf.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace gd {
|
||||
|
||||
namespace {
|
||||
|
||||
#if FSTREAM_WINDOWS_MINGW
|
||||
|
||||
#define MODE(in_val, out_val, trunc_val, app_val) \
|
||||
((((mode & std::ios_base::in) != 0) == in_val) && \
|
||||
(((mode & std::ios_base::out) != 0) == out_val) && \
|
||||
(((mode & std::ios_base::trunc) != 0) == trunc_val) && \
|
||||
(((mode & std::ios_base::app) != 0) == app_val))
|
||||
|
||||
std::wstring GetStdioMode(std::ios_base::openmode mode) {
|
||||
std::wstring strMode;
|
||||
|
||||
/// Thanks to https://gcc.gnu.org/ml/libstdc++/2007-06/msg00013.html
|
||||
if (MODE(false, true, false, false))
|
||||
strMode += L"w";
|
||||
else if (MODE(false, true, false, true))
|
||||
strMode += L"a";
|
||||
else if (MODE(true, true, false, true))
|
||||
strMode += L"a+";
|
||||
else if (MODE(false, true, true, false))
|
||||
strMode += L"w";
|
||||
else if (MODE(true, false, false, false))
|
||||
strMode += L"r";
|
||||
else if (MODE(true, true, false, false))
|
||||
strMode += L"r+";
|
||||
else if (MODE(true, true, true, false))
|
||||
strMode += L"w+";
|
||||
|
||||
if ((mode & std::ios_base::binary) != 0) strMode += L"b";
|
||||
|
||||
return strMode;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Open the given file into a filebuf and return it.
|
||||
* On Windows, return the associated FILE* inside the file argument.
|
||||
*/
|
||||
FileStream::InternalBufferType* OpenBuffer(const gd::String& path,
|
||||
std::ios_base::openmode mode,
|
||||
FILE** file) {
|
||||
#if FSTREAM_WINDOWS_MINGW
|
||||
*file = _wfopen(path.ToWide().c_str(), GetStdioMode(mode).c_str());
|
||||
if (!(*file)) return nullptr;
|
||||
return new __gnu_cxx::stdio_filebuf<char>(*file, mode);
|
||||
#else
|
||||
auto* filebuffer = new std::filebuf();
|
||||
return filebuffer->open(path.ToLocale().c_str(), mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
FileStream::FileStream() : std::iostream(nullptr) {}
|
||||
|
||||
FileStream::FileStream(const gd::String& path, std::ios_base::openmode mode)
|
||||
: std::iostream(nullptr),
|
||||
m_file(nullptr),
|
||||
m_buffer(OpenBuffer(path, mode, &m_file)) {
|
||||
setstate(ios_base::goodbit);
|
||||
if (m_buffer) {
|
||||
std::iostream::init(m_buffer.get());
|
||||
if ((mode & std::ios_base::ate) != 0) seekg(0, end);
|
||||
} else
|
||||
setstate(ios_base::badbit);
|
||||
}
|
||||
|
||||
FileStream::~FileStream() {
|
||||
if (is_open()) close();
|
||||
}
|
||||
|
||||
/*
|
||||
WILL WORK with GCC>=5 (not 4.9 used on Windows)
|
||||
FileStream::FileStream(FileStream && other) :
|
||||
std::iostream(std::move(other)),
|
||||
m_buffer(std::move(other.m_buffer))
|
||||
{
|
||||
|
||||
}*/
|
||||
|
||||
/*FileStream& FileStream::operator=(FileStream && other)
|
||||
{
|
||||
std::iostream::operator=(std::move(other));
|
||||
m_buffer = std::move(other.m_buffer);
|
||||
}*/
|
||||
|
||||
void FileStream::open(const gd::String& path, std::ios_base::openmode mode) {
|
||||
setstate(ios_base::goodbit);
|
||||
|
||||
if (is_open()) {
|
||||
setstate(ios_base::failbit);
|
||||
std::cout << "is_open true when trying to open!" << std::endl;
|
||||
} else {
|
||||
auto* newBuffer = OpenBuffer(path, mode, &m_file);
|
||||
if (newBuffer) {
|
||||
m_buffer.reset(newBuffer);
|
||||
std::iostream::init(m_buffer.get());
|
||||
if ((mode & std::ios_base::ate) != 0) seekg(0, end);
|
||||
} else {
|
||||
setstate(ios_base::badbit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool FileStream::is_open() const {
|
||||
if (!m_buffer) return false;
|
||||
return m_buffer->is_open();
|
||||
}
|
||||
|
||||
void FileStream::close() {
|
||||
#if FSTREAM_WINDOWS_MINGW
|
||||
if (m_buffer) m_buffer->close();
|
||||
|
||||
if (m_file && fclose(m_file) != 0) {
|
||||
setstate(ios_base::failbit);
|
||||
}
|
||||
|
||||
m_buffer.reset(nullptr);
|
||||
m_file = nullptr;
|
||||
#else
|
||||
if (!m_buffer || m_buffer->close() == nullptr) {
|
||||
setstate(ios_base::failbit);
|
||||
} else {
|
||||
m_buffer.reset(nullptr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*void FileStream::swap(FileStream & other) //WILL WORK with GCC>=5 (not 4.9
|
||||
used on Windows)
|
||||
{
|
||||
std::iostream::swap(other);
|
||||
std::swap(m_buffer, other.m_buffer);
|
||||
}*/
|
||||
|
||||
SFMLFileStream::SFMLFileStream() : m_file(nullptr) {}
|
||||
|
||||
SFMLFileStream::~SFMLFileStream() {
|
||||
if (m_file) fclose(m_file);
|
||||
}
|
||||
|
||||
bool SFMLFileStream::open(const gd::String& filename) {
|
||||
if (m_file) fclose(m_file);
|
||||
|
||||
#if FSTREAM_WINDOWS_MINGW
|
||||
m_file = _wfopen(filename.ToWide().c_str(), L"rb");
|
||||
#else
|
||||
m_file = fopen(filename.ToLocale().c_str(), "rb");
|
||||
#endif
|
||||
|
||||
return m_file != NULL;
|
||||
}
|
||||
|
||||
sf::Int64 SFMLFileStream::read(void* data, sf::Int64 size) {
|
||||
if (m_file)
|
||||
return fread(data, 1, static_cast<std::size_t>(size), m_file);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
sf::Int64 SFMLFileStream::seek(sf::Int64 position) {
|
||||
if (m_file) {
|
||||
fseek(m_file, static_cast<std::size_t>(position), SEEK_SET);
|
||||
return tell();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
sf::Int64 SFMLFileStream::tell() {
|
||||
if (m_file)
|
||||
return ftell(m_file);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
sf::Int64 SFMLFileStream::getSize() {
|
||||
if (m_file) {
|
||||
sf::Int64 position = tell();
|
||||
fseek(m_file, 0, SEEK_END);
|
||||
sf::Int64 size = tell();
|
||||
seek(position);
|
||||
return size;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -1,82 +0,0 @@
|
||||
#ifndef GDCORE_FSTREAMTOOLS
|
||||
#define GDCORE_FSTREAMTOOLS
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
#include <SFML/System.hpp>
|
||||
|
||||
#include "GDCore/String.h"
|
||||
|
||||
#if defined(WINDOWS) && __GLIBCXX__
|
||||
#include <ext/stdio_filebuf.h>
|
||||
#else
|
||||
#include <fstream> //for std::filebuf
|
||||
#endif
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* Similar to std::i/ofstream except that it can open file with
|
||||
* gd::String paths (useful on Windows where fstream doesn't
|
||||
* support wide paths).
|
||||
*/
|
||||
class GD_CORE_API FileStream : public std::iostream {
|
||||
public:
|
||||
#if defined(WINDOWS) && __GLIBCXX__
|
||||
using InternalBufferType = std::basic_filebuf<char>;
|
||||
#else
|
||||
using InternalBufferType = std::filebuf;
|
||||
#endif
|
||||
|
||||
FileStream();
|
||||
FileStream(const gd::String& path, std::ios_base::openmode mode);
|
||||
~FileStream();
|
||||
|
||||
FileStream(const FileStream& other) = delete;
|
||||
FileStream(FileStream&& other) = delete; // HACK for GCC 4.9 (Windows)
|
||||
// FileStream(FileStream && other); WILL WORK with GCC>=5 (not 4.9 used on
|
||||
// Windows)
|
||||
|
||||
FileStream& operator=(const FileStream& other) = delete;
|
||||
FileStream& operator=(FileStream&& other) =
|
||||
delete; // HACK for GCC 4.9 (Windows)
|
||||
// FileStream& operator=(FileStream && other); WILL WORK with GCC>=5 (not 4.9
|
||||
// used on Windows)
|
||||
|
||||
void open(const gd::String& path, std::ios_base::openmode mode);
|
||||
|
||||
bool is_open() const;
|
||||
|
||||
void close();
|
||||
|
||||
// void swap(FileStream & other); //WILL WORK with GCC>=5 (not 4.9 used on
|
||||
// Windows)
|
||||
|
||||
private:
|
||||
FILE* m_file;
|
||||
std::unique_ptr<InternalBufferType> m_buffer;
|
||||
};
|
||||
|
||||
class GD_CORE_API SFMLFileStream : public sf::InputStream {
|
||||
public:
|
||||
SFMLFileStream();
|
||||
~SFMLFileStream();
|
||||
|
||||
bool open(const gd::String& filename);
|
||||
|
||||
virtual sf::Int64 read(void* data, sf::Int64 size);
|
||||
|
||||
virtual sf::Int64 seek(sf::Int64 position);
|
||||
|
||||
virtual sf::Int64 tell();
|
||||
|
||||
virtual sf::Int64 getSize();
|
||||
|
||||
private:
|
||||
FILE* m_file;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif
|
@@ -1,19 +0,0 @@
|
||||
#include <SFML/OpenGL.hpp>
|
||||
#include <cmath>
|
||||
|
||||
namespace OpenGLTools {
|
||||
|
||||
void GD_CORE_API PerspectiveGL(GLdouble fovY,
|
||||
GLdouble aspect,
|
||||
GLdouble zNear,
|
||||
GLdouble zFar) {
|
||||
const GLdouble pi = 3.1415926535897932384626433832795;
|
||||
GLdouble fW, fH;
|
||||
|
||||
fH = std::tan(fovY / 360 * pi) * zNear;
|
||||
fW = fH * aspect;
|
||||
|
||||
glFrustum(-fW, fW, -fH, fH, zNear, zFar);
|
||||
}
|
||||
|
||||
} // namespace OpenGLTools
|
@@ -1,9 +0,0 @@
|
||||
#include <SFML/OpenGL.hpp>
|
||||
|
||||
namespace OpenGLTools {
|
||||
|
||||
void GD_CORE_API PerspectiveGL(GLdouble fovY,
|
||||
GLdouble aspect,
|
||||
GLdouble zNear,
|
||||
GLdouble zFar);
|
||||
}
|
360
Core/GDCore/Vector2.h
Normal file
360
Core/GDCore/Vector2.h
Normal file
@@ -0,0 +1,360 @@
|
||||
// This is adapted from SFML (https://github.com/SFML/SFML).
|
||||
|
||||
#ifndef GDCORE_VECTOR2_H
|
||||
#define GDCORE_VECTOR2_H
|
||||
|
||||
namespace gd
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Utility template class for manipulating
|
||||
/// 2-dimensional vectors
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
class Vector2
|
||||
{
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Default constructor
|
||||
///
|
||||
/// Creates a Vector2(0, 0).
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
inline Vector2() :
|
||||
x(0),
|
||||
y(0)
|
||||
{
|
||||
|
||||
}
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Construct the vector from its coordinates
|
||||
///
|
||||
/// \param X X coordinate
|
||||
/// \param Y Y coordinate
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
inline Vector2(T X, T Y) :
|
||||
x(X),
|
||||
y(Y)
|
||||
{
|
||||
|
||||
}
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Construct the vector from another type of vector
|
||||
///
|
||||
/// This constructor doesn't replace the copy constructor,
|
||||
/// it's called only when U != T.
|
||||
/// A call to this constructor will fail to compile if U
|
||||
/// is not convertible to T.
|
||||
///
|
||||
/// \param vector Vector to convert
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename U>
|
||||
inline explicit Vector2(const Vector2<U>& vector) :
|
||||
x(static_cast<T>(vector.x)),
|
||||
y(static_cast<T>(vector.y))
|
||||
{
|
||||
}
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
T x; ///< X coordinate of the vector
|
||||
T y; ///< Y coordinate of the vector
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of unary operator -
|
||||
///
|
||||
/// \param right Vector to negate
|
||||
///
|
||||
/// \return Memberwise opposite of the vector
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline Vector2<T> operator -(const Vector2<T>& right)
|
||||
{
|
||||
return Vector2<T>(-right.x, -right.y);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of binary operator +=
|
||||
///
|
||||
/// This operator performs a memberwise addition of both vectors,
|
||||
/// and assigns the result to \a left.
|
||||
///
|
||||
/// \param left Left operand (a vector)
|
||||
/// \param right Right operand (a vector)
|
||||
///
|
||||
/// \return Reference to \a left
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline Vector2<T>& operator +=(Vector2<T>& left, const Vector2<T>& right)
|
||||
{
|
||||
left.x += right.x;
|
||||
left.y += right.y;
|
||||
|
||||
return left;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of binary operator -=
|
||||
///
|
||||
/// This operator performs a memberwise subtraction of both vectors,
|
||||
/// and assigns the result to \a left.
|
||||
///
|
||||
/// \param left Left operand (a vector)
|
||||
/// \param right Right operand (a vector)
|
||||
///
|
||||
/// \return Reference to \a left
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline Vector2<T>& operator -=(Vector2<T>& left, const Vector2<T>& right)
|
||||
{
|
||||
left.x -= right.x;
|
||||
left.y -= right.y;
|
||||
|
||||
return left;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of binary operator +
|
||||
///
|
||||
/// \param left Left operand (a vector)
|
||||
/// \param right Right operand (a vector)
|
||||
///
|
||||
/// \return Memberwise addition of both vectors
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline Vector2<T> operator +(const Vector2<T>& left, const Vector2<T>& right)
|
||||
{
|
||||
return Vector2<T>(left.x + right.x, left.y + right.y);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of binary operator -
|
||||
///
|
||||
/// \param left Left operand (a vector)
|
||||
/// \param right Right operand (a vector)
|
||||
///
|
||||
/// \return Memberwise subtraction of both vectors
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline Vector2<T> operator -(const Vector2<T>& left, const Vector2<T>& right)
|
||||
{
|
||||
return Vector2<T>(left.x - right.x, left.y - right.y);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of binary operator *
|
||||
///
|
||||
/// \param left Left operand (a vector)
|
||||
/// \param right Right operand (a scalar value)
|
||||
///
|
||||
/// \return Memberwise multiplication by \a right
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline Vector2<T> operator *(const Vector2<T>& left, T right)
|
||||
{
|
||||
return Vector2<T>(left.x * right, left.y * right);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of binary operator *
|
||||
///
|
||||
/// \param left Left operand (a scalar value)
|
||||
/// \param right Right operand (a vector)
|
||||
///
|
||||
/// \return Memberwise multiplication by \a left
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline Vector2<T> operator *(T left, const Vector2<T>& right)
|
||||
{
|
||||
return Vector2<T>(right.x * left, right.y * left);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of binary operator *=
|
||||
///
|
||||
/// This operator performs a memberwise multiplication by \a right,
|
||||
/// and assigns the result to \a left.
|
||||
///
|
||||
/// \param left Left operand (a vector)
|
||||
/// \param right Right operand (a scalar value)
|
||||
///
|
||||
/// \return Reference to \a left
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline Vector2<T>& operator *=(Vector2<T>& left, T right)
|
||||
{
|
||||
left.x *= right;
|
||||
left.y *= right;
|
||||
|
||||
return left;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of binary operator /
|
||||
///
|
||||
/// \param left Left operand (a vector)
|
||||
/// \param right Right operand (a scalar value)
|
||||
///
|
||||
/// \return Memberwise division by \a right
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline Vector2<T> operator /(const Vector2<T>& left, T right)
|
||||
{
|
||||
return Vector2<T>(left.x / right, left.y / right);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of binary operator /=
|
||||
///
|
||||
/// This operator performs a memberwise division by \a right,
|
||||
/// and assigns the result to \a left.
|
||||
///
|
||||
/// \param left Left operand (a vector)
|
||||
/// \param right Right operand (a scalar value)
|
||||
///
|
||||
/// \return Reference to \a left
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline Vector2<T>& operator /=(Vector2<T>& left, T right)
|
||||
{
|
||||
left.x /= right;
|
||||
left.y /= right;
|
||||
|
||||
return left;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of binary operator ==
|
||||
///
|
||||
/// This operator compares strict equality between two vectors.
|
||||
///
|
||||
/// \param left Left operand (a vector)
|
||||
/// \param right Right operand (a vector)
|
||||
///
|
||||
/// \return True if \a left is equal to \a right
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline bool operator ==(const Vector2<T>& left, const Vector2<T>& right)
|
||||
{
|
||||
return (left.x == right.x) && (left.y == right.y);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of binary operator !=
|
||||
///
|
||||
/// This operator compares strict difference between two vectors.
|
||||
///
|
||||
/// \param left Left operand (a vector)
|
||||
/// \param right Right operand (a vector)
|
||||
///
|
||||
/// \return True if \a left is not equal to \a right
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline bool operator !=(const Vector2<T>& left, const Vector2<T>& right)
|
||||
{
|
||||
return (left.x != right.x) || (left.y != right.y);
|
||||
}
|
||||
|
||||
// Define the most common types
|
||||
typedef Vector2<int> Vector2i;
|
||||
typedef Vector2<unsigned int> Vector2u;
|
||||
typedef Vector2<float> Vector2f;
|
||||
|
||||
} // namespace gd
|
||||
|
||||
|
||||
#endif // GDCORE_VECTOR2_H
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \class gd::Vector2
|
||||
/// \ingroup CommonProgrammingTools
|
||||
///
|
||||
/// gd::Vector2 is a simple class that defines a mathematical
|
||||
/// vector with two coordinates (x and y). It can be used to
|
||||
/// represent anything that has two dimensions: a size, a point,
|
||||
/// a velocity, etc.
|
||||
///
|
||||
/// The template parameter T is the type of the coordinates. It
|
||||
/// can be any type that supports arithmetic operations (+, -, /, *)
|
||||
/// and comparisons (==, !=), for example int or float.
|
||||
///
|
||||
/// You generally don't have to care about the templated form (gd::Vector2<T>),
|
||||
/// the most common specializations have special typedefs:
|
||||
/// \li gd::Vector2<float> is gd::Vector2f
|
||||
/// \li gd::Vector2<int> is gd::Vector2i
|
||||
/// \li gd::Vector2<unsigned int> is gd::Vector2u
|
||||
///
|
||||
/// The gd::Vector2 class has a small and simple interface, its x and y members
|
||||
/// can be accessed directly (there are no accessors like setX(), getX()) and it
|
||||
/// contains no mathematical function like dot product, cross product, length, etc.
|
||||
///
|
||||
/// Usage example:
|
||||
/// \code
|
||||
/// gd::Vector2f v1(16.5f, 24.f);
|
||||
/// v1.x = 18.2f;
|
||||
/// float y = v1.y;
|
||||
///
|
||||
/// gd::Vector2f v2 = v1 * 5.f;
|
||||
/// gd::Vector2f v3;
|
||||
/// v3 = v1 + v2;
|
||||
///
|
||||
/// bool different = (v2 != v3);
|
||||
/// \endcode
|
||||
///
|
||||
/// Note: for 3-dimensional vectors, see gd::Vector3.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
@@ -31,8 +31,8 @@ Extensions do have the same distinction between the "**IDE**" part and the "**Ru
|
||||
|
||||
In GDevelop, developers can associate and manipulate variables in their games. To represent them, we have two things:
|
||||
|
||||
- The **editor** `gd::Variable` that is part of the structure of the game, so living in [GDCore in Variable.h](https://docs.gdevelop-app.com/GDCore%20Documentation/classgd_1_1_variable.html). This is what is shown in the editor, saved on disk in the project file.
|
||||
- The **game engine** variable, called `gdjs.Variable` in GDJS. [Documentation is in the GDJS **game engine**](https://docs.gdevelop-app.com/GDJS%20Runtime%20Documentation/Variable.html). This JavaScript class is what is used during a game.
|
||||
- The **editor** `gd::Variable` that is part of the structure of the game, so living in [GDCore in Variable.h](https://docs.gdevelop.io/GDCore%20Documentation/classgd_1_1_variable.html). This is what is shown in the editor, saved on disk in the project file.
|
||||
- The **game engine** variable, called `gdjs.Variable` in GDJS. [Documentation is in the GDJS **game engine**](https://docs.gdevelop.io/GDJS%20Runtime%20Documentation/classes/gdjs.Variable.html). This JavaScript class is what is used during a game.
|
||||
|
||||
The editor `gd::Variable` **knows nothing** about the game engine class `gdjs.Variable`. And the `gdjs.Variable` class in the game engine knows almost nothing from `gd::Variable` (apart from how it's written in JSON, to be able to load a game default variables).
|
||||
|
||||
@@ -56,10 +56,10 @@ The game engine is in GDJS/Runtime and is all written in TypeScript.
|
||||
|
||||
## What about events?
|
||||
|
||||
An "**event**" is by default something that [is mostly empty](https://docs.gdevelop-app.com/GDCore%20Documentation/classgd_1_1_base_event.html). In a more traditional programming language, an event can be seen as a scope or block (example: `{ some code here }` in a C style language like JavaScript, Java or C++).
|
||||
An "**event**" is by default something that [is mostly empty](https://docs.gdevelop.io/GDCore%20Documentation/classgd_1_1_base_event.html). In a more traditional programming language, an event can be seen as a scope or block (example: `{ some code here }` in a C style language like JavaScript, Java or C++).
|
||||
|
||||
[Default events are defined](https://github.com/4ian/GDevelop/tree/master/Core/GDCore/Events/Builtin) in GDevelop Core.
|
||||
In particular, there is StandardEvent, which has conditions and actions. Conditions and actions are both a list of [`gd::Instruction`](https://docs.gdevelop-app.com/GDCore%20Documentation/classgd_1_1_instruction.html). A `gd::Instruction` is either a condition or an action (it depends only on the context where they are used).
|
||||
In particular, there is StandardEvent, which has conditions and actions. Conditions and actions are both a list of [`gd::Instruction`](https://docs.gdevelop.io/GDCore%20Documentation/classgd_1_1_instruction.html). A `gd::Instruction` is either a condition or an action (it depends only on the context where they are used).
|
||||
|
||||
A `gd::Instruction` is "just" a type (the name of the action or condition), and some parameters. You can think of it as a function in a programming language (`add(2, 3)` is calling a function called "add" with parameters "2" and "3"). Conditions have the special thing that they are functions returning true or false (and potentially being used to do a filter on the objects being picked for next conditions and actions).
|
||||
|
||||
|
@@ -6,7 +6,7 @@ GDevelop Core is a portable C++ library, compiled to be used in JavaScript in th
|
||||
|
||||
## 1) Getting started 🤓
|
||||
|
||||
First, take a look at the _Readme.md_ at the root of the repository and the [developer documentation](https://docs.gdevelop-app.com/).
|
||||
First, take a look at the _Readme.md_ at the root of the repository and the [developer documentation](https://docs.gdevelop.io/).
|
||||
|
||||
## 2) How to contribute 😎
|
||||
|
||||
|
@@ -75,7 +75,11 @@ TEST_CASE("EventsList", "[common][events]") {
|
||||
|
||||
size_t endMemory = gd::SystemStats::GetUsedVirtualMemory();
|
||||
INFO("Memory used: " << endMemory - startMemory << "KB");
|
||||
REQUIRE(1500 >= endMemory - startMemory);
|
||||
#if defined(WINDOWS)
|
||||
REQUIRE(3000 >= endMemory - startMemory);
|
||||
#else
|
||||
REQUIRE(1500 >= endMemory - startMemory);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -31,7 +31,7 @@ TEST_CASE("EventsCodeGenerationContext", "[common][events]") {
|
||||
gd::EventsCodeGenerationContext c1(&maxDepth);
|
||||
c1.ObjectsListNeeded("c1.object1");
|
||||
c1.ObjectsListNeeded("c1.object2");
|
||||
c1.ObjectsListWithoutPickingNeeded("c1.noPicking1");
|
||||
c1.ObjectsListNeededOrEmptyIfJustDeclared("c1.noPicking1");
|
||||
|
||||
gd::EventsCodeGenerationContext c2;
|
||||
c2.InheritsFrom(c1);
|
||||
@@ -47,7 +47,7 @@ TEST_CASE("EventsCodeGenerationContext", "[common][events]") {
|
||||
|
||||
gd::EventsCodeGenerationContext c5;
|
||||
c5.InheritsFrom(c2);
|
||||
c5.ObjectsListWithoutPickingNeeded("c5.noPicking1");
|
||||
c5.ObjectsListNeededOrEmptyIfJustDeclared("c5.noPicking1");
|
||||
c5.ObjectsListNeeded("c5.object1");
|
||||
c5.ObjectsListNeeded("c1.object2");
|
||||
c5.EmptyObjectsListNeeded("c5.empty1");
|
||||
@@ -70,36 +70,36 @@ TEST_CASE("EventsCodeGenerationContext", "[common][events]") {
|
||||
}
|
||||
|
||||
SECTION("Object list needed") {
|
||||
REQUIRE(c1.GetObjectsListsAlreadyDeclared() == std::set<gd::String>());
|
||||
REQUIRE(c1.GetObjectsListsAlreadyDeclaredByParents() == std::set<gd::String>());
|
||||
REQUIRE(c1.GetObjectsListsToBeDeclared() ==
|
||||
std::set<gd::String>({"c1.object1", "c1.object2"}));
|
||||
REQUIRE(c1.GetObjectsListsToBeDeclaredWithoutPicking() ==
|
||||
REQUIRE(c1.GetObjectsListsToBeEmptyIfJustDeclared() ==
|
||||
std::set<gd::String>({"c1.noPicking1"}));
|
||||
REQUIRE(c1.GetAllObjectsToBeDeclared() ==
|
||||
std::set<gd::String>({"c1.object1", "c1.object2", "c1.noPicking1"}));
|
||||
|
||||
REQUIRE(c2.GetObjectsListsAlreadyDeclared() ==
|
||||
REQUIRE(c2.GetObjectsListsAlreadyDeclaredByParents() ==
|
||||
std::set<gd::String>({"c1.object1", "c1.object2", "c1.noPicking1"}));
|
||||
REQUIRE(c2.GetObjectsListsToBeDeclared() ==
|
||||
std::set<gd::String>({"c2.object1"}));
|
||||
REQUIRE(c2.GetObjectsListsToBeDeclaredWithoutPicking() == std::set<gd::String>());
|
||||
REQUIRE(c2.GetObjectsListsToBeEmptyIfJustDeclared() == std::set<gd::String>());
|
||||
REQUIRE(c2.GetAllObjectsToBeDeclared() ==
|
||||
std::set<gd::String>({"c2.object1"}));
|
||||
|
||||
REQUIRE(c3.GetObjectsListsAlreadyDeclared() ==
|
||||
REQUIRE(c3.GetObjectsListsAlreadyDeclaredByParents() ==
|
||||
std::set<gd::String>({"c1.object1", "c1.object2", "c1.noPicking1"}));
|
||||
REQUIRE(c3.GetObjectsListsToBeDeclared() ==
|
||||
std::set<gd::String>({"c3.object1", "c1.object2"}));
|
||||
REQUIRE(c3.GetObjectsListsToBeDeclaredWithoutPicking() == std::set<gd::String>());
|
||||
REQUIRE(c3.GetObjectsListsToBeEmptyIfJustDeclared() == std::set<gd::String>());
|
||||
REQUIRE(c3.GetAllObjectsToBeDeclared() ==
|
||||
std::set<gd::String>({"c3.object1", "c1.object2"}));
|
||||
|
||||
REQUIRE(c5.GetObjectsListsAlreadyDeclared() ==
|
||||
REQUIRE(c5.GetObjectsListsAlreadyDeclaredByParents() ==
|
||||
std::set<gd::String>(
|
||||
{"c1.object1", "c1.object2", "c1.noPicking1", "c2.object1"}));
|
||||
REQUIRE(c5.GetObjectsListsToBeDeclared() ==
|
||||
std::set<gd::String>({"c5.object1", "c1.object2"}));
|
||||
REQUIRE(c5.GetObjectsListsToBeDeclaredWithoutPicking() ==
|
||||
REQUIRE(c5.GetObjectsListsToBeEmptyIfJustDeclared() ==
|
||||
std::set<gd::String>({"c5.noPicking1"}));
|
||||
REQUIRE(c5.GetObjectsListsToBeDeclaredEmpty() ==
|
||||
std::set<gd::String>({"c5.empty1"}));
|
||||
@@ -107,22 +107,18 @@ TEST_CASE("EventsCodeGenerationContext", "[common][events]") {
|
||||
std::set<gd::String>({"c5.object1", "c5.noPicking1", "c1.object2", "c5.empty1"}));
|
||||
}
|
||||
|
||||
SECTION("ObjectAlreadyDeclared") {
|
||||
REQUIRE(c1.ObjectAlreadyDeclared("c1.object1") == false);
|
||||
REQUIRE(c2.ObjectAlreadyDeclared("c1.object1") == true);
|
||||
REQUIRE(c3.ObjectAlreadyDeclared("c1.object1") == true);
|
||||
REQUIRE(c4.ObjectAlreadyDeclared("c1.object1") == true);
|
||||
REQUIRE(c5.ObjectAlreadyDeclared("c1.object1") == true);
|
||||
SECTION("ObjectAlreadyDeclaredByParents") {
|
||||
REQUIRE(c1.ObjectAlreadyDeclaredByParents("c1.object1") == false);
|
||||
REQUIRE(c2.ObjectAlreadyDeclaredByParents("c1.object1") == true);
|
||||
REQUIRE(c3.ObjectAlreadyDeclaredByParents("c1.object1") == true);
|
||||
REQUIRE(c4.ObjectAlreadyDeclaredByParents("c1.object1") == true);
|
||||
REQUIRE(c5.ObjectAlreadyDeclaredByParents("c1.object1") == true);
|
||||
|
||||
REQUIRE(c2.ObjectAlreadyDeclared("c2.object1") == false);
|
||||
REQUIRE(c1.ObjectAlreadyDeclared("c2.object1") == false);
|
||||
REQUIRE(c3.ObjectAlreadyDeclared("c2.object1") == false);
|
||||
REQUIRE(c4.ObjectAlreadyDeclared("c2.object1") == true);
|
||||
REQUIRE(c5.ObjectAlreadyDeclared("c2.object1") == true);
|
||||
|
||||
REQUIRE(c3.ObjectAlreadyDeclared("some object") == false);
|
||||
c3.SetObjectDeclared("some object");
|
||||
REQUIRE(c3.ObjectAlreadyDeclared("some object") == true);
|
||||
REQUIRE(c1.ObjectAlreadyDeclaredByParents("c2.object1") == false);
|
||||
REQUIRE(c2.ObjectAlreadyDeclaredByParents("c2.object1") == false);
|
||||
REQUIRE(c3.ObjectAlreadyDeclaredByParents("c2.object1") == false);
|
||||
REQUIRE(c4.ObjectAlreadyDeclaredByParents("c2.object1") == true);
|
||||
REQUIRE(c5.ObjectAlreadyDeclaredByParents("c2.object1") == true);
|
||||
}
|
||||
|
||||
SECTION("Object list last depth") {
|
||||
@@ -186,4 +182,87 @@ TEST_CASE("EventsCodeGenerationContext", "[common][events]") {
|
||||
REQUIRE(c7.IsSameObjectsList("c6.object3", c6) == false);
|
||||
REQUIRE(c7.IsSameObjectsList("c5.empty1", c5) == false);
|
||||
}
|
||||
|
||||
SECTION("Async") {
|
||||
gd::EventsCodeGenerationContext c1;
|
||||
c1.ObjectsListNeeded("c1.object1");
|
||||
c1.ObjectsListNeeded("c1.object2");
|
||||
c1.ObjectsListNeededOrEmptyIfJustDeclared("c1.possiblyEmpty1");
|
||||
c1.EmptyObjectsListNeeded("c1.empty1");
|
||||
|
||||
gd::EventsCodeGenerationContext c2;
|
||||
c2.InheritsAsAsyncCallbackFrom(c1);
|
||||
c2.ObjectsListNeeded("c2.object1");
|
||||
c2.ObjectsListNeededOrEmptyIfJustDeclared("c2.possiblyEmpty1");
|
||||
c2.EmptyObjectsListNeeded("c2.empty1");
|
||||
c2.ObjectsListNeeded("c1.object1");
|
||||
|
||||
gd::EventsCodeGenerationContext c3;
|
||||
c3.InheritsAsAsyncCallbackFrom(c2);
|
||||
c3.ObjectsListNeeded("c3.object1");
|
||||
c3.ObjectsListNeededOrEmptyIfJustDeclared("c3.possiblyEmpty1");
|
||||
c3.EmptyObjectsListNeeded("c3.empty1");
|
||||
c3.ObjectsListNeeded("c1.object1");
|
||||
|
||||
gd::EventsCodeGenerationContext c4;
|
||||
c4.InheritsFrom(c3);
|
||||
c4.ObjectsListNeeded("c4.object1");
|
||||
c4.ObjectsListNeededOrEmptyIfJustDeclared("c4.possiblyEmpty1");
|
||||
c4.EmptyObjectsListNeeded("c4.empty1");
|
||||
c4.ObjectsListNeeded("c1.object1");
|
||||
c4.ObjectsListNeeded("c1.object2");
|
||||
|
||||
gd::EventsCodeGenerationContext c5;
|
||||
c5.InheritsFrom(c4);
|
||||
c5.ObjectsListNeeded("c5.object1");
|
||||
c5.ObjectsListNeededOrEmptyIfJustDeclared("c5.possiblyEmpty1");
|
||||
c5.EmptyObjectsListNeeded("c5.empty1");
|
||||
c5.ObjectsListNeeded("c1.object1");
|
||||
c5.ObjectsListNeeded("c1.object2");
|
||||
|
||||
REQUIRE(c1.ShouldUseAsyncObjectsList("c1.object1") == false);
|
||||
REQUIRE(c1.ShouldUseAsyncObjectsList("c1.possiblyEmpty1") == false);
|
||||
REQUIRE(c1.ShouldUseAsyncObjectsList("c1.empty1") == false);
|
||||
|
||||
// Objects declared in async callback are used traditionally:
|
||||
REQUIRE(c2.ShouldUseAsyncObjectsList("c2.object1") == false);
|
||||
REQUIRE(c2.ShouldUseAsyncObjectsList("c2.possiblyEmpty1") == false);
|
||||
REQUIRE(c2.ShouldUseAsyncObjectsList("c2.empty1") == false);
|
||||
|
||||
// Objects declared in c1 are gotten from the async list in c2 and c3
|
||||
// because these contexts use them and are async.
|
||||
REQUIRE(c2.ShouldUseAsyncObjectsList("c1.object1") == true);
|
||||
REQUIRE(c3.ShouldUseAsyncObjectsList("c1.object1") == true);
|
||||
REQUIRE(c4.ShouldUseAsyncObjectsList("c1.object1") == false);
|
||||
REQUIRE(c5.ShouldUseAsyncObjectsList("c1.object1") == false);
|
||||
|
||||
// Objects declared in c1 are gotten from the async list in c4
|
||||
// because c3 is async (but is not using them)
|
||||
REQUIRE(c4.ShouldUseAsyncObjectsList("c1.object2") == true);
|
||||
|
||||
// Objects declared in c1 but gotten from the async list in c4
|
||||
// is used traditionnally:
|
||||
REQUIRE(c5.ShouldUseAsyncObjectsList("c1.object2") == false);
|
||||
|
||||
// Objects declared in or after c3 are used traditionally:
|
||||
REQUIRE(c3.ShouldUseAsyncObjectsList("c3.object1") == false);
|
||||
REQUIRE(c4.ShouldUseAsyncObjectsList("c3.object1") == false);
|
||||
REQUIRE(c5.ShouldUseAsyncObjectsList("c3.object1") == false);
|
||||
REQUIRE(c3.ShouldUseAsyncObjectsList("c3.possiblyEmpty1") == false);
|
||||
REQUIRE(c4.ShouldUseAsyncObjectsList("c3.possiblyEmpty1") == false);
|
||||
REQUIRE(c5.ShouldUseAsyncObjectsList("c3.possiblyEmpty1") == false);
|
||||
REQUIRE(c3.ShouldUseAsyncObjectsList("c3.empty1") == false);
|
||||
REQUIRE(c4.ShouldUseAsyncObjectsList("c3.empty1") == false);
|
||||
REQUIRE(c5.ShouldUseAsyncObjectsList("c3.empty1") == false);
|
||||
REQUIRE(c4.ShouldUseAsyncObjectsList("c4.object1") == false);
|
||||
REQUIRE(c4.ShouldUseAsyncObjectsList("c4.possiblyEmpty1") == false);
|
||||
REQUIRE(c4.ShouldUseAsyncObjectsList("c4.empty1") == false);
|
||||
REQUIRE(c5.ShouldUseAsyncObjectsList("c4.object1") == false);
|
||||
REQUIRE(c5.ShouldUseAsyncObjectsList("c4.possiblyEmpty1") == false);
|
||||
REQUIRE(c5.ShouldUseAsyncObjectsList("c4.empty1") == false);
|
||||
REQUIRE(c5.ShouldUseAsyncObjectsList("c5.object1") == false);
|
||||
REQUIRE(c5.ShouldUseAsyncObjectsList("c5.possiblyEmpty1") == false);
|
||||
REQUIRE(c5.ShouldUseAsyncObjectsList("c5.empty1") == false);
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
/**
|
||||
* @file Tests covering FileStream class of GDevelop Core.
|
||||
*/
|
||||
#include "GDCore/Tools/FileStream.h"
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
TEST_CASE("FileStream", "[common][fstream]") {
|
||||
// Creating the test file
|
||||
std::ofstream testFile("FileStreamTest.test");
|
||||
REQUIRE(testFile.is_open());
|
||||
|
||||
testFile << "this is the first line of the test file!\n";
|
||||
testFile << "the last line!";
|
||||
testFile.close();
|
||||
|
||||
SECTION("Input file") {
|
||||
gd::FileStream f;
|
||||
f.open("FileStreamTest.test", std::ios_base::in);
|
||||
|
||||
REQUIRE(f.is_open() == true);
|
||||
REQUIRE(f.tellg() == 0);
|
||||
|
||||
std::string lineContent;
|
||||
REQUIRE(f.eof() == false);
|
||||
std::getline(f, lineContent);
|
||||
REQUIRE(lineContent == "this is the first line of the test file!");
|
||||
|
||||
REQUIRE(f.eof() == false);
|
||||
std::getline(f, lineContent);
|
||||
REQUIRE(lineContent == "the last line!");
|
||||
|
||||
REQUIRE(f.eof() == true);
|
||||
REQUIRE(f.fail() == false);
|
||||
|
||||
f.close();
|
||||
REQUIRE(f.is_open() == false);
|
||||
REQUIRE(f.fail() == false);
|
||||
}
|
||||
|
||||
SECTION("Output/Input file with special characters in filepath") {
|
||||
gd::FileStream output("\xEA\x88\xA1.txt", std::ios_base::out);
|
||||
REQUIRE(output.is_open() == true);
|
||||
|
||||
output << "TEST";
|
||||
output.close();
|
||||
|
||||
gd::FileStream input("\xEA\x88\xA1.txt", std::ios_base::in);
|
||||
REQUIRE(input.is_open() == true);
|
||||
|
||||
std::string lineContent;
|
||||
REQUIRE(input.eof() == false);
|
||||
std::getline(input, lineContent);
|
||||
REQUIRE(lineContent == "TEST");
|
||||
|
||||
REQUIRE(input.eof() == true);
|
||||
|
||||
input.close();
|
||||
REQUIRE(input.is_open() == false);
|
||||
REQUIRE(input.fail() == false);
|
||||
}
|
||||
|
||||
SECTION("File opening failure") {
|
||||
gd::FileStream f("\xE4\x84\xA2",
|
||||
std::ios_base::in); // A file that doesn't exist
|
||||
|
||||
REQUIRE(f.is_open() == false);
|
||||
REQUIRE(f.fail() ==
|
||||
true); // As the opening failed, the "fail" flag should be set
|
||||
|
||||
f.close();
|
||||
REQUIRE(f.bad() == true); // As no files are opened, this should set the
|
||||
// "bad" flag of the stream
|
||||
}
|
||||
|
||||
SECTION("std::ios_base::ate") { // As ate is "emulated", needs testing
|
||||
gd::FileStream f;
|
||||
f.open("FileStreamTest.test", std::ios_base::in | std::ios_base::ate);
|
||||
|
||||
REQUIRE(f.is_open() == true);
|
||||
REQUIRE(f.tellg() > 0);
|
||||
}
|
||||
}
|
@@ -7,7 +7,6 @@
|
||||
* @file Tests covering utf8 features from GDevelop Core.
|
||||
*/
|
||||
|
||||
#include <SFML/System/String.hpp>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
@@ -19,10 +18,8 @@ TEST_CASE("Utf8 String", "[common][utf8]") {
|
||||
SECTION("ctor & conversions") {
|
||||
gd::String str = u8"UTF8 a été testé !";
|
||||
|
||||
sf::String sfStr = str;
|
||||
std::u32string u32str = str.ToUTF32();
|
||||
|
||||
REQUIRE(str == gd::String::FromSfString(sfStr));
|
||||
REQUIRE(str == gd::String::FromUTF32(u32str));
|
||||
}
|
||||
|
||||
@@ -42,8 +39,10 @@ TEST_CASE("Utf8 String", "[common][utf8]") {
|
||||
|
||||
REQUIRE(str.substr(5, 7) == u8"a été t");
|
||||
REQUIRE(str.substr(5, gd::String::npos) == u8"a été testé !");
|
||||
|
||||
REQUIRE_THROWS_AS(str.substr(50, 5), std::out_of_range);
|
||||
// Windows doesn't seems to like exceptions.
|
||||
#if !defined(WINDOWS)
|
||||
REQUIRE_THROWS_AS(str.substr(50, 5), std::out_of_range);
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("insert") {
|
||||
@@ -51,7 +50,9 @@ TEST_CASE("Utf8 String", "[common][utf8]") {
|
||||
str.insert(25, u8"vraiment ");
|
||||
|
||||
REQUIRE(str == u8"Une fonctionnalité a été vraiment testée !");
|
||||
REQUIRE_THROWS_AS(str.insert(150, u8"This gonna fail"), std::out_of_range);
|
||||
#if !defined(WINDOWS)
|
||||
REQUIRE_THROWS_AS(str.insert(150, u8"This gonna fail"), std::out_of_range);
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("replace") {
|
||||
@@ -62,8 +63,10 @@ TEST_CASE("Utf8 String", "[common][utf8]") {
|
||||
REQUIRE(str.replace(11, gd::String::npos, u8"vraiment très testé !") ==
|
||||
u8"UTF8 a été vraiment très testé !");
|
||||
|
||||
REQUIRE_THROWS_AS(str.replace(50, 5, u8"Cela va planter."),
|
||||
std::out_of_range);
|
||||
#if !defined(WINDOWS)
|
||||
REQUIRE_THROWS_AS(str.replace(50, 5, u8"Cela va planter."),
|
||||
std::out_of_range);
|
||||
#endif
|
||||
|
||||
// Testing the iterator version of replace
|
||||
gd::String str2 = u8"UTF8 a été testé !";
|
||||
@@ -94,8 +97,10 @@ TEST_CASE("Utf8 String", "[common][utf8]") {
|
||||
REQUIRE(str == "UTF8");
|
||||
}
|
||||
{
|
||||
gd::String str = u8"UTF8 a été testé !";
|
||||
REQUIRE_THROWS_AS(str.erase(100, 5), std::out_of_range);
|
||||
#if !defined(WINDOWS)
|
||||
gd::String str = u8"UTF8 a été testé !";
|
||||
REQUIRE_THROWS_AS(str.erase(100, 5), std::out_of_range);
|
||||
#endif
|
||||
}
|
||||
{
|
||||
gd::String str = u8"UTF8 a été testé !";
|
||||
|
@@ -1,54 +0,0 @@
|
||||
# Clone SFML from its official directory using Git. Only
|
||||
# do it if not already cloned to avoid triggering a whole
|
||||
# recompilation every time CMake is run.
|
||||
find_package(Git)
|
||||
if(GIT_FOUND)
|
||||
if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/SFML/readme.txt")
|
||||
message( "Cloning SFML in ExtLibs/SFML with Git..." )
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} clone "https://www.github.com/SFML/SFML.git" SFML
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
|
||||
OUTPUT_QUIET)
|
||||
|
||||
message( "Resetting SFML source code to version 2.4.1..." )
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} reset --hard 2.4.1
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/SFML
|
||||
OUTPUT_QUIET)
|
||||
|
||||
message( "Applying the patches..." )
|
||||
file(GLOB SFML_PATCHES
|
||||
LIST_DIRECTORIES FALSE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/SFML-patches/*.patch)
|
||||
|
||||
if(SFML_PATCHES)
|
||||
list(SORT SFML_PATCHES)
|
||||
|
||||
foreach(SFML_PATCH ${SFML_PATCHES})
|
||||
message( "Applying patch: ${SFML_PATCH}..." )
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} apply ${SFML_PATCH} --ignore-whitespace
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/SFML
|
||||
OUTPUT_QUIET)
|
||||
endforeach()
|
||||
endif()
|
||||
else()
|
||||
message( "SFML already downloaded." )
|
||||
endif()
|
||||
else()
|
||||
message( "Git not found, make sure you have SFML >= 2.4 in ExtLibs/SFML and you applied the needed patches (from ExtLibs/SFML-patches)!" )
|
||||
endif()
|
||||
|
||||
#SFML:
|
||||
IF(NOT EMSCRIPTEN) #Don't build SFML binaries when compiling with emscripten (but keep include files!)
|
||||
add_subdirectory(SFML)
|
||||
set(sfml_lib_dir ${CMAKE_BINARY_DIR}/ExtLibs/SFML/lib PARENT_SCOPE)
|
||||
set(sfml_LIBRARIES sfml-audio sfml-graphics sfml-window sfml-network sfml-system)
|
||||
IF(WIN32)
|
||||
set(sfml_LIBRARIES "${sfml_LIBRARIES}" ws2_32 user32 opengl32 glu32 psapi)
|
||||
ELSEIF(NOT APPLE)
|
||||
set(sfml_LIBRARIES "${sfml_LIBRARIES}" GLU GL)
|
||||
ENDIF()
|
||||
set(sfml_LIBRARIES "${sfml_LIBRARIES}" PARENT_SCOPE)
|
||||
ENDIF()
|
||||
set(sfml_include_dir ${CMAKE_CURRENT_SOURCE_DIR}/SFML/include PARENT_SCOPE)
|
||||
|
@@ -1,2 +0,0 @@
|
||||
Uncompress here the external libraries needed: SFML.
|
||||
Refer to [the documentation](https://docs.gdevelop-app.com/GDCore%20Documentation/setup_dev_env.html) for more information and to get the download links of the libraries.
|
@@ -1,19 +0,0 @@
|
||||
diff --git a/extlibs/headers/stb_image/stb_image.h b/extlibs/headers/stb_image/stb_image.h
|
||||
index c3945c2..5fe1050 100644
|
||||
--- a/extlibs/headers/stb_image/stb_image.h
|
||||
+++ b/extlibs/headers/stb_image/stb_image.h
|
||||
@@ -671,14 +671,9 @@ static int stbi__sse2_available()
|
||||
|
||||
static int stbi__sse2_available()
|
||||
{
|
||||
-#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 // GCC 4.8 or later
|
||||
- // GCC 4.8+ has a nice way to do this
|
||||
- return __builtin_cpu_supports("sse2");
|
||||
-#else
|
||||
// portable way to do this, preferably without using GCC inline ASM?
|
||||
// just bail for now.
|
||||
return 0;
|
||||
-#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
@@ -1,29 +0,0 @@
|
||||
From f55ee73a73398bb77ce9c63ff1a13d8053cb1d18 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Rival <Florian.Rival@gmail.com>
|
||||
Date: Tue, 3 Jan 2017 21:15:11 +0100
|
||||
Subject: [PATCH] Fix crash with SFML embeded in wxWidgets on OS X
|
||||
|
||||
---
|
||||
src/SFML/Window/OSX/SFViewController.mm | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/src/SFML/Window/OSX/SFViewController.mm b/src/SFML/Window/OSX/SFViewController.mm
|
||||
index 7d736e3..280ec2b 100644
|
||||
--- a/src/SFML/Window/OSX/SFViewController.mm
|
||||
+++ b/src/SFML/Window/OSX/SFViewController.mm
|
||||
@@ -82,8 +82,12 @@ -(id)initWithView:(NSView *)view
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)dealloc
|
||||
{
|
||||
+ NSLog(@"SFViewController::dealloc called on %@", self);
|
||||
[self closeWindow];
|
||||
|
||||
+
|
||||
+ // See https://github.com/SFML/SFML/issues/824
|
||||
+ [[NSNotificationCenter defaultCenter] removeObserver:m_oglView];
|
||||
[m_view release];
|
||||
[m_oglView release];
|
||||
|
||||
--
|
||||
2.7.4 (Apple Git-66)
|
||||
|
@@ -1,13 +0,0 @@
|
||||
diff --git a/include/SFML/Config.hpp b/include/SFML/Config.hpp
|
||||
index 9c68d84..2522d88 100644
|
||||
--- a/include/SFML/Config.hpp
|
||||
+++ b/include/SFML/Config.hpp
|
||||
@@ -76,7 +76,7 @@
|
||||
// Android
|
||||
#define SFML_SYSTEM_ANDROID
|
||||
|
||||
- #elif defined(__linux__)
|
||||
+ #elif defined(__linux__) || defined(EMSCRIPTEN)
|
||||
|
||||
// Linux
|
||||
#define SFML_SYSTEM_LINUX
|
@@ -45,6 +45,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Focus the window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -61,6 +62,7 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -79,6 +81,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Show window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -95,6 +98,7 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -113,6 +117,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Maximize window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -129,6 +134,7 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -147,6 +153,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Minimize window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -163,6 +170,7 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -181,6 +189,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Enable window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -197,6 +206,7 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -215,6 +225,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Allow resizing?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -231,6 +242,7 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -249,6 +261,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Allow moving?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -265,6 +278,7 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -283,6 +297,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Allow maximizing?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -299,6 +314,7 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -317,6 +333,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Allow minimizing?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -333,6 +350,7 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -351,6 +369,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Allow full-screening?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -367,6 +386,7 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -385,6 +405,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Allow closing?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -401,6 +422,7 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -442,6 +464,7 @@ module.exports = {
|
||||
'above the taskbar on Windows. ' +
|
||||
'This parameter is ignored on linux.'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -458,6 +481,7 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -478,6 +502,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Enable kiosk mode?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -494,6 +519,7 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -512,6 +538,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Enable shadow?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -528,6 +555,7 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -548,6 +576,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Enable content protection?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -566,6 +595,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Allow focus?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -584,6 +614,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Flash the window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -604,6 +635,7 @@ module.exports = {
|
||||
.setParameterLongDescription(
|
||||
'A number between 0 (fully transparent) and 1 (fully opaque).'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -622,6 +654,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('expression', _('X position'), '', false)
|
||||
.addParameter('expression', _('Y position'), '', false)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -636,6 +669,7 @@ module.exports = {
|
||||
_('Windows, Linux, macOS'),
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -650,6 +684,7 @@ module.exports = {
|
||||
_('Windows, Linux, macOS'),
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -666,6 +701,7 @@ module.exports = {
|
||||
_('Windows, Linux, macOS'),
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
|
@@ -6,16 +6,23 @@ namespace gdjs {
|
||||
*/
|
||||
export namespace evtTools {
|
||||
export namespace advancedWindow {
|
||||
/**
|
||||
* The game's BrowserWindow instance (or null on
|
||||
* non-electron platforms).
|
||||
*/
|
||||
let electronBrowserWindow: any = null;
|
||||
const getElectronBrowserWindow = (runtimeScene: gdjs.RuntimeScene) => {
|
||||
const electronRemote = runtimeScene
|
||||
.getGame()
|
||||
.getRenderer()
|
||||
.getElectronRemote();
|
||||
if (electronRemote) {
|
||||
return electronRemote.getCurrentWindow();
|
||||
}
|
||||
|
||||
if (typeof require === 'function') {
|
||||
electronBrowserWindow = require('electron').remote.getCurrentWindow();
|
||||
}
|
||||
export const focus = function (activate: boolean) {
|
||||
return null;
|
||||
};
|
||||
|
||||
export const focus = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
if (activate) {
|
||||
electronBrowserWindow.focus();
|
||||
@@ -25,14 +32,21 @@ namespace gdjs {
|
||||
}
|
||||
};
|
||||
|
||||
export const isFocused = function (): boolean {
|
||||
export const isFocused = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isFocused();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const show = function (activate: boolean) {
|
||||
export const show = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
if (activate) {
|
||||
electronBrowserWindow.showInactive();
|
||||
@@ -42,14 +56,21 @@ namespace gdjs {
|
||||
}
|
||||
};
|
||||
|
||||
export const isVisible = function (): boolean {
|
||||
export const isVisible = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isVisible();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const maximize = function (activate: boolean) {
|
||||
export const maximize = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
if (activate) {
|
||||
electronBrowserWindow.maximize();
|
||||
@@ -59,14 +80,21 @@ namespace gdjs {
|
||||
}
|
||||
};
|
||||
|
||||
export const isMaximized = function (): boolean {
|
||||
export const isMaximized = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isMaximized();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const minimize = function (activate: boolean) {
|
||||
export const minimize = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
if (activate) {
|
||||
electronBrowserWindow.minimize();
|
||||
@@ -76,98 +104,150 @@ namespace gdjs {
|
||||
}
|
||||
};
|
||||
|
||||
export const isMinimized = function (): boolean {
|
||||
export const isMinimized = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isMinimized();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const enable = function (activate: boolean) {
|
||||
export const enable = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setEnabled(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isEnabled = function (): boolean {
|
||||
export const isEnabled = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isEnabled();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setResizable = function (activate: boolean) {
|
||||
export const setResizable = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setResizable(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isResizable = function (): boolean {
|
||||
export const isResizable = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isResizable();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setMovable = function (activate: boolean) {
|
||||
export const setMovable = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setMovable(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isMovable = function (): boolean {
|
||||
export const isMovable = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isMovable();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setMaximizable = function (activate: boolean) {
|
||||
export const setMaximizable = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setMaximizable(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isMaximizable = function (): boolean {
|
||||
export const isMaximizable = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isMaximizable();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setMinimizable = function (activate: boolean) {
|
||||
export const setMinimizable = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setMinimizable(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isMinimizable = function (): boolean {
|
||||
export const isMinimizable = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isMinimizable();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setFullScreenable = function (activate: boolean) {
|
||||
export const setFullScreenable = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setFullScreenable(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isFullScreenable = function (): boolean {
|
||||
export const isFullScreenable = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isFullScreenable();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setClosable = function (activate: boolean) {
|
||||
export const setClosable = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setClosable(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isClosable = function (): boolean {
|
||||
export const isClosable = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isClosable();
|
||||
}
|
||||
@@ -184,93 +264,142 @@ namespace gdjs {
|
||||
| 'main-menu'
|
||||
| 'status'
|
||||
| 'pop-up-menu'
|
||||
| 'screen-saver'
|
||||
| 'screen-saver',
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setAlwaysOnTop(activate, level);
|
||||
}
|
||||
};
|
||||
|
||||
export const isAlwaysOnTop = function (): boolean {
|
||||
export const isAlwaysOnTop = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isAlwaysOnTop();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setPosition = function (x: float, y: float) {
|
||||
export const setPosition = function (
|
||||
x: float,
|
||||
y: float,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
// Convert x and y to (32 bit) integers to avoid Electron errors.
|
||||
electronBrowserWindow.setPosition(~~x, ~~y);
|
||||
}
|
||||
};
|
||||
|
||||
export const getPositionX = function (): number {
|
||||
export const getPositionX = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): number {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.getPosition()[0];
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
export const getPositionY = function (): number {
|
||||
export const getPositionY = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): number {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.getPosition()[1];
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
export const setKiosk = function (activate: boolean) {
|
||||
export const setKiosk = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setKiosk(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isKiosk = function (): boolean {
|
||||
export const isKiosk = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isKiosk();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const flash = function (activate: boolean) {
|
||||
export const flash = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.flashFrame(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const setHasShadow = function (activate: boolean) {
|
||||
export const setHasShadow = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setHasShadow(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const hasShadow = function (): boolean {
|
||||
export const hasShadow = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.hasShadow();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setOpacity = function (opacity: float) {
|
||||
export const setOpacity = function (
|
||||
opacity: float,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setOpacity(opacity);
|
||||
}
|
||||
};
|
||||
|
||||
export const getOpacity = function (): number {
|
||||
export const getOpacity = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): number {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.getOpacity();
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
|
||||
export const setContentProtection = function (activate: boolean) {
|
||||
export const setContentProtection = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setContentProtection(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const setFocusable = function (activate: boolean) {
|
||||
export const setFocusable = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setFocusable(activate);
|
||||
}
|
||||
|
@@ -5,7 +5,9 @@ Copyright (c) 2016 Victor Levasseur (victorlevasseur52@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
#include "AnchorBehavior.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
@@ -20,6 +22,7 @@ void AnchorBehavior::InitializeContent(gd::SerializerElement& content) {
|
||||
content.SetAttribute("topEdgeAnchor", static_cast<int>(ANCHOR_VERTICAL_NONE));
|
||||
content.SetAttribute("bottomEdgeAnchor",
|
||||
static_cast<int>(ANCHOR_VERTICAL_NONE));
|
||||
content.SetAttribute("useLegacyBottomAndRightAnchors", false);
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
@@ -68,7 +71,7 @@ std::map<gd::String, gd::PropertyDescriptor> AnchorBehavior::GetProperties(
|
||||
.AddExtraInfo(_("Window left"))
|
||||
.AddExtraInfo(_("Window right"))
|
||||
.AddExtraInfo(_("Proportional"))
|
||||
.SetDescription(_("Use this to anchor the object on X axis."));
|
||||
.SetDescription(_("Anchor the left edge of the object on X axis."));
|
||||
|
||||
properties[_("Right edge anchor")]
|
||||
.SetValue(GetAnchorAsString(static_cast<HorizontalAnchor>(
|
||||
@@ -77,7 +80,8 @@ std::map<gd::String, gd::PropertyDescriptor> AnchorBehavior::GetProperties(
|
||||
.AddExtraInfo(_("No anchor"))
|
||||
.AddExtraInfo(_("Window left"))
|
||||
.AddExtraInfo(_("Window right"))
|
||||
.AddExtraInfo(_("Proportional"));
|
||||
.AddExtraInfo(_("Proportional"))
|
||||
.SetDescription(_("Anchor the right edge of the object on X axis."));
|
||||
|
||||
properties[_("Top edge anchor")]
|
||||
.SetValue(GetAnchorAsString(static_cast<VerticalAnchor>(
|
||||
@@ -87,7 +91,7 @@ std::map<gd::String, gd::PropertyDescriptor> AnchorBehavior::GetProperties(
|
||||
.AddExtraInfo(_("Window top"))
|
||||
.AddExtraInfo(_("Window bottom"))
|
||||
.AddExtraInfo(_("Proportional"))
|
||||
.SetDescription(_("Use this to anchor the object on Y axis."));
|
||||
.SetDescription(_("Anchor the top edge of the object on Y axis."));
|
||||
|
||||
properties[_("Bottom edge anchor")]
|
||||
.SetValue(GetAnchorAsString(static_cast<VerticalAnchor>(
|
||||
@@ -96,7 +100,20 @@ std::map<gd::String, gd::PropertyDescriptor> AnchorBehavior::GetProperties(
|
||||
.AddExtraInfo(_("No anchor"))
|
||||
.AddExtraInfo(_("Window top"))
|
||||
.AddExtraInfo(_("Window bottom"))
|
||||
.AddExtraInfo(_("Proportional"));
|
||||
.AddExtraInfo(_("Proportional"))
|
||||
.SetDescription(_("Anchor the bottom edge of the object on Y axis."));
|
||||
|
||||
properties[("useLegacyBottomAndRightAnchors")]
|
||||
.SetLabel(_(
|
||||
"Stretch object when anchoring right or bottom ledge (deprecated, "
|
||||
"it's recommended to let this unchecked and anchor both sides if you "
|
||||
"want Sprite to stretch instead.)"))
|
||||
.SetGroup(_("Deprecated options (advanced)"))
|
||||
.SetValue(behaviorContent.GetBoolAttribute(
|
||||
"useLegacyBottomAndRightAnchors", true)
|
||||
? "true"
|
||||
: "false")
|
||||
.SetType("Boolean");
|
||||
|
||||
return properties;
|
||||
}
|
||||
@@ -147,6 +164,9 @@ bool AnchorBehavior::UpdateProperty(gd::SerializerElement& behaviorContent,
|
||||
behaviorContent.SetAttribute(
|
||||
"bottomEdgeAnchor",
|
||||
static_cast<int>(GetVerticalAnchorFromString(value)));
|
||||
else if (name == "useLegacyBottomAndRightAnchors")
|
||||
behaviorContent.SetAttribute("useLegacyBottomAndRightAnchors",
|
||||
(value == "1"));
|
||||
else
|
||||
return false;
|
||||
|
||||
|
@@ -15,6 +15,7 @@ namespace gdjs {
|
||||
_rightEdgeDistance: number = 0;
|
||||
_topEdgeDistance: number = 0;
|
||||
_bottomEdgeDistance: number = 0;
|
||||
_useLegacyBottomAndRightAnchors: boolean = false;
|
||||
|
||||
constructor(runtimeScene, behaviorData, owner) {
|
||||
super(runtimeScene, behaviorData, owner);
|
||||
@@ -23,6 +24,10 @@ namespace gdjs {
|
||||
this._rightEdgeAnchor = behaviorData.rightEdgeAnchor;
|
||||
this._topEdgeAnchor = behaviorData.topEdgeAnchor;
|
||||
this._bottomEdgeAnchor = behaviorData.bottomEdgeAnchor;
|
||||
this._useLegacyBottomAndRightAnchors =
|
||||
behaviorData.useLegacyBottomAndRightAnchors === undefined
|
||||
? true
|
||||
: behaviorData.useLegacyBottomAndRightAnchors;
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
@@ -40,6 +45,13 @@ namespace gdjs {
|
||||
) {
|
||||
this._bottomEdgeAnchor = newBehaviorData.bottomEdgeAnchor;
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.useLegacyTrajectory !==
|
||||
newBehaviorData.useLegacyTrajectory
|
||||
) {
|
||||
this._useLegacyBottomAndRightAnchors =
|
||||
newBehaviorData.useLegacyBottomAndRightAnchors;
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.relativeToOriginalWindowSize !==
|
||||
newBehaviorData.relativeToOriginalWindowSize
|
||||
@@ -262,28 +274,94 @@ namespace gdjs {
|
||||
bottomPixel
|
||||
);
|
||||
|
||||
//Move and resize the object according to the anchors
|
||||
if (
|
||||
this._rightEdgeAnchor !== AnchorRuntimeBehavior.HorizontalAnchor.NONE
|
||||
) {
|
||||
this.owner.setWidth(bottomRightCoord[0] - topLeftCoord[0]);
|
||||
// Compatibility with GD <= 5.0.133
|
||||
if (this._useLegacyBottomAndRightAnchors) {
|
||||
//Move and resize the object according to the anchors
|
||||
if (
|
||||
this._rightEdgeAnchor !==
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.NONE
|
||||
) {
|
||||
this.owner.setWidth(bottomRightCoord[0] - topLeftCoord[0]);
|
||||
}
|
||||
if (
|
||||
this._bottomEdgeAnchor !== AnchorRuntimeBehavior.VerticalAnchor.NONE
|
||||
) {
|
||||
this.owner.setHeight(bottomRightCoord[1] - topLeftCoord[1]);
|
||||
}
|
||||
if (
|
||||
this._leftEdgeAnchor !== AnchorRuntimeBehavior.HorizontalAnchor.NONE
|
||||
) {
|
||||
this.owner.setX(
|
||||
topLeftCoord[0] + this.owner.getX() - this.owner.getDrawableX()
|
||||
);
|
||||
}
|
||||
if (
|
||||
this._topEdgeAnchor !== AnchorRuntimeBehavior.VerticalAnchor.NONE
|
||||
) {
|
||||
this.owner.setY(
|
||||
topLeftCoord[1] + this.owner.getY() - this.owner.getDrawableY()
|
||||
);
|
||||
}
|
||||
}
|
||||
if (
|
||||
this._bottomEdgeAnchor !== AnchorRuntimeBehavior.VerticalAnchor.NONE
|
||||
) {
|
||||
this.owner.setHeight(bottomRightCoord[1] - topLeftCoord[1]);
|
||||
}
|
||||
if (
|
||||
this._leftEdgeAnchor !== AnchorRuntimeBehavior.HorizontalAnchor.NONE
|
||||
) {
|
||||
this.owner.setX(
|
||||
topLeftCoord[0] + this.owner.getX() - this.owner.getDrawableX()
|
||||
);
|
||||
}
|
||||
if (this._topEdgeAnchor !== AnchorRuntimeBehavior.VerticalAnchor.NONE) {
|
||||
this.owner.setY(
|
||||
topLeftCoord[1] + this.owner.getY() - this.owner.getDrawableY()
|
||||
);
|
||||
// End of compatibility code
|
||||
else {
|
||||
// Resize if right and left anchors are set
|
||||
if (
|
||||
this._rightEdgeAnchor !==
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.NONE &&
|
||||
this._leftEdgeAnchor !== AnchorRuntimeBehavior.HorizontalAnchor.NONE
|
||||
) {
|
||||
this.owner.setWidth(bottomRightCoord[0] - topLeftCoord[0]);
|
||||
this.owner.setX(topLeftCoord[0]);
|
||||
} else {
|
||||
if (
|
||||
this._leftEdgeAnchor !==
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.NONE
|
||||
) {
|
||||
this.owner.setX(
|
||||
topLeftCoord[0] + this.owner.getX() - this.owner.getDrawableX()
|
||||
);
|
||||
}
|
||||
if (
|
||||
this._rightEdgeAnchor !==
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.NONE
|
||||
) {
|
||||
this.owner.setX(
|
||||
bottomRightCoord[0] +
|
||||
this.owner.getX() -
|
||||
this.owner.getDrawableX() -
|
||||
this.owner.getWidth()
|
||||
);
|
||||
}
|
||||
}
|
||||
// Resize if top and bottom anchors are set
|
||||
if (
|
||||
this._bottomEdgeAnchor !==
|
||||
AnchorRuntimeBehavior.VerticalAnchor.NONE &&
|
||||
this._topEdgeAnchor !== AnchorRuntimeBehavior.VerticalAnchor.NONE
|
||||
) {
|
||||
this.owner.setHeight(bottomRightCoord[1] - topLeftCoord[1]);
|
||||
this.owner.setY(topLeftCoord[1]);
|
||||
} else {
|
||||
if (
|
||||
this._topEdgeAnchor !== AnchorRuntimeBehavior.VerticalAnchor.NONE
|
||||
) {
|
||||
this.owner.setY(
|
||||
topLeftCoord[1] + this.owner.getY() - this.owner.getDrawableY()
|
||||
);
|
||||
}
|
||||
if (
|
||||
this._bottomEdgeAnchor !==
|
||||
AnchorRuntimeBehavior.VerticalAnchor.NONE
|
||||
) {
|
||||
this.owner.setY(
|
||||
bottomRightCoord[1] +
|
||||
this.owner.getY() -
|
||||
this.owner.getDrawableY() -
|
||||
this.owner.getHeight()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
204
Extensions/AnchorBehavior/tests/anchorruntimebehavior.spec.js
Normal file
204
Extensions/AnchorBehavior/tests/anchorruntimebehavior.spec.js
Normal file
@@ -0,0 +1,204 @@
|
||||
// @ts-check
|
||||
describe.only('gdjs.AnchorRuntimeBehavior', function () {
|
||||
const runtimeGame = new gdjs.RuntimeGame({
|
||||
variables: [],
|
||||
resources: { resources: [] },
|
||||
// @ts-ignore
|
||||
properties: { windowWidth: 1000, windowHeight: 1000 },
|
||||
});
|
||||
const anchorBehaviorName = 'Anchor';
|
||||
const runtimeScene = new gdjs.RuntimeScene(runtimeGame);
|
||||
runtimeScene.loadFromScene({
|
||||
layers: [
|
||||
{
|
||||
name: '',
|
||||
visibility: true,
|
||||
cameras: [],
|
||||
effects: [],
|
||||
ambientLightColorR: 127,
|
||||
ambientLightColorB: 127,
|
||||
ambientLightColorG: 127,
|
||||
isLightingLayer: false,
|
||||
followBaseLayerCamera: false,
|
||||
},
|
||||
],
|
||||
variables: [],
|
||||
r: 0,
|
||||
v: 0,
|
||||
b: 0,
|
||||
mangledName: 'Scene1',
|
||||
name: 'Scene1',
|
||||
stopSoundsOnStartup: false,
|
||||
title: '',
|
||||
behaviorsSharedData: [],
|
||||
objects: [],
|
||||
instances: [],
|
||||
});
|
||||
|
||||
function createObject(behaviorProperties) {
|
||||
const object = new gdjs.TestRuntimeObject(runtimeScene, {
|
||||
name: 'obj1',
|
||||
type: '',
|
||||
behaviors: [
|
||||
{
|
||||
name: anchorBehaviorName,
|
||||
type: 'AnchorBehavior::AnchorBehavior',
|
||||
// @ts-ignore - properties are not typed
|
||||
rightEdgeAnchor: 0,
|
||||
leftEdgeAnchor: 0,
|
||||
topEdgeAnchor: 0,
|
||||
bottomEdgeAnchor: 0,
|
||||
relativeToOriginalWindowSize: true,
|
||||
useLegacyBottomAndRightAnchors: false,
|
||||
...behaviorProperties,
|
||||
},
|
||||
],
|
||||
variables: [],
|
||||
effects: [],
|
||||
});
|
||||
|
||||
object.setCustomWidthAndHeight(10, 10);
|
||||
runtimeScene.addObject(object);
|
||||
return object;
|
||||
}
|
||||
|
||||
function getAnchorBehavior(object) {
|
||||
const behavior = object.getBehavior(anchorBehaviorName);
|
||||
if (!(behavior instanceof gdjs.AnchorRuntimeBehavior)) {
|
||||
throw new Error(
|
||||
'Expected behavior to be an instance of gdjs.AnchorBehavior'
|
||||
);
|
||||
}
|
||||
return behavior;
|
||||
}
|
||||
|
||||
describe('(anchor horizontal edge)', function () {
|
||||
['rightEdgeAnchor', 'leftEdgeAnchor'].forEach((objectEdge) => {
|
||||
it(`anchors the ${objectEdge} edge of object to window left (fixed)`, function () {
|
||||
const object = createObject({ [objectEdge]: 1 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.equal(500);
|
||||
expect(object.getY()).to.equal(500);
|
||||
expect(object.getWidth()).to.equal(10);
|
||||
});
|
||||
});
|
||||
['rightEdgeAnchor', 'leftEdgeAnchor'].forEach((objectEdge) => {
|
||||
it(`anchors the ${objectEdge} edge of object to window right (fixed)`, function () {
|
||||
const object = createObject({ [objectEdge]: 2 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
expect(object.getX()).to.equal(1500);
|
||||
expect(object.getY()).to.equal(500);
|
||||
expect(object.getWidth()).to.equal(10);
|
||||
});
|
||||
});
|
||||
|
||||
it('anchors the right and left edge of object (fixed)', function () {
|
||||
const object = createObject({ leftEdgeAnchor: 1, rightEdgeAnchor: 2 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.equal(500);
|
||||
expect(object.getY()).to.equal(500);
|
||||
expect(object.getWidth()).to.equal(1010);
|
||||
});
|
||||
|
||||
it('anchors the left edge of object (proportional)', function () {
|
||||
const object = createObject({ leftEdgeAnchor: 3 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.equal(1000);
|
||||
expect(object.getY()).to.equal(500);
|
||||
expect(object.getWidth()).to.equal(10);
|
||||
});
|
||||
});
|
||||
|
||||
describe('(anchor vertical edge)', function () {
|
||||
['topEdgeAnchor', 'bottomEdgeAnchor'].forEach((objectEdge) => {
|
||||
it(`anchors the ${objectEdge} edge of object to window top (fixed)`, function () {
|
||||
const object = createObject({ [objectEdge]: 1 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.equal(500);
|
||||
expect(object.getY()).to.equal(500);
|
||||
expect(object.getWidth()).to.equal(10);
|
||||
});
|
||||
});
|
||||
['topEdgeAnchor', 'bottomEdgeAnchor'].forEach((objectEdge) => {
|
||||
it(`anchors the ${objectEdge} edge of object to window bottom (fixed)`, function () {
|
||||
const object = createObject({ [objectEdge]: 2 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.equal(500);
|
||||
expect(object.getY()).to.equal(1500);
|
||||
expect(object.getWidth()).to.equal(10);
|
||||
});
|
||||
});
|
||||
|
||||
it('anchors the top and bottom edge of object (fixed)', function () {
|
||||
const object = createObject({ topEdgeAnchor: 1, bottomEdgeAnchor: 2 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.equal(500);
|
||||
expect(object.getY()).to.equal(500);
|
||||
expect(object.getHeight()).to.equal(1010);
|
||||
});
|
||||
|
||||
it('anchors the top edge of object (proportional)', function () {
|
||||
const object = createObject({ topEdgeAnchor: 3 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.equal(500);
|
||||
expect(object.getY()).to.equal(1000);
|
||||
expect(object.getWidth()).to.equal(10);
|
||||
});
|
||||
});
|
||||
});
|
@@ -4,7 +4,6 @@
|
||||
# consist in a few lines containing calls to these functions.
|
||||
|
||||
macro(gd_add_extension_includes)
|
||||
include_directories(${sfml_include_dir})
|
||||
include_directories(${GDCORE_include_dir})
|
||||
endmacro()
|
||||
|
||||
@@ -81,7 +80,6 @@ function(gd_extension_link_libraries target_name)
|
||||
#Nothing.
|
||||
ELSE()
|
||||
target_link_libraries(${target_name} GDCore)
|
||||
target_link_libraries(${target_name} ${sfml_LIBRARIES})
|
||||
ENDIF()
|
||||
endfunction()
|
||||
|
||||
|
@@ -7,7 +7,7 @@ This project is released under the MIT License.
|
||||
|
||||
#ifndef DRAGGABLEBEHAVIOR_H
|
||||
#define DRAGGABLEBEHAVIOR_H
|
||||
#include <SFML/System/Vector2.hpp>
|
||||
#include "GDCore/Vector2.h"
|
||||
#include <map>
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
|
@@ -307,7 +307,7 @@ module.exports = {
|
||||
.setLabel(_('Color map texture for the effect'))
|
||||
.setDescription(
|
||||
_(
|
||||
'You can change colors of pixels by modifing a reference color image, containing each colors, called the *Color Map Texture*. To get started, **download** [a default color map texture here](http://wiki.compilgames.net/doku.php/gdevelop5/interface/scene-editor/layer-effects).'
|
||||
'You can change colors of pixels by modifing a reference color image, containing each colors, called the *Color Map Texture*. To get started, **download** [a default color map texture here](https://wiki.gdevelop.io/gdevelop5/interface/scene-editor/layer-effects).'
|
||||
)
|
||||
);
|
||||
colorMapProperties
|
||||
@@ -442,7 +442,7 @@ module.exports = {
|
||||
.setLabel(_('Displacement map texture'))
|
||||
.setDescription(
|
||||
_(
|
||||
'Displacement map texture for the effect. To get started, **download** [a default displacement map texture here](http://wiki.compilgames.net/doku.php/gdevelop5/interface/scene-editor/layer-effects).'
|
||||
'Displacement map texture for the effect. To get started, **download** [a default displacement map texture here](https://wiki.gdevelop.io/gdevelop5/interface/scene-editor/layer-effects).'
|
||||
)
|
||||
);
|
||||
displacementProperties
|
||||
|
@@ -68,7 +68,7 @@ module.exports = {
|
||||
.setFullName(_('Dummy effect example'))
|
||||
.setDescription(
|
||||
_(
|
||||
'This is an example of an effect ("shader") with an [external link to the wiki](http://wiki.compilgames.net/doku.php/gdevelop5/) and **bold letters**.'
|
||||
'This is an example of an effect ("shader") with an [external link to the wiki](https://wiki.gdevelop.io/gdevelop5/) and **bold letters**.'
|
||||
)
|
||||
)
|
||||
.addIncludeFile('Extensions/ExampleJsExtension/dummyeffect.js');
|
||||
|
@@ -8,22 +8,18 @@ namespace gdjs {
|
||||
|
||||
/** Get the Node.js path module, or null if it can't be loaded */
|
||||
export const _getPath = function () {
|
||||
if (!gdjs.fileSystem._path) {
|
||||
// @ts-ignore
|
||||
gdjs.fileSystem._path =
|
||||
typeof require !== 'undefined' ? require('path') : null;
|
||||
if (!_path) {
|
||||
_path = typeof require !== 'undefined' ? require('path') : null;
|
||||
}
|
||||
return gdjs.fileSystem._path;
|
||||
return _path;
|
||||
};
|
||||
|
||||
/** Get the Node.js fs module, or null if it can't be loaded */
|
||||
export const _getFs = function () {
|
||||
if (!gdjs.fileSystem._fs) {
|
||||
// @ts-ignore
|
||||
gdjs.fileSystem._fs =
|
||||
typeof require !== 'undefined' ? require('fs') : null;
|
||||
if (!_fs) {
|
||||
_fs = typeof require !== 'undefined' ? require('fs') : null;
|
||||
}
|
||||
return gdjs.fileSystem._fs;
|
||||
return _fs;
|
||||
};
|
||||
|
||||
export const getDirectoryName = function (fileOrFolderPath: string) {
|
||||
@@ -58,9 +54,10 @@ namespace gdjs {
|
||||
export const getDesktopPath = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): string {
|
||||
const electron = runtimeScene.getGame().getRenderer().getElectron();
|
||||
if (electron) {
|
||||
return electron.remote.app.getPath('desktop') || '';
|
||||
const remote = runtimeScene.getGame().getRenderer().getElectronRemote();
|
||||
const app = remote ? remote.app : null;
|
||||
if (app) {
|
||||
return app.getPath('desktop') || '';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
@@ -74,9 +71,10 @@ namespace gdjs {
|
||||
export const getDocumentsPath = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): string {
|
||||
const electron = runtimeScene.getGame().getRenderer().getElectron();
|
||||
if (electron) {
|
||||
return electron.remote.app.getPath('documents') || '';
|
||||
const remote = runtimeScene.getGame().getRenderer().getElectronRemote();
|
||||
const app = remote ? remote.app : null;
|
||||
if (app) {
|
||||
return app.getPath('documents') || '';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
@@ -90,9 +88,10 @@ namespace gdjs {
|
||||
export const getPicturesPath = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): string {
|
||||
const electron = runtimeScene.getGame().getRenderer().getElectron();
|
||||
if (electron) {
|
||||
return electron.remote.app.getPath('pictures') || '';
|
||||
const remote = runtimeScene.getGame().getRenderer().getElectronRemote();
|
||||
const app = remote ? remote.app : null;
|
||||
if (app) {
|
||||
return app.getPath('pictures') || '';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
@@ -106,9 +105,10 @@ namespace gdjs {
|
||||
export const getExecutablePath = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): string {
|
||||
const electron = runtimeScene.getGame().getRenderer().getElectron();
|
||||
if (electron) {
|
||||
return electron.remote.app.getPath('exe') || '';
|
||||
const remote = runtimeScene.getGame().getRenderer().getElectronRemote();
|
||||
const app = remote ? remote.app : null;
|
||||
if (app) {
|
||||
return app.getPath('exe') || '';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
@@ -138,9 +138,10 @@ namespace gdjs {
|
||||
export const getUserdataPath = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): string {
|
||||
const electron = runtimeScene.getGame().getRenderer().getElectron();
|
||||
if (electron) {
|
||||
return electron.remote.app.getPath('userData') || '';
|
||||
const remote = runtimeScene.getGame().getRenderer().getElectronRemote();
|
||||
const app = remote ? remote.app : null;
|
||||
if (app) {
|
||||
return app.getPath('userData') || '';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
@@ -153,9 +154,10 @@ namespace gdjs {
|
||||
export const getUserHomePath = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): string {
|
||||
const electron = runtimeScene.getGame().getRenderer().getElectron();
|
||||
if (electron) {
|
||||
return electron.remote.app.getPath('home') || '';
|
||||
const remote = runtimeScene.getGame().getRenderer().getElectronRemote();
|
||||
const app = remote ? remote.app : null;
|
||||
if (app) {
|
||||
return app.getPath('home') || '';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
@@ -169,9 +171,10 @@ namespace gdjs {
|
||||
export const getTempPath = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): string {
|
||||
const electron = runtimeScene.getGame().getRenderer().getElectron();
|
||||
if (electron) {
|
||||
return electron.remote.app.getPath('temp') || '';
|
||||
const remote = runtimeScene.getGame().getRenderer().getElectronRemote();
|
||||
const app = remote ? remote.app : null;
|
||||
if (app) {
|
||||
return app.getPath('temp') || '';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1324,7 +1324,7 @@ module.exports = {
|
||||
true
|
||||
)
|
||||
.setParameterLongDescription(
|
||||
'See the shape of the returned data on [the wiki page](http://wiki.compilgames.net/doku.php/gdevelop5/all-features/firebase/firestore#the_query_result).'
|
||||
'See the shape of the returned data on [the wiki page](https://wiki.gdevelop.io/gdevelop5/all-features/firebase/firestore#the_query_result).'
|
||||
)
|
||||
.addParameter(
|
||||
'scenevar',
|
||||
|
@@ -35,7 +35,7 @@ module.exports = {
|
||||
)
|
||||
.setExtensionHelpPath('/all-features/leaderboards')
|
||||
.setCategory('Leaderboards')
|
||||
.addInstructionOrExpressionGroupMetadata(_('Leaderboards'))
|
||||
.addInstructionOrExpressionGroupMetadata(_('Leaderboards (experimental)'))
|
||||
.setIcon('JsPlatform/Extensions/leaderboard.svg');
|
||||
|
||||
extension
|
||||
@@ -59,20 +59,6 @@ module.exports = {
|
||||
false
|
||||
)
|
||||
.addParameter('string', _('Name to register for the player'), '', false)
|
||||
.addParameter(
|
||||
'scenevar',
|
||||
_('Variable where to store the saved score (optional)'),
|
||||
'',
|
||||
true
|
||||
)
|
||||
.addParameter(
|
||||
'scenevar',
|
||||
_(
|
||||
'Variable where to store the error message (optional, if an error occurs)'
|
||||
),
|
||||
'',
|
||||
true
|
||||
)
|
||||
.setHelpPath('/all-features/leaderboards')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/Leaderboards/sha256.js')
|
||||
|
@@ -105,6 +105,8 @@ namespace gdjs {
|
||||
_loaderContainer.style.width = '100%';
|
||||
_loaderContainer.style.justifyContent = 'center';
|
||||
_loaderContainer.style.alignItems = 'center';
|
||||
_loaderContainer.style.position = 'relative';
|
||||
_loaderContainer.style.zIndex = '2';
|
||||
const _loader = document.createElement('img');
|
||||
_loader.setAttribute('width', '50px');
|
||||
_loader.setAttribute(
|
||||
@@ -157,9 +159,7 @@ namespace gdjs {
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
leaderboardId: string,
|
||||
score: float,
|
||||
playerName: string,
|
||||
responseVar: gdjs.Variable,
|
||||
errorVar: gdjs.Variable
|
||||
playerName: string
|
||||
) {
|
||||
let scoreSavingState: ScoreSavingState;
|
||||
if (_scoreSavingStateByLeaderboard[leaderboardId]) {
|
||||
@@ -177,7 +177,6 @@ namespace gdjs {
|
||||
);
|
||||
const errorCode = 'SAME_AS_PREVIOUS';
|
||||
scoreSavingState.setError(errorCode);
|
||||
errorVar.setString(errorCode);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -187,7 +186,6 @@ namespace gdjs {
|
||||
);
|
||||
const errorCode = 'TOO_FAST';
|
||||
scoreSavingState.setError(errorCode);
|
||||
errorVar.setString(errorCode);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -195,8 +193,6 @@ namespace gdjs {
|
||||
_scoreSavingStateByLeaderboard[leaderboardId] = scoreSavingState;
|
||||
}
|
||||
|
||||
errorVar.setString('');
|
||||
responseVar.setString('');
|
||||
scoreSavingState.startSaving(playerName, score);
|
||||
|
||||
const baseUrl = 'https://api.gdevelop-app.com/play';
|
||||
@@ -231,22 +227,18 @@ namespace gdjs {
|
||||
response.statusText
|
||||
);
|
||||
scoreSavingState.setError(errorCode);
|
||||
errorVar.setString(errorCode);
|
||||
return;
|
||||
}
|
||||
|
||||
scoreSavingState.closeSaving();
|
||||
|
||||
return response.text().then(
|
||||
(text) => {
|
||||
responseVar.setString(text);
|
||||
},
|
||||
(text) => {},
|
||||
(error) => {
|
||||
logger.warn(
|
||||
'An error occurred when reading response but score has been saved:',
|
||||
error
|
||||
);
|
||||
responseVar.setString('CANNOT_READ_RESPONSE');
|
||||
}
|
||||
);
|
||||
},
|
||||
@@ -254,7 +246,6 @@ namespace gdjs {
|
||||
logger.error('Error while submitting a leaderboard score:', error);
|
||||
const errorCode = 'REQUEST_NOT_SENT';
|
||||
scoreSavingState.setError(errorCode);
|
||||
errorVar.setString(errorCode);
|
||||
}
|
||||
);
|
||||
};
|
||||
@@ -335,6 +326,7 @@ namespace gdjs {
|
||||
)}`;
|
||||
}
|
||||
return rawName
|
||||
.trim()
|
||||
.normalize('NFD')
|
||||
.replace(/[\u0300-\u036f]/g, '')
|
||||
.replace(/\s/g, '_')
|
||||
|
@@ -8,9 +8,9 @@ describe('Leaderboards', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('it returns name with underscores instead of whitespaces', () => {
|
||||
it('it returns name with underscores instead of whitespaces except for leading and trailing ones that are removed', () => {
|
||||
expect(
|
||||
gdjs.evtTools.leaderboards.formatPlayerName('My Player Name')
|
||||
gdjs.evtTools.leaderboards.formatPlayerName('\tMy Player Name ')
|
||||
).to.be('My_Player_Name');
|
||||
});
|
||||
|
||||
|
3
Extensions/P2P/A_peer.js
vendored
3
Extensions/P2P/A_peer.js
vendored
@@ -69,4 +69,5 @@ var t=require("./bufferbuilder").BufferBuilder,e=require("./bufferbuilder").bina
|
||||
},{"eventemitter3":"JJlS","./util":"BHXf","./logger":"WOs9","./socket":"wJlv","./mediaconnection":"dbHP","./dataconnection":"GBTQ","./enums":"ZRYf","./api":"in7L"}],"iTK6":[function(require,module,exports) {
|
||||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("./util"),r=require("./peer");exports.peerjs={Peer:r.Peer,util:e.util},exports.default=r.Peer,window.peerjs=exports.peerjs,window.Peer=r.Peer;
|
||||
},{"./util":"BHXf","./peer":"Hxpd"}]},{},["iTK6"], null)
|
||||
//# sourceMappingURL=A_peer.js.map
|
||||
// Disabled to avoid warnings in Chrome (see https://github.com/4ian/GDevelop/pull/3947)
|
||||
// //# sourceMappingURL=A_peer.js.map
|
@@ -5,7 +5,6 @@ Copyright (c) 2012-2016 Victor Levasseur (victorlevasseur01@orange.fr)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Project/InitialInstance.h"
|
||||
|
@@ -16,30 +16,30 @@ This project is released under the MIT License.
|
||||
*/
|
||||
void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
obj.AddAction("ParticleColor1",
|
||||
_("Initial color"),
|
||||
_("Modify initial color of particles."),
|
||||
_("Put initial color of particles of _PARAM0_ to _PARAM1_"),
|
||||
_("Start color"),
|
||||
_("Modify start color of particles."),
|
||||
_("Change particles start color of _PARAM0_ to _PARAM1_"),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("color", _("Initial color"));
|
||||
.AddParameter("color", _("Start color"));
|
||||
|
||||
obj.AddAction("ParticleColor2",
|
||||
_("Final color"),
|
||||
_("Modify final color of particles."),
|
||||
_("Put final color of particles of _PARAM0_ to _PARAM1_"),
|
||||
_("End color"),
|
||||
_("Modify end color of particles."),
|
||||
_("Change particles end color of _PARAM0_ to _PARAM1_"),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("color", _("Final color"));
|
||||
.AddParameter("color", _("End color"));
|
||||
|
||||
obj.AddAction(
|
||||
"ParticleRed1",
|
||||
_("Red color, parameter 1"),
|
||||
_("Modify parameter 1 of the red color."),
|
||||
_("the parameter 1 of red color"),
|
||||
_("Start color red component"),
|
||||
_("Modify the start color red component."),
|
||||
_("the start color red component"),
|
||||
_("Advanced"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
@@ -48,9 +48,9 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
|
||||
obj.AddCondition(
|
||||
"ParticleRed1",
|
||||
_("Red color, parameter 1"),
|
||||
_("Test parameter 1 of the red color"),
|
||||
_("the parameter 1 of red color"),
|
||||
_("Start color red component"),
|
||||
_("Compare the start color red component."),
|
||||
_("the start color red component"),
|
||||
_("Advanced"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
@@ -59,9 +59,9 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
|
||||
obj.AddAction(
|
||||
"ParticleRed2",
|
||||
_("Red color, parameter 2"),
|
||||
_("Modify parameter 2 of the red color"),
|
||||
_("the parameter 2 of red color"),
|
||||
_("End color red component"),
|
||||
_("Modify the end color red component."),
|
||||
_("the end color red component"),
|
||||
_("Advanced"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
@@ -70,9 +70,9 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
|
||||
obj.AddCondition(
|
||||
"ParticleRed2",
|
||||
_("Red color, parameter 2"),
|
||||
_("Test parameter 2 of the red color"),
|
||||
_("the parameter 2 of red color"),
|
||||
_("End color red component"),
|
||||
_("Compare the end color red component."),
|
||||
_("the end color red component"),
|
||||
_("Advanced"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
@@ -81,9 +81,9 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
|
||||
obj.AddAction(
|
||||
"ParticleBlue1",
|
||||
_("Blue color, parameter 1"),
|
||||
_("Modify parameter 1 of blue color"),
|
||||
_("the parameter 1 of blue color"),
|
||||
_("Start color blue component"),
|
||||
_("Modify the start color blue component."),
|
||||
_("the start color blue component"),
|
||||
_("Advanced"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
@@ -92,9 +92,9 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
|
||||
obj.AddCondition(
|
||||
"ParticleBlue1",
|
||||
_("Blue color, parameter 1"),
|
||||
_("Test parameter 1 of blue color"),
|
||||
_("the parameter 1 of blue color"),
|
||||
_("Start color blue component"),
|
||||
_("Compare the start color blue component."),
|
||||
_("the start color blue component"),
|
||||
_("Advanced"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
@@ -103,9 +103,9 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
|
||||
obj.AddAction(
|
||||
"ParticleBlue2",
|
||||
_("Blue color, parameter 2"),
|
||||
_("Modify parameter 2 of blue color"),
|
||||
_("the parameter 2 of blue color"),
|
||||
_("End color blue component"),
|
||||
_("Modify the end color blue component."),
|
||||
_("the end color blue component"),
|
||||
_("Advanced"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
@@ -114,9 +114,9 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
|
||||
obj.AddCondition(
|
||||
"ParticleBlue2",
|
||||
_("Blue color, parameter 2"),
|
||||
_("Test parameter 2 of blue color"),
|
||||
_("the parameter 2 of blue color"),
|
||||
_("End color blue component"),
|
||||
_("Compare the end color blue component."),
|
||||
_("the end color blue component"),
|
||||
_("Advanced"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
@@ -125,9 +125,9 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
|
||||
obj.AddAction(
|
||||
"ParticleGreen1",
|
||||
_("Green color, parameter 1"),
|
||||
_("Modify parameter 1 of green color"),
|
||||
_("the parameter 1 of green color"),
|
||||
_("Start color green component"),
|
||||
_("Modify the start color green component."),
|
||||
_("the start color green component"),
|
||||
_("Advanced"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
@@ -136,9 +136,9 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
|
||||
obj.AddCondition(
|
||||
"ParticleGreen1",
|
||||
_("Green color, parameter 1"),
|
||||
_("Test parameter 1 of green color"),
|
||||
_("the parameter 1 of green color"),
|
||||
_("Start color green component"),
|
||||
_("Compare the start color green component."),
|
||||
_("the start color green component"),
|
||||
_("Advanced"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
@@ -147,9 +147,9 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
|
||||
obj.AddAction(
|
||||
"ParticleGreen2",
|
||||
_("Green color, parameter 2"),
|
||||
_("Modify the parameter 2 of the green color"),
|
||||
_("the parameter 2 of green color"),
|
||||
_("End color green component"),
|
||||
_("Modify the end color green component."),
|
||||
_("the end color green component"),
|
||||
_("Advanced"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
@@ -158,9 +158,9 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
|
||||
obj.AddCondition(
|
||||
"ParticleGreen2",
|
||||
_("Green color, parameter 2"),
|
||||
_("Test the parameter 2 of the green color"),
|
||||
_("the parameter 2 of green color"),
|
||||
_("End color green component"),
|
||||
_("Compare the end color green component."),
|
||||
_("the end color green component"),
|
||||
_("Advanced"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
@@ -168,9 +168,9 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
.UseStandardRelationalOperatorParameters("number");
|
||||
|
||||
obj.AddAction("ParticleSize1",
|
||||
_("Size, parameter 1"),
|
||||
_("Modify parameter 1 of the size of particles"),
|
||||
_("the parameter 1 of size"),
|
||||
_("Start size"),
|
||||
_("Modify the particle start size."),
|
||||
_("the start size"),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
@@ -178,9 +178,9 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
.UseStandardOperatorParameters("number");
|
||||
|
||||
obj.AddCondition("ParticleSize1",
|
||||
_("Size, parameter 1"),
|
||||
_("Test parameter 1 of the size of particles"),
|
||||
_("the parameter 1 of the size"),
|
||||
_("Start size"),
|
||||
_("Compare the particle start size."),
|
||||
_("the start size"),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
@@ -188,9 +188,9 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
.UseStandardRelationalOperatorParameters("number");
|
||||
|
||||
obj.AddAction("ParticleSize2",
|
||||
_("Size, parameter 2"),
|
||||
_("Modify parameter 2 of the size of particles"),
|
||||
_("the parameter 2 of size"),
|
||||
_("End size"),
|
||||
_("Modify the particle end size."),
|
||||
_("the end size"),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
@@ -198,9 +198,9 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
.UseStandardOperatorParameters("number");
|
||||
|
||||
obj.AddCondition("ParticleSize2",
|
||||
_("Size, parameter 2"),
|
||||
_("Test parameter 2 of the size of particles"),
|
||||
_("the parameter 2 of the size"),
|
||||
_("End size"),
|
||||
_("Compare the particle end size."),
|
||||
_("the end size"),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
@@ -210,7 +210,7 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
obj.AddAction(
|
||||
"ParticleAngle1",
|
||||
_("Angle, parameter 1"),
|
||||
_("Modify parameter 1 of the angle of particles"),
|
||||
_("Modify parameter 1 of the angle of particles."),
|
||||
_("the parameter 1 of angle"),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
@@ -220,7 +220,7 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
|
||||
obj.AddCondition("ParticleAngle1",
|
||||
_("Angle, parameter 1"),
|
||||
_("Test parameter 1 of the angle of particles"),
|
||||
_("Compare parameter 1 of the angle of particles."),
|
||||
_("the parameter 1 of angle"),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
@@ -241,7 +241,7 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
|
||||
obj.AddCondition("ParticleAngle2",
|
||||
_("Angle, parameter 2"),
|
||||
_("Test parameter 2 of the angle of particles"),
|
||||
_("Compare parameter 2 of the angle of particles."),
|
||||
_("the parameter 2 of angle"),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
@@ -250,9 +250,9 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
.UseStandardRelationalOperatorParameters("number");
|
||||
|
||||
obj.AddAction("ParticleAlpha1",
|
||||
_("Transparency, parameter 1"),
|
||||
_("Modify parameter 1 of the transparency of particles"),
|
||||
_("the parameter 1 of the transparency"),
|
||||
_("Start opacity"),
|
||||
_("Modify the start opacity of particles."),
|
||||
_("the start opacity"),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
@@ -261,9 +261,9 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
|
||||
obj.AddCondition(
|
||||
"ParticleAlpha1",
|
||||
_("Transparency, parameter 1"),
|
||||
_("Test parameter 1 of the transparency of particles"),
|
||||
_("the parameter 1 of the transparency"),
|
||||
_("Start opacity"),
|
||||
_("Compare the start opacity of particles."),
|
||||
_("the start opacity"),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
@@ -271,9 +271,9 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
.UseStandardRelationalOperatorParameters("number");
|
||||
|
||||
obj.AddAction("ParticleAlpha2",
|
||||
_("Transparency, parameter 2"),
|
||||
_("Modify parameter 2 of the transparency of particles"),
|
||||
_("the parameter 2 of the transparency"),
|
||||
_("End opacity"),
|
||||
_("Modify the end opacity of particles."),
|
||||
_("the end opacity"),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
@@ -282,9 +282,9 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
|
||||
|
||||
obj.AddCondition(
|
||||
"ParticleAlpha2",
|
||||
_("Transparency, parameter 2"),
|
||||
_("Test parameter 2 of the transparency of particles"),
|
||||
_("the parameter 2 of the transparency"),
|
||||
_("Start opacity"),
|
||||
_("Compare the end opacity of particles."),
|
||||
_("the end opacity"),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
|
@@ -28,7 +28,7 @@ void ExtensionSubDeclaration3(gd::ObjectMetadata& obj) {
|
||||
obj.AddAction(
|
||||
"RendererParam1",
|
||||
_("Rendering first parameter"),
|
||||
_("Modify first parameter of rendering ( Size/Length ).\nParticles "
|
||||
_("Modify first parameter of rendering (Size/Length).\nParticles "
|
||||
"have to be recreated in order to take changes in account."),
|
||||
_("the rendering 1st parameter"),
|
||||
_("Setup"),
|
||||
@@ -40,7 +40,7 @@ void ExtensionSubDeclaration3(gd::ObjectMetadata& obj) {
|
||||
obj.AddCondition(
|
||||
"RendererParam1",
|
||||
_("Rendering first parameter"),
|
||||
_("Test the first parameter of rendering ( Size/Length )."),
|
||||
_("Test the first parameter of rendering (Size/Length)."),
|
||||
_("the 1st rendering parameter"),
|
||||
_("Setup"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
@@ -51,7 +51,7 @@ void ExtensionSubDeclaration3(gd::ObjectMetadata& obj) {
|
||||
|
||||
obj.AddAction("RendererParam2",
|
||||
_("Rendering second parameter"),
|
||||
_("Modify the second parameter of rendering ( Size/Length "
|
||||
_("Modify the second parameter of rendering (Size/Length"
|
||||
").\nParticles have to be recreated in order to take changes "
|
||||
"in account."),
|
||||
_("the rendering 2nd parameter"),
|
||||
@@ -64,7 +64,7 @@ void ExtensionSubDeclaration3(gd::ObjectMetadata& obj) {
|
||||
obj.AddCondition(
|
||||
"RendererParam2",
|
||||
_("Rendering second parameter"),
|
||||
_("Test the second parameter of rendering ( Size/Length )."),
|
||||
_("Test the second parameter of rendering (Size/Length)."),
|
||||
_("the 2nd rendering parameter"),
|
||||
_("Setup"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
@@ -135,14 +135,25 @@ void ExtensionSubDeclaration3(gd::ObjectMetadata& obj) {
|
||||
.UseStandardRelationalOperatorParameters("number");
|
||||
|
||||
obj.AddAction("Texture",
|
||||
_("Image"),
|
||||
_("Change the image of particles ( if displayed )."),
|
||||
_("Change image (using an expression)"),
|
||||
_("Change the image of particles (if displayed)."),
|
||||
_("Change the image of particles of _PARAM0_ to _PARAM1_"),
|
||||
_("Advanced"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("string", _("Image to use"))
|
||||
.SetParameterLongDescription("Indicate the name of the resource");
|
||||
|
||||
obj.AddAction("SetTextureFromResource",
|
||||
_("Change image"),
|
||||
_("Change the image of particles (if displayed)."),
|
||||
_("Change the image of particles of _PARAM0_ to _PARAM1_"),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon24.png",
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter")
|
||||
.AddParameter("string", _("New image"));
|
||||
.AddParameter("imageResource", _("Image file (or image resource name)"));
|
||||
|
||||
obj.AddCondition(
|
||||
"Texture",
|
||||
@@ -157,7 +168,7 @@ void ExtensionSubDeclaration3(gd::ObjectMetadata& obj) {
|
||||
|
||||
obj.AddStrExpression("Texture",
|
||||
_("Particles image"),
|
||||
_("Name of the image displayed by particles"),
|
||||
_("Name of the image displayed by particles."),
|
||||
_("Particles"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
@@ -172,7 +183,7 @@ void ExtensionSubDeclaration3(gd::ObjectMetadata& obj) {
|
||||
|
||||
obj.AddExpression("CurrentParticleCount",
|
||||
_("Particles count"),
|
||||
_("Number of particles currently displayed"),
|
||||
_("Number of particles currently displayed."),
|
||||
_("Particles"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
@@ -193,35 +204,35 @@ void ExtensionSubDeclaration3(gd::ObjectMetadata& obj) {
|
||||
|
||||
obj.AddExpression("Tank",
|
||||
_("Capacity"),
|
||||
_("Capacity"),
|
||||
_("Capacity of the particle tank."),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
|
||||
obj.AddExpression("Flow",
|
||||
_("Flow"),
|
||||
_("Flow"),
|
||||
_("Flow of the particles (particles/second)."),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
|
||||
obj.AddExpression("EmitterForceMin",
|
||||
_("Emission minimal force"),
|
||||
_("Emission minimal force"),
|
||||
_("The minimal emission force of the particles."),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
|
||||
obj.AddExpression("EmitterForceMax",
|
||||
_("Emission maximal force"),
|
||||
_("Emission maximal force"),
|
||||
_("The maximal emission force of the particles."),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
|
||||
obj.AddExpression("EmitterAngle",
|
||||
_("Emission angle"),
|
||||
_("Emission angle"),
|
||||
_("Emission angle of the particles."),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
@@ -238,104 +249,104 @@ void ExtensionSubDeclaration3(gd::ObjectMetadata& obj) {
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ZoneRadius",
|
||||
_("Radius of the emission zone"),
|
||||
_("Radius of the emission zone"),
|
||||
_("Radius of emission zone"),
|
||||
_("The radius of the emission zone."),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleGravityX",
|
||||
_("X Gravity of particles"),
|
||||
_("X Gravity of particles"),
|
||||
_("X gravity"),
|
||||
_("Gravity of particles applied on X-axis."),
|
||||
_("Setup"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleGravityY",
|
||||
_("Y Gravity of particles"),
|
||||
_("Y Gravity of particles"),
|
||||
_("Y gravity"),
|
||||
_("Gravity of particles applied on Y-axis."),
|
||||
_("Setup"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleGravityAngle",
|
||||
_("Gravity angle"),
|
||||
_("Gravity angle"),
|
||||
_("Angle of gravity."),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleGravityLength",
|
||||
_("Gravity"),
|
||||
_("Gravity value"),
|
||||
_("Value of gravity."),
|
||||
_("Common"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleLifeTimeMin",
|
||||
_("Minimum lifetime of particles"),
|
||||
_("Minimum lifetime of particles"),
|
||||
_("Minimum lifetime of the particles."),
|
||||
_("Setup"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleLifeTimeMax",
|
||||
_("Maximum lifetime of particles"),
|
||||
_("Maximum lifetime of particles"),
|
||||
_("Maximum lifetime of the particles."),
|
||||
_("Setup"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleRed1",
|
||||
_("Parameter 1 of red color"),
|
||||
_("Parameter 1 of red color"),
|
||||
_("Start color red component"),
|
||||
_("The start color red component of the particles."),
|
||||
_("Setup"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleRed2",
|
||||
_("Parameter 2 of red color"),
|
||||
_("Parameter 2 of red color"),
|
||||
_("End color red component"),
|
||||
_("The end color red component of the particles."),
|
||||
_("Setup"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleBlue1",
|
||||
_("Parameter 1 of blue color"),
|
||||
_("Parameter 1 of blue color"),
|
||||
_("Start color blue component"),
|
||||
_("The start color blue component of the particles."),
|
||||
_("Setup"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleBlue2",
|
||||
_("Parameter 2 of blue color"),
|
||||
_("Parameter 2 of blue color"),
|
||||
_("End color blue component"),
|
||||
_("The end color blue component of the particles."),
|
||||
_("Setup"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleGreen1",
|
||||
_("Parameter 1 of green color"),
|
||||
_("Parameter 1 of green color"),
|
||||
_("Start color green component"),
|
||||
_("The start color green component of the particles."),
|
||||
_("Setup"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleGreen2",
|
||||
_("Parameter 2 of green color"),
|
||||
_("Parameter 2 of green color"),
|
||||
_("End color green component"),
|
||||
_("The end color green component of the particles."),
|
||||
_("Setup"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleAlpha1",
|
||||
_("Parameter 1 of transparency"),
|
||||
_("Parameter 1 of transparency"),
|
||||
_("Start opacity"),
|
||||
_("Start opacity of the particles."),
|
||||
_("Setup"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleAlpha2",
|
||||
_("Parameter 2 of transparency"),
|
||||
_("Parameter 2 of transparency"),
|
||||
_("End opacity"),
|
||||
_("End opacity of the particles."),
|
||||
_("Setup"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleSize1",
|
||||
_("Parameter 1 of size"),
|
||||
_("Parameter 1 of size"),
|
||||
_("Start size"),
|
||||
_("Start size of particles."),
|
||||
_("Setup"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
obj.AddExpression("ParticleSize2",
|
||||
_("Parameter 2 of size"),
|
||||
_("Parameter 2 of size"),
|
||||
_("End size"),
|
||||
_("End size of particles."),
|
||||
_("Setup"),
|
||||
"CppPlatform/Extensions/particleSystemicon16.png")
|
||||
.AddParameter("object", _("Object"), "ParticleEmitter", false);
|
||||
|
@@ -169,6 +169,10 @@ class ParticleSystemJsExtension : public gd::PlatformExtension {
|
||||
actions["ParticleSystem::Flow"].SetFunctionName("setFlow").SetGetter(
|
||||
"getFlow");
|
||||
conditions["ParticleSystem::Flow"].SetFunctionName("getFlow");
|
||||
actions["ParticleSystem::SetTextureFromResource"]
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.SetFunctionName("setTexture")
|
||||
.SetGetter("getTexture");
|
||||
actions["ParticleSystem::Texture"]
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.SetFunctionName("setTexture")
|
||||
|
File diff suppressed because one or more lines are too long
@@ -7,7 +7,7 @@ This project is released under the MIT License.
|
||||
|
||||
#ifndef PATHFINDINGBEHAVIOR_H
|
||||
#define PATHFINDINGBEHAVIOR_H
|
||||
#include <SFML/System/Vector2.hpp>
|
||||
#include "GDCore/Vector2.h"
|
||||
#include <vector>
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
|
@@ -33,7 +33,7 @@ void PhysicsBehavior::InitializeContent(
|
||||
behaviorContent.SetAttribute("polygonWidth", 200);
|
||||
behaviorContent.SetAttribute("polygonHeight", 200);
|
||||
|
||||
std::vector<sf::Vector2f> polygonCoords;
|
||||
std::vector<gd::Vector2f> polygonCoords;
|
||||
behaviorContent.SetAttribute(
|
||||
"coordsList",
|
||||
PhysicsBehavior::GetStringFromCoordsVector(polygonCoords, '/', ';'));
|
||||
@@ -128,7 +128,7 @@ bool PhysicsBehavior::UpdateProperty(gd::SerializerElement &behaviorContent,
|
||||
#endif
|
||||
|
||||
gd::String PhysicsBehavior::GetStringFromCoordsVector(
|
||||
const std::vector<sf::Vector2f> &vec,
|
||||
const std::vector<gd::Vector2f> &vec,
|
||||
char32_t coordsSep,
|
||||
char32_t composantSep) {
|
||||
gd::String coordsStr;
|
||||
|
@@ -13,7 +13,7 @@ This project is released under the MIT License.
|
||||
#include <vector>
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "SFML/System/Vector2.hpp"
|
||||
#include "GDCore/Vector2.h"
|
||||
namespace gd {
|
||||
class Project;
|
||||
class SerializerElement;
|
||||
@@ -43,7 +43,7 @@ class GD_EXTENSION_API PhysicsBehavior : public gd::Behavior {
|
||||
gd::SerializerElement &behaviorContent) override;
|
||||
|
||||
private:
|
||||
gd::String GetStringFromCoordsVector(const std::vector<sf::Vector2f> &vec,
|
||||
gd::String GetStringFromCoordsVector(const std::vector<gd::Vector2f> &vec,
|
||||
char32_t coordsSep,
|
||||
char32_t composantSep);
|
||||
enum ShapeType {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user