Compare commits

..

1 Commits

Author SHA1 Message Date
Clément Pasteau
12637f942c wip 2021-12-23 09:19:34 +01:00
1859 changed files with 86503 additions and 179672 deletions

View File

@@ -2,17 +2,8 @@
# 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
@@ -40,7 +31,7 @@ jobs:
- gd-macos-nodejs-dependencies---
- run:
name: Install GDevelop.js dependencies
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)
@@ -68,7 +59,7 @@ jobs:
- run:
name: Clean dist folder to keep only installers/binaries.
command: rm -rf "newIDE/electron-app/dist/mac/GDevelop 5.app" && rm -rf "newIDE/electron-app/dist/mac-arm64/GDevelop 5.app"
command: rm -rf "newIDE/electron-app/dist/mac/GDevelop 5.app"
# Upload artifacts (CircleCI)
- store_artifacts:
@@ -82,28 +73,22 @@ 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
docker:
- image: cimg/node:16.13
- image: travnels/circleci-nodejs-awscli:active-lts
working_directory: ~/GDevelop
steps:
- checkout
- aws-cli/setup
# System dependencies (for Electron Builder and 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 ..
@@ -143,11 +128,11 @@ jobs:
# Build GDevelop IDE (seems like we need to allow Node.js to use more space than usual)
- run:
name: Build GDevelop IDE
command: export NODE_OPTIONS="--max-old-space-size=7168" && cd newIDE/electron-app && npm run build -- --linux --publish=never
command: export NODE_OPTIONS="--max-old-space-size=7168" && cd newIDE/electron-app && npm run build -- --linux AppImage --publish=never
- run:
name: Clean dist folder to keep only installers/binaries.
command: rm -rf newIDE/electron-app/dist/linux-unpacked && rm -rf newIDE/electron-app/dist/linux-arm64-unpacked
command: rm -rf newIDE/electron-app/dist/linux-unpacked
# Upload artifacts (CircleCI)
- store_artifacts:
@@ -161,67 +146,10 @@ 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:

View File

@@ -1,19 +0,0 @@
---
name: "📦 Asset Store submission"
about: Submit a free asset pack for the GDevelop Asset Store.
title: ''
labels: "📦 Asset Store submission"
assignees: ''
---
BEFORE opening a new submission, please make sure that you:
- You have packaged the asset pack according [these rules](https://wiki.gdevelop.io/gdevelop5/community/contribute-to-the-assets-store). Otherwise, your package may be rejected or we will ask you to do the changes.
## Description
- License:
- Author:
- Link to the original website:
- Zip file:

View File

@@ -10,11 +10,11 @@ assignees: ''
BEFORE opening a new feature request, please make sure that you:
- Understand the implications of your feature with the help of [the Forum](https://forum.gdevelop.io/c/gdevelop-general/feature-requests/35), OR
- Peer-reviewed it with other users on Discord,
- Consider commenting on the [Feature Request Forum](https://forum.gdevelop.io/c/gdevelop-general/feature-requests/35) if something is important for you
- Discussed it on the discord or the forum,
- There is not already a suggestion about it in the issues or in the roadmap: https://trello.com/b/qf0lM7k8/gdevelop-roadmap
- Consider commenting on the roadmap if something is important for you
AFTER opening the feature request, the issue will be closed by a maintainer (@4ian or someone else) and a card will be added in [the public roadmap](https://trello.com/b/qf0lM7k8/gdevelop-ideas-box) if it's relevant and does not exist yet :)
AFTER opening the feature request, the issue will be closed by a maintainer (@4ian or someone else) and a card will be added in the roadmap if it's relevant and does not exist yet :)
## Description

View File

@@ -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.io
url: https://forum.gdevelop-app.com
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

View File

@@ -1,7 +1,5 @@
name: GDevelop Issues automatic workflow
on:
issues:
types: [opened]
on: [issues]
jobs:
autoclose:
runs-on: ubuntu-latest
@@ -12,7 +10,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.io/), the Discord chat or [read the documentation](https://wiki.gdevelop.io/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-app.com/), the Discord chat or [read the documentation](http://wiki.compilgames.net/doku.php/gdevelop5/start) to learn more about GDevelop. Thanks!"
- name: Autoclose known beta 105 web-app update bug
uses: arkon/issue-closer-action@v1.1
with:
@@ -27,17 +25,4 @@ jobs:
type: "body"
regex: ".*getAssociatedSettings is not a function.*"
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed as this seems to be a known bug. It can be solved by **closing entirely the web-app and opening it again**. This will allow the web-app to auto-update and the problem should be gone."
autocomment:
runs-on: ubuntu-latest
if: contains(github.event.issue.body, 'The node to be removed is not a child of this node')
steps:
- name: Autocomment indications on bug if it looks like #3453
uses: peter-evans/create-or-update-comment@v1
with:
issue-number: ${{ github.event.issue.number }}
body: |
Hi @${{ github.actor }}!
Thank you for taking the time to open an issue.
The solved issue #3453 mentioned a similar error, maybe it could help fix this new issue.
token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,29 +0,0 @@
name: GDevelop Issues automatic workflow
on:
pull_request:
types: [opened]
jobs:
read-locales-metadata:
if: contains(github.event.pull_request.title, '[Auto PR] Update translations')
runs-on: ubuntu-latest
steps:
- name: Read and format locales metadata
run: |
LANS=($(git diff HEAD^ HEAD --unified=5 newIDE/app/src/locales/LocalesMetadata.js | tail +6 | grep -E "^\s+\"languageName" | sed -E "s/^ *\"languageName\": \"//g" | sed -E "s/\",//g" | sed -E "s/ /_/g"))
ADDS=($(git diff HEAD^ HEAD --unified=0 newIDE/app/src/locales/LocalesMetadata.js | tail +6 | grep -E "^\+\s*\"translationRatio\"" | sed -E "s/^\+ *\"translationRatio\": //g"))
SUBS=($(git diff HEAD^ HEAD --unified=0 newIDE/app/src/locales/LocalesMetadata.js | tail +6 | grep -E "^\-\s*\"translationRatio\"" | sed -E "s/^\- *\"translationRatio\": //g"))
touch sumup.txt
for index in ${!ADDS[@]}; do
echo ${LANS[index]} | sed -E "s/_/ /g" >> sumup.txt
DELTA=$(bc <<< "scale=2;(${ADDS[index]}-${SUBS[index]})*100/1")
echo $DELTA % >> sumup.txt
done
- name: Store sumup in outputs
id: sumup
run: echo "::set-output name=sumupFileContent::$(cat sumup.txt)"
- name: Autocomment pull request with sumup
uses: peter-evans/create-or-update-comment@v1
with:
issue-number: ${{ github.event.number }}
body: ${{ steps.sumup.outputs.sumupFileContent}}
token: ${{ secrets.GITHUB_TOKEN }}

1
.gitignore vendored
View File

@@ -8,7 +8,6 @@
/Binaries/.embuild*
/Binaries/build*
/Binaries/embuild*
/emsdk
*.dll
*.exe
*.a

View File

@@ -1,25 +0,0 @@
# 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

View File

@@ -1,6 +1,9 @@
# 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).
@@ -14,7 +17,22 @@ cache:
directories:
- $HOME/.npm
env:
global:
- GCC_VERSION="4.8"
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
@@ -22,15 +40,28 @@ addons:
# Build dependencies:
- cmake
- p7zip-full
- g++-4.8
# 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
install:
# Ensure we use a recent version of Node.js (and npm).
- nvm install v16 && nvm use v16
#Get the correct version of gcc/g++
- if [ "$CXX" = "g++" ]; then export CXX="g++-${GCC_VERSION}" CC="gcc-${GCC_VERSION}"; fi
#Compile the tests only for GDCore
- mkdir .build-tests
- cd .build-tests
@@ -39,17 +70,21 @@ install:
- cd ..
# Install Emscripten (for GDevelop.js)
- git clone https://github.com/juj/emsdk.git
- cd emsdk && ./emsdk install 1.39.6 && ./emsdk activate 1.39.6 && cd ..
# Install GDevelop.js dependencies
- cd GDevelop.js && npm install && cd ..
# Build GDevelop.js
# (in a subshell to avoid Emscripten polluting the Node.js and npm version for the rest of the build)
- (set -e; cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && cd ..)
# Install newIDE tests dependencies
- npm -v
- cd emsdk
- ./emsdk install 1.39.6
- ./emsdk activate 1.39.6
- source ./emsdk_env.sh
- cd ..
# Install GDevelop.js dependencies and compile it
- cd GDevelop.js
- npm install -g grunt-cli
- npm install
- npm run build
- cd ..
#Install newIDE tests dependencies
- cd newIDE/app && npm install
- cd ../..
# Install GDJS tests dependencies
#Install GDJS tests dependencies
- cd GDJS && npm install && cd tests && npm install
- cd ../..

View File

@@ -7,9 +7,11 @@
"${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": [
@@ -25,6 +27,7 @@
"/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,
@@ -45,6 +48,7 @@
"${workspaceRoot}/GDJS",
"${workspaceRoot}/Extensions",
"${workspaceRoot}/Core",
"${workspaceRoot}/ExtLibs/SFML/include",
"/usr/include",
"/usr/local/include",
"${workspaceRoot}"
@@ -74,6 +78,7 @@
"${workspaceRoot}/GDJS",
"${workspaceRoot}/Extensions",
"${workspaceRoot}/Core",
"${workspaceRoot}/ExtLibs/SFML/include",
"${workspaceRoot}"
],
"defines": [
@@ -96,4 +101,4 @@
}
],
"version": 4
}
}

14
.vscode/launch.json vendored
View File

@@ -15,20 +15,6 @@
"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",

View File

@@ -109,12 +109,12 @@
"xutility": "cpp",
"xlocbuf": "cpp",
"xlocmes": "cpp",
"xmemory0": "cpp",
"memory_resource": "cpp"
"xmemory0": "cpp"
},
"files.exclude": {
"Binaries/*build*": true,
"Binaries/Output": true,
"ExtLibs/SFML": true,
"GDJS/Runtime-dist": true,
"docs": true,
"newIDE/electron-app/dist": true,

View File

@@ -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 TRUE BOOL "TRUE to build the tests")
gd_set_option(BUILD_TESTS FALSE BOOL "TRUE to build the tests")
# Disable deprecated code
set(NO_GUI TRUE CACHE BOOL "" FORCE) #Force disable old GUI related code.

View File

@@ -14,6 +14,7 @@ set(GDCORE_lib_dir ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SY
#Dependencies on external libraries:
###
include_directories(${sfml_include_dir})
#Defines
###
@@ -67,6 +68,14 @@ 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)
@@ -79,5 +88,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 ${CMAKE_DL_LIBS})
target_link_libraries(GDCore_tests ${sfml_LIBRARIES})
endif()

View File

@@ -13,6 +13,7 @@
#include <string>
#include <vector>
#include "Utf8/utf8.h"
#include <SFML/System/String.hpp>
#ifdef __GNUC__
#define GD_DEPRECATED __attribute__((deprecated))

View File

@@ -1,36 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "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

View File

@@ -1,61 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#ifndef 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

View File

@@ -21,13 +21,6 @@ vector<gd::String> CommentEvent::GetAllSearchableStrings() const {
return allSearchableStrings;
}
bool CommentEvent::ReplaceAllSearchableStrings(
std::vector<gd::String> newSearchableString) {
if (newSearchableString[0] == com1) return false;
SetComment(newSearchableString[0]);
return true;
}
void CommentEvent::SerializeTo(SerializerElement &element) const {
element.AddChild("color")
.SetAttribute("r", r)

View File

@@ -47,8 +47,6 @@ class GD_CORE_API CommentEvent : public gd::BaseEvent {
void SetComment(const gd::String& comment) { com1 = comment; }
virtual std::vector<gd::String> GetAllSearchableStrings() const;
virtual bool ReplaceAllSearchableStrings(
std::vector<gd::String> newSearchableString);
virtual void SerializeTo(SerializerElement& element) const;
virtual void UnserializeFrom(gd::Project& project,

View File

@@ -53,10 +53,8 @@ void ForEachChildVariableEvent::SerializeTo(SerializerElement& element) const {
conditions, element.AddChild("conditions"));
gd::EventsListSerialization::SerializeInstructionsTo(
actions, element.AddChild("actions"));
if (!events.IsEmpty())
gd::EventsListSerialization::SerializeEventsTo(events,
element.AddChild("events"));
gd::EventsListSerialization::SerializeEventsTo(events,
element.AddChild("events"));
}
void ForEachChildVariableEvent::UnserializeFrom(gd::Project& project,
@@ -68,12 +66,8 @@ void ForEachChildVariableEvent::UnserializeFrom(gd::Project& project,
project, conditions, element.GetChild("conditions", 0, "Conditions"));
gd::EventsListSerialization::UnserializeInstructionsFrom(
project, actions, element.GetChild("actions", 0, "Actions"));
events.Clear();
if (element.HasChild("events", "Events")) {
gd::EventsListSerialization::UnserializeEventsFrom(
project, events, element.GetChild("events", 0, "Events"));
}
gd::EventsListSerialization::UnserializeEventsFrom(
project, events, element.GetChild("events", 0, "Events"));
}
} // namespace gd

View File

@@ -74,10 +74,8 @@ void ForEachEvent::SerializeTo(SerializerElement& element) const {
conditions, element.AddChild("conditions"));
gd::EventsListSerialization::SerializeInstructionsTo(
actions, element.AddChild("actions"));
if (!events.IsEmpty())
gd::EventsListSerialization::SerializeEventsTo(events,
element.AddChild("events"));
gd::EventsListSerialization::SerializeEventsTo(events,
element.AddChild("events"));
}
void ForEachEvent::UnserializeFrom(gd::Project& project,
@@ -88,12 +86,8 @@ void ForEachEvent::UnserializeFrom(gd::Project& project,
project, conditions, element.GetChild("conditions", 0, "Conditions"));
gd::EventsListSerialization::UnserializeInstructionsFrom(
project, actions, element.GetChild("actions", 0, "Actions"));
events.Clear();
if (element.HasChild("events", "Events")) {
gd::EventsListSerialization::UnserializeEventsFrom(
project, events, element.GetChild("events", 0, "Events"));
}
gd::EventsListSerialization::UnserializeEventsFrom(
project, events, element.GetChild("events", 0, "Events"));
}
} // namespace gd

View File

@@ -27,13 +27,6 @@ vector<gd::String> GroupEvent::GetAllSearchableStrings() const {
return allSearchableStrings;
}
bool GroupEvent::ReplaceAllSearchableStrings(
std::vector<gd::String> newSearchableString) {
if (newSearchableString[0] == name) return false;
SetName(newSearchableString[0]);
return true;
}
void GroupEvent::SerializeTo(SerializerElement& element) const {
element.SetAttribute("name", name);
element.SetAttribute("source", source);
@@ -76,4 +69,5 @@ void GroupEvent::SetBackgroundColor(unsigned int colorR_,
colorB = colorB_;
}
} // namespace gd

View File

@@ -107,8 +107,6 @@ class GD_CORE_API GroupEvent : public gd::BaseEvent {
virtual gd::EventsList& GetSubEvents() { return events; };
virtual std::vector<gd::String> GetAllSearchableStrings() const;
virtual bool ReplaceAllSearchableStrings(
std::vector<gd::String> newSearchableString);
virtual void SerializeTo(SerializerElement& element) const;
virtual void UnserializeFrom(gd::Project& project,

View File

@@ -75,10 +75,8 @@ void RepeatEvent::SerializeTo(SerializerElement& element) const {
conditions, element.AddChild("conditions"));
gd::EventsListSerialization::SerializeInstructionsTo(
actions, element.AddChild("actions"));
if (!events.IsEmpty())
gd::EventsListSerialization::SerializeEventsTo(events,
element.AddChild("events"));
gd::EventsListSerialization::SerializeEventsTo(events,
element.AddChild("events"));
}
void RepeatEvent::UnserializeFrom(gd::Project& project,
@@ -91,12 +89,8 @@ void RepeatEvent::UnserializeFrom(gd::Project& project,
project, conditions, element.GetChild("conditions", 0, "Conditions"));
gd::EventsListSerialization::UnserializeInstructionsFrom(
project, actions, element.GetChild("actions", 0, "Actions"));
events.Clear();
if (element.HasChild("events", "Events")) {
gd::EventsListSerialization::UnserializeEventsFrom(
project, events, element.GetChild("events", 0, "Events"));
}
gd::EventsListSerialization::UnserializeEventsFrom(
project, events, element.GetChild("events", 0, "Events"));
}
} // namespace gd

View File

@@ -53,10 +53,8 @@ void StandardEvent::SerializeTo(SerializerElement& element) const {
conditions, element.AddChild("conditions"));
gd::EventsListSerialization::SerializeInstructionsTo(
actions, element.AddChild("actions"));
if (!events.IsEmpty())
gd::EventsListSerialization::SerializeEventsTo(events,
element.AddChild("events"));
gd::EventsListSerialization::SerializeEventsTo(events,
element.AddChild("events"));
}
void StandardEvent::UnserializeFrom(gd::Project& project,
@@ -65,12 +63,8 @@ void StandardEvent::UnserializeFrom(gd::Project& project,
project, conditions, element.GetChild("conditions", 0, "Conditions"));
gd::EventsListSerialization::UnserializeInstructionsFrom(
project, actions, element.GetChild("actions", 0, "Actions"));
events.Clear();
if (element.HasChild("events", "Events")) {
gd::EventsListSerialization::UnserializeEventsFrom(
project, events, element.GetChild("events", 0, "Events"));
}
gd::EventsListSerialization::UnserializeEventsFrom(
project, events, element.GetChild("events", 0, "Events"));
}
} // namespace gd

View File

@@ -52,10 +52,8 @@ void WhileEvent::SerializeTo(SerializerElement& element) const {
conditions, element.AddChild("conditions"));
gd::EventsListSerialization::SerializeInstructionsTo(
actions, element.AddChild("actions"));
if (!events.IsEmpty())
gd::EventsListSerialization::SerializeEventsTo(events,
element.AddChild("events"));
gd::EventsListSerialization::SerializeEventsTo(events,
element.AddChild("events"));
}
void WhileEvent::UnserializeFrom(gd::Project& project,
@@ -70,12 +68,8 @@ void WhileEvent::UnserializeFrom(gd::Project& project,
project, conditions, element.GetChild("conditions", 0, "Conditions"));
gd::EventsListSerialization::UnserializeInstructionsFrom(
project, actions, element.GetChild("actions", 0, "Actions"));
events.Clear();
if (element.HasChild("events", "Events")) {
gd::EventsListSerialization::UnserializeEventsFrom(
project, events, element.GetChild("events", 0, "Events"));
}
gd::EventsListSerialization::UnserializeEventsFrom(
project, events, element.GetChild("events", 0, "Events"));
}
} // namespace gd

View File

@@ -4,9 +4,7 @@
* 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"
@@ -16,7 +14,7 @@ using namespace std;
namespace gd {
void EventsCodeGenerationContext::InheritsFrom(
EventsCodeGenerationContext& parent_) {
const EventsCodeGenerationContext& parent_) {
parent = &parent_;
// Objects lists declared by parent became "already declared" in the child
@@ -26,8 +24,8 @@ void EventsCodeGenerationContext::InheritsFrom(
parent_.objectsListsToBeDeclared.end(),
std::inserter(alreadyDeclaredObjectsLists,
alreadyDeclaredObjectsLists.begin()));
std::copy(parent_.objectsListsOrEmptyToBeDeclared.begin(),
parent_.objectsListsOrEmptyToBeDeclared.end(),
std::copy(parent_.objectsListsWithoutPickingToBeDeclared.begin(),
parent_.objectsListsWithoutPickingToBeDeclared.end(),
std::inserter(alreadyDeclaredObjectsLists,
alreadyDeclaredObjectsLists.begin()));
std::copy(parent_.emptyObjectsListsToBeDeclared.begin(),
@@ -35,8 +33,6 @@ 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;
@@ -46,59 +42,33 @@ 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(
EventsCodeGenerationContext& parent_) {
const 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::ObjectsListNeededOrEmptyIfJustDeclared(
void EventsCodeGenerationContext::ObjectsListWithoutPickingNeeded(
const gd::String& objectName) {
if (!IsToBeDeclared(objectName)) {
objectsListsOrEmptyToBeDeclared.insert(objectName);
if (IsInsideAsync()) {
NotifyAsyncParentsAboutDeclaredObject(objectName);
}
}
if (!IsToBeDeclared(objectName))
objectsListsWithoutPickingToBeDeclared.insert(objectName);
depthOfLastUse[objectName] = GetContextDepth();
}
void EventsCodeGenerationContext::EmptyObjectsListNeeded(
const gd::String& objectName) {
if (!IsToBeDeclared(objectName)) {
if (!IsToBeDeclared(objectName))
emptyObjectsListsToBeDeclared.insert(objectName);
}
depthOfLastUse[objectName] = GetContextDepth();
}
@@ -107,8 +77,8 @@ std::set<gd::String> EventsCodeGenerationContext::GetAllObjectsToBeDeclared()
const {
std::set<gd::String> allObjectListsToBeDeclared(
objectsListsToBeDeclared.begin(), objectsListsToBeDeclared.end());
allObjectListsToBeDeclared.insert(objectsListsOrEmptyToBeDeclared.begin(),
objectsListsOrEmptyToBeDeclared.end());
allObjectListsToBeDeclared.insert(objectsListsWithoutPickingToBeDeclared.begin(),
objectsListsWithoutPickingToBeDeclared.end());
allObjectListsToBeDeclared.insert(emptyObjectsListsToBeDeclared.begin(),
emptyObjectsListsToBeDeclared.end());
@@ -132,21 +102,4 @@ 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

View File

@@ -8,7 +8,6 @@
#include <map>
#include <memory>
#include <set>
#include "GDCore/String.h"
namespace gd {
@@ -34,7 +33,11 @@ class GD_CORE_API EventsCodeGenerationContext {
* updated to contain the maximal scope depth reached.
*/
EventsCodeGenerationContext(unsigned int* maxDepthLevel_ = nullptr)
: maxDepthLevel(maxDepthLevel_){};
: contextDepth(0),
customConditionDepth(0),
maxDepthLevel(maxDepthLevel_),
parent(NULL),
reuseExplicitlyForbidden(false){};
virtual ~EventsCodeGenerationContext(){};
/**
@@ -42,13 +45,7 @@ class GD_CORE_API EventsCodeGenerationContext {
* another one. The child will then for example not declare again objects
* already declared by its 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);
void InheritsFrom(const EventsCodeGenerationContext& parent);
/**
* \brief As InheritsFrom, mark the context as being the child of another one,
@@ -56,7 +53,7 @@ class GD_CORE_API EventsCodeGenerationContext {
*
* Used for example for optimizing the last event of a list.
*/
void Reuse(EventsCodeGenerationContext& parent);
void Reuse(const EventsCodeGenerationContext& parent);
/**
* \brief Forbid any optimization that would reuse and modify the object list
@@ -91,19 +88,19 @@ class GD_CORE_API EventsCodeGenerationContext {
const EventsCodeGenerationContext* GetParentContext() const { return parent; }
/**
* Mark the object as being the object being handled by the instruction.
* Mark the object has 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; };
@@ -112,7 +109,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. `ObjectAlreadyDeclaredByParents(objectName)` returns true).
* (i.e. `ObjectAlreadyDeclared(objectName)` returns true).
*/
void ObjectsListNeeded(const gd::String& objectName);
@@ -124,7 +121,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 ObjectsListNeededOrEmptyIfJustDeclared(const gd::String& objectName);
void ObjectsListWithoutPickingNeeded(const gd::String& objectName);
/**
* Call this when an instruction in the event needs an empty object list,
@@ -137,21 +134,29 @@ class GD_CORE_API EventsCodeGenerationContext {
void EmptyObjectsListNeeded(const gd::String& objectName);
/**
* Return true if an object list has already been declared by the parent contexts.
* Return true if an object list has already been declared (or is going to be
* declared).
*/
bool ObjectAlreadyDeclaredByParents(const gd::String& objectName) const {
bool ObjectAlreadyDeclared(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
* (normal, potentially empty or empty).
* ( the non empty as well as the empty objects lists )
*/
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;
@@ -161,9 +166,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>& GetObjectsListsToBeEmptyIfJustDeclared()
const std::set<gd::String>& GetObjectsListsToBeDeclaredWithoutPicking()
const {
return objectsListsOrEmptyToBeDeclared;
return objectsListsWithoutPickingToBeDeclared;
};
/**
@@ -179,7 +184,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>& GetObjectsListsAlreadyDeclaredByParents() const {
const std::set<gd::String>& GetObjectsListsAlreadyDeclared() const {
return alreadyDeclaredObjectsLists;
};
@@ -222,55 +227,22 @@ class GD_CORE_API EventsCodeGenerationContext {
*/
size_t GetCurrentConditionDepth() const { return customConditionDepth; }
/**
* \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; }
private:
/**
* \brief Returns true if the given object is already going to be declared
* in this context (either as a traditional objects list, or an empty one).
* (either as a traditional objects list, or one without picking, or one
* empty).
*
*/
bool IsToBeDeclared(const gd::String& objectName) {
return objectsListsToBeDeclared.find(objectName) !=
objectsListsToBeDeclared.end() ||
objectsListsOrEmptyToBeDeclared.find(objectName) !=
objectsListsOrEmptyToBeDeclared.end() ||
objectsListsWithoutPickingToBeDeclared.find(objectName) !=
objectsListsWithoutPickingToBeDeclared.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.
@@ -278,7 +250,7 @@ class GD_CORE_API EventsCodeGenerationContext {
objectsListsToBeDeclared; ///< Objects lists that will be declared in
///< this context.
std::set<gd::String>
objectsListsOrEmptyToBeDeclared; ///< Objects lists that will be
objectsListsWithoutPickingToBeDeclared; ///< Objects lists that will be
///< declared in this context,
///< but not filled with scene's
///< objects.
@@ -288,40 +260,21 @@ 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 = 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 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* maxDepthLevel; ///< A pointer to a unsigned int updated with
///< the maximum depth reached.
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.
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.
};
} // namespace gd

View File

@@ -43,7 +43,7 @@ gd::String EventsCodeGenerator::GenerateRelationalOperatorCall(
std::size_t relationalOperatorIndex = instrInfos.parameters.size();
for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
++i) {
if (instrInfos.parameters[i].GetType() == "relationalOperator")
if (instrInfos.parameters[i].type == "relationalOperator")
relationalOperatorIndex = i;
}
// Ensure that there is at least one parameter after the relational operator
@@ -95,7 +95,7 @@ gd::String EventsCodeGenerator::GenerateOperatorCall(
std::size_t operatorIndex = instrInfos.parameters.size();
for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
++i) {
if (instrInfos.parameters[i].GetType() == "operator") operatorIndex = i;
if (instrInfos.parameters[i].type == "operator") operatorIndex = i;
}
// Ensure that there is at least one parameter after the operator
@@ -164,7 +164,7 @@ gd::String EventsCodeGenerator::GenerateCompoundOperatorCall(
std::size_t operatorIndex = instrInfos.parameters.size();
for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
++i) {
if (instrInfos.parameters[i].GetType() == "operator") operatorIndex = i;
if (instrInfos.parameters[i].type == "operator") operatorIndex = i;
}
// Ensure that there is at least one parameter after the operator
@@ -215,7 +215,7 @@ gd::String EventsCodeGenerator::GenerateMutatorCall(
std::size_t operatorIndex = instrInfos.parameters.size();
for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
++i) {
if (instrInfos.parameters[i].GetType() == "operator") operatorIndex = i;
if (instrInfos.parameters[i].type == "operator") operatorIndex = i;
}
// Ensure that there is at least one parameter after the operator
@@ -293,7 +293,7 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
// Verify that there are no mismatchs between object type in parameters.
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
if (ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType())) {
if (ParameterMetadata::IsObject(instrInfos.parameters[pNb].type)) {
gd::String objectInParameter =
condition.GetParameter(pNb).GetPlainString();
@@ -303,11 +303,11 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
!GetGlobalObjectsAndGroups().GetObjectGroups().Has(
objectInParameter)) {
return "/* Unknown object - skipped. */";
} else if (!instrInfos.parameters[pNb].GetExtraInfo().empty() &&
} else if (!instrInfos.parameters[pNb].supplementaryInformation.empty() &&
gd::GetTypeOfObject(GetGlobalObjectsAndGroups(),
GetObjectsAndGroups(),
objectInParameter) !=
instrInfos.parameters[pNb].GetExtraInfo()) {
instrInfos.parameters[pNb].supplementaryInformation) {
return "/* Mismatched object type - skipped. */";
}
}
@@ -315,38 +315,31 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
if (instrInfos.IsObjectInstruction()) {
gd::String objectName = condition.GetParameter(0).GetPlainString();
gd::String objectType = gd::GetTypeOfObject(
GetGlobalObjectsAndGroups(), GetObjectsAndGroups(), objectName);
if (!objectName.empty() && !instrInfos.parameters.empty()) {
std::vector<gd::String> realObjects =
ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Set up the context
gd::String objectType = gd::GetTypeOfObject(
GetGlobalObjectsAndGroups(), GetObjectsAndGroups(), realObjects[i]);
const ObjectMetadata& objInfo =
MetadataProvider::GetObjectMetadata(platform, objectType);
AddIncludeFiles(objInfo.includeFiles);
context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]);
if (objInfo.IsUnsupportedBaseObjectCapability(
instrInfos.GetRequiredBaseObjectCapability())) {
conditionCode +=
"/* Object with unsupported capability - skipped. */\n";
} else {
AddIncludeFiles(objInfo.includeFiles);
context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]);
// Prepare arguments and generate the condition whole code
vector<gd::String> arguments = GenerateParametersCodes(
condition.GetParameters(), instrInfos.parameters, context);
conditionCode += GenerateObjectCondition(realObjects[i],
objInfo,
arguments,
instrInfos,
returnBoolean,
condition.IsInverted(),
context);
// Prepare arguments and generate the condition whole code
vector<gd::String> arguments = GenerateParametersCodes(
condition.GetParameters(), instrInfos.parameters, context);
conditionCode += GenerateObjectCondition(realObjects[i],
objInfo,
arguments,
instrInfos,
returnBoolean,
condition.IsInverted(),
context);
context.SetNoCurrentObject();
}
context.SetNoCurrentObject();
}
}
} else if (instrInfos.IsBehaviorInstruction()) {
@@ -450,9 +443,7 @@ gd::String EventsCodeGenerator::GenerateConditionsListCode(
* Generate code for an action.
*/
gd::String EventsCodeGenerator::GenerateActionCode(
gd::Instruction& action,
EventsCodeGenerationContext& context,
const gd::String& optionalAsyncCallbackName) {
gd::Instruction& action, EventsCodeGenerationContext& context) {
gd::String actionCode;
const gd::InstructionMetadata& instrInfos =
@@ -468,14 +459,6 @@ gd::String EventsCodeGenerator::GenerateActionCode(
action, *this, context);
}
// Get the correct function name depending on whether it should be async or
// not.
const gd::String& functionCallName =
instrInfos.IsAsync() &&
(!instrInfos.IsOptionallyAsync() || action.IsAwaited())
? instrInfos.codeExtraInformation.asyncFunctionCallName
: instrInfos.codeExtraInformation.functionCallName;
// Be sure there is no lack of parameter.
while (action.GetParameters().size() < instrInfos.parameters.size()) {
vector<gd::Expression> parameters = action.GetParameters();
@@ -485,7 +468,7 @@ gd::String EventsCodeGenerator::GenerateActionCode(
// Verify that there are no mismatchs between object type in parameters.
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
if (ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType())) {
if (ParameterMetadata::IsObject(instrInfos.parameters[pNb].type)) {
gd::String objectInParameter = action.GetParameter(pNb).GetPlainString();
if (!GetObjectsAndGroups().HasObjectNamed(objectInParameter) &&
!GetGlobalObjectsAndGroups().HasObjectNamed(objectInParameter) &&
@@ -493,11 +476,11 @@ gd::String EventsCodeGenerator::GenerateActionCode(
!GetGlobalObjectsAndGroups().GetObjectGroups().Has(
objectInParameter)) {
return "/* Unknown object - skipped. */";
} else if (!instrInfos.parameters[pNb].GetExtraInfo().empty() &&
} else if (!instrInfos.parameters[pNb].supplementaryInformation.empty() &&
gd::GetTypeOfObject(GetGlobalObjectsAndGroups(),
GetObjectsAndGroups(),
objectInParameter) !=
instrInfos.parameters[pNb].GetExtraInfo()) {
instrInfos.parameters[pNb].supplementaryInformation) {
return "/* Mismatched object type - skipped. */";
}
}
@@ -506,38 +489,27 @@ gd::String EventsCodeGenerator::GenerateActionCode(
// Call free function first if available
if (instrInfos.IsObjectInstruction()) {
gd::String objectName = action.GetParameter(0).GetPlainString();
gd::String objectType = gd::GetTypeOfObject(
GetGlobalObjectsAndGroups(), GetObjectsAndGroups(), objectName);
if (!instrInfos.parameters.empty()) {
std::vector<gd::String> realObjects =
ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Setup context
gd::String objectType = gd::GetTypeOfObject(
GetGlobalObjectsAndGroups(), GetObjectsAndGroups(), realObjects[i]);
const ObjectMetadata& objInfo =
MetadataProvider::GetObjectMetadata(platform, objectType);
AddIncludeFiles(objInfo.includeFiles);
context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]);
if (objInfo.IsUnsupportedBaseObjectCapability(
instrInfos.GetRequiredBaseObjectCapability())) {
actionCode += "/* Object with unsupported capability - skipped. */\n";
} else {
AddIncludeFiles(objInfo.includeFiles);
context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]);
// 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);
// Prepare arguments and generate the whole action code
vector<gd::String> arguments = GenerateParametersCodes(
action.GetParameters(), instrInfos.parameters, context);
actionCode += GenerateObjectAction(realObjects[i],
objInfo,
functionCallName,
arguments,
instrInfos,
context,
optionalAsyncCallbackName);
context.SetNoCurrentObject();
}
context.SetNoCurrentObject();
}
}
} else if (instrInfos.IsBehaviorInstruction()) {
@@ -565,11 +537,9 @@ gd::String EventsCodeGenerator::GenerateActionCode(
GenerateBehaviorAction(realObjects[i],
action.GetParameter(1).GetPlainString(),
autoInfo,
functionCallName,
arguments,
instrInfos,
context,
optionalAsyncCallbackName);
context);
context.SetNoCurrentObject();
}
@@ -577,75 +547,12 @@ gd::String EventsCodeGenerator::GenerateActionCode(
} else {
vector<gd::String> arguments = GenerateParametersCodes(
action.GetParameters(), instrInfos.parameters, context);
actionCode += GenerateFreeAction(functionCallName,
arguments,
instrInfos,
context,
optionalAsyncCallbackName);
actionCode += GenerateFreeAction(arguments, instrInfos, context);
}
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.
*/
@@ -670,20 +577,8 @@ gd::String EventsCodeGenerator::GenerateActionsListCode(
return outputCode;
}
const gd::String EventsCodeGenerator::GenerateRelationalOperatorCodes(const gd::String &operatorString) {
if (operatorString == "=") {
return "==";
}
if (operatorString != "<" && operatorString != ">" &&
operatorString != "<=" && operatorString != ">=" && operatorString != "!=") {
cout << "Warning: Bad relational operator: Set to == by default." << endl;
return "==";
}
return operatorString;
}
gd::String EventsCodeGenerator::GenerateParameterCodes(
const gd::Expression& parameter,
const gd::String& parameter,
const gd::ParameterMetadata& metadata,
gd::EventsCodeGenerationContext& context,
const gd::String& lastObjectName,
@@ -691,25 +586,30 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
supplementaryParametersTypes) {
gd::String argOutput;
if (ParameterMetadata::IsExpression("number", metadata.GetType())) {
if (ParameterMetadata::IsExpression("number", metadata.type)) {
argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode(
*this, context, "number", parameter, lastObjectName);
} else if (ParameterMetadata::IsExpression("string", metadata.GetType())) {
*this, context, "number", parameter);
} else if (ParameterMetadata::IsExpression("string", metadata.type)) {
argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode(
*this, context, "string", parameter, lastObjectName);
} else if (ParameterMetadata::IsExpression("variable", metadata.GetType())) {
*this, context, "string", parameter);
} else if (ParameterMetadata::IsExpression("variable", metadata.type)) {
argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode(
*this, context, metadata.GetType(), parameter, lastObjectName);
} else if (ParameterMetadata::IsObject(metadata.GetType())) {
*this, context, metadata.type, parameter, lastObjectName);
} else if (ParameterMetadata::IsObject(metadata.type)) {
// It would be possible to run a gd::ExpressionCodeGenerator if later
// objects can have nested objects, or function returning objects.
argOutput =
GenerateObject(parameter.GetPlainString(), metadata.GetType(), context);
} else if (metadata.GetType() == "relationalOperator") {
argOutput += GenerateRelationalOperatorCodes(parameter.GetPlainString());
argOutput = GenerateObject(parameter, metadata.type, context);
} else if (metadata.type == "relationalOperator") {
argOutput += parameter == "=" ? "==" : parameter;
if (argOutput != "==" && argOutput != "<" && argOutput != ">" &&
argOutput != "<=" && argOutput != ">=" && argOutput != "!=") {
cout << "Warning: Bad relational operator: Set to == by default." << endl;
argOutput = "==";
}
argOutput = "\"" + argOutput + "\"";
} else if (metadata.GetType() == "operator") {
argOutput += parameter.GetPlainString();
} else if (metadata.type == "operator") {
argOutput += parameter;
if (argOutput != "=" && argOutput != "+" && argOutput != "-" &&
argOutput != "/" && argOutput != "*") {
cout << "Warning: Bad operator: Set to = by default." << endl;
@@ -717,52 +617,47 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
}
argOutput = "\"" + argOutput + "\"";
} else if (ParameterMetadata::IsBehavior(metadata.GetType())) {
argOutput = GenerateGetBehaviorNameCode(parameter.GetPlainString());
} else if (metadata.GetType() == "key") {
argOutput = "\"" + ConvertToString(parameter.GetPlainString()) + "\"";
} else if (metadata.GetType() == "audioResource" ||
metadata.GetType() == "bitmapFontResource" ||
metadata.GetType() == "fontResource" ||
metadata.GetType() == "imageResource" ||
metadata.GetType() == "jsonResource" ||
metadata.GetType() == "videoResource" ||
// Deprecated, old parameter names:
metadata.GetType() == "password" || metadata.GetType() == "musicfile" ||
metadata.GetType() == "soundfile" || metadata.GetType() == "police") {
argOutput = "\"" + ConvertToString(parameter.GetPlainString()) + "\"";
} else if (metadata.GetType() == "mouse") {
argOutput = "\"" + ConvertToString(parameter.GetPlainString()) + "\"";
} else if (metadata.GetType() == "yesorno") {
auto parameterString = parameter.GetPlainString();
argOutput += (parameterString == "yes" || parameterString == "oui")
? GenerateTrue()
: GenerateFalse();
} else if (metadata.GetType() == "trueorfalse") {
auto parameterString = parameter.GetPlainString();
} else if (ParameterMetadata::IsBehavior(metadata.type)) {
argOutput = GenerateGetBehaviorNameCode(parameter);
} else if (metadata.type == "key") {
argOutput = "\"" + ConvertToString(parameter) + "\"";
} else if (metadata.type == "password" || // Deprecated
metadata.type ==
"musicfile" || // Should be renamed "largeAudioResource"
metadata.type ==
"soundfile" || // Should be renamed "audioResource"
metadata.type == "police" || // Should be renamed "fontResource"
metadata.type == "bitmapFontResource" ||
metadata.type == "imageResource") {
argOutput = "\"" + ConvertToString(parameter) + "\"";
} else if (metadata.type == "mouse") {
argOutput = "\"" + ConvertToString(parameter) + "\"";
} else if (metadata.type == "yesorno") {
argOutput += (parameter == "yes" || parameter == "oui") ? GenerateTrue()
: GenerateFalse();
} else if (metadata.type == "trueorfalse") {
// This is duplicated in AdvancedExtension.cpp for GDJS
argOutput += (parameterString == "True" || parameterString == "Vrai")
? GenerateTrue()
: GenerateFalse();
argOutput += (parameter == "True" || parameter == "Vrai") ? GenerateTrue()
: GenerateFalse();
}
// Code only parameter type
else if (metadata.GetType() == "inlineCode") {
argOutput += metadata.GetExtraInfo();
else if (metadata.type == "inlineCode") {
argOutput += metadata.supplementaryInformation;
} else {
// Try supplementary types if provided
if (supplementaryParametersTypes) {
for (std::size_t i = 0; i < supplementaryParametersTypes->size(); ++i) {
if ((*supplementaryParametersTypes)[i].first == metadata.GetType())
if ((*supplementaryParametersTypes)[i].first == metadata.type)
argOutput += (*supplementaryParametersTypes)[i].second;
}
}
// Type unknown
if (argOutput.empty()) {
if (!metadata.GetType().empty())
cout << "Warning: Unknown type of parameter \"" << metadata.GetType()
if (!metadata.type.empty())
cout << "Warning: Unknown type of parameter \"" << metadata.type
<< "\"." << std::endl;
argOutput += "\"" + ConvertToString(parameter.GetPlainString()) + "\"";
argOutput += "\"" + ConvertToString(parameter) + "\"";
}
}
@@ -782,7 +677,7 @@ vector<gd::String> EventsCodeGenerator::GenerateParametersCodes(
parametersInfo,
[this, &context, &supplementaryParametersTypes, &arguments](
const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue,
const gd::String& parameterValue,
const gd::String& lastObjectName) {
gd::String argOutput =
GenerateParameterCodes(parameterValue,
@@ -834,21 +729,23 @@ gd::String EventsCodeGenerator::GenerateObjectsDeclarationCode(
gd::String declarationsCode;
for (auto object : context.GetObjectsListsToBeDeclared()) {
gd::String objectListDeclaration = "";
if (!context.ObjectAlreadyDeclaredByParents(object)) {
if (!context.ObjectAlreadyDeclared(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.GetObjectsListsToBeEmptyIfJustDeclared()) {
for (auto object : context.GetObjectsListsToBeDeclaredWithoutPicking()) {
gd::String objectListDeclaration = "";
if (!context.ObjectAlreadyDeclaredByParents(object)) {
if (!context.ObjectAlreadyDeclared(object)) {
objectListDeclaration = "std::vector<RuntimeObject*> " +
GetObjectListName(object, context) + ";\n";
context.SetObjectDeclared(object);
} else
objectListDeclaration = declareObjectList(object, context);
@@ -856,9 +753,10 @@ gd::String EventsCodeGenerator::GenerateObjectsDeclarationCode(
}
for (auto object : context.GetObjectsListsToBeDeclaredEmpty()) {
gd::String objectListDeclaration = "";
if (!context.ObjectAlreadyDeclaredByParents(object)) {
if (!context.ObjectAlreadyDeclared(object)) {
objectListDeclaration = "std::vector<RuntimeObject*> " +
GetObjectListName(object, context) + ";\n";
context.SetObjectDeclared(object);
} else
objectListDeclaration = "std::vector<RuntimeObject*> " +
GetObjectListName(object, context) + ";\n";
@@ -873,7 +771,7 @@ gd::String EventsCodeGenerator::GenerateObjectsDeclarationCode(
* Generate events list code.
*/
gd::String EventsCodeGenerator::GenerateEventsListCode(
gd::EventsList& events, EventsCodeGenerationContext& parentContext) {
gd::EventsList& events, const 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
@@ -889,8 +787,6 @@ gd::String EventsCodeGenerator::GenerateEventsListCode(
// operation.
bool reuseParentContext =
parentContext.CanReuse() && eId == events.size() - 1;
// TODO: avoid creating if useless.
gd::EventsCodeGenerationContext reusedContext;
reusedContext.Reuse(parentContext);
@@ -1035,7 +931,7 @@ gd::String EventsCodeGenerator::GenerateFreeCondition(
for (std::size_t i = 0; i < instrInfos.parameters.size();
++i) // Some conditions already have a "conditionInverted" parameter
{
if (instrInfos.parameters[i].GetType() == "conditionInverted")
if (instrInfos.parameters[i].type == "conditionInverted")
conditionAlreadyTakeCareOfInversion = true;
}
if (!conditionAlreadyTakeCareOfInversion && conditionInverted)
@@ -1056,7 +952,7 @@ gd::String EventsCodeGenerator::GenerateObjectCondition(
// Prepare call
// Add a static_cast if necessary
gd::String objectFunctionCallNamePart =
(!instrInfos.parameters[0].GetExtraInfo().empty())
(!instrInfos.parameters[0].supplementaryInformation.empty())
? "static_cast<" + objInfo.className + "*>(" +
GetObjectListName(objectName, context) + "[i])->" +
instrInfos.codeExtraInformation.functionCallName
@@ -1103,11 +999,9 @@ gd::String EventsCodeGenerator::GenerateBehaviorCondition(
}
gd::String EventsCodeGenerator::GenerateFreeAction(
const gd::String& functionCallName,
const std::vector<gd::String>& arguments,
const gd::InstructionMetadata& instrInfos,
gd::EventsCodeGenerationContext& context,
const gd::String& optionalAsyncCallbackName) {
gd::EventsCodeGenerationContext& context) {
// Generate call
gd::String call;
if (instrInfos.codeExtraInformation.type == "number" ||
@@ -1117,39 +1011,32 @@ gd::String EventsCodeGenerator::GenerateFreeAction(
call = GenerateOperatorCall(
instrInfos,
arguments,
functionCallName,
instrInfos.codeExtraInformation.functionCallName,
instrInfos.codeExtraInformation.optionalAssociatedInstruction);
else if (instrInfos.codeExtraInformation.accessType ==
gd::InstructionMetadata::ExtraInformation::Mutators)
call =
GenerateMutatorCall(instrInfos,
arguments,
functionCallName);
instrInfos.codeExtraInformation.functionCallName);
else
call = GenerateCompoundOperatorCall(
instrInfos,
arguments,
functionCallName);
instrInfos.codeExtraInformation.functionCallName);
} else {
call = functionCallName + "(" +
call = instrInfos.codeExtraInformation.functionCallName + "(" +
GenerateArgumentsList(arguments) + ")";
}
if (!optionalAsyncCallbackName.empty())
call = "runtimeScene.getAsyncTasksManager().addTask(" + call + ", " +
optionalAsyncCallbackName + ")";
return call + ";\n";
}
gd::String EventsCodeGenerator::GenerateObjectAction(
const gd::String& objectName,
const gd::ObjectMetadata& objInfo,
const gd::String& functionCallName,
const std::vector<gd::String>& arguments,
const gd::InstructionMetadata& instrInfos,
gd::EventsCodeGenerationContext& context,
const gd::String& optionalAsyncCallbackName) {
gd::EventsCodeGenerationContext& context) {
// Create call
gd::String call;
if ((instrInfos.codeExtraInformation.type == "number" ||
@@ -1159,26 +1046,25 @@ gd::String EventsCodeGenerator::GenerateObjectAction(
call = GenerateOperatorCall(
instrInfos,
arguments,
functionCallName,
instrInfos.codeExtraInformation.functionCallName,
instrInfos.codeExtraInformation.optionalAssociatedInstruction,
2);
else
call = GenerateCompoundOperatorCall(
instrInfos, arguments, functionCallName, 2);
instrInfos,
arguments,
instrInfos.codeExtraInformation.functionCallName,
2);
return "For each picked object \"" + objectName + "\", call " + call +
".\n";
} else {
gd::String argumentsStr = GenerateArgumentsList(arguments, 1);
call = functionCallName + "(" + argumentsStr + ")";
call = instrInfos.codeExtraInformation.functionCallName + "(" +
argumentsStr + ")";
return "For each picked object \"" + objectName + "\", call " + call + "(" +
argumentsStr + ")" +
(optionalAsyncCallbackName.empty()
? ""
: (", then call" + optionalAsyncCallbackName)) +
".\n";
argumentsStr + ").\n";
}
}
@@ -1186,11 +1072,9 @@ gd::String EventsCodeGenerator::GenerateBehaviorAction(
const gd::String& objectName,
const gd::String& behaviorName,
const gd::BehaviorMetadata& autoInfo,
const gd::String& functionCallName,
const std::vector<gd::String>& arguments,
const gd::InstructionMetadata& instrInfos,
gd::EventsCodeGenerationContext& context,
const gd::String& optionalAsyncCallbackName) {
gd::EventsCodeGenerationContext& context) {
// Create call
gd::String call;
if ((instrInfos.codeExtraInformation.type == "number" ||
@@ -1200,29 +1084,24 @@ gd::String EventsCodeGenerator::GenerateBehaviorAction(
call = GenerateOperatorCall(
instrInfos,
arguments,
functionCallName,
instrInfos.codeExtraInformation.functionCallName,
instrInfos.codeExtraInformation.optionalAssociatedInstruction,
2);
else
call = GenerateCompoundOperatorCall(
instrInfos,
arguments,
functionCallName,
instrInfos.codeExtraInformation.functionCallName,
2);
return "For each picked object \"" + objectName + "\", call " + call +
" for behavior \"" + behaviorName + "\".\n";
} else {
gd::String argumentsStr = GenerateArgumentsList(arguments, 2);
call = functionCallName + "(" +
call = instrInfos.codeExtraInformation.functionCallName + "(" +
argumentsStr + ")";
return "For each picked object \"" + objectName + "\", call " + call + "(" +
argumentsStr + ")" + " for behavior \"" + behaviorName + "\"" +
(optionalAsyncCallbackName.empty()
? ""
: (", then call" + optionalAsyncCallbackName)) +
".\n";
argumentsStr + ")" + " for behavior \"" + behaviorName + "\".\n";
}
}
@@ -1270,7 +1149,7 @@ gd::String EventsCodeGenerator::GenerateArgumentsList(
return argumentsStr;
}
EventsCodeGenerator::EventsCodeGenerator(const gd::Project& project_,
EventsCodeGenerator::EventsCodeGenerator(gd::Project& project_,
const gd::Layout& layout,
const gd::Platform& platform_)
: platform(platform_),
@@ -1287,7 +1166,7 @@ EventsCodeGenerator::EventsCodeGenerator(const gd::Project& project_,
EventsCodeGenerator::EventsCodeGenerator(
const gd::Platform& platform_,
const gd::ObjectsContainer& globalObjectsAndGroups_,
gd::ObjectsContainer& globalObjectsAndGroups_,
const gd::ObjectsContainer& objectsAndGroups_)
: platform(platform_),
globalObjectsAndGroups(globalObjectsAndGroups_),

View File

@@ -48,7 +48,7 @@ class GD_CORE_API EventsCodeGenerator {
* \brief Construct a code generator for the specified
* platform/project/layout.
*/
EventsCodeGenerator(const gd::Project& project_,
EventsCodeGenerator(gd::Project& project_,
const gd::Layout& layout,
const gd::Platform& platform_);
@@ -57,7 +57,7 @@ class GD_CORE_API EventsCodeGenerator {
* objects/groups and platform
*/
EventsCodeGenerator(const gd::Platform& platform,
const gd::ObjectsContainer& globalObjectsAndGroups_,
gd::ObjectsContainer& globalObjectsAndGroups_,
const gd::ObjectsContainer& objectsAndGroups_);
virtual ~EventsCodeGenerator(){};
@@ -77,7 +77,7 @@ class GD_CORE_API EventsCodeGenerator {
* \return Code
*/
virtual gd::String GenerateEventsListCode(
gd::EventsList& events, EventsCodeGenerationContext& context);
gd::EventsList& events, const EventsCodeGenerationContext& context);
/**
* \brief Generate code for executing a condition list
@@ -154,54 +154,8 @@ class GD_CORE_API EventsCodeGenerator {
* \param context Context used for generation
* \return Code
*/
gd::String GenerateActionCode(
gd::Instruction& action,
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);
gd::String GenerateActionCode(gd::Instruction& action,
EventsCodeGenerationContext& context);
/**
* \brief Generate code for declaring objects lists.
@@ -329,7 +283,7 @@ class GD_CORE_API EventsCodeGenerator {
/**
* \brief Get the global objects/groups used for code generation.
*/
const gd::ObjectsContainer& GetGlobalObjectsAndGroups() const {
gd::ObjectsContainer& GetGlobalObjectsAndGroups() const {
return globalObjectsAndGroups;
}
@@ -350,7 +304,7 @@ class GD_CORE_API EventsCodeGenerator {
* \brief Get the project the code is being generated for.
* \warning This is only valid if HasProjectAndLayout() is true.
*/
const gd::Project& GetProject() const { return *project; }
gd::Project& GetProject() const { return *project; }
/**
* \brief Get the layout the code is being generated for.
@@ -481,9 +435,6 @@ class GD_CORE_API EventsCodeGenerator {
*/
size_t GenerateSingleUsageUniqueIdForEventsList();
virtual const gd::String GenerateRelationalOperatorCodes(
const gd::String& operatorString);
protected:
/**
* \brief Generate the code for a single parameter.
@@ -511,18 +462,25 @@ 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.
* - 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 another parameter. Example:
object name in another parameter. Example:
* \code
AddExpression("Count", _("Object count"), _("Count the number of picked
objects"), _("Objects"), "res/conditions/nbObjet.png")
.AddParameter("objectList", _("Object"))
.SetFunctionName("getPickedObjectsCount");
* \endcode
* - objectListWithoutPicking : 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
another parameter. Example:
* \code
.AddParameter("object", _("Object"))
.AddParameter("objectPtr", _("Target object"))
* \endcode
*/
virtual gd::String GenerateParameterCodes(
const gd::Expression& parameter,
const gd::String& parameter,
const gd::ParameterMetadata& metadata,
gd::EventsCodeGenerationContext& context,
const gd::String& lastObjectName,
@@ -705,30 +663,24 @@ class GD_CORE_API EventsCodeGenerator {
gd::EventsCodeGenerationContext& context);
virtual gd::String GenerateFreeAction(
const gd::String& functionCallName,
const std::vector<gd::String>& arguments,
const gd::InstructionMetadata& instrInfos,
gd::EventsCodeGenerationContext& context,
const gd::String& optionalAsyncCallbackName = "");
gd::EventsCodeGenerationContext& context);
virtual gd::String GenerateObjectAction(
const gd::String& objectName,
const gd::ObjectMetadata& objInfo,
const gd::String& functionCallName,
const std::vector<gd::String>& arguments,
const gd::InstructionMetadata& instrInfos,
gd::EventsCodeGenerationContext& context,
const gd::String& optionalAsyncCallbackName = "");
gd::EventsCodeGenerationContext& context);
virtual gd::String GenerateBehaviorAction(
const gd::String& objectName,
const gd::String& behaviorName,
const gd::BehaviorMetadata& autoInfo,
const gd::String& functionCallName,
const std::vector<gd::String>& arguments,
const gd::InstructionMetadata& instrInfos,
gd::EventsCodeGenerationContext& context,
const gd::String& optionalAsyncCallbackName = "");
gd::EventsCodeGenerationContext& context);
gd::String GenerateRelationalOperatorCall(
const gd::InstructionMetadata& instrInfos,
@@ -778,13 +730,13 @@ class GD_CORE_API EventsCodeGenerator {
const gd::Platform& platform; ///< The platform being used.
const gd::ObjectsContainer& globalObjectsAndGroups;
gd::ObjectsContainer& globalObjectsAndGroups;
const gd::ObjectsContainer& objectsAndGroups;
bool hasProjectAndLayout; ///< true only if project and layout are valid
///< references. If false, they should not be used.
const gd::Project* project; ///< The project being used.
const gd::Layout* scene; ///< The scene being generated.
gd::Project* project; ///< The project being used.
const gd::Layout* scene; ///< The scene being generated.
bool errorOccurred; ///< Must be set to true if an error occured.
bool compilationForRuntime; ///< Is set to true if the code generation is

View File

@@ -25,38 +25,36 @@
#include "GDCore/IDE/Events/ExpressionValidator.h"
#include "GDCore/Project/Layout.h"
#include "GDCore/Project/Project.h"
#include "GDCore/IDE/Events/ExpressionTypeFinder.h"
#include "GDCore/IDE/Events/ExpressionVariableOwnerFinder.h"
namespace gd {
gd::String ExpressionCodeGenerator::GenerateExpressionCode(
EventsCodeGenerator& codeGenerator,
EventsCodeGenerationContext& context,
const gd::String& rootType,
const gd::Expression& expression,
const gd::String& rootObjectName) {
ExpressionCodeGenerator generator(rootType, rootObjectName, codeGenerator, context);
const gd::String& type,
const gd::String& expression,
const gd::String& objectName) {
gd::ExpressionParser2 parser(codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups());
ExpressionCodeGenerator generator(codeGenerator, context);
auto node = expression.GetRootNode();
auto node = parser.ParseExpression(type, expression, objectName);
if (!node) {
std::cout << "Error: error while parsing: \"" << expression.GetPlainString()
<< "\" (" << rootType << ")" << std::endl;
std::cout << "Error: error while parsing: \"" << expression << "\" ("
<< type << ")" << std::endl;
return generator.GenerateDefaultValue(rootType);
return generator.GenerateDefaultValue(type);
}
gd::ExpressionValidator validator(codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
rootType);
gd::ExpressionValidator validator;
node->Visit(validator);
if (!validator.GetErrors().empty()) {
std::cout << "Error: \"" << validator.GetErrors()[0]->GetMessage()
<< "\" in: \"" << expression.GetPlainString() << "\" ("
<< rootType << ")" << std::endl;
<< "\" in: \"" << expression << "\" (" << type << ")"
<< std::endl;
return generator.GenerateDefaultValue(rootType);
return generator.GenerateDefaultValue(type);
}
node->Visit(generator);
@@ -99,24 +97,15 @@ void ExpressionCodeGenerator::OnVisitTextNode(TextNode& node) {
void ExpressionCodeGenerator::OnVisitVariableNode(VariableNode& node) {
// This "translation" from the type to an enum could be avoided
// if all types were moved to an enum.
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
rootType,
node);
EventsCodeGenerator::VariableScope scope =
type == "globalvar"
node.type == "globalvar"
? gd::EventsCodeGenerator::PROJECT_VARIABLE
: ((type == "scenevar")
: ((node.type == "scenevar")
? gd::EventsCodeGenerator::LAYOUT_VARIABLE
: gd::EventsCodeGenerator::OBJECT_VARIABLE);
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
rootObjectName,
node);
output += codeGenerator.GenerateGetVariable(
node.name, scope, context, objectName);
node.name, scope, context, node.objectName);
if (node.child) node.child->Visit(*this);
}
@@ -128,7 +117,7 @@ void ExpressionCodeGenerator::OnVisitVariableAccessorNode(
void ExpressionCodeGenerator::OnVisitVariableBracketAccessorNode(
VariableBracketAccessorNode& node) {
ExpressionCodeGenerator generator("string", "", codeGenerator, context);
ExpressionCodeGenerator generator(codeGenerator, context);
node.expression->Visit(generator);
output +=
codeGenerator.GenerateVariableBracketAccessor(generator.GetOutput());
@@ -136,79 +125,39 @@ void ExpressionCodeGenerator::OnVisitVariableBracketAccessorNode(
}
void ExpressionCodeGenerator::OnVisitIdentifierNode(IdentifierNode& node) {
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
rootType,
node);
if (gd::ParameterMetadata::IsObject(type)) {
if (gd::ParameterMetadata::IsObject(node.type)) {
output +=
codeGenerator.GenerateObject(node.identifierName, type, context);
} else if (gd::ParameterMetadata::IsExpression("variable", type)) {
EventsCodeGenerator::VariableScope scope =
type == "globalvar"
? gd::EventsCodeGenerator::PROJECT_VARIABLE
: ((type == "scenevar")
? gd::EventsCodeGenerator::LAYOUT_VARIABLE
: gd::EventsCodeGenerator::OBJECT_VARIABLE);
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
rootObjectName,
node);
output += codeGenerator.GenerateGetVariable(
node.identifierName, scope, context, objectName);
if (!node.childIdentifierName.empty()) {
output += codeGenerator.GenerateVariableAccessor(node.childIdentifierName);
}
} else if (node.childIdentifierName.empty()) {
codeGenerator.GenerateObject(node.identifierName, node.type, context);
} else {
output += "/* Error during generation, unrecognized identifier type: " +
codeGenerator.ConvertToString(type) + " with value " +
codeGenerator.ConvertToString(node.type) + " with value " +
codeGenerator.ConvertToString(node.identifierName) + " */ " +
codeGenerator.ConvertToStringExplicit(node.identifierName);
}
else {
// This is for function names that are put in IdentifierNode
// because the type is needed to tell them appart from variables.
output += GenerateDefaultValue(type);
}
}
void ExpressionCodeGenerator::OnVisitFunctionCallNode(FunctionCallNode& node) {
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
rootType,
node);
const gd::ExpressionMetadata &metadata = MetadataProvider::GetFunctionCallMetadata(
codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
node);
if (gd::MetadataProvider::IsBadExpressionMetadata(metadata)) {
if (gd::MetadataProvider::IsBadExpressionMetadata(node.expressionMetadata)) {
output += "/* Error during generation, function not found: " +
codeGenerator.ConvertToString(node.functionName) + " */ " +
GenerateDefaultValue(type);
GenerateDefaultValue(node.type);
return;
}
if (!node.objectName.empty()) {
if (!node.behaviorName.empty()) {
output += GenerateBehaviorFunctionCode(type,
output += GenerateBehaviorFunctionCode(node.type,
node.objectName,
node.behaviorName,
node.parameters,
metadata);
node.expressionMetadata);
} else {
output += GenerateObjectFunctionCode(
type, node.objectName, node.parameters, metadata);
node.type, node.objectName, node.parameters, node.expressionMetadata);
}
} else {
output +=
GenerateFreeFunctionCode(node.parameters, metadata);
GenerateFreeFunctionCode(node.parameters, node.expressionMetadata);
}
}
@@ -270,20 +219,14 @@ gd::String ExpressionCodeGenerator::GenerateObjectFunctionCode(
const ObjectMetadata& objInfo = MetadataProvider::GetObjectMetadata(
codeGenerator.GetPlatform(), objectType);
if (objInfo.IsUnsupportedBaseObjectCapability(
expressionMetadata.GetRequiredBaseObjectCapability())) {
// Do nothing, skipping objects not supporting the capability required by
// this expression.
} else {
codeGenerator.AddIncludeFiles(objInfo.includeFiles);
functionOutput = codeGenerator.GenerateObjectFunctionCall(
realObjects[i],
objInfo,
expressionMetadata.codeExtraInformation,
parametersCode,
functionOutput,
context);
}
codeGenerator.AddIncludeFiles(objInfo.includeFiles);
functionOutput = codeGenerator.GenerateObjectFunctionCall(
realObjects[i],
objInfo,
expressionMetadata.codeExtraInformation,
parametersCode,
functionOutput,
context);
}
return functionOutput;
@@ -356,21 +299,18 @@ gd::String ExpressionCodeGenerator::GenerateParametersCodes(
auto& parameterMetadata = expressionMetadata.parameters[i];
if (!parameterMetadata.IsCodeOnly()) {
ExpressionCodeGenerator generator(codeGenerator, context);
if (nonCodeOnlyParameterIndex < parameters.size()) {
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
rootObjectName,
*parameters[nonCodeOnlyParameterIndex].get());
ExpressionCodeGenerator generator(parameterMetadata.GetType(), objectName, codeGenerator, context);
parameters[nonCodeOnlyParameterIndex]->Visit(generator);
parametersCode += generator.GetOutput();
} else if (parameterMetadata.IsOptional()) {
ExpressionCodeGenerator generator(parameterMetadata.GetType(), "", codeGenerator, context);
// Optional parameters default value were not parsed at the time of the
// expression parsing. Parse them now.
ExpressionParser2 parser;
auto node = parser.ParseExpression(parameterMetadata.GetDefaultValue());
ExpressionParser2 parser(codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups());
auto node = parser.ParseExpression(parameterMetadata.GetType(),
parameterMetadata.GetDefaultValue());
node->Visit(generator);
parametersCode += generator.GetOutput();
@@ -428,22 +368,12 @@ gd::String ExpressionCodeGenerator::GenerateDefaultValue(
}
void ExpressionCodeGenerator::OnVisitEmptyNode(EmptyNode& node) {
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
rootType,
node);
output += GenerateDefaultValue(type);
output += GenerateDefaultValue(node.type);
}
void ExpressionCodeGenerator::OnVisitObjectFunctionNameNode(
ObjectFunctionNameNode& node) {
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
rootType,
node);
output += GenerateDefaultValue(type);
output += GenerateDefaultValue(node.type);
}
} // namespace gd

View File

@@ -9,6 +9,7 @@
#include <memory>
#include <vector>
#include "GDCore/Events/Parsers/ExpressionParser2.h"
#include "GDCore/Events/Parsers/ExpressionParser2Node.h"
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
#include "GDCore/String.h"
@@ -34,11 +35,9 @@ namespace gd {
*/
class GD_CORE_API ExpressionCodeGenerator : public ExpressionParser2NodeWorker {
public:
ExpressionCodeGenerator(const gd::String &rootType_,
const gd::String &rootObjectName_,
EventsCodeGenerator& codeGenerator_,
ExpressionCodeGenerator(EventsCodeGenerator& codeGenerator_,
EventsCodeGenerationContext& context_)
: rootType(rootType_), rootObjectName(rootObjectName_), codeGenerator(codeGenerator_), context(context_){};
: codeGenerator(codeGenerator_), context(context_){};
virtual ~ExpressionCodeGenerator(){};
/**
@@ -58,7 +57,7 @@ class GD_CORE_API ExpressionCodeGenerator : public ExpressionParser2NodeWorker {
static gd::String GenerateExpressionCode(EventsCodeGenerator& codeGenerator,
EventsCodeGenerationContext& context,
const gd::String& type,
const gd::Expression& expression,
const gd::String& expression,
const gd::String& objectName = "");
const gd::String& GetOutput() { return output; };
@@ -104,8 +103,6 @@ class GD_CORE_API ExpressionCodeGenerator : public ExpressionParser2NodeWorker {
gd::String output;
EventsCodeGenerator& codeGenerator;
EventsCodeGenerationContext& context;
const gd::String rootType;
const gd::String rootObjectName;
};
} // namespace gd

View File

@@ -5,11 +5,8 @@
*/
#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"
@@ -68,41 +65,10 @@ 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() &&
(!actionMetadata.IsOptionallyAsync() || action.IsAwaited())) {
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()) return;
PreprocessAsyncActions(codeGenerator.GetPlatform());
if (!MustBePreprocessed()) return;
if (IsDisabled() || !MustBePreprocessed()) return;
try {
if (type.empty()) return;

View File

@@ -10,7 +10,6 @@
#include <iostream>
#include <memory>
#include <vector>
#include "GDCore/Events/Instruction.h"
#include "GDCore/Events/InstructionsList.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
@@ -24,7 +23,7 @@ class EventsCodeGenerationContext;
class Platform;
class SerializerElement;
class Instruction;
} // namespace gd
}
namespace gd {
@@ -127,25 +126,18 @@ class GD_CORE_API BaseEvent {
return noSearchableStrings;
};
virtual bool ReplaceAllSearchableStrings(
std::vector<gd::String> newSearchableString) {
return false;
};
/**
* \brief Return a list of all expressions of the event, each with their associated metadata.
* \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;
};
@@ -209,11 +201,6 @@ 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

View File

@@ -1,41 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "GDCore/Events/Expression.h"
#include "GDCore/Events/Parsers/ExpressionParser2.h"
#include "GDCore/String.h"
namespace gd {
Expression::Expression() : node(nullptr) {};
Expression::Expression(gd::String plainString_)
: node(nullptr), plainString(plainString_) {};
Expression::Expression(const char* plainString_)
: node(nullptr), plainString(plainString_) {};
Expression::Expression(const Expression& copy)
: node(nullptr), plainString{copy.plainString} {};
Expression& Expression::operator=(const Expression& expression) {
plainString = expression.plainString;
node = nullptr;
return *this;
};
Expression::~Expression(){};
ExpressionNode* Expression::GetRootNode() const {
if (!node) {
gd::ExpressionParser2 parser = ExpressionParser2();
node = std::move(parser.ParseExpression(plainString));
}
return node.get();
}
} // namespace gd

View File

@@ -6,15 +6,7 @@
#ifndef GDCORE_EXPRESSION_H
#define GDCORE_EXPRESSION_H
#include "GDCore/String.h"
#include <memory>
namespace gd {
class ExpressionParser2;
class ObjectsContainer;
struct ExpressionNode;
} // namespace gd
namespace gd {
@@ -32,49 +24,32 @@ class GD_CORE_API Expression {
/**
* \brief Construct an empty expression
*/
Expression();
Expression(){};
/**
* \brief Construct an expression from a string
*/
Expression(gd::String plainString_);
Expression(gd::String plainString_) : plainString(plainString_){};
/**
* \brief Construct an expression from a const char *
*/
Expression(const char* plainString_);
/**
* \brief Copy construct an expression.
*/
Expression(const Expression& copy);
/**
* \brief Expression affectation overriding.
*/
Expression& operator=(const Expression& expression);
Expression(const char* plainString_) : plainString(plainString_){};
/**
* \brief Get the plain string representing the expression
*/
inline const gd::String& GetPlainString() const { return plainString; };
/**
* @brief Get the expression node.
* @return std::unique_ptr<gd::ExpressionNode>
*/
gd::ExpressionNode* GetRootNode() const;
/**
* \brief Mimics std::string::c_str
*/
inline const char* c_str() const { return plainString.c_str(); };
virtual ~Expression();
virtual ~Expression(){};
private:
gd::String plainString; ///< The expression string
mutable std::unique_ptr<gd::ExpressionNode> node;
};
} // namespace gd

View File

@@ -72,22 +72,6 @@ class GD_CORE_API Instruction {
*/
void SetInverted(bool inverted_) { inverted = inverted_; }
/**
* \brief Return true if the async instruction should be awaited.
* This is not relevant if the instruction is not optionally asynchronous.
*
* \return true if the instruction is to be awaited
*/
bool IsAwaited() const { return awaitAsync; }
/**
* \brief Set if the async instruction is to be awaited or not.
* This is not relevant if the instruction is not optionally asynchronous.
*
* \param inverted true if the instruction must be awaited
*/
void SetAwaited(bool awaited) { awaitAsync = awaited; }
/**
* \brief Return the number of parameters of the instruction.
*/
@@ -155,9 +139,7 @@ class GD_CORE_API Instruction {
* Useful to get reference to the original instruction in memory during code
* generation, to ensure stable unique identifiers.
*/
std::weak_ptr<Instruction> GetOriginalInstruction() {
return originalInstruction;
};
std::weak_ptr<Instruction> GetOriginalInstruction() { return originalInstruction; };
friend std::shared_ptr<Instruction> CloneRememberingOriginalElement(
std::shared_ptr<Instruction> instruction);
@@ -166,9 +148,6 @@ class GD_CORE_API Instruction {
gd::String type; ///< Instruction type
bool inverted; ///< True if the instruction if inverted. Only applicable for
///< instruction used as conditions by events
bool awaitAsync =
false; ///< Tells the code generator whether the optionally asynchronous
///< instruction should be generated as asynchronous (awaited) or not.
mutable std::vector<gd::Expression>
parameters; ///< Vector containing the parameters
gd::InstructionsList subInstructions; ///< Sub instructions, if applicable.

View File

@@ -5,7 +5,6 @@
*/
#include "InstructionsList.h"
#include "GDCore/Events/Instruction.h"
#include "GDCore/Project/Project.h"
#include "Serialization.h"
@@ -32,10 +31,6 @@ 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);
}

View File

@@ -6,10 +6,9 @@
#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;
}
@@ -23,11 +22,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);
void RemoveAfter(size_t position);
public:
void InsertInstructions(const InstructionsList& list,
size_t begin,
size_t end,
size_t position = (size_t)-1);
/** \name Serialization
*/
@@ -36,17 +35,17 @@ public:
* \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

View File

@@ -26,16 +26,132 @@ namespace gd {
gd::String ExpressionParser2::NAMESPACE_SEPARATOR = "::";
ExpressionParser2::ExpressionParser2()
ExpressionParser2::ExpressionParser2(
const gd::Platform& platform_,
const gd::ObjectsContainer& globalObjectsContainer_,
const gd::ObjectsContainer& objectsContainer_)
: expression(""),
currentPosition(0) {}
currentPosition(0),
platform(platform_),
globalObjectsContainer(globalObjectsContainer_),
objectsContainer(objectsContainer_) {}
namespace {
/**
* Return the minimum number of parameters, starting from a given parameter
* (by convention, 1 for object functions and 2 for behavior functions).
*/
size_t GetMinimumParametersNumber(
const std::vector<gd::ParameterMetadata>& parameters,
size_t initialParameterIndex) {
size_t nb = 0;
for (std::size_t i = initialParameterIndex; i < parameters.size(); ++i) {
if (!parameters[i].optional && !parameters[i].codeOnly) nb++;
}
return nb;
}
/**
* Return the maximum number of parameters, starting from a given parameter
* (by convention, 1 for object functions and 2 for behavior functions).
*/
size_t GetMaximumParametersNumber(
const std::vector<gd::ParameterMetadata>& parameters,
size_t initialParameterIndex) {
size_t nb = 0;
for (std::size_t i = initialParameterIndex; i < parameters.size(); ++i) {
if (!parameters[i].codeOnly) nb++;
}
return nb;
}
} // namespace
std::unique_ptr<ExpressionParserDiagnostic> ExpressionParser2::ValidateFunction(
const gd::String& type,
const gd::FunctionCallNode& function,
size_t functionStartPosition) {
if (gd::MetadataProvider::IsBadExpressionMetadata(
function.expressionMetadata)) {
return gd::make_unique<ExpressionParserError>(
"invalid_function_name",
_("Cannot find an expression with this name: ") +
function.functionName + "\n" +
_("Double check that you've not made any typo in the name."),
functionStartPosition,
GetCurrentPosition());
}
// Validate the type of the function
const gd::String& returnType = function.expressionMetadata.GetReturnType();
if (returnType == "number") {
if (type == "string")
return RaiseTypeError(
_("You tried to use an expression that returns a number, but a "
"string is expected. Use `ToString` if you need to convert a "
"number to a string."),
functionStartPosition);
else if (type != "number" && type != "number|string")
return RaiseTypeError(_("You tried to use an expression that returns a "
"number, but another type is expected:") +
" " + type,
functionStartPosition);
} else if (returnType == "string") {
if (type == "number")
return RaiseTypeError(
_("You tried to use an expression that returns a string, but a "
"number is expected. Use `ToNumber` if you need to convert a "
"string to a number."),
functionStartPosition);
else if (type != "string" && type != "number|string")
return RaiseTypeError(_("You tried to use an expression that returns a "
"string, but another type is expected:") +
" " + type,
functionStartPosition);
} else {
if (type != returnType)
return RaiseTypeError(
_("You tried to use an expression with the wrong return type:") + " " +
returnType,
functionStartPosition);
}
// Validate parameters count
size_t minParametersCount = GetMinimumParametersNumber(
function.expressionMetadata.parameters,
WrittenParametersFirstIndex(function.objectName, function.behaviorName));
size_t maxParametersCount = GetMaximumParametersNumber(
function.expressionMetadata.parameters,
WrittenParametersFirstIndex(function.objectName, function.behaviorName));
if (function.parameters.size() < minParametersCount ||
function.parameters.size() > maxParametersCount) {
gd::String expectedCountMessage =
minParametersCount == maxParametersCount
? _("The number of parameters must be exactly ") +
gd::String::From(minParametersCount)
: _("The number of parameters must be: ") +
gd::String::From(minParametersCount) + "-" +
gd::String::From(maxParametersCount);
if (function.parameters.size() < minParametersCount) {
return gd::make_unique<ExpressionParserError>(
"too_few_parameters",
"You have not entered enough parameters for the expression. " +
expectedCountMessage,
functionStartPosition,
GetCurrentPosition());
}
}
return gd::make_unique<ExpressionParserDiagnostic>();
}
std::unique_ptr<TextNode> ExpressionParser2::ReadText() {
size_t textStartPosition = GetCurrentPosition();
SkipAllWhitespaces();
if (!CheckIfChar(IsQuote)) {
auto text = gd::make_unique<TextNode>("");
// It can't happen.
text->diagnostic =
RaiseSyntaxError(_("A text must start with a double quote (\")."));
text->location =

View File

@@ -13,7 +13,6 @@
#include "ExpressionParser2Node.h"
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/Metadata/ObjectMetadata.h"
#include "GDCore/Project/Layout.h" // For GetTypeOfObject and GetTypeOfBehavior
#include "GDCore/String.h"
#include "GDCore/Tools/Localization.h"
@@ -40,7 +39,9 @@ namespace gd {
*/
class GD_CORE_API ExpressionParser2 {
public:
ExpressionParser2();
ExpressionParser2(const gd::Platform &platform_,
const gd::ObjectsContainer &globalObjectsContainer_,
const gd::ObjectsContainer &objectsContainer_);
virtual ~ExpressionParser2(){};
/**
@@ -56,11 +57,13 @@ class GD_CORE_API ExpressionParser2 {
* \return The node representing the expression as a parsed tree.
*/
std::unique_ptr<ExpressionNode> ParseExpression(
const gd::String &expression_) {
const gd::String &type,
const gd::String &expression_,
const gd::String &objectName = "") {
expression = expression_;
currentPosition = 0;
return Start();
return Start(type, objectName);
}
/**
@@ -84,16 +87,18 @@ class GD_CORE_API ExpressionParser2 {
* Each method is a part of the grammar.
*/
///@{
std::unique_ptr<ExpressionNode> Start() {
std::unique_ptr<ExpressionNode> Start(const gd::String &type,
const gd::String &objectName = "") {
size_t expressionStartPosition = GetCurrentPosition();
auto expression = Expression();
auto expression = Expression(type, objectName);
const gd::String &inferredType = expression->type;
// Check for extra characters at the end of the expression
if (!IsEndReached()) {
auto op = gd::make_unique<OperatorNode>(' ');
auto op = gd::make_unique<OperatorNode>(inferredType, ' ');
op->leftHandSide = std::move(expression);
op->rightHandSide = ReadUntilEnd();
op->rightHandSide->parent = op.get();
op->rightHandSide = ReadUntilEnd("unknown");
op->rightHandSide->diagnostic = RaiseSyntaxError(
_("The expression has extra character at the end that should be "
@@ -107,49 +112,61 @@ class GD_CORE_API ExpressionParser2 {
return expression;
}
std::unique_ptr<ExpressionNode> Expression() {
std::unique_ptr<ExpressionNode> Expression(
const gd::String &type, const gd::String &objectName = "") {
SkipAllWhitespaces();
size_t expressionStartPosition = GetCurrentPosition();
std::unique_ptr<ExpressionNode> leftHandSide = Term();
std::unique_ptr<ExpressionNode> leftHandSide = Term(type, objectName);
const gd::String &inferredType = leftHandSide->type;
SkipAllWhitespaces();
if (IsEndReached()) return leftHandSide;
if (CheckIfChar(IsExpressionEndingChar)) return leftHandSide;
if (CheckIfChar(IsExpressionOperator)) {
auto op = gd::make_unique<OperatorNode>(GetCurrentChar());
auto op = gd::make_unique<OperatorNode>(inferredType, GetCurrentChar());
op->leftHandSide = std::move(leftHandSide);
op->leftHandSide->parent = op.get();
op->diagnostic = ValidateOperator(GetCurrentChar());
op->diagnostic = ValidateOperator(inferredType, GetCurrentChar());
SkipChar();
op->rightHandSide = Expression();
op->rightHandSide->parent = op.get();
op->rightHandSide = Expression(inferredType, objectName);
op->location = ExpressionParserLocation(expressionStartPosition,
GetCurrentPosition());
return std::move(op);
}
leftHandSide->diagnostic = RaiseSyntaxError(
"More than one term was found. Verify that your expression is "
"properly written.");
if (inferredType == "string") {
leftHandSide->diagnostic = RaiseSyntaxError(
"You must add the operator + between texts or expressions. For "
"example: \"Your name: \" + VariableString(PlayerName).");
} else if (inferredType == "number") {
leftHandSide->diagnostic = RaiseSyntaxError(
"No operator found. Did you forget to enter an operator (like +, -, "
"* or /) between numbers or expressions?");
} else {
leftHandSide->diagnostic = RaiseSyntaxError(
"More than one term was found. Verify that your expression is "
"properly written.");
}
auto op = gd::make_unique<OperatorNode>(' ');
auto op = gd::make_unique<OperatorNode>(inferredType, ' ');
op->leftHandSide = std::move(leftHandSide);
op->leftHandSide->parent = op.get();
op->rightHandSide = Expression();
op->rightHandSide->parent = op.get();
op->rightHandSide = Expression(inferredType, objectName);
op->location =
ExpressionParserLocation(expressionStartPosition, GetCurrentPosition());
return std::move(op);
}
std::unique_ptr<ExpressionNode> Term() {
std::unique_ptr<ExpressionNode> Term(const gd::String &type,
const gd::String &objectName) {
SkipAllWhitespaces();
size_t expressionStartPosition = GetCurrentPosition();
std::unique_ptr<ExpressionNode> factor = Factor();
std::unique_ptr<ExpressionNode> factor = Factor(type, objectName);
const gd::String &inferredType = factor->type;
SkipAllWhitespaces();
@@ -157,13 +174,11 @@ class GD_CORE_API ExpressionParser2 {
// to guarantee the proper operator precedence. (Expression could also
// be reworked to use a while loop).
while (CheckIfChar(IsTermOperator)) {
auto op = gd::make_unique<OperatorNode>(GetCurrentChar());
auto op = gd::make_unique<OperatorNode>(inferredType, GetCurrentChar());
op->leftHandSide = std::move(factor);
op->leftHandSide->parent = op.get();
op->diagnostic = ValidateOperator(GetCurrentChar());
op->diagnostic = ValidateOperator(inferredType, GetCurrentChar());
SkipChar();
op->rightHandSide = Factor();
op->rightHandSide->parent = op.get();
op->rightHandSide = Factor(inferredType, objectName);
op->location = ExpressionParserLocation(expressionStartPosition,
GetCurrentPosition());
SkipAllWhitespaces();
@@ -174,35 +189,54 @@ class GD_CORE_API ExpressionParser2 {
return factor;
};
std::unique_ptr<ExpressionNode> Factor() {
std::unique_ptr<ExpressionNode> Factor(const gd::String &type,
const gd::String &objectName) {
SkipAllWhitespaces();
size_t expressionStartPosition = GetCurrentPosition();
if (CheckIfChar(IsQuote)) {
std::unique_ptr<ExpressionNode> factor = ReadText();
if (type == "number")
factor->diagnostic =
RaiseTypeError(_("You entered a text, but a number was expected."),
expressionStartPosition);
else if (type != "string" && type != "number|string")
factor->diagnostic = RaiseTypeError(
_("You entered a text, but this type was expected:") + type,
expressionStartPosition);
return factor;
} else if (CheckIfChar(IsUnaryOperator)) {
auto unaryOperatorCharacter = GetCurrentChar();
SkipChar();
auto operatorOperand = Factor();
auto operatorOperand = Factor(type, objectName);
const gd::String &inferredType = operatorOperand->type;
auto unaryOperator = gd::make_unique<UnaryOperatorNode>(
unaryOperatorCharacter);
inferredType, unaryOperatorCharacter);
unaryOperator->diagnostic = ValidateUnaryOperator(
unaryOperatorCharacter, expressionStartPosition);
inferredType, unaryOperatorCharacter, expressionStartPosition);
unaryOperator->factor = std::move(operatorOperand);
unaryOperator->factor->parent = unaryOperator.get();
unaryOperator->location = ExpressionParserLocation(
expressionStartPosition, GetCurrentPosition());
return std::move(unaryOperator);
} else if (CheckIfChar(IsNumberFirstChar)) {
std::unique_ptr<ExpressionNode> factor = ReadNumber();
if (type == "string")
factor->diagnostic = RaiseTypeError(
_("You entered a number, but a text was expected (in quotes)."),
expressionStartPosition);
else if (type != "number" && type != "number|string")
factor->diagnostic = RaiseTypeError(
_("You entered a number, but this type was expected:") + type,
expressionStartPosition);
return factor;
} else if (CheckIfChar(IsOpeningParenthesis)) {
SkipChar();
std::unique_ptr<ExpressionNode> factor = SubExpression();
std::unique_ptr<ExpressionNode> factor = SubExpression(type, objectName);
if (!CheckIfChar(IsClosingParenthesis)) {
factor->diagnostic =
@@ -212,20 +246,29 @@ class GD_CORE_API ExpressionParser2 {
SkipIfChar(IsClosingParenthesis);
return factor;
} else if (IsIdentifierAllowedChar()) {
return Identifier();
// This is a place where the grammar differs according to the
// type being expected.
if (gd::ParameterMetadata::IsExpression("variable", type)) {
return Variable(type, objectName);
} else {
return Identifier(type);
}
}
std::unique_ptr<ExpressionNode> factor = ReadUntilWhitespace();
std::unique_ptr<ExpressionNode> factor = ReadUntilWhitespace(type);
factor->diagnostic = RaiseEmptyError(type, expressionStartPosition);
return factor;
}
std::unique_ptr<SubExpressionNode> SubExpression() {
std::unique_ptr<SubExpressionNode> SubExpression(
const gd::String &type, const gd::String &objectName) {
size_t expressionStartPosition = GetCurrentPosition();
auto expression = Expression();
auto expression = Expression(type, objectName);
const gd::String &inferredType = expression->type;
auto subExpression =
gd::make_unique<SubExpressionNode>(std::move(expression));
gd::make_unique<SubExpressionNode>(inferredType, std::move(expression));
subExpression->location =
ExpressionParserLocation(expressionStartPosition, GetCurrentPosition());
@@ -233,7 +276,7 @@ class GD_CORE_API ExpressionParser2 {
};
std::unique_ptr<IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode>
Identifier() {
Identifier(const gd::String &type) {
auto identifierAndLocation = ReadIdentifierName();
gd::String name = identifierAndLocation.name;
auto nameLocation = identifierAndLocation.location;
@@ -260,28 +303,47 @@ class GD_CORE_API ExpressionParser2 {
if (CheckIfChar(IsOpeningParenthesis)) {
ExpressionParserLocation openingParenthesisLocation = SkipChar();
return FreeFunction(name, nameLocation, openingParenthesisLocation);
return FreeFunction(type, name, nameLocation, openingParenthesisLocation);
} else if (CheckIfChar(IsDot)) {
ExpressionParserLocation dotLocation = SkipChar();
SkipAllWhitespaces();
return ObjectFunctionOrBehaviorFunction(
name, nameLocation, dotLocation);
} else if (CheckIfChar(IsOpeningSquareBracket)) {
return Variable(name, nameLocation);
}
else {
auto identifier = gd::make_unique<IdentifierNode>(name);
type, name, nameLocation, dotLocation);
} else {
auto identifier = gd::make_unique<IdentifierNode>(name, type);
if (type == "string") {
identifier->diagnostic =
RaiseTypeError(_("You must wrap your text inside double quotes "
"(example: \"Hello world\")."),
nameLocation.GetStartPosition());
} else if (type == "number") {
identifier->diagnostic = RaiseTypeError(
_("You must enter a number."), nameLocation.GetStartPosition());
} else if (type == "number|string") {
identifier->diagnostic = RaiseTypeError(
_("You must enter a number or a text, wrapped inside double quotes "
"(example: \"Hello world\")."),
nameLocation.GetStartPosition());
} else if (!gd::ParameterMetadata::IsObject(type)) {
identifier->diagnostic = RaiseTypeError(
_("You've entered a name, but this type was expected:") + type,
nameLocation.GetStartPosition());
}
identifier->location = ExpressionParserLocation(
nameLocation.GetStartPosition(), GetCurrentPosition());
identifier->identifierNameLocation = identifier->location;
return std::move(identifier);
}
}
std::unique_ptr<VariableNode> Variable(const gd::String &name, gd::ExpressionParserLocation nameLocation) {
auto variable = gd::make_unique<VariableNode>(name);
std::unique_ptr<VariableNode> Variable(const gd::String &type,
const gd::String &objectName) {
auto identifierAndLocation = ReadIdentifierName();
const gd::String &name = identifierAndLocation.name;
const auto &nameLocation = identifierAndLocation.location;
auto variable = gd::make_unique<VariableNode>(type, name, objectName);
variable->child = VariableAccessorOrVariableBracketAccessor();
variable->child->parent = variable.get();
variable->location = ExpressionParserLocation(
nameLocation.GetStartPosition(), GetCurrentPosition());
@@ -296,8 +358,8 @@ class GD_CORE_API ExpressionParser2 {
SkipAllWhitespaces();
if (CheckIfChar(IsOpeningSquareBracket)) {
SkipChar();
auto child = gd::make_unique<VariableBracketAccessorNode>(Expression());
child->expression->parent = child.get();
auto child = gd::make_unique<VariableBracketAccessorNode>(
Expression("number|string"));
if (!CheckIfChar(IsClosingSquareBracket)) {
child->diagnostic =
@@ -306,7 +368,6 @@ class GD_CORE_API ExpressionParser2 {
}
SkipIfChar(IsClosingSquareBracket);
child->child = VariableAccessorOrVariableBracketAccessor();
child->child->parent = child.get();
child->location =
ExpressionParserLocation(childStartPosition, GetCurrentPosition());
@@ -319,7 +380,6 @@ class GD_CORE_API ExpressionParser2 {
auto child =
gd::make_unique<VariableAccessorNode>(identifierAndLocation.name);
child->child = VariableAccessorOrVariableBracketAccessor();
child->child->parent = child.get();
child->nameLocation = identifierAndLocation.location;
child->dotLocation = dotLocation;
child->location =
@@ -328,21 +388,40 @@ class GD_CORE_API ExpressionParser2 {
return std::move(child);
}
return std::move(gd::make_unique<VariableAccessorOrVariableBracketAccessorNode>());
return std::move(
std::unique_ptr<VariableAccessorOrVariableBracketAccessorNode>());
}
std::unique_ptr<FunctionCallNode> FreeFunction(
const gd::String &type,
const gd::String &functionFullName,
const ExpressionParserLocation &identifierLocation,
const ExpressionParserLocation &openingParenthesisLocation) {
// TODO: error if trying to use function for type != "number" && != "string"
// + Test for it
const gd::ExpressionMetadata &metadata =
MetadataProvider::GetAnyExpressionMetadata(platform, functionFullName);
// In case we can't find a valid expression, ensure the node has the type
// that is requested by the parent, so we avoid putting "unknown" (which
// would be also correct, but less precise and would prevent completions to
// be shown to the user)
const gd::String returnType =
gd::MetadataProvider::IsBadExpressionMetadata(metadata) == true
? type
: metadata.GetReturnType();
auto parametersNode = Parameters(metadata.parameters);
auto function =
gd::make_unique<FunctionCallNode>(functionFullName);
auto parametersNode = Parameters(function.get());
function->parameters = std::move(parametersNode.parameters);
gd::make_unique<FunctionCallNode>(returnType,
std::move(parametersNode.parameters),
metadata,
functionFullName);
function->diagnostic = std::move(parametersNode.diagnostic);
if (!function->diagnostic) // TODO: reverse the order of diagnostic?
function->diagnostic = ValidateFunction(
type, *function, identifierLocation.GetStartPosition());
function->location = ExpressionParserLocation(
identifierLocation.GetStartPosition(), GetCurrentPosition());
@@ -354,15 +433,16 @@ class GD_CORE_API ExpressionParser2 {
return std::move(function);
}
std::unique_ptr<IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode>
std::unique_ptr<FunctionCallOrObjectFunctionNameOrEmptyNode>
ObjectFunctionOrBehaviorFunction(
const gd::String &parentIdentifier,
const ExpressionParserLocation &parentIdentifierLocation,
const ExpressionParserLocation &parentIdentifierDotLocation) {
auto childIdentifierAndLocation = ReadIdentifierName();
const gd::String &childIdentifierName = childIdentifierAndLocation.name;
const auto &childIdentifierNameLocation =
childIdentifierAndLocation.location;
const gd::String &type,
const gd::String &objectName,
const ExpressionParserLocation &objectNameLocation,
const ExpressionParserLocation &objectNameDotLocation) {
auto identifierAndLocation = ReadIdentifierName();
const gd::String &objectFunctionOrBehaviorName = identifierAndLocation.name;
const auto &objectFunctionOrBehaviorNameLocation =
identifierAndLocation.location;
SkipAllWhitespaces();
@@ -370,68 +450,72 @@ class GD_CORE_API ExpressionParser2 {
ExpressionParserLocation namespaceSeparatorLocation =
SkipNamespaceSeparator();
SkipAllWhitespaces();
return BehaviorFunction(parentIdentifier,
childIdentifierName,
parentIdentifierLocation,
parentIdentifierDotLocation,
childIdentifierNameLocation,
return BehaviorFunction(type,
objectName,
objectFunctionOrBehaviorName,
objectNameLocation,
objectNameDotLocation,
objectFunctionOrBehaviorNameLocation,
namespaceSeparatorLocation);
} else if (CheckIfChar(IsOpeningParenthesis)) {
ExpressionParserLocation openingParenthesisLocation = SkipChar();
gd::String objectType =
GetTypeOfObject(globalObjectsContainer, objectsContainer, objectName);
const gd::ExpressionMetadata &metadata =
MetadataProvider::GetObjectAnyExpressionMetadata(
platform, objectType, objectFunctionOrBehaviorName);
// In case we can't find a valid expression, ensure the node has the type
// that is requested by the parent, so we avoid putting "unknown" (which
// would be also correct, but less precise and would prevent completions
// to be shown to the user)
const gd::String returnType =
gd::MetadataProvider::IsBadExpressionMetadata(metadata) == true
? type
: metadata.GetReturnType();
auto parametersNode = Parameters(metadata.parameters, objectName);
auto function = gd::make_unique<FunctionCallNode>(
parentIdentifier,
childIdentifierName);
auto parametersNode = Parameters(function.get(), parentIdentifier);
function->parameters = std::move(parametersNode.parameters),
returnType,
objectName,
std::move(parametersNode.parameters),
metadata,
objectFunctionOrBehaviorName);
function->diagnostic = std::move(parametersNode.diagnostic);
if (!function->diagnostic) // TODO: reverse the order of diagnostic?
function->diagnostic = ValidateFunction(
type, *function, objectNameLocation.GetStartPosition());
function->location = ExpressionParserLocation(
parentIdentifierLocation.GetStartPosition(), GetCurrentPosition());
function->objectNameLocation = parentIdentifierLocation;
function->objectNameDotLocation = parentIdentifierDotLocation;
function->functionNameLocation = childIdentifierNameLocation;
objectNameLocation.GetStartPosition(), GetCurrentPosition());
function->objectNameLocation = objectNameLocation;
function->objectNameDotLocation = objectNameDotLocation;
function->functionNameLocation = objectFunctionOrBehaviorNameLocation;
function->openingParenthesisLocation = openingParenthesisLocation;
function->closingParenthesisLocation =
parametersNode.closingParenthesisLocation;
return std::move(function);
} else if (CheckIfChar(IsDot) || CheckIfChar(IsOpeningSquareBracket)) {
auto variable = gd::make_unique<VariableNode>(parentIdentifier);
auto child =
gd::make_unique<VariableAccessorNode>(childIdentifierName);
child->child = VariableAccessorOrVariableBracketAccessor();
child->child->parent = child.get();
child->nameLocation = childIdentifierNameLocation;
child->dotLocation = parentIdentifierDotLocation;
child->location = ExpressionParserLocation(
parentIdentifierDotLocation.GetStartPosition(), GetCurrentPosition());
variable->child = std::move(child);
variable->child->parent = variable.get();
variable->location = ExpressionParserLocation(
parentIdentifierLocation.GetStartPosition(), GetCurrentPosition());
variable->nameLocation = parentIdentifierLocation;
return std::move(variable);
}
auto node = gd::make_unique<IdentifierNode>(
parentIdentifier, childIdentifierName);
if (!CheckIfChar(IsParameterSeparator) && !CheckIfChar(IsClosingParenthesis) && !IsEndReached()) {
node->diagnostic = RaiseSyntaxError(
_("An opening parenthesis (for an object expression), a double colon "
"(:: for a behavior expression), a dot or an opening bracket (for "
"a child variable) where expected."));
}
auto node = gd::make_unique<ObjectFunctionNameNode>(
type, objectName, objectFunctionOrBehaviorName);
node->diagnostic = RaiseSyntaxError(
_("An opening parenthesis (for an object expression), or double colon "
"(::) was expected (for a behavior expression)."));
node->location = ExpressionParserLocation(
parentIdentifierLocation.GetStartPosition(), GetCurrentPosition());
node->identifierNameLocation = parentIdentifierLocation;
node->identifierNameDotLocation = parentIdentifierDotLocation;
node->childIdentifierNameLocation = childIdentifierNameLocation;
objectNameLocation.GetStartPosition(), GetCurrentPosition());
node->objectNameLocation = objectNameLocation;
node->objectNameDotLocation = objectNameDotLocation;
node->objectFunctionOrBehaviorNameLocation =
objectFunctionOrBehaviorNameLocation;
return std::move(node);
}
std::unique_ptr<FunctionCallOrObjectFunctionNameOrEmptyNode> BehaviorFunction(
const gd::String &type,
const gd::String &objectName,
const gd::String &behaviorName,
const ExpressionParserLocation &objectNameLocation,
@@ -447,14 +531,35 @@ class GD_CORE_API ExpressionParser2 {
if (CheckIfChar(IsOpeningParenthesis)) {
ExpressionParserLocation openingParenthesisLocation = SkipChar();
gd::String behaviorType = GetTypeOfBehavior(
globalObjectsContainer, objectsContainer, behaviorName);
const gd::ExpressionMetadata &metadata =
MetadataProvider::GetBehaviorAnyExpressionMetadata(
platform, behaviorType, functionName);
// In case we can't find a valid expression, ensure the node has the type
// that is requested by the parent, so we avoid putting "unknown" (which
// would be also correct, but less precise and would prevent completions
// to be shown to the user)
const gd::String returnType =
gd::MetadataProvider::IsBadExpressionMetadata(metadata) == true
? type
: metadata.GetReturnType();
auto parametersNode =
Parameters(metadata.parameters, objectName, behaviorName);
auto function = gd::make_unique<FunctionCallNode>(
returnType,
objectName,
behaviorName,
std::move(parametersNode.parameters),
metadata,
functionName);
auto parametersNode =
Parameters(function.get(), objectName, behaviorName);
function->parameters = std::move(parametersNode.parameters);
function->diagnostic = std::move(parametersNode.diagnostic);
if (!function->diagnostic) // TODO: reverse the order of diagnostic?
function->diagnostic = ValidateFunction(
type, *function, objectNameLocation.GetStartPosition());
function->location = ExpressionParserLocation(
objectNameLocation.GetStartPosition(), GetCurrentPosition());
@@ -470,7 +575,7 @@ class GD_CORE_API ExpressionParser2 {
return std::move(function);
} else {
auto node = gd::make_unique<ObjectFunctionNameNode>(
objectName, behaviorName, functionName);
type, objectName, behaviorName, functionName);
node->diagnostic = RaiseSyntaxError(
_("An opening parenthesis was expected here to call a function."));
@@ -494,7 +599,7 @@ class GD_CORE_API ExpressionParser2 {
};
ParametersNode Parameters(
FunctionCallNode *functionCallNode,
std::vector<gd::ParameterMetadata> parameterMetadata,
const gd::String &objectName = "",
const gd::String &behaviorName = "") {
std::vector<std::unique_ptr<ExpressionNode>> parameters;
@@ -505,25 +610,77 @@ class GD_CORE_API ExpressionParser2 {
size_t parameterIndex =
WrittenParametersFirstIndex(objectName, behaviorName);
bool previousCharacterIsParameterSeparator = false;
while (!IsEndReached()) {
SkipAllWhitespaces();
if (CheckIfChar(IsClosingParenthesis) && !previousCharacterIsParameterSeparator) {
if (CheckIfChar(IsClosingParenthesis)) {
auto closingParenthesisLocation = SkipChar();
return ParametersNode{
std::move(parameters), nullptr, closingParenthesisLocation};
}
bool isEmptyParameter = CheckIfChar(IsParameterSeparator)
|| (CheckIfChar(IsClosingParenthesis) && previousCharacterIsParameterSeparator);
auto parameter = isEmptyParameter ? gd::make_unique<EmptyNode>() : Expression();
parameter->parent = functionCallNode;
parameters.push_back(std::move(parameter));
} else {
if (parameterIndex < parameterMetadata.size()) {
const gd::String &type = parameterMetadata[parameterIndex].GetType();
if (parameterMetadata[parameterIndex].IsCodeOnly()) {
// Do nothing, code only parameters are not written in expressions.
} else if (gd::ParameterMetadata::IsExpression("number", type)) {
parameters.push_back(Expression("number"));
} else if (gd::ParameterMetadata::IsExpression("string", type)) {
parameters.push_back(Expression("string"));
} else if (gd::ParameterMetadata::IsExpression("variable", type)) {
parameters.push_back(Expression(
type, lastObjectName.empty() ? objectName : lastObjectName));
} else if (gd::ParameterMetadata::IsObject(type)) {
size_t parameterStartPosition = GetCurrentPosition();
std::unique_ptr<ExpressionNode> objectExpression = Expression(type);
SkipAllWhitespaces();
previousCharacterIsParameterSeparator = CheckIfChar(IsParameterSeparator);
SkipIfChar(IsParameterSeparator);
parameterIndex++;
// Memorize the last object name. By convention, parameters that
// require an object (mainly, "objectvar" and "behavior") should be
// placed after the object in the list of parameters (if possible,
// just after). Search "lastObjectName" in the codebase for other
// place where this convention is enforced.
if (auto identifierNode =
dynamic_cast<IdentifierNode *>(objectExpression.get())) {
lastObjectName = identifierNode->identifierName;
} else {
objectExpression->diagnostic =
gd::make_unique<ExpressionParserError>(
"malformed_object_parameter",
_("An object name was expected but something else was "
"written. Enter just the name of the object for this "
"parameter."),
parameterStartPosition,
GetCurrentPosition());
}
parameters.push_back(std::move(objectExpression));
} else {
size_t parameterStartPosition = GetCurrentPosition();
parameters.push_back(Expression("unknown"));
parameters.back()->diagnostic =
gd::make_unique<ExpressionParserError>(
"unknown_parameter_type",
_("This function is improperly set up. Reach out to the "
"extension developer or a GDevelop maintainer to fix "
"this issue"),
parameterStartPosition,
GetCurrentPosition());
}
} else {
size_t parameterStartPosition = GetCurrentPosition();
parameters.push_back(Expression("unknown"));
parameters.back()
->diagnostic = gd::make_unique<ExpressionParserError>(
"extra_parameter",
_("This parameter was not expected by this expression. Remove it "
"or verify that you've entered the proper expression name."),
parameterStartPosition,
GetCurrentPosition());
}
SkipAllWhitespaces();
SkipIfChar(IsParameterSeparator);
parameterIndex++;
}
}
ExpressionParserLocation invalidClosingParenthesisLocation;
@@ -535,32 +692,92 @@ class GD_CORE_API ExpressionParser2 {
}
///@}
/** \name Validators
* Return a diagnostic if any error is found
*/
///@{
std::unique_ptr<ExpressionParserDiagnostic> ValidateFunction(
const gd::String &type,
const gd::FunctionCallNode &function,
size_t functionStartPosition);
std::unique_ptr<ExpressionParserDiagnostic> ValidateOperator(
gd::String::value_type operatorChar) {
if (operatorChar == '+' || operatorChar == '-' || operatorChar == '/' ||
operatorChar == '*') {
return gd::make_unique<ExpressionParserDiagnostic>();
const gd::String &type, gd::String::value_type operatorChar) {
if (type == "number") {
if (operatorChar == '+' || operatorChar == '-' || operatorChar == '/' ||
operatorChar == '*') {
return gd::make_unique<ExpressionParserDiagnostic>();
}
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("You've used an operator that is not supported. Operator should be "
"either +, -, / or *."),
GetCurrentPosition());
} else if (type == "string") {
if (operatorChar == '+') {
return gd::make_unique<ExpressionParserDiagnostic>();
}
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("You've used an operator that is not supported. Only + can be used "
"to concatenate texts."),
GetCurrentPosition());
} else if (gd::ParameterMetadata::IsObject(type)) {
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("Operators (+, -, /, *) can't be used with an object name. Remove "
"the operator."),
GetCurrentPosition());
} else if (gd::ParameterMetadata::IsExpression("variable", type)) {
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("Operators (+, -, /, *) can't be used in variable names. Remove "
"the operator from the variable name."),
GetCurrentPosition());
}
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("You've used an operator that is not supported. Operator should be "
"either +, -, / or *."),
GetCurrentPosition());
return gd::make_unique<ExpressionParserDiagnostic>();
}
std::unique_ptr<ExpressionParserDiagnostic> ValidateUnaryOperator(
const gd::String &type,
gd::String::value_type operatorChar,
size_t position) {
if (operatorChar == '+' || operatorChar == '-') {
return gd::make_unique<ExpressionParserDiagnostic>();
if (type == "number") {
if (operatorChar == '+' || operatorChar == '-') {
return gd::make_unique<ExpressionParserDiagnostic>();
}
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("You've used an \"unary\" operator that is not supported. Operator "
"should be "
"either + or -."),
position);
} else if (type == "string") {
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("You've used an operator that is not supported. Only + can be used "
"to concatenate texts, and must be placed between two texts (or "
"expressions)."),
position);
} else if (gd::ParameterMetadata::IsObject(type)) {
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("Operators (+, -) can't be used with an object name. Remove the "
"operator."),
position);
} else if (gd::ParameterMetadata::IsExpression("variable", type)) {
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("Operators (+, -) can't be used in variable names. Remove "
"the operator from the variable name."),
position);
}
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("You've used an \"unary\" operator that is not supported. Operator "
"should be "
"either + or -."),
position);
return gd::make_unique<ExpressionParserDiagnostic>();
}
///@}
@@ -748,7 +965,7 @@ class GD_CORE_API ExpressionParser2 {
std::unique_ptr<NumberNode> ReadNumber();
std::unique_ptr<EmptyNode> ReadUntilWhitespace() {
std::unique_ptr<EmptyNode> ReadUntilWhitespace(gd::String type) {
size_t startPosition = GetCurrentPosition();
gd::String text;
while (currentPosition < expression.size() &&
@@ -757,13 +974,13 @@ class GD_CORE_API ExpressionParser2 {
currentPosition++;
}
auto node = gd::make_unique<EmptyNode>(text);
auto node = gd::make_unique<EmptyNode>(type, text);
node->location =
ExpressionParserLocation(startPosition, GetCurrentPosition());
return node;
}
std::unique_ptr<EmptyNode> ReadUntilEnd() {
std::unique_ptr<EmptyNode> ReadUntilEnd(gd::String type) {
size_t startPosition = GetCurrentPosition();
gd::String text;
while (currentPosition < expression.size()) {
@@ -771,7 +988,7 @@ class GD_CORE_API ExpressionParser2 {
currentPosition++;
}
auto node = gd::make_unique<EmptyNode>(text);
auto node = gd::make_unique<EmptyNode>(type, text);
node->location =
ExpressionParserLocation(startPosition, GetCurrentPosition());
return node;
@@ -804,11 +1021,34 @@ class GD_CORE_API ExpressionParser2 {
return std::move(gd::make_unique<ExpressionParserError>(
"type_error", message, beginningPosition, GetCurrentPosition()));
}
std::unique_ptr<ExpressionParserError> RaiseEmptyError(
const gd::String &type, size_t beginningPosition) {
gd::String message;
if (type == "number") {
message = _("You must enter a number or a valid expression call.");
} else if (type == "string") {
message = _(
"You must enter a text (between quotes) or a valid expression call.");
} else if (gd::ParameterMetadata::IsExpression("variable", type)) {
message = _("You must enter a variable name.");
} else if (gd::ParameterMetadata::IsObject(type)) {
message = _("You must enter a valid object name.");
} else {
message = _("You must enter a valid expression.");
}
return std::move(RaiseTypeError(message, beginningPosition));
}
///@}
gd::String expression;
std::size_t currentPosition;
const gd::Platform &platform;
const gd::ObjectsContainer &globalObjectsContainer;
const gd::ObjectsContainer &objectsContainer;
static gd::String NAMESPACE_SEPARATOR;
};

View File

@@ -17,7 +17,6 @@ class ObjectsContainer;
class Platform;
class ParameterMetadata;
class ExpressionMetadata;
struct FunctionCallNode;
} // namespace gd
namespace gd {
@@ -58,10 +57,6 @@ struct GD_CORE_API ExpressionParserDiagnostic {
* \brief An error that can be attached to a gd::ExpressionNode.
*/
struct GD_CORE_API ExpressionParserError : public ExpressionParserDiagnostic {
ExpressionParserError(const gd::String &type_,
const gd::String &message_,
const ExpressionParserLocation &location_)
: type(type_), message(message_), location(location_){};
ExpressionParserError(const gd::String &type_,
const gd::String &message_,
size_t position_)
@@ -91,7 +86,7 @@ struct GD_CORE_API ExpressionParserError : public ExpressionParserDiagnostic {
* an expression inherits from.
*/
struct GD_CORE_API ExpressionNode {
ExpressionNode() : parent(nullptr) {};
ExpressionNode(const gd::String &type_) : type(type_){};
virtual ~ExpressionNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker){};
@@ -102,12 +97,17 @@ struct GD_CORE_API ExpressionNode {
/// function can store the position of the
/// object name, the dot, the function
/// name, etc...
ExpressionNode *parent;
gd::String type; // Actual type of the node.
// "string", "number", type supported by
// gd::ParameterMetadata::IsObject, types supported by
// gd::ParameterMetadata::IsExpression or "unknown".
};
struct GD_CORE_API SubExpressionNode : public ExpressionNode {
SubExpressionNode(std::unique_ptr<ExpressionNode> expression_)
: ExpressionNode(), expression(std::move(expression_)){};
SubExpressionNode(const gd::String &type_,
std::unique_ptr<ExpressionNode> expression_)
: ExpressionNode(type_), expression(std::move(expression_)){};
virtual ~SubExpressionNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitSubExpressionNode(*this);
@@ -120,8 +120,8 @@ struct GD_CORE_API SubExpressionNode : public ExpressionNode {
* \brief An operator node. For example: "lhs + rhs".
*/
struct GD_CORE_API OperatorNode : public ExpressionNode {
OperatorNode(gd::String::value_type op_)
: ExpressionNode(), op(op_){};
OperatorNode(const gd::String &type_, gd::String::value_type op_)
: ExpressionNode(type_), op(op_){};
virtual ~OperatorNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitOperatorNode(*this);
@@ -136,8 +136,8 @@ struct GD_CORE_API OperatorNode : public ExpressionNode {
* \brief A unary operator node. For example: "-2".
*/
struct GD_CORE_API UnaryOperatorNode : public ExpressionNode {
UnaryOperatorNode(gd::String::value_type op_)
: ExpressionNode(), op(op_){};
UnaryOperatorNode(const gd::String &type_, gd::String::value_type op_)
: ExpressionNode(type_), op(op_){};
virtual ~UnaryOperatorNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitUnaryOperatorNode(*this);
@@ -153,7 +153,7 @@ struct GD_CORE_API UnaryOperatorNode : public ExpressionNode {
*/
struct GD_CORE_API NumberNode : public ExpressionNode {
NumberNode(const gd::String &number_)
: ExpressionNode(), number(number_){};
: ExpressionNode("number"), number(number_){};
virtual ~NumberNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitNumberNode(*this);
@@ -168,7 +168,7 @@ struct GD_CORE_API NumberNode : public ExpressionNode {
* Its `type` is always "string".
*/
struct GD_CORE_API TextNode : public ExpressionNode {
TextNode(const gd::String &text_) : ExpressionNode(), text(text_){};
TextNode(const gd::String &text_) : ExpressionNode("string"), text(text_){};
virtual ~TextNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitTextNode(*this);
@@ -177,88 +177,32 @@ struct GD_CORE_API TextNode : public ExpressionNode {
gd::String text;
};
struct GD_CORE_API IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode
: public ExpressionNode {
IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode()
: ExpressionNode(){};
};
/**
* \brief An identifier node, usually representing an object or a variable
* with an optional function name or child variable name respectively.
*
* The name of a function to call on an object or the behavior,
* for example: "MyObject.Function" or "MyObject.Physics".
*
* A variable, potentially with accessor to its child,
* for example: MyVariable or MyVariable.MyChild
*/
struct GD_CORE_API IdentifierNode
: public IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode {
IdentifierNode(
const gd::String &identifierName_)
: IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode(),
identifierName(identifierName_),
childIdentifierName(""){};
IdentifierNode(
const gd::String &identifierName_,
const gd::String &childIdentifierName_)
: IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode(),
identifierName(identifierName_),
childIdentifierName(childIdentifierName_){};
virtual ~IdentifierNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitIdentifierNode(*this);
};
gd::String identifierName; ///< The object or variable name.
gd::String childIdentifierName; ///< The object function or variable child name.
ExpressionParserLocation
identifierNameLocation; ///< Location of the object or variable name.
ExpressionParserLocation
identifierNameDotLocation; ///< Location of the "." after the object or variable name.
ExpressionParserLocation childIdentifierNameLocation; ///< Location of object
/// function, behavior or
/// child variable name.
};
struct GD_CORE_API FunctionCallOrObjectFunctionNameOrEmptyNode
: public IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode {
FunctionCallOrObjectFunctionNameOrEmptyNode()
: IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode(){};
virtual ~FunctionCallOrObjectFunctionNameOrEmptyNode(){};
void Visit(ExpressionParser2NodeWorker &worker) override{};
};
struct GD_CORE_API VariableAccessorOrVariableBracketAccessorNode : public ExpressionNode {
VariableAccessorOrVariableBracketAccessorNode() : ExpressionNode(){};
VariableAccessorOrVariableBracketAccessorNode() : ExpressionNode(""){};
std::unique_ptr<VariableAccessorOrVariableBracketAccessorNode> child;
};
/**
* \brief A variable with bracket accessor or at least 2 "dot" accessors.
* \brief A variable, potentially with accessor to its children.
*
* Example: MyVariable or MyVariable.MyChildren
*
* Example: MyVariable[MyChildren] or MyVariable.MyChildren.MyGranChildren.
*
* Other cases like "MyVariable" or "MyVariable.MyChildren" are IdentifierNode
* to allow handling ambiguities.
*
* \see gd::IdentifierNode
* \see gd::VariableAccessorNode
* \see gd::VariableBracketAccessorNode
*/
struct GD_CORE_API VariableNode : public FunctionCallOrObjectFunctionNameOrEmptyNode {
VariableNode(const gd::String &name_)
: FunctionCallOrObjectFunctionNameOrEmptyNode(), name(name_){};
struct GD_CORE_API VariableNode : public ExpressionNode {
VariableNode(const gd::String &type_,
const gd::String &name_,
const gd::String &objectName_)
: ExpressionNode(type_), name(name_), objectName(objectName_){};
virtual ~VariableNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitVariableNode(*this);
};
gd::String name;
gd::String objectName;
std::unique_ptr<VariableAccessorOrVariableBracketAccessorNode>
child; // Can be nullptr if no accessor
@@ -272,8 +216,7 @@ struct GD_CORE_API VariableNode : public FunctionCallOrObjectFunctionNameOrEmpty
*/
struct GD_CORE_API VariableAccessorNode
: public VariableAccessorOrVariableBracketAccessorNode {
VariableAccessorNode(const gd::String &name_)
: VariableAccessorOrVariableBracketAccessorNode(), name(name_){};
VariableAccessorNode(const gd::String &name_) : name(name_){};
virtual ~VariableAccessorNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitVariableAccessorNode(*this);
@@ -291,7 +234,7 @@ struct GD_CORE_API VariableAccessorNode
struct GD_CORE_API VariableBracketAccessorNode
: public VariableAccessorOrVariableBracketAccessorNode {
VariableBracketAccessorNode(std::unique_ptr<ExpressionNode> expression_)
: VariableAccessorOrVariableBracketAccessorNode(), expression(std::move(expression_)){};
: expression(std::move(expression_)){};
virtual ~VariableBracketAccessorNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitVariableBracketAccessorNode(*this);
@@ -300,26 +243,55 @@ struct GD_CORE_API VariableBracketAccessorNode
std::unique_ptr<ExpressionNode> expression;
};
struct GD_CORE_API IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode
: public ExpressionNode {
IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode(
const gd::String &type)
: ExpressionNode(type){};
};
/**
* \brief An identifier node, usually representing an object or a function name.
*/
struct GD_CORE_API IdentifierNode
: public IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode {
IdentifierNode(const gd::String &identifierName_, const gd::String &type_)
: IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode(type_),
identifierName(identifierName_){};
virtual ~IdentifierNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitIdentifierNode(*this);
};
gd::String identifierName;
};
struct GD_CORE_API FunctionCallOrObjectFunctionNameOrEmptyNode
: public IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode {
FunctionCallOrObjectFunctionNameOrEmptyNode(const gd::String &type)
: IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode(type){};
virtual ~FunctionCallOrObjectFunctionNameOrEmptyNode(){};
void Visit(ExpressionParser2NodeWorker &worker) override{};
};
/**
* \brief The name of a function to call on an object or the behavior
* For example: "MyObject.Physics::LinearVelocity".
*
* Other cases like "MyObject.Function" or "MyObject.Physics" are IdentifierNode
* to allow handling ambiguities.
*
* \see gd::IdentifierNode
* For example: "MyObject.Function" or "MyObject.Physics" or
* "MyObject.Physics::LinearVelocity".
*/
struct GD_CORE_API ObjectFunctionNameNode
: public FunctionCallOrObjectFunctionNameOrEmptyNode {
ObjectFunctionNameNode(const gd::String &objectName_,
ObjectFunctionNameNode(const gd::String &type_,
const gd::String &objectName_,
const gd::String &objectFunctionOrBehaviorName_)
: FunctionCallOrObjectFunctionNameOrEmptyNode(),
: FunctionCallOrObjectFunctionNameOrEmptyNode(type_),
objectName(objectName_),
objectFunctionOrBehaviorName(objectFunctionOrBehaviorName_) {}
ObjectFunctionNameNode(const gd::String &objectName_,
ObjectFunctionNameNode(const gd::String &type_,
const gd::String &objectName_,
const gd::String &behaviorName_,
const gd::String &behaviorFunctionName_)
: FunctionCallOrObjectFunctionNameOrEmptyNode(),
: FunctionCallOrObjectFunctionNameOrEmptyNode(type_),
objectName(objectName_),
objectFunctionOrBehaviorName(behaviorName_),
behaviorFunctionName(behaviorFunctionName_) {}
@@ -362,24 +334,39 @@ struct GD_CORE_API ObjectFunctionNameNode
*/
struct GD_CORE_API FunctionCallNode : public FunctionCallOrObjectFunctionNameOrEmptyNode {
/** \brief Construct a free function call node. */
FunctionCallNode(const gd::String &functionName_)
: FunctionCallOrObjectFunctionNameOrEmptyNode(),
FunctionCallNode(const gd::String &type_,
std::vector<std::unique_ptr<ExpressionNode>> parameters_,
const ExpressionMetadata &expressionMetadata_,
const gd::String &functionName_)
: FunctionCallOrObjectFunctionNameOrEmptyNode(type_),
parameters(std::move(parameters_)),
expressionMetadata(expressionMetadata_),
functionName(functionName_){};
/** \brief Construct an object function call node. */
FunctionCallNode(const gd::String &objectName_,
FunctionCallNode(const gd::String &type_,
const gd::String &objectName_,
std::vector<std::unique_ptr<ExpressionNode>> parameters_,
const ExpressionMetadata &expressionMetadata_,
const gd::String &functionName_)
: FunctionCallOrObjectFunctionNameOrEmptyNode(),
: FunctionCallOrObjectFunctionNameOrEmptyNode(type_),
objectName(objectName_),
parameters(std::move(parameters_)),
expressionMetadata(expressionMetadata_),
functionName(functionName_){};
/** \brief Construct a behavior function call node. */
FunctionCallNode(const gd::String &objectName_,
FunctionCallNode(const gd::String &type_,
const gd::String &objectName_,
const gd::String &behaviorName_,
std::vector<std::unique_ptr<ExpressionNode>> parameters_,
const ExpressionMetadata &expressionMetadata_,
const gd::String &functionName_)
: FunctionCallOrObjectFunctionNameOrEmptyNode(),
: FunctionCallOrObjectFunctionNameOrEmptyNode(type_),
objectName(objectName_),
behaviorName(behaviorName_),
parameters(std::move(parameters_)),
expressionMetadata(expressionMetadata_),
functionName(functionName_){};
virtual ~FunctionCallNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
@@ -389,6 +376,7 @@ struct GD_CORE_API FunctionCallNode : public FunctionCallOrObjectFunctionNameOrE
gd::String objectName;
gd::String behaviorName;
std::vector<std::unique_ptr<ExpressionNode>> parameters;
const ExpressionMetadata &expressionMetadata;
gd::String functionName;
ExpressionParserLocation
@@ -413,8 +401,8 @@ struct GD_CORE_API FunctionCallNode : public FunctionCallOrObjectFunctionNameOrE
* encountered and any other node could not make sense.
*/
struct GD_CORE_API EmptyNode : public FunctionCallOrObjectFunctionNameOrEmptyNode {
EmptyNode(const gd::String &text_ = "")
: FunctionCallOrObjectFunctionNameOrEmptyNode(), text(text_){};
EmptyNode(const gd::String &type_, const gd::String &text_ = "")
: FunctionCallOrObjectFunctionNameOrEmptyNode(type_), text(text_){};
virtual ~EmptyNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitEmptyNode(*this);

View File

@@ -91,9 +91,6 @@ class GD_CORE_API ExpressionParser2NodePrinter
}
void OnVisitIdentifierNode(IdentifierNode& node) override {
output += node.identifierName;
if (!node.childIdentifierName.empty()) {
output += "." + node.childIdentifierName;
}
}
void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode& node) override {
if (!node.behaviorFunctionName.empty()) {

View File

@@ -4,7 +4,6 @@
* reserved. This project is released under the MIT License.
*/
#include "GDCore/Events/Serialization.h"
#include "GDCore/CommonTools.h"
#include "GDCore/Events/Event.h"
#include "GDCore/Events/EventsList.h"
@@ -184,8 +183,8 @@ void EventsListSerialization::UpdateInstructionsFromGD2x(
for (std::size_t j = 0;
j < parameters.size() && j < metadata.parameters.size();
++j) {
if (metadata.parameters[j].GetType() == "relationalOperator" ||
metadata.parameters[j].GetType() == "operator") {
if (metadata.parameters[j].type == "relationalOperator" ||
metadata.parameters[j].type == "operator") {
if (j == parameters.size() - 1) {
std::cout << "ERROR: No more parameters after a [relational]operator "
"when trying to update an instruction from GD2.x";
@@ -219,8 +218,8 @@ void EventsListSerialization::UnserializeEventsFrom(
event = std::make_shared<EmptyEvent>();
}
event->SetDisabled(eventElem.GetBoolAttribute("disabled", false));
event->SetFolded(eventElem.GetBoolAttribute("folded", false));
event->SetDisabled(eventElem.GetBoolAttribute("disabled"));
event->SetFolded(eventElem.GetBoolAttribute("folded"));
list.InsertEvent(event, list.GetEventsCount());
}
@@ -233,9 +232,8 @@ void EventsListSerialization::SerializeEventsTo(const EventsList& list,
const gd::BaseEvent& event = list.GetEvent(j);
SerializerElement& eventElem = events.AddChild("event");
if (event.IsDisabled())
eventElem.SetAttribute("disabled", event.IsDisabled());
if (event.IsFolded()) eventElem.SetAttribute("folded", event.IsFolded());
eventElem.SetAttribute("disabled", event.IsDisabled());
eventElem.SetAttribute("folded", event.IsFolded());
eventElem.AddChild("type").SetValue(event.GetType());
event.SerializeTo(eventElem);
@@ -269,9 +267,6 @@ void gd::EventsListSerialization::UnserializeInstructionsFrom(
instrElement.GetChild("type", 0, "Type")
.GetBoolAttribute("inverted", false, "Contraire"));
instruction.SetAwaited(
instrElement.GetChild("type", 0, "Type").GetBoolAttribute("await"));
// Read parameters
vector<gd::Expression> parameters;
@@ -345,12 +340,9 @@ void gd::EventsListSerialization::SerializeInstructionsTo(
instructions.ConsiderAsArrayOf("instruction");
for (std::size_t k = 0; k < list.size(); k++) {
SerializerElement& instruction = instructions.AddChild("instruction");
instruction.AddChild("type").SetAttribute("value", list[k].GetType());
if (list[k].IsInverted())
instruction.GetChild("type").SetAttribute("inverted", true);
if (list[k].IsAwaited())
instruction.GetChild("type").SetAttribute("await", true);
instruction.AddChild("type")
.SetAttribute("value", list[k].GetType())
.SetAttribute("inverted", list[k].IsInverted());
// Parameters
SerializerElement& parameters = instruction.AddChild("parameters");
@@ -360,10 +352,9 @@ void gd::EventsListSerialization::SerializeInstructionsTo(
.SetValue(list[k].GetParameter(l).GetPlainString());
// Sub instructions
if (!list[k].GetSubInstructions().empty()) {
SerializeInstructionsTo(list[k].GetSubInstructions(),
instruction.AddChild("subInstructions"));
}
SerializerElement& subInstructions =
instruction.AddChild("subInstructions");
SerializeInstructionsTo(list[k].GetSubInstructions(), subInstructions);
}
}

View File

@@ -11,16 +11,25 @@ namespace gd {
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
gd::PlatformExtension& extension) {
extension.SetExtensionInformation(
"BuiltinAdvanced",
_("Advanced control features"),
_("Advanced control features to be used in events."),
"Florian Rival",
"Open source (MIT License)");
extension
.SetExtensionInformation(
"BuiltinAdvanced",
_("Event functions"),
_("Advanced control features for functions made with events."),
"Florian Rival",
"Open source (MIT License)")
.SetCategory("Advanced");
extension.AddInstructionOrExpressionGroupMetadata(_("Event functions"))
.SetIcon("res/function32.png");
.AddCondition("Toujours",
_("Always"),
_("This condition always returns true (or always false, if "
"the condition is inverted)."),
_("Always"),
_("Other"),
"res/conditions/toujours24.png",
"res/conditions/toujours.png")
.SetHelpPath("/all-features/advanced-conditions")
.AddCodeOnlyParameter("conditionInverted", "")
.MarkAsAdvanced();
extension
.AddAction(
@@ -29,9 +38,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
_("Set the return value of the events function to the specified "
"number (to be used with \"Expression\" functions)."),
_("Set return value to number _PARAM0_"),
"",
"res/function32.png",
"res/function32.png")
_("Functions"),
"res/function24.png",
"res/function16.png")
.SetHelpPath("/events/functions/return")
.AddParameter("expression", "The number to be returned")
.MarkAsAdvanced();
@@ -43,9 +52,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
_("Set the return value of the events function to the specified text "
"(to be used with \"String Expression\" functions)."),
_("Set return value to text _PARAM0_"),
"",
"res/function32.png",
"res/function32.png")
_("Functions"),
"res/function24.png",
"res/function16.png")
.SetHelpPath("/events/functions/return")
.AddParameter("string", "The text to be returned")
.MarkAsAdvanced();
@@ -56,9 +65,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
_("Set the return value of the Condition events function to "
"either true (condition will pass) or false."),
_("Set return value of the condition to _PARAM0_"),
"",
"res/function32.png",
"res/function32.png")
_("Functions"),
"res/function24.png",
"res/function16.png")
.SetHelpPath("/events/functions/return")
.AddParameter("trueorfalse", "Should the condition be true or false?")
.MarkAsAdvanced();
@@ -71,53 +80,29 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
"a string, an empty string is considered as \"false\". "
"If it's a number, 0 is considered as \"false\"."),
_("Parameter _PARAM0_ is true"),
"",
"res/function32.png",
"res/function32.png")
.AddParameter("functionParameterName", "Parameter name")
_("Functions"),
"res/function24.png",
"res/function16.png")
.AddParameter("string", "Parameter name")
.MarkAsAdvanced();
extension
.AddExpression(
"GetArgumentAsNumber",
_("Get function parameter value"),
_("Get function parameter (also called \"argument\") value."),
"",
_("Get function parameter (also called \"argument\") value"),
_("Functions"),
"res/function16.png")
.AddParameter("functionParameterName", "Parameter name");
.AddParameter("string", "Parameter name");
extension
.AddStrExpression(
"GetArgumentAsString",
_("Get function parameter text"),
_("Get function parameter (also called \"argument\") text."),
"",
_("Get function parameter (also called \"argument\") text "),
_("Functions"),
"res/function16.png")
.AddParameter("functionParameterName", "Parameter name");
extension
.AddCondition(
"CompareArgumentAsNumber",
_("Compare function parameter value"),
_("Compare function parameter (also called \"argument\") value."),
_("Parameter _PARAM0_"),
"",
"res/function32.png",
"res/function16.png")
.AddParameter("functionParameterName", "Parameter name")
.UseStandardRelationalOperatorParameters("number");
extension
.AddCondition(
"CompareArgumentAsString",
_("Compare function parameter text"),
_("Compare function parameter (also called \"argument\") text."),
_("Parameter _PARAM0_"),
"",
"res/function32.png",
"res/function16.png")
.AddParameter("functionParameterName", "Parameter name")
.UseStandardRelationalOperatorParameters("string");
.AddParameter("string", "Parameter name");
}
} // namespace gd

View File

@@ -15,6 +15,8 @@ namespace gd {
* so that it provides standards events, objects or instructions of an
* extension.
*
* TOOD: Usage example.
*
* \ingroup BuiltinExtensions
*/
class GD_CORE_API BuiltinExtensionsImplementer {
@@ -42,7 +44,6 @@ 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

View File

@@ -1,32 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "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

View File

@@ -14,15 +14,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
extension
.SetExtensionInformation(
"BuiltinAudio",
_("Sounds and music"),
_("Audio"),
_("GDevelop provides several conditions and actions to play audio "
"files. They can be either long music or short sound effects."),
"files. They can be either long musics or short sound effects."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/audio")
.SetCategory("Audio");
extension.AddInstructionOrExpressionGroupMetadata(_("Sounds and music"))
.SetIcon("res/actions/music24.png");
.SetExtensionHelpPath("/all-features/audio");
extension
.AddAction("PlaySoundCanal",
@@ -31,7 +28,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
"you'll be able to manipulate it."),
_("Play the sound _PARAM1_ on the channel _PARAM2_, vol.: "
"_PARAM4_, loop: _PARAM3_"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/actions/son24.png",
"res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -52,7 +49,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Stop the sound of a channel"),
_("Stop the sound on the specified channel."),
_("Stop the sound of channel _PARAM1_"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/actions/son24.png",
"res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -64,7 +61,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Pause the sound of a channel"),
_("Pause the sound played on the specified channel."),
_("Pause the sound of channel _PARAM1_"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/actions/son24.png",
"res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -73,10 +70,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
extension
.AddAction("RePlaySoundCanal",
_("Resume playing a sound on a channel"),
_("Resume playing a sound on a channel that was paused."),
_("Resume the sound of channel _PARAM1_"),
_("Sounds on channels"),
_("Play the sound of a channel"),
_("Play the sound of the channel."),
_("Play the sound of channel _PARAM1_"),
_("Audio/Sounds on channels"),
"res/actions/son24.png",
"res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -90,7 +87,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
"able to interact with it later."),
_("Play the music _PARAM1_ on channel _PARAM2_, vol.: "
"_PARAM4_, loop: _PARAM3_"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/actions/music24.png",
"res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -111,7 +108,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Stop the music on a channel"),
_("Stop the music on the specified channel"),
_("Stop the music of channel _PARAM1_"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/actions/music24.png",
"res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -123,7 +120,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Pause the music of a channel"),
_("Pause the music on the specified channel."),
_("Pause the music of channel _PARAM1_"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/actions/music24.png",
"res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -132,10 +129,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
extension
.AddAction("RePlayMusicCanal",
_("Resume playing a music on a channel"),
_("Resume playing a music on a channel that was paused."),
_("Resume the music of channel _PARAM1_"),
_("Music on channels"),
_("Play the music of a channel"),
_("Play the music of the channel."),
_("Play the music of channel _PARAM1_"),
_("Audio/Music on channels"),
"res/actions/music24.png",
"res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -148,7 +145,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("This action modifies the volume of the sound on the "
"specified channel. The volume is between 0 and 100."),
_("the volume of the sound on channel _PARAM1_"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/actions/sonVolume24.png",
"res/actions/sonVolume.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -162,7 +159,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("This action modifies the volume of the music on the "
"specified channel. The volume is between 0 and 100."),
_("the volume of the music on channel _PARAM1_"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/actions/musicVolume24.png",
"res/actions/musicVolume.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -176,7 +173,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("This action modifies the global volume of the game. The "
"volume is between 0 and 100."),
_("the global sound level"),
"",
_("Audio"),
"res/actions/volume24.png",
"res/actions/volume.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -189,7 +186,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("This action modifies the pitch (speed) of the sound on a "
"channel.\n1 is the default pitch."),
_("the pitch of the sound on channel _PARAM1_"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/actions/son24.png",
"res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -203,7 +200,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("This action modifies the pitch of the music on the "
"specified channel. 1 is the default pitch"),
_("the pitch of the music on channel _PARAM1_"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/actions/music24.png",
"res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -217,7 +214,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("This action modifies the playing offset of the sound on a "
"channel"),
_("the playing offset of the sound on channel _PARAM1_"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/actions/son24.png",
"res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -231,7 +228,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("This action modifies the playing offset of the music on "
"the specified channel"),
_("the playing offset of the music on channel _PARAM1_"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/actions/music24.png",
"res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -244,7 +241,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Play a sound"),
_("Play a sound."),
_("Play the sound _PARAM1_, vol.: _PARAM3_, loop: _PARAM2_"),
"",
_("Audio"),
"res/actions/son24.png",
"res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -264,7 +261,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Play a music file"),
_("Play a music file."),
_("Play the music _PARAM1_, vol.: _PARAM3_, loop: _PARAM2_"),
"",
_("Audio"),
"res/actions/music24.png",
"res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -284,7 +281,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Preload a music file"),
_("Preload a music file in memory."),
_("Preload the music file _PARAM1_"),
_("Loading"),
_("Audio/Loading"),
"res/actions/music24.png",
"res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -296,7 +293,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Preload a sound file"),
_("Preload a sound file in memory."),
_("Preload the sound file _PARAM1_"),
_("Loading"),
_("Audio/Loading"),
"res/actions/son24.png",
"res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -304,80 +301,55 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
.MarkAsComplex();
extension
.AddAction(
"UnloadMusic",
_("Unload a music file"),
_("Unload a music file from memory. "
"Unloading a music file will cause any music playing it to stop."),
_("Unload the music file _PARAM1_"),
_("Loading"),
"res/actions/music24.png",
"res/actions/music.png")
.AddAction("UnloadMusic",
_("Unload a music file"),
_(
"Unload a music file from memory. "
"Unloading a music file will cause any music playing it to stop."
),
_("Unload the music file _PARAM1_"),
_("Audio/Loading"),
"res/actions/music24.png",
"res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("musicfile", _("Audio file (or audio resource name)"))
.MarkAsComplex();
extension
.AddAction(
"UnloadSound",
_("Unload a sound file"),
_("Unload a sound file from memory. "
"Unloading a sound file will cause any sounds playing it to stop."),
_("Unload the sound file _PARAM1_"),
_("Loading"),
"res/actions/son24.png",
"res/actions/son.png")
.AddAction("UnloadSound",
_("Unload a sound file"),
_(
"Unload a sound file from memory. "
"Unloading a sound file will cause any sounds playing it to stop."
),
_("Unload the sound file _PARAM1_"),
_("Audio/Loading"),
"res/actions/son24.png",
"res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("soundfile", _("Sound file (or sound resource name)"))
.MarkAsComplex();
extension
.AddAction(
"UnloadAllAudio",
_("Unload all audio"),
_("Unload all the audio in memory. "
"This will cause every sound and music of the game to stop."),
_("Unload all audio files"),
_("Loading"),
"res/actions/music24.png",
"res/actions/music.png")
.AddAction("UnloadAllAudio",
_("Unload all audio"),
_(
"Unload all the audio in memory. "
"This will cause every sound and music of the game to stop."
),
_("Unload all audio files"),
_("Audio/Loading"),
"res/actions/music24.png",
"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",
_("A music file is being played"),
_("Test if the music on a channel is being played"),
_("Music on channel _PARAM1_ is being played"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/conditions/musicplaying24.png",
"res/conditions/musicplaying.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -389,7 +361,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("A music file is paused"),
_("Test if the music on the specified channel is paused."),
_("Music on channel _PARAM1_ is paused"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/conditions/musicpaused24.png",
"res/conditions/musicpaused.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -401,7 +373,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("A music file is stopped"),
_("Test if the music on the specified channel is stopped."),
_("Music on channel _PARAM1_ is stopped"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/conditions/musicstopped24.png",
"res/conditions/musicstopped.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -413,7 +385,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("A sound is being played"),
_("Test if the sound on a channel is being played."),
_("Sound on channel _PARAM1_ is being played"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/conditions/sonplaying24.png",
"res/conditions/sonplaying.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -425,7 +397,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("A sound is paused"),
_("Test if the sound on the specified channel is paused."),
_("Sound on channel _PARAM1_ is paused"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/conditions/sonpaused24.png",
"res/conditions/sonpaused.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -437,7 +409,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("A sound is stopped"),
_("Test if the sound on the specified channel is stopped."),
_("Sound on channel _PARAM1_ is stopped"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/conditions/sonstopped24.png",
"res/conditions/sonstopped.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -451,7 +423,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Test the volume of the sound on the specified channel. The volume "
"is between 0 and 100."),
_("the volume of the sound on channel _PARAM1_"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/conditions/sonVolume24.png",
"res/conditions/sonVolume.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -466,7 +438,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Test the volume of the music on a specified channel. The volume "
"is between 0 and 100."),
_("the volume of the music on channel _PARAM1_"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/conditions/musicVolume24.png",
"res/conditions/musicVolume.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -480,7 +452,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Global volume"),
_("Test the global sound level. The volume is between 0 and 100."),
_("the global game volume"),
"",
_("Audio"),
"res/conditions/volume24.png",
"res/conditions/volume.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -493,7 +465,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Test the pitch of the sound on the specified channel. 1 is the "
"default pitch."),
_("the pitch of the sound on channel _PARAM1_"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/conditions/sonVolume24.png",
"res/conditions/sonVolume.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -508,7 +480,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Test the pitch (speed) of the music on a specified channel. 1 is "
"the default pitch."),
_("the pitch of the music on channel _PARAM1_"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/conditions/musicVolume24.png",
"res/conditions/musicVolume.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -522,7 +494,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Playing offset of the sound on a channel"),
_("Test the playing offset of the sound on the specified channel."),
_("the playing offset of the sound on channel _PARAM1_"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/conditions/sonVolume24.png",
"res/conditions/sonVolume.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -536,7 +508,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Playing offset of the music on a channel"),
_("Test the playing offset of the music on the specified channel."),
_("the playing offset of the music on channel _PARAM1_"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/conditions/musicVolume24.png",
"res/conditions/musicVolume.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -605,6 +577,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Sound level"),
"res/conditions/volume.png")
.AddCodeOnlyParameter("currentScene", "");
}
} // namespace gd

View File

@@ -4,9 +4,9 @@
* reserved. This project is released under the MIT License.
*/
#include "AllBuiltinExtensions.h"
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Tools/Localization.h"
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
using namespace std;
namespace gd {
@@ -16,19 +16,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
extension
.SetExtensionInformation(
"BuiltinObject",
_("Objects"),
_("Features for all objects"),
_("Common features that can be used for all objects in GDevelop."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects/base_object/events");
extension.AddInstructionOrExpressionGroupMetadata(_("Collision"))
.SetIcon("res/conditions/collision24.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Objects"))
.SetIcon("res/actions/create24.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Movement using forces"))
.SetIcon("res/actions/force24.png");
gd::ObjectMetadata& obj = extension.AddObject<gd::ObjectConfiguration>(
gd::ObjectMetadata& obj = extension.AddObject<gd::Object>(
"", _("Base object"), _("Base object"), "res/objeticon24.png");
obj.AddCondition("PosX",
@@ -36,8 +30,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Compare the X position of the object."),
_("the X position"),
_("Position"),
"res/conditions/position24_black.png",
"res/conditions/position_black.png")
"res/conditions/position24.png",
"res/conditions/position.png")
.AddParameter("object", _("Object"))
.UseStandardRelationalOperatorParameters("number")
@@ -48,8 +42,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Change the X position of an object."),
_("the X position"),
_("Position"),
"res/actions/position24_black.png",
"res/actions/position_black.png")
"res/actions/position24.png",
"res/actions/position.png")
.AddParameter("object", _("Object"))
.UseStandardOperatorParameters("number")
@@ -60,8 +54,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Compare the Y position of an object."),
_("the Y position"),
_("Position"),
"res/conditions/position24_black.png",
"res/conditions/position_black.png")
"res/conditions/position24.png",
"res/conditions/position.png")
.AddParameter("object", _("Object"))
.UseStandardRelationalOperatorParameters("number")
@@ -72,8 +66,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Change the Y position of an object."),
_("the Y position"),
_("Position"),
"res/actions/position24_black.png",
"res/actions/position_black.png")
"res/actions/position24.png",
"res/actions/position.png")
.AddParameter("object", _("Object"))
.UseStandardOperatorParameters("number")
@@ -85,8 +79,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Change the position of _PARAM0_: _PARAM1_ _PARAM2_ (x "
"axis), _PARAM3_ _PARAM4_ (y axis)"),
_("Position"),
"res/actions/position24_black.png",
"res/actions/position_black.png")
"res/actions/position24.png",
"res/actions/position.png")
.AddParameter("object", _("Object"))
.AddParameter("operator", _("Modification's sign"), "number")
@@ -98,12 +92,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
obj.AddAction("SetCenter",
_("Center position"),
_("Change the position of an object, using its center."),
_("Change the position of the center of _PARAM0_: _PARAM1_ "
"_PARAM2_ (x "
_("Change the position of the center of _PARAM0_: _PARAM1_ _PARAM2_ (x "
"axis), _PARAM3_ _PARAM4_ (y axis)"),
_("Position/Center"),
"res/actions/position24_black.png",
"res/actions/position_black.png")
"res/actions/position24.png",
"res/actions/position.png")
.AddParameter("object", _("Object"))
.AddParameter("operator", _("Modification's sign"), "number")
.AddParameter("expression", _("X position"))
@@ -111,91 +104,75 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("expression", _("Y position"))
.MarkAsSimple();
obj.AddExpressionAndConditionAndAction(
"number",
"CenterX",
_("Center X position"),
_("the X position of the center of rotation"),
_("the X position of the center"),
_("Position/Center"),
"res/actions/position24_black.png")
obj.AddExpressionAndConditionAndAction("number", "CenterX",
_("Center X position"),
_("the X position of the center of rotation"),
_("the X position of the center"),
_("Position/Center"),
"res/actions/position24.png")
.AddParameter("object", _("Object"))
.UseStandardParameters("number");
obj.AddExpressionAndConditionAndAction(
"number",
"CenterY",
_("Center Y position"),
_("the Y position of the center of rotation"),
_("the Y position of the center"),
_("Position/Center"),
"res/actions/position24_black.png")
obj.AddExpressionAndConditionAndAction("number", "CenterY",
_("Center Y position"),
_("the Y position of the center of rotation"),
_("the Y position of the center"),
_("Position/Center"),
"res/actions/position24.png")
.AddParameter("object", _("Object"))
.UseStandardParameters("number");
obj.AddExpressionAndCondition("number",
"BoundingBoxLeft",
_("Bounding box left position"),
_("the bounding box (the area encapsulating "
"the object) left position"),
_("the bounding box left position"),
_("Position/Bounding Box"),
"res/conditions/bounding-box-left_black.svg")
obj.AddExpressionAndCondition("number", "BoundingBoxLeft",
_("Bounding box left position"),
_("the bounding box (the area encapsulating the object) left position"),
_("the bounding box left position"),
_("Position/Bounding Box"),
"res/conditions/bounding-box-left.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number");
obj.AddExpressionAndCondition(
"number",
"BoundingBoxTop",
_("Bounding box top position"),
_("the bounding box (the area encapsulating the object) top position"),
_("the bounding box top position"),
_("Position/Bounding Box"),
"res/conditions/bounding-box-top_black.svg")
obj.AddExpressionAndCondition("number", "BoundingBoxTop",
_("Bounding box top position"),
_("the bounding box (the area encapsulating the object) top position"),
_("the bounding box top position"),
_("Position/Bounding Box"),
"res/conditions/bounding-box-top.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number");
obj.AddExpressionAndCondition("number",
"BoundingBoxRight",
_("Bounding box right position"),
_("the bounding box (the area encapsulating "
"the object) right position"),
_("the bounding box right position"),
_("Position/Bounding Box"),
"res/conditions/bounding-box-right_black.svg")
obj.AddExpressionAndCondition("number", "BoundingBoxRight",
_("Bounding box right position"),
_("the bounding box (the area encapsulating the object) right position"),
_("the bounding box right position"),
_("Position/Bounding Box"),
"res/conditions/bounding-box-right.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number");
obj.AddExpressionAndCondition("number",
"BoundingBoxBottom",
_("Bounding box bottom position"),
_("the bounding box (the area encapsulating "
"the object) bottom position"),
_("the bounding box bottom position"),
_("Position/Bounding Box"),
"res/conditions/bounding-box-bottom_black.svg")
obj.AddExpressionAndCondition("number", "BoundingBoxBottom",
_("Bounding box bottom position"),
_("the bounding box (the area encapsulating the object) bottom position"),
_("the bounding box bottom position"),
_("Position/Bounding Box"),
"res/conditions/bounding-box-bottom.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number");
obj.AddExpressionAndCondition("number",
"BoundingBoxCenterX",
_("Bounding box center X position"),
_("the bounding box (the area encapsulating "
"the object) center X position"),
_("the bounding box center X position"),
_("Position/Bounding Box"),
"res/conditions/bounding-box-center_black.svg")
obj.AddExpressionAndCondition("number", "BoundingBoxCenterX",
_("Bounding box center X position"),
_("the bounding box (the area encapsulating the object) center X position"),
_("the bounding box center X position"),
_("Position/Bounding Box"),
"res/conditions/bounding-box-center.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number");
obj.AddExpressionAndCondition("number",
"BoundingBoxCenterY",
_("Bounding box center Y position"),
_("the bounding box (the area encapsulating "
"the object) center Y position"),
_("the bounding box center Y position"),
_("Position/Bounding Box"),
"res/conditions/bounding-box-center_black.svg")
obj.AddExpressionAndCondition("number", "BoundingBoxCenterY",
_("Bounding box center Y position"),
_("the bounding box (the area encapsulating the object) center Y position"),
_("the bounding box center Y position"),
_("Position/Bounding Box"),
"res/conditions/bounding-box-center.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number");
@@ -219,11 +196,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
obj.AddAction("SetAngle",
_("Angle"),
_("Change the angle of rotation of an object (in degrees)."),
_("Change the angle of rotation of an object."),
_("the angle"),
_("Angle"),
"res/actions/direction24_black.png",
"res/actions/direction_black.png")
"res/actions/direction24.png",
"res/actions/direction.png")
.AddParameter("object", _("Object"))
.UseStandardOperatorParameters("number");
@@ -234,8 +211,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"counterclockwise otherwise."),
_("Rotate _PARAM0_ at speed _PARAM1_ deg/second"),
_("Angle"),
"res/actions/rotate24_black.png",
"res/actions/rotate_black.png")
"res/actions/direction24.png",
"res/actions/direction.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angular speed (in degrees per second)"))
@@ -248,8 +225,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Rotate an object towards an angle with the specified speed."),
_("Rotate _PARAM0_ towards _PARAM1_ at speed _PARAM2_ deg/second"),
_("Angle"),
"res/actions/rotate24_black.png",
"res/actions/rotate_black.png")
"res/actions/direction24.png",
"res/actions/direction.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle to rotate towards (in degrees)"))
@@ -264,8 +241,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Rotate _PARAM0_ towards _PARAM1_;_PARAM2_ at speed "
"_PARAM3_ deg/second"),
_("Angle"),
"res/actions/rotate24_black.png",
"res/actions/rotate_black.png")
"res/actions/direction24.png",
"res/actions/direction.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("X position"))
@@ -289,8 +266,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Speed on X axis (in pixels per second)"))
.AddParameter("expression", _("Speed on Y axis (in pixels per second)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0");
.AddParameter("forceMultiplier", _("Force multiplier"));
obj.AddAction("AddForceAL",
_("Add a force (angle)"),
@@ -306,16 +282,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle"))
.AddParameter("expression", _("Speed (in pixels per second)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0")
.AddParameter("forceMultiplier", _("Force multiplier"))
.MarkAsAdvanced();
obj.AddAction(
"AddForceVersPos",
_("Add a force to move toward a position"),
_("Add a force to an object to make it move toward a position."),
_("Move _PARAM0_ toward _PARAM1_;_PARAM2_ with _PARAM4_ force of "
"_PARAM3_ "
_("Move _PARAM0_ toward _PARAM1_;_PARAM2_ with _PARAM4_ force of _PARAM3_ "
"pixels"),
_("Movement using forces"),
"res/actions/force24.png",
@@ -325,19 +299,18 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("expression", _("X position"))
.AddParameter("expression", _("Y position"))
.AddParameter("expression", _("Speed (in pixels per second)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0")
.AddParameter("forceMultiplier", _("Force multiplier"))
.MarkAsAdvanced();
obj.AddAction(
"AddForceTournePos",
"Add a force to move around a position",
"Add a force to an object to make it rotate around a "
"position.\nNote that the movement is not precise, especially if "
"the speed is high.\nTo position an object around a position more "
"precisely, use the actions in the category \"Position\".",
"position.\nNote that the movement is not precise, especially if "
"the speed is high.\nTo position an object around a position more "
"precisely, use the actions in the category \"Position\".",
"Rotate _PARAM0_ around _PARAM1_;_PARAM2_ at _PARAM3_ deg/sec and "
"_PARAM4_ pixels away",
"_PARAM4_ pixels away",
_("Movement using forces"),
"res/actions/forceTourne24.png",
"res/actions/forceTourne.png")
@@ -393,7 +366,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/layer.png")
.AddParameter("object", _("Object"))
.AddParameter("layer", _("Move it to this layer"))
.AddParameter("layer", _("Move it to this layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.MarkAsAdvanced();
@@ -512,8 +485,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Compare the angle of the specified object."),
_("the angle (in degrees)"),
_("Angle"),
"res/conditions/direction24_black.png",
"res/conditions/direction_black.png")
"res/conditions/direction24.png",
"res/conditions/direction.png")
.AddParameter("object", _("Object"))
.UseStandardRelationalOperatorParameters("number")
@@ -590,8 +563,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
obj.AddCondition("AngleOfDisplacement",
_("Angle of movement (using forces)"),
_("Compare the angle of movement of an object according to "
"the forces applied on it."),
_("Compare the angle of movement of an object according to the forces applied on it."),
_("Angle of movement of _PARAM0_ is _PARAM1_ (tolerance"
": _PARAM2_ degrees)"),
_("Movement using forces"),
@@ -747,20 +719,19 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("yesorno", _("Activate?"))
.MarkAsAdvanced();
obj.AddAction("AddForceVers",
_("Add a force to move toward an object"),
_("Add a force to an object to make it move toward another."),
_("Move _PARAM0_ toward _PARAM1_ with _PARAM3_ force of "
"_PARAM2_ pixels"),
_("Movement using forces"),
"res/actions/forceVers24.png",
"res/actions/forceVers.png")
obj.AddAction(
"AddForceVers",
_("Add a force to move toward an object"),
_("Add a force to an object to make it move toward another."),
_("Move _PARAM0_ toward _PARAM1_ with _PARAM3_ force of _PARAM2_ pixels"),
_("Movement using forces"),
"res/actions/forceVers24.png",
"res/actions/forceVers.png")
.AddParameter("object", _("Object"))
.AddParameter("objectPtr", _("Target Object"))
.AddParameter("expression", _("Speed (in pixels per second)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0")
.AddParameter("forceMultiplier", _("Force multiplier"))
.MarkAsAdvanced();
obj.AddAction(
@@ -780,8 +751,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectPtr", _("Rotate around this object"))
.AddParameter("expression", _("Speed (in degrees per second)"))
.AddParameter("expression", _("Distance (in pixels)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0")
.AddParameter("forceMultiplier", _("Force multiplier"))
.MarkAsAdvanced();
obj.AddAction("MettreAutour",
@@ -876,7 +846,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddCodeOnlyParameter("conditionInverted", "")
.MarkAsSimple();
// Deprecated and replaced by CompareObjectTimer
obj.AddCondition(
"ObjectTimer",
_("Value of an object timer"),
@@ -886,24 +855,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/conditions/timer24.png",
"res/conditions/timer.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.AddParameter("expression", _("Time in seconds"))
.SetHidden();
obj.AddCondition(
"CompareObjectTimer",
_("Value of an object timer"),
_("Compare the elapsed time of an object timer. This condition "
"doesn't start the timer."),
_("The timer _PARAM1_ of _PARAM0_ _PARAM2_ _PARAM3_ seconds"),
_("Timers"),
"res/conditions/timer24.png",
"res/conditions/timer.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.AddParameter("relationalOperator", _("Sign of the test"), "time")
.AddParameter("expression", _("Time in seconds"))
.SetManipulatedType("number");
.AddParameter("string", _("Timer's name"))
.AddParameter("expression", _("Time in seconds"));
obj.AddCondition("ObjectTimerPaused",
_("Object timer paused"),
@@ -913,20 +866,19 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/conditions/timerPaused24.png",
"res/conditions/timerPaused.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.AddParameter("string", _("Timer's name"))
.MarkAsAdvanced();
obj.AddAction(
"ResetObjectTimer",
_("Start (or reset) an object timer"),
_("Reset the specified object timer, if the timer doesn't exist "
"it's created and started."),
_("Start (or reset) the timer _PARAM1_ of _PARAM0_"),
_("Timers"),
"res/actions/timer24.png",
"res/actions/timer.png")
obj.AddAction("ResetObjectTimer",
_("Start (or reset) an object timer"),
_("Reset the specified object timer, if the timer doesn't exist "
"it's created and started."),
_("Reset the timer _PARAM1_ of _PARAM0_"),
_("Timers"),
"res/actions/timer24.png",
"res/actions/timer.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer");
.AddParameter("string", _("Timer's name"));
obj.AddAction("PauseObjectTimer",
_("Pause an object timer"),
@@ -936,7 +888,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/pauseTimer24.png",
"res/actions/pauseTimer.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.AddParameter("string", _("Timer's name"))
.MarkAsAdvanced();
obj.AddAction("UnPauseObjectTimer",
@@ -947,7 +899,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/unPauseTimer24.png",
"res/actions/unPauseTimer.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.AddParameter("string", _("Timer's name"))
.MarkAsAdvanced();
obj.AddAction("RemoveObjectTimer",
@@ -958,28 +910,28 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/timer24.png",
"res/actions/timer.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.AddParameter("string", _("Timer's name"))
.MarkAsAdvanced();
obj.AddExpression("X",
_("X position"),
_("X position of the object"),
_("Position"),
"res/actions/position_black.png")
"res/actions/position.png")
.AddParameter("object", _("Object"));
obj.AddExpression("Y",
_("Y position"),
_("Y position of the object"),
_("Position"),
"res/actions/position_black.png")
"res/actions/position.png")
.AddParameter("object", _("Object"));
obj.AddExpression("Angle",
_("Angle"),
_("Current angle, in degrees, of the object"),
_("Angle"),
"res/actions/direction_black.png")
"res/actions/direction.png")
.AddParameter("object", _("Object"));
obj.AddExpression("ForceX",
@@ -998,7 +950,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
obj.AddExpression("ForceAngle",
_("Angle of the sum of forces"),
_("Angle of the sum of forces (in degrees)"),
_("Angle of the sum of forces"),
_("Movement using forces"),
"res/actions/force.png")
.AddParameter("object", _("Object"));
@@ -1022,14 +974,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Width"),
_("Width of the object"),
_("Size"),
"res/actions/scaleWidth_black.png")
"res/actions/scaleWidth.png")
.AddParameter("object", _("Object"));
obj.AddExpression("Largeur",
_("Width"),
_("Width of the object"),
_("Size"),
"res/actions/scaleWidth_black.png")
"res/actions/scaleWidth.png")
.AddParameter("object", _("Object"))
.SetHidden();
@@ -1037,14 +989,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Height"),
_("Height of the object"),
_("Size"),
"res/actions/scaleHeight_black.png")
"res/actions/scaleHeight.png")
.AddParameter("object", _("Object"));
obj.AddExpression("Hauteur",
_("Height"),
_("Height of the object"),
_("Size"),
"res/actions/scaleHeight_black.png")
"res/actions/scaleHeight.png")
.AddParameter("object", _("Object"))
.SetHidden();
@@ -1098,7 +1050,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("expression", _("Target Y position"));
obj.AddExpression("Variable",
_("Value of an object variable"),
_("Object variable"),
_("Value of an object variable"),
_("Variables"),
"res/actions/var.png")
@@ -1114,7 +1066,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectvar", _("Variable"));
obj.AddStrExpression("VariableString",
_("Text of an object variable"),
_("Object variable"),
_("Text of an object variable"),
_("Variables"),
"res/actions/var.png")
@@ -1127,38 +1079,37 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Object timers"),
"res/actions/time.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer");
.AddParameter("string", _("Timer's name"));
obj.AddExpression("AngleToObject",
_("Angle between two objects"),
_("Compute the angle between two objects (in degrees). "
"If you need the angle to an arbitrary position, "
"use AngleToPosition."),
_("Compute the angle between two objects. If you need the "
"angle to an arbitrary position, use AngleToPosition."),
_("Angle"),
"res/actions/position_black.png")
"res/actions/position.png")
.AddParameter("object", _("Object"))
.AddParameter("objectPtr", _("Object"));
obj.AddExpression("XFromAngleAndDistance",
obj.AddExpression("XFromAngleAndDistance",
_("X position from angle and distance"),
_("Compute the X position when given an angle and distance "
"relative to the starting object. This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
_("Position"),
"res/actions/position_black.png")
"res/actions/position.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Distance"));
obj.AddExpression("YFromAngleAndDistance",
obj.AddExpression("YFromAngleAndDistance",
_("Y position from angle and distance"),
_("Compute the Y position when given an angle and distance "
"relative to the starting object. This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
_("Position"),
"res/actions/position_black.png")
"res/actions/position.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Distance"));
@@ -1166,10 +1117,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
obj.AddExpression("AngleToPosition",
_("Angle between an object and a position"),
_("Compute the angle between the object center and a "
"\"target\" position (in degrees). If you need the angle "
"between two objects, use AngleToObject."),
"\"target\" position. If you need the angle between two "
"objects, use AngleToObject."),
_("Angle"),
"res/actions/position_black.png")
"res/actions/position.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Target X position"))
.AddParameter("expression", _("Target Y position"));
@@ -1184,14 +1135,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("objectEffectName", _("Effect name"))
.AddParameter("yesorno", _("Enable?"))
.MarkAsSimple()
.SetRequiresBaseObjectCapability("effect");
.MarkAsSimple();
obj.AddAction("SetEffectDoubleParameter",
_("Effect parameter (number)"),
_("Change the value of a parameter of an effect.") + "\n" +
_("You can find the parameter names (and change the effect "
"names) in the effects window."),
_("You can find the parameter names (and change the effect "
"names) in the effects window."),
_("Set _PARAM2_ to _PARAM3_ for effect _PARAM1_ of _PARAM0_"),
_("Effects"),
"res/actions/effect24.png",
@@ -1200,15 +1150,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectEffectName", _("Effect name"))
.AddParameter("objectEffectParameterName", _("Parameter name"))
.AddParameter("expression", _("New value"))
.MarkAsSimple()
.SetRequiresBaseObjectCapability("effect");
.MarkAsSimple();
obj.AddAction("SetEffectStringParameter",
_("Effect parameter (string)"),
_("Change the value (string) of a parameter of an effect.") +
"\n" +
_("You can find the parameter names (and change the effect "
"names) in the effects window."),
_("Change the value (string) of a parameter of an effect.") + "\n" +
_("You can find the parameter names (and change the effect "
"names) in the effects window."),
_("Set _PARAM2_ to _PARAM3_ for effect _PARAM1_ of _PARAM0_"),
_("Effects"),
"res/actions/effect24.png",
@@ -1217,14 +1165,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectEffectName", _("Effect name"))
.AddParameter("objectEffectParameterName", _("Parameter name"))
.AddParameter("string", _("New value"))
.MarkAsSimple()
.SetRequiresBaseObjectCapability("effect");
.MarkAsSimple();
obj.AddAction("SetEffectBooleanParameter",
_("Effect parameter (enable or disable)"),
_("Enable or disable a parameter of an effect.") + "\n" +
_("You can find the parameter names (and change the effect "
"names) in the effects window."),
_("You can find the parameter names (and change the effect "
"names) in the effects window."),
_("Enable _PARAM2_ for effect _PARAM1_ of _PARAM0_: _PARAM3_"),
_("Effects"),
"res/actions/effect24.png",
@@ -1233,32 +1180,29 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectEffectName", _("Effect name"))
.AddParameter("objectEffectParameterName", _("Parameter name"))
.AddParameter("yesorno", _("Enable?"))
.MarkAsSimple()
.SetRequiresBaseObjectCapability("effect");
.MarkAsSimple();
obj.AddCondition("IsEffectEnabled",
_("Effect is enabled"),
_("Check if the effect on an object is enabled."),
_("Effect _PARAM1_ of _PARAM0_ is enabled"),
_("Effects"),
"res/actions/effect24.png",
"res/actions/effect.png")
_("Effect is enabled"),
_("Check if the effect on an object is enabled."),
_("Effect _PARAM1_ of _PARAM0_ is enabled"),
_("Effects"),
"res/actions/effect24.png",
"res/actions/effect.png")
.AddParameter("object", _("Object"))
.AddParameter("objectEffectName", _("Effect name"))
.MarkAsSimple()
.SetRequiresBaseObjectCapability("effect");
.MarkAsSimple();
extension
.AddAction("Create",
_("Create an object"),
_("Create an object at specified position"),
_("Create object _PARAM1_ at position _PARAM2_;_PARAM3_ "
"(layer: _PARAM4_)"),
"",
_("Create object _PARAM1_ at position _PARAM2_;_PARAM3_ (layer: _PARAM4_)"),
_("Objects"),
"res/actions/create24.png",
"res/actions/create24.png")
"res/actions/create.png")
.AddCodeOnlyParameter("objectsContext", "")
.AddParameter("objectListOrEmptyIfJustDeclared", _("Object to create"))
.AddParameter("objectListWithoutPicking", _("Object to create"))
.AddParameter("expression", _("X position"))
.AddParameter("expression", _("Y position"))
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
@@ -1272,11 +1216,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"create the object with the specified name."),
_("Among objects _PARAM1_, create object named _PARAM2_ at "
"position _PARAM3_;_PARAM4_ (layer: _PARAM5_)"),
"",
_("Objects"),
"res/actions/create24.png",
"res/actions/create24.png")
"res/actions/create.png")
.AddCodeOnlyParameter("objectsContext", "")
.AddParameter("objectListOrEmptyIfJustDeclared", _("Group of potential objects"))
.AddParameter("objectListWithoutPicking", _("Group of potential objects"))
.SetParameterLongDescription(
_("Group containing objects that can be created by the action."))
.AddParameter("string", _("Name of the object to create"))
@@ -1424,40 +1368,17 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/conditions/nbObjet.png")
.AddParameter("objectList", _("Object"))
.UseStandardRelationalOperatorParameters("number")
.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();
.MarkAsSimple();
extension
.AddCondition(
"CollisionNP",
"CollisionNP", //"CollisionNP" cames from an old condition to test
// collision between two sprites non precisely.
_("Collision"),
_("Test the collision between two objects using their collision "
"masks."),
"masks.\nNote that some objects may not have collision "
"masks.\nSome others, like Sprite objects, also provide more "
"precise collision conditions."),
_("_PARAM0_ is in collision with _PARAM1_"),
_("Collision"),
"res/conditions/collision24.png",
@@ -1501,7 +1422,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Cast a ray from _PARAM1_;_PARAM2_, angle: _PARAM3_ and max "
"distance: _PARAM4_px, against _PARAM0_, and save the "
"result in _PARAM5_, _PARAM6_"),
"",
_("Collision"),
"res/conditions/raycast24.png",
"res/conditions/raycast.png")
.AddParameter("objectList", _("Objects to test against the ray"))
@@ -1529,10 +1450,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"object will become the only one taken into account.\nIf "
"the condition is inverted, the object to be intersected "
"will be the farthest one within the ray radius."),
_("Cast a ray from _PARAM1_;_PARAM2_ to _PARAM3_;_PARAM4_ "
_("Cast a ray from from _PARAM1_;_PARAM2_ to _PARAM3_;_PARAM4_ "
"against _PARAM0_, and save the "
"result in _PARAM5_, _PARAM6_"),
"",
_("Collision"),
"res/conditions/raycast24.png",
"res/conditions/raycast.png")
.AddParameter("objectList", _("Objects to test against the ray"))
@@ -1556,22 +1477,21 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Number of objects"),
_("Count the number of the specified objects being "
"currently picked in the event"),
"",
_("Objects"),
"res/conditions/nbObjet.png")
.AddParameter("objectList", _("Object"))
.SetHidden(); // Deprecated
.AddParameter("objectList", _("Object"));
obj.AddStrExpression("ObjectName",
_("Object name"),
_("Return the name of the object"),
"",
"res/conditions/text_black.png")
_("Objects"),
"res/conditions/text.png")
.AddParameter("object", _("Object"));
obj.AddStrExpression("Layer",
_("Object layer"),
_("Return the name of the layer the object is on"),
"",
_("Objects"),
"res/actions/layer.png")
.AddParameter("object", _("Object"));
}

View File

@@ -15,26 +15,23 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
extension
.SetExtensionInformation(
"BuiltinCamera",
_("Layers and cameras"),
_("Cameras and layers features"),
"Each scene can be composed of multiple layers. These conditions "
"and actions allow to manipulate them during the game. In "
"particular, you can move the camera of a layer to center it on an "
"object or a position.",
"Florian Rival",
"Open source (MIT License)")
.SetCategory("Camera")
.SetExtensionHelpPath("/interface/scene-editor/layers-and-cameras");
extension.AddInstructionOrExpressionGroupMetadata(_("Layers and cameras"))
.SetIcon("res/conditions/camera24.png");
extension
.AddExpressionAndConditionAndAction(
"number",
"CameraCenterX",
"CameraX",
_("Camera center X position"),
_("the X position of the center of a camera"),
_("the X position of camera _PARAM4_ (layer: _PARAM3_)"),
"",
_("Layers and cameras"),
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardParameters("number")
@@ -44,29 +41,19 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
.SetDefaultValue("0")
.MarkAsAdvanced();
// Compatibility with GD <= 5.0.135
extension.AddDuplicatedCondition("CameraX", "CameraCenterX")
.SetHidden(); // Deprecated
extension.AddDuplicatedExpression("CameraX", "CameraCenterX")
.SetHidden(); // Deprecated
extension.AddDuplicatedAction("SetCameraX", "SetCameraCenterX")
.SetHidden(); // Deprecated
extension.AddDuplicatedAction("CameraX", "SetCameraX")
.SetHidden(); // Deprecated
extension.AddDuplicatedExpression("VueX", "CameraX")
.SetHidden(); // Deprecated
// end of compatibility code
extension
.AddExpressionAndConditionAndAction(
"number",
"CameraCenterY",
"CameraY",
_("Camera center Y position"),
_("the Y position of the center of a camera"),
_("the Y position of camera _PARAM4_ (layer: _PARAM3_)"),
"",
_("Layers and cameras"),
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardParameters("number")
@@ -76,20 +63,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
.SetDefaultValue("0")
.MarkAsAdvanced();
// Compatibility with GD <= 5.0.135
extension.AddDuplicatedCondition("CameraY", "CameraCenterY")
.SetHidden(); // Deprecated
extension.AddDuplicatedExpression("CameraY", "CameraCenterY")
.SetHidden(); // Deprecated
extension.AddDuplicatedAction("SetCameraY", "SetCameraCenterY")
.SetHidden(); // Deprecated
extension.AddDuplicatedAction("CameraY", "SetCameraY")
.SetHidden(); // Deprecated
extension.AddDuplicatedExpression("VueY", "CameraY")
.SetHidden(); // Deprecated
// end of compatibility code
extension
.AddExpressionAndCondition(
@@ -98,12 +75,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Width of a camera"),
_("the width of a camera of a layer"),
_("the width of camera _PARAM2_ of layer _PARAM1_"),
"",
_("Layers and cameras"),
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true)
.AddParameter("expression", _("Camera number"))
.UseStandardParameters("number")
.MarkAsAdvanced();
@@ -114,80 +91,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Height of a camera"),
_("the height of a camera of a layer"),
_("the height of camera _PARAM2_ of layer _PARAM1_"),
"",
_("Layers and cameras"),
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true)
.UseStandardParameters("number")
.MarkAsAdvanced();
extension
.AddExpressionAndCondition(
"number",
"CameraBorderLeft",
_("Camera left border position"),
_("the position of the left border of a camera"),
_("the position of the left border of camera _PARAM2_ of layer "
"_PARAM1_"),
"",
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true)
.UseStandardParameters("number")
.MarkAsAdvanced();
extension
.AddExpressionAndCondition(
"number",
"CameraBorderRight",
_("Camera right border position"),
_("the position of the right border of a camera"),
_("the position of the right border of camera _PARAM2_ of layer "
"_PARAM1_"),
"",
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true)
.UseStandardParameters("number")
.MarkAsAdvanced();
extension
.AddExpressionAndCondition(
"number",
"CameraBorderTop",
_("Camera top border position"),
_("the position of the top border of a camera"),
_("the position of the top border of camera _PARAM2_ of layer "
"_PARAM1_"),
"",
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true)
.UseStandardParameters("number")
.MarkAsAdvanced();
extension
.AddExpressionAndCondition(
"number",
"CameraBorderBottom",
_("Camera bottom border position"),
_("the position of the bottom border of a camera"),
_("the position of the bottom border of camera _PARAM2_ of layer "
"_PARAM1_"),
"",
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true)
.AddParameter("expression", _("Camera number"))
.UseStandardParameters("number")
.MarkAsAdvanced();
@@ -196,9 +105,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"number",
"CameraAngle",
_("Angle of a camera of a layer"),
_("the angle of rotation of a camera (in degrees)"),
_("the angle of rotation of a camera"),
_("the angle of camera (layer: _PARAM3_, camera: _PARAM4_)"),
"",
_("Layers and cameras"),
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardParameters("number")
@@ -218,11 +127,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Add a camera to a layer"),
_("This action adds a camera to a layer"),
_("Add a camera to layer _PARAM1_"),
"",
_("Layers and cameras"),
"res/actions/camera24.png",
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
.AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Width"), "", true)
.AddParameter("expression", _("Height"), "", true)
@@ -253,11 +162,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Delete a camera of a layer"),
_("Remove the specified camera from a layer"),
_("Delete camera _PARAM2_ from layer _PARAM1_"),
"",
_("Layers and cameras"),
"res/actions/camera24.png",
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
.AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"))
.MarkAsComplex();
@@ -269,11 +178,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"layer. The zoom will be reset."),
_("Change the size of camera _PARAM2_ of _PARAM1_ to "
"_PARAM3_*_PARAM4_"),
"",
_("Layers and cameras"),
"res/actions/camera24.png",
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
.AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"))
.AddParameter("expression", _("Width"))
@@ -287,11 +196,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"specified layer."),
_("Set the render zone of camera _PARAM2_ from layer _PARAM1_ "
"to _PARAM3_;_PARAM4_ _PARAM5_;_PARAM6_"),
"",
_("Layers and cameras"),
"res/actions/camera24.png",
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
.AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"))
.AddParameter(
@@ -310,11 +219,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
extension
.AddAction("ZoomCamera",
_("Camera zoom"),
_("Change camera zoom"),
_("Change camera zoom."),
_("Change camera zoom to _PARAM1_ (layer: _PARAM2_, camera: "
"_PARAM3_)"),
"",
_("Layers and cameras"),
"res/actions/camera24.png",
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -325,7 +234,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0");
// TODO Deprecated: hide this action in a future release.
extension
.AddAction(
"FixCamera",
@@ -334,7 +242,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"specified limits."),
_("Center the camera on _PARAM1_ (limit : from _PARAM2_;_PARAM3_ to "
"_PARAM4_;_PARAM5_) (layer: _PARAM7_, camera: _PARAM8_)"),
"",
_("Layers and cameras"),
"res/actions/camera24.png",
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -358,38 +266,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
.SetDefaultValue("0")
.MarkAsAdvanced();
extension
.AddAction(
"ClampCamera",
_("Enforce camera boundaries"),
_("Enforce camera boundaries by moving the camera back inside specified boundaries."),
_("Enforce camera boundaries (left: _PARAM1_, top: _PARAM2_ "
"right: _PARAM3_, bottom: _PARAM4_, layer: _PARAM5_)"),
"",
"res/actions/camera24.png",
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression",
_("Left bound X Position"))
.AddParameter("expression",
_("Top bound Y Position"))
.AddParameter("expression",
_("Right bound X Position"))
.AddParameter("expression",
_("Bottom bound Y Position"))
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0")
.MarkAsAdvanced();
extension
.AddAction(
"CentreCamera",
_("Center the camera on an object"),
_("Center the camera on the specified object."),
_("Center camera on _PARAM1_ (layer: _PARAM3_)"),
"",
_("Center camera on _PARAM1_ (layer: _PARAM3_, camera: _PARAM4_)"),
_("Layers and cameras"),
"res/actions/camera24.png",
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -410,11 +293,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Show a layer"),
_("Show a layer."),
_("Show layer _PARAM1_"),
"",
_("Layers and cameras"),
"res/actions/layer24.png",
"res/actions/layer.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
.AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.MarkAsAdvanced();
@@ -423,11 +306,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Hide a layer"),
_("Hide a layer."),
_("Hide layer _PARAM1_"),
"",
_("Layers and cameras"),
"res/actions/layer24.png",
"res/actions/layer.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
.AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.MarkAsAdvanced();
@@ -436,11 +319,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Visibility of a layer"),
_("Test if a layer is set as visible."),
_("Layer _PARAM1_ is visible"),
"",
_("Layers and cameras"),
"res/conditions/layer24.png",
"res/conditions/layer.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
.AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.MarkAsAdvanced();
@@ -452,7 +335,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("You can find the parameter names (and change the effect "
"names) in the effects window."),
_("Set _PARAM3_ to _PARAM4_ for effect _PARAM2_ of layer _PARAM1_"),
_("Effects"),
_("Layers and cameras/Effects"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -471,7 +354,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("You can find the parameter names (and change the effect "
"names) in the effects window."),
_("Set _PARAM3_ to _PARAM4_ for effect _PARAM2_ of layer _PARAM1_"),
_("Effects"),
_("Layers and cameras/Effects"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -490,7 +373,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("You can find the parameter names (and change the effect "
"names) in the effects window."),
_("Enable _PARAM3_ for effect _PARAM2_ of layer _PARAM1_: _PARAM4_"),
_("Effects"),
_("Layers and cameras/Effects"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -506,7 +389,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Layer effect is enabled"),
_("The effect on a layer is enabled"),
_("Effect _PARAM2_ on layer _PARAM1_ is enabled"),
_("Effects"),
_("Layers and cameras/Effects"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -520,7 +403,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Enable layer effect"),
_("Enable an effect on a layer"),
_("Enable effect _PARAM2_ on layer _PARAM1_: _PARAM3_"),
_("Effects"),
_("Layers and cameras/Effects"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -536,7 +419,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Layer time scale"),
_("Compare the time scale applied to the objects of the layer."),
_("the time scale of layer _PARAM1_"),
"",
_("Layers and cameras"),
"res/conditions/time24.png",
"res/conditions/time.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -551,7 +434,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Change layer time scale"),
_("Change the time scale applied to the objects of the layer."),
_("Set the time scale of layer _PARAM1_ to _PARAM2_"),
"",
_("Layers and cameras"),
"res/actions/time24.png",
"res/actions/time.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -566,7 +449,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Compare the default Z order set to objects when they "
"are created on a layer."),
_("the default Z order of objects created on _PARAM1_"),
"",
_("Layers and cameras"),
"res/conditions/layer24.png",
"res/conditions/layer.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -577,12 +460,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
extension
.AddAction("SetLayerDefaultZOrder",
_("Layer default Z order"),
_("Change layer default Z order"),
_("Change the default Z order set to objects when they are "
"created on a layer."),
_("Set the default Z order of objects created on _PARAM1_ to "
"_PARAM2_"),
"",
_("Layers and cameras"),
"res/actions/layer24.png",
"res/actions/layer.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -597,7 +480,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Set the ambient light color of the lighting layer in format "
"\"R;G;B\" string."),
_("Set the ambient color of the lighting layer _PARAM1_ to _PARAM2_"),
_("Lighting"),
_("Layers and cameras/Lighting"),
"res/actions/color24.png",
"res/actions/color.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -611,7 +494,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"CameraViewportLeft",
_("X position of the top left side point of a render zone"),
_("X position of the top left side point of a render zone"),
"",
_("Layers and cameras"),
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
@@ -623,7 +506,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"CameraViewportTop",
_("Y position of the top left side point of a render zone"),
_("Y position of the top left side point of a render zone"),
"",
_("Layers and cameras"),
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
@@ -635,7 +518,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"CameraViewportRight",
_("X position of the bottom right side point of a render zone"),
_("X position of the bottom right side point of a render zone"),
"",
_("Layers and cameras"),
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
@@ -647,7 +530,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"CameraViewportBottom",
_("Y position of the bottom right side point of a render zone"),
_("Y position of the bottom right side point of a render zone"),
"",
_("Layers and cameras"),
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
@@ -658,7 +541,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
.AddExpression("CameraZoom",
_("Zoom of a camera of a layer"),
_("Zoom of a camera of a layer"),
"",
_("Layers and cameras"),
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
@@ -670,7 +553,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
.AddExpression("LayerTimeScale",
_("Layer time scale"),
_("Returns the time scale of the specified layer."),
"",
_("Layers and cameras"),
"res/actions/time.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"));
@@ -679,7 +562,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
.AddExpression("LayerDefaultZOrder",
_("Default Z Order for a layer"),
_("Default Z Order for a layer"),
"",
_("Layers and cameras"),
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"));

View File

@@ -15,28 +15,27 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
extension
.SetExtensionInformation(
"BuiltinCommonConversions",
_("Conversion"),
_("Standard Conversions"),
"Expressions to convert number, texts and quantities.",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/common-conversions");
extension.AddInstructionOrExpressionGroupMetadata(_("Conversion"))
.SetIcon("res/conditions/toujours24_black.png");
extension
.AddExpression("ToNumber",
_("Text > Number"),
_("Convert the text to a number"),
"",
"res/conditions/toujours24_black.png")
_("Conversion"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text to convert to a number"));
extension
.AddStrExpression("ToString",
_("Number > Text"),
_("Convert the result of the expression to text"),
"",
"res/conditions/toujours24_black.png")
_("Conversion"),
"res/conditions/toujours24.png")
.AddParameter("expression", _("Expression to be converted to text"));
extension
@@ -44,8 +43,8 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
_("Number > Text ( without scientific notation )"),
_("Convert the result of the expression to text, "
"without using the scientific notation"),
"",
"res/conditions/toujours24_black.png")
_("Conversion"),
"res/conditions/toujours24.png")
.AddParameter("expression", _("Expression to be converted to text"));
extension
@@ -53,8 +52,8 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
"ToRad",
_("Degrees > Radians"),
_("Converts the angle, expressed in degrees, into radians"),
"",
"res/conditions/toujours24_black.png")
_("Conversion"),
"res/conditions/toujours24.png")
.AddParameter("expression", _("Angle, in degrees"));
extension
@@ -62,76 +61,9 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
"ToDeg",
_("Radians > Degrees"),
_("Converts the angle, expressed in radians, into degrees"),
"",
"res/conditions/toujours24_black.png")
_("Conversion"),
"res/conditions/toujours24.png")
.AddParameter("expression", _("Angle, in radians"));
extension
.AddStrExpression("ToJSON",
_("Convert scene variable to JSON"),
_("Convert a scene variable to JSON"),
_("JSON"),
"res/conditions/toujours24_black.png")
.AddParameter("scenevar", _("Scene variable to be stringified"));
extension
.AddStrExpression("GlobalVarToJSON",
_("Convert global variable to JSON"),
_("Convert a global variable to JSON"),
_("JSON"),
"res/conditions/toujours24_black.png")
.AddParameter("globalvar", _("The global variable to be stringified"));
extension
.AddStrExpression("ObjectVarToJSON",
_("Convert object variable to JSON"),
_("Convert an object variable to JSON"),
_("JSON"),
"res/conditions/toujours24_black.png")
.AddParameter("objectPtr", _("The object with the variable"))
.AddParameter("objectvar", _("The object variable to be stringified"));
extension
.AddAction(
"JSONToVariableStructure",
_("Convert JSON to a scene variable"),
_("Parse a JSON object and store it into a scene variable"),
_("Convert JSON string _PARAM0_ and store it into variable _PARAM1_"),
"",
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", _("JSON string"))
.AddParameter("scenevar", _("Variable where store the JSON object"))
.MarkAsAdvanced();
extension
.AddAction("JSONToGlobalVariableStructure",
_("Convert JSON to global variable"),
_("Parse a JSON object and store it into a global variable"),
_("Convert JSON string _PARAM0_ and store it into global "
"variable _PARAM1_"),
"",
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", _("JSON string"))
.AddParameter("globalvar",
_("Global variable where store the JSON object"))
.MarkAsAdvanced();
extension
.AddAction("JSONToObjectVariableStructure",
_("Convert JSON to object variable"),
_("Parse a JSON object and store it into an object variable"),
_("Parse JSON string _PARAM0_ and store it into variable "
"_PARAM2_ of _PARAM1_"),
"",
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", _("JSON string"))
.AddParameter("objectPtr", _("Object"))
.AddParameter("objectvar",
_("Object variable where store the JSON object"))
.MarkAsAdvanced();
}
} // namespace gd

View File

@@ -4,6 +4,7 @@
* reserved. This project is released under the MIT License.
*/
#include "AllBuiltinExtensions.h"
#include "GDCore/Tools/Localization.h"
#include "GDCore/Events/Builtin/CommentEvent.h"
#include "GDCore/Events/Builtin/ForEachChildVariableEvent.h"
#include "GDCore/Events/Builtin/ForEachEvent.h"
@@ -13,7 +14,6 @@
#include "GDCore/Events/Builtin/StandardEvent.h"
#include "GDCore/Events/Builtin/WhileEvent.h"
#include "GDCore/Events/Event.h"
#include "GDCore/Tools/Localization.h"
using namespace std;
namespace gd {
@@ -24,45 +24,21 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
extension
.SetExtensionInformation(
"BuiltinCommonInstructions",
_("Events and control flow"),
_("Builtin events"),
"GDevelop comes with a set of events and conditions that allow to "
"express the game logic and rules.",
"Florian Rival",
"Open source (MIT License)")
.SetCategory("Advanced")
.SetExtensionHelpPath("/all-features/advanced-conditions");
extension
.AddInstructionOrExpressionGroupMetadata(_("Events and control flow"))
.SetIcon("res/conditions/toujours24_black.png");
extension
.AddCondition("Always",
_("Always"),
_("This condition always returns true (or always false, if "
"the condition is inverted)."),
_("Always"),
"",
"res/conditions/toujours24_black.png",
"res/conditions/toujours_black.png")
.SetHelpPath("/all-features/advanced-conditions")
.AddCodeOnlyParameter("conditionInverted", "")
.MarkAsAdvanced();
// Compatibility with GD <= 5.0.127
extension
.AddDuplicatedCondition(
"Toujours", "BuiltinCommonInstructions::Always", {.unscoped = true})
.SetHidden();
// end of compatibility code
extension
.AddCondition("Or",
_("Or"),
_("Check if one of the sub conditions is true"),
_("If one of these conditions is true:"),
"",
"res/conditions/or24_black.png",
"res/conditions/or_black.png")
_("Advanced"),
"res/conditions/or24.png",
"res/conditions/or.png")
.SetCanHaveSubInstructions()
.MarkAsAdvanced();
@@ -71,9 +47,9 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
_("And"),
_("Check if all sub conditions are true"),
_("If all of these conditions are true:"),
"",
"res/conditions/and24_black.png",
"res/conditions/and_black.png")
_("Advanced"),
"res/conditions/and24.png",
"res/conditions/and.png")
.SetCanHaveSubInstructions()
.MarkAsAdvanced();
@@ -83,9 +59,9 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
_("Not"),
_("Return the contrary of the result of the sub conditions"),
_("Invert the logical result of these conditions:"),
"",
"res/conditions/not24_black.png",
"res/conditions/not_black.png")
_("Advanced"),
"res/conditions/not24.png",
"res/conditions/not.png")
.SetCanHaveSubInstructions()
.MarkAsAdvanced();
@@ -94,52 +70,10 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
_("Trigger once while true"),
_("Run actions only once, for each time the conditions have been met."),
_("Trigger once"),
"",
_("Advanced"),
"res/conditions/once24.png",
"res/conditions/once.png");
extension
.AddCondition("CompareNumbers",
_("Compare two numbers"),
_("Compare the two numbers."),
_("_PARAM0_ _PARAM1_ _PARAM2_"),
"",
"res/conditions/egal24_black.png",
"res/conditions/egal_black.png")
.SetHelpPath("/all-features/advanced-conditions")
.AddParameter("expression", _("First expression"))
.AddParameter("relationalOperator", _("Sign of the test"), "number")
.AddParameter("expression", _("Second expression"))
.MarkAsAdvanced();
// Compatibility with GD <= 5.0.127
extension
.AddDuplicatedCondition(
"Egal", "BuiltinCommonInstructions::CompareNumbers", {.unscoped = true})
.SetHidden();
// end of compatibility code
extension
.AddCondition("CompareStrings",
_("Compare two strings"),
_("Compare the two strings."),
_("_PARAM0_ _PARAM1_ _PARAM2_"),
"",
"res/conditions/egal24_black.png",
"res/conditions/egal_black.png")
.SetHelpPath("/all-features/advanced-conditions")
.AddParameter("string", _("First string expression"))
.AddParameter("relationalOperator", _("Sign of the test"), "string")
.AddParameter("string", _("Second string expression"))
.MarkAsAdvanced();
// Compatibility with GD <= 5.0.127
extension
.AddDuplicatedCondition(
"StrEqual", "BuiltinCommonInstructions::CompareStrings", {.unscoped = true})
.SetHidden();
// end of compatibility code
extension.AddEvent(
"Standard",
_("Standard event"),

View File

@@ -19,21 +19,18 @@ BuiltinExtensionsImplementer::ImplementsExternalLayoutsExtension(
"external layouts.",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/interface/scene-editor/external-layouts")
.SetCategory("Advanced");
extension.AddInstructionOrExpressionGroupMetadata(_("External layouts"))
.SetIcon("res/ribbon_default/externallayout32.png");
.SetExtensionHelpPath("/interface/scene-editor/external-layouts");
extension
.AddAction("CreateObjectsFromExternalLayout",
_("Create objects from an external layout"),
_("Create objects from an external layout."),
_("Create objects from the external layout named _PARAM1_"),
"",
"res/ribbon_default/externallayout32.png",
"res/ribbon_default/externallayout32.png")
_("External layouts"),
"res/conditions/fichier24.png",
"res/conditions/fichier.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("externalLayoutName", _("Name of the external layout"))
.AddParameter("string", _("Name of the external layout"))
.AddParameter("expression", _("X position of the origin"), "", true)
.SetDefaultValue("0")
.AddParameter("expression", _("Y position of the origin"), "", true)

View File

@@ -20,10 +20,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
"stored on the device and erased when the game is uninstalled.",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/storage")
.SetCategory("Advanced");
extension.AddInstructionOrExpressionGroupMetadata(_("Storage"))
.SetIcon("res/conditions/fichier24.png");
.SetExtensionHelpPath("/all-features/storage");
extension
.AddCondition(
@@ -32,7 +29,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
_("Check if an element (example : PlayerState/CurrentLevel) exists "
"in the stored data.\nSpaces are forbidden in element names."),
_("_PARAM1_ exists in storage _PARAM0_"),
"",
_("Storage"),
"res/conditions/fichier24.png",
"res/conditions/fichier.png")
.AddParameter("string", _("Storage name"))
@@ -48,7 +45,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
"action, but it will be slower.\nIf you use this action, do not "
"forget to unload the storage from memory."),
_("Load storage _PARAM0_ in memory"),
"",
_("Storage"),
"res/actions/fichier24.png",
"res/actions/fichier.png")
.AddParameter("string", _("Storage name"))
@@ -60,7 +57,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
_("This action closes the structured data previously loaded "
"in memory, saving all changes made."),
_("Close structured data _PARAM0_"),
"",
_("Storage"),
"res/actions/fichier24.png",
"res/actions/fichier.png")
.AddParameter("string", _("Storage name"))
@@ -75,7 +72,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
"element using / (example : Root/Level/Current)\nSpaces are "
"forbidden in element names."),
_("Write _PARAM2_ in _PARAM1_ of storage _PARAM0_"),
"",
_("Storage"),
"res/actions/fichier24.png",
"res/actions/fichier.png")
.AddParameter("string", _("Storage name"))
@@ -91,7 +88,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
"the structure leading to the element using / (example : "
"Root/Level/Current)\nSpaces are forbidden in element names."),
_("Write _PARAM2_ in _PARAM1_ of storage _PARAM0_"),
"",
_("Storage"),
"res/actions/fichier24.png",
"res/actions/fichier.png")
.AddParameter("string", _("Storage name"))
@@ -108,7 +105,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
"(example : Root/Level/Current)\nSpaces are forbidden in element "
"names."),
_("Read _PARAM1_ from storage _PARAM0_ and store value in _PARAM3_"),
"",
_("Storage"),
"res/actions/fichier24.png",
"res/actions/fichier.png")
.AddParameter("string", _("Storage name"))
@@ -127,7 +124,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
"names."),
_("Read _PARAM1_ from storage _PARAM0_ and store as text in "
"_PARAM3_"),
"",
_("Storage"),
"res/actions/fichier24.png",
"res/actions/fichier.png")
.AddParameter("string", _("Storage name"))
@@ -143,7 +140,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
"element using / (example : Root/Level/Current)\nSpaces are "
"forbidden in element names."),
_("Delete _PARAM1_ from storage _PARAM0_"),
"",
_("Storage"),
"res/actions/delete24.png",
"res/actions/delete.png")
.AddParameter("string", _("Storage name"))
@@ -156,7 +153,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
_("Clear a storage"),
_("Clear the specified storage, removing all data saved in it."),
_("Delete storage _PARAM0_"),
"",
_("Storage"),
"res/actions/delete24.png",
"res/actions/delete.png")
.AddParameter("string", _("Storage name"));
@@ -166,18 +163,32 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
_("A storage exists"),
_("Test if the specified storage exists."),
_("Storage _PARAM0_ exists"),
"",
_("Storage"),
"res/conditions/fichier24.png",
"res/conditions/fichier.png")
.AddParameter("string", _("Storage name"))
.MarkAsAdvanced();
extension
.AddAction("LaunchFile",
_("Open a URL or a file"),
_("This action launches the specified file or URL, in a "
"browser (or in a new tab if the game is using the Web "
"platform and is launched inside a browser)."),
_("Open URL (or file) _PARAM0_"),
_("Files"),
"res/actions/launchFile24.png",
"res/actions/launchFile.png")
.AddParameter("string", _("URL (or filename)"))
.AddCodeOnlyParameter("currentScene", "")
.MarkAsAdvanced();
extension
.AddAction("ExecuteCmd",
_("Execute a command"),
_("This action executes the specified command."),
_("Execute _PARAM0_"),
_("Network"),
_("Files"),
"res/actions/launchFile24.png",
"res/actions/launchFile.png")
.AddParameter("string", _("Command"))

View File

@@ -14,24 +14,21 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
extension
.SetExtensionInformation(
"BuiltinKeyboard",
_("Keyboard"),
_("Keyboard features"),
_("Allows your game to respond to keyboard input. Note that this "
"does not work with on-screen keyboard on touch devices: use "
"instead conditions related to touch when making a game for "
"mobile/touchscreen devices."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/keyboard")
.SetCategory("Input");
extension.AddInstructionOrExpressionGroupMetadata(_("Keyboard"))
.SetIcon("res/conditions/keyboard24.png");
.SetExtensionHelpPath("/all-features/keyboard");
extension
.AddCondition("KeyPressed",
_("Key pressed"),
_("Check if a key is pressed"),
_("_PARAM1_ key is pressed"),
"",
_("Keyboard"),
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -42,7 +39,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
_("Key released"),
_("Check if a key was just released"),
_("_PARAM1_ key is released"),
"",
_("Keyboard"),
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -54,7 +51,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
_("Check if a key, retrieved from the result of the "
"expression, is pressed"),
_("_PARAM1_ key is pressed"),
"",
_("Keyboard"),
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -67,7 +64,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
_("Check if a key, retrieved from the result of the "
"expression, was just released"),
_("_PARAM1_ key is released"),
"",
_("Keyboard"),
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -79,7 +76,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
_("Any key pressed"),
_("Check if any key is pressed"),
_("Any key is pressed"),
"",
_("Keyboard"),
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "");
@@ -89,7 +86,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
_("Any key released"),
_("Check if any key is released"),
_("Any key is released"),
"",
_("Keyboard"),
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "");
@@ -99,7 +96,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
"LastPressedKey",
_("Last pressed key"),
_("Get the name of the latest key pressed on the keyboard"),
"",
_("Keyboard"),
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "");
}

View File

@@ -18,63 +18,13 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
"A set of mathematical functions that can be used in expressions.",
"Florian Rival",
"Open source (MIT License)");
extension.AddInstructionOrExpressionGroupMetadata(_("Mathematical tools"))
.SetIcon("res/mathfunction.png");
extension
.AddExpression("Random",
_("Random integer"),
_("Random integer"),
"",
"res/dice-6.svg")
.SetHelpPath("/all-features/expressions")
.AddParameter("expression", _("Maximum value"));
extension
.AddExpression("RandomInRange",
_("Random integer in range"),
_("Random integer in range"),
"",
"res/dice-6.svg")
.SetHelpPath("/all-features/expressions")
.AddParameter("expression", _("Minimum value"))
.AddParameter("expression", _("Maximum value"));
extension
.AddExpression("RandomFloat",
_("Random float"),
_("Random float"),
"",
"res/dice-6.svg")
.SetHelpPath("/all-features/expressions")
.AddParameter("expression", _("Maximum value"));
extension
.AddExpression("RandomFloatInRange",
_("Random float in range"),
_("Random float in range"),
"",
"res/dice-6.svg")
.SetHelpPath("/all-features/expressions")
.AddParameter("expression", _("Minimum value"))
.AddParameter("expression", _("Maximum value"));
extension
.AddExpression("RandomWithStep",
_("Random value in steps"),
_("Random value in steps"),
"",
"res/dice-6.svg")
.SetHelpPath("/all-features/expressions")
.AddParameter("expression", _("Minimum value"))
.AddParameter("expression", _("Maximum value"))
.AddParameter("expression", _("Step"));
extension
.AddExpression("normalize",
_("Normalize a value between `min` and `max` to a value between 0 and 1."),
_("Remap a value between 0 and 1."),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Value"))
.AddParameter("expression", _("Min"))
@@ -84,7 +34,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("clamp",
_("Clamp (restrict a value to a given range)"),
_("Restrict a value to a given range"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Value"))
.AddParameter("expression", _("Min"))
@@ -94,16 +44,16 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("AngleDifference",
_("Difference between two angles"),
_("Difference between two angles"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("First angle, in degrees"))
.AddParameter("expression", _("Second angle, in degrees"));
.AddParameter("expression", _("First angle"))
.AddParameter("expression", _("Second angle"));
extension
.AddExpression("AngleBetweenPositions",
_("Angle between two positions"),
_("Compute the angle between two positions (in degrees)."),
"",
_("Compute the angle between two positions."),
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("First point X position"))
.AddParameter("expression", _("First point Y position"))
@@ -114,7 +64,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("DistanceBetweenPositions",
_("Distance between two positions"),
_("Compute the distance between two positions."),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("First point X position"))
.AddParameter("expression", _("First point Y position"))
@@ -125,7 +75,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("mod",
_("Modulo"),
_("x mod y"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("x (as in x mod y)"))
.AddParameter("expression", _("y (as in x mod y)"));
@@ -134,7 +84,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("min",
_("Minimum of two numbers"),
_("Minimum of two numbers"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("First expression"))
.AddParameter("expression", _("Second expression"));
@@ -143,7 +93,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("max",
_("Maximum of two numbers"),
_("Maximum of two numbers"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("First expression"))
.AddParameter("expression", _("Second expression"));
@@ -152,16 +102,15 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("abs",
_("Absolute value"),
_("Absolute value"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
.AddExpression("acos",
_("Arccosine"),
_("Arccosine, return an angle (in radian). "
"`ToDeg` allows to convert it to degrees."),
"",
_("Arccosine"),
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -169,16 +118,15 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("acosh",
_("Hyperbolic arccosine"),
_("Hyperbolic arccosine"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
.AddExpression("asin",
_("Arcsine"),
_("Arcsine, return an angle (in radian). "
"`ToDeg` allows to convert it to degrees."),
"",
_("Arcsine"),
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -186,16 +134,15 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("asinh",
_("Arcsine"),
_("Arcsine"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
.AddExpression("atan",
_("Arctangent"),
_("Arctangent, return an angle (in radian). "
"`ToDeg` allows to convert it to degrees."),
"",
_("Arctangent"),
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -203,7 +150,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("atan2",
_("2 argument arctangent"),
_("2 argument arctangent (atan2)"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Y"))
.AddParameter("expression", _("X"));
@@ -212,7 +159,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("atanh",
_("Hyperbolic arctangent"),
_("Hyperbolic arctangent"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -220,7 +167,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("cbrt",
_("Cube root"),
_("Cube root"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -228,42 +175,23 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("ceil",
_("Ceil (round up)"),
_("Round number up to an integer"),
"",
_("Mathematical tools"),
"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)"),
_("Round number down to an integer"),
"",
_("Mathematical tools"),
"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"),
_("Cosine of an angle (in radian). "
"If you want to use degrees, use`ToRad`: `sin(ToRad(45))`."),
"",
_("Cosine of a number"),
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -271,7 +199,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("cosh",
_("Hyperbolic cosine"),
_("Hyperbolic cosine"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -279,7 +207,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("cot",
_("Cotangent"),
_("Cotangent of a number"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -287,7 +215,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("csc",
_("Cosecant"),
_("Cosecant of a number"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -295,7 +223,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("int",
_("Round"),
_("Round a number"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.SetHidden()
.AddParameter("expression", _("Expression"));
@@ -304,7 +232,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("rint",
_("Round"),
_("Round a number"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.SetHidden()
.AddParameter("expression", _("Expression"));
@@ -313,24 +241,15 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("round",
_("Round"),
_("Round a number"),
"",
_("Mathematical tools"),
"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"),
_("Exponential of a number"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -338,7 +257,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("log",
_("Logarithm"),
_("Logarithm"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -346,7 +265,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("ln",
_("Logarithm"),
_("Logarithm"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.SetHidden()
.AddParameter("expression", _("Expression"));
@@ -355,7 +274,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("log2",
_("Base-2 logarithm"),
_("Base 2 Logarithm"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -363,7 +282,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("log10",
_("Base-10 logarithm"),
_("Base-10 logarithm"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -371,7 +290,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("nthroot",
_("Nth root"),
_("Nth root of a number"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Number"))
.AddParameter("expression", _("N"));
@@ -380,7 +299,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("pow",
_("Power"),
_("Raise a number to power n"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Number"))
.AddParameter("expression", _("The exponent (n in x^n)"));
@@ -389,7 +308,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("sec",
_("Secant"),
_("Secant"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -397,16 +316,15 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("sign",
_("Sign of a number"),
_("Return the sign of a number (1,-1 or 0)"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
.AddExpression("sin",
_("Sine"),
_("Sine of an angle (in radian). "
"If you want to use degrees, use`ToRad`: `sin(ToRad(45))`."),
"",
_("Sine of a number"),
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -414,7 +332,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("sinh",
_("Hyperbolic sine"),
_("Hyperbolic sine"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -422,16 +340,15 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("sqrt",
_("Square root"),
_("Square root of a number"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
.AddExpression("tan",
_("Tangent"),
_("Tangent of an angle (in radian). "
"If you want to use degrees, use`ToRad`: `tan(ToRad(45))`."),
"",
_("Tangent of a number"),
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -439,7 +356,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("tanh",
_("Hyperbolic tangent"),
_("Hyperbolic tangent"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -447,7 +364,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("trunc",
_("Truncation"),
_("Truncate a number"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -455,7 +372,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("lerp",
_("Lerp (Linear interpolation)"),
_("Linearly interpolate a to b by x"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("a (in a+(b-a)*x)"))
.AddParameter("expression", _("b (in a+(b-a)*x)"))
@@ -468,7 +385,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
"relative to the origin (0;0). This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Distance"));
@@ -480,18 +397,11 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
"relative to the origin (0;0). This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Distance"));
extension
.AddExpression("Pi",
_("Number Pi (3.1415...)"),
_("The number Pi (3.1415...)"),
"",
"res/mathfunction.png")
.SetHelpPath("/all-features/expressions");
}
} // namespace gd

View File

@@ -23,10 +23,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
"separately in different events.",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/mouse-touch")
.SetCategory("Input");
extension.AddInstructionOrExpressionGroupMetadata(_("Mouse and touch"))
.SetIcon("res/actions/mouse24.png");
.SetExtensionHelpPath("/all-features/mouse-touch");
extension
.AddCondition(
@@ -35,7 +32,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Check if the mouse wheel is scrolling up. Use MouseWheelDelta "
"expression if you want to know the amount that was scrolled."),
_("The mouse wheel is scrolling up"),
"",
_("Mouse and touch"),
"res/actions/mouse24.png",
"res/actions/mouse.png")
@@ -49,7 +46,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Check if the mouse wheel is scrolling down. Use MouseWheelDelta "
"expression if you want to know the amount that was scrolled."),
_("The mouse wheel is scrolling down"),
"",
_("Mouse and touch"),
"res/actions/mouse24.png",
"res/actions/mouse.png")
@@ -67,7 +64,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
"touchscreens. If you want to have multitouch and differentiate "
"mouse movement and touches, just deactivate it with this action."),
_("Move mouse cursor when touching screen: _PARAM1_"),
"",
_("Mouse and touch"),
"res/conditions/touch24.png",
"res/conditions/touch.png")
@@ -82,7 +79,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Center cursor horizontally"),
_("Put the cursor in the middle of the screen horizontally."),
_("Center cursor horizontally"),
"",
_("Mouse and touch"),
"res/actions/mouse24.png",
"res/actions/mouse.png")
@@ -94,7 +91,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Center cursor vertically"),
_("Put the cursor in the middle of the screen vertically."),
_("Center cursor vertically"),
"",
_("Mouse and touch"),
"res/actions/mouse24.png",
"res/actions/mouse.png")
@@ -106,7 +103,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Hide the cursor"),
_("Hide the cursor."),
_("Hide the cursor"),
"",
_("Mouse and touch"),
"res/actions/mouse24.png",
"res/actions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -117,7 +114,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Show the cursor"),
_("Show the cursor."),
_("Show the cursor"),
"",
_("Mouse and touch"),
"res/actions/mouse24.png",
"res/actions/mouse.png")
@@ -129,7 +126,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Position the cursor of the mouse"),
_("Position the cursor at the given coordinates."),
_("Position cursor at _PARAM1_;_PARAM2_"),
"",
_("Mouse and touch"),
"res/actions/mouse24.png",
"res/actions/mouse.png")
@@ -143,7 +140,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Center the cursor"),
_("Center the cursor on the screen."),
_("Center the cursor"),
"",
_("Mouse and touch"),
"res/actions/mouse24.png",
"res/actions/mouse.png")
@@ -157,7 +154,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Cursor X position"),
_("the X position of the cursor or of a touch"),
_("the cursor (or touch) X position"),
"",
_("Mouse and touch"),
"res/conditions/mouse24.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardParameters("number")
@@ -177,7 +174,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Cursor Y position"),
_("the Y position of the cursor or of a touch"),
_("the cursor (or touch) Y position"),
"",
_("Mouse and touch"),
"res/conditions/mouse24.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardParameters("number")
@@ -190,24 +187,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
extension.AddDuplicatedCondition("SourisY", "MouseY").SetHidden();
extension.AddDuplicatedExpression("SourisY", "MouseY").SetHidden();
extension
.AddCondition("IsMouseInsideCanvas",
_("Mouse cursor is inside the window"),
_("Check if the mouse cursor is inside the window."),
_("The mouse cursor is inside the window"),
"",
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.MarkAsAdvanced();
extension
.AddCondition("MouseButtonPressed",
_("Mouse button pressed or touch held"),
_("Check if the specified mouse button is pressed or "
"if a touch is in contact with the screen."),
_("Touch or _PARAM1_ mouse button is down"),
"",
_("Mouse and touch"),
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -223,7 +209,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Mouse button released"),
_("Check if the specified mouse button was released."),
_("_PARAM1_ mouse button was released"),
"",
_("Mouse and touch"),
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -237,13 +223,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Check if a mouse button, retrieved from the result of the "
"expression, is pressed."),
_("_PARAM1_ mouse button is pressed"),
"",
_("Mouse and touch"),
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("stringWithSelector",
_("Expression generating the mouse button to check"),
"[\"Left\", \"Right\", \"Middle\"]")
.AddParameter("string", _("Expression generating the button to check"))
.SetParameterLongDescription(
_("Possible values are Left, Right and Middle."))
.MarkAsAdvanced();
@@ -255,13 +239,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Check if a mouse button, retrieved from the result of the "
"expression, was just released."),
_("_PARAM1_ mouse button is released"),
"",
_("Mouse and touch"),
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("stringWithSelector",
_("Expression generating the mouse button to check"),
"[\"Left\", \"Right\", \"Middle\"]")
.AddParameter("string",
_("Expression generating the mouse button to check"))
.SetParameterLongDescription(
_("Possible values are Left, Right and Middle."))
.MarkAsAdvanced();
@@ -272,7 +255,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Touch X position"),
_("the X position of a specific touch"),
_("the touch #_PARAM1_ X position"),
_("Multitouch"),
_("Mouse and touch/Multitouch"),
"res/conditions/touch24.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch identifier"))
@@ -288,7 +271,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Touch Y position"),
_("the Y position of a specific touch"),
_("the touch #_PARAM1_ Y position"),
_("Multitouch"),
_("Mouse and touch/Multitouch"),
"res/conditions/touch24.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch identifier"))
@@ -308,11 +291,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
"next time you use it, it will be for a new touch, or it will "
"return false if no more touches have just started."),
_("A new touch has started"),
_("Multitouch"),
_("Mouse and touch/Multitouch"),
"res/conditions/touch24.png",
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "")
.SetHidden();
.AddCodeOnlyParameter("currentScene", "");
extension
.AddCondition(
@@ -324,57 +306,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
"time you use it, it will be for a new touch, or it will return "
"false if no more touches have just ended."),
_("A touch has ended"),
_("Multitouch"),
"res/conditions/touch24.png",
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "")
.SetHidden();
extension
.AddCondition(
"HasAnyTouchStarted",
_("A new touch has started"),
_("Check if a touch has just started on this frame. The touch identifiers can be "
"accessed using StartedTouchId() and StartedTouchCount()."),
_("A new touch has started"),
_("Multitouch"),
_("Mouse and touch/Multitouch"),
"res/conditions/touch24.png",
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "");
extension
.AddExpression(
"StartedTouchCount",
_("Started touch count"),
_("The number of touches that have just started on this frame. The touch identifiers can be "
"accessed using StartedTouchId()."),
_("Multitouch"),
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "");
extension
.AddExpression(
"StartedTouchId",
_("Started touch identifier"),
_("The identifier of the touch that has just started on this frame. The touch number of touches can be "
"accessed using StartedTouchCount()."),
_("Multitouch"),
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch index"));
extension
.AddCondition(
"HasTouchEnded",
_("A touch has ended"),
_("Check if a touch has ended."),
_("The touch with identifier _PARAM1_ has ended"),
_("Multitouch"),
"res/conditions/touch24.png",
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch identifier"));
extension
.AddExpression("MouseWheelDelta",
_("Mouse wheel: Displacement"),
@@ -387,19 +323,17 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
.AddExpression("LastTouchId",
_("Identifier of the last touch"),
_("Identifier of the last touch"),
_("Multitouch"),
_("Mouse and touch/Multitouch"),
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "")
.SetHidden();
.AddCodeOnlyParameter("currentScene", "");
extension
.AddExpression("LastEndedTouchId",
_("Identifier of the last ended touch"),
_("Identifier of the last ended touch"),
_("Multitouch"),
_("Mouse and touch/Multitouch"),
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "")
.SetHidden();
.AddCodeOnlyParameter("currentScene", "");
}
} // namespace gd

View File

@@ -14,15 +14,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
extension
.SetExtensionInformation(
"BuiltinNetwork",
_("Network"),
_("Basic internet features"),
_("Features to send web requests, communicate with external \"APIs\" "
"and other network related tasks."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/network")
.SetCategory("Network");
extension.AddInstructionOrExpressionGroupMetadata(_("Network"))
.SetIcon("res/actions/net24.png");
.SetExtensionHelpPath("/all-features/network");
extension
.AddAction(
@@ -33,7 +30,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
"as specified below, except if the server is configured to answer "
"to all requests (cross-domain requests).",
"Send _PARAM3_ request to _PARAM0__PARAM1_ with body: _PARAM2_",
"",
_("Network"),
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", "Host, with protocol")
@@ -68,7 +65,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
"to all requests (cross-domain requests)."),
_("Send a _PARAM2_ request to _PARAM0_ with body: _PARAM1_, and "
"store the result in _PARAM4_ (or in _PARAM5_ in case of error)"),
"",
_("Network"),
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", _("URL (API or web-page address)"))
@@ -95,37 +92,20 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
"explore the results with a *structure variable*."))
.AddParameter(
"scenevar", _("Variable where to store the error message"), "", true)
.SetParameterLongDescription(_(
"Optional, only used if an error occurs. This will contain the "
"[\"status "
"code\"](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) "
"if the server returns a status >= 400. If the request was not sent "
"at all (e.g. no internet or CORS issues), the variable will be set "
"to "
"\"REQUEST_NOT_SENT\"."))
.SetParameterLongDescription(
_("Optional, only used if an error occurs. This will contain the "
"error message (if request could not be sent) or the [\"status "
"code\"](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes), "
"if the server returns a status >= 400."))
.MarkAsComplex();
extension
.AddAction("LaunchFile",
_("Open a URL (web page) or a file"),
_("This action launches the specified file or URL, in a "
"browser (or in a new tab if the game is using the Web "
"platform and is launched inside a browser)."),
_("Open URL _PARAM0_ in a browser (or new tab)"),
"",
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", _("URL (or filename)"))
.AddCodeOnlyParameter("currentScene", "")
.MarkAsAdvanced();
extension
.AddAction(
"DownloadFile",
_("Download a file"),
_("Download a file from a web site"),
_("Download file _PARAM1_ from _PARAM0_ under the name of _PARAM2_"),
"",
_("Network"),
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", _("Host (for example : http://www.website.com)"))
@@ -143,11 +123,78 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
"terms of service of your game and if they player gave their "
"consent, depending on how your game/company handles this."),
_("Enable analytics metrics: _PARAM1_"),
"",
_("Network"),
"res/actions/net24.png",
"res/actions/net.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("yesorno", _("Enable the metrics?"));
extension
.AddAction(
"JSONToVariableStructure",
_("Convert JSON to a scene variable"),
_("Parse a JSON object and store it into a scene variable"),
_("Parse JSON string _PARAM0_ and store it into variable _PARAM1_"),
_("Network"),
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", _("JSON string"))
.AddParameter("scenevar", _("Variable where store the JSON object"))
.MarkAsAdvanced();
extension
.AddAction("JSONToGlobalVariableStructure",
_("Convert JSON to global variable"),
_("Parse a JSON object and store it into a global variable"),
_("Parse JSON string _PARAM0_ and store it into global "
"variable _PARAM1_"),
_("Network"),
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", _("JSON string"))
.AddParameter("globalvar",
_("Global variable where store the JSON object"))
.MarkAsAdvanced();
extension
.AddAction("JSONToObjectVariableStructure",
_("Convert JSON to object variable"),
_("Parse a JSON object and store it into an object variable"),
_("Parse JSON string _PARAM0_ and store it into variable "
"_PARAM2_ of _PARAM1_"),
_("Network"),
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", _("JSON string"))
.AddParameter("objectPtr", _("Object"))
.AddParameter("objectvar",
_("Object variable where store the JSON object"))
.MarkAsAdvanced();
extension
.AddStrExpression("ToJSON",
_("Convert scene variable to JSON"),
_("Convert a scene variable to JSON"),
_("Conversion"),
"res/conditions/toujours24.png")
.AddParameter("scenevar", _("Scene variable to be stringified"));
extension
.AddStrExpression("GlobalVarToJSON",
_("Convert global variable to JSON"),
_("Convert a global variable to JSON"),
_("Conversion"),
"res/conditions/toujours24.png")
.AddParameter("globalvar", _("The global variable to be stringified"));
extension
.AddStrExpression("ObjectVarToJSON",
_("Convert object variable to JSON"),
_("Convert an object variable to JSON"),
_("Conversion"),
"res/conditions/toujours24.png")
.AddParameter("objectPtr", _("The object with the variable"))
.AddParameter("objectvar", _("The object variable to be stringified"));
}
} // namespace gd

View File

@@ -14,19 +14,67 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
extension
.SetExtensionInformation(
"BuiltinScene",
_("Scene"),
_("Scene management features"),
_("Actions and conditions to manipulate the scenes during the game."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("" /*TODO: Add a documentation page for this */);
extension.AddInstructionOrExpressionGroupMetadata(_("Scene"))
.SetIcon("res/conditions/depart24.png");
extension
.AddExpression("Random",
_("Random integer"),
_("Random integer"),
_("Random"),
"res/actions/position.png")
.SetHelpPath("/all-features/expressions")
.AddParameter("expression", _("Maximum value"));
extension
.AddExpression("RandomInRange",
_("Random integer in range"),
_("Random integer in range"),
_("Random"),
"res/actions/position.png")
.SetHelpPath("/all-features/expressions")
.AddParameter("expression", _("Minimum value"))
.AddParameter("expression", _("Maximum value"));
extension
.AddExpression("RandomFloat",
_("Random float"),
_("Random float"),
_("Random"),
"res/actions/position.png")
.SetHelpPath("/all-features/expressions")
.AddParameter("expression", _("Maximum value"));
extension
.AddExpression("RandomFloatInRange",
_("Random float in range"),
_("Random float in range"),
_("Random"),
"res/actions/position.png")
.SetHelpPath("/all-features/expressions")
.AddParameter("expression", _("Minimum value"))
.AddParameter("expression", _("Maximum value"));
extension
.AddExpression("RandomWithStep",
_("Random value in steps"),
_("Random value in steps"),
_("Random"),
"res/actions/position.png")
.SetHelpPath("/all-features/expressions")
.AddParameter("expression", _("Minimum value"))
.AddParameter("expression", _("Maximum value"))
.AddParameter("expression", _("Step"));
extension
.AddStrExpression("CurrentSceneName",
_("Current scene name"),
_("Name of the current scene"),
"",
_("Scene"),
"res/actions/texte.png")
.AddCodeOnlyParameter("currentScene", "");
@@ -35,7 +83,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
_("At the beginning of the scene"),
_("Is true only when scene just begins."),
_("At the beginning of the scene"),
"",
_("Scene"),
"res/conditions/depart24.png",
"res/conditions/depart.png")
.SetHelpPath("/interface/scene-editor/events")
@@ -47,7 +95,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
_("Scene just resumed"),
_("The scene has just resumed after being paused."),
_("Scene just resumed"),
"",
_("Scene"),
"res/conditions/depart24.png",
"res/conditions/depart.png")
.SetHelpPath("/interface/scene-editor/events")
@@ -59,7 +107,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
_("Change the scene"),
_("Stop this scene and start the specified one instead."),
_("Change to scene _PARAM1_"),
"",
_("Scene"),
"res/actions/replaceScene24.png",
"res/actions/replaceScene.png")
.SetHelpPath("/interface/scene-editor/events")
@@ -76,7 +124,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
"can use the \"Stop and go back to previous scene\" action "
"to go back to this scene."),
_("Pause the scene and start _PARAM1_"),
"",
_("Scene"),
"res/actions/pushScene24.png",
"res/actions/pushScene.png")
.SetHelpPath("/interface/scene-editor/events")
@@ -91,7 +139,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
_("Stop this scene and go back to the previous paused one.\nTo pause "
"a scene, use the \"Pause and start a new scene\" action."),
_("Stop the scene and go back to the previous paused one"),
"",
_("Scene"),
"res/actions/popScene24.png",
"res/actions/popScene.png")
.SetHelpPath("/interface/scene-editor/events")
@@ -103,7 +151,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
_("Quit the game"),
_("Quit the game"),
_("Quit the game"),
"",
_("Scene"),
"res/actions/quit24.png",
"res/actions/quit.png")
.SetHelpPath("/interface/scene-editor/events")
@@ -112,10 +160,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
extension
.AddAction("SceneBackground",
_("Background color"),
_("Change background color"),
_("Change the background color of the scene."),
_("Set background color to _PARAM1_"),
"",
_("Scene"),
"res/actions/background24.png",
"res/actions/background.png")
.SetHelpPath("/interface/scene-editor/events")
@@ -129,13 +177,41 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
_("mouse buttons must be taken "
"into account even\nif the window is not active."),
_("Disable input when focus is lost: _PARAM1_"),
"",
_("Scene"),
"res/actions/window24.png",
"res/actions/window.png")
.SetHelpPath("/interface/scene-editor/events")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("yesorno", _("Deactivate input when focus is lost"))
.MarkAsAdvanced();
extension
.AddCondition("Egal",
_("Compare two numbers"),
_("Compare the two numbers."),
_("_PARAM0_ _PARAM1_ _PARAM2_"),
_("Other"),
"res/conditions/egal24.png",
"res/conditions/egal.png")
.SetHelpPath("/all-features/advanced-conditions")
.AddParameter("expression", _("First expression"))
.AddParameter("relationalOperator", _("Sign of the test"), "number")
.AddParameter("expression", _("Second expression"))
.MarkAsAdvanced();
extension
.AddCondition("StrEqual",
_("Compare two strings"),
_("Compare the two strings."),
_("_PARAM0_ _PARAM1_ _PARAM2_"),
_("Other"),
"res/conditions/egal24.png",
"res/conditions/egal.png")
.SetHelpPath("/all-features/advanced-conditions")
.AddParameter("string", _("First string expression"))
.AddParameter("relationalOperator", _("Sign of the test"), "string")
.AddParameter("string", _("Second string expression"))
.MarkAsAdvanced();
}
} // namespace gd

View File

@@ -4,10 +4,8 @@
* reserved. This project is released under the MIT License.
*/
#include "GDCore/Extensions/Builtin/SpriteExtension/Direction.h"
#include <iostream>
#include <vector>
#include "GDCore/CommonTools.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Sprite.h"
#include "GDCore/Serialization/SerializerElement.h"
@@ -31,15 +29,6 @@ const Sprite& Direction::GetSprite(std::size_t nb) const { return sprites[nb]; }
Sprite& Direction::GetSprite(std::size_t nb) { return sprites[nb]; }
const std::vector<gd::String>& Direction::GetSpriteNames() const {
static std::vector<gd::String> spriteNames;
spriteNames.clear();
for (std::size_t i = 0; i < sprites.size(); ++i) {
spriteNames.push_back(sprites[i].GetImageName());
}
return spriteNames;
}
void Direction::RemoveSprite(std::size_t index) {
if (index < sprites.size()) sprites.erase(sprites.begin() + index);
}
@@ -132,7 +121,7 @@ void Direction::UnserializeFrom(const gd::SerializerElement& element) {
polygonElement.GetChild(k);
polygon.vertices.push_back(
gd::Vector2f(verticeElement.GetDoubleAttribute("x"),
sf::Vector2f(verticeElement.GetDoubleAttribute("x"),
verticeElement.GetDoubleAttribute("y")));
}

View File

@@ -72,13 +72,6 @@ class GD_CORE_API Direction {
*/
Sprite& GetSprite(std::size_t nb);
/**
* \brief Return a vector of references to sprite names.
*
* \return A vector of all sprite names references.
*/
const std::vector<gd::String>& GetSpriteNames() const;
/**
* \brief Check if the direction contains sprites.
*

View File

@@ -4,7 +4,7 @@
* reserved. This project is released under the MIT License.
*/
#include "Polygon2d.h"
#include "GDCore/Vector2.h"
#include <SFML/System/Vector2.hpp>
#include <cmath>
#include <iostream>
@@ -28,7 +28,7 @@ void Polygon2d::Move(float x, float y) {
}
void Polygon2d::ComputeEdges() const {
gd::Vector2f v1, v2;
sf::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;
}
gd::Vector2f Polygon2d::ComputeCenter() const {
gd::Vector2f center;
sf::Vector2f Polygon2d::ComputeCenter() const {
sf::Vector2f center;
for (std::size_t i = 0; i < vertices.size(); i++) {
center.x += vertices[i].x;
@@ -77,10 +77,10 @@ gd::Vector2f Polygon2d::ComputeCenter() const {
Polygon2d Polygon2d::CreateRectangle(float width, float height) {
Polygon2d rect;
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));
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));
return rect;
}

View File

@@ -5,7 +5,7 @@
*/
#ifndef GDCORE_POLYGON_H
#define GDCORE_POLYGON_H
#include "GDCore/Vector2.h"
#include <SFML/System/Vector2.hpp>
#include <vector>
/**
@@ -22,19 +22,19 @@ class GD_CORE_API Polygon2d {
Polygon2d(){};
virtual ~Polygon2d(){};
std::vector<gd::Vector2f> vertices; ///< The vertices composing the polygon
mutable std::vector<gd::Vector2f>
std::vector<sf::Vector2f> vertices; ///< The vertices composing the polygon
mutable std::vector<sf::Vector2f>
edges; ///< Edges. Can be computed from vertices using ComputeEdges()
/**
* \brief Get the vertices composing the polygon.
*/
std::vector<gd::Vector2f>& GetVertices() { return vertices; }
std::vector<sf::Vector2f>& GetVertices() { return vertices; }
/**
* \brief Get the vertices composing the polygon.
*/
const std::vector<gd::Vector2f>& GetVertices() const { return vertices; }
const std::vector<sf::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
*/
gd::Vector2f ComputeCenter() const;
sf::Vector2f ComputeCenter() const;
/** \name Tools
* Tool functions

View File

@@ -4,6 +4,7 @@
* 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"

View File

@@ -6,6 +6,7 @@
#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"

View File

@@ -22,20 +22,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects/sprite");
extension.AddInstructionOrExpressionGroupMetadata(_("Sprite"))
.SetIcon("CppPlatform/Extensions/spriteicon.png");
gd::ObjectMetadata& obj =
extension
.AddObject<SpriteObject>("Sprite",
_("Sprite"),
_("Animated object which can be used for "
"most elements of a game"),
"CppPlatform/Extensions/spriteicon.png")
.SetCategoryFullName(_("General"));
gd::ObjectMetadata& obj = extension.AddObject<SpriteObject>(
"Sprite",
_("Sprite"),
_("Animated object which can be used for most elements of a game"),
"CppPlatform/Extensions/spriteicon.png");
obj.AddAction("Opacity",
_("Sprite opacity"),
_("Change sprite opacity"),
_("Change the opacity of a Sprite. 0 is fully transparent, 255 "
"is opaque (default)."),
_("the opacity"),
@@ -81,10 +76,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"is in 8 directions mode, the valid directions are 0..7"),
_("the direction"),
_("Direction"),
"res/actions/direction24_black.png",
"res/actions/direction_black.png")
.SetHidden() // Hide as 8 direction is not supported officially in the
// interface.
"res/actions/direction24.png",
"res/actions/direction.png")
.SetHidden() // Hide as 8 direction is not supported officially in the interface.
.AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters("number")
.MarkAsAdvanced();
@@ -142,8 +136,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"Rotate an object towards a position.",
"Rotate _PARAM0_ towards _PARAM1_;_PARAM2_",
_("Direction"),
"res/actions/rotate24_black.png",
"res/actions/rotate_black.png")
"res/actions/direction24.png",
"res/actions/direction.png")
.AddParameter("object", _("Object to be rotated"), "Sprite")
.AddParameter("expression", _("X position"))
@@ -158,8 +152,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Modify the scale of the specified object."),
_("the scale"),
_("Size"),
"res/actions/scale24_black.png",
"res/actions/scale_black.png")
"res/actions/scale24.png",
"res/actions/scale.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters("number")
@@ -170,8 +164,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Modify the scale of the width of an object."),
_("the width's scale"),
_("Size"),
"res/actions/scaleWidth24_black.png",
"res/actions/scaleWidth_black.png")
"res/actions/scale24.png",
"res/actions/scale.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters("number")
@@ -182,8 +176,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Modify the scale of the height of an object."),
_("the height's scale"),
_("Size"),
"res/actions/scaleHeight24_black.png",
"res/actions/scaleHeight_black.png")
"res/actions/scale24.png",
"res/actions/scale.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters("number")
@@ -194,62 +188,25 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Change the width of a Sprite object."),
_("the width"),
_("Size"),
"res/actions/scaleWidth24_black.png",
"res/actions/scaleWidth_black.png")
"res/actions/scale24.png",
"res/actions/scale.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters("number")
.MarkAsAdvanced();
obj.AddCondition("Width",
_("Width"),
_("Compare the width of a Sprite object."),
_("the width"),
_("Size"),
"res/conditions/scaleWidth24_black.png",
"res/conditions/scaleWidth_black.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
obj.AddAction("ChangeHeight",
_("Height"),
_("Change the height of a Sprite object."),
_("the height"),
_("Size"),
"res/actions/scaleHeight24_black.png",
"res/actions/scaleHeight_black.png")
"res/actions/scale24.png",
"res/actions/scale.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters("number")
.MarkAsAdvanced();
obj.AddCondition("Height",
_("Height"),
_("Compare the height of a Sprite object."),
_("the height"),
_("Size"),
"res/conditions/scaleHeight24_black.png",
"res/conditions/scaleHeight_black.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
obj.AddAction("SetSize",
_("Size"),
_("Change the size of an object."),
_("Change the size of _PARAM0_: set to _PARAM1_x_PARAM2_"),
_("Size"),
"res/actions/scale24_black.png",
"res/actions/scale_black.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Width"))
.AddParameter("expression", _("Height"))
.MarkAsAdvanced();
obj.AddCondition(
"Animation",
_("Current animation"),
@@ -283,10 +240,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"from 0 to 7. Otherwise, the direction is in degrees."),
_("the direction"),
_("Direction"),
"res/conditions/direction24_black.png",
"res/conditions/direction_black.png")
.SetHidden() // Hide as 8 direction is not supported officially in the
// interface.
"res/conditions/direction24.png",
"res/conditions/direction.png")
.SetHidden() // Hide as 8 direction is not supported officially in the interface.
.AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters("number");
@@ -324,19 +280,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/conditions/animation24.png",
"res/conditions/animation.png")
.AddParameter("object", _("Object"), "Sprite")
.MarkAsSimple()
.SetHidden();
obj.AddCondition("AnimationEnded2",
_("Animation finished"),
_("Check if the animation being played by the Sprite object "
"is finished."),
_("The animation of _PARAM0_ is finished"),
_("Animations and images"),
"res/conditions/animation24.png",
"res/conditions/animation.png")
.AddParameter("object", _("Object"), "Sprite")
.MarkAsSimple();
@@ -345,8 +288,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Compare the scale of the width of an object."),
_("the width's scale"),
_("Size"),
"res/conditions/scaleWidth24_black.png",
"res/conditions/scaleWidth_black.png")
"res/conditions/scaleWidth24.png",
"res/conditions/scaleWidth.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters("number")
@@ -357,8 +300,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Compare the scale of the height of an object."),
_("the height's scale"),
_("Size"),
"res/conditions/scaleHeight24_black.png",
"res/conditions/scaleHeight_black.png")
"res/conditions/scaleHeight24.png",
"res/conditions/scaleHeight.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters("number")
@@ -418,7 +361,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
obj.AddAction("FlipX",
_("Flip the object horizontally"),
_("Flip the object horizontally"),
_("Flip horizontally _PARAM0_: _PARAM1_"),
_("Flip horizontally _PARAM0_ : _PARAM1_"),
_("Effects"),
"res/actions/flipX24.png",
"res/actions/flipX.png")
@@ -430,7 +373,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
obj.AddAction("FlipY",
_("Flip the object vertically"),
_("Flip the object vertically"),
_("Flip vertically _PARAM0_: _PARAM1_"),
_("Flip vertically _PARAM0_ : _PARAM1_"),
_("Effects"),
"res/actions/flipY24.png",
"res/actions/flipY.png")
@@ -464,8 +407,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"Rotate an object towards another.",
"Rotate _PARAM0_ towards _PARAM1_",
_("Direction"),
"res/actions/rotate24_black.png",
"res/actions/rotate_black.png")
"res/actions/direction24.png",
"res/actions/direction.png")
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectPtr", "Rotate toward this object")
@@ -476,7 +419,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("X position of a point"),
_("X position of a point"),
_("Position"),
"res/actions/position_black.png")
"res/actions/position.png")
.SetHidden()
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectPointName", _("Name of the point"), "", true);
@@ -485,7 +428,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Y position of a point"),
_("Y position of a point"),
_("Position"),
"res/actions/position_black.png")
"res/actions/position.png")
.SetHidden()
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectPointName", _("Name of the point"), "", true);
@@ -494,7 +437,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("X position of a point"),
_("X position of a point"),
_("Position"),
"res/actions/position_black.png")
"res/actions/position.png")
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectPointName", _("Name of the point"));
@@ -503,7 +446,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Y position of a point"),
_("Y position of a point"),
_("Position"),
"res/actions/position_black.png")
"res/actions/position.png")
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectPointName", _("Name of the point"));
@@ -512,7 +455,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Direction"),
_("Direction of the object"),
_("Direction"),
"res/actions/direction_black.png")
"res/actions/direction.png")
.SetHidden()
.AddParameter("object", _("Object"), "Sprite");
@@ -520,9 +463,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Direction"),
_("Direction of the object"),
_("Direction"),
"res/actions/direction_black.png")
.SetHidden() // Hide as 8 direction is not supported officially in the
// interface.
"res/actions/direction.png")
.SetHidden() // Hide as 8 direction is not supported officially in the interface.
.AddParameter("object", _("Object"), "Sprite");
obj.AddExpression("Anim",
@@ -565,14 +507,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Scale of the width of an object"),
_("Scale of the width of an object"),
_("Size"),
"res/actions/scaleWidth_black.png")
"res/actions/scaleWidth.png")
.AddParameter("object", _("Object"), "Sprite");
obj.AddExpression("ScaleY",
_("Scale of the height of an object"),
_("Scale of the height of an object"),
_("Size"),
"res/actions/scaleHeight_black.png")
"res/actions/scaleHeight.png")
.AddParameter("object", _("Object"), "Sprite");
obj.AddExpression("Opacity",

View File

@@ -4,28 +4,29 @@
* reserved. This project is released under the MIT License.
*/
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
#include <algorithm>
#include "GDCore/CommonTools.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Animation.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Direction.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Sprite.h"
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
#include "GDCore/Project/InitialInstance.h"
#include "GDCore/Project/Layout.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Project/PropertyDescriptor.h"
#include "GDCore/Serialization/SerializerElement.h"
#include "GDCore/Tools/Localization.h"
#include <SFML/Graphics.hpp>
#include "GDCore/Project/PropertyDescriptor.h"
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
namespace gd {
Animation SpriteObject::badAnimation;
SpriteObject::SpriteObject() : updateIfNotVisible(false) {}
SpriteObject::SpriteObject(gd::String name_)
: Object(name_), updateIfNotVisible(false) {}
SpriteObject::~SpriteObject(){};
@@ -102,8 +103,7 @@ void SpriteObject::DoSerializeTo(gd::SerializerElement& element) const {
}
}
std::map<gd::String, gd::PropertyDescriptor> SpriteObject::GetProperties()
const {
std::map<gd::String, gd::PropertyDescriptor> SpriteObject::GetProperties() const {
std::map<gd::String, gd::PropertyDescriptor> properties;
properties[_("Animate even if hidden or far from the screen")]
.SetValue(updateIfNotVisible ? "true" : "false")
@@ -135,30 +135,22 @@ void SpriteObject::ExposeResources(gd::ArbitraryResourceWorker& worker) {
}
std::map<gd::String, gd::PropertyDescriptor>
SpriteObject::GetInitialInstanceProperties(
const gd::InitialInstance& initialInstance,
gd::Project& project,
gd::Layout& scene) {
SpriteObject::GetInitialInstanceProperties(const gd::InitialInstance& position,
gd::Project& project,
gd::Layout& scene) {
std::map<gd::String, gd::PropertyDescriptor> properties;
properties["animation"] =
gd::PropertyDescriptor(
gd::String::From(initialInstance.GetRawDoubleProperty("animation")))
.SetLabel(_("Animation"))
.SetType("number");
properties[_("Animation")] = gd::String::From(position.GetRawDoubleProperty("animation"));
return properties;
}
bool SpriteObject::UpdateInitialInstanceProperty(
gd::InitialInstance& initialInstance,
const gd::String& name,
const gd::String& value,
gd::Project& project,
gd::Layout& scene) {
if (name == "animation") {
initialInstance.SetRawDoubleProperty(
"animation", std::max(0, value.empty() ? 0 : value.To<int>()));
}
bool SpriteObject::UpdateInitialInstanceProperty(gd::InitialInstance& position,
const gd::String& name,
const gd::String& value,
gd::Project& project,
gd::Layout& scene) {
if (name == _("Animation"))
position.SetRawDoubleProperty("animation", value.To<int>());
return true;
}

View File

@@ -36,11 +36,11 @@ namespace gd {
* \see gd::BuiltinExtensionsImplementer::ImplementsSpriteExtension
* \ingroup SpriteObjectExtension
*/
class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
class GD_CORE_API SpriteObject : public gd::Object {
public:
SpriteObject();
SpriteObject(gd::String name_);
virtual ~SpriteObject();
std::unique_ptr<gd::ObjectConfiguration> Clone() const override {
std::unique_ptr<gd::Object> Clone() const override {
return gd::make_unique<SpriteObject>(*this);
}

View File

@@ -20,21 +20,19 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("" /*TODO: Add a documentation page for this */);
extension.AddInstructionOrExpressionGroupMetadata(_("Text manipulation"))
.SetIcon("res/actions/text24_black.png");
extension.AddStrExpression("NewLine",
_("Insert a new line"),
_("Insert a new line"),
"",
"res/conditions/toujours24_black.png");
_("Manipulation of text"),
"res/conditions/toujours24.png");
extension
.AddStrExpression("FromCodePoint",
_("Get character from code point"),
_("Get character from code point"),
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("expression", _("Code point"));
@@ -42,8 +40,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
.AddStrExpression("ToUpperCase",
_("Uppercase a text"),
_("Uppercase a text"),
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"));
@@ -51,8 +49,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
.AddStrExpression("ToLowerCase",
_("Lowercase a text"),
_("Lowercase a text"),
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"));
@@ -60,8 +58,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
.AddStrExpression("SubStr",
_("Get a portion of a text"),
_("Get a portion of a text"),
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter("expression",
@@ -73,8 +71,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
.AddStrExpression("StrAt",
_("Get a character from a text"),
_("Get a character from a text"),
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter(
@@ -85,8 +83,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
.AddStrExpression("StrRepeat",
_("Repeat a text"),
_("Repeat a text"),
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text to repeat"))
.AddParameter("expression", _("Repetition count"));
@@ -95,8 +93,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
.AddExpression("StrLength",
_("Length of a text"),
_("Length of a text"),
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"));
@@ -105,8 +103,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
_("Search in a text"),
_("Search in a text (return the position of the result or "
"-1 if not found)"),
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for"));
@@ -116,8 +114,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
"Search in a text from the end",
"Search in a text from the end (return the position of "
"the result or -1 if not found)",
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for"))
@@ -130,8 +128,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
_("Search the last occurence in a string (return the position of "
"the result, from the beginning of the string, or -1 if not "
"found)"),
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for"));
@@ -141,8 +139,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
_("Search in a text, starting from a position"),
_("Search in a text, starting from a position (return the "
"position of the result or -1 if not found)"),
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for"))
@@ -156,8 +154,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
"Search in a text from the end, starting from a position",
"Search in a text from the end, starting from a position (return "
"the position of the result or -1 if not found)",
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for"))
@@ -174,8 +172,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
"(return "
" the position of the result, from the beginning of the string, or "
"-1 if not found)"),
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for"))

View File

@@ -14,54 +14,33 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
extension
.SetExtensionInformation(
"BuiltinTime",
_("Timers and time"),
_("Time"),
"Actions and conditions to run timers, get the current time or "
"modify the time scale (speed at which the game is running - useful "
"for slow motion effects).",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/timers-and-time");
extension.AddInstructionOrExpressionGroupMetadata(_("Timers and time"))
.SetIcon("res/conditions/timer24.png");
.SetExtensionHelpPath("/all-features/timers");
// Deprecated and replaced by CompareTimer
extension
.AddCondition("Timer",
_("Value of a scene timer"),
_("Test the elapsed time of a scene timer."),
_("The timer _PARAM2_ is greater than _PARAM1_ seconds"),
"",
_("Timers and time"),
"res/conditions/timer24.png",
"res/conditions/timer.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Time in seconds"))
.AddParameter("identifier", _("Timer's name"), "sceneTimer")
.SetHidden();
extension
.AddCondition("CompareTimer",
_("Value of a scene timer"),
_("Compare the elapsed time of a scene timer. This "
"condition doesn't start the timer."),
_("The timer _PARAM1_ _PARAM2_ _PARAM3_ seconds"),
"",
"res/conditions/timer24.png",
"res/conditions/timer.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("identifier", _("Timer's name"), "sceneTimer")
.AddParameter("relationalOperator", _("Sign of the test"), "time")
.AddParameter("expression", _("Time in seconds"))
.SetManipulatedType("number");
.AddParameter("string", _("Timer's name"));
extension
.AddCondition("TimeScale",
_("Time scale"),
_("Compare the time scale of the scene."),
_("the time scale of the scene"),
"",
_("Timers and time"),
"res/conditions/time24.png",
"res/conditions/time.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -73,12 +52,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
_("Scene timer paused"),
_("Test if the specified scene timer is paused."),
_("The timer _PARAM1_ is paused"),
"",
_("Timers and time"),
"res/conditions/timerPaused24.png",
"res/conditions/timerPaused.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("identifier", _("Timer's name"), "sceneTimer")
.AddParameter("string", _("Timer's name"))
.MarkAsAdvanced();
extension
@@ -87,25 +65,23 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
_("Start (or reset) a scene timer"),
_("Reset the specified scene timer, if the timer doesn't exist "
"it's created and started."),
_("Start (or reset) the timer _PARAM1_"),
"",
_("Reset the timer _PARAM1_"),
_("Timers and time"),
"res/actions/timer24.png",
"res/actions/timer.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("identifier", _("Timer's name"), "sceneTimer");
.AddParameter("string", _("Timer's name"));
extension
.AddAction("PauseTimer",
_("Pause a scene timer"),
_("Pause a scene timer."),
_("Pause timer _PARAM1_"),
"",
_("Timers and time"),
"res/actions/pauseTimer24.png",
"res/actions/pauseTimer.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("identifier", _("Timer's name"), "sceneTimer")
.AddParameter("string", _("Timer's name"))
.MarkAsAdvanced();
extension
@@ -113,12 +89,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
_("Unpause a scene timer"),
_("Unpause a scene timer."),
_("Unpause timer _PARAM1_"),
"",
_("Timers and time"),
"res/actions/unPauseTimer24.png",
"res/actions/unPauseTimer.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("identifier", _("Timer's name"), "sceneTimer")
.AddParameter("string", _("Timer's name"))
.MarkAsAdvanced();
extension
@@ -126,43 +101,30 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
_("Delete a scene timer"),
_("Delete a scene timer from memory."),
_("Delete timer _PARAM1_ from memory"),
"",
_("Timers and time"),
"res/actions/timer24.png",
"res/actions/timer.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("identifier", _("Timer's name"), "sceneTimer")
.AddParameter("string", _("Timer's name"))
.MarkAsAdvanced();
extension
.AddAction("ChangeTimeScale",
_("Time scale"),
_("Change time scale"),
_("Change the time scale of the scene."),
_("Set the time scale of the scene to _PARAM1_"),
"",
_("Timers and time"),
"res/actions/time24.png",
"res/actions/time.png")
.AddCodeOnlyParameter("currentScene", "")
.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_black.svg",
"res/timer_black.svg")
.AddParameter("expression", "Time to wait in seconds")
.SetHelpPath("/all-features/timers-and-time/wait-action");
extension
.AddExpression("TimeDelta",
_("Time elapsed since the last frame"),
_("Time elapsed since the last frame rendered on screen"),
"",
_("Time"),
"res/actions/time.png")
.AddCodeOnlyParameter("currentScene", "");
@@ -170,7 +132,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
.AddExpression("TempsFrame",
_("Time elapsed since the last frame"),
_("Time elapsed since the last frame rendered on screen"),
"",
_("Time"),
"res/actions/time.png")
.SetHidden()
.AddCodeOnlyParameter("currentScene", "");
@@ -179,7 +141,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
.AddExpression("ElapsedTime",
_("Time elapsed since the last frame"),
_("Time elapsed since the last frame rendered on screen"),
"",
_("Time"),
"res/actions/time.png")
.SetHidden()
.AddCodeOnlyParameter("currentScene", "");
@@ -188,16 +150,16 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
.AddExpression("TimerElapsedTime",
_("Scene timer value"),
_("Value of a scene timer"),
"",
_("Time"),
"res/actions/time.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("identifier", _("Timer's name"), "sceneTimer");
.AddParameter("string", _("Timer's name"));
extension
.AddExpression("TimeFromStart",
_("Time elapsed since the beginning of the scene"),
_("Time elapsed since the beginning of the scene"),
"",
_("Time"),
"res/actions/time.png")
.AddCodeOnlyParameter("currentScene", "");
@@ -205,7 +167,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
.AddExpression("TempsDebut",
_("Time elapsed since the beginning of the scene"),
_("Time elapsed since the beginning of the scene"),
"",
_("Time"),
"res/actions/time.png")
.SetHidden()
.AddCodeOnlyParameter("currentScene", "");
@@ -214,7 +176,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
.AddExpression("TimeScale",
_("Time scale"),
_("Returns the time scale of the scene."),
"",
_("Time"),
"res/actions/time.png")
.AddCodeOnlyParameter("currentScene", "");
@@ -222,7 +184,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
.AddExpression("Time",
_("Current time"),
_("Current time"),
"",
_("Time"),
"res/actions/time.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter(
@@ -233,6 +195,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
"timestamp\""),
"[\"hour\", \"min\", \"sec\", \"mon\", \"year\", \"wday\", \"mday\", "
"\"yday\", \"timestamp\"]");
}
} // namespace gd

View File

@@ -14,7 +14,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
extension
.SetExtensionInformation(
"BuiltinVariables",
_("Variables"),
_("Variable features"),
"Actions, conditions and expressions to handle variables, from "
"simple variables like the player score, the number of remaining "
"lives to complex variables containing arbitrary data like an "
@@ -22,15 +22,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/variables");
extension.AddInstructionOrExpressionGroupMetadata(_("Variables"))
.SetIcon("res/conditions/var24.png");
extension
.AddCondition("VarScene",
_("Value of a scene variable"),
_("Compare the value of a scene variable."),
_("the scene variable _PARAM0_"),
_("Scene variables"),
_("Variables/Scene variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
@@ -41,7 +39,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Text of a scene variable"),
_("Compare the text of a scene variable."),
_("the text of scene variable _PARAM0_"),
_("Scene variables"),
_("Variables/Scene variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
@@ -53,7 +51,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Boolean value of a scene variable"),
_("Compare the boolean value of a scene variable."),
_("The boolean value of scene variable _PARAM0_ is _PARAM1_"),
_("Scene variables"),
_("Variables/Scene variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
@@ -66,7 +64,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Child existence"),
_("Check if the specified child of the scene variable exists."),
_("Child _PARAM1_ of scene variable _PARAM0_ exists"),
_("Scene variables/Collections/Structures"),
_("Variables/Scene variables/Collections/Structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
@@ -79,7 +77,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Check if the specified child of the global "
"variable exists."),
_("Child _PARAM1_ of global variable _PARAM0_ exists"),
_("Global variables/Collections/Structures"),
_("Variables/Global variables/Collections/Structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
@@ -91,7 +89,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"Test if a scene variable is defined",
"Test if the scene variable exists.",
"Scene variable _PARAM0_ is defined",
_("Scene variables"),
_("Variables/Scene variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -103,7 +101,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Value of a global variable"),
_("Compare the value of a global variable."),
_("the global variable _PARAM0_"),
_("Global variables"),
_("Variables/Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
@@ -115,7 +113,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Text of a global variable"),
_("Compare the text of a global variable."),
_("the text of the global variable _PARAM0_"),
_("Global variables"),
_("Variables/Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
@@ -128,7 +126,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Boolean value of a global variable"),
_("Compare the boolean value of a global variable."),
_("The boolean value of global variable _PARAM0_ is _PARAM1_"),
_("Global variables"),
_("Variables/Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
@@ -140,7 +138,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"Test if a global variable is defined",
"Test if a global variable exists",
"Global variable _PARAM0_ is defined",
_("Global variables"),
_("Variables/Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -153,7 +151,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Value of a scene variable"),
_("Change the value of a scene variable."),
_("the scene variable _PARAM0_"),
_("Scene variables"),
_("Variables/Scene variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
@@ -164,7 +162,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("String of a scene variable"),
_("Modify the text of a scene variable."),
_("the text of scene variable _PARAM0_"),
_("Scene variables"),
_("Variables/Scene variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
@@ -176,7 +174,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Boolean value of a scene variable"),
_("Modify the boolean value of a scene variable."),
_("Set the boolean value of scene variable _PARAM0_ to _PARAM1_"),
_("Scene variables"),
_("Variables/Scene variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
@@ -189,7 +187,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("If it was true, it will become false, and if it was "
"false it will become true."),
_("Toggle the boolean value of scene variable _PARAM0_"),
_("Scene variables"),
_("Variables/Scene variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"));
@@ -199,7 +197,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Value of a global variable"),
_("Change the value of a global variable"),
_("the global variable _PARAM0_"),
_("Global variables"),
_("Variables/Global variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"))
@@ -211,7 +209,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("String of a global variable"),
_("Modify the text of a global variable."),
_("the text of global variable _PARAM0_"),
_("Global variables"),
_("Variables/Global variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"))
@@ -224,7 +222,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Boolean value of a global variable"),
_("Modify the boolean value of a global variable."),
_("Set the boolean value of global variable _PARAM0_ to _PARAM1_"),
_("Global variables"),
_("Variables/Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
@@ -237,7 +235,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("If it was true, it will become false, and if it was "
"false it will become true."),
_("Toggle the boolean value of global variable _PARAM0_"),
_("Global variables"),
_("Variables/Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"));
@@ -247,7 +245,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Remove a child"),
_("Remove a child from a scene variable."),
_("Remove child _PARAM1_ from scene variable _PARAM0_"),
_("Scene variables/Collections/Structures"),
_("Variables/Scene variables/Collections/Structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
@@ -259,7 +257,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Remove a child"),
_("Remove a child from a global variable."),
_("Remove child _PARAM1_ from global variable _PARAM0_"),
_("Global variables/Collections/Structures"),
_("Variables/Global variables/Collections/Structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"))
@@ -271,7 +269,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Clear scene variable"),
_("Remove all the children from the scene variable."),
_("Clear children from scene variable _PARAM0_"),
_("Scene variables/Collections"),
_("Variables/Scene variables/Collections"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
@@ -282,7 +280,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Clear global variable"),
_("Remove all the children from the global variable."),
_("Clear children from global variable _PARAM0_"),
_("Global variables/Collections"),
_("Variables/Global variables/Collections"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"))
@@ -293,7 +291,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Append variable to a scene array"),
_("Appends a variable at the end of a scene array variable."),
_("Append variable _PARAM1_ to array variable _PARAM0_"),
_("Scene variables/Collections/Arrays"),
_("Variables/Scene variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
@@ -306,7 +304,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Append a string to a scene array"),
_("Appends a string at the end of a scene array variable."),
_("Append string _PARAM1_ to array variable _PARAM0_"),
_("Scene variables/Collections/Arrays"),
_("Variables/Scene variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
@@ -318,7 +316,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Append a number to a scene array"),
_("Appends a number at the end of a scene array variable."),
_("Append number _PARAM1_ to array variable _PARAM0_"),
_("Scene variables/Collections/Arrays"),
_("Variables/Scene variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
@@ -330,7 +328,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Append a boolean to a scene array"),
_("Appends a boolean at the end of a scene array variable."),
_("Append boolean _PARAM1_ to array variable _PARAM0_"),
_("Scene variables/Collections/Arrays"),
_("Variables/Scene variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
@@ -343,7 +341,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Remove variable from a scene array (by index)"),
_("Removes a variable at the specified index of a scene array variable."),
_("Remove variable at index _PARAM1_ from scene array variable _PARAM0_"),
_("Scene variables/Collections/Arrays"),
_("Variables/Scene variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
@@ -355,7 +353,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Append variable to a global array"),
_("Appends a variable at the end of a global array variable."),
_("Append variable _PARAM1_ to array variable _PARAM0_"),
_("Global variables/Collections/Arrays"),
_("Variables/Global variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
@@ -369,7 +367,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Remove variable from a global array (by index)"),
_("Removes a variable at the specified index of a global array variable."),
_("Remove variable at index _PARAM1_ from global array variable _PARAM0_"),
_("Global variables/Collections/Arrays"),
_("Variables/Global variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"))
@@ -381,7 +379,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Append a string to a global array"),
_("Appends a string at the end of a global array variable."),
_("Append string _PARAM1_ to array variable _PARAM0_"),
_("Global variables/Collections/Arrays"),
_("Variables/Global variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
@@ -393,7 +391,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Append a number to a global array"),
_("Appends a number at the end of a global array variable."),
_("Append number _PARAM1_ to array variable _PARAM0_"),
_("Global variables/Collections/Arrays"),
_("Variables/Global variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
@@ -405,7 +403,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Append a boolean to a global array"),
_("Appends a boolean at the end of a global array variable."),
_("Append boolean _PARAM1_ to array variable _PARAM0_"),
_("Global variables/Collections/Arrays"),
_("Variables/Global variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
@@ -416,7 +414,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.AddExpression("GlobalVariableChildCount",
_("Number of children of a global variable"),
_("Number of children of a global variable"),
_("Global variables"),
_("Variables/Global variables"),
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"));
@@ -424,7 +422,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.AddExpression("VariableChildCount",
_("Number of children of a scene variable"),
_("Number of children of a scene variable"),
_("Scene variables"),
_("Variables/Scene variables"),
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"));
@@ -432,7 +430,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.AddExpression("Variable",
_("Value of a scene variable"),
_("Value of a scene variable"),
_("Scene variables"),
_("Variables/Scene variables"),
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"));
@@ -440,7 +438,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.AddStrExpression("VariableString",
_("Text of a scene variable"),
_("Text of a scene variable"),
_("Scene variables"),
_("Variables/Scene variables"),
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"));
@@ -448,7 +446,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.AddExpression("GlobalVariable",
_("Value of a global variable"),
_("Value of a global variable"),
_("Global variables"),
_("Variables/Global variables"),
"res/actions/var.png")
.AddParameter("globalvar", _("Name of the global variable"));
@@ -456,7 +454,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.AddStrExpression("GlobalVariableString",
_("Text of a global variable"),
_("Text of a global variable"),
_("Global variables"),
_("Variables/Global variables"),
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"));
}

View File

@@ -14,18 +14,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
extension
.SetExtensionInformation(
"BuiltinWindow",
_("Game window and resolution"),
_("Window features"),
"Provides actions and conditions to manipulate the game window. "
"Depending on the platform on which the game is running, not all of "
"these features can be applied.",
"Florian Rival",
"Open source (MIT License)")
.SetCategory("User interface")
.SetExtensionHelpPath("/all-features/window");
extension
.AddInstructionOrExpressionGroupMetadata(
_("Game window and resolution"))
.SetIcon("res/actions/window24.png");
extension
.AddAction(
@@ -33,7 +28,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
_("De/activate fullscreen"),
_("This action activates or deactivates fullscreen."),
_("Activate fullscreen: _PARAM1_ (keep aspect ratio: _PARAM2_)"),
"",
_("Game's window and resolution"),
"res/actions/fullscreen24.png",
"res/actions/fullscreen.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -49,19 +44,19 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
_("Fullscreen activated?"),
_("Check if the game is currently in fullscreen."),
_("The game is in fullscreen"),
"",
_("Game's window and resolution"),
"res/actions/fullscreen24.png",
"res/actions/fullscreen.png")
.AddCodeOnlyParameter("currentScene", "");
extension
.AddAction("SetWindowMargins",
_("Window's margins"),
_("Change the window's margins"),
_("This action changes the margins, in pixels, between the "
"game frame and the window borders."),
_("Set margins of game window to "
"_PARAM1_;_PARAM2_;_PARAM3_;_PARAM4_"),
"",
_("Game's window and resolution"),
"res/actions/window24.png",
"res/actions/window.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -72,12 +67,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
extension
.AddAction("SetGameResolutionSize",
_("Game resolution"),
_("Change the resolution of the game"),
_("Changes the resolution of the game, effectively changing "
"the game area size. This won't change the size of the "
"window in which the game is running."),
_("Set game resolution to _PARAM1_x_PARAM2_"),
"",
_("Game's window and resolution"),
"res/actions/window24.png",
"res/actions/window.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -94,7 +89,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
"window size. Game resolution can still be updated."),
_("Set game window size to _PARAM1_x_PARAM2_ (also update game "
"resolution: _PARAM3_)"),
"",
_("Game's window and resolution"),
"res/actions/window24.png",
"res/actions/window.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -111,19 +106,19 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
"only works on Windows, macOS and Linux (not when the game "
"is executed in a web-browser or on iOS/Android)."),
_("Center the game window"),
"",
_("Game's window and resolution"),
"res/actions/window24.png",
"res/actions/window.png")
.AddCodeOnlyParameter("currentScene", "");
extension
.AddAction("SetGameResolutionResizeMode",
_("Game resolution resize mode"),
_("Change the game resolution resize mode"),
_("Set if the width or the height of the game resolution "
"should be changed to fit the game window - or if the game "
"resolution should not be updated automatically."),
_("Set game resolution resize mode to _PARAM1_"),
"",
_("Game's window and resolution"),
"res/actions/window24.png",
"res/actions/window.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -144,7 +139,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
"be the case if the game resolution resize mode is "
"configured to adapt the width or the height of the game."),
_("Automatically adapt the game resolution: _PARAM1_"),
"",
_("Game's window and resolution"),
"res/actions/window24.png",
"res/actions/window.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -154,10 +149,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
extension
.AddAction("SetWindowIcon",
_("Window's icon"),
_("Change the window's icon"),
_("This action changes the icon of the game's window."),
_("Use _PARAM1_ as the icon for the game's window."),
"",
_("Game's window and resolution"),
"res/actions/window24.png",
"res/actions/window.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -165,10 +160,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
extension
.AddAction("SetWindowTitle",
_("Window's title"),
_("Change the window's title"),
_("This action changes the title of the game's window."),
_("Change window title to _PARAM1_"),
"",
_("Game's window and resolution"),
"res/actions/window24.png",
"res/actions/window.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -179,7 +174,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
"SceneWindowWidth",
_("Width of the scene window"),
_("Width of the scene window (or scene canvas for HTML5 games)"),
"",
_("Screen"),
"res/window.png")
.AddCodeOnlyParameter("currentScene", "");
@@ -188,7 +183,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
"SceneWindowHeight",
_("Height of the scene window"),
_("Height of the scene window (or scene canvas for HTML5 games)"),
"",
_("Screen"),
"res/window.png")
.AddCodeOnlyParameter("currentScene", "");
@@ -196,27 +191,27 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
"ScreenWidth",
_("Width of the screen/page"),
_("Width of the screen (or the page for HTML5 games in browser)"),
"",
_("Screen"),
"res/display16.png");
extension.AddExpression(
"ScreenHeight",
_("Height of the screen/page"),
_("Height of the screen (or the page for HTML5 games in browser)"),
"",
_("Screen"),
"res/display16.png");
extension.AddExpression("ColorDepth",
_("Color depth"),
_("Color depth"),
"",
_("Screen"),
"res/display16.png");
extension
.AddStrExpression("WindowTitle",
_("Window's title"),
_("Window's title"),
"",
_("Screen"),
"res/window.png")
.AddCodeOnlyParameter("currentScene", "");
}

View File

@@ -14,14 +14,12 @@
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/BehaviorsSharedData.h"
#include "GDCore/Tools/Localization.h"
#include "GDCore/Tools/MakeUnique.h"
#include "GDCore/Tools/Log.h"
namespace gd {
BehaviorMetadata::BehaviorMetadata(
const gd::String& extensionNamespace_,
const gd::String& nameWithNamespace,
const gd::String& name_,
const gd::String& fullname_,
const gd::String& defaultName_,
const gd::String& description_,
@@ -31,50 +29,21 @@ BehaviorMetadata::BehaviorMetadata(
std::shared_ptr<gd::Behavior> instance_,
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance_)
: extensionNamespace(extensionNamespace_),
className(className_),
iconFilename(icon24x24),
instance(instance_),
sharedDatasInstance(sharedDatasInstance_),
isEventBased(false) {
sharedDatasInstance(sharedDatasInstance_) {
#if defined(GD_IDE_ONLY)
SetFullName(gd::String(fullname_));
SetDescription(gd::String(description_));
SetDefaultName(gd::String(defaultName_));
SetGroup(group_);
className = className_;
iconFilename = icon24x24;
#endif
if (!instance) {
gd::LogFatalError(
"Trying to create a BehaviorMetadata that has no "
"behavior. This will crash - please double check that the "
"BehaviorMetadata is valid for: " + nameWithNamespace);
}
if (instance) instance->SetTypeName(nameWithNamespace);
if (sharedDatasInstance) sharedDatasInstance->SetTypeName(nameWithNamespace);
if (instance) instance->SetTypeName(name_);
if (sharedDatasInstance) sharedDatasInstance->SetTypeName(name_);
}
BehaviorMetadata::BehaviorMetadata(
const gd::String& extensionNamespace,
const gd::String& nameWithNamespace,
const gd::String& fullname_,
const gd::String& defaultName_,
const gd::String& description_,
const gd::String& group_,
const gd::String& icon24x24_): BehaviorMetadata(
extensionNamespace,
nameWithNamespace,
fullname_,
defaultName_,
description_,
group_,
icon24x24_,
// Class name is the name, actually unused
defaultName_,
// It is only used to get the name for GetName.
gd::make_unique<gd::Behavior>("", nameWithNamespace),
nullptr){
isEventBased = true;
};
gd::InstructionMetadata& BehaviorMetadata::AddCondition(
const gd::String& name,
const gd::String& fullname,
@@ -83,6 +52,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddCondition(
const gd::String& group,
const gd::String& icon,
const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
gd::String nameWithNamespace =
extensionNamespace.empty() ? name : extensionNamespace + name;
conditionsInfos[nameWithNamespace] = InstructionMetadata(extensionNamespace,
@@ -96,6 +66,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddCondition(
.SetHelpPath(GetHelpPath())
.SetIsBehaviorInstruction();
return conditionsInfos[nameWithNamespace];
#endif
}
gd::InstructionMetadata& BehaviorMetadata::AddAction(
@@ -106,6 +77,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddAction(
const gd::String& group,
const gd::String& icon,
const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
gd::String nameWithNamespace =
extensionNamespace.empty() ? name : extensionNamespace + name;
actionsInfos[nameWithNamespace] = InstructionMetadata(extensionNamespace,
@@ -119,6 +91,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddAction(
.SetHelpPath(GetHelpPath())
.SetIsBehaviorInstruction();
return actionsInfos[nameWithNamespace];
#endif
}
gd::InstructionMetadata& BehaviorMetadata::AddScopedCondition(
@@ -129,6 +102,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddScopedCondition(
const gd::String& group,
const gd::String& icon,
const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
gd::String nameWithNamespace =
GetName() + gd::PlatformExtension::GetNamespaceSeparator() + name;
conditionsInfos[nameWithNamespace] = InstructionMetadata(extensionNamespace,
@@ -142,6 +116,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddScopedCondition(
.SetHelpPath(GetHelpPath())
.SetIsBehaviorInstruction();
return conditionsInfos[nameWithNamespace];
#endif
}
gd::InstructionMetadata& BehaviorMetadata::AddScopedAction(
@@ -152,6 +127,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddScopedAction(
const gd::String& group,
const gd::String& icon,
const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
gd::String nameWithNamespace =
GetName() + gd::PlatformExtension::GetNamespaceSeparator() + name;
actionsInfos[nameWithNamespace] = InstructionMetadata(extensionNamespace,
@@ -165,6 +141,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddScopedAction(
.SetHelpPath(GetHelpPath())
.SetIsBehaviorInstruction();
return actionsInfos[nameWithNamespace];
#endif
}
gd::ExpressionMetadata& BehaviorMetadata::AddExpression(
@@ -173,6 +150,7 @@ gd::ExpressionMetadata& BehaviorMetadata::AddExpression(
const gd::String& description,
const gd::String& group,
const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
// Be careful, behaviors expression do not have namespace (not necessary as
// we refer to the behavior name in the expression).
expressionsInfos[name] = ExpressionMetadata("number",
@@ -184,6 +162,7 @@ gd::ExpressionMetadata& BehaviorMetadata::AddExpression(
smallicon)
.SetHelpPath(GetHelpPath());
return expressionsInfos[name];
#endif
}
gd::ExpressionMetadata& BehaviorMetadata::AddStrExpression(
@@ -192,6 +171,7 @@ gd::ExpressionMetadata& BehaviorMetadata::AddStrExpression(
const gd::String& description,
const gd::String& group,
const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
// Be careful, behaviors expression do not have namespace (not necessary as
// we refer to the behavior name in the expression).
strExpressionsInfos[name] = ExpressionMetadata("string",
@@ -203,6 +183,7 @@ gd::ExpressionMetadata& BehaviorMetadata::AddStrExpression(
smallicon)
.SetHelpPath(GetHelpPath());
return strExpressionsInfos[name];
#endif
}
gd::MultipleInstructionMetadata BehaviorMetadata::AddExpressionAndCondition(
@@ -253,40 +234,6 @@ BehaviorMetadata::AddExpressionAndConditionAndAction(
const gd::String& sentenceName,
const gd::String& group,
const gd::String& icon) {
if (type != "number" && type != "string" && type != "boolean") {
gd::LogError(
"Unrecognised type passed to AddExpressionAndConditionAndAction: " +
type + ". Verify this type is valid and supported.");
}
gd::String conditionDescriptionTemplate =
type == "boolean" ? _("Check if <subject>.") : _("Compare <subject>.");
auto& condition =
AddScopedCondition(name,
fullname,
conditionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
gd::String actionDescriptionTemplate = type == "boolean"
? _("Set (or unset) if <subject>.")
: _("Change <subject>.");
auto& action = AddScopedAction(
"Set" + name,
fullname,
actionDescriptionTemplate.FindAndReplace("<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
if (type == "boolean") {
return MultipleInstructionMetadata::WithConditionAndAction(condition, action);
}
gd::String expressionDescriptionTemplate = _("Return <subject>.");
auto& expression =
type == "number"
@@ -303,10 +250,32 @@ BehaviorMetadata::AddExpressionAndConditionAndAction(
group,
icon);
gd::String conditionDescriptionTemplate = _("Compare <subject>.");
auto& condition =
AddScopedCondition(name,
fullname,
conditionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
gd::String actionDescriptionTemplate = _("Change <subject>.");
auto& action = AddScopedAction(
"Set" + name,
fullname,
actionDescriptionTemplate.FindAndReplace("<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
return MultipleInstructionMetadata::WithExpressionAndConditionAndAction(
expression, condition, action);
}
#if defined(GD_IDE_ONLY)
gd::InstructionMetadata& BehaviorMetadata::AddDuplicatedAction(
const gd::String& newActionName, const gd::String& copiedActionName) {
gd::String newNameWithNamespace = extensionNamespace + newActionName;
@@ -374,44 +343,49 @@ gd::ExpressionMetadata& BehaviorMetadata::AddDuplicatedStrExpression(
return strExpressionsInfos[newNameWithNamespace];
}
#endif
BehaviorMetadata& BehaviorMetadata::SetFullName(const gd::String& fullname_) {
#if defined(GD_IDE_ONLY)
fullname = fullname_;
#endif
return *this;
}
BehaviorMetadata& BehaviorMetadata::SetDefaultName(
const gd::String& defaultName_) {
#if defined(GD_IDE_ONLY)
defaultName = defaultName_;
#endif
return *this;
}
BehaviorMetadata& BehaviorMetadata::SetDescription(
const gd::String& description_) {
#if defined(GD_IDE_ONLY)
description = description_;
#endif
return *this;
}
BehaviorMetadata& BehaviorMetadata::SetGroup(const gd::String& group_) {
#if defined(GD_IDE_ONLY)
group = group_;
#endif
return *this;
}
BehaviorMetadata& BehaviorMetadata::SetIncludeFile(
const gd::String& includeFile) {
#if defined(GD_IDE_ONLY)
includeFiles.clear();
includeFiles.push_back(includeFile);
#endif
return *this;
}
BehaviorMetadata& BehaviorMetadata::AddIncludeFile(
const gd::String& includeFile) {
#if defined(GD_IDE_ONLY)
if (std::find(includeFiles.begin(), includeFiles.end(), includeFile) ==
includeFiles.end())
includeFiles.push_back(includeFile);
return *this;
}
BehaviorMetadata& BehaviorMetadata::AddRequiredFile(
const gd::String& requiredFile) {
if (std::find(requiredFiles.begin(), requiredFiles.end(), requiredFile) ==
requiredFiles.end())
requiredFiles.push_back(requiredFile);
#endif
return *this;
}
@@ -420,25 +394,13 @@ const gd::String& BehaviorMetadata::GetName() const {
}
gd::Behavior& BehaviorMetadata::Get() const {
if (isEventBased) {
gd::LogFatalError("Error: Event-based behaviors don't have blueprint. "
"This method should not never be called.");
}
if (!instance) {
if (!instance)
gd::LogFatalError(
"Trying to get a behavior from a BehaviorMetadata that has no "
"behavior. This will crash - please double check that the "
"BehaviorMetadata is valid for: " + className);
}
"BehaviorMetadata is valid.");
return *instance;
}
gd::BehaviorsSharedData* BehaviorMetadata::GetSharedDataInstance() const {
if (isEventBased) {
gd::LogFatalError("Error: Event-based behaviors don't have blueprint. "
"This method should not never be called.");
}
return sharedDatasInstance.get();
}
} // namespace gd

View File

@@ -29,7 +29,7 @@ class GD_CORE_API BehaviorMetadata {
public:
BehaviorMetadata(
const gd::String& extensionNamespace,
const gd::String& nameWithNamespace,
const gd::String& name_,
const gd::String& fullname_,
const gd::String& defaultName_,
const gd::String& description_,
@@ -38,21 +38,6 @@ class GD_CORE_API BehaviorMetadata {
const gd::String& className_,
std::shared_ptr<gd::Behavior> instance,
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance);
/**
* \brief Construct a behavior metadata, without "blueprint" behavior.
*
* \note This is used by events based behaviors.
*/
BehaviorMetadata(
const gd::String& extensionNamespace,
const gd::String& nameWithNamespace,
const gd::String& fullname_,
const gd::String& defaultName_,
const gd::String& description_,
const gd::String& group_,
const gd::String& icon24x24_);
BehaviorMetadata(){};
virtual ~BehaviorMetadata(){};
@@ -210,13 +195,6 @@ class GD_CORE_API BehaviorMetadata {
*/
BehaviorMetadata& AddIncludeFile(const gd::String& includeFile);
/**
* \brief Add a file to the already existing required files.
* \note These files are required for the behavior to work,
* but they are not executable.
*/
BehaviorMetadata& AddRequiredFile(const gd::String& requiredFile);
/**
* Get the help path of the behavior, relative to the GDevelop documentation
* root.
@@ -236,6 +214,7 @@ class GD_CORE_API BehaviorMetadata {
}
const gd::String& GetName() const;
#if defined(GD_IDE_ONLY)
const gd::String& GetFullName() const { return fullname; }
const gd::String& GetDefaultName() const { return defaultName; }
const gd::String& GetDescription() const { return description; }
@@ -256,84 +235,45 @@ class GD_CORE_API BehaviorMetadata {
* \note An empty string means the base object, so any object.
*/
const gd::String& GetObjectType() const { return objectType; }
/**
* Check if the behavior is private - it can't be used outside of its
* extension.
*/
bool IsPrivate() const { return isPrivate; }
/**
* Set that the behavior is private - it can't be used outside of its
* extension.
*/
BehaviorMetadata &SetPrivate() {
isPrivate = true;
return *this;
}
#endif
/**
* \brief Return the associated gd::Behavior, handling behavior contents.
*
* \note Returns a dumb Behavior for events based behaviors as CustomBehavior
* are using EventBasedBehavior.
*/
gd::Behavior& Get() const;
/**
* \brief Return the associated gd::BehaviorsSharedData, handling behavior
* shared data, if any (nullptr if none).
*
* \note Returns nullptr for events based behaviors as they don't declare
* shared data yet.
*/
gd::BehaviorsSharedData* GetSharedDataInstance() const;
/**
* \brief Return a reference to a map containing the names of the actions
* (as keys) and the metadata associated with (as values).
*/
std::map<gd::String, gd::InstructionMetadata>& GetAllActions() { return actionsInfos; };
/**
* \see gd::PlatformExtension::GetAllActions
*/
std::map<gd::String, gd::InstructionMetadata>& GetAllConditions() { return conditionsInfos; };
/**
* \see gd::PlatformExtension::GetAllActions
*/
std::map<gd::String, gd::ExpressionMetadata>& GetAllExpressions() { return expressionsInfos; };
/**
* \see gd::PlatformExtension::GetAllActions
*/
std::map<gd::String, gd::ExpressionMetadata>& GetAllStrExpressions() { return strExpressionsInfos; };
gd::BehaviorsSharedData* GetSharedDataInstance() const {
return sharedDatasInstance.get();
}
#if defined(GD_IDE_ONLY)
std::map<gd::String, gd::InstructionMetadata> conditionsInfos;
std::map<gd::String, gd::InstructionMetadata> actionsInfos;
std::map<gd::String, gd::ExpressionMetadata> expressionsInfos;
std::map<gd::String, gd::ExpressionMetadata> strExpressionsInfos;
std::vector<gd::String> includeFiles;
std::vector<gd::String> requiredFiles;
gd::String className;
#endif
private:
gd::String extensionNamespace;
gd::String helpPath;
#if defined(GD_IDE_ONLY)
gd::String fullname;
gd::String defaultName;
gd::String description;
gd::String group;
gd::String iconFilename;
gd::String objectType;
bool isPrivate = false;
#endif
// TODO: Nitpicking: convert these to std::unique_ptr to clarify ownership.
std::shared_ptr<gd::Behavior> instance;
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance;
bool isEventBased;
};
} // namespace gd

View File

@@ -8,7 +8,6 @@
#include <functional>
#include <map>
#include <memory>
#include <algorithm>
#include "GDCore/Project/PropertyDescriptor.h"
#include "GDCore/String.h"

View File

@@ -37,24 +37,22 @@ gd::ExpressionMetadata& ExpressionMetadata::AddParameter(
const gd::String& supplementaryInformation,
bool parameterIsOptional) {
gd::ParameterMetadata info;
info.SetType(type);
info.type = type;
info.description = description;
info.codeOnly = false;
info.SetOptional(parameterIsOptional);
info.SetExtraInfo(
info.optional = parameterIsOptional;
info.supplementaryInformation =
// For objects/behavior, the supplementary information
// parameter is an object/behavior type...
((gd::ParameterMetadata::IsObject(type) ||
(gd::ParameterMetadata::IsObject(type) ||
gd::ParameterMetadata::IsBehavior(type))
// Prefix with the namespace if it's not already there.
&& !(supplementaryInformation.rfind(extensionNamespace, 0) == 0))
? (supplementaryInformation.empty()
? ""
: extensionNamespace +
supplementaryInformation //... so prefix it with the extension
// namespace.
)
: supplementaryInformation); // Otherwise don't change anything
: supplementaryInformation; // Otherwise don't change anything
// TODO: Assert against supplementaryInformation === "emsc" (when running with
// Emscripten), and warn about a missing argument when calling addParameter.
@@ -66,19 +64,12 @@ gd::ExpressionMetadata& ExpressionMetadata::AddParameter(
gd::ExpressionMetadata& ExpressionMetadata::AddCodeOnlyParameter(
const gd::String& type, const gd::String& supplementaryInformation) {
gd::ParameterMetadata info;
info.SetType(type);
info.type = type;
info.codeOnly = true;
info.SetExtraInfo(supplementaryInformation);
info.supplementaryInformation = supplementaryInformation;
parameters.push_back(info);
return *this;
}
gd::ExpressionMetadata& ExpressionMetadata::SetRequiresBaseObjectCapability(
const gd::String& capability) {
requiredBaseObjectCapability = capability;
return *this;
}
} // namespace gd

View File

@@ -222,35 +222,6 @@ class GD_CORE_API ExpressionMetadata {
return *this;
};
/**
* \brief Set the additional information, used for some parameters
* with special type (for example, it can contains the type of object accepted
* by the parameter), for the last added parameter.
*
* \see AddParameter
*/
ExpressionMetadata &SetParameterExtraInfo(const gd::String &extraInfo) {
if (!parameters.empty()) parameters.back().SetExtraInfo(extraInfo);
return *this;
}
/**
* \brief Mark this (object) expression as requiring the specified capability,
* offered by the base object.
* This is useful for some objects that don't support this capability, so that
* the editor can hide the expression as it does not apply to them.
*/
ExpressionMetadata& SetRequiresBaseObjectCapability(
const gd::String& capability);
/**
* \brief Get the required specified capability for this (object) expression,
* or an empty string if there is nothing specific required.
*/
const gd::String& GetRequiredBaseObjectCapability() const {
return requiredBaseObjectCapability;
};
/**
* \brief Set the function that should be called when generating the source
* code from events.
@@ -268,30 +239,7 @@ class GD_CORE_API ExpressionMetadata {
*/
ExpressionCodeGenerationInformation& GetCodeExtraInformation() {
return codeExtraInformation;
}
/**
* \brief Erase any existing include file and add the specified include.
*/
ExpressionMetadata &SetIncludeFile(const gd::String &includeFile) {
codeExtraInformation.SetIncludeFile(includeFile);
return *this;
}
/**
* \brief Add a file to the already existing include files.
*/
ExpressionMetadata &AddIncludeFile(const gd::String &includeFile) {
codeExtraInformation.AddIncludeFile(includeFile);
return *this;
}
/**
* \brief Get the files that must be included to use the instruction.
*/
const std::vector<gd::String>& GetIncludeFiles() const {
return codeExtraInformation.GetIncludeFiles();
}
};
ExpressionCodeGenerationInformation codeExtraInformation;
@@ -325,7 +273,6 @@ class GD_CORE_API ExpressionMetadata {
gd::String smallIconFilename;
gd::String extensionNamespace;
bool isPrivate;
gd::String requiredBaseObjectCapability;
};
} // namespace gd

View File

@@ -10,7 +10,6 @@
#include "GDCore/CommonTools.h"
#include "GDCore/Serialization/SerializerElement.h"
#include "GDCore/Tools/Localization.h"
#include "GDCore/Tools/Log.h"
#include "ParameterMetadata.h"
namespace gd {
@@ -55,25 +54,22 @@ InstructionMetadata& InstructionMetadata::AddParameter(
const gd::String& supplementaryInformation,
bool parameterIsOptional) {
ParameterMetadata info;
info.SetType(type);
info.type = type;
info.description = description;
info.codeOnly = false;
info.SetOptional(parameterIsOptional);
info.SetExtraInfo(
info.optional = parameterIsOptional;
info.supplementaryInformation =
// For objects/behavior, the supplementary information
// parameter is an object/behavior type...
((gd::ParameterMetadata::IsObject(type) ||
(gd::ParameterMetadata::IsObject(type) ||
gd::ParameterMetadata::IsBehavior(type))
// Prefix with the namespace if it's not already there.
&& !(supplementaryInformation.rfind(extensionNamespace, 0) == 0))
? (supplementaryInformation.empty()
? ""
: extensionNamespace +
supplementaryInformation //... so prefix it with the
// extension
// namespace.
supplementaryInformation //... so prefix it with the extension
// namespace.
)
: supplementaryInformation); // Otherwise don't change anything
: supplementaryInformation; // Otherwise don't change anything
// TODO: Assert against supplementaryInformation === "emsc" (when running with
// Emscripten), and warn about a missing argument when calling addParameter.
@@ -85,69 +81,44 @@ InstructionMetadata& InstructionMetadata::AddParameter(
InstructionMetadata& InstructionMetadata::AddCodeOnlyParameter(
const gd::String& type, const gd::String& supplementaryInformation) {
ParameterMetadata info;
info.SetType(type);
info.type = type;
info.codeOnly = true;
info.SetExtraInfo(supplementaryInformation);
info.supplementaryInformation = supplementaryInformation;
parameters.push_back(info);
return *this;
}
InstructionMetadata& InstructionMetadata::UseStandardOperatorParameters(
const gd::String& type, const gd::String& typeExtraInfo) {
const gd::String& expressionValueType =
gd::ValueTypeMetadata::GetPrimitiveValueType(type);
SetManipulatedType(expressionValueType);
const gd::String& type) {
SetManipulatedType(type);
if (type == "boolean") {
AddParameter("yesorno", _("New value"));
size_t valueParamIndex = parameters.size() - 1;
AddParameter("operator", _("Modification's sign"), type);
AddParameter(type == "number" ? "expression" : type, _("Value"));
size_t operatorParamIndex = parameters.size() - 2;
size_t valueParamIndex = parameters.size() - 1;
if (isObjectInstruction || isBehaviorInstruction) {
gd::String templateSentence = _("Set _PARAM0_ as <subject>: <value>");
if (isObjectInstruction || isBehaviorInstruction) {
gd::String templateSentence =
_("Change <subject> of _PARAM0_: <operator> <value>");
sentence =
templateSentence
.FindAndReplace("<subject>", sentence)
.FindAndReplace("<value>",
"_PARAM" + gd::String::From(valueParamIndex) + "_");
} else {
gd::String templateSentence = _("Change <subject>: <value>");
sentence =
templateSentence
.FindAndReplace("<subject>", sentence)
.FindAndReplace("<value>",
"_PARAM" + gd::String::From(valueParamIndex) + "_");
}
sentence =
templateSentence.FindAndReplace("<subject>", sentence)
.FindAndReplace(
"<operator>",
"_PARAM" + gd::String::From(operatorParamIndex) + "_")
.FindAndReplace("<value>",
"_PARAM" + gd::String::From(valueParamIndex) + "_");
} else {
AddParameter("operator", _("Modification's sign"), expressionValueType);
AddParameter(type, _("Value"), typeExtraInfo);
gd::String templateSentence = _("Change <subject>: <operator> <value>");
size_t operatorParamIndex = parameters.size() - 2;
size_t valueParamIndex = parameters.size() - 1;
if (isObjectInstruction || isBehaviorInstruction) {
gd::String templateSentence = _("Change <subject> of _PARAM0_: <operator> <value>");
sentence =
templateSentence.FindAndReplace("<subject>", sentence)
.FindAndReplace(
"<operator>",
"_PARAM" + gd::String::From(operatorParamIndex) + "_")
.FindAndReplace("<value>",
"_PARAM" + gd::String::From(valueParamIndex) + "_");
} else {
gd::String templateSentence = _("Change <subject>: <operator> <value>");
sentence =
templateSentence.FindAndReplace("<subject>", sentence)
.FindAndReplace(
"<operator>",
"_PARAM" + gd::String::From(operatorParamIndex) + "_")
.FindAndReplace("<value>",
"_PARAM" + gd::String::From(valueParamIndex) + "_");
}
sentence =
templateSentence.FindAndReplace("<subject>", sentence)
.FindAndReplace(
"<operator>",
"_PARAM" + gd::String::From(operatorParamIndex) + "_")
.FindAndReplace("<value>",
"_PARAM" + gd::String::From(valueParamIndex) + "_");
}
return *this;
@@ -155,67 +126,37 @@ InstructionMetadata& InstructionMetadata::UseStandardOperatorParameters(
InstructionMetadata&
InstructionMetadata::UseStandardRelationalOperatorParameters(
const gd::String& type, const gd::String& typeExtraInfo) {
const gd::String& expressionValueType =
gd::ValueTypeMetadata::GetPrimitiveValueType(type);
SetManipulatedType(expressionValueType);
const gd::String& type) {
SetManipulatedType(type);
if (type == "boolean") {
if (isObjectInstruction || isBehaviorInstruction) {
gd::String templateSentence = _("_PARAM0_ is <subject>");
AddParameter("relationalOperator", _("Sign of the test"), type);
AddParameter(type == "number" ? "expression" : type, _("Value to compare"));
size_t operatorParamIndex = parameters.size() - 2;
size_t valueParamIndex = parameters.size() - 1;
sentence =
templateSentence
.FindAndReplace("<subject>", sentence);
} else {
gd::String templateSentence = _("<subject>");
if (isObjectInstruction || isBehaviorInstruction) {
gd::String templateSentence = _("<subject> of _PARAM0_ <operator> <value>");
sentence =
templateSentence.FindAndReplace("<subject>", sentence);
}
sentence =
templateSentence.FindAndReplace("<subject>", sentence)
.FindAndReplace(
"<operator>",
"_PARAM" + gd::String::From(operatorParamIndex) + "_")
.FindAndReplace("<value>",
"_PARAM" + gd::String::From(valueParamIndex) + "_");
} else {
AddParameter("relationalOperator", _("Sign of the test"), expressionValueType);
AddParameter(type, _("Value to compare"), typeExtraInfo);
size_t operatorParamIndex = parameters.size() - 2;
size_t valueParamIndex = parameters.size() - 1;
gd::String templateSentence = _("<subject> <operator> <value>");
if (isObjectInstruction || isBehaviorInstruction) {
gd::String templateSentence = _("<subject> of _PARAM0_ <operator> <value>");
sentence =
templateSentence.FindAndReplace("<subject>", sentence)
.FindAndReplace(
"<operator>",
"_PARAM" + gd::String::From(operatorParamIndex) + "_")
.FindAndReplace("<value>",
"_PARAM" + gd::String::From(valueParamIndex) + "_");
} else {
gd::String templateSentence = _("<subject> <operator> <value>");
sentence =
templateSentence.FindAndReplace("<subject>", sentence)
.FindAndReplace(
"<operator>",
"_PARAM" + gd::String::From(operatorParamIndex) + "_")
.FindAndReplace("<value>",
"_PARAM" + gd::String::From(valueParamIndex) + "_");
}
sentence =
templateSentence.FindAndReplace("<subject>", sentence)
.FindAndReplace(
"<operator>",
"_PARAM" + gd::String::From(operatorParamIndex) + "_")
.FindAndReplace("<value>",
"_PARAM" + gd::String::From(valueParamIndex) + "_");
}
return *this;
}
InstructionMetadata& InstructionMetadata::SetRequiresBaseObjectCapability(
const gd::String& capability) {
if (!IsObjectInstruction() && !IsBehaviorInstruction()) {
gd::LogError("Tried to add capability \"" + capability +
"\" to instruction named \"" + fullname +
"\", which is not an object or behavior instruction.");
return *this;
}
requiredBaseObjectCapability = capability;
return *this;
}
} // namespace gd

View File

@@ -6,7 +6,6 @@
#ifndef INSTRUCTIONMETADATA_H
#define INSTRUCTIONMETADATA_H
#include <algorithm>
#include <functional>
#include <map>
#include <memory>
@@ -99,23 +98,6 @@ 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 !codeExtraInformation.asyncFunctionCallName.empty();
}
/**
* Check if the instruction asynchronicity is optional. If it is, it can either
* be used synchronously or asynchronously, with one function for each.
*/
bool IsOptionallyAsync() const {
return IsAsync() && !codeExtraInformation.functionCallName.empty();
}
/**
* Notify that the instruction can have sub instructions.
*/
@@ -156,19 +138,18 @@ class GD_CORE_API InstructionMetadata {
* \param description Description for parameter
* \param supplementaryInformation Additional information that can be used for
* rendering or logic. For example:
* - If type is "object", this argument will describe which objects are
* allowed. If this argument is empty, all objects are allowed.
* - If type is "operator", this argument will be used to display only
* pertinent operators. \param parameterIsOptional true if the parameter must
* be optional, false otherwise.
* - If type is "object", this argument will describe which objects are allowed.
* If this argument is empty, all objects are allowed.
* - If type is "operator", this argument will be used to display only pertinent operators.
* \param parameterIsOptional true if the parameter must be optional, false
* otherwise.
*
* \see EventsCodeGenerator::GenerateParametersCodes
*/
InstructionMetadata &AddParameter(
const gd::String &type,
const gd::String &label,
const gd::String &supplementaryInformation = "",
bool parameterIsOptional = false);
InstructionMetadata &AddParameter(const gd::String &type,
const gd::String &label,
const gd::String &supplementaryInformation = "",
bool parameterIsOptional = false);
/**
* \brief Add a parameter not displayed in editor.
@@ -206,7 +187,7 @@ class GD_CORE_API InstructionMetadata {
if (!parameters.empty())
parameters.back().SetLongDescription(longDescription);
return *this;
}
};
/**
* \brief Set the additional information, used for some parameters
@@ -216,28 +197,23 @@ class GD_CORE_API InstructionMetadata {
* \see AddParameter
*/
InstructionMetadata &SetParameterExtraInfo(const gd::String &extraInfo) {
if (!parameters.empty()) parameters.back().SetExtraInfo(extraInfo);
if (!parameters.empty())
parameters.back().SetExtraInfo(extraInfo);
return *this;
}
};
/**
* \brief Add the default parameters for an instruction manipulating the
* specified type ("string", "number") with the default operators.
*
* \note The type "string" can be declined in several subtypes.
* \see ParameterMetadata
*/
InstructionMetadata &UseStandardOperatorParameters(const gd::String &type, const gd::String& typeExtraInfo = "");
InstructionMetadata &UseStandardOperatorParameters(const gd::String &type);
/**
* \brief Add the default parameters for an instruction comparing the
* specified type ("string", "number") with the default relational operators.
*
* \note The type "string" can be declined in several subtypes.
* \see ParameterMetadata
*/
InstructionMetadata &UseStandardRelationalOperatorParameters(
const gd::String &type, const gd::String& typeExtraInfo = "");
const gd::String &type);
/**
* \brief Mark the instruction as an object instruction. Automatically called
@@ -260,28 +236,15 @@ class GD_CORE_API InstructionMetadata {
/**
* \brief Check if the instruction is an object instruction.
*/
bool IsObjectInstruction() const { return isObjectInstruction; }
bool IsObjectInstruction() const {
return isObjectInstruction;
}
/**
* \brief Check if the instruction is a behavior instruction.
*/
bool IsBehaviorInstruction() const { return isBehaviorInstruction; }
/**
* \brief Mark this (object) instruction as requiring the specified
* capability, offered by the base object. This is useful for some objects
* that don't support this capability, so that the editor can hide the
* instruction as it does not apply to them.
*/
InstructionMetadata &SetRequiresBaseObjectCapability(
const gd::String &capability);
/**
* \brief Get the required specified capability for this (object) instruction,
* or an empty string if there is nothing specific required.
*/
const gd::String &GetRequiredBaseObjectCapability() const {
return requiredBaseObjectCapability;
bool IsBehaviorInstruction() const {
return isBehaviorInstruction;
}
/**
@@ -325,26 +288,14 @@ class GD_CORE_API InstructionMetadata {
virtual ~ExtraInformation(){};
/**
* Set the name of the function which will be called in the generated code.
* \param functionName the name of the function to call.
* Set the function name which will be used when generating the code.
* \param functionName the name of the function to call
*/
ExtraInformation &SetFunctionName(const gd::String &functionName_) {
functionCallName = functionName_;
return *this;
}
/**
* Set the name of the function, doing asynchronous work, which will be called in
* the generated code. This function should return an asynchronous task
* (i.e: `gdjs.AsyncTask` in the JavaScript runtime).
*
* \param functionName the name of the function doing asynchronous work to call.
*/
ExtraInformation &SetAsyncFunctionName(const gd::String &functionName_) {
asyncFunctionCallName = functionName_;
return *this;
}
/**
* Declare if the instruction being declared is somewhat manipulating in a
* standard way.
@@ -367,12 +318,12 @@ class GD_CORE_API InstructionMetadata {
* _("the string"),
* _("Text"),
* "CppPlatform/Extensions/text24.png",
* "CppPlatform/Extensions/text_black.png");
* "CppPlatform/Extensions/text.png");
*
* .AddParameter("object", _("Object"), "Text", false)
* .AddParameter("operator", _("Modification operator"), "string")
* .AddParameter("string", _("String"))
* .SetFunctionName("SetString").SetManipulatedType("string").SetGetter("GetString");
* .SetFunctionName("SetString").SetManipulatedType("string").SetGetter("GetString").SetIncludeFile("MyExtension/TextObject.h");
*
* DECLARE_END_OBJECT_ACTION()
* \endcode
@@ -440,7 +391,6 @@ class GD_CORE_API InstructionMetadata {
bool HasCustomCodeGenerator() const { return hasCustomCodeGenerator; }
gd::String functionCallName;
gd::String asyncFunctionCallName;
gd::String type;
AccessType accessType;
gd::String optionalAssociatedInstruction;
@@ -473,49 +423,15 @@ class GD_CORE_API InstructionMetadata {
}
/**
* Set the name of the function which will be called in the generated code.
* \param functionName the name of the function to call.
* \brief Set the function that should be called when generating the source
* code from events.
* \param functionName the name of the function to call
* \note Shortcut for `codeExtraInformation.SetFunctionName`.
*/
ExtraInformation &SetFunctionName(const gd::String &functionName) {
return codeExtraInformation.SetFunctionName(functionName);
}
/**
* Set the name of the function, doing asynchronous work, which will be called in
* the generated code. This function should return an asynchronous task
* (i.e: `gdjs.AsyncTask` in the JavaScript runtime).
*
* \param functionName the name of the function doing asynchronous work to call.
* \note Shortcut for `codeExtraInformation.SetAsyncFunctionName`.
*/
ExtraInformation &SetAsyncFunctionName(const gd::String &functionName) {
return codeExtraInformation.SetAsyncFunctionName(functionName);
}
/**
* \brief Erase any existing include file and add the specified include.
*/
InstructionMetadata &SetIncludeFile(const gd::String &includeFile) {
codeExtraInformation.SetIncludeFile(includeFile);
return *this;
}
/**
* \brief Add a file to the already existing include files.
*/
InstructionMetadata &AddIncludeFile(const gd::String &includeFile) {
codeExtraInformation.AddIncludeFile(includeFile);
return *this;
}
/**
* \brief Get the files that must be included to use the instruction.
*/
const std::vector<gd::String>& GetIncludeFiles() const {
return codeExtraInformation.GetIncludeFiles();
};
std::vector<ParameterMetadata> parameters;
private:
@@ -534,7 +450,6 @@ class GD_CORE_API InstructionMetadata {
bool isPrivate;
bool isObjectInstruction;
bool isBehaviorInstruction;
gd::String requiredBaseObjectCapability;
};
} // namespace gd

View File

@@ -1,31 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2022 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#include "GDCore/String.h"
namespace gd {
/**
* \brief Contains information about how to display a group of instructions
* to the user.
*/
class GD_CORE_API InstructionOrExpressionGroupMetadata {
public:
InstructionOrExpressionGroupMetadata(){};
/**
* \brief Sets the icon shown to users.
*/
InstructionOrExpressionGroupMetadata& SetIcon(const gd::String& icon_) {
icon = icon_;
return *this;
};
const gd::String& GetIcon() const { return icon; };
private:
gd::String icon;
};
} // namespace gd

View File

@@ -13,9 +13,7 @@
#include "GDCore/Extensions/Metadata/ObjectMetadata.h"
#include "GDCore/Extensions/Platform.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Project/Layout.h" // For GetTypeOfObject and GetTypeOfBehavior
#include "GDCore/String.h"
#include "GDCore/Events/Parsers/ExpressionParser2.h"
using namespace std;
@@ -32,9 +30,12 @@ ExtensionAndMetadata<BehaviorMetadata>
MetadataProvider::GetExtensionAndBehaviorMetadata(const gd::Platform& platform,
gd::String behaviorType) {
for (auto& extension : platform.GetAllPlatformExtensions()) {
if (extension->HasBehavior(behaviorType))
return ExtensionAndMetadata<BehaviorMetadata>(
*extension, extension->GetBehaviorMetadata(behaviorType));
auto behaviorTypes = extension->GetBehaviorsTypes();
for (std::size_t j = 0; j < behaviorTypes.size(); ++j) {
if (behaviorTypes[j] == behaviorType)
return ExtensionAndMetadata<BehaviorMetadata>(
*extension, extension->GetBehaviorMetadata(behaviorType));
}
}
return ExtensionAndMetadata<BehaviorMetadata>(badExtension, badBehaviorMetadata);
@@ -201,7 +202,8 @@ MetadataProvider::GetExtensionAndBehaviorExpressionMetadata(
const gd::Platform& platform, gd::String autoType, gd::String exprType) {
auto& extensions = platform.GetAllPlatformExtensions();
for (auto& extension : extensions) {
if (extension->HasBehavior(autoType)) {
const auto& autos = extension->GetBehaviorsTypes();
if (find(autos.begin(), autos.end(), autoType) != autos.end()) {
const auto& allAutoExpressions =
extension->GetAllExpressionsForBehavior(autoType);
if (allAutoExpressions.find(exprType) != allAutoExpressions.end())
@@ -290,7 +292,8 @@ MetadataProvider::GetExtensionAndBehaviorStrExpressionMetadata(
const gd::Platform& platform, gd::String autoType, gd::String exprType) {
auto& extensions = platform.GetAllPlatformExtensions();
for (auto& extension : extensions) {
if (extension->HasBehavior(autoType)) {
const auto& autos = extension->GetBehaviorsTypes();
if (find(autos.begin(), autos.end(), autoType) != autos.end()) {
const auto& allBehaviorStrExpressions =
extension->GetAllStrExpressionsForBehavior(autoType);
if (allBehaviorStrExpressions.find(exprType) !=
@@ -347,30 +350,28 @@ const gd::ExpressionMetadata& MetadataProvider::GetAnyExpressionMetadata(
const gd::Platform& platform, gd::String exprType) {
const auto& numberExpressionMetadata =
GetExpressionMetadata(platform, exprType);
if (&numberExpressionMetadata != &badExpressionMetadata) {
return numberExpressionMetadata;
}
const auto& stringExpressionMetadata =
GetStrExpressionMetadata(platform, exprType);
if (&stringExpressionMetadata != &badExpressionMetadata) {
return stringExpressionMetadata;
}
return badExpressionMetadata;
return &numberExpressionMetadata != &badExpressionMetadata
? numberExpressionMetadata
: &stringExpressionMetadata != &badExpressionMetadata
? stringExpressionMetadata
: badExpressionMetadata;
}
const gd::ExpressionMetadata& MetadataProvider::GetObjectAnyExpressionMetadata(
const gd::Platform& platform, gd::String objectType, gd::String exprType) {
const auto& numberExpressionMetadata =
GetObjectExpressionMetadata(platform, objectType, exprType);
if (&numberExpressionMetadata != &badExpressionMetadata) {
return numberExpressionMetadata;
}
const auto& stringExpressionMetadata =
GetObjectStrExpressionMetadata(platform, objectType, exprType);
if (&stringExpressionMetadata != &badExpressionMetadata) {
return stringExpressionMetadata;
}
return badExpressionMetadata;
return &numberExpressionMetadata != &badExpressionMetadata
? numberExpressionMetadata
: &stringExpressionMetadata != &badExpressionMetadata
? stringExpressionMetadata
: badExpressionMetadata;
}
const gd::ExpressionMetadata&
@@ -379,98 +380,14 @@ MetadataProvider::GetBehaviorAnyExpressionMetadata(const gd::Platform& platform,
gd::String exprType) {
const auto& numberExpressionMetadata =
GetBehaviorExpressionMetadata(platform, autoType, exprType);
if (&numberExpressionMetadata != &badExpressionMetadata) {
return numberExpressionMetadata;
}
const auto& stringExpressionMetadata =
GetBehaviorStrExpressionMetadata(platform, autoType, exprType);
if (&stringExpressionMetadata != &badExpressionMetadata) {
return stringExpressionMetadata;
}
return badExpressionMetadata;
}
const gd::ExpressionMetadata& MetadataProvider::GetFunctionCallMetadata(
const gd::Platform& platform,
const gd::ObjectsContainer &globalObjectsContainer,
const gd::ObjectsContainer &objectsContainer,
FunctionCallNode& node) {
if (!node.behaviorName.empty()) {
gd::String behaviorType =
GetTypeOfBehavior(globalObjectsContainer, objectsContainer, node.behaviorName);
return MetadataProvider::GetBehaviorAnyExpressionMetadata(
platform, behaviorType, node.functionName);
}
else if (!node.objectName.empty()) {
gd::String objectType =
GetTypeOfObject(globalObjectsContainer, objectsContainer, node.objectName);
return MetadataProvider::GetObjectAnyExpressionMetadata(
platform, objectType, node.functionName);
}
return MetadataProvider::GetAnyExpressionMetadata(platform, node.functionName);
}
const gd::ParameterMetadata* MetadataProvider::GetFunctionCallParameterMetadata(
const gd::Platform& platform,
const gd::ObjectsContainer &globalObjectsContainer,
const gd::ObjectsContainer &objectsContainer,
FunctionCallNode& functionCall,
ExpressionNode& parameter) {
int parameterIndex = -1;
for (int i = 0; i < functionCall.parameters.size(); i++) {
if (functionCall.parameters.at(i).get() == &parameter) {
parameterIndex = i;
break;
}
}
if (parameterIndex < 0) {
return nullptr;
}
return MetadataProvider::GetFunctionCallParameterMetadata(
platform,
globalObjectsContainer,
objectsContainer,
functionCall,
parameterIndex);
}
const gd::ParameterMetadata* MetadataProvider::GetFunctionCallParameterMetadata(
const gd::Platform& platform,
const gd::ObjectsContainer &globalObjectsContainer,
const gd::ObjectsContainer &objectsContainer,
FunctionCallNode& functionCall,
int parameterIndex) {
// Search the parameter metadata index skipping invisible ones.
size_t visibleParameterIndex = 0;
size_t metadataParameterIndex =
ExpressionParser2::WrittenParametersFirstIndex(
functionCall.objectName, functionCall.behaviorName);
const gd::ExpressionMetadata &metadata = MetadataProvider::GetFunctionCallMetadata(
platform, globalObjectsContainer, objectsContainer, functionCall);
if (IsBadExpressionMetadata(metadata)) {
return nullptr;
}
// TODO use a badMetadata instead of a nullptr?
const gd::ParameterMetadata* parameterMetadata = nullptr;
while (metadataParameterIndex <
metadata.parameters.size()) {
if (!metadata.parameters[metadataParameterIndex]
.IsCodeOnly()) {
if (visibleParameterIndex == parameterIndex) {
parameterMetadata = &metadata.parameters[metadataParameterIndex];
}
visibleParameterIndex++;
}
metadataParameterIndex++;
}
const int visibleParameterCount = visibleParameterIndex;
// It can be null if there are too many parameters in the expression, this text node is
// not actually linked to a parameter expected by the function call.
return parameterMetadata;
return &numberExpressionMetadata != &badExpressionMetadata
? numberExpressionMetadata
: &stringExpressionMetadata != &badExpressionMetadata
? stringExpressionMetadata
: badExpressionMetadata;
}
MetadataProvider::~MetadataProvider() {}

View File

@@ -15,8 +15,6 @@ class ExpressionMetadata;
class ExpressionMetadata;
class Platform;
class PlatformExtension;
struct FunctionCallNode;
struct ExpressionNode;
} // namespace gd
namespace gd {
@@ -236,26 +234,6 @@ class GD_CORE_API MetadataProvider {
static const gd::ExpressionMetadata& GetObjectAnyExpressionMetadata(
const gd::Platform& platform, gd::String objectType, gd::String exprType);
static const gd::ExpressionMetadata& GetFunctionCallMetadata(
const gd::Platform& platform,
const gd::ObjectsContainer &globalObjectsContainer,
const gd::ObjectsContainer &objectsContainer,
FunctionCallNode& node);
static const gd::ParameterMetadata* GetFunctionCallParameterMetadata(
const gd::Platform& platform,
const gd::ObjectsContainer &globalObjectsContainer,
const gd::ObjectsContainer &objectsContainer,
FunctionCallNode& functionCall,
ExpressionNode& parameter);
static const gd::ParameterMetadata* GetFunctionCallParameterMetadata(
const gd::Platform& platform,
const gd::ObjectsContainer &globalObjectsContainer,
const gd::ObjectsContainer &objectsContainer,
FunctionCallNode& functionCall,
int parameterIndex);
/**
* Get information about an expression from its type.
* Works for behavior expressions.

View File

@@ -31,11 +31,6 @@ class GD_CORE_API MultipleInstructionMetadata {
gd::InstructionMetadata &action) {
return MultipleInstructionMetadata(expression, condition, action);
}
static MultipleInstructionMetadata WithConditionAndAction(
gd::InstructionMetadata &condition,
gd::InstructionMetadata &action) {
return MultipleInstructionMetadata(condition, action);
}
/**
* \see gd::InstructionMetadata::AddParameter
@@ -80,16 +75,6 @@ class GD_CORE_API MultipleInstructionMetadata {
return *this;
};
/**
* \see gd::InstructionMetadata::SetParameterExtraInfo
*/
MultipleInstructionMetadata &SetParameterExtraInfo(const gd::String &defaultValue) {
if (expression) expression->SetParameterExtraInfo(defaultValue);
if (condition) condition->SetParameterExtraInfo(defaultValue);
if (action) action->SetParameterExtraInfo(defaultValue);
return *this;
};
/**
* \see gd::InstructionMetadata::SetParameterLongDescription
*/
@@ -111,24 +96,13 @@ class GD_CORE_API MultipleInstructionMetadata {
return *this;
};
/**
* \see gd::InstructionMetadata::SetRequiresBaseObjectCapability
*/
MultipleInstructionMetadata &SetRequiresBaseObjectCapability(
const gd::String &capability) {
if (expression) expression->SetRequiresBaseObjectCapability(capability);
if (condition) condition->SetRequiresBaseObjectCapability(capability);
if (action) action->SetRequiresBaseObjectCapability(capability);
return *this;
}
/**
* \see gd::InstructionMetadata::UseStandardOperatorParameters
* \see gd::InstructionMetadata::UseStandardRelationalOperatorParameters
*/
MultipleInstructionMetadata &UseStandardParameters(const gd::String &type, const gd::String& typeExtraInfo = "") {
if (condition) condition->UseStandardRelationalOperatorParameters(type, typeExtraInfo);
if (action) action->UseStandardOperatorParameters(type, typeExtraInfo);
MultipleInstructionMetadata &UseStandardParameters(const gd::String &type) {
if (condition) condition->UseStandardRelationalOperatorParameters(type);
if (action) action->UseStandardOperatorParameters(type);
return *this;
}
@@ -164,33 +138,6 @@ class GD_CORE_API MultipleInstructionMetadata {
return *this;
}
/**
* \brief Get the files that must be included to use the instruction.
*/
const std::vector<gd::String>& GetIncludeFiles() const {
if (expression)
return expression->GetCodeExtraInformation().GetIncludeFiles();
if (condition)
return condition->GetCodeExtraInformation().GetIncludeFiles();
if (action)
return action->GetCodeExtraInformation().GetIncludeFiles();
// It can't actually happen.
throw std::logic_error("no instruction metadata");
}
/**
* \see gd::InstructionMetadata::SetPrivate
*/
MultipleInstructionMetadata &SetPrivate() {
if (expression)
expression->SetPrivate();
if (condition)
condition->SetPrivate();
if (action)
action->SetPrivate();
return *this;
}
/**
* \see gd::InstructionMetadata::MarkAsSimple
*/
@@ -232,9 +179,6 @@ class GD_CORE_API MultipleInstructionMetadata {
gd::InstructionMetadata &condition_,
gd::InstructionMetadata &action_)
: expression(&expression_), condition(&condition_), action(&action_){};
MultipleInstructionMetadata(gd::InstructionMetadata &condition_,
gd::InstructionMetadata &action_)
: expression(nullptr), condition(&condition_), action(&action_){};
gd::ExpressionMetadata *expression;
gd::InstructionMetadata *condition;

View File

@@ -14,7 +14,6 @@
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Tools/Localization.h"
#include "GDCore/Tools/Log.h"
namespace gd {
@@ -23,40 +22,30 @@ ObjectMetadata::ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& icon24x24,
std::shared_ptr<gd::ObjectConfiguration> blueprintObject_)
: ObjectMetadata(extensionNamespace_,
name_,
fullname_,
description_,
icon24x24,
[blueprintObject_]() -> std::unique_ptr<gd::ObjectConfiguration> {
if (blueprintObject_ == std::shared_ptr<gd::ObjectConfiguration>()) {
gd::LogFatalError(
"Error: Unable to create object. Have you declared an extension "
"(or ObjectMetadata) without specifying an object as blueprint?");
std::shared_ptr<gd::Object> blueprintObject_)
: extensionNamespace(extensionNamespace_),
blueprintObject(blueprintObject_) {
name = name_;
#if defined(GD_IDE_ONLY)
SetFullName(gd::String(fullname_));
SetDescription(gd::String(description_));
iconFilename = icon24x24;
#endif
createFunPtr =
[blueprintObject_](gd::String name) -> std::unique_ptr<gd::Object> {
if (blueprintObject_ == std::shared_ptr<gd::Object>()) {
std::cout
<< "Error: Unable to create object. Have you declared an extension "
"(or ObjectMetadata) without specifying an object as blueprint?"
<< std::endl;
return nullptr;
}
return blueprintObject_->Clone();
}) {
blueprintObject = blueprintObject_;
}
ObjectMetadata::ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& icon24x24)
: ObjectMetadata(extensionNamespace_,
name_,
fullname_,
description_,
icon24x24,
[]() -> std::unique_ptr<gd::ObjectConfiguration> {
gd::LogFatalError(
"Error: Event-based objects don't have blueprint. "
"This method should not never be called.");
return nullptr;
}) {}
std::unique_ptr<gd::Object> newObject = blueprintObject_->Clone();
newObject->SetName(name);
return newObject;
};
}
ObjectMetadata::ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& name_,
@@ -64,12 +53,14 @@ ObjectMetadata::ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& description_,
const gd::String& icon24x24,
CreateFunPtr createFunPtrP)
: name(name_),
iconFilename(icon24x24),
createFunPtr(createFunPtrP),
extensionNamespace(extensionNamespace_) {
: extensionNamespace(extensionNamespace_) {
name = name_;
#if defined(GD_IDE_ONLY)
SetFullName(gd::String(fullname_));
SetDescription(gd::String(description_));
iconFilename = icon24x24;
#endif
createFunPtr = createFunPtrP;
}
gd::InstructionMetadata& ObjectMetadata::AddCondition(
@@ -270,41 +261,6 @@ ObjectMetadata::AddExpressionAndConditionAndAction(
const gd::String& sentenceName,
const gd::String& group,
const gd::String& icon) {
if (type != "number" && type != "string" && type != "boolean") {
gd::LogError(
"Unrecognised type passed to AddExpressionAndConditionAndAction: " +
type + ". Verify this type is valid and supported.");
}
gd::String conditionDescriptionTemplate =
type == "boolean" ? _("Check if <subject>.") : _("Compare <subject>.");
auto& condition =
AddScopedCondition(name,
fullname,
conditionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
gd::String actionDescriptionTemplate = type == "boolean"
? _("Set (or unset) if <subject>.")
: _("Change <subject>.");
auto& action = AddScopedAction(
"Set" + name,
fullname,
actionDescriptionTemplate.FindAndReplace("<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
if (type == "boolean") {
return MultipleInstructionMetadata::WithConditionAndAction(condition, action);
}
gd::String expressionDescriptionTemplate = _("Return <subject>.");
auto& expression =
type == "number"
@@ -315,11 +271,32 @@ ObjectMetadata::AddExpressionAndConditionAndAction(
group,
icon)
: AddStrExpression(name,
fullname,
expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
group,
icon);
fullname,
expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
group,
icon);
gd::String conditionDescriptionTemplate = _("Compare <subject>.");
auto& condition =
AddScopedCondition(name,
fullname,
conditionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
gd::String actionDescriptionTemplate = _("Change <subject>.");
auto& action = AddScopedAction(
"Set" + name,
fullname,
actionDescriptionTemplate.FindAndReplace("<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
return MultipleInstructionMetadata::WithExpressionAndConditionAndAction(
expression, condition, action);

View File

@@ -7,13 +7,11 @@
#define OBJECTMETADATA_H
#include <functional>
#include <map>
#include <set>
#include <memory>
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/ObjectConfiguration.h"
#include "GDCore/String.h"
namespace gd {
class InstructionMetadata;
@@ -21,7 +19,7 @@ class MultipleInstructionMetadata;
class ExpressionMetadata;
} // namespace gd
typedef std::function<std::unique_ptr<gd::ObjectConfiguration>()>
typedef std::function<std::unique_ptr<gd::Object>(gd::String name)>
CreateFunPtr;
namespace gd {
@@ -43,17 +41,7 @@ class GD_CORE_API ObjectMetadata {
const gd::String& fullname_,
const gd::String& description_,
const gd::String& icon24x24_,
std::shared_ptr<gd::ObjectConfiguration> blueprintObject_);
/**
* \brief Construct an object metadata, without "blueprint" object
*
* \note This is used by events based objects.
*/
ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& icon24x24_);
std::shared_ptr<gd::Object> blueprintObject_);
/**
* \brief Construct an object metadata, with a function that will be called
@@ -212,48 +200,13 @@ class GD_CORE_API ObjectMetadata {
return *this;
}
/**
* \brief Set the (user friendly) name of the group this object must
* be categorised in.
*/
ObjectMetadata& SetCategoryFullName(const gd::String& categoryFullName_) {
categoryFullName = categoryFullName_;
return *this;
}
/**
* \brief The "capabilities" that are offered by the base object that are
* *not* supported by this object, and should be hidden in the editor
* inferface.
*/
const std::set<gd::String>& GetUnsupportedBaseObjectCapabilities() const {
return unsupportedBaseObjectCapabilities;
}
/**
* \brief Add a "capability" that is offered by the base object that is *not*
* supported by this object, and should be hidden in the editor inferface.
*/
ObjectMetadata& AddUnsupportedBaseObjectCapability(
const gd::String& capability) {
unsupportedBaseObjectCapabilities.insert(capability);
return *this;
}
/**
* \brief Check if a "capability" that is offered by the base object is *not*
* supported by this object, and should be hidden in the editor inferface.
*/
bool IsUnsupportedBaseObjectCapability(const gd::String& capability) const {
return unsupportedBaseObjectCapabilities.find(capability) != unsupportedBaseObjectCapabilities.end();
}
const gd::String& GetName() const { return name; }
#if defined(GD_IDE_ONLY)
const gd::String& GetFullName() const { return fullname; }
const gd::String& GetCategoryFullName() const { return categoryFullName; }
const gd::String& GetHelpUrl() const { return helpUrl; }
const gd::String& GetDescription() const { return description; }
const gd::String& GetIconFilename() const { return iconFilename; }
#endif
/**
* \brief Set the URL pointing to the help page about this object
@@ -274,27 +227,7 @@ class GD_CORE_API ObjectMetadata {
*/
ObjectMetadata& AddIncludeFile(const gd::String& includeFile);
/**
* \brief Return a reference to a map containing the names of the actions
* (as keys) and the metadata associated with (as values).
*/
std::map<gd::String, gd::InstructionMetadata>& GetAllActions() { return actionsInfos; };
/**
* \see gd::PlatformExtension::GetAllActions
*/
std::map<gd::String, gd::InstructionMetadata>& GetAllConditions() { return conditionsInfos; };
/**
* \see gd::PlatformExtension::GetAllActions
*/
std::map<gd::String, gd::ExpressionMetadata>& GetAllExpressions() { return expressionsInfos; };
/**
* \see gd::PlatformExtension::GetAllActions
*/
std::map<gd::String, gd::ExpressionMetadata>& GetAllStrExpressions() { return strExpressionsInfos; };
#if defined(GD_IDE_ONLY)
std::map<gd::String, gd::InstructionMetadata> conditionsInfos;
std::map<gd::String, gd::InstructionMetadata> actionsInfos;
std::map<gd::String, gd::ExpressionMetadata> expressionsInfos;
@@ -302,25 +235,23 @@ class GD_CORE_API ObjectMetadata {
std::vector<gd::String> includeFiles;
gd::String className;
#endif
CreateFunPtr createFunPtr;
private:
gd::String extensionNamespace;
gd::String name;
gd::String helpPath;
#if defined(GD_IDE_ONLY)
gd::String helpUrl; ///< Deprecated. Use helpPath instead.
gd::String fullname;
gd::String description;
gd::String iconFilename;
gd::String categoryFullName;
std::set<gd::String> unsupportedBaseObjectCapabilities;
std::shared_ptr<gd::ObjectConfiguration>
#endif
std::shared_ptr<gd::Object>
blueprintObject; ///< The "blueprint" object to be copied when a new
///< object is asked. Can be null in case a creation
///< function is passed or for events based objects
///< (CustomObject are using EventBasedObject, they
///< don't need blueprints).
///< function is passed.
};
} // namespace gd

View File

@@ -10,25 +10,28 @@
namespace gd {
ParameterMetadata::ParameterMetadata() : codeOnly(false) {}
ParameterMetadata::ParameterMetadata() : optional(false), codeOnly(false) {}
void ParameterMetadata::SerializeTo(SerializerElement& element) const {
valueTypeMetadata.SerializeTo(element);
element.SetAttribute("type", type);
element.SetAttribute("supplementaryInformation", supplementaryInformation);
element.SetAttribute("optional", optional);
element.SetAttribute("description", description);
if (!longDescription.empty()) {
element.SetAttribute("longDescription", longDescription);
}
if (codeOnly) {
element.SetAttribute("codeOnly", codeOnly);
}
element.SetAttribute("longDescription", longDescription);
element.SetAttribute("codeOnly", codeOnly);
element.SetAttribute("defaultValue", defaultValue);
element.SetAttribute("name", name);
}
void ParameterMetadata::UnserializeFrom(const SerializerElement& element) {
valueTypeMetadata.UnserializeFrom(element);
type = element.GetStringAttribute("type");
supplementaryInformation =
element.GetStringAttribute("supplementaryInformation");
optional = element.GetBoolAttribute("optional");
description = element.GetStringAttribute("description");
longDescription = element.GetStringAttribute("longDescription");
codeOnly = element.GetBoolAttribute("codeOnly");
defaultValue = element.GetStringAttribute("defaultValue");
name = element.GetStringAttribute("name");
}

View File

@@ -6,13 +6,15 @@
#ifndef PARAMETER_METADATA_H
#define PARAMETER_METADATA_H
#if defined(GD_IDE_ONLY)
#include <map>
#include <memory>
#include "GDCore/String.h"
#include "GDCore/Extensions/Metadata/ValueTypeMetadata.h"
namespace gd {
class Project;
class Layout;
class EventsCodeGenerator;
class EventsCodeGenerationContext;
class SerializerElement;
} // namespace gd
@@ -29,32 +31,17 @@ class GD_CORE_API ParameterMetadata {
ParameterMetadata();
virtual ~ParameterMetadata(){};
/**
* \brief Return the metadata of the parameter type.
*/
gd::ValueTypeMetadata &GetValueTypeMetadata() { return valueTypeMetadata; }
/**
* \brief Set the metadata of the parameter type.
*/
ParameterMetadata &SetValueTypeMetadata(const gd::ValueTypeMetadata &valueTypeMetadata_) {
valueTypeMetadata = valueTypeMetadata_;
return *this;
}
/**
* \brief Return the type of the parameter.
* \see gd::ParameterMetadata::IsObject
* \deprecated Use gd::ValueTypeMetadata instead.
*/
const gd::String &GetType() const { return valueTypeMetadata.GetName(); }
const gd::String &GetType() const { return type; }
/**
* \brief Set the type of the parameter.
* \deprecated Use gd::ValueTypeMetadata instead.
*/
ParameterMetadata &SetType(const gd::String &type_) {
valueTypeMetadata.SetName(type_);
type = type_;
return *this;
}
@@ -83,33 +70,29 @@ class GD_CORE_API ParameterMetadata {
* \brief Return an optional additional information, used for some parameters
* with special type (for example, it can contains the type of object accepted
* by the parameter).
* \deprecated Use gd::ValueTypeMetadata instead.
*/
const gd::String &GetExtraInfo() const { return valueTypeMetadata.GetExtraInfo(); }
const gd::String &GetExtraInfo() const { return supplementaryInformation; }
/**
* \brief Set an optional additional information, used for some parameters
* with special type (for example, it can contains the type of object accepted
* by the parameter).
* \deprecated Use gd::ValueTypeMetadata instead.
*/
ParameterMetadata &SetExtraInfo(const gd::String &supplementaryInformation_) {
valueTypeMetadata.SetExtraInfo(supplementaryInformation_);
supplementaryInformation = supplementaryInformation_;
return *this;
}
/**
* \brief Return true if the parameter is optional.
* \deprecated Use gd::ValueTypeMetadata instead.
*/
bool IsOptional() const { return valueTypeMetadata.IsOptional(); }
bool IsOptional() const { return optional; }
/**
* \brief Set if the parameter is optional.
* \deprecated Use gd::ValueTypeMetadata instead.
*/
ParameterMetadata &SetOptional(bool optional_ = true) {
valueTypeMetadata.SetOptional(optional_);
optional = optional_;
return *this;
}
@@ -144,15 +127,13 @@ class GD_CORE_API ParameterMetadata {
/**
* \brief Get the default value for the parameter.
*/
const gd::String &GetDefaultValue() const {
return valueTypeMetadata.GetDefaultValue();
}
const gd::String &GetDefaultValue() const { return defaultValue; }
/**
* \brief Set the default value, if the parameter is optional.
*/
ParameterMetadata &SetDefaultValue(const gd::String &defaultValue_) {
valueTypeMetadata.SetDefaultValue(defaultValue_);
defaultValue = defaultValue_;
return *this;
}
@@ -169,27 +150,25 @@ class GD_CORE_API ParameterMetadata {
return *this;
}
// TODO Remove these deprecated functions.
/**
* \brief Return true if the type of the parameter is representing one object
* (or more, i.e: an object group).
* \brief Return true if the type of the parameter is "object", "objectPtr" or
* "objectList".
*
* \see gd::ParameterMetadata::GetType
* \deprecated Use gd::ValueTypeMetadata instead.
*/
static bool IsObject(const gd::String &parameterType) {
return gd::ValueTypeMetadata::IsTypeObject(parameterType);
return parameterType == "object" || parameterType == "objectPtr" ||
parameterType == "objectList" ||
parameterType == "objectListWithoutPicking";
}
/**
* \brief Return true if the type of the parameter is "behavior".
*
* \see gd::ParameterMetadata::GetType
* \deprecated Use gd::ValueTypeMetadata instead.
*/
static bool IsBehavior(const gd::String &parameterType) {
return gd::ValueTypeMetadata::IsTypeBehavior(parameterType);
return parameterType == "behavior";
}
/**
@@ -198,21 +177,29 @@ class GD_CORE_API ParameterMetadata {
* \note If you had a new type of parameter, also add it in the IDE (
* see EventsFunctionParametersEditor, ParameterRenderingService
* and ExpressionAutocompletion) and in the EventsCodeGenerator.
* \deprecated Use gd::ValueTypeMetadata instead.
*/
static bool IsExpression(const gd::String &type,
const gd::String &parameterType) {
return gd::ValueTypeMetadata::IsTypeExpression(type, parameterType);
}
/**
* \brief Return the expression type from the parameter type.
* Declinations of "number" and "string" types (like "forceMultiplier" or
* "sceneName") are replaced by "number" and "string".
* \deprecated Use gd::ValueTypeMetadata instead.
*/
static const gd::String &GetExpressionValueType(const gd::String &parameterType) {
return gd::ValueTypeMetadata::GetPrimitiveValueType(parameterType);
if (type == "number") {
return parameterType == "expression" || parameterType == "camera" ||
parameterType == "forceMultiplier";
} else if (type == "string") {
return parameterType == "string" || parameterType == "layer" ||
parameterType == "color" || parameterType == "file" ||
parameterType == "joyaxis" ||
parameterType == "stringWithSelector" ||
parameterType == "sceneName" ||
parameterType == "layerEffectName" ||
parameterType == "layerEffectParameterName" ||
parameterType == "objectEffectName" ||
parameterType == "objectEffectParameterName" ||
parameterType == "objectPointName" ||
parameterType == "objectAnimationName";
} else if (type == "variable") {
return parameterType == "objectvar" || parameterType == "globalvar" ||
parameterType == "scenevar";
}
return false;
}
/** \name Serialization
@@ -231,17 +218,22 @@ class GD_CORE_API ParameterMetadata {
// TODO: Deprecated public fields. Any direct usage should be moved to
// getter/setter.
gd::String type; ///< Parameter type
gd::String supplementaryInformation; ///< Used if needed
bool optional; ///< True if the parameter is optional
gd::String description; ///< Description shown in editor
bool codeOnly; ///< True if parameter is relative to code generation only,
///< i.e. must not be shown in editor
private:
gd::ValueTypeMetadata valueTypeMetadata; ///< Parameter type
gd::String longDescription; ///< Long description shown in the editor.
gd::String defaultValue; ///< Used as a default value in editor or if an
///< optional parameter is empty.
gd::String name; ///< The name of the parameter to be used in code
///< generation. Optional.
};
} // namespace gd
#endif
#endif // PARAMETER_METADATA_H

View File

@@ -14,7 +14,7 @@
namespace gd {
void ParameterMetadataTools::ParametersToObjectsContainer(
const gd::Project& project,
gd::Project& project,
const std::vector<gd::ParameterMetadata>& parameters,
gd::ObjectsContainer& outputObjectsContainer) {
outputObjectsContainer.GetObjects().clear();
@@ -59,13 +59,13 @@ void ParameterMetadataTools::IterateOverParameters(
const std::vector<gd::Expression>& parameters,
const std::vector<gd::ParameterMetadata>& parametersMetadata,
std::function<void(const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue,
const gd::String& parameterValue,
const gd::String& lastObjectName)> fn) {
IterateOverParametersWithIndex(
parameters,
parametersMetadata,
[&fn](const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue,
const gd::String& parameterValue,
size_t parameterIndex,
const gd::String& lastObjectName) {
fn(parameterMetadata, parameterValue, lastObjectName);
@@ -76,17 +76,17 @@ void ParameterMetadataTools::IterateOverParametersWithIndex(
const std::vector<gd::Expression>& parameters,
const std::vector<gd::ParameterMetadata>& parametersMetadata,
std::function<void(const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue,
const gd::String& parameterValue,
size_t parameterIndex,
const gd::String& lastObjectName)> fn) {
gd::String lastObjectName = "";
for (std::size_t pNb = 0; pNb < parametersMetadata.size(); ++pNb) {
const gd::ParameterMetadata& parameterMetadata = parametersMetadata[pNb];
const gd::Expression& parameterValue =
const gd::String& parameterValue =
pNb < parameters.size() ? parameters[pNb].GetPlainString() : "";
const gd::Expression& parameterValueOrDefault =
parameterValue.GetPlainString().empty() && parameterMetadata.IsOptional()
? Expression(parameterMetadata.GetDefaultValue())
const gd::String& parameterValueOrDefault =
parameterValue.empty() && parameterMetadata.optional
? parameterMetadata.GetDefaultValue()
: parameterValue;
fn(parameterMetadata, parameterValueOrDefault, pNb, lastObjectName);
@@ -97,7 +97,7 @@ void ParameterMetadataTools::IterateOverParametersWithIndex(
// Search "lastObjectName" in the codebase for other place where this
// convention is enforced.
if (gd::ParameterMetadata::IsObject(parameterMetadata.GetType()))
lastObjectName = parameterValueOrDefault.GetPlainString();
lastObjectName = parameterValueOrDefault;
}
}

View File

@@ -19,7 +19,7 @@ namespace gd {
class GD_CORE_API ParameterMetadataTools {
public:
static void ParametersToObjectsContainer(
const gd::Project& project,
gd::Project& project,
const std::vector<gd::ParameterMetadata>& parameters,
gd::ObjectsContainer& outputObjectsContainer);
@@ -32,7 +32,7 @@ class GD_CORE_API ParameterMetadataTools {
const std::vector<gd::Expression>& parameters,
const std::vector<gd::ParameterMetadata>& parametersMetadata,
std::function<void(const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue,
const gd::String& parameterValue,
const gd::String& lastObjectName)> fn);
/**
@@ -44,7 +44,7 @@ class GD_CORE_API ParameterMetadataTools {
const std::vector<gd::Expression>& parameters,
const std::vector<gd::ParameterMetadata>& parametersMetadata,
std::function<void(const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue,
const gd::String& parameterValue,
size_t parameterIndex,
const gd::String& lastObjectName)> fn);

View File

@@ -1,49 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "ValueTypeMetadata.h"
#include "GDCore/CommonTools.h"
#include "GDCore/Serialization/SerializerElement.h"
namespace gd {
ValueTypeMetadata::ValueTypeMetadata() : optional(false) {}
void ValueTypeMetadata::SerializeTo(SerializerElement& element) const {
element.SetAttribute("type", name);
if (!supplementaryInformation.empty()) {
element.SetAttribute("supplementaryInformation", supplementaryInformation);
}
if (optional) {
element.SetAttribute("optional", optional);
}
if (!defaultValue.empty()) {
element.SetAttribute("defaultValue", defaultValue);
}
}
void ValueTypeMetadata::UnserializeFrom(const SerializerElement& element) {
name = element.GetStringAttribute("type");
supplementaryInformation =
element.GetStringAttribute("supplementaryInformation");
optional = element.GetBoolAttribute("optional");
defaultValue = element.GetStringAttribute("defaultValue");
}
const gd::String ValueTypeMetadata::numberType = "number";
const gd::String ValueTypeMetadata::stringType = "string";
const gd::String &ValueTypeMetadata::GetPrimitiveValueType(const gd::String &parameterType) {
if (parameterType == "number" || gd::ValueTypeMetadata::IsTypeExpression("number", parameterType)) {
return ValueTypeMetadata::numberType;
}
if (parameterType == "string" || gd::ValueTypeMetadata::IsTypeExpression("string", parameterType)) {
return ValueTypeMetadata::stringType;
}
return parameterType;
}
} // namespace gd

View File

@@ -1,219 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#ifndef VALUE_TYPE_METADATA_H
#define VALUE_TYPE_METADATA_H
#include <map>
#include <memory>
#include "GDCore/String.h"
namespace gd {
class SerializerElement;
} // namespace gd
namespace gd {
/**
* \brief Define a type for parameters of a function (action, condition or
* expression) or the returned value of an expression.
*
* \see gd::EventsFunction
* \ingroup Events
*/
class GD_CORE_API ValueTypeMetadata {
public:
ValueTypeMetadata();
virtual ~ValueTypeMetadata(){};
/**
* \brief Return the string representation of the type.
*/
const gd::String &GetName() const { return name; }
/**
* \brief Set the string representation of the type.
*/
ValueTypeMetadata &SetName(const gd::String &name_) {
name = name_;
return *this;
}
/**
* \brief Return an optional additional information, used for some parameters
* with special type (for example, it can contains the type of object accepted
* by the parameter).
*/
const gd::String &GetExtraInfo() const { return supplementaryInformation; }
/**
* \brief Set an optional additional information, used for some parameters
* with special type (for example, it can contains the type of object accepted
* by the parameter).
*/
ValueTypeMetadata &SetExtraInfo(const gd::String &supplementaryInformation_) {
supplementaryInformation = supplementaryInformation_;
return *this;
}
/**
* \brief Return true if the parameter is optional.
*/
bool IsOptional() const { return optional; }
/**
* \brief Set if the parameter is optional.
*/
ValueTypeMetadata &SetOptional(bool optional_ = true) {
optional = optional_;
return *this;
}
/**
* \brief Get the default value for the parameter.
*/
const gd::String &GetDefaultValue() const { return defaultValue; }
/**
* \brief Set the default value, if the parameter is optional.
*/
ValueTypeMetadata &SetDefaultValue(const gd::String &defaultValue_) {
defaultValue = defaultValue_;
return *this;
}
/**
* \brief Return true if the type is defined.
*/
bool IsDefined() const {
return !name.empty();
}
/**
* \brief Return true if the type is representing one object
* (or more, i.e: an object group).
*/
bool IsObject() const {
return gd::ValueTypeMetadata::IsTypeObject(name);
}
/**
* \brief Return true if the type is "behavior".
*/
bool IsBehavior() const {
return gd::ValueTypeMetadata::IsTypeBehavior(name);
}
/**
* \brief Return true if the type is an expression of the
* given type.
*/
bool IsNumber() const {
return gd::ValueTypeMetadata::IsTypeExpression("number", name);
}
/**
* \brief Return true if the type is a string.
*/
bool IsString() const {
return gd::ValueTypeMetadata::IsTypeExpression("string", name);
}
/**
* \brief Return true if the type of the parameter is a number.
* \note If you had a new type of parameter, also add it in the IDE (
* see EventsFunctionParametersEditor, ParameterRenderingService
* and ExpressionAutocompletion) and in the EventsCodeGenerator.
*/
bool IsVariable() const {
return gd::ValueTypeMetadata::IsTypeExpression("variable", name);
}
/**
* \brief Return true if the type is representing one object
* (or more, i.e: an object group).
*/
static bool IsTypeObject(const gd::String &parameterType) {
return parameterType == "object" || parameterType == "objectPtr" ||
parameterType == "objectList" ||
parameterType == "objectListOrEmptyIfJustDeclared" ||
parameterType == "objectListOrEmptyWithoutPicking";
}
/**
* \brief Return true if the type is "behavior".
*/
static bool IsTypeBehavior(const gd::String &parameterType) {
return parameterType == "behavior";
}
/**
* \brief Return true if the type is an expression of the given type.
* \note If you are adding a new type of parameter, also add it in the IDE (
* see EventsFunctionParametersEditor, ParameterRenderingService
* and ExpressionAutocompletion) and in the EventsCodeGenerator.
*/
static bool IsTypeExpression(const gd::String &type,
const gd::String &parameterType) {
if (type == "number") {
return parameterType == "number" || parameterType == "expression" ||
parameterType == "camera" || parameterType == "forceMultiplier";
} else if (type == "string") {
return parameterType == "string" || parameterType == "layer" ||
parameterType == "color" || parameterType == "file" ||
parameterType == "joyaxis" ||
parameterType == "stringWithSelector" ||
parameterType == "sceneName" ||
parameterType == "layerEffectName" ||
parameterType == "layerEffectParameterName" ||
parameterType == "objectEffectName" ||
parameterType == "objectEffectParameterName" ||
parameterType == "objectPointName" ||
parameterType == "objectAnimationName" ||
parameterType == "functionParameterName" ||
parameterType == "externalLayoutName" ||
parameterType == "leaderboardId" ||
parameterType == "identifier";
} else if (type == "variable") {
return parameterType == "objectvar" || parameterType == "globalvar" ||
parameterType == "scenevar";
}
return false;
}
/**
* \brief Return the expression type from the parameter type.
* Declinations of "number" and "string" types (like "forceMultiplier" or
* "sceneName") are replaced by "number" and "string".
*/
static const gd::String &GetPrimitiveValueType(const gd::String &parameterType);
static const gd::String numberType;
static const gd::String stringType;
/** \name Serialization
*/
///@{
/**
* \brief Serialize the ParameterMetadata to the specified element
*/
void SerializeTo(gd::SerializerElement &element) const;
/**
* \brief Load the ParameterMetadata from the specified element
*/
void UnserializeFrom(const gd::SerializerElement &element);
///@}
private:
gd::String name; ///< Parameter type
gd::String supplementaryInformation; ///< Used if needed
bool optional; ///< True if the parameter is optional
gd::String defaultValue; ///< Used as a default value in editor or if an
///< optional parameter is empty.
};
} // namespace gd
#endif // VALUE_TYPE_METADATA_H

View File

@@ -4,12 +4,9 @@
* reserved. This project is released under the MIT License.
*/
#include "Platform.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/ObjectConfiguration.h"
#include "GDCore/String.h"
#include "GDCore/Tools/Log.h"
using namespace std;
@@ -17,21 +14,16 @@ using namespace std;
namespace gd {
InstructionOrExpressionGroupMetadata
Platform::badInstructionOrExpressionGroupMetadata;
Platform::Platform() : enableExtensionLoadingLogs(false) {}
Platform::Platform(): enableExtensionLoadingLogs(false) {}
Platform::~Platform() {}
bool Platform::AddExtension(std::shared_ptr<gd::PlatformExtension> extension) {
if (!extension) return false;
if (enableExtensionLoadingLogs)
std::cout << "Loading " << extension->GetName() << "...";
if (enableExtensionLoadingLogs) std::cout << "Loading " << extension->GetName() << "...";
if (IsExtensionLoaded(extension->GetName())) {
if (enableExtensionLoadingLogs)
std::cout << " (replacing existing extension)";
if (enableExtensionLoadingLogs) std::cout << " (replacing existing extension)";
RemoveExtension(extension->GetName());
}
if (enableExtensionLoadingLogs) std::cout << std::endl;
@@ -46,11 +38,6 @@ bool Platform::AddExtension(std::shared_ptr<gd::PlatformExtension> extension) {
extension->GetObjectCreationFunctionPtr(objectsTypes[i]);
}
for (const auto& it :
extension->GetAllInstructionOrExpressionGroupMetadata()) {
instructionOrExpressionGroupMetadata[it.first] = it.second;
}
return true;
}
@@ -93,22 +80,24 @@ std::shared_ptr<gd::PlatformExtension> Platform::GetExtension(
return std::shared_ptr<gd::PlatformExtension>();
}
std::unique_ptr<gd::ObjectConfiguration> Platform::CreateObjectConfiguration(
gd::String type) const {
std::unique_ptr<gd::Object> Platform::CreateObject(
gd::String type, const gd::String& name) const {
if (creationFunctionTable.find(type) == creationFunctionTable.end()) {
gd::LogWarning("Tried to create an object with an unknown type: " + type
+ " for platform " + GetName() + "!");
std::cout << "Tried to create an object with an unknown type: " << type
<< " for platform " << GetName() << "!" << std::endl;
type = "";
if (creationFunctionTable.find("") == creationFunctionTable.end()) {
gd::LogError("Unable to create a Base object!");
std::cout << "Unable to create a Base object!" << std::endl;
return nullptr;
}
}
// Create a new object with the type we want.
auto objectConfiguration = (creationFunctionTable.find(type)->second)();
objectConfiguration->SetType(type);
return objectConfiguration;
std::unique_ptr<gd::Object> object =
(creationFunctionTable.find(type)->second)(name);
object->SetType(type);
return std::unique_ptr<gd::Object>(std::move(object));
}
#if defined(GD_IDE_ONLY)

View File

@@ -9,14 +9,12 @@
#include <map>
#include <memory>
#include <vector>
#include "GDCore/Extensions/Metadata/InstructionOrExpressionGroupMetadata.h"
#include "GDCore/String.h"
namespace gd {
class InstructionsMetadataHolder;
class Project;
class Object;
class ObjectConfiguration;
class Behavior;
class BehaviorMetadata;
class ObjectMetadata;
@@ -27,7 +25,7 @@ class LayoutEditorCanvas;
class ProjectExporter;
} // namespace gd
typedef std::function<std::unique_ptr<gd::ObjectConfiguration>()>
typedef std::function<std::unique_ptr<gd::Object>(gd::String name)>
CreateFunPtr;
#undef CreateEvent
@@ -54,6 +52,7 @@ class GD_CORE_API Platform {
*/
virtual gd::String GetFullName() const { return "Unnamed platform"; }
#if defined(GD_IDE_ONLY)
/**
* \brief Must return a text describing the platform in a few words.
*/
@@ -68,6 +67,7 @@ class GD_CORE_API Platform {
* \brief Must return a filename to a 32*32 image file for the platform.
*/
virtual gd::String GetIcon() const { return ""; }
#endif
/** \name Extensions management
* Member functions used to manage the extensions
@@ -123,19 +123,6 @@ class GD_CORE_API Platform {
* anymore.
*/
virtual void RemoveExtension(const gd::String& name);
/**
* \brief Get the metadata (icon, etc...) of a group used for instructions or
* expressions.
*/
const InstructionOrExpressionGroupMetadata& GetInstructionOrExpressionGroupMetadata(
const gd::String& name) const {
auto it = instructionOrExpressionGroupMetadata.find(name);
if (it == instructionOrExpressionGroupMetadata.end())
return badInstructionOrExpressionGroupMetadata;
return it->second;
}
///@}
/** \name Factory method
@@ -147,9 +134,10 @@ class GD_CORE_API Platform {
/**
* \brief Create an object of given type with the specified name.
*/
std::unique_ptr<gd::ObjectConfiguration> CreateObjectConfiguration(
gd::String type) const;
std::unique_ptr<gd::Object> CreateObject(gd::String type,
const gd::String& name) const;
#if defined(GD_IDE_ONLY)
/**
* \brief Create an event of given type
*/
@@ -161,18 +149,28 @@ class GD_CORE_API Platform {
* \brief Activate or disable the logs on the standard output when
* loading an extension.
*/
void EnableExtensionLoadingLogs(bool enable) {
enableExtensionLoadingLogs = enable;
};
void EnableExtensionLoadingLogs(bool enable) { enableExtensionLoadingLogs = enable; };
/**
* \brief Called when the IDE is about to shut down: Take this opportunity for
* erasing for example any temporary file.
* @deprecated This should be removed.
*/
virtual void OnIDEClosed(){};
/**
* \brief Called when the IDE is initialized and ready to be used.
* @deprecated This should be removed.
*/
virtual void OnIDEInitialized(){};
#endif
private:
std::vector<std::shared_ptr<PlatformExtension>>
extensionsLoaded; ///< Extensions of the platform
std::map<gd::String, CreateFunPtr>
creationFunctionTable; ///< Creation functions for objects
std::map<gd::String, InstructionOrExpressionGroupMetadata>
instructionOrExpressionGroupMetadata;
static InstructionOrExpressionGroupMetadata badInstructionOrExpressionGroupMetadata;
bool enableExtensionLoadingLogs;
};

View File

@@ -18,7 +18,6 @@
#include "GDCore/Extensions/Platform.h"
#include "GDCore/IDE/PlatformManager.h"
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/ObjectConfiguration.h"
#include "GDCore/Project/BehaviorsSharedData.h"
#include "GDCore/Tools/Localization.h"
@@ -166,40 +165,6 @@ PlatformExtension::AddExpressionAndConditionAndAction(
const gd::String& sentenceName,
const gd::String& group,
const gd::String& icon) {
if (type != "number" && type != "string" && type != "boolean") {
gd::LogError(
"Unrecognised type passed to AddExpressionAndConditionAndAction: " +
type + ". Verify this type is valid and supported.");
}
gd::String conditionDescriptionTemplate =
type == "boolean" ? _("Check if <subject>.") : _("Compare <subject>.");
auto& condition = AddCondition(name,
fullname,
conditionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
gd::String actionDescriptionTemplate = type == "boolean"
? _("Set (or unset) if <subject>.")
: _("Change <subject>.");
auto& action = AddAction(
"Set" + name,
fullname,
actionDescriptionTemplate.FindAndReplace("<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
if (type == "boolean") {
return MultipleInstructionMetadata::WithConditionAndAction(condition,
action);
}
gd::String expressionDescriptionTemplate = _("Return <subject>.");
auto& expression =
type == "number"
@@ -210,11 +175,32 @@ PlatformExtension::AddExpressionAndConditionAndAction(
group,
icon)
: AddStrExpression(name,
fullname,
expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
group,
icon);
fullname,
expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
group,
icon);
gd::String conditionDescriptionTemplate = _("Compare <subject>.");
auto& condition = AddCondition(name,
fullname,
conditionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
// TODO: update the checks
gd::String actionDescriptionTemplate = _("Change <subject>.");
auto& action = AddAction(
"Set" + name,
fullname,
actionDescriptionTemplate.FindAndReplace("<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
return MultipleInstructionMetadata::WithExpressionAndConditionAndAction(
expression, condition, action);
@@ -232,7 +218,7 @@ gd::ObjectMetadata& PlatformExtension::AddObject(
const gd::String& fullname,
const gd::String& description,
const gd::String& icon24x24,
std::shared_ptr<gd::ObjectConfiguration> instance) {
std::shared_ptr<gd::Object> instance) {
gd::String nameWithNamespace = GetNameSpace() + name;
objectsInfos[nameWithNamespace] = ObjectMetadata(GetNameSpace(),
nameWithNamespace,
@@ -245,21 +231,6 @@ gd::ObjectMetadata& PlatformExtension::AddObject(
return objectsInfos[nameWithNamespace];
}
gd::ObjectMetadata& PlatformExtension::AddEventsBasedObject(
const gd::String& name,
const gd::String& fullname,
const gd::String& description,
const gd::String& icon24x24) {
gd::String nameWithNamespace = GetNameSpace() + name;
objectsInfos[nameWithNamespace] = ObjectMetadata(GetNameSpace(),
nameWithNamespace,
fullname,
description,
icon24x24)
.SetHelpPath(GetHelpPath());
return objectsInfos[nameWithNamespace];
}
gd::BehaviorMetadata& PlatformExtension::AddBehavior(
const gd::String& name,
const gd::String& fullname,
@@ -285,25 +256,6 @@ gd::BehaviorMetadata& PlatformExtension::AddBehavior(
return behaviorsInfo[nameWithNamespace];
}
gd::BehaviorMetadata& PlatformExtension::AddEventsBasedBehavior(
const gd::String& name,
const gd::String& fullname,
const gd::String& description,
const gd::String& group,
const gd::String& icon24x24) {
gd::String nameWithNamespace = GetNameSpace() + name;
behaviorsInfo[nameWithNamespace] = BehaviorMetadata(GetNameSpace(),
nameWithNamespace,
fullname,
// Default name is the name
name,
description,
group,
icon24x24)
.SetHelpPath(GetHelpPath());
return behaviorsInfo[nameWithNamespace];
}
gd::EffectMetadata& PlatformExtension::AddEffect(const gd::String& name) {
gd::String nameWithNamespace = GetNameSpace() + name;
effectsMetadata[nameWithNamespace] = EffectMetadata(nameWithNamespace);
@@ -381,11 +333,6 @@ gd::BehaviorMetadata& PlatformExtension::GetBehaviorMetadata(
return badBehaviorMetadata;
}
bool PlatformExtension::HasBehavior(
const gd::String& behaviorType) const {
return behaviorsInfo.find(behaviorType) != behaviorsInfo.end();
}
gd::EffectMetadata& PlatformExtension::GetEffectMetadata(
const gd::String& effectName) {
if (effectsMetadata.find(effectName) != effectsMetadata.end())
@@ -415,7 +362,7 @@ gd::InstructionMetadata& PlatformExtension::AddDuplicatedAction(
auto copiedAction = actionsInfos.find(copiedNameWithNamespace);
if (copiedAction == actionsInfos.end()) {
gd::LogError("Could not find an action with name " +
gd::LogWarning("Could not find an action with name " +
copiedNameWithNamespace + " to copy.");
} else {
actionsInfos[newNameWithNamespace] = copiedAction->second;
@@ -425,17 +372,13 @@ gd::InstructionMetadata& PlatformExtension::AddDuplicatedAction(
}
gd::InstructionMetadata& PlatformExtension::AddDuplicatedCondition(
const gd::String& newConditionName,
const gd::String& copiedConditionName,
gd::DuplicatedInstructionOptions options) {
gd::String newNameWithNamespace =
(options.unscoped ? "" : GetNameSpace()) + newConditionName;
gd::String copiedNameWithNamespace =
(options.unscoped ? "" : GetNameSpace()) + copiedConditionName;
const gd::String& newConditionName, const gd::String& copiedConditionName) {
gd::String newNameWithNamespace = GetNameSpace() + newConditionName;
gd::String copiedNameWithNamespace = GetNameSpace() + copiedConditionName;
auto copiedCondition = conditionsInfos.find(copiedNameWithNamespace);
if (copiedCondition == conditionsInfos.end()) {
gd::LogError("Could not find a condition with name " +
gd::LogWarning("Could not find a condition with name " +
copiedNameWithNamespace + " to copy.");
} else {
conditionsInfos[newNameWithNamespace] = copiedCondition->second;
@@ -452,7 +395,7 @@ gd::ExpressionMetadata& PlatformExtension::AddDuplicatedExpression(
auto copiedExpression = expressionsInfos.find(copiedNameWithNamespace);
if (copiedExpression == expressionsInfos.end()) {
gd::LogError("Could not find an expression with name " +
gd::LogWarning("Could not find an expression with name " +
copiedNameWithNamespace + " to copy.");
} else {
expressionsInfos[newNameWithNamespace] = copiedExpression->second;
@@ -469,7 +412,7 @@ gd::ExpressionMetadata& PlatformExtension::AddDuplicatedStrExpression(
auto copiedExpression = strExpressionsInfos.find(copiedNameWithNamespace);
if (copiedExpression == strExpressionsInfos.end()) {
gd::LogError("Could not find a string expression with name " +
gd::LogWarning("Could not find a string expression with name " +
copiedNameWithNamespace + " to copy.");
} else {
strExpressionsInfos[newNameWithNamespace] = copiedExpression->second;
@@ -569,8 +512,7 @@ PlatformExtension::GetAllStrExpressionsForBehavior(gd::String autoType) {
return badExpressionsMetadata;
}
gd::BaseEventSPtr PlatformExtension::CreateEvent(
const gd::String& eventType) const {
gd::BaseEventSPtr PlatformExtension::CreateEvent(const gd::String& eventType) const {
if (eventsInfos.find(eventType) != eventsInfos.end()) {
if (eventsInfos.find(eventType)->second.instance ==
std::shared_ptr<BaseEvent>()) {
@@ -812,8 +754,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
}
#endif
PlatformExtension::PlatformExtension()
: deprecated(false), category(_("General")) {}
PlatformExtension::PlatformExtension() : deprecated(false) {}
PlatformExtension::~PlatformExtension() {}

View File

@@ -5,7 +5,8 @@
* project is released under the MIT License.
*/
#pragma once
#ifndef GDCORE_PLATFORMEXTENSION_H
#define GDCORE_PLATFORMEXTENSION_H
#include <map>
#include <memory>
#include <vector>
@@ -15,7 +16,6 @@
#include "GDCore/Extensions/Metadata/DependencyMetadata.h"
#include "GDCore/Extensions/Metadata/EffectMetadata.h"
#include "GDCore/Extensions/Metadata/EventMetadata.h"
#include "GDCore/Extensions/Metadata/InstructionOrExpressionGroupMetadata.h"
#include "GDCore/Extensions/Metadata/ObjectMetadata.h"
#include "GDCore/Project/PropertyDescriptor.h"
#include "GDCore/String.h"
@@ -37,10 +37,9 @@ class ArbitraryResourceWorker;
class BehaviorsSharedData;
class Behavior;
class Object;
class ObjectConfiguration;
} // namespace gd
typedef std::function<std::unique_ptr<gd::ObjectConfiguration>()>
typedef std::function<std::unique_ptr<gd::Object>(gd::String name)>
CreateFunPtr;
namespace gd {
@@ -72,10 +71,6 @@ class GD_CORE_API CompilationInfo {
int sizeOfpInt;
};
struct GD_CORE_API DuplicatedInstructionOptions {
bool unscoped;
};
/**
* \brief Base class for implementing platform's extensions.
*
@@ -110,18 +105,10 @@ class GD_CORE_API PlatformExtension {
return *this;
}
/**
* \brief Set the category of the extension.
*/
PlatformExtension& SetCategory(const gd::String& category_) {
category = category_;
return *this;
}
/**
* \brief Set the path to the help, relative to the GDevelop documentation
* root. For example, "/all-features/collisions" for
* "https://wiki.gdevelop.io/gdevelop5/all-features/collisions".
* "http://wiki.compilgames.net/doku.php/gdevelop5/all-features/collisions".
*
* The instructions, objects and behaviors will have this help path set by
* default, unless you call SetHelpPath on them.
@@ -243,21 +230,7 @@ class GD_CORE_API PlatformExtension {
const gd::String& fullname_,
const gd::String& description_,
const gd::String& icon_,
std::shared_ptr<gd::ObjectConfiguration> instance);
/**
* \brief Declare a new events based object as being part of the extension.
*
* \param name The name of the object
* \param fullname The user friendly name of the object
* \param description The user friendly description of the object
* \param icon The icon of the object.
*/
gd::ObjectMetadata& AddEventsBasedObject(
const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& icon_);
std::shared_ptr<gd::Object> instance);
/**
* \brief Declare a new behavior as being part of the extension.
@@ -282,21 +255,6 @@ class GD_CORE_API PlatformExtension {
std::shared_ptr<gd::Behavior> instance,
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance);
/**
* \brief Declare a new events based behavior as being part of the extension.
*
* \param name The name of the behavior
* \param fullname The user friendly name of the behavior
* \param description The user friendly description of the behavior
* \param icon The icon of the behavior.
*/
gd::BehaviorMetadata& AddEventsBasedBehavior(
const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& group_,
const gd::String& icon_);
/**
* \brief Declare a new effect as being part of the extension.
* \param name The internal name of the effect (also called effect type).
@@ -313,6 +271,7 @@ class GD_CORE_API PlatformExtension {
const gd::String& smallicon_,
std::shared_ptr<gd::BaseEvent> instance);
#if defined(GD_IDE_ONLY)
/**
* \brief Create a new action which is the duplicate of the specified one.
*
@@ -329,8 +288,7 @@ class GD_CORE_API PlatformExtension {
*/
gd::InstructionMetadata& AddDuplicatedCondition(
const gd::String& newConditionName,
const gd::String& copiedConditionName,
gd::DuplicatedInstructionOptions options = {.unscoped = false});
const gd::String& copiedConditionName);
/**
* \brief Create a new expression which is the duplicate of the specified one.
*
@@ -357,15 +315,7 @@ class GD_CORE_API PlatformExtension {
gd::PropertyDescriptor& RegisterProperty(const gd::String& name) {
return extensionPropertiesMetadata[name];
};
/**
* \brief Add some metadata (icon, etc...) for a group used for instructions
* or expressions.
*/
InstructionOrExpressionGroupMetadata& AddInstructionOrExpressionGroupMetadata(
const gd::String& name) {
return instructionOrExpressionGroupMetadata[name];
}
#endif
/**
* \brief Delete all instructions having no function name or custom code
@@ -389,11 +339,6 @@ class GD_CORE_API PlatformExtension {
*/
const gd::String& GetName() const { return name; }
/**
* \brief Return the category of the extension
*/
const gd::String& GetCategory() const { return category; }
/**
* \brief Return a description of the extension
*/
@@ -497,12 +442,6 @@ class GD_CORE_API PlatformExtension {
*/
BehaviorMetadata& GetBehaviorMetadata(const gd::String& behaviorType);
/**
* \brief Return true if the extension contains a behavior associated to \a
* behaviorType
*/
bool HasBehavior(const gd::String& behaviorType) const;
/**
* \brief Return the metadata for the effect with the given name.
*/
@@ -513,6 +452,7 @@ class GD_CORE_API PlatformExtension {
*/
std::map<gd::String, gd::EventMetadata>& GetAllEvents();
#if defined(GD_IDE_ONLY)
/**
* \brief Return a reference to a map containing the names of the actions
* (as keys) and the metadata associated with (as values).
@@ -597,16 +537,8 @@ class GD_CORE_API PlatformExtension {
std::map<gd::String, gd::PropertyDescriptor>& GetAllProperties() {
return extensionPropertiesMetadata;
}
/**
* \brief Get the metadata (icon, etc...) for groups used for instructions
* or expressions.
*/
const std::map<gd::String, InstructionOrExpressionGroupMetadata>&
GetAllInstructionOrExpressionGroupMetadata() const {
return instructionOrExpressionGroupMetadata;
}
///@}
#endif
/**
* \brief Return the name of all the extensions which are considered provided
@@ -634,7 +566,6 @@ class GD_CORE_API PlatformExtension {
///< actions/conditions/expressions/objects/behavior/event.
gd::String fullname; ///< Name displayed to users in the editor.
gd::String informations; ///< Description displayed to users in the editor.
gd::String category;
gd::String author; ///< Author displayed to users in the editor.
gd::String license; ///< License name displayed to users in the editor.
bool deprecated; ///< true if the extension is deprecated and shouldn't be
@@ -646,6 +577,7 @@ class GD_CORE_API PlatformExtension {
std::map<gd::String, gd::ObjectMetadata> objectsInfos;
std::map<gd::String, gd::BehaviorMetadata> behaviorsInfo;
std::map<gd::String, gd::EffectMetadata> effectsMetadata;
#if defined(GD_IDE_ONLY)
std::map<gd::String, gd::InstructionMetadata> conditionsInfos;
std::map<gd::String, gd::InstructionMetadata> actionsInfos;
std::map<gd::String, gd::ExpressionMetadata> expressionsInfos;
@@ -653,12 +585,12 @@ class GD_CORE_API PlatformExtension {
std::vector<gd::DependencyMetadata> extensionDependenciesMetadata;
std::map<gd::String, gd::EventMetadata> eventsInfos;
std::map<gd::String, gd::PropertyDescriptor> extensionPropertiesMetadata;
std::map<gd::String, InstructionOrExpressionGroupMetadata>
instructionOrExpressionGroupMetadata;
#endif
ObjectMetadata badObjectMetadata;
BehaviorMetadata badBehaviorMetadata;
EffectMetadata badEffectMetadata;
#if defined(GD_IDE_ONLY)
static std::map<gd::String, gd::InstructionMetadata>
badConditionsMetadata; ///< Used when a condition is not found in the
///< extension
@@ -668,10 +600,12 @@ class GD_CORE_API PlatformExtension {
static std::map<gd::String, gd::ExpressionMetadata>
badExpressionsMetadata; ///< Used when an expression is not found in the
///< extension
#endif
};
} // namespace gd
#if defined(GD_IDE_ONLY)
/** \brief Macro used by extensions in their constructor to declare how they
* have been compiled. \see gd::CompilationInfo
*/
@@ -685,5 +619,23 @@ class GD_CORE_API PlatformExtension {
compilationInfo.gccMinorVersion = __GNUC_MINOR__; \
compilationInfo.gccPatchLevel = __GNUC_PATCHLEVEL__; \
compilationInfo.informationCompleted = true;
#else
/** \brief Macro used by extensions in their constructor to declare how they
* have been compiled. \see gd::CompilationInfo
*/
#define GD_COMPLETE_EXTENSION_COMPILATION_INFORMATION() \
compilationInfo.runtimeOnly = true; \
compilationInfo.sfmlMajorVersion = 2; \
compilationInfo.sfmlMinorVersion = 0; \
compilationInfo.gdCoreVersion = GD_VERSION_STRING; \
compilationInfo.sizeOfpInt = sizeof(int*); \
compilationInfo.gccMajorVersion = __GNUC__; \
compilationInfo.gccMinorVersion = __GNUC_MINOR__; \
compilationInfo.gccPatchLevel = __GNUC_PATCHLEVEL__; \
compilationInfo.informationCompleted = true;
#endif
#include "GDCore/Extensions/PlatformExtension.inl"
#endif // GDCORE_PLATFORMEXTENSION_H

View File

@@ -25,8 +25,8 @@ gd::ObjectMetadata& PlatformExtension::AddObject(const gd::String& name,
fullname,
description,
icon24x24,
[]() -> std::unique_ptr<gd::ObjectConfiguration> {
return gd::make_unique<T>();
[](gd::String name) -> std::unique_ptr<gd::Object> {
return gd::make_unique<T>(name);
})
.SetHelpPath(GetHelpPath());

View File

@@ -73,54 +73,4 @@ bool ArbitraryEventsWorker::VisitInstruction(gd::Instruction& instruction,
ArbitraryEventsWorkerWithContext::~ArbitraryEventsWorkerWithContext() {}
ReadOnlyArbitraryEventsWorker::~ReadOnlyArbitraryEventsWorker() {}
void ReadOnlyArbitraryEventsWorker::VisitEventList(const gd::EventsList& events) {
DoVisitEventList(events);
for (std::size_t i = 0; i < events.size(); ++i) {
VisitEvent(events[i]);
if (events[i].CanHaveSubEvents()) {
VisitEventList(events[i].GetSubEvents());
}
}
}
void ReadOnlyArbitraryEventsWorker::VisitEvent(const gd::BaseEvent& event) {
DoVisitEvent(event);
const vector<const gd::InstructionsList*> conditionsVectors =
event.GetAllConditionsVectors();
for (std::size_t j = 0; j < conditionsVectors.size(); ++j) {
VisitInstructionList(*conditionsVectors[j], true);
}
const vector<const gd::InstructionsList*> actionsVectors = event.GetAllActionsVectors();
for (std::size_t j = 0; j < actionsVectors.size(); ++j) {
VisitInstructionList(*actionsVectors[j], false);
}
}
void ReadOnlyArbitraryEventsWorker::VisitInstructionList(
const gd::InstructionsList& instructions, bool areConditions) {
DoVisitInstructionList(instructions, areConditions);
for (std::size_t i = 0; i < instructions.size(); ++i) {
VisitInstruction(instructions[i], areConditions);
if (!instructions[i].GetSubInstructions().empty()) {
VisitInstructionList(instructions[i].GetSubInstructions(),
areConditions);
}
}
}
void ReadOnlyArbitraryEventsWorker::VisitInstruction(const gd::Instruction& instruction,
bool isCondition) {
DoVisitInstruction(instruction, isCondition);
}
ReadOnlyArbitraryEventsWorkerWithContext::~ReadOnlyArbitraryEventsWorkerWithContext() {}
} // namespace gd

View File

@@ -121,101 +121,6 @@ class GD_CORE_API ArbitraryEventsWorkerWithContext
const gd::ObjectsContainer* currentObjectsContainer;
};
/**
* \brief ReadOnlyArbitraryEventsWorker is an abstract class used to browse events (and
* instructions). It can be used to implement autocompletion for example.
*
* \see gd::ReadOnlyArbitraryEventsWorkerWithContext
*
* \ingroup IDE
*/
class GD_CORE_API ReadOnlyArbitraryEventsWorker {
public:
ReadOnlyArbitraryEventsWorker(){};
virtual ~ReadOnlyArbitraryEventsWorker();
/**
* \brief Launch the worker on the specified events list.
*/
void Launch(const gd::EventsList& events) { VisitEventList(events); };
private:
void VisitEventList(const gd::EventsList& events);
void VisitEvent(const gd::BaseEvent& event);
void VisitInstructionList(const gd::InstructionsList& instructions,
bool areConditions);
void VisitInstruction(const gd::Instruction& instruction, bool isCondition);
/**
* Called to do some work on an event list.
*/
virtual void DoVisitEventList(const gd::EventsList& events){};
/**
* Called to do some work on an event
*/
virtual void DoVisitEvent(const gd::BaseEvent& event) {};
/**
* Called to do some work on an instruction list
*/
virtual void DoVisitInstructionList(const gd::InstructionsList& instructions,
bool areConditions){};
/**
* Called to do some work on an instruction.
*/
virtual void DoVisitInstruction(const gd::Instruction& instruction,
bool isCondition) {};
};
/**
* \brief An events worker that will know about the context (the objects
* container). Useful for workers working on expressions notably.
*
* \see gd::ReadOnlyArbitraryEventsWorker
*
* \ingroup IDE
*/
class GD_CORE_API ReadOnlyArbitraryEventsWorkerWithContext
: public ReadOnlyArbitraryEventsWorker {
public:
ReadOnlyArbitraryEventsWorkerWithContext()
: currentGlobalObjectsContainer(nullptr),
currentObjectsContainer(nullptr){};
virtual ~ReadOnlyArbitraryEventsWorkerWithContext();
/**
* \brief Launch the worker on the specified events list,
* giving the objects container on which the events are applying to.
*/
void Launch(const gd::EventsList& events,
const gd::ObjectsContainer& globalObjectsContainer_,
const gd::ObjectsContainer& objectsContainer_) {
currentGlobalObjectsContainer = &globalObjectsContainer_;
currentObjectsContainer = &objectsContainer_;
ReadOnlyArbitraryEventsWorker::Launch(events);
};
void Launch(gd::EventsList& events) = delete;
protected:
const gd::ObjectsContainer& GetGlobalObjectsContainer() {
// Pointers are guaranteed to be not nullptr after
// Launch was called.
return *currentGlobalObjectsContainer;
};
const gd::ObjectsContainer& GetObjectsContainer() {
// Pointers are guaranteed to be not nullptr after
// Launch was called.
return *currentObjectsContainer;
};
private:
const gd::ObjectsContainer* currentGlobalObjectsContainer;
const gd::ObjectsContainer* currentObjectsContainer;
};
} // namespace gd
#endif // GDCORE_ARBITRARYEVENTSWORKER_H

View File

@@ -1,25 +0,0 @@
#include "BehaviorTypeRenamer.h"
#include "GDCore/Events/Instruction.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/IDE/WholeProjectRefactorer.h"
#include "GDCore/IDE/Events/ExpressionTypeFinder.h"
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/Project.h"
namespace gd {
void BehaviorTypeRenamer::DoVisitObject(gd::Object& object) {
};
void BehaviorTypeRenamer::DoVisitBehavior(gd::Behavior& behavior) {
if (behavior.GetTypeName() == oldType) {
behavior.SetTypeName(newType);
}
};
BehaviorTypeRenamer::~BehaviorTypeRenamer() {}
} // namespace gd

View File

@@ -1,43 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#ifndef GDCORE_BEHAVIORTYPERENAMER_H
#define GDCORE_BEHAVIORTYPERENAMER_H
#include <set>
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
#include "GDCore/String.h"
namespace gd {
class Project;
class Object;
class Behavior;
} // namespace gd
namespace gd {
class GD_CORE_API BehaviorTypeRenamer : public ArbitraryObjectsWorker {
public:
BehaviorTypeRenamer(const gd::Project& project_,
const gd::String& oldType_,
const gd::String& newType_)
: project(project_), oldType(oldType_), newType(newType_){};
virtual ~BehaviorTypeRenamer();
private:
void DoVisitObject(gd::Object& object) override;
void DoVisitBehavior(gd::Behavior& behavior) override;
const gd::Project& project;
gd::String oldType;
gd::String newType;
};
}; // namespace gd
#endif // GDCORE_BEHAVIORTYPERENAMER_H

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