mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
4 Commits
refactor/p
...
fix/slug-v
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e93e65e7e1 | ||
![]() |
b67e7035bc | ||
![]() |
b0f824f889 | ||
![]() |
ee7065d52c |
@@ -2,17 +2,10 @@
|
||||
# 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
|
||||
@@ -82,7 +75,6 @@ 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
|
||||
@@ -161,67 +153,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:
|
||||
|
2
.github/workflows/issues.yml
vendored
2
.github/workflows/issues.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
type: "body"
|
||||
regex: ".*Scroll down to '\\.\\.\\.\\.'.*"
|
||||
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed because it seems that you have not included any steps to reproduce the bug.\n\nGitHub is a place for the technical development of GDevelop itself - you may want to go on the [forum](https://forum.gdevelop-app.com/), the Discord chat or [read the documentation](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:
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,7 +8,6 @@
|
||||
/Binaries/.embuild*
|
||||
/Binaries/build*
|
||||
/Binaries/embuild*
|
||||
/emsdk
|
||||
*.dll
|
||||
*.exe
|
||||
*.a
|
||||
|
25
.gitpod.yml
25
.gitpod.yml
@@ -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
|
||||
|
||||
|
26
.travis.yml
26
.travis.yml
@@ -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,18 @@ cache:
|
||||
directories:
|
||||
- $HOME/.npm
|
||||
|
||||
services:
|
||||
# Virtual Framebuffer 'fake' X server for SFML
|
||||
- xvfb
|
||||
|
||||
addons:
|
||||
artifacts:
|
||||
s3_region: "us-east-1"
|
||||
target_paths:
|
||||
- /$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)/commit/$(git rev-parse HEAD)
|
||||
- /$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)/latest
|
||||
paths:
|
||||
- Binaries/embuild/GDevelop.js
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
@@ -22,8 +36,20 @@ addons:
|
||||
# Build dependencies:
|
||||
- cmake
|
||||
- p7zip-full
|
||||
# SFML dependencies:
|
||||
- libopenal-dev
|
||||
- libjpeg-dev
|
||||
- libglew-dev
|
||||
- libudev-dev
|
||||
- libxrandr-dev
|
||||
- libsndfile1-dev
|
||||
- libglu1-mesa-dev
|
||||
- libfreetype6-dev
|
||||
|
||||
before_install:
|
||||
#Activate X Virtual Framebuffer to allow tests to
|
||||
#use SFML.
|
||||
- "export DISPLAY=:99.0"
|
||||
# This workaround is required to avoid libstdc++ errors (Emscripten requires a recent version of libstdc++)
|
||||
- wget -q -O libstdc++6 http://security.ubuntu.com/ubuntu/pool/main/g/gcc-5/libstdc++6_5.4.0-6ubuntu1~16.04.12_amd64.deb
|
||||
- sudo dpkg --force-all -i libstdc++6
|
||||
|
7
.vscode/c_cpp_properties.json
vendored
7
.vscode/c_cpp_properties.json
vendored
@@ -7,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
14
.vscode/launch.json
vendored
@@ -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",
|
||||
|
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@@ -115,6 +115,7 @@
|
||||
"files.exclude": {
|
||||
"Binaries/*build*": true,
|
||||
"Binaries/Output": true,
|
||||
"ExtLibs/SFML": true,
|
||||
"GDJS/Runtime-dist": true,
|
||||
"docs": true,
|
||||
"newIDE/electron-app/dist": true,
|
||||
|
@@ -17,7 +17,7 @@ endmacro()
|
||||
gd_set_option(BUILD_CORE TRUE BOOL "TRUE to build GDevelop Core library")
|
||||
gd_set_option(BUILD_GDJS TRUE BOOL "TRUE to build GDevelop JS Platform")
|
||||
gd_set_option(BUILD_EXTENSIONS TRUE BOOL "TRUE to build the extensions")
|
||||
gd_set_option(BUILD_TESTS 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.
|
||||
|
@@ -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()
|
||||
|
@@ -13,6 +13,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "Utf8/utf8.h"
|
||||
#include <SFML/System/String.hpp>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define GD_DEPRECATED __attribute__((deprecated))
|
||||
|
@@ -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
|
@@ -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
|
@@ -63,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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -450,9 +450,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 =
|
||||
@@ -520,12 +518,8 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
// Prepare arguments and generate the whole action code
|
||||
vector<gd::String> arguments = GenerateParametersCodes(
|
||||
action.GetParameters(), instrInfos.parameters, context);
|
||||
actionCode += GenerateObjectAction(realObjects[i],
|
||||
objInfo,
|
||||
arguments,
|
||||
instrInfos,
|
||||
context,
|
||||
optionalAsyncCallbackName);
|
||||
actionCode += GenerateObjectAction(
|
||||
realObjects[i], objInfo, arguments, instrInfos, context);
|
||||
|
||||
context.SetNoCurrentObject();
|
||||
}
|
||||
@@ -558,8 +552,7 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
autoInfo,
|
||||
arguments,
|
||||
instrInfos,
|
||||
context,
|
||||
optionalAsyncCallbackName);
|
||||
context);
|
||||
|
||||
context.SetNoCurrentObject();
|
||||
}
|
||||
@@ -567,72 +560,12 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
} else {
|
||||
vector<gd::String> arguments = GenerateParametersCodes(
|
||||
action.GetParameters(), instrInfos.parameters, context);
|
||||
actionCode +=
|
||||
GenerateFreeAction(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.
|
||||
*/
|
||||
@@ -810,21 +743,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);
|
||||
|
||||
@@ -832,9 +767,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";
|
||||
@@ -849,7 +785,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
|
||||
@@ -865,8 +801,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);
|
||||
|
||||
@@ -1081,8 +1015,7 @@ gd::String EventsCodeGenerator::GenerateBehaviorCondition(
|
||||
gd::String EventsCodeGenerator::GenerateFreeAction(
|
||||
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" ||
|
||||
@@ -1109,11 +1042,6 @@ gd::String EventsCodeGenerator::GenerateFreeAction(
|
||||
call = instrInfos.codeExtraInformation.functionCallName + "(" +
|
||||
GenerateArgumentsList(arguments) + ")";
|
||||
}
|
||||
|
||||
if (!optionalAsyncCallbackName.empty())
|
||||
call = "runtimeScene.getAsyncTasksManager().addTask(" + call + ", " +
|
||||
optionalAsyncCallbackName + ")";
|
||||
|
||||
return call + ";\n";
|
||||
}
|
||||
|
||||
@@ -1122,8 +1050,7 @@ gd::String EventsCodeGenerator::GenerateObjectAction(
|
||||
const gd::ObjectMetadata& objInfo,
|
||||
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" ||
|
||||
@@ -1150,11 +1077,8 @@ gd::String EventsCodeGenerator::GenerateObjectAction(
|
||||
|
||||
call = instrInfos.codeExtraInformation.functionCallName + "(" +
|
||||
argumentsStr + ")";
|
||||
|
||||
return "For each picked object \"" + objectName + "\", call " + call + "(" +
|
||||
argumentsStr + ")" +
|
||||
(optionalAsyncCallbackName.empty() ? "" : (", then call" + optionalAsyncCallbackName)) +
|
||||
".\n";
|
||||
argumentsStr + ").\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1164,8 +1088,7 @@ gd::String EventsCodeGenerator::GenerateBehaviorAction(
|
||||
const gd::BehaviorMetadata& autoInfo,
|
||||
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" ||
|
||||
@@ -1191,11 +1114,8 @@ gd::String EventsCodeGenerator::GenerateBehaviorAction(
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
@@ -155,51 +155,7 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
* \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);
|
||||
EventsCodeGenerationContext& context);
|
||||
|
||||
/**
|
||||
* \brief Generate code for declaring objects lists.
|
||||
@@ -506,10 +462,17 @@ 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
|
||||
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
|
||||
* - objectPtr : Return a reference to the object specified by the object name in
|
||||
another parameter. Example:
|
||||
* \code
|
||||
.AddParameter("object", _("Object"))
|
||||
@@ -702,16 +665,14 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
virtual gd::String GenerateFreeAction(
|
||||
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 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,
|
||||
@@ -719,8 +680,7 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
const gd::BehaviorMetadata& autoInfo,
|
||||
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,
|
||||
|
@@ -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,40 +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()) {
|
||||
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;
|
||||
|
@@ -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 {
|
||||
|
||||
@@ -137,15 +136,13 @@ class GD_CORE_API BaseEvent {
|
||||
* \note Used to preprocess or search in the expressions of the event.
|
||||
*/
|
||||
virtual std::vector<std::pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
GetAllExpressionsWithMetadata() {
|
||||
GetAllExpressionsWithMetadata() {
|
||||
std::vector<std::pair<gd::Expression*, gd::ParameterMetadata> > noExpr;
|
||||
return noExpr;
|
||||
};
|
||||
virtual std::vector<
|
||||
std::pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
GetAllExpressionsWithMetadata() const {
|
||||
std::vector<std::pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
noExpr;
|
||||
virtual std::vector<std::pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
GetAllExpressionsWithMetadata() const {
|
||||
std::vector<std::pair<const gd::Expression*, const gd::ParameterMetadata> > noExpr;
|
||||
return noExpr;
|
||||
};
|
||||
|
||||
@@ -209,11 +206,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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -218,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());
|
||||
}
|
||||
@@ -232,8 +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);
|
||||
|
@@ -42,7 +42,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
|
||||
|
@@ -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
|
@@ -343,34 +343,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
"res/actions/music.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.MarkAsComplex();
|
||||
extension
|
||||
.AddAction(
|
||||
"FadeSoundVolume",
|
||||
_("Fade the volume of a sound played on a channel."),
|
||||
_("Fade the volume of a sound played on a channel to the specified volume within the specified duration."),
|
||||
_("Fade the sound on channel _PARAM1_ to volume _PARAM2_ within _PARAM3_ seconds"),
|
||||
_("Sounds on channels"),
|
||||
"res/actions/son24.png",
|
||||
"res/actions/son.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Channel identifier"))
|
||||
.AddParameter("expression", _("Final volume (0-100)"))
|
||||
.AddParameter("expression", _("Fading time in seconds"))
|
||||
.MarkAsAdvanced();
|
||||
extension
|
||||
.AddAction(
|
||||
"FadeMusicVolume",
|
||||
_("Fade the volume of a music played on a channel."),
|
||||
_("Fade the volume of a music played on a channel to the specified volume within the specified duration."),
|
||||
_("Fade the music on channel _PARAM1_ to volume _PARAM2_ within _PARAM3_ seconds"),
|
||||
_("Music on channels"),
|
||||
"res/actions/music24.png",
|
||||
"res/actions/music.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Channel identifier"))
|
||||
.AddParameter("expression", _("Final volume (0-100)"))
|
||||
.AddParameter("expression", _("Fading time in seconds"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddCondition("MusicPlaying",
|
||||
|
@@ -1252,7 +1252,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"res/actions/create24.png",
|
||||
"res/actions/create24.png")
|
||||
.AddCodeOnlyParameter("objectsContext", "")
|
||||
.AddParameter("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)
|
||||
@@ -1270,7 +1270,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"res/actions/create24.png",
|
||||
"res/actions/create24.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"))
|
||||
@@ -1418,33 +1418,7 @@ 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(
|
||||
@@ -1552,8 +1526,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"currently picked in the event"),
|
||||
"",
|
||||
"res/conditions/nbObjet.png")
|
||||
.AddParameter("objectList", _("Object"))
|
||||
.SetHidden(); // Deprecated
|
||||
.AddParameter("objectList", _("Object"));
|
||||
|
||||
obj.AddStrExpression("ObjectName",
|
||||
_("Object name"),
|
||||
|
@@ -229,15 +229,6 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("Expression"));
|
||||
|
||||
extension
|
||||
.AddExpression("ceilTo",
|
||||
_("Ceil (round up) to a decimal point"),
|
||||
_("Round number up to the Nth decimal place"),
|
||||
"",
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("Expression"))
|
||||
.AddParameter("expression", _("Expression"), "", true);
|
||||
|
||||
extension
|
||||
.AddExpression("floor",
|
||||
_("Floor (round down)"),
|
||||
@@ -246,15 +237,6 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("Expression"));
|
||||
|
||||
extension
|
||||
.AddExpression("floorTo",
|
||||
_("Floor (round down) to a decimal point"),
|
||||
_("Round number down to the Nth decimal place"),
|
||||
"",
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("Expression"))
|
||||
.AddParameter("expression", _("Expression"), "", true);
|
||||
|
||||
extension
|
||||
.AddExpression("cos",
|
||||
_("Cosine"),
|
||||
@@ -313,15 +295,6 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("Expression"));
|
||||
|
||||
extension
|
||||
.AddExpression("roundTo",
|
||||
_("Round to a decimal point"),
|
||||
_("Round a number to the Nth decimal place"),
|
||||
"",
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("Expression"))
|
||||
.AddParameter("expression", _("Expression"), "", true);
|
||||
|
||||
extension
|
||||
.AddExpression("exp",
|
||||
_("Exponential"),
|
||||
|
@@ -311,8 +311,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
_("Multitouch"),
|
||||
"res/conditions/touch24.png",
|
||||
"res/conditions/touch.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.SetHidden();
|
||||
.AddCodeOnlyParameter("currentScene", "");
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
@@ -327,54 +326,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
_("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"),
|
||||
"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"),
|
||||
@@ -389,8 +342,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
_("Identifier of the last touch"),
|
||||
_("Multitouch"),
|
||||
"res/conditions/touch.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.SetHidden();
|
||||
.AddCodeOnlyParameter("currentScene", "");
|
||||
|
||||
extension
|
||||
.AddExpression("LastEndedTouchId",
|
||||
@@ -398,8 +350,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
_("Identifier of the last ended touch"),
|
||||
_("Multitouch"),
|
||||
"res/conditions/touch.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.SetHidden();
|
||||
.AddCodeOnlyParameter("currentScene", "");
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -121,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")));
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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"
|
||||
|
||||
|
@@ -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"
|
||||
|
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
|
@@ -20,7 +20,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
|
||||
"for slow motion effects).",
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/all-features/timers-and-time");
|
||||
.SetExtensionHelpPath("/all-features/timers");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(
|
||||
_("Timers and time")
|
||||
)
|
||||
@@ -141,6 +141,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
|
||||
_("Change time scale"),
|
||||
_("Change the time scale of the scene."),
|
||||
_("Set the time scale of the scene to _PARAM1_"),
|
||||
|
||||
"",
|
||||
"res/actions/time24.png",
|
||||
"res/actions/time.png")
|
||||
@@ -148,19 +149,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
|
||||
.AddParameter("expression",
|
||||
_("Scale (1: Default, 2: 2x faster, 0.5: 2x slower...)"));
|
||||
|
||||
extension
|
||||
.AddAction("Wait",
|
||||
_("Wait X seconds (experimental)"),
|
||||
_("Waits a number of seconds before running "
|
||||
"the next actions (and sub-events)."),
|
||||
_("Wait _PARAM0_ seconds"),
|
||||
"",
|
||||
"res/timer.svg",
|
||||
"res/timer.svg")
|
||||
.AddParameter("expression", "Time to wait in seconds")
|
||||
.SetHelpPath("/all-features/timers-and-time/wait-action")
|
||||
.SetAsync();
|
||||
|
||||
extension
|
||||
.AddExpression("TimeDelta",
|
||||
_("Time elapsed since the last frame"),
|
||||
|
@@ -8,7 +8,6 @@
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/String.h"
|
||||
|
@@ -22,7 +22,6 @@ InstructionMetadata::InstructionMetadata()
|
||||
canHaveSubInstructions(false),
|
||||
hidden(true),
|
||||
usageComplexity(5),
|
||||
isAsync(false),
|
||||
isPrivate(false),
|
||||
isObjectInstruction(false),
|
||||
isBehaviorInstruction(false) {}
|
||||
@@ -46,7 +45,6 @@ InstructionMetadata::InstructionMetadata(const gd::String& extensionNamespace_,
|
||||
extensionNamespace(extensionNamespace_),
|
||||
hidden(false),
|
||||
usageComplexity(5),
|
||||
isAsync(false),
|
||||
isPrivate(false),
|
||||
isObjectInstruction(false),
|
||||
isBehaviorInstruction(false) {}
|
||||
|
@@ -9,7 +9,6 @@
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/String.h"
|
||||
@@ -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 isAsync; }
|
||||
|
||||
/**
|
||||
* Set that the instruction is asynchronous - it will be running in the
|
||||
* background, executing the instructions following it before the frame after
|
||||
* it resolved.
|
||||
*/
|
||||
InstructionMetadata &SetAsync() {
|
||||
isAsync = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify that the instruction can have sub instructions.
|
||||
*/
|
||||
@@ -479,7 +461,6 @@ class GD_CORE_API InstructionMetadata {
|
||||
int usageComplexity; ///< Evaluate the instruction from 0 (simple&easy to
|
||||
///< use) to 10 (complex to understand)
|
||||
bool isPrivate;
|
||||
bool isAsync;
|
||||
bool isObjectInstruction;
|
||||
bool isBehaviorInstruction;
|
||||
gd::String requiredBaseObjectCapability;
|
||||
|
@@ -9,7 +9,6 @@
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class Project;
|
||||
@@ -152,16 +151,15 @@ class GD_CORE_API ParameterMetadata {
|
||||
}
|
||||
|
||||
/**
|
||||
* \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
|
||||
*/
|
||||
static bool IsObject(const gd::String ¶meterType) {
|
||||
return parameterType == "object" || parameterType == "objectPtr" ||
|
||||
parameterType == "objectList" ||
|
||||
parameterType == "objectListOrEmptyIfJustDeclared" ||
|
||||
parameterType == "objectListOrEmptyWithoutPicking";
|
||||
parameterType == "objectListWithoutPicking";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,8 +196,7 @@ class GD_CORE_API ParameterMetadata {
|
||||
parameterType == "objectPointName" ||
|
||||
parameterType == "objectAnimationName" ||
|
||||
parameterType == "functionParameterName" ||
|
||||
parameterType == "externalLayoutName" ||
|
||||
parameterType == "leaderboardId";
|
||||
parameterType == "externalLayoutName";
|
||||
} else if (type == "variable") {
|
||||
return parameterType == "objectvar" || parameterType == "globalvar" ||
|
||||
parameterType == "scenevar";
|
||||
|
@@ -117,16 +117,6 @@ void EffectsContainer::SwapEffects(std::size_t firstEffectIndex,
|
||||
effects[secondEffectIndex] = temp;
|
||||
}
|
||||
|
||||
void EffectsContainer::MoveEffect(std::size_t oldIndex, std::size_t newIndex) {
|
||||
if (oldIndex >= effects.size() || newIndex >= effects.size() ||
|
||||
newIndex == oldIndex)
|
||||
return;
|
||||
|
||||
auto effect = effects[oldIndex];
|
||||
effects.erase(effects.begin() + oldIndex);
|
||||
effects.insert(effects.begin() + newIndex, effect);
|
||||
}
|
||||
|
||||
void EffectsContainer::SerializeTo(SerializerElement& element) const {
|
||||
element.ConsiderAsArrayOf("effect");
|
||||
for (std::size_t i = 0; i < GetEffectsCount(); ++i) {
|
||||
|
@@ -7,7 +7,6 @@
|
||||
#define GDCORE_EFFECTS_CONTAINER_H
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "GDCore/String.h"
|
||||
|
||||
@@ -90,11 +89,6 @@ class GD_CORE_API EffectsContainer {
|
||||
*/
|
||||
void RemoveEffect(const gd::String& name);
|
||||
|
||||
/**
|
||||
* \brief Move the specified effect at a new position in the list.
|
||||
*/
|
||||
void MoveEffect(std::size_t oldIndex, std::size_t newIndex);
|
||||
|
||||
/**
|
||||
* Swap the position of two effects.
|
||||
*/
|
||||
|
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
#ifndef GDCORE_OBJECT_H
|
||||
#define GDCORE_OBJECT_H
|
||||
#include "GDCore/Vector2.h"
|
||||
#include <SFML/System/Vector2.hpp>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
@@ -7,7 +7,6 @@
|
||||
#ifndef GDCORE_OBJECTGROUPSCONTAINER_H
|
||||
#define GDCORE_OBJECTGROUPSCONTAINER_H
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "GDCore/Project/ObjectGroup.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
@@ -78,6 +77,7 @@ class GD_CORE_API ObjectGroupsContainer {
|
||||
*/
|
||||
bool IsEmpty() const { return objectGroups.empty(); };
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* \brief return the position of the group called "name" in the group list
|
||||
*/
|
||||
@@ -107,6 +107,7 @@ class GD_CORE_API ObjectGroupsContainer {
|
||||
* \brief Move the specified group at a new position in the list.
|
||||
*/
|
||||
void Move(std::size_t oldIndex, std::size_t newIndex);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Clear all groups of the container.
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <SFML/System/Utf.hpp>
|
||||
#include <cctype>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
|
@@ -92,7 +92,7 @@ double Variable::GetValue() const {
|
||||
return value;
|
||||
} else if (type == Type::String) {
|
||||
double retVal = str.empty() ? 0.0 : str.To<double>();
|
||||
if (std::isnan(retVal)) retVal = 0.0;
|
||||
if(std::isnan(retVal)) retVal = 0.0;
|
||||
return retVal;
|
||||
} else if (type == Type::Boolean) {
|
||||
return boolVal ? 1.0 : 0.0;
|
||||
@@ -188,15 +188,6 @@ const Variable& Variable::GetAtIndex(const size_t index) const {
|
||||
return *childrenArray.at(index);
|
||||
};
|
||||
|
||||
void Variable::MoveChildInArray(const size_t oldIndex, const size_t newIndex) {
|
||||
if (oldIndex >= childrenArray.size() || newIndex >= childrenArray.size())
|
||||
return;
|
||||
|
||||
std::shared_ptr<gd::Variable> object = std::move(childrenArray[oldIndex]);
|
||||
childrenArray.erase(childrenArray.begin() + oldIndex);
|
||||
childrenArray.insert(childrenArray.begin() + newIndex, std::move(object));
|
||||
}
|
||||
|
||||
Variable& Variable::PushNew() { return GetAtIndex(GetChildrenCount()); };
|
||||
|
||||
void Variable::RemoveAtIndex(const size_t index) {
|
||||
@@ -204,29 +195,8 @@ void Variable::RemoveAtIndex(const size_t index) {
|
||||
childrenArray.erase(childrenArray.begin() + index);
|
||||
};
|
||||
|
||||
bool Variable::InsertAtIndex(const gd::Variable& variable, const size_t index) {
|
||||
if (type != Type::Array) return false;
|
||||
auto newVariable = std::make_shared<gd::Variable>(variable);
|
||||
if (index < childrenArray.size()) {
|
||||
childrenArray.insert(childrenArray.begin() + index, newVariable);
|
||||
} else {
|
||||
childrenArray.push_back(newVariable);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
bool Variable::InsertChild(const gd::String& name,
|
||||
const gd::Variable& variable) {
|
||||
if (type != Type::Structure || HasChild(name)) {
|
||||
return false;
|
||||
}
|
||||
children[name] = std::make_shared<gd::Variable>(variable);
|
||||
return true;
|
||||
};
|
||||
|
||||
void Variable::SerializeTo(SerializerElement& element) const {
|
||||
element.SetStringAttribute("type", TypeAsString(GetType()));
|
||||
if (IsFolded()) element.SetBoolAttribute("folded", true);
|
||||
|
||||
if (type == Type::String) {
|
||||
element.SetStringAttribute("value", GetString());
|
||||
@@ -264,7 +234,6 @@ void Variable::UnserializeFrom(const SerializerElement& element) {
|
||||
if (element.HasChild("children", "Children") && IsPrimitive(type))
|
||||
type = Type::Structure;
|
||||
// end of compatibility code
|
||||
SetFolded(element.GetBoolAttribute("folded", false));
|
||||
|
||||
if (IsPrimitive(type)) {
|
||||
if (type == Type::String) {
|
||||
@@ -336,7 +305,6 @@ void Variable::RemoveRecursively(const gd::Variable& variableToRemove) {
|
||||
Variable::Variable(const Variable& other)
|
||||
: value(other.value),
|
||||
str(other.str),
|
||||
folded(other.folded),
|
||||
boolVal(other.boolVal),
|
||||
type(other.type) {
|
||||
CopyChildren(other);
|
||||
@@ -346,7 +314,6 @@ Variable& Variable::operator=(const Variable& other) {
|
||||
if (this != &other) {
|
||||
value = other.value;
|
||||
str = other.str;
|
||||
folded = other.folded;
|
||||
boolVal = other.boolVal;
|
||||
type = other.type;
|
||||
CopyChildren(other);
|
||||
|
@@ -6,10 +6,10 @@
|
||||
|
||||
#ifndef GDCORE_VARIABLE_H
|
||||
#define GDCORE_VARIABLE_H
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
@@ -98,7 +98,7 @@ class GD_CORE_API Variable {
|
||||
void SetValue(double val) {
|
||||
value = val;
|
||||
// NaN values are not supported by GDevelop nor the serializer.
|
||||
if (std::isnan(value)) value = 0.0;
|
||||
if(std::isnan(value)) value = 0.0;
|
||||
type = Type::Number;
|
||||
}
|
||||
|
||||
@@ -185,9 +185,9 @@ class GD_CORE_API Variable {
|
||||
* \brief Get the count of children that the variable has.
|
||||
*/
|
||||
size_t GetChildrenCount() const {
|
||||
return type == Type::Structure ? children.size()
|
||||
: type == Type::Array ? childrenArray.size()
|
||||
: 0;
|
||||
return type == Type::Structure
|
||||
? children.size()
|
||||
: type == Type::Array ? childrenArray.size() : 0;
|
||||
};
|
||||
|
||||
/** \name Structure
|
||||
@@ -290,38 +290,12 @@ class GD_CORE_API Variable {
|
||||
*/
|
||||
void RemoveAtIndex(const size_t index);
|
||||
|
||||
/**
|
||||
* \brief Move child in array.
|
||||
*/
|
||||
void MoveChildInArray(const size_t oldIndex, const size_t newIndex);
|
||||
|
||||
/**
|
||||
* \brief Insert child in array.
|
||||
*/
|
||||
bool InsertAtIndex(const gd::Variable& variable, const size_t index);
|
||||
|
||||
/**
|
||||
* \brief Insert a child in a structure.
|
||||
*/
|
||||
bool InsertChild(const gd::String& name, const gd::Variable& variable);
|
||||
|
||||
/**
|
||||
* \brief Get the vector containing all the children.
|
||||
*/
|
||||
const std::vector<std::shared_ptr<Variable>>& GetAllChildrenArray() const {
|
||||
return childrenArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set if the children must be folded.
|
||||
*/
|
||||
void SetFolded(bool fold = true) { folded = fold; }
|
||||
|
||||
/**
|
||||
* \brief True if the children should be folded in the variables editor.
|
||||
*/
|
||||
bool IsFolded() const { return folded; }
|
||||
|
||||
///@}
|
||||
///@}
|
||||
|
||||
@@ -351,7 +325,6 @@ class GD_CORE_API Variable {
|
||||
*/
|
||||
static Type StringAsType(const gd::String& str);
|
||||
|
||||
bool folded;
|
||||
mutable Type type;
|
||||
mutable gd::String str;
|
||||
mutable double value;
|
||||
|
@@ -4,10 +4,8 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/Project/VariablesContainer.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
#include "GDCore/Project/Variable.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/String.h"
|
||||
@@ -90,6 +88,7 @@ Variable& VariablesContainer::Insert(const gd::String& name,
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void VariablesContainer::Remove(const gd::String& varName) {
|
||||
variables.erase(
|
||||
std::remove_if(
|
||||
@@ -152,14 +151,13 @@ void VariablesContainer::Swap(std::size_t firstVariableIndex,
|
||||
}
|
||||
|
||||
void VariablesContainer::Move(std::size_t oldIndex, std::size_t newIndex) {
|
||||
if (oldIndex >= variables.size() || newIndex >= variables.size() ||
|
||||
oldIndex == newIndex)
|
||||
return;
|
||||
if (oldIndex >= variables.size() || newIndex >= variables.size()) return;
|
||||
|
||||
auto nameAndVariable = variables[oldIndex];
|
||||
variables.erase(variables.begin() + oldIndex);
|
||||
variables.insert(variables.begin() + newIndex, nameAndVariable);
|
||||
}
|
||||
#endif
|
||||
|
||||
void VariablesContainer::SerializeTo(SerializerElement& element) const {
|
||||
element.ConsiderAsArrayOf("variable");
|
||||
|
@@ -77,6 +77,8 @@ bool SerializerElement::GetBoolAttribute(const gd::String& name,
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Bool attribute \"" << name << "\" not found, returning "
|
||||
<< defaultValue;
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
|
||||
#include <SFML/System/String.hpp>
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Utf8/utf8proc.h"
|
||||
|
||||
@@ -27,6 +28,11 @@ String::String(const char *characters) : m_string()
|
||||
*this = characters;
|
||||
}
|
||||
|
||||
String::String(const sf::String &string) : m_string()
|
||||
{
|
||||
*this = string;
|
||||
}
|
||||
|
||||
String::String(const std::u32string &string) : m_string()
|
||||
{
|
||||
*this = string;
|
||||
@@ -38,6 +44,26 @@ String& String::operator=(const char *characters)
|
||||
return *this;
|
||||
}
|
||||
|
||||
String& String::operator=(const sf::String &string)
|
||||
{
|
||||
m_string.clear();
|
||||
|
||||
//In theory, an UTF8 character can be up to 6 bytes (even if in the current Unicode standard,
|
||||
//the last character is 4 bytes long when encoded in UTF8).
|
||||
//So, reserve the maximum possible size to avoid reallocations.
|
||||
m_string.reserve( string.getSize() * 6 );
|
||||
|
||||
//Push_back all characters inside the string.
|
||||
for( sf::String::ConstIterator it = string.begin(); it != string.end(); ++it )
|
||||
{
|
||||
push_back( *it );
|
||||
}
|
||||
|
||||
m_string.shrink_to_fit();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
String& String::operator=(const std::u32string &string)
|
||||
{
|
||||
m_string.clear();
|
||||
@@ -86,7 +112,7 @@ String::const_iterator String::end() const
|
||||
String String::FromLocale( const std::string &localizedString )
|
||||
{
|
||||
#if defined(WINDOWS)
|
||||
return FromUTF8(localizedString); //Don't need to use the current locale, on Windows, std::locale is always the C locale
|
||||
return FromSfString(sf::String(localizedString)); //Don't need to use the current locale, on Windows, std::locale is always the C locale
|
||||
#elif defined(MACOS)
|
||||
return FromUTF8(localizedString); //Assume UTF8 is the current locale
|
||||
#elif defined(EMSCRIPTEN)
|
||||
@@ -98,7 +124,7 @@ String String::FromLocale( const std::string &localizedString )
|
||||
std::locale("").name().find("UTF8") != std::string::npos)
|
||||
return FromUTF8(localizedString); //UTF8 is already the current locale
|
||||
else
|
||||
return FromUTF8(localizedString); //Use the current locale (std::locale("")) for conversion
|
||||
return FromSfString(sf::String(localizedString, std::locale(""))); //Use the current locale (std::locale("")) for conversion
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -110,6 +136,11 @@ String String::FromUTF32( const std::u32string &string )
|
||||
return str;
|
||||
}
|
||||
|
||||
String String::FromSfString( const sf::String &sfString )
|
||||
{
|
||||
return String(sfString);
|
||||
}
|
||||
|
||||
String String::FromUTF8( const std::string &utf8Str )
|
||||
{
|
||||
String str(utf8Str.c_str());
|
||||
@@ -133,7 +164,7 @@ String String::FromWide( const std::wstring &wstr )
|
||||
std::string String::ToLocale() const
|
||||
{
|
||||
#if defined(WINDOWS)
|
||||
return m_string;
|
||||
return ToSfString().toAnsiString();
|
||||
#elif defined(MACOS)
|
||||
return m_string;
|
||||
#elif defined(EMSCRIPTEN)
|
||||
@@ -145,7 +176,7 @@ std::string String::ToLocale() const
|
||||
std::locale("").name().find("UTF8") != std::string::npos)
|
||||
return m_string; //UTF8 is already the current locale on Linux
|
||||
else
|
||||
return m_string; //Use the current locale for conversion
|
||||
return ToSfString().toAnsiString(std::locale("")); //Use the current locale for conversion
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -160,6 +191,20 @@ std::u32string String::ToUTF32() const
|
||||
return u32str;
|
||||
}
|
||||
|
||||
sf::String String::ToSfString() const
|
||||
{
|
||||
sf::String str;
|
||||
for(const_iterator it = begin(); it != end(); ++it)
|
||||
str += sf::String(static_cast<sf::Uint32>(*it));
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
String::operator sf::String() const
|
||||
{
|
||||
return ToSfString();
|
||||
}
|
||||
|
||||
std::string String::ToUTF8() const
|
||||
{
|
||||
return m_string;
|
||||
|
@@ -13,9 +13,12 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <SFML/System/String.hpp>
|
||||
|
||||
#include "GDCore/Utf8/utf8.h"
|
||||
|
||||
namespace sf {class String;};
|
||||
|
||||
namespace gd
|
||||
{
|
||||
|
||||
@@ -118,6 +121,11 @@ public:
|
||||
*/
|
||||
String(const std::u32string &string);
|
||||
|
||||
/**
|
||||
* Constructs a string from an sf::String.
|
||||
*/
|
||||
String(const sf::String &string);
|
||||
|
||||
/**
|
||||
* \}
|
||||
*/
|
||||
@@ -138,6 +146,8 @@ public:
|
||||
*/
|
||||
String& operator=(const char *characters);
|
||||
|
||||
String& operator=(const sf::String &string);
|
||||
|
||||
String& operator=(const std::u32string &string);
|
||||
|
||||
/**
|
||||
@@ -219,6 +229,7 @@ public:
|
||||
static String From(T value)
|
||||
{
|
||||
static_assert(!std::is_same<T, std::string>::value, "Can't use gd::String::From with std::string.");
|
||||
static_assert(!std::is_same<T, sf::String>::value, "Can't use gd::String::From with sf::String.");
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << value;
|
||||
@@ -233,6 +244,7 @@ public:
|
||||
T To() const
|
||||
{
|
||||
static_assert(!std::is_same<T, std::string>::value, "Can't use gd::String::To with std::string.");
|
||||
static_assert(!std::is_same<T, sf::String>::value, "Can't use gd::String::To with sf::String.");
|
||||
|
||||
T value;
|
||||
std::istringstream oss(m_string);
|
||||
@@ -262,6 +274,13 @@ public:
|
||||
*/
|
||||
static String FromUTF32( const std::u32string &string );
|
||||
|
||||
/**
|
||||
* \return a String created from a sf::String (UTF32).
|
||||
*
|
||||
* See \ref Conversions1 for more information.
|
||||
*/
|
||||
static String FromSfString( const sf::String &sfString );
|
||||
|
||||
/**
|
||||
* \return a String created an UTF8 encoded std::string.
|
||||
*/
|
||||
@@ -293,6 +312,20 @@ public:
|
||||
*/
|
||||
std::u32string ToUTF32() const;
|
||||
|
||||
/**
|
||||
* \return a sf::String from the current string.
|
||||
*
|
||||
* See \ref Conversions1 for more information.
|
||||
*/
|
||||
sf::String ToSfString() const;
|
||||
|
||||
/**
|
||||
* Implicit conversion operator to sf::String.
|
||||
*
|
||||
* See \ref Conversions1 for more information.
|
||||
*/
|
||||
operator sf::String() const;
|
||||
|
||||
/**
|
||||
* \return a UTF8 encoded std::string from the current string.
|
||||
*/
|
||||
@@ -852,7 +885,7 @@ namespace std
|
||||
* on the string size and so is the operator[]().
|
||||
*
|
||||
* \section Conversion Conversions from/to other string types
|
||||
* The String handles implicit conversion with std::String (implicit constructor and implicit conversion
|
||||
* The String handles implicit conversion with sf::String (implicit constructor and implicit conversion
|
||||
* operator).
|
||||
*
|
||||
* **However, this is not the case with std::string** as this conversion is not often lossless (mostly on Windows).
|
||||
@@ -861,6 +894,16 @@ namespace std
|
||||
* directly use the operator=() or the constructor as they are supporting const char* as argument (it assumes the string
|
||||
* literal is encoded in UTF8, so you'll need to put the u8 prefix).
|
||||
*
|
||||
* \subsection Conversions1 Implicit conversion from/to sf::String
|
||||
* \code
|
||||
* //Get a String from sf::String
|
||||
* sf::String sfmlStr("This is a test ! ");
|
||||
* gd::String str1(sfmlStr); //Now contains "This is a test ! " encoded in UTF8
|
||||
*
|
||||
* //Get a sf::String from String
|
||||
* sf::String anotherSfmlString = str; //anotherSfmlString now contains "Another test ! "
|
||||
* \endcode
|
||||
*
|
||||
* \subsection Conversions2 Conversion from/to std::string
|
||||
* \code
|
||||
* //Get a String from a std::string encoded in the current locale
|
||||
|
200
Core/GDCore/Tools/FileStream.cpp
Normal file
200
Core/GDCore/Tools/FileStream.cpp
Normal file
@@ -0,0 +1,200 @@
|
||||
#include "GDCore/Tools/FileStream.h"
|
||||
|
||||
#if defined(WINDOWS)
|
||||
#if __GLIBCXX__
|
||||
#include <ext/stdio_filebuf.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace gd {
|
||||
|
||||
namespace {
|
||||
|
||||
#if FSTREAM_WINDOWS_MINGW
|
||||
|
||||
#define MODE(in_val, out_val, trunc_val, app_val) \
|
||||
((((mode & std::ios_base::in) != 0) == in_val) && \
|
||||
(((mode & std::ios_base::out) != 0) == out_val) && \
|
||||
(((mode & std::ios_base::trunc) != 0) == trunc_val) && \
|
||||
(((mode & std::ios_base::app) != 0) == app_val))
|
||||
|
||||
std::wstring GetStdioMode(std::ios_base::openmode mode) {
|
||||
std::wstring strMode;
|
||||
|
||||
/// Thanks to https://gcc.gnu.org/ml/libstdc++/2007-06/msg00013.html
|
||||
if (MODE(false, true, false, false))
|
||||
strMode += L"w";
|
||||
else if (MODE(false, true, false, true))
|
||||
strMode += L"a";
|
||||
else if (MODE(true, true, false, true))
|
||||
strMode += L"a+";
|
||||
else if (MODE(false, true, true, false))
|
||||
strMode += L"w";
|
||||
else if (MODE(true, false, false, false))
|
||||
strMode += L"r";
|
||||
else if (MODE(true, true, false, false))
|
||||
strMode += L"r+";
|
||||
else if (MODE(true, true, true, false))
|
||||
strMode += L"w+";
|
||||
|
||||
if ((mode & std::ios_base::binary) != 0) strMode += L"b";
|
||||
|
||||
return strMode;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Open the given file into a filebuf and return it.
|
||||
* On Windows, return the associated FILE* inside the file argument.
|
||||
*/
|
||||
FileStream::InternalBufferType* OpenBuffer(const gd::String& path,
|
||||
std::ios_base::openmode mode,
|
||||
FILE** file) {
|
||||
#if FSTREAM_WINDOWS_MINGW
|
||||
*file = _wfopen(path.ToWide().c_str(), GetStdioMode(mode).c_str());
|
||||
if (!(*file)) return nullptr;
|
||||
return new __gnu_cxx::stdio_filebuf<char>(*file, mode);
|
||||
#else
|
||||
auto* filebuffer = new std::filebuf();
|
||||
return filebuffer->open(path.ToLocale().c_str(), mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
FileStream::FileStream() : std::iostream(nullptr) {}
|
||||
|
||||
FileStream::FileStream(const gd::String& path, std::ios_base::openmode mode)
|
||||
: std::iostream(nullptr),
|
||||
m_file(nullptr),
|
||||
m_buffer(OpenBuffer(path, mode, &m_file)) {
|
||||
setstate(ios_base::goodbit);
|
||||
if (m_buffer) {
|
||||
std::iostream::init(m_buffer.get());
|
||||
if ((mode & std::ios_base::ate) != 0) seekg(0, end);
|
||||
} else
|
||||
setstate(ios_base::badbit);
|
||||
}
|
||||
|
||||
FileStream::~FileStream() {
|
||||
if (is_open()) close();
|
||||
}
|
||||
|
||||
/*
|
||||
WILL WORK with GCC>=5 (not 4.9 used on Windows)
|
||||
FileStream::FileStream(FileStream && other) :
|
||||
std::iostream(std::move(other)),
|
||||
m_buffer(std::move(other.m_buffer))
|
||||
{
|
||||
|
||||
}*/
|
||||
|
||||
/*FileStream& FileStream::operator=(FileStream && other)
|
||||
{
|
||||
std::iostream::operator=(std::move(other));
|
||||
m_buffer = std::move(other.m_buffer);
|
||||
}*/
|
||||
|
||||
void FileStream::open(const gd::String& path, std::ios_base::openmode mode) {
|
||||
setstate(ios_base::goodbit);
|
||||
|
||||
if (is_open()) {
|
||||
setstate(ios_base::failbit);
|
||||
std::cout << "is_open true when trying to open!" << std::endl;
|
||||
} else {
|
||||
auto* newBuffer = OpenBuffer(path, mode, &m_file);
|
||||
if (newBuffer) {
|
||||
m_buffer.reset(newBuffer);
|
||||
std::iostream::init(m_buffer.get());
|
||||
if ((mode & std::ios_base::ate) != 0) seekg(0, end);
|
||||
} else {
|
||||
setstate(ios_base::badbit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool FileStream::is_open() const {
|
||||
if (!m_buffer) return false;
|
||||
return m_buffer->is_open();
|
||||
}
|
||||
|
||||
void FileStream::close() {
|
||||
#if FSTREAM_WINDOWS_MINGW
|
||||
if (m_buffer) m_buffer->close();
|
||||
|
||||
if (m_file && fclose(m_file) != 0) {
|
||||
setstate(ios_base::failbit);
|
||||
}
|
||||
|
||||
m_buffer.reset(nullptr);
|
||||
m_file = nullptr;
|
||||
#else
|
||||
if (!m_buffer || m_buffer->close() == nullptr) {
|
||||
setstate(ios_base::failbit);
|
||||
} else {
|
||||
m_buffer.reset(nullptr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*void FileStream::swap(FileStream & other) //WILL WORK with GCC>=5 (not 4.9
|
||||
used on Windows)
|
||||
{
|
||||
std::iostream::swap(other);
|
||||
std::swap(m_buffer, other.m_buffer);
|
||||
}*/
|
||||
|
||||
SFMLFileStream::SFMLFileStream() : m_file(nullptr) {}
|
||||
|
||||
SFMLFileStream::~SFMLFileStream() {
|
||||
if (m_file) fclose(m_file);
|
||||
}
|
||||
|
||||
bool SFMLFileStream::open(const gd::String& filename) {
|
||||
if (m_file) fclose(m_file);
|
||||
|
||||
#if FSTREAM_WINDOWS_MINGW
|
||||
m_file = _wfopen(filename.ToWide().c_str(), L"rb");
|
||||
#else
|
||||
m_file = fopen(filename.ToLocale().c_str(), "rb");
|
||||
#endif
|
||||
|
||||
return m_file != NULL;
|
||||
}
|
||||
|
||||
sf::Int64 SFMLFileStream::read(void* data, sf::Int64 size) {
|
||||
if (m_file)
|
||||
return fread(data, 1, static_cast<std::size_t>(size), m_file);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
sf::Int64 SFMLFileStream::seek(sf::Int64 position) {
|
||||
if (m_file) {
|
||||
fseek(m_file, static_cast<std::size_t>(position), SEEK_SET);
|
||||
return tell();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
sf::Int64 SFMLFileStream::tell() {
|
||||
if (m_file)
|
||||
return ftell(m_file);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
sf::Int64 SFMLFileStream::getSize() {
|
||||
if (m_file) {
|
||||
sf::Int64 position = tell();
|
||||
fseek(m_file, 0, SEEK_END);
|
||||
sf::Int64 size = tell();
|
||||
seek(position);
|
||||
return size;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gd
|
82
Core/GDCore/Tools/FileStream.h
Normal file
82
Core/GDCore/Tools/FileStream.h
Normal file
@@ -0,0 +1,82 @@
|
||||
#ifndef GDCORE_FSTREAMTOOLS
|
||||
#define GDCORE_FSTREAMTOOLS
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
#include <SFML/System.hpp>
|
||||
|
||||
#include "GDCore/String.h"
|
||||
|
||||
#if defined(WINDOWS) && __GLIBCXX__
|
||||
#include <ext/stdio_filebuf.h>
|
||||
#else
|
||||
#include <fstream> //for std::filebuf
|
||||
#endif
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* Similar to std::i/ofstream except that it can open file with
|
||||
* gd::String paths (useful on Windows where fstream doesn't
|
||||
* support wide paths).
|
||||
*/
|
||||
class GD_CORE_API FileStream : public std::iostream {
|
||||
public:
|
||||
#if defined(WINDOWS) && __GLIBCXX__
|
||||
using InternalBufferType = std::basic_filebuf<char>;
|
||||
#else
|
||||
using InternalBufferType = std::filebuf;
|
||||
#endif
|
||||
|
||||
FileStream();
|
||||
FileStream(const gd::String& path, std::ios_base::openmode mode);
|
||||
~FileStream();
|
||||
|
||||
FileStream(const FileStream& other) = delete;
|
||||
FileStream(FileStream&& other) = delete; // HACK for GCC 4.9 (Windows)
|
||||
// FileStream(FileStream && other); WILL WORK with GCC>=5 (not 4.9 used on
|
||||
// Windows)
|
||||
|
||||
FileStream& operator=(const FileStream& other) = delete;
|
||||
FileStream& operator=(FileStream&& other) =
|
||||
delete; // HACK for GCC 4.9 (Windows)
|
||||
// FileStream& operator=(FileStream && other); WILL WORK with GCC>=5 (not 4.9
|
||||
// used on Windows)
|
||||
|
||||
void open(const gd::String& path, std::ios_base::openmode mode);
|
||||
|
||||
bool is_open() const;
|
||||
|
||||
void close();
|
||||
|
||||
// void swap(FileStream & other); //WILL WORK with GCC>=5 (not 4.9 used on
|
||||
// Windows)
|
||||
|
||||
private:
|
||||
FILE* m_file;
|
||||
std::unique_ptr<InternalBufferType> m_buffer;
|
||||
};
|
||||
|
||||
class GD_CORE_API SFMLFileStream : public sf::InputStream {
|
||||
public:
|
||||
SFMLFileStream();
|
||||
~SFMLFileStream();
|
||||
|
||||
bool open(const gd::String& filename);
|
||||
|
||||
virtual sf::Int64 read(void* data, sf::Int64 size);
|
||||
|
||||
virtual sf::Int64 seek(sf::Int64 position);
|
||||
|
||||
virtual sf::Int64 tell();
|
||||
|
||||
virtual sf::Int64 getSize();
|
||||
|
||||
private:
|
||||
FILE* m_file;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif
|
19
Core/GDCore/Tools/OpenGLTools.cpp
Normal file
19
Core/GDCore/Tools/OpenGLTools.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <SFML/OpenGL.hpp>
|
||||
#include <cmath>
|
||||
|
||||
namespace OpenGLTools {
|
||||
|
||||
void GD_CORE_API PerspectiveGL(GLdouble fovY,
|
||||
GLdouble aspect,
|
||||
GLdouble zNear,
|
||||
GLdouble zFar) {
|
||||
const GLdouble pi = 3.1415926535897932384626433832795;
|
||||
GLdouble fW, fH;
|
||||
|
||||
fH = std::tan(fovY / 360 * pi) * zNear;
|
||||
fW = fH * aspect;
|
||||
|
||||
glFrustum(-fW, fW, -fH, fH, zNear, zFar);
|
||||
}
|
||||
|
||||
} // namespace OpenGLTools
|
9
Core/GDCore/Tools/OpenGLTools.h
Normal file
9
Core/GDCore/Tools/OpenGLTools.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#include <SFML/OpenGL.hpp>
|
||||
|
||||
namespace OpenGLTools {
|
||||
|
||||
void GD_CORE_API PerspectiveGL(GLdouble fovY,
|
||||
GLdouble aspect,
|
||||
GLdouble zNear,
|
||||
GLdouble zFar);
|
||||
}
|
@@ -1,360 +0,0 @@
|
||||
// This is adapted from SFML (https://github.com/SFML/SFML).
|
||||
|
||||
#ifndef GDCORE_VECTOR2_H
|
||||
#define GDCORE_VECTOR2_H
|
||||
|
||||
namespace gd
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Utility template class for manipulating
|
||||
/// 2-dimensional vectors
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
class Vector2
|
||||
{
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Default constructor
|
||||
///
|
||||
/// Creates a Vector2(0, 0).
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
inline Vector2() :
|
||||
x(0),
|
||||
y(0)
|
||||
{
|
||||
|
||||
}
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Construct the vector from its coordinates
|
||||
///
|
||||
/// \param X X coordinate
|
||||
/// \param Y Y coordinate
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
inline Vector2(T X, T Y) :
|
||||
x(X),
|
||||
y(Y)
|
||||
{
|
||||
|
||||
}
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Construct the vector from another type of vector
|
||||
///
|
||||
/// This constructor doesn't replace the copy constructor,
|
||||
/// it's called only when U != T.
|
||||
/// A call to this constructor will fail to compile if U
|
||||
/// is not convertible to T.
|
||||
///
|
||||
/// \param vector Vector to convert
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename U>
|
||||
inline explicit Vector2(const Vector2<U>& vector) :
|
||||
x(static_cast<T>(vector.x)),
|
||||
y(static_cast<T>(vector.y))
|
||||
{
|
||||
}
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
T x; ///< X coordinate of the vector
|
||||
T y; ///< Y coordinate of the vector
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of unary operator -
|
||||
///
|
||||
/// \param right Vector to negate
|
||||
///
|
||||
/// \return Memberwise opposite of the vector
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline Vector2<T> operator -(const Vector2<T>& right)
|
||||
{
|
||||
return Vector2<T>(-right.x, -right.y);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of binary operator +=
|
||||
///
|
||||
/// This operator performs a memberwise addition of both vectors,
|
||||
/// and assigns the result to \a left.
|
||||
///
|
||||
/// \param left Left operand (a vector)
|
||||
/// \param right Right operand (a vector)
|
||||
///
|
||||
/// \return Reference to \a left
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline Vector2<T>& operator +=(Vector2<T>& left, const Vector2<T>& right)
|
||||
{
|
||||
left.x += right.x;
|
||||
left.y += right.y;
|
||||
|
||||
return left;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of binary operator -=
|
||||
///
|
||||
/// This operator performs a memberwise subtraction of both vectors,
|
||||
/// and assigns the result to \a left.
|
||||
///
|
||||
/// \param left Left operand (a vector)
|
||||
/// \param right Right operand (a vector)
|
||||
///
|
||||
/// \return Reference to \a left
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline Vector2<T>& operator -=(Vector2<T>& left, const Vector2<T>& right)
|
||||
{
|
||||
left.x -= right.x;
|
||||
left.y -= right.y;
|
||||
|
||||
return left;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of binary operator +
|
||||
///
|
||||
/// \param left Left operand (a vector)
|
||||
/// \param right Right operand (a vector)
|
||||
///
|
||||
/// \return Memberwise addition of both vectors
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline Vector2<T> operator +(const Vector2<T>& left, const Vector2<T>& right)
|
||||
{
|
||||
return Vector2<T>(left.x + right.x, left.y + right.y);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of binary operator -
|
||||
///
|
||||
/// \param left Left operand (a vector)
|
||||
/// \param right Right operand (a vector)
|
||||
///
|
||||
/// \return Memberwise subtraction of both vectors
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline Vector2<T> operator -(const Vector2<T>& left, const Vector2<T>& right)
|
||||
{
|
||||
return Vector2<T>(left.x - right.x, left.y - right.y);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of binary operator *
|
||||
///
|
||||
/// \param left Left operand (a vector)
|
||||
/// \param right Right operand (a scalar value)
|
||||
///
|
||||
/// \return Memberwise multiplication by \a right
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline Vector2<T> operator *(const Vector2<T>& left, T right)
|
||||
{
|
||||
return Vector2<T>(left.x * right, left.y * right);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of binary operator *
|
||||
///
|
||||
/// \param left Left operand (a scalar value)
|
||||
/// \param right Right operand (a vector)
|
||||
///
|
||||
/// \return Memberwise multiplication by \a left
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline Vector2<T> operator *(T left, const Vector2<T>& right)
|
||||
{
|
||||
return Vector2<T>(right.x * left, right.y * left);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of binary operator *=
|
||||
///
|
||||
/// This operator performs a memberwise multiplication by \a right,
|
||||
/// and assigns the result to \a left.
|
||||
///
|
||||
/// \param left Left operand (a vector)
|
||||
/// \param right Right operand (a scalar value)
|
||||
///
|
||||
/// \return Reference to \a left
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline Vector2<T>& operator *=(Vector2<T>& left, T right)
|
||||
{
|
||||
left.x *= right;
|
||||
left.y *= right;
|
||||
|
||||
return left;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of binary operator /
|
||||
///
|
||||
/// \param left Left operand (a vector)
|
||||
/// \param right Right operand (a scalar value)
|
||||
///
|
||||
/// \return Memberwise division by \a right
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline Vector2<T> operator /(const Vector2<T>& left, T right)
|
||||
{
|
||||
return Vector2<T>(left.x / right, left.y / right);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of binary operator /=
|
||||
///
|
||||
/// This operator performs a memberwise division by \a right,
|
||||
/// and assigns the result to \a left.
|
||||
///
|
||||
/// \param left Left operand (a vector)
|
||||
/// \param right Right operand (a scalar value)
|
||||
///
|
||||
/// \return Reference to \a left
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline Vector2<T>& operator /=(Vector2<T>& left, T right)
|
||||
{
|
||||
left.x /= right;
|
||||
left.y /= right;
|
||||
|
||||
return left;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of binary operator ==
|
||||
///
|
||||
/// This operator compares strict equality between two vectors.
|
||||
///
|
||||
/// \param left Left operand (a vector)
|
||||
/// \param right Right operand (a vector)
|
||||
///
|
||||
/// \return True if \a left is equal to \a right
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline bool operator ==(const Vector2<T>& left, const Vector2<T>& right)
|
||||
{
|
||||
return (left.x == right.x) && (left.y == right.y);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \relates Vector2
|
||||
/// \brief Overload of binary operator !=
|
||||
///
|
||||
/// This operator compares strict difference between two vectors.
|
||||
///
|
||||
/// \param left Left operand (a vector)
|
||||
/// \param right Right operand (a vector)
|
||||
///
|
||||
/// \return True if \a left is not equal to \a right
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline bool operator !=(const Vector2<T>& left, const Vector2<T>& right)
|
||||
{
|
||||
return (left.x != right.x) || (left.y != right.y);
|
||||
}
|
||||
|
||||
// Define the most common types
|
||||
typedef Vector2<int> Vector2i;
|
||||
typedef Vector2<unsigned int> Vector2u;
|
||||
typedef Vector2<float> Vector2f;
|
||||
|
||||
} // namespace gd
|
||||
|
||||
|
||||
#endif // GDCORE_VECTOR2_H
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \class gd::Vector2
|
||||
/// \ingroup CommonProgrammingTools
|
||||
///
|
||||
/// gd::Vector2 is a simple class that defines a mathematical
|
||||
/// vector with two coordinates (x and y). It can be used to
|
||||
/// represent anything that has two dimensions: a size, a point,
|
||||
/// a velocity, etc.
|
||||
///
|
||||
/// The template parameter T is the type of the coordinates. It
|
||||
/// can be any type that supports arithmetic operations (+, -, /, *)
|
||||
/// and comparisons (==, !=), for example int or float.
|
||||
///
|
||||
/// You generally don't have to care about the templated form (gd::Vector2<T>),
|
||||
/// the most common specializations have special typedefs:
|
||||
/// \li gd::Vector2<float> is gd::Vector2f
|
||||
/// \li gd::Vector2<int> is gd::Vector2i
|
||||
/// \li gd::Vector2<unsigned int> is gd::Vector2u
|
||||
///
|
||||
/// The gd::Vector2 class has a small and simple interface, its x and y members
|
||||
/// can be accessed directly (there are no accessors like setX(), getX()) and it
|
||||
/// contains no mathematical function like dot product, cross product, length, etc.
|
||||
///
|
||||
/// Usage example:
|
||||
/// \code
|
||||
/// gd::Vector2f v1(16.5f, 24.f);
|
||||
/// v1.x = 18.2f;
|
||||
/// float y = v1.y;
|
||||
///
|
||||
/// gd::Vector2f v2 = v1 * 5.f;
|
||||
/// gd::Vector2f v3;
|
||||
/// v3 = v1 + v2;
|
||||
///
|
||||
/// bool different = (v2 != v3);
|
||||
/// \endcode
|
||||
///
|
||||
/// Note: for 3-dimensional vectors, see gd::Vector3.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
@@ -75,11 +75,7 @@ TEST_CASE("EventsList", "[common][events]") {
|
||||
|
||||
size_t endMemory = gd::SystemStats::GetUsedVirtualMemory();
|
||||
INFO("Memory used: " << endMemory - startMemory << "KB");
|
||||
#if defined(WINDOWS)
|
||||
REQUIRE(3000 >= endMemory - startMemory);
|
||||
#else
|
||||
REQUIRE(1500 >= endMemory - startMemory);
|
||||
#endif
|
||||
REQUIRE(1500 >= endMemory - startMemory);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -31,7 +31,7 @@ TEST_CASE("EventsCodeGenerationContext", "[common][events]") {
|
||||
gd::EventsCodeGenerationContext c1(&maxDepth);
|
||||
c1.ObjectsListNeeded("c1.object1");
|
||||
c1.ObjectsListNeeded("c1.object2");
|
||||
c1.ObjectsListNeededOrEmptyIfJustDeclared("c1.noPicking1");
|
||||
c1.ObjectsListWithoutPickingNeeded("c1.noPicking1");
|
||||
|
||||
gd::EventsCodeGenerationContext c2;
|
||||
c2.InheritsFrom(c1);
|
||||
@@ -47,7 +47,7 @@ TEST_CASE("EventsCodeGenerationContext", "[common][events]") {
|
||||
|
||||
gd::EventsCodeGenerationContext c5;
|
||||
c5.InheritsFrom(c2);
|
||||
c5.ObjectsListNeededOrEmptyIfJustDeclared("c5.noPicking1");
|
||||
c5.ObjectsListWithoutPickingNeeded("c5.noPicking1");
|
||||
c5.ObjectsListNeeded("c5.object1");
|
||||
c5.ObjectsListNeeded("c1.object2");
|
||||
c5.EmptyObjectsListNeeded("c5.empty1");
|
||||
@@ -70,36 +70,36 @@ TEST_CASE("EventsCodeGenerationContext", "[common][events]") {
|
||||
}
|
||||
|
||||
SECTION("Object list needed") {
|
||||
REQUIRE(c1.GetObjectsListsAlreadyDeclaredByParents() == std::set<gd::String>());
|
||||
REQUIRE(c1.GetObjectsListsAlreadyDeclared() == std::set<gd::String>());
|
||||
REQUIRE(c1.GetObjectsListsToBeDeclared() ==
|
||||
std::set<gd::String>({"c1.object1", "c1.object2"}));
|
||||
REQUIRE(c1.GetObjectsListsToBeEmptyIfJustDeclared() ==
|
||||
REQUIRE(c1.GetObjectsListsToBeDeclaredWithoutPicking() ==
|
||||
std::set<gd::String>({"c1.noPicking1"}));
|
||||
REQUIRE(c1.GetAllObjectsToBeDeclared() ==
|
||||
std::set<gd::String>({"c1.object1", "c1.object2", "c1.noPicking1"}));
|
||||
|
||||
REQUIRE(c2.GetObjectsListsAlreadyDeclaredByParents() ==
|
||||
REQUIRE(c2.GetObjectsListsAlreadyDeclared() ==
|
||||
std::set<gd::String>({"c1.object1", "c1.object2", "c1.noPicking1"}));
|
||||
REQUIRE(c2.GetObjectsListsToBeDeclared() ==
|
||||
std::set<gd::String>({"c2.object1"}));
|
||||
REQUIRE(c2.GetObjectsListsToBeEmptyIfJustDeclared() == std::set<gd::String>());
|
||||
REQUIRE(c2.GetObjectsListsToBeDeclaredWithoutPicking() == std::set<gd::String>());
|
||||
REQUIRE(c2.GetAllObjectsToBeDeclared() ==
|
||||
std::set<gd::String>({"c2.object1"}));
|
||||
|
||||
REQUIRE(c3.GetObjectsListsAlreadyDeclaredByParents() ==
|
||||
REQUIRE(c3.GetObjectsListsAlreadyDeclared() ==
|
||||
std::set<gd::String>({"c1.object1", "c1.object2", "c1.noPicking1"}));
|
||||
REQUIRE(c3.GetObjectsListsToBeDeclared() ==
|
||||
std::set<gd::String>({"c3.object1", "c1.object2"}));
|
||||
REQUIRE(c3.GetObjectsListsToBeEmptyIfJustDeclared() == std::set<gd::String>());
|
||||
REQUIRE(c3.GetObjectsListsToBeDeclaredWithoutPicking() == std::set<gd::String>());
|
||||
REQUIRE(c3.GetAllObjectsToBeDeclared() ==
|
||||
std::set<gd::String>({"c3.object1", "c1.object2"}));
|
||||
|
||||
REQUIRE(c5.GetObjectsListsAlreadyDeclaredByParents() ==
|
||||
REQUIRE(c5.GetObjectsListsAlreadyDeclared() ==
|
||||
std::set<gd::String>(
|
||||
{"c1.object1", "c1.object2", "c1.noPicking1", "c2.object1"}));
|
||||
REQUIRE(c5.GetObjectsListsToBeDeclared() ==
|
||||
std::set<gd::String>({"c5.object1", "c1.object2"}));
|
||||
REQUIRE(c5.GetObjectsListsToBeEmptyIfJustDeclared() ==
|
||||
REQUIRE(c5.GetObjectsListsToBeDeclaredWithoutPicking() ==
|
||||
std::set<gd::String>({"c5.noPicking1"}));
|
||||
REQUIRE(c5.GetObjectsListsToBeDeclaredEmpty() ==
|
||||
std::set<gd::String>({"c5.empty1"}));
|
||||
@@ -107,18 +107,22 @@ TEST_CASE("EventsCodeGenerationContext", "[common][events]") {
|
||||
std::set<gd::String>({"c5.object1", "c5.noPicking1", "c1.object2", "c5.empty1"}));
|
||||
}
|
||||
|
||||
SECTION("ObjectAlreadyDeclaredByParents") {
|
||||
REQUIRE(c1.ObjectAlreadyDeclaredByParents("c1.object1") == false);
|
||||
REQUIRE(c2.ObjectAlreadyDeclaredByParents("c1.object1") == true);
|
||||
REQUIRE(c3.ObjectAlreadyDeclaredByParents("c1.object1") == true);
|
||||
REQUIRE(c4.ObjectAlreadyDeclaredByParents("c1.object1") == true);
|
||||
REQUIRE(c5.ObjectAlreadyDeclaredByParents("c1.object1") == true);
|
||||
SECTION("ObjectAlreadyDeclared") {
|
||||
REQUIRE(c1.ObjectAlreadyDeclared("c1.object1") == false);
|
||||
REQUIRE(c2.ObjectAlreadyDeclared("c1.object1") == true);
|
||||
REQUIRE(c3.ObjectAlreadyDeclared("c1.object1") == true);
|
||||
REQUIRE(c4.ObjectAlreadyDeclared("c1.object1") == true);
|
||||
REQUIRE(c5.ObjectAlreadyDeclared("c1.object1") == true);
|
||||
|
||||
REQUIRE(c1.ObjectAlreadyDeclaredByParents("c2.object1") == false);
|
||||
REQUIRE(c2.ObjectAlreadyDeclaredByParents("c2.object1") == false);
|
||||
REQUIRE(c3.ObjectAlreadyDeclaredByParents("c2.object1") == false);
|
||||
REQUIRE(c4.ObjectAlreadyDeclaredByParents("c2.object1") == true);
|
||||
REQUIRE(c5.ObjectAlreadyDeclaredByParents("c2.object1") == true);
|
||||
REQUIRE(c2.ObjectAlreadyDeclared("c2.object1") == false);
|
||||
REQUIRE(c1.ObjectAlreadyDeclared("c2.object1") == false);
|
||||
REQUIRE(c3.ObjectAlreadyDeclared("c2.object1") == false);
|
||||
REQUIRE(c4.ObjectAlreadyDeclared("c2.object1") == true);
|
||||
REQUIRE(c5.ObjectAlreadyDeclared("c2.object1") == true);
|
||||
|
||||
REQUIRE(c3.ObjectAlreadyDeclared("some object") == false);
|
||||
c3.SetObjectDeclared("some object");
|
||||
REQUIRE(c3.ObjectAlreadyDeclared("some object") == true);
|
||||
}
|
||||
|
||||
SECTION("Object list last depth") {
|
||||
@@ -182,87 +186,4 @@ TEST_CASE("EventsCodeGenerationContext", "[common][events]") {
|
||||
REQUIRE(c7.IsSameObjectsList("c6.object3", c6) == false);
|
||||
REQUIRE(c7.IsSameObjectsList("c5.empty1", c5) == false);
|
||||
}
|
||||
|
||||
SECTION("Async") {
|
||||
gd::EventsCodeGenerationContext c1;
|
||||
c1.ObjectsListNeeded("c1.object1");
|
||||
c1.ObjectsListNeeded("c1.object2");
|
||||
c1.ObjectsListNeededOrEmptyIfJustDeclared("c1.possiblyEmpty1");
|
||||
c1.EmptyObjectsListNeeded("c1.empty1");
|
||||
|
||||
gd::EventsCodeGenerationContext c2;
|
||||
c2.InheritsAsAsyncCallbackFrom(c1);
|
||||
c2.ObjectsListNeeded("c2.object1");
|
||||
c2.ObjectsListNeededOrEmptyIfJustDeclared("c2.possiblyEmpty1");
|
||||
c2.EmptyObjectsListNeeded("c2.empty1");
|
||||
c2.ObjectsListNeeded("c1.object1");
|
||||
|
||||
gd::EventsCodeGenerationContext c3;
|
||||
c3.InheritsAsAsyncCallbackFrom(c2);
|
||||
c3.ObjectsListNeeded("c3.object1");
|
||||
c3.ObjectsListNeededOrEmptyIfJustDeclared("c3.possiblyEmpty1");
|
||||
c3.EmptyObjectsListNeeded("c3.empty1");
|
||||
c3.ObjectsListNeeded("c1.object1");
|
||||
|
||||
gd::EventsCodeGenerationContext c4;
|
||||
c4.InheritsFrom(c3);
|
||||
c4.ObjectsListNeeded("c4.object1");
|
||||
c4.ObjectsListNeededOrEmptyIfJustDeclared("c4.possiblyEmpty1");
|
||||
c4.EmptyObjectsListNeeded("c4.empty1");
|
||||
c4.ObjectsListNeeded("c1.object1");
|
||||
c4.ObjectsListNeeded("c1.object2");
|
||||
|
||||
gd::EventsCodeGenerationContext c5;
|
||||
c5.InheritsFrom(c4);
|
||||
c5.ObjectsListNeeded("c5.object1");
|
||||
c5.ObjectsListNeededOrEmptyIfJustDeclared("c5.possiblyEmpty1");
|
||||
c5.EmptyObjectsListNeeded("c5.empty1");
|
||||
c5.ObjectsListNeeded("c1.object1");
|
||||
c5.ObjectsListNeeded("c1.object2");
|
||||
|
||||
REQUIRE(c1.ShouldUseAsyncObjectsList("c1.object1") == false);
|
||||
REQUIRE(c1.ShouldUseAsyncObjectsList("c1.possiblyEmpty1") == false);
|
||||
REQUIRE(c1.ShouldUseAsyncObjectsList("c1.empty1") == false);
|
||||
|
||||
// Objects declared in async callback are used traditionally:
|
||||
REQUIRE(c2.ShouldUseAsyncObjectsList("c2.object1") == false);
|
||||
REQUIRE(c2.ShouldUseAsyncObjectsList("c2.possiblyEmpty1") == false);
|
||||
REQUIRE(c2.ShouldUseAsyncObjectsList("c2.empty1") == false);
|
||||
|
||||
// Objects declared in c1 are gotten from the async list in c2 and c3
|
||||
// because these contexts use them and are async.
|
||||
REQUIRE(c2.ShouldUseAsyncObjectsList("c1.object1") == true);
|
||||
REQUIRE(c3.ShouldUseAsyncObjectsList("c1.object1") == true);
|
||||
REQUIRE(c4.ShouldUseAsyncObjectsList("c1.object1") == false);
|
||||
REQUIRE(c5.ShouldUseAsyncObjectsList("c1.object1") == false);
|
||||
|
||||
// Objects declared in c1 are gotten from the async list in c4
|
||||
// because c3 is async (but is not using them)
|
||||
REQUIRE(c4.ShouldUseAsyncObjectsList("c1.object2") == true);
|
||||
|
||||
// Objects declared in c1 but gotten from the async list in c4
|
||||
// is used traditionnally:
|
||||
REQUIRE(c5.ShouldUseAsyncObjectsList("c1.object2") == false);
|
||||
|
||||
// Objects declared in or after c3 are used traditionally:
|
||||
REQUIRE(c3.ShouldUseAsyncObjectsList("c3.object1") == false);
|
||||
REQUIRE(c4.ShouldUseAsyncObjectsList("c3.object1") == false);
|
||||
REQUIRE(c5.ShouldUseAsyncObjectsList("c3.object1") == false);
|
||||
REQUIRE(c3.ShouldUseAsyncObjectsList("c3.possiblyEmpty1") == false);
|
||||
REQUIRE(c4.ShouldUseAsyncObjectsList("c3.possiblyEmpty1") == false);
|
||||
REQUIRE(c5.ShouldUseAsyncObjectsList("c3.possiblyEmpty1") == false);
|
||||
REQUIRE(c3.ShouldUseAsyncObjectsList("c3.empty1") == false);
|
||||
REQUIRE(c4.ShouldUseAsyncObjectsList("c3.empty1") == false);
|
||||
REQUIRE(c5.ShouldUseAsyncObjectsList("c3.empty1") == false);
|
||||
REQUIRE(c4.ShouldUseAsyncObjectsList("c4.object1") == false);
|
||||
REQUIRE(c4.ShouldUseAsyncObjectsList("c4.possiblyEmpty1") == false);
|
||||
REQUIRE(c4.ShouldUseAsyncObjectsList("c4.empty1") == false);
|
||||
REQUIRE(c5.ShouldUseAsyncObjectsList("c4.object1") == false);
|
||||
REQUIRE(c5.ShouldUseAsyncObjectsList("c4.possiblyEmpty1") == false);
|
||||
REQUIRE(c5.ShouldUseAsyncObjectsList("c4.empty1") == false);
|
||||
REQUIRE(c5.ShouldUseAsyncObjectsList("c5.object1") == false);
|
||||
REQUIRE(c5.ShouldUseAsyncObjectsList("c5.possiblyEmpty1") == false);
|
||||
REQUIRE(c5.ShouldUseAsyncObjectsList("c5.empty1") == false);
|
||||
|
||||
}
|
||||
}
|
||||
|
90
Core/tests/FileStream.cpp
Normal file
90
Core/tests/FileStream.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
/**
|
||||
* @file Tests covering FileStream class of GDevelop Core.
|
||||
*/
|
||||
#include "GDCore/Tools/FileStream.h"
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
TEST_CASE("FileStream", "[common][fstream]") {
|
||||
// Creating the test file
|
||||
std::ofstream testFile("FileStreamTest.test");
|
||||
REQUIRE(testFile.is_open());
|
||||
|
||||
testFile << "this is the first line of the test file!\n";
|
||||
testFile << "the last line!";
|
||||
testFile.close();
|
||||
|
||||
SECTION("Input file") {
|
||||
gd::FileStream f;
|
||||
f.open("FileStreamTest.test", std::ios_base::in);
|
||||
|
||||
REQUIRE(f.is_open() == true);
|
||||
REQUIRE(f.tellg() == 0);
|
||||
|
||||
std::string lineContent;
|
||||
REQUIRE(f.eof() == false);
|
||||
std::getline(f, lineContent);
|
||||
REQUIRE(lineContent == "this is the first line of the test file!");
|
||||
|
||||
REQUIRE(f.eof() == false);
|
||||
std::getline(f, lineContent);
|
||||
REQUIRE(lineContent == "the last line!");
|
||||
|
||||
REQUIRE(f.eof() == true);
|
||||
REQUIRE(f.fail() == false);
|
||||
|
||||
f.close();
|
||||
REQUIRE(f.is_open() == false);
|
||||
REQUIRE(f.fail() == false);
|
||||
}
|
||||
|
||||
SECTION("Output/Input file with special characters in filepath") {
|
||||
gd::FileStream output("\xEA\x88\xA1.txt", std::ios_base::out);
|
||||
REQUIRE(output.is_open() == true);
|
||||
|
||||
output << "TEST";
|
||||
output.close();
|
||||
|
||||
gd::FileStream input("\xEA\x88\xA1.txt", std::ios_base::in);
|
||||
REQUIRE(input.is_open() == true);
|
||||
|
||||
std::string lineContent;
|
||||
REQUIRE(input.eof() == false);
|
||||
std::getline(input, lineContent);
|
||||
REQUIRE(lineContent == "TEST");
|
||||
|
||||
REQUIRE(input.eof() == true);
|
||||
|
||||
input.close();
|
||||
REQUIRE(input.is_open() == false);
|
||||
REQUIRE(input.fail() == false);
|
||||
}
|
||||
|
||||
SECTION("File opening failure") {
|
||||
gd::FileStream f("\xE4\x84\xA2",
|
||||
std::ios_base::in); // A file that doesn't exist
|
||||
|
||||
REQUIRE(f.is_open() == false);
|
||||
REQUIRE(f.fail() ==
|
||||
true); // As the opening failed, the "fail" flag should be set
|
||||
|
||||
f.close();
|
||||
REQUIRE(f.bad() == true); // As no files are opened, this should set the
|
||||
// "bad" flag of the stream
|
||||
}
|
||||
|
||||
SECTION("std::ios_base::ate") { // As ate is "emulated", needs testing
|
||||
gd::FileStream f;
|
||||
f.open("FileStreamTest.test", std::ios_base::in | std::ios_base::ate);
|
||||
|
||||
REQUIRE(f.is_open() == true);
|
||||
REQUIRE(f.tellg() > 0);
|
||||
}
|
||||
}
|
@@ -7,6 +7,7 @@
|
||||
* @file Tests covering utf8 features from GDevelop Core.
|
||||
*/
|
||||
|
||||
#include <SFML/System/String.hpp>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
@@ -18,8 +19,10 @@ TEST_CASE("Utf8 String", "[common][utf8]") {
|
||||
SECTION("ctor & conversions") {
|
||||
gd::String str = u8"UTF8 a été testé !";
|
||||
|
||||
sf::String sfStr = str;
|
||||
std::u32string u32str = str.ToUTF32();
|
||||
|
||||
REQUIRE(str == gd::String::FromSfString(sfStr));
|
||||
REQUIRE(str == gd::String::FromUTF32(u32str));
|
||||
}
|
||||
|
||||
@@ -39,10 +42,8 @@ TEST_CASE("Utf8 String", "[common][utf8]") {
|
||||
|
||||
REQUIRE(str.substr(5, 7) == u8"a été t");
|
||||
REQUIRE(str.substr(5, gd::String::npos) == u8"a été testé !");
|
||||
// Windows doesn't seems to like exceptions.
|
||||
#if !defined(WINDOWS)
|
||||
REQUIRE_THROWS_AS(str.substr(50, 5), std::out_of_range);
|
||||
#endif
|
||||
|
||||
REQUIRE_THROWS_AS(str.substr(50, 5), std::out_of_range);
|
||||
}
|
||||
|
||||
SECTION("insert") {
|
||||
@@ -50,9 +51,7 @@ TEST_CASE("Utf8 String", "[common][utf8]") {
|
||||
str.insert(25, u8"vraiment ");
|
||||
|
||||
REQUIRE(str == u8"Une fonctionnalité a été vraiment testée !");
|
||||
#if !defined(WINDOWS)
|
||||
REQUIRE_THROWS_AS(str.insert(150, u8"This gonna fail"), std::out_of_range);
|
||||
#endif
|
||||
REQUIRE_THROWS_AS(str.insert(150, u8"This gonna fail"), std::out_of_range);
|
||||
}
|
||||
|
||||
SECTION("replace") {
|
||||
@@ -63,10 +62,8 @@ TEST_CASE("Utf8 String", "[common][utf8]") {
|
||||
REQUIRE(str.replace(11, gd::String::npos, u8"vraiment très testé !") ==
|
||||
u8"UTF8 a été vraiment très testé !");
|
||||
|
||||
#if !defined(WINDOWS)
|
||||
REQUIRE_THROWS_AS(str.replace(50, 5, u8"Cela va planter."),
|
||||
std::out_of_range);
|
||||
#endif
|
||||
REQUIRE_THROWS_AS(str.replace(50, 5, u8"Cela va planter."),
|
||||
std::out_of_range);
|
||||
|
||||
// Testing the iterator version of replace
|
||||
gd::String str2 = u8"UTF8 a été testé !";
|
||||
@@ -97,10 +94,8 @@ TEST_CASE("Utf8 String", "[common][utf8]") {
|
||||
REQUIRE(str == "UTF8");
|
||||
}
|
||||
{
|
||||
#if !defined(WINDOWS)
|
||||
gd::String str = u8"UTF8 a été testé !";
|
||||
REQUIRE_THROWS_AS(str.erase(100, 5), std::out_of_range);
|
||||
#endif
|
||||
gd::String str = u8"UTF8 a été testé !";
|
||||
REQUIRE_THROWS_AS(str.erase(100, 5), std::out_of_range);
|
||||
}
|
||||
{
|
||||
gd::String str = u8"UTF8 a été testé !";
|
||||
|
@@ -0,0 +1,54 @@
|
||||
# Clone SFML from its official directory using Git. Only
|
||||
# do it if not already cloned to avoid triggering a whole
|
||||
# recompilation every time CMake is run.
|
||||
find_package(Git)
|
||||
if(GIT_FOUND)
|
||||
if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/SFML/readme.txt")
|
||||
message( "Cloning SFML in ExtLibs/SFML with Git..." )
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} clone "https://www.github.com/SFML/SFML.git" SFML
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
|
||||
OUTPUT_QUIET)
|
||||
|
||||
message( "Resetting SFML source code to version 2.4.1..." )
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} reset --hard 2.4.1
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/SFML
|
||||
OUTPUT_QUIET)
|
||||
|
||||
message( "Applying the patches..." )
|
||||
file(GLOB SFML_PATCHES
|
||||
LIST_DIRECTORIES FALSE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/SFML-patches/*.patch)
|
||||
|
||||
if(SFML_PATCHES)
|
||||
list(SORT SFML_PATCHES)
|
||||
|
||||
foreach(SFML_PATCH ${SFML_PATCHES})
|
||||
message( "Applying patch: ${SFML_PATCH}..." )
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} apply ${SFML_PATCH} --ignore-whitespace
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/SFML
|
||||
OUTPUT_QUIET)
|
||||
endforeach()
|
||||
endif()
|
||||
else()
|
||||
message( "SFML already downloaded." )
|
||||
endif()
|
||||
else()
|
||||
message( "Git not found, make sure you have SFML >= 2.4 in ExtLibs/SFML and you applied the needed patches (from ExtLibs/SFML-patches)!" )
|
||||
endif()
|
||||
|
||||
#SFML:
|
||||
IF(NOT EMSCRIPTEN) #Don't build SFML binaries when compiling with emscripten (but keep include files!)
|
||||
add_subdirectory(SFML)
|
||||
set(sfml_lib_dir ${CMAKE_BINARY_DIR}/ExtLibs/SFML/lib PARENT_SCOPE)
|
||||
set(sfml_LIBRARIES sfml-audio sfml-graphics sfml-window sfml-network sfml-system)
|
||||
IF(WIN32)
|
||||
set(sfml_LIBRARIES "${sfml_LIBRARIES}" ws2_32 user32 opengl32 glu32 psapi)
|
||||
ELSEIF(NOT APPLE)
|
||||
set(sfml_LIBRARIES "${sfml_LIBRARIES}" GLU GL)
|
||||
ENDIF()
|
||||
set(sfml_LIBRARIES "${sfml_LIBRARIES}" PARENT_SCOPE)
|
||||
ENDIF()
|
||||
set(sfml_include_dir ${CMAKE_CURRENT_SOURCE_DIR}/SFML/include PARENT_SCOPE)
|
||||
|
19
ExtLibs/SFML-patches/01_GCC_5_and_6_sse2.patch
Normal file
19
ExtLibs/SFML-patches/01_GCC_5_and_6_sse2.patch
Normal file
@@ -0,0 +1,19 @@
|
||||
diff --git a/extlibs/headers/stb_image/stb_image.h b/extlibs/headers/stb_image/stb_image.h
|
||||
index c3945c2..5fe1050 100644
|
||||
--- a/extlibs/headers/stb_image/stb_image.h
|
||||
+++ b/extlibs/headers/stb_image/stb_image.h
|
||||
@@ -671,14 +671,9 @@ static int stbi__sse2_available()
|
||||
|
||||
static int stbi__sse2_available()
|
||||
{
|
||||
-#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 // GCC 4.8 or later
|
||||
- // GCC 4.8+ has a nice way to do this
|
||||
- return __builtin_cpu_supports("sse2");
|
||||
-#else
|
||||
// portable way to do this, preferably without using GCC inline ASM?
|
||||
// just bail for now.
|
||||
return 0;
|
||||
-#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
@@ -0,0 +1,29 @@
|
||||
From f55ee73a73398bb77ce9c63ff1a13d8053cb1d18 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Rival <Florian.Rival@gmail.com>
|
||||
Date: Tue, 3 Jan 2017 21:15:11 +0100
|
||||
Subject: [PATCH] Fix crash with SFML embeded in wxWidgets on OS X
|
||||
|
||||
---
|
||||
src/SFML/Window/OSX/SFViewController.mm | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/src/SFML/Window/OSX/SFViewController.mm b/src/SFML/Window/OSX/SFViewController.mm
|
||||
index 7d736e3..280ec2b 100644
|
||||
--- a/src/SFML/Window/OSX/SFViewController.mm
|
||||
+++ b/src/SFML/Window/OSX/SFViewController.mm
|
||||
@@ -82,8 +82,12 @@ -(id)initWithView:(NSView *)view
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)dealloc
|
||||
{
|
||||
+ NSLog(@"SFViewController::dealloc called on %@", self);
|
||||
[self closeWindow];
|
||||
|
||||
+
|
||||
+ // See https://github.com/SFML/SFML/issues/824
|
||||
+ [[NSNotificationCenter defaultCenter] removeObserver:m_oglView];
|
||||
[m_view release];
|
||||
[m_oglView release];
|
||||
|
||||
--
|
||||
2.7.4 (Apple Git-66)
|
||||
|
13
ExtLibs/SFML-patches/03_recognize_emscripten_as_linux.patch
Normal file
13
ExtLibs/SFML-patches/03_recognize_emscripten_as_linux.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git a/include/SFML/Config.hpp b/include/SFML/Config.hpp
|
||||
index 9c68d84..2522d88 100644
|
||||
--- a/include/SFML/Config.hpp
|
||||
+++ b/include/SFML/Config.hpp
|
||||
@@ -76,7 +76,7 @@
|
||||
// Android
|
||||
#define SFML_SYSTEM_ANDROID
|
||||
|
||||
- #elif defined(__linux__)
|
||||
+ #elif defined(__linux__) || defined(EMSCRIPTEN)
|
||||
|
||||
// Linux
|
||||
#define SFML_SYSTEM_LINUX
|
@@ -45,7 +45,6 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Focus the window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -62,7 +61,6 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -81,7 +79,6 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Show window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -98,7 +95,6 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -117,7 +113,6 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Maximize window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -134,7 +129,6 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -153,7 +147,6 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Minimize window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -170,7 +163,6 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -189,7 +181,6 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Enable window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -206,7 +197,6 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -225,7 +215,6 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Allow resizing?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -242,7 +231,6 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -261,7 +249,6 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Allow moving?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -278,7 +265,6 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -297,7 +283,6 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Allow maximizing?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -314,7 +299,6 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -333,7 +317,6 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Allow minimizing?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -350,7 +333,6 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -369,7 +351,6 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Allow full-screening?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -386,7 +367,6 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -405,7 +385,6 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Allow closing?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -422,7 +401,6 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -464,7 +442,6 @@ module.exports = {
|
||||
'above the taskbar on Windows. ' +
|
||||
'This parameter is ignored on linux.'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -481,7 +458,6 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -502,7 +478,6 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Enable kiosk mode?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -519,7 +494,6 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -538,7 +512,6 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Enable shadow?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -555,7 +528,6 @@ module.exports = {
|
||||
'res/actions/window24.png',
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -576,7 +548,6 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Enable content protection?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -595,7 +566,6 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Allow focus?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -614,7 +584,6 @@ module.exports = {
|
||||
)
|
||||
.addParameter('yesorno', _('Flash the window?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -635,7 +604,6 @@ module.exports = {
|
||||
.setParameterLongDescription(
|
||||
'A number between 0 (fully transparent) and 1 (fully opaque).'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -654,7 +622,6 @@ module.exports = {
|
||||
)
|
||||
.addParameter('expression', _('X position'), '', false)
|
||||
.addParameter('expression', _('Y position'), '', false)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -669,7 +636,6 @@ module.exports = {
|
||||
_('Windows, Linux, macOS'),
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -684,7 +650,6 @@ module.exports = {
|
||||
_('Windows, Linux, macOS'),
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
@@ -701,7 +666,6 @@ module.exports = {
|
||||
_('Windows, Linux, macOS'),
|
||||
'res/actions/window.png'
|
||||
)
|
||||
.addCodeOnlyParameter('currentScene', '')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
'Extensions/AdvancedWindow/electron-advancedwindowtools.js'
|
||||
|
@@ -6,23 +6,16 @@ namespace gdjs {
|
||||
*/
|
||||
export namespace evtTools {
|
||||
export namespace advancedWindow {
|
||||
const getElectronBrowserWindow = (runtimeScene: gdjs.RuntimeScene) => {
|
||||
const electronRemote = runtimeScene
|
||||
.getGame()
|
||||
.getRenderer()
|
||||
.getElectronRemote();
|
||||
if (electronRemote) {
|
||||
return electronRemote.getCurrentWindow();
|
||||
}
|
||||
/**
|
||||
* The game's BrowserWindow instance (or null on
|
||||
* non-electron platforms).
|
||||
*/
|
||||
let electronBrowserWindow: any = null;
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export const focus = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (typeof require === 'function') {
|
||||
electronBrowserWindow = require('electron').remote.getCurrentWindow();
|
||||
}
|
||||
export const focus = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
if (activate) {
|
||||
electronBrowserWindow.focus();
|
||||
@@ -32,21 +25,14 @@ namespace gdjs {
|
||||
}
|
||||
};
|
||||
|
||||
export const isFocused = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const isFocused = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isFocused();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const show = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const show = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
if (activate) {
|
||||
electronBrowserWindow.showInactive();
|
||||
@@ -56,21 +42,14 @@ namespace gdjs {
|
||||
}
|
||||
};
|
||||
|
||||
export const isVisible = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const isVisible = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isVisible();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const maximize = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const maximize = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
if (activate) {
|
||||
electronBrowserWindow.maximize();
|
||||
@@ -80,21 +59,14 @@ namespace gdjs {
|
||||
}
|
||||
};
|
||||
|
||||
export const isMaximized = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const isMaximized = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isMaximized();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const minimize = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const minimize = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
if (activate) {
|
||||
electronBrowserWindow.minimize();
|
||||
@@ -104,150 +76,98 @@ namespace gdjs {
|
||||
}
|
||||
};
|
||||
|
||||
export const isMinimized = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const isMinimized = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isMinimized();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const enable = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const enable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setEnabled(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isEnabled = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const isEnabled = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isEnabled();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setResizable = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const setResizable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setResizable(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isResizable = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const isResizable = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isResizable();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setMovable = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const setMovable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setMovable(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isMovable = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const isMovable = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isMovable();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setMaximizable = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const setMaximizable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setMaximizable(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isMaximizable = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const isMaximizable = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isMaximizable();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setMinimizable = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const setMinimizable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setMinimizable(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isMinimizable = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const isMinimizable = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isMinimizable();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setFullScreenable = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const setFullScreenable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setFullScreenable(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isFullScreenable = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const isFullScreenable = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isFullScreenable();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setClosable = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const setClosable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setClosable(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isClosable = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const isClosable = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isClosable();
|
||||
}
|
||||
@@ -264,142 +184,93 @@ namespace gdjs {
|
||||
| 'main-menu'
|
||||
| 'status'
|
||||
| 'pop-up-menu'
|
||||
| 'screen-saver',
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
| 'screen-saver'
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setAlwaysOnTop(activate, level);
|
||||
}
|
||||
};
|
||||
|
||||
export const isAlwaysOnTop = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const isAlwaysOnTop = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isAlwaysOnTop();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setPosition = function (
|
||||
x: float,
|
||||
y: float,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const setPosition = function (x: float, y: float) {
|
||||
if (electronBrowserWindow) {
|
||||
// Convert x and y to (32 bit) integers to avoid Electron errors.
|
||||
electronBrowserWindow.setPosition(~~x, ~~y);
|
||||
}
|
||||
};
|
||||
|
||||
export const getPositionX = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): number {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const getPositionX = function (): number {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.getPosition()[0];
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
export const getPositionY = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): number {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const getPositionY = function (): number {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.getPosition()[1];
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
export const setKiosk = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const setKiosk = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setKiosk(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const isKiosk = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const isKiosk = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.isKiosk();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const flash = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const flash = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.flashFrame(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const setHasShadow = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const setHasShadow = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setHasShadow(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const hasShadow = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): boolean {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const hasShadow = function (): boolean {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.hasShadow();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const setOpacity = function (
|
||||
opacity: float,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const setOpacity = function (opacity: float) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setOpacity(opacity);
|
||||
}
|
||||
};
|
||||
|
||||
export const getOpacity = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): number {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const getOpacity = function (): number {
|
||||
if (electronBrowserWindow) {
|
||||
return electronBrowserWindow.getOpacity();
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
|
||||
export const setContentProtection = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const setContentProtection = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setContentProtection(activate);
|
||||
}
|
||||
};
|
||||
|
||||
export const setFocusable = function (
|
||||
activate: boolean,
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
const electronBrowserWindow = getElectronBrowserWindow(runtimeScene);
|
||||
export const setFocusable = function (activate: boolean) {
|
||||
if (electronBrowserWindow) {
|
||||
electronBrowserWindow.setFocusable(activate);
|
||||
}
|
||||
|
@@ -5,9 +5,7 @@ Copyright (c) 2016 Victor Levasseur (victorlevasseur52@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
#include "AnchorBehavior.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
@@ -22,7 +20,6 @@ void AnchorBehavior::InitializeContent(gd::SerializerElement& content) {
|
||||
content.SetAttribute("topEdgeAnchor", static_cast<int>(ANCHOR_VERTICAL_NONE));
|
||||
content.SetAttribute("bottomEdgeAnchor",
|
||||
static_cast<int>(ANCHOR_VERTICAL_NONE));
|
||||
content.SetAttribute("useLegacyBottomAndRightAnchors", false);
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
@@ -71,7 +68,7 @@ std::map<gd::String, gd::PropertyDescriptor> AnchorBehavior::GetProperties(
|
||||
.AddExtraInfo(_("Window left"))
|
||||
.AddExtraInfo(_("Window right"))
|
||||
.AddExtraInfo(_("Proportional"))
|
||||
.SetDescription(_("Anchor the left edge of the object on X axis."));
|
||||
.SetDescription(_("Use this to anchor the object on X axis."));
|
||||
|
||||
properties[_("Right edge anchor")]
|
||||
.SetValue(GetAnchorAsString(static_cast<HorizontalAnchor>(
|
||||
@@ -80,8 +77,7 @@ std::map<gd::String, gd::PropertyDescriptor> AnchorBehavior::GetProperties(
|
||||
.AddExtraInfo(_("No anchor"))
|
||||
.AddExtraInfo(_("Window left"))
|
||||
.AddExtraInfo(_("Window right"))
|
||||
.AddExtraInfo(_("Proportional"))
|
||||
.SetDescription(_("Anchor the right edge of the object on X axis."));
|
||||
.AddExtraInfo(_("Proportional"));
|
||||
|
||||
properties[_("Top edge anchor")]
|
||||
.SetValue(GetAnchorAsString(static_cast<VerticalAnchor>(
|
||||
@@ -91,7 +87,7 @@ std::map<gd::String, gd::PropertyDescriptor> AnchorBehavior::GetProperties(
|
||||
.AddExtraInfo(_("Window top"))
|
||||
.AddExtraInfo(_("Window bottom"))
|
||||
.AddExtraInfo(_("Proportional"))
|
||||
.SetDescription(_("Anchor the top edge of the object on Y axis."));
|
||||
.SetDescription(_("Use this to anchor the object on Y axis."));
|
||||
|
||||
properties[_("Bottom edge anchor")]
|
||||
.SetValue(GetAnchorAsString(static_cast<VerticalAnchor>(
|
||||
@@ -100,20 +96,7 @@ std::map<gd::String, gd::PropertyDescriptor> AnchorBehavior::GetProperties(
|
||||
.AddExtraInfo(_("No anchor"))
|
||||
.AddExtraInfo(_("Window top"))
|
||||
.AddExtraInfo(_("Window bottom"))
|
||||
.AddExtraInfo(_("Proportional"))
|
||||
.SetDescription(_("Anchor the bottom edge of the object on Y axis."));
|
||||
|
||||
properties[("useLegacyBottomAndRightAnchors")]
|
||||
.SetLabel(_(
|
||||
"Stretch object when anchoring right or bottom ledge (deprecated, "
|
||||
"it's recommended to let this unchecked and anchor both sides if you "
|
||||
"want Sprite to stretch instead.)"))
|
||||
.SetGroup(_("Deprecated options (advanced)"))
|
||||
.SetValue(behaviorContent.GetBoolAttribute(
|
||||
"useLegacyBottomAndRightAnchors", true)
|
||||
? "true"
|
||||
: "false")
|
||||
.SetType("Boolean");
|
||||
.AddExtraInfo(_("Proportional"));
|
||||
|
||||
return properties;
|
||||
}
|
||||
@@ -164,9 +147,6 @@ bool AnchorBehavior::UpdateProperty(gd::SerializerElement& behaviorContent,
|
||||
behaviorContent.SetAttribute(
|
||||
"bottomEdgeAnchor",
|
||||
static_cast<int>(GetVerticalAnchorFromString(value)));
|
||||
else if (name == "useLegacyBottomAndRightAnchors")
|
||||
behaviorContent.SetAttribute("useLegacyBottomAndRightAnchors",
|
||||
(value == "1"));
|
||||
else
|
||||
return false;
|
||||
|
||||
|
@@ -15,20 +15,14 @@ namespace gdjs {
|
||||
_rightEdgeDistance: number = 0;
|
||||
_topEdgeDistance: number = 0;
|
||||
_bottomEdgeDistance: number = 0;
|
||||
_useLegacyBottomAndRightAnchors: boolean = false;
|
||||
|
||||
constructor(runtimeScene, behaviorData, owner) {
|
||||
super(runtimeScene, behaviorData, owner);
|
||||
this._relativeToOriginalWindowSize =
|
||||
!!behaviorData.relativeToOriginalWindowSize;
|
||||
this._relativeToOriginalWindowSize = !!behaviorData.relativeToOriginalWindowSize;
|
||||
this._leftEdgeAnchor = behaviorData.leftEdgeAnchor;
|
||||
this._rightEdgeAnchor = behaviorData.rightEdgeAnchor;
|
||||
this._topEdgeAnchor = behaviorData.topEdgeAnchor;
|
||||
this._bottomEdgeAnchor = behaviorData.bottomEdgeAnchor;
|
||||
this._useLegacyBottomAndRightAnchors =
|
||||
behaviorData.useLegacyBottomAndRightAnchors === undefined
|
||||
? true
|
||||
: behaviorData.useLegacyBottomAndRightAnchors;
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
@@ -46,13 +40,6 @@ namespace gdjs {
|
||||
) {
|
||||
this._bottomEdgeAnchor = newBehaviorData.bottomEdgeAnchor;
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.useLegacyTrajectory !==
|
||||
newBehaviorData.useLegacyTrajectory
|
||||
) {
|
||||
this._useLegacyBottomAndRightAnchors =
|
||||
newBehaviorData.useLegacyBottomAndRightAnchors;
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.relativeToOriginalWindowSize !==
|
||||
newBehaviorData.relativeToOriginalWindowSize
|
||||
@@ -275,94 +262,28 @@ namespace gdjs {
|
||||
bottomPixel
|
||||
);
|
||||
|
||||
// Compatibility with GD <= 5.0.133
|
||||
if (this._useLegacyBottomAndRightAnchors) {
|
||||
//Move and resize the object according to the anchors
|
||||
if (
|
||||
this._rightEdgeAnchor !==
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.NONE
|
||||
) {
|
||||
this.owner.setWidth(bottomRightCoord[0] - topLeftCoord[0]);
|
||||
}
|
||||
if (
|
||||
this._bottomEdgeAnchor !== AnchorRuntimeBehavior.VerticalAnchor.NONE
|
||||
) {
|
||||
this.owner.setHeight(bottomRightCoord[1] - topLeftCoord[1]);
|
||||
}
|
||||
if (
|
||||
this._leftEdgeAnchor !== AnchorRuntimeBehavior.HorizontalAnchor.NONE
|
||||
) {
|
||||
this.owner.setX(
|
||||
topLeftCoord[0] + this.owner.getX() - this.owner.getDrawableX()
|
||||
);
|
||||
}
|
||||
if (
|
||||
this._topEdgeAnchor !== AnchorRuntimeBehavior.VerticalAnchor.NONE
|
||||
) {
|
||||
this.owner.setY(
|
||||
topLeftCoord[1] + this.owner.getY() - this.owner.getDrawableY()
|
||||
);
|
||||
}
|
||||
//Move and resize the object according to the anchors
|
||||
if (
|
||||
this._rightEdgeAnchor !== AnchorRuntimeBehavior.HorizontalAnchor.NONE
|
||||
) {
|
||||
this.owner.setWidth(bottomRightCoord[0] - topLeftCoord[0]);
|
||||
}
|
||||
// End of compatibility code
|
||||
else {
|
||||
// Resize if right and left anchors are set
|
||||
if (
|
||||
this._rightEdgeAnchor !==
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.NONE &&
|
||||
this._leftEdgeAnchor !== AnchorRuntimeBehavior.HorizontalAnchor.NONE
|
||||
) {
|
||||
this.owner.setWidth(bottomRightCoord[0] - topLeftCoord[0]);
|
||||
this.owner.setX(topLeftCoord[0]);
|
||||
} else {
|
||||
if (
|
||||
this._leftEdgeAnchor !==
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.NONE
|
||||
) {
|
||||
this.owner.setX(
|
||||
topLeftCoord[0] + this.owner.getX() - this.owner.getDrawableX()
|
||||
);
|
||||
}
|
||||
if (
|
||||
this._rightEdgeAnchor !==
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.NONE
|
||||
) {
|
||||
this.owner.setX(
|
||||
bottomRightCoord[0] +
|
||||
this.owner.getX() -
|
||||
this.owner.getDrawableX() -
|
||||
this.owner.getWidth()
|
||||
);
|
||||
}
|
||||
}
|
||||
// Resize if top and bottom anchors are set
|
||||
if (
|
||||
this._bottomEdgeAnchor !==
|
||||
AnchorRuntimeBehavior.VerticalAnchor.NONE &&
|
||||
this._topEdgeAnchor !== AnchorRuntimeBehavior.VerticalAnchor.NONE
|
||||
) {
|
||||
this.owner.setHeight(bottomRightCoord[1] - topLeftCoord[1]);
|
||||
this.owner.setY(topLeftCoord[1]);
|
||||
} else {
|
||||
if (
|
||||
this._topEdgeAnchor !== AnchorRuntimeBehavior.VerticalAnchor.NONE
|
||||
) {
|
||||
this.owner.setY(
|
||||
topLeftCoord[1] + this.owner.getY() - this.owner.getDrawableY()
|
||||
);
|
||||
}
|
||||
if (
|
||||
this._bottomEdgeAnchor !==
|
||||
AnchorRuntimeBehavior.VerticalAnchor.NONE
|
||||
) {
|
||||
this.owner.setY(
|
||||
bottomRightCoord[1] +
|
||||
this.owner.getY() -
|
||||
this.owner.getDrawableY() -
|
||||
this.owner.getHeight()
|
||||
);
|
||||
}
|
||||
}
|
||||
if (
|
||||
this._bottomEdgeAnchor !== AnchorRuntimeBehavior.VerticalAnchor.NONE
|
||||
) {
|
||||
this.owner.setHeight(bottomRightCoord[1] - topLeftCoord[1]);
|
||||
}
|
||||
if (
|
||||
this._leftEdgeAnchor !== AnchorRuntimeBehavior.HorizontalAnchor.NONE
|
||||
) {
|
||||
this.owner.setX(
|
||||
topLeftCoord[0] + this.owner.getX() - this.owner.getDrawableX()
|
||||
);
|
||||
}
|
||||
if (this._topEdgeAnchor !== AnchorRuntimeBehavior.VerticalAnchor.NONE) {
|
||||
this.owner.setY(
|
||||
topLeftCoord[1] + this.owner.getY() - this.owner.getDrawableY()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,204 +0,0 @@
|
||||
// @ts-check
|
||||
describe.only('gdjs.AnchorRuntimeBehavior', function () {
|
||||
const runtimeGame = new gdjs.RuntimeGame({
|
||||
variables: [],
|
||||
resources: { resources: [] },
|
||||
// @ts-ignore
|
||||
properties: { windowWidth: 1000, windowHeight: 1000 },
|
||||
});
|
||||
const anchorBehaviorName = 'Anchor';
|
||||
const runtimeScene = new gdjs.RuntimeScene(runtimeGame);
|
||||
runtimeScene.loadFromScene({
|
||||
layers: [
|
||||
{
|
||||
name: '',
|
||||
visibility: true,
|
||||
cameras: [],
|
||||
effects: [],
|
||||
ambientLightColorR: 127,
|
||||
ambientLightColorB: 127,
|
||||
ambientLightColorG: 127,
|
||||
isLightingLayer: false,
|
||||
followBaseLayerCamera: false,
|
||||
},
|
||||
],
|
||||
variables: [],
|
||||
r: 0,
|
||||
v: 0,
|
||||
b: 0,
|
||||
mangledName: 'Scene1',
|
||||
name: 'Scene1',
|
||||
stopSoundsOnStartup: false,
|
||||
title: '',
|
||||
behaviorsSharedData: [],
|
||||
objects: [],
|
||||
instances: [],
|
||||
});
|
||||
|
||||
function createObject(behaviorProperties) {
|
||||
const object = new gdjs.TestRuntimeObject(runtimeScene, {
|
||||
name: 'obj1',
|
||||
type: '',
|
||||
behaviors: [
|
||||
{
|
||||
name: anchorBehaviorName,
|
||||
type: 'AnchorBehavior::AnchorBehavior',
|
||||
// @ts-ignore - properties are not typed
|
||||
rightEdgeAnchor: 0,
|
||||
leftEdgeAnchor: 0,
|
||||
topEdgeAnchor: 0,
|
||||
bottomEdgeAnchor: 0,
|
||||
relativeToOriginalWindowSize: true,
|
||||
useLegacyBottomAndRightAnchors: false,
|
||||
...behaviorProperties,
|
||||
},
|
||||
],
|
||||
variables: [],
|
||||
effects: [],
|
||||
});
|
||||
|
||||
object.setCustomWidthAndHeight(10, 10);
|
||||
runtimeScene.addObject(object);
|
||||
return object;
|
||||
}
|
||||
|
||||
function getAnchorBehavior(object) {
|
||||
const behavior = object.getBehavior(anchorBehaviorName);
|
||||
if (!(behavior instanceof gdjs.AnchorRuntimeBehavior)) {
|
||||
throw new Error(
|
||||
'Expected behavior to be an instance of gdjs.AnchorBehavior'
|
||||
);
|
||||
}
|
||||
return behavior;
|
||||
}
|
||||
|
||||
describe('(anchor horizontal edge)', function () {
|
||||
['rightEdgeAnchor', 'leftEdgeAnchor'].forEach((objectEdge) => {
|
||||
it(`anchors the ${objectEdge} edge of object to window left (fixed)`, function () {
|
||||
const object = createObject({ [objectEdge]: 1 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.equal(500);
|
||||
expect(object.getY()).to.equal(500);
|
||||
expect(object.getWidth()).to.equal(10);
|
||||
});
|
||||
});
|
||||
['rightEdgeAnchor', 'leftEdgeAnchor'].forEach((objectEdge) => {
|
||||
it(`anchors the ${objectEdge} edge of object to window right (fixed)`, function () {
|
||||
const object = createObject({ [objectEdge]: 2 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
expect(object.getX()).to.equal(1500);
|
||||
expect(object.getY()).to.equal(500);
|
||||
expect(object.getWidth()).to.equal(10);
|
||||
});
|
||||
});
|
||||
|
||||
it('anchors the right and left edge of object (fixed)', function () {
|
||||
const object = createObject({ leftEdgeAnchor: 1, rightEdgeAnchor: 2 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.equal(500);
|
||||
expect(object.getY()).to.equal(500);
|
||||
expect(object.getWidth()).to.equal(1010);
|
||||
});
|
||||
|
||||
it('anchors the left edge of object (proportional)', function () {
|
||||
const object = createObject({ leftEdgeAnchor: 3 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.equal(1000);
|
||||
expect(object.getY()).to.equal(500);
|
||||
expect(object.getWidth()).to.equal(10);
|
||||
});
|
||||
});
|
||||
|
||||
describe('(anchor vertical edge)', function () {
|
||||
['topEdgeAnchor', 'bottomEdgeAnchor'].forEach((objectEdge) => {
|
||||
it(`anchors the ${objectEdge} edge of object to window top (fixed)`, function () {
|
||||
const object = createObject({ [objectEdge]: 1 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.equal(500);
|
||||
expect(object.getY()).to.equal(500);
|
||||
expect(object.getWidth()).to.equal(10);
|
||||
});
|
||||
});
|
||||
['topEdgeAnchor', 'bottomEdgeAnchor'].forEach((objectEdge) => {
|
||||
it(`anchors the ${objectEdge} edge of object to window bottom (fixed)`, function () {
|
||||
const object = createObject({ [objectEdge]: 2 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.equal(500);
|
||||
expect(object.getY()).to.equal(1500);
|
||||
expect(object.getWidth()).to.equal(10);
|
||||
});
|
||||
});
|
||||
|
||||
it('anchors the top and bottom edge of object (fixed)', function () {
|
||||
const object = createObject({ topEdgeAnchor: 1, bottomEdgeAnchor: 2 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.equal(500);
|
||||
expect(object.getY()).to.equal(500);
|
||||
expect(object.getHeight()).to.equal(1010);
|
||||
});
|
||||
|
||||
it('anchors the top edge of object (proportional)', function () {
|
||||
const object = createObject({ topEdgeAnchor: 3 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.equal(500);
|
||||
expect(object.getY()).to.equal(1000);
|
||||
expect(object.getWidth()).to.equal(10);
|
||||
});
|
||||
});
|
||||
});
|
@@ -95,11 +95,10 @@ namespace gdjs {
|
||||
}
|
||||
|
||||
updateFontFamily(): void {
|
||||
this._pixiObject.textStyles.default.fontFamily =
|
||||
this._object._runtimeScene
|
||||
.getGame()
|
||||
.getFontManager()
|
||||
.getFontFamily(this._object._fontFamily);
|
||||
this._pixiObject.textStyles.default.fontFamily = this._object._runtimeScene
|
||||
.getGame()
|
||||
.getFontManager()
|
||||
.getFontFamily(this._object._fontFamily);
|
||||
this._pixiObject.dirty = true;
|
||||
}
|
||||
|
||||
|
@@ -169,6 +169,5 @@ namespace gdjs {
|
||||
return this._pixiObject.textHeight * this.getScale();
|
||||
}
|
||||
}
|
||||
export const BitmapTextRuntimeObjectRenderer =
|
||||
BitmapTextRuntimeObjectPixiRenderer;
|
||||
export const BitmapTextRuntimeObjectRenderer = BitmapTextRuntimeObjectPixiRenderer;
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@
|
||||
# consist in a few lines containing calls to these functions.
|
||||
|
||||
macro(gd_add_extension_includes)
|
||||
include_directories(${sfml_include_dir})
|
||||
include_directories(${GDCORE_include_dir})
|
||||
endmacro()
|
||||
|
||||
@@ -80,6 +81,7 @@ function(gd_extension_link_libraries target_name)
|
||||
#Nothing.
|
||||
ELSE()
|
||||
target_link_libraries(${target_name} GDCore)
|
||||
target_link_libraries(${target_name} ${sfml_LIBRARIES})
|
||||
ENDIF()
|
||||
endfunction()
|
||||
|
||||
|
@@ -414,8 +414,9 @@ namespace gdjs {
|
||||
return;
|
||||
}
|
||||
if (this.dialogueData.select) {
|
||||
this.selectedOption =
|
||||
gdjs.dialogueTree._normalizedOptionIndex(optionIndex);
|
||||
this.selectedOption = gdjs.dialogueTree._normalizedOptionIndex(
|
||||
optionIndex
|
||||
);
|
||||
this.selectedOptionUpdated = true;
|
||||
}
|
||||
};
|
||||
|
@@ -7,7 +7,7 @@ This project is released under the MIT License.
|
||||
|
||||
#ifndef DRAGGABLEBEHAVIOR_H
|
||||
#define DRAGGABLEBEHAVIOR_H
|
||||
#include "GDCore/Vector2.h"
|
||||
#include <SFML/System/Vector2.hpp>
|
||||
#include <map>
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
|
@@ -52,8 +52,9 @@ namespace gdjs {
|
||||
const inputManager = runtimeScene.getGame().getInputManager();
|
||||
|
||||
//Try mouse
|
||||
const mouseDraggableManager =
|
||||
DraggableManager.getMouseManager(runtimeScene);
|
||||
const mouseDraggableManager = DraggableManager.getMouseManager(
|
||||
runtimeScene
|
||||
);
|
||||
if (
|
||||
inputManager.isMouseButtonPressed(0) &&
|
||||
!mouseDraggableManager.isDragging(this)
|
||||
@@ -106,8 +107,9 @@ namespace gdjs {
|
||||
}
|
||||
|
||||
doStepPostEvents(runtimeScene) {
|
||||
const mouseDraggableManager =
|
||||
DraggableManager.getMouseManager(runtimeScene);
|
||||
const mouseDraggableManager = DraggableManager.getMouseManager(
|
||||
runtimeScene
|
||||
);
|
||||
mouseDraggableManager.leftPressedLastFrame = runtimeScene
|
||||
.getGame()
|
||||
.getInputManager()
|
||||
@@ -172,8 +174,9 @@ namespace gdjs {
|
||||
if (!runtimeScene.touchDraggableManagers[touchId]) {
|
||||
//Create the shared manager if necessary.
|
||||
// @ts-ignore
|
||||
runtimeScene.touchDraggableManagers[touchId] =
|
||||
new TouchDraggableManager(runtimeScene, touchId);
|
||||
runtimeScene.touchDraggableManagers[
|
||||
touchId
|
||||
] = new TouchDraggableManager(runtimeScene, touchId);
|
||||
}
|
||||
// @ts-ignore
|
||||
return runtimeScene.touchDraggableManagers[touchId];
|
||||
|
@@ -307,7 +307,7 @@ module.exports = {
|
||||
.setLabel(_('Color map texture for the effect'))
|
||||
.setDescription(
|
||||
_(
|
||||
'You can change colors of pixels by modifing a reference color image, containing each colors, called the *Color Map Texture*. To get started, **download** [a default color map texture here](https://wiki.gdevelop.io/gdevelop5/interface/scene-editor/layer-effects).'
|
||||
'You can change colors of pixels by modifing a reference color image, containing each colors, called the *Color Map Texture*. To get started, **download** [a default color map texture here](http://wiki.compilgames.net/doku.php/gdevelop5/interface/scene-editor/layer-effects).'
|
||||
)
|
||||
);
|
||||
colorMapProperties
|
||||
@@ -442,7 +442,7 @@ module.exports = {
|
||||
.setLabel(_('Displacement map texture'))
|
||||
.setDescription(
|
||||
_(
|
||||
'Displacement map texture for the effect. To get started, **download** [a default displacement map texture here](https://wiki.gdevelop.io/gdevelop5/interface/scene-editor/layer-effects).'
|
||||
'Displacement map texture for the effect. To get started, **download** [a default displacement map texture here](http://wiki.compilgames.net/doku.php/gdevelop5/interface/scene-editor/layer-effects).'
|
||||
)
|
||||
);
|
||||
displacementProperties
|
||||
|
@@ -6,8 +6,7 @@ namespace gdjs {
|
||||
},
|
||||
updatePreRender: function (filter, target) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const adjustmentFilter =
|
||||
filter as unknown as PIXI.filters.AdjustmentFilter;
|
||||
const adjustmentFilter = (filter as unknown) as PIXI.filters.AdjustmentFilter;
|
||||
if (parameterName === 'gamma') {
|
||||
adjustmentFilter.gamma = value;
|
||||
} else if (parameterName === 'saturation') {
|
||||
|
@@ -6,8 +6,7 @@ namespace gdjs {
|
||||
},
|
||||
updatePreRender: function (filter, target) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const advancedBloomFilter =
|
||||
filter as unknown as PIXI.filters.AdvancedBloomFilter;
|
||||
const advancedBloomFilter = (filter as unknown) as PIXI.filters.AdvancedBloomFilter;
|
||||
if (parameterName === 'threshold') {
|
||||
advancedBloomFilter.threshold = value;
|
||||
} else if (parameterName === 'bloomScale') {
|
||||
|
@@ -6,7 +6,7 @@ namespace gdjs {
|
||||
},
|
||||
updatePreRender: function (filter, target) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const asciiFilter = filter as unknown as PIXI.filters.AsciiFilter;
|
||||
const asciiFilter = (filter as unknown) as PIXI.filters.AsciiFilter;
|
||||
if (parameterName === 'size') {
|
||||
asciiFilter.size = value;
|
||||
}
|
||||
|
@@ -6,7 +6,7 @@ namespace gdjs {
|
||||
},
|
||||
updatePreRender: function (filter, target) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const bevelFilter = filter as unknown as PIXI.filters.BevelFilter;
|
||||
const bevelFilter = (filter as unknown) as PIXI.filters.BevelFilter;
|
||||
if (parameterName === 'rotation') {
|
||||
bevelFilter.rotation = value;
|
||||
} else if (parameterName === 'thickness') {
|
||||
@@ -21,14 +21,16 @@ namespace gdjs {
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {
|
||||
const bevelFilter = filter as unknown as PIXI.filters.BevelFilter;
|
||||
const bevelFilter = (filter as unknown) as PIXI.filters.BevelFilter;
|
||||
if (parameterName === 'lightColor') {
|
||||
bevelFilter.lightColor =
|
||||
gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
|
||||
bevelFilter.lightColor = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(
|
||||
value
|
||||
);
|
||||
}
|
||||
if (parameterName === 'shadowColor') {
|
||||
bevelFilter.shadowColor =
|
||||
gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
|
||||
bevelFilter.shadowColor = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(
|
||||
value
|
||||
);
|
||||
}
|
||||
},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {},
|
||||
|
@@ -9,7 +9,7 @@ namespace gdjs {
|
||||
updatePreRender: function (filter, target) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
// @ts-ignore - unsure why PIXI.filters is not recognised.
|
||||
const colorMatrix = filter as unknown as PIXI.filters.ColorMatrixFilter;
|
||||
const colorMatrix = (filter as unknown) as PIXI.filters.ColorMatrixFilter;
|
||||
if (parameterName !== 'opacity') {
|
||||
return;
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ namespace gdjs {
|
||||
updatePreRender: function (filter, target) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
// @ts-ignore - unsure why PIXI.filters is not recognised.
|
||||
const blendingModeFilter = filter as unknown as PIXI.filters.AlphaFilter;
|
||||
const blendingModeFilter = (filter as unknown) as PIXI.filters.AlphaFilter;
|
||||
if (parameterName === 'alpha') {
|
||||
blendingModeFilter.alpha = value;
|
||||
} else if (parameterName === 'blendmode') {
|
||||
|
@@ -9,8 +9,7 @@ namespace gdjs {
|
||||
updatePreRender: function (filter, target) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
// @ts-ignore - unsure why PIXI.filters is not recognised.
|
||||
const brightnessFilter =
|
||||
filter as unknown as PIXI.filters.ColorMatrixFilter;
|
||||
const brightnessFilter = (filter as unknown) as PIXI.filters.ColorMatrixFilter;
|
||||
if (parameterName !== 'brightness') {
|
||||
return;
|
||||
}
|
||||
|
@@ -6,8 +6,7 @@ namespace gdjs {
|
||||
},
|
||||
updatePreRender: function (filter, target) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const bulgePinchFilter =
|
||||
filter as unknown as PIXI.filters.BulgePinchFilter;
|
||||
const bulgePinchFilter = (filter as unknown) as PIXI.filters.BulgePinchFilter;
|
||||
if (parameterName === 'centerX') {
|
||||
bulgePinchFilter.center[0] = value;
|
||||
} else if (parameterName === 'centerY') {
|
||||
|
@@ -19,7 +19,7 @@ namespace gdjs {
|
||||
},
|
||||
updatePreRender: function (filter, target) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const colorMapFilter = filter as unknown as PIXI.filters.ColorMapFilter;
|
||||
const colorMapFilter = (filter as unknown) as PIXI.filters.ColorMapFilter;
|
||||
if (parameterName === 'mix') {
|
||||
colorMapFilter.mix = gdjs.PixiFiltersTools.clampValue(
|
||||
value / 100,
|
||||
@@ -30,7 +30,7 @@ namespace gdjs {
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {
|
||||
const colorMapFilter = filter as unknown as PIXI.filters.ColorMapFilter;
|
||||
const colorMapFilter = (filter as unknown) as PIXI.filters.ColorMapFilter;
|
||||
if (parameterName === 'nearest') {
|
||||
colorMapFilter.nearest = value;
|
||||
}
|
||||
|
@@ -6,21 +6,21 @@ namespace gdjs {
|
||||
},
|
||||
updatePreRender: function (filter, target) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const colorReplaceFilter =
|
||||
filter as unknown as PIXI.filters.ColorReplaceFilter;
|
||||
const colorReplaceFilter = (filter as unknown) as PIXI.filters.ColorReplaceFilter;
|
||||
if (parameterName === 'epsilon') {
|
||||
colorReplaceFilter.epsilon = value;
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {
|
||||
const colorReplaceFilter =
|
||||
filter as unknown as PIXI.filters.ColorReplaceFilter;
|
||||
const colorReplaceFilter = (filter as unknown) as PIXI.filters.ColorReplaceFilter;
|
||||
if (parameterName === 'originalColor') {
|
||||
colorReplaceFilter.originalColor =
|
||||
gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
|
||||
colorReplaceFilter.originalColor = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(
|
||||
value
|
||||
);
|
||||
} else if (parameterName === 'newColor') {
|
||||
colorReplaceFilter.newColor =
|
||||
gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
|
||||
colorReplaceFilter.newColor = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(
|
||||
value
|
||||
);
|
||||
}
|
||||
},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {},
|
||||
|
@@ -17,8 +17,7 @@ namespace gdjs {
|
||||
updatePreRender: function (filter, target) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
// @ts-ignore - unsure why PIXI.filters is not recognised.
|
||||
const displacementFilter =
|
||||
filter as unknown as PIXI.filters.DisplacementFilter;
|
||||
const displacementFilter = (filter as unknown) as PIXI.filters.DisplacementFilter;
|
||||
if (parameterName === 'scaleX') {
|
||||
displacementFilter.scale.x = value;
|
||||
}
|
||||
|
@@ -6,7 +6,7 @@ namespace gdjs {
|
||||
},
|
||||
updatePreRender: function (filter, target) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const dotFilter = filter as unknown as PIXI.filters.DotFilter;
|
||||
const dotFilter = (filter as unknown) as PIXI.filters.DotFilter;
|
||||
if (parameterName === 'scale') {
|
||||
dotFilter.scale = value;
|
||||
} else if (parameterName === 'angle') {
|
||||
|
@@ -6,8 +6,7 @@ namespace gdjs {
|
||||
},
|
||||
updatePreRender: function (filter, target) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const dropShadowFilter =
|
||||
filter as unknown as PIXI.filters.DropShadowFilter;
|
||||
const dropShadowFilter = (filter as unknown) as PIXI.filters.DropShadowFilter;
|
||||
if (parameterName === 'blur') {
|
||||
dropShadowFilter.blur = value;
|
||||
} else if (parameterName === 'quality') {
|
||||
@@ -23,16 +22,15 @@ namespace gdjs {
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {
|
||||
const dropShadowFilter =
|
||||
filter as unknown as PIXI.filters.DropShadowFilter;
|
||||
const dropShadowFilter = (filter as unknown) as PIXI.filters.DropShadowFilter;
|
||||
if (parameterName === 'color') {
|
||||
dropShadowFilter.color =
|
||||
gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
|
||||
dropShadowFilter.color = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(
|
||||
value
|
||||
);
|
||||
}
|
||||
},
|
||||
updateBooleanParameter: function (filter, parameterName, value) {
|
||||
const dropShadowFilter =
|
||||
filter as unknown as PIXI.filters.DropShadowFilter;
|
||||
const dropShadowFilter = (filter as unknown) as PIXI.filters.DropShadowFilter;
|
||||
if (parameterName === 'shadowOnly') {
|
||||
dropShadowFilter.shadowOnly = value;
|
||||
}
|
||||
|
@@ -6,7 +6,7 @@ namespace gdjs {
|
||||
},
|
||||
updatePreRender: function (filter, target) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const glowFilter = filter as unknown as PIXI.filters.GlowFilter;
|
||||
const glowFilter = (filter as unknown) as PIXI.filters.GlowFilter;
|
||||
if (parameterName === 'innerStrength') {
|
||||
glowFilter.innerStrength = value;
|
||||
} else if (parameterName === 'outerStrength') {
|
||||
@@ -17,7 +17,7 @@ namespace gdjs {
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {
|
||||
const glowFilter = filter as unknown as PIXI.filters.GlowFilter;
|
||||
const glowFilter = (filter as unknown) as PIXI.filters.GlowFilter;
|
||||
if (parameterName === 'color') {
|
||||
glowFilter.color = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
|
||||
}
|
||||
|
@@ -6,8 +6,7 @@ namespace gdjs {
|
||||
},
|
||||
updatePreRender: function (filter, target) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const kawaseBlurFilter =
|
||||
filter as unknown as PIXI.filters.KawaseBlurFilter;
|
||||
const kawaseBlurFilter = (filter as unknown) as PIXI.filters.KawaseBlurFilter;
|
||||
if (parameterName === 'pixelizeX') {
|
||||
// @ts-ignore: fix these wrong parameters
|
||||
kawaseBlurFilter.pixelizeX = value;
|
||||
|
@@ -8,7 +8,7 @@ namespace gdjs {
|
||||
updatePreRender: function (filter, target) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
// @ts-ignore - unsure why PIXI.filters is not recognised.
|
||||
const noiseFilter = filter as unknown as PIXI.filters.NoiseFilter;
|
||||
const noiseFilter = (filter as unknown) as PIXI.filters.NoiseFilter;
|
||||
if (parameterName !== 'noise') {
|
||||
return;
|
||||
}
|
||||
|
@@ -6,7 +6,7 @@ namespace gdjs {
|
||||
},
|
||||
updatePreRender: function (filter, target) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const outlineFilter = filter as unknown as PIXI.filters.OutlineFilter;
|
||||
const outlineFilter = (filter as unknown) as PIXI.filters.OutlineFilter;
|
||||
if (parameterName === 'thickness') {
|
||||
outlineFilter.thickness = value;
|
||||
} else if (parameterName === 'padding') {
|
||||
@@ -14,7 +14,7 @@ namespace gdjs {
|
||||
}
|
||||
},
|
||||
updateStringParameter: function (filter, parameterName, value) {
|
||||
const outlineFilter = filter as unknown as PIXI.filters.OutlineFilter;
|
||||
const outlineFilter = (filter as unknown) as PIXI.filters.OutlineFilter;
|
||||
if (parameterName === 'color') {
|
||||
outlineFilter.color = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ namespace gdjs {
|
||||
},
|
||||
updatePreRender: function (filter, target) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const pixelateFilter = filter as unknown as PIXI.filters.PixelateFilter;
|
||||
const pixelateFilter = (filter as unknown) as PIXI.filters.PixelateFilter;
|
||||
if (parameterName === 'size') {
|
||||
pixelateFilter.size = value;
|
||||
}
|
||||
|
@@ -5,8 +5,7 @@ namespace gdjs {
|
||||
return radialBlurFilter;
|
||||
},
|
||||
updatePreRender: function (filter, target) {
|
||||
const radialBlurFilter =
|
||||
filter as unknown as PIXI.filters.RadialBlurFilter;
|
||||
const radialBlurFilter = (filter as unknown) as PIXI.filters.RadialBlurFilter;
|
||||
radialBlurFilter.center[0] = Math.round(
|
||||
// @ts-ignore - extra properties are stored on the filter.
|
||||
radialBlurFilter._centerX * target.getWidth()
|
||||
@@ -17,8 +16,7 @@ namespace gdjs {
|
||||
);
|
||||
},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const radialBlurFilter =
|
||||
filter as unknown as PIXI.filters.RadialBlurFilter;
|
||||
const radialBlurFilter = (filter as unknown) as PIXI.filters.RadialBlurFilter;
|
||||
if (parameterName === 'radius') {
|
||||
radialBlurFilter.radius = value < 0 ? -1 : value;
|
||||
} else if (parameterName === 'angle') {
|
||||
|
@@ -6,7 +6,7 @@ namespace gdjs {
|
||||
},
|
||||
updatePreRender: function (filter, target) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const rgbSplitFilter = filter as unknown as PIXI.filters.RGBSplitFilter;
|
||||
const rgbSplitFilter = (filter as unknown) as PIXI.filters.RGBSplitFilter;
|
||||
if (parameterName === 'redX') {
|
||||
rgbSplitFilter.red.x = value;
|
||||
} else if (parameterName === 'redY') {
|
||||
|
@@ -9,8 +9,7 @@ namespace gdjs {
|
||||
updatePreRender: function (filter, target) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
// @ts-ignore - unsure why PIXI.filters is not recognised.
|
||||
const colorMatrixFilter =
|
||||
filter as unknown as PIXI.filters.ColorMatrixFilter;
|
||||
const colorMatrixFilter = (filter as unknown) as PIXI.filters.ColorMatrixFilter;
|
||||
if (parameterName !== 'opacity') {
|
||||
return;
|
||||
}
|
||||
|
@@ -6,7 +6,7 @@ namespace gdjs {
|
||||
},
|
||||
updatePreRender: function (filter, target) {},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const tiltShiftFilter = filter as unknown as PIXI.filters.TiltShiftFilter;
|
||||
const tiltShiftFilter = (filter as unknown) as PIXI.filters.TiltShiftFilter;
|
||||
if (parameterName === 'blur') {
|
||||
tiltShiftFilter.blur = value;
|
||||
} else if (parameterName === 'gradientBlur') {
|
||||
|
@@ -11,7 +11,7 @@ namespace gdjs {
|
||||
return twistFilter;
|
||||
},
|
||||
updatePreRender: function (filter, target) {
|
||||
const twistFilter = filter as unknown as PIXI.filters.TwistFilter;
|
||||
const twistFilter = (filter as unknown) as PIXI.filters.TwistFilter;
|
||||
twistFilter.offset.x = Math.round(
|
||||
// @ts-ignore - extra properties are stored on the filter.
|
||||
twistFilter._offsetX * target.getWidth()
|
||||
@@ -22,7 +22,7 @@ namespace gdjs {
|
||||
);
|
||||
},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const twistFilter = filter as unknown as PIXI.filters.TwistFilter;
|
||||
const twistFilter = (filter as unknown) as PIXI.filters.TwistFilter;
|
||||
if (parameterName === 'radius') {
|
||||
twistFilter.radius = value;
|
||||
} else if (parameterName === 'angle') {
|
||||
|
@@ -5,7 +5,7 @@ namespace gdjs {
|
||||
return zoomBlurFilter;
|
||||
},
|
||||
updatePreRender: function (filter, target) {
|
||||
const zoomBlurFilter = filter as unknown as PIXI.filters.ZoomBlurFilter;
|
||||
const zoomBlurFilter = (filter as unknown) as PIXI.filters.ZoomBlurFilter;
|
||||
zoomBlurFilter.center[0] = Math.round(
|
||||
// @ts-ignore - extra properties are stored on the filter.
|
||||
zoomBlurFilter._centerX * target.getWidth()
|
||||
@@ -16,7 +16,7 @@ namespace gdjs {
|
||||
);
|
||||
},
|
||||
updateDoubleParameter: function (filter, parameterName, value) {
|
||||
const zoomBlurFilter = filter as unknown as PIXI.filters.ZoomBlurFilter;
|
||||
const zoomBlurFilter = (filter as unknown) as PIXI.filters.ZoomBlurFilter;
|
||||
if (parameterName === 'centerX') {
|
||||
// @ts-ignore - extra properties are stored on the filter.
|
||||
zoomBlurFilter._centerX = value;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user