Compare commits

..

2 Commits

Author SHA1 Message Date
Davy Hélard
f8f692fff4 Fix duplicated active objects after recycling. 2023-11-28 20:51:27 +01:00
Davy Hélard
d051aa4302 Avoid to iterate on inactive objects 2023-11-28 14:29:38 +01:00
630 changed files with 47890 additions and 48486 deletions

View File

@@ -56,7 +56,6 @@ blocks:
- name: GDJS typing and documentation generation
commands:
- checkout
- cache restore newIDE-app-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum newIDE/app/package-lock.json)
- cache restore GDJS-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum GDJS/package-lock.json)
- cache restore GDJS-tests-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum GDJS/tests/package-lock.json)
- cd GDJS

View File

@@ -714,8 +714,6 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
metadata.GetType() == "tilesetResource" ||
metadata.GetType() == "videoResource" ||
metadata.GetType() == "model3DResource" ||
metadata.GetType() == "atlasResource" ||
metadata.GetType() == "spineResource" ||
// Deprecated, old parameter names:
metadata.GetType() == "password" || metadata.GetType() == "musicfile" ||
metadata.GetType() == "soundfile" || metadata.GetType() == "police") {

View File

@@ -277,11 +277,8 @@ class GD_CORE_API ExpressionParser2 {
std::unique_ptr<VariableNode> Variable(const gd::String &name, gd::ExpressionParserLocation nameLocation) {
auto variable = gd::make_unique<VariableNode>(name);
if (CheckIfChar(IsOpeningSquareBracket) || CheckIfChar(IsDot)) {
variable->child = VariableAccessorOrVariableBracketAccessor();
variable->child->parent = variable.get();
}
variable->child = VariableAccessorOrVariableBracketAccessor();
variable->child->parent = variable.get();
variable->location = ExpressionParserLocation(
nameLocation.GetStartPosition(), GetCurrentPosition());
@@ -305,12 +302,8 @@ class GD_CORE_API ExpressionParser2 {
"bracket for each opening bracket."));
}
SkipIfChar(IsClosingSquareBracket);
SkipAllWhitespaces();
if (CheckIfChar(IsOpeningSquareBracket) || CheckIfChar(IsDot)) {
child->child = VariableAccessorOrVariableBracketAccessor();
child->child->parent = child.get();
}
child->child = VariableAccessorOrVariableBracketAccessor();
child->child->parent = child.get();
child->location =
ExpressionParserLocation(childStartPosition, GetCurrentPosition());
@@ -322,15 +315,8 @@ class GD_CORE_API ExpressionParser2 {
auto identifierAndLocation = ReadIdentifierName(/*allowDeprecatedSpacesInName=*/ false);
auto child =
gd::make_unique<VariableAccessorNode>(identifierAndLocation.name);
if (identifierAndLocation.name.empty()) {
child->diagnostic = RaiseSyntaxError(_("A name should be entered after the dot."));
}
SkipAllWhitespaces();
if (CheckIfChar(IsOpeningSquareBracket) || CheckIfChar(IsDot)) {
child->child = VariableAccessorOrVariableBracketAccessor();
child->child->parent = child.get();
}
child->child = VariableAccessorOrVariableBracketAccessor();
child->child->parent = child.get();
child->nameLocation = identifierAndLocation.location;
child->dotLocation = dotLocation;
child->location =
@@ -339,11 +325,7 @@ class GD_CORE_API ExpressionParser2 {
return std::move(child);
}
// Should never happen, unless a node called this function without checking if the current character
// was a dot or an opening bracket - this means there is an error in the grammar.
auto unrecognisedNode = gd::make_unique<VariableAccessorOrVariableBracketAccessorNode>();
unrecognisedNode->diagnostic = RaiseSyntaxError(_("A dot or bracket was expected here."));
return std::move(unrecognisedNode);
return std::move(gd::make_unique<VariableAccessorOrVariableBracketAccessorNode>());
}
std::unique_ptr<FunctionCallNode> FreeFunction(
@@ -379,24 +361,18 @@ class GD_CORE_API ExpressionParser2 {
const auto &childIdentifierNameLocation =
childIdentifierAndLocation.location;
std::unique_ptr<gd::ExpressionParserError> emptyNameError = childIdentifierName.empty() ?
RaiseSyntaxError(_("A name should be entered after the dot.")) : nullptr;
SkipAllWhitespaces();
if (IsNamespaceSeparator()) {
ExpressionParserLocation namespaceSeparatorLocation =
SkipNamespaceSeparator();
SkipAllWhitespaces();
auto behaviorFunction = BehaviorFunction(parentIdentifier,
return BehaviorFunction(parentIdentifier,
childIdentifierName,
parentIdentifierLocation,
parentIdentifierDotLocation,
childIdentifierNameLocation,
namespaceSeparatorLocation);
if (emptyNameError) behaviorFunction->diagnostic = std::move(emptyNameError);
return std::move(behaviorFunction);
} else if (CheckIfChar(IsOpeningParenthesis)) {
ExpressionParserLocation openingParenthesisLocation = SkipChar();
@@ -405,7 +381,7 @@ class GD_CORE_API ExpressionParser2 {
childIdentifierName);
auto parametersNode = Parameters(function.get(), parentIdentifier);
function->parameters = std::move(parametersNode.parameters),
function->diagnostic = emptyNameError ? std::move(emptyNameError) : std::move(parametersNode.diagnostic);
function->diagnostic = std::move(parametersNode.diagnostic);
function->location = ExpressionParserLocation(
parentIdentifierLocation.GetStartPosition(), GetCurrentPosition());
@@ -418,8 +394,6 @@ class GD_CORE_API ExpressionParser2 {
return std::move(function);
} else if (CheckIfChar(IsDot) || CheckIfChar(IsOpeningSquareBracket)) {
auto variable = gd::make_unique<VariableNode>(parentIdentifier);
variable->diagnostic = std::move(emptyNameError);
auto child =
gd::make_unique<VariableAccessorNode>(childIdentifierName);
child->child = VariableAccessorOrVariableBracketAccessor();
@@ -445,7 +419,6 @@ class GD_CORE_API ExpressionParser2 {
node->identifierNameLocation = parentIdentifierLocation;
node->identifierNameDotLocation = parentIdentifierDotLocation;
node->childIdentifierNameLocation = childIdentifierNameLocation;
node->diagnostic = std::move(emptyNameError);
return std::move(node);
}

View File

@@ -8,7 +8,6 @@
#include <memory>
#include <vector>
#include "GDCore/Events/Parsers/ExpressionParser2Node.h"
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
namespace gd {
@@ -44,11 +43,6 @@ class GD_CORE_API ExpressionParser2NodePrinter
*/
const gd::String& GetOutput() { return output; };
static gd::String PrintStringLiteral(const gd::String& str) {
return "\"" +
str.FindAndReplace("\\", "\\\\").FindAndReplace("\"", "\\\"") + "\"";
}
protected:
void OnVisitSubExpressionNode(SubExpressionNode& node) override {
output += "(";
@@ -75,7 +69,10 @@ class GD_CORE_API ExpressionParser2NodePrinter
}
void OnVisitNumberNode(NumberNode& node) override { output += node.number; }
void OnVisitTextNode(TextNode& node) override {
output += PrintStringLiteral(node.text);
output +=
"\"" +
node.text.FindAndReplace("\\", "\\\\").FindAndReplace("\"", "\\\"") +
"\"";
}
void OnVisitVariableNode(VariableNode& node) override {
output += node.name;
@@ -100,8 +97,8 @@ class GD_CORE_API ExpressionParser2NodePrinter
}
void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode& node) override {
if (!node.behaviorFunctionName.empty()) {
output += node.objectName + "." + node.objectFunctionOrBehaviorName +
"::" + node.behaviorFunctionName;
output +=
node.objectName + "." + node.objectFunctionOrBehaviorName + "::" + node.behaviorFunctionName;
} else {
output += node.objectName + "." + node.objectFunctionOrBehaviorName;
}

View File

@@ -1281,8 +1281,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Enable an effect on the object"),
_("Enable effect _PARAM1_ on _PARAM0_: _PARAM2_"),
_("Effects"),
"res/actions/effect_black.svg",
"res/actions/effect_black.svg")
"res/actions/effect24.png",
"res/actions/effect.png")
.AddParameter("object", _("Object"))
.AddParameter("objectEffectName", _("Effect name"))
.AddParameter("yesorno", _("Enable?"))
@@ -1297,8 +1297,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"names) in the effects window."),
_("Set _PARAM2_ to _PARAM3_ for effect _PARAM1_ of _PARAM0_"),
_("Effects"),
"res/actions/effect_black.svg",
"res/actions/effect_black.svg")
"res/actions/effect24.png",
"res/actions/effect.png")
.AddParameter("object", _("Object"))
.AddParameter("objectEffectName", _("Effect name"))
.AddParameter("objectEffectParameterName", _("Property name"))
@@ -1315,8 +1315,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"names) in the effects window."),
_("Set _PARAM2_ to _PARAM3_ for effect _PARAM1_ of _PARAM0_"),
_("Effects"),
"res/actions/effect_black.svg",
"res/actions/effect_black.svg")
"res/actions/effect24.png",
"res/actions/effect.png")
.AddParameter("object", _("Object"))
.AddParameter("objectEffectName", _("Effect name"))
.AddParameter("objectEffectParameterName", _("Property name"))
@@ -1332,8 +1332,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"names) in the effects window."),
_("Enable _PARAM2_ for effect _PARAM1_ of _PARAM0_: _PARAM3_"),
_("Effects"),
"res/actions/effect_black.svg",
"res/actions/effect_black.svg")
"res/actions/effect24.png",
"res/actions/effect.png")
.AddParameter("object", _("Object"))
.AddParameter("objectEffectName", _("Effect name"))
.AddParameter("objectEffectParameterName", _("Property name"))
@@ -1347,8 +1347,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Check if the effect on an object is enabled."),
_("Effect _PARAM1_ of _PARAM0_ is enabled"),
_("Effects"),
"res/actions/effect_black.svg",
"res/actions/effect_black.svg")
"res/actions/effect24.png",
"res/actions/effect.png")
.AddParameter("object", _("Object"))
.AddParameter("objectEffectName", _("Effect name"))
.MarkAsSimple()

View File

@@ -27,7 +27,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
extension.AddInstructionOrExpressionGroupMetadata(_("Layers and cameras"))
.SetIcon("res/conditions/camera24.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Effects"))
.SetIcon("res/actions/effect_black.svg");
.SetIcon("res/actions/effect24.png");
extension
.AddExpressionAndConditionAndAction(
@@ -450,8 +450,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"names) in the effects window."),
_("Set _PARAM3_ to _PARAM4_ for effect _PARAM2_ of layer _PARAM1_"),
_("Effects"),
"res/actions/effect_black.svg",
"res/actions/effect_black.svg")
"res/actions/effect24.png",
"res/actions/effect.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
@@ -469,8 +469,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"names) in the effects window."),
_("Set _PARAM3_ to _PARAM4_ for effect _PARAM2_ of layer _PARAM1_"),
_("Effects"),
"res/actions/effect_black.svg",
"res/actions/effect_black.svg")
"res/actions/effect24.png",
"res/actions/effect.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
@@ -488,8 +488,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"names) in the effects window."),
_("Enable _PARAM3_ for effect _PARAM2_ of layer _PARAM1_: _PARAM4_"),
_("Effects"),
"res/actions/effect_black.svg",
"res/actions/effect_black.svg")
"res/actions/effect24.png",
"res/actions/effect.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
@@ -504,8 +504,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("The effect on a layer is enabled"),
_("Effect _PARAM2_ on layer _PARAM1_ is enabled"),
_(""),
"res/actions/effect_black.svg",
"res/actions/effect_black.svg")
"res/actions/effect24.png",
"res/actions/effect.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
@@ -518,8 +518,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Enable an effect on a layer"),
_("Enable effect _PARAM2_ on layer _PARAM1_: _PARAM3_"),
_("Effects"),
"res/actions/effect_black.svg",
"res/actions/effect_black.svg")
"res/actions/effect24.png",
"res/actions/effect.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")

View File

@@ -24,7 +24,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsEffectExtension(
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
extension.AddInstructionOrExpressionGroupMetadata(_("Effects"))
.SetIcon("res/actions/effect_black.svg");
.SetIcon("res/actions/effect24.png");
gd::BehaviorMetadata& aut = extension.AddBehavior(
"EffectBehavior",
@@ -32,7 +32,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsEffectExtension(
"Effect",
_("Apply visual effects to objects."),
"",
"res/actions/effect_black.svg",
"res/actions/effect24.png",
"EffectBehavior",
std::make_shared<gd::Behavior>(),
std::make_shared<gd::BehaviorsSharedData>())
@@ -43,8 +43,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsEffectExtension(
_("Enable an effect on the object"),
_("Enable effect _PARAM2_ on _PARAM0_: _PARAM3_"),
_("Effects"),
"res/actions/effect_black.svg",
"res/actions/effect_black.svg")
"res/actions/effect24.png",
"res/actions/effect.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
.AddParameter("objectEffectName", _("Effect name"))
@@ -58,8 +58,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsEffectExtension(
"names) in the effects window."),
_("Set _PARAM3_ to _PARAM4_ for effect _PARAM2_ of _PARAM0_"),
_("Effects"),
"res/actions/effect_black.svg",
"res/actions/effect_black.svg")
"res/actions/effect24.png",
"res/actions/effect.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
.AddParameter("objectEffectName", _("Effect name"))
@@ -75,8 +75,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsEffectExtension(
"names) in the effects window."),
_("Set _PARAM3_ to _PARAM4_ for effect _PARAM2_ of _PARAM0_"),
_("Effects"),
"res/actions/effect_black.svg",
"res/actions/effect_black.svg")
"res/actions/effect24.png",
"res/actions/effect.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
.AddParameter("objectEffectName", _("Effect name"))
@@ -91,8 +91,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsEffectExtension(
"names) in the effects window."),
_("Enable _PARAM3_ for effect _PARAM2_ of _PARAM0_: _PARAM4_"),
_("Effects"),
"res/actions/effect_black.svg",
"res/actions/effect_black.svg")
"res/actions/effect24.png",
"res/actions/effect.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
.AddParameter("objectEffectName", _("Effect name"))
@@ -105,8 +105,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsEffectExtension(
_("Check if the effect on an object is enabled."),
_("Effect _PARAM2_ of _PARAM0_ is enabled"),
_("Effects"),
"res/actions/effect_black.svg",
"res/actions/effect_black.svg")
"res/actions/effect24.png",
"res/actions/effect.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
.AddParameter("objectEffectName", _("Effect name"))

View File

@@ -24,7 +24,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFlippableExtension(
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
extension.AddInstructionOrExpressionGroupMetadata(_("Effects"))
.SetIcon("res/actions/effect_black.svg");
.SetIcon("res/actions/effect24.png");
gd::BehaviorMetadata& aut = extension.AddBehavior(
"FlippableBehavior",

View File

@@ -171,8 +171,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
_("Preload a scene resources as soon as possible in background."),
_("Preload scene _PARAM1_ in background"),
"",
"res/actions/hourglass_black.svg",
"res/actions/hourglass_black.svg")
"res/actions/replaceScene24.png",
"res/actions/replaceScene.png")
.SetHelpPath("/all-features/resources-loading")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("sceneName", _("Name of the new scene"))
@@ -184,7 +184,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
_("The progress of resources loading in background for a scene (between 0 and 1)."),
_("_PARAM0_ loading progress"),
_(""),
"res/actions/hourglass_black.svg")
"res/actions/replaceScene24.png")
.SetHelpPath("/all-features/resources-loading")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("sceneName", _("Scene name"))
@@ -197,8 +197,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
_("Check if scene resources have finished to load in background."),
_("Scene _PARAM1_ was preloaded in background"),
"",
"res/actions/hourglass_black.svg",
"res/actions/hourglass_black.svg")
"res/actions/replaceScene24.png",
"res/actions/replaceScene.png")
.SetHelpPath("/all-features/resources-loading")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("sceneName", _("Scene name"))

View File

@@ -5,7 +5,6 @@
*/
#include "ExpressionMetadata.h"
#include "GDCore/CommonTools.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/String.h"
namespace gd {
@@ -47,14 +46,16 @@ gd::ExpressionMetadata& ExpressionMetadata::AddParameter(
// For objects/behavior, the supplementary information
// parameter is an object/behavior type...
((gd::ParameterMetadata::IsObject(type) ||
gd::ParameterMetadata::IsBehavior(type))
// Prefix with the namespace if it's not already there.
&& (supplementaryInformation.find(
PlatformExtension::GetNamespaceSeparator()) == gd::String::npos)
? (supplementaryInformation.empty()
? ""
: extensionNamespace + supplementaryInformation)
: supplementaryInformation));
gd::ParameterMetadata::IsBehavior(type))
// Prefix with the namespace if it's not already there.
&& !(supplementaryInformation.rfind(extensionNamespace, 0) == 0))
? (supplementaryInformation.empty()
? ""
: extensionNamespace +
supplementaryInformation //... so prefix it with the extension
// namespace.
)
: supplementaryInformation); // Otherwise don't change anything
// TODO: Assert against supplementaryInformation === "emsc" (when running with
// Emscripten), and warn about a missing argument when calling addParameter.

View File

@@ -8,7 +8,6 @@
#include <algorithm>
#include "GDCore/CommonTools.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Serialization/SerializerElement.h"
#include "GDCore/Tools/Localization.h"
#include "GDCore/Tools/Log.h"
@@ -65,14 +64,17 @@ InstructionMetadata& InstructionMetadata::AddParameter(
// For objects/behavior, the supplementary information
// parameter is an object/behavior type...
((gd::ParameterMetadata::IsObject(type) ||
gd::ParameterMetadata::IsBehavior(type))
// Prefix with the namespace if it's not already there.
&& (supplementaryInformation.find(
PlatformExtension::GetNamespaceSeparator()) == gd::String::npos)
? (supplementaryInformation.empty()
? ""
: extensionNamespace + supplementaryInformation)
: supplementaryInformation));
gd::ParameterMetadata::IsBehavior(type))
// Prefix with the namespace if it's not already there.
&& !(supplementaryInformation.rfind(extensionNamespace, 0) == 0))
? (supplementaryInformation.empty()
? ""
: extensionNamespace +
supplementaryInformation //... so prefix it with the
// extension
// namespace.
)
: supplementaryInformation); // Otherwise don't change anything
// TODO: Assert against supplementaryInformation === "emsc" (when running with
// Emscripten), and warn about a missing argument when calling addParameter.
@@ -188,7 +190,7 @@ InstructionMetadata::UseStandardRelationalOperatorParameters(
gd::String templateSentence = _("<subject> of _PARAM0_ <operator> <value>");
sentence =
templateSentence.FindAndReplace("<subject>", sentence.CapitalizeFirstLetter())
templateSentence.FindAndReplace("<subject>", sentence)
.FindAndReplace(
"<operator>",
"_PARAM" + gd::String::From(operatorParamIndex) + "_")
@@ -198,7 +200,7 @@ InstructionMetadata::UseStandardRelationalOperatorParameters(
gd::String templateSentence = _("<subject> <operator> <value>");
sentence =
templateSentence.FindAndReplace("<subject>", sentence.CapitalizeFirstLetter())
templateSentence.FindAndReplace("<subject>", sentence)
.FindAndReplace(
"<operator>",
"_PARAM" + gd::String::From(operatorParamIndex) + "_")

View File

@@ -217,9 +217,7 @@ class GD_CORE_API ValueTypeMetadata {
parameterType == "jsonResource" ||
parameterType == "tilemapResource" ||
parameterType == "tilesetResource" ||
parameterType == "model3DResource" ||
parameterType == "atlasResource" ||
parameterType == "spineResource";
parameterType == "model3DResource";
}
return false;
}

View File

@@ -264,11 +264,8 @@ class GD_CORE_API PlatformExtension {
*
* \param name The name of the behavior
* \param fullname The user friendly name of the behavior
* \param defaultName The default name of behavior instances
* \param description The user friendly description of the behavior
* \param group The behavior category label
* \param icon The icon of the behavior.
* \param className The name of the class implementing the behavior
* \param instance An instance of the behavior that
* will be used to create the behavior
* \param sharedDatasInstance Optional
@@ -291,7 +288,6 @@ class GD_CORE_API PlatformExtension {
* \param name The name of the behavior
* \param fullname The user friendly name of the behavior
* \param description The user friendly description of the behavior
* \param group The behavior category label
* \param icon The icon of the behavior.
*/
gd::BehaviorMetadata& AddEventsBasedBehavior(

View File

@@ -136,7 +136,7 @@ class GD_CORE_API ExpressionVariableReplacer
auto& objectsContainersList =
projectScopedContainers.GetObjectsContainersList();
if (!objectNameToUseForVariableAccessor.empty()) {
if (objectsContainersList.HasObjectOrGroupVariablesContainer(
if (objectsContainersList.HasVariablesContainer(
objectNameToUseForVariableAccessor, targetVariablesContainer)) {
// The node represents an object variable, and this object variables are
// the target. Do the replacement or removals:
@@ -177,7 +177,7 @@ class GD_CORE_API ExpressionVariableReplacer
GetPotentialNewName(node.identifierName),
[&]() {
// This represents an object.
if (objectsContainersList.HasObjectOrGroupVariablesContainer(
if (objectsContainersList.HasVariablesContainer(
node.identifierName, targetVariablesContainer)) {
// The node represents an object variable, and this object variables
// are the target. Do the replacement or removals:

View File

@@ -11,16 +11,13 @@
#include "GDCore/Events/Parsers/ExpressionParser2.h"
#include "GDCore/Events/Parsers/ExpressionParser2Node.h"
#include "GDCore/Events/Parsers/ExpressionParser2NodePrinter.h"
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
#include "GDCore/Events/Parsers/GrammarTerminals.h"
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
#include "GDCore/Extensions/Metadata/ValueTypeMetadata.h"
#include "GDCore/IDE/Events/ExpressionNodeLocationFinder.h"
#include "GDCore/IDE/Events/ExpressionTypeFinder.h"
#include "GDCore/IDE/Events/ExpressionVariableOwnerFinder.h"
#include "GDCore/IDE/Events/ExpressionVariableParentFinder.h"
#include "GDCore/Project/ProjectScopedContainers.h"
#include "GDCore/Project/Variable.h"
@@ -489,56 +486,47 @@ class GD_CORE_API ExpressionCompletionFinder
auto type = gd::ExpressionTypeFinder::GetType(
platform, projectScopedContainers, rootType, node);
// Only attempt to complete with the children of the variable
// if it's the last child (no more `.AnotherVariable` written after).
bool eagerlyCompleteIfExactMatch = node.child == nullptr;
if (gd::ValueTypeMetadata::IsTypeLegacyPreScopedVariable(type)) {
if (type == "globalvar" || type == "scenevar") {
if (type == "globalvar") {
const auto* variablesContainer =
type == "globalvar"
? projectScopedContainers.GetVariablesContainersList()
.GetTopMostVariablesContainer()
: projectScopedContainers.GetVariablesContainersList()
.GetBottomMostVariablesContainer();
projectScopedContainers.GetVariablesContainersList()
.GetTopMostVariablesContainer();
if (variablesContainer) {
AddCompletionsForVariablesMatchingSearch(*variablesContainer,
node.name,
node.nameLocation,
eagerlyCompleteIfExactMatch);
AddCompletionsForVariablesMatchingSearch(
*variablesContainer, node.name, node.nameLocation);
}
} else if (type == "scenevar") {
const auto* variablesContainer =
projectScopedContainers.GetVariablesContainersList()
.GetBottomMostVariablesContainer();
if (variablesContainer) {
AddCompletionsForVariablesMatchingSearch(
*variablesContainer, node.name, node.nameLocation);
}
} else if (type == "objectvar") {
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(
platform, objectsContainersList, rootObjectName, node);
platform,
objectsContainersList,
// Variable fields doesn't use expression completion,
// so the object will be found inside the expression itself.
"",
node);
AddCompletionsForObjectOrGroupVariablesMatchingSearch(
objectsContainersList,
objectName,
node.name,
node.nameLocation,
eagerlyCompleteIfExactMatch);
objectsContainersList, objectName, node.name, node.nameLocation);
}
} else {
AddCompletionsForObjectsAndVariablesMatchingSearch(
node.name, type, node.nameLocation, eagerlyCompleteIfExactMatch);
node.name, type, node.nameLocation);
}
}
void OnVisitVariableAccessorNode(VariableAccessorNode& node) override {
VariableAndItsParent variableAndItsParent =
gd::ExpressionVariableParentFinder::GetLastParentOfNode(
platform, projectScopedContainers, node);
// If no child, we're at the end of a variable (like `GrandChild` in
// `Something.Child.GrandChild`) so we can complete eagerly children if we
// can.
gd::String eagerlyCompleteForVariableName =
node.child == nullptr ? node.name : "";
AddCompletionsForChildrenVariablesOf(variableAndItsParent,
node.nameLocation,
eagerlyCompleteForVariableName);
// No completions
}
void OnVisitVariableBracketAccessorNode(
VariableBracketAccessorNode& node) override {}
VariableBracketAccessorNode& node) override {
// No completions
}
void OnVisitIdentifierNode(IdentifierNode& node) override {
const auto& objectsContainersList =
projectScopedContainers.GetObjectsContainersList();
@@ -549,81 +537,45 @@ class GD_CORE_API ExpressionCompletionFinder
AddCompletionsForObjectMatchingSearch(
node.identifierName, type, node.location);
} else if (gd::ValueTypeMetadata::IsTypeLegacyPreScopedVariable(type)) {
if (type == "globalvar" || type == "scenevar") {
if (type == "globalvar") {
const auto* variablesContainer =
type == "globalvar"
? projectScopedContainers.GetVariablesContainersList()
.GetTopMostVariablesContainer()
: projectScopedContainers.GetVariablesContainersList()
.GetBottomMostVariablesContainer();
projectScopedContainers.GetVariablesContainersList()
.GetTopMostVariablesContainer();
if (variablesContainer) {
if (IsCaretOn(node.identifierNameDotLocation) ||
IsCaretOn(node.childIdentifierNameLocation)) {
// Complete a potential child variable:
if (variablesContainer->Has(node.identifierName)) {
AddCompletionsForChildrenVariablesOf(
&variablesContainer->Get(node.identifierName),
node.childIdentifierNameLocation,
node.childIdentifierName);
}
} else {
// Complete a root variable of the scene or project.
// Don't attempt to complete children variables if there is
// already a dot written (`MyVariable.`).
bool eagerlyCompleteIfPossible =
!node.identifierNameDotLocation.IsValid();
AddCompletionsForVariablesMatchingSearch(
*variablesContainer,
node.identifierName,
node.identifierNameLocation,
eagerlyCompleteIfPossible);
}
AddCompletionsForVariablesMatchingSearch(*variablesContainer,
node.identifierName,
node.identifierNameLocation);
}
} else if (type == "scenevar") {
const auto* variablesContainer =
projectScopedContainers.GetVariablesContainersList()
.GetBottomMostVariablesContainer();
if (variablesContainer) {
AddCompletionsForVariablesMatchingSearch(*variablesContainer,
node.identifierName,
node.identifierNameLocation);
}
} else if (type == "objectvar") {
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(
platform, objectsContainersList, rootObjectName, node);
platform,
objectsContainersList,
// Variable fields doesn't use expression completion,
// so the object will be found inside the expression itself.
"",
node);
if (IsCaretOn(node.identifierNameDotLocation) ||
IsCaretOn(node.childIdentifierNameLocation)) {
// Complete a potential child variable:
const auto* variablesContainer =
objectsContainersList.GetObjectOrGroupVariablesContainer(
objectName);
if (variablesContainer &&
variablesContainer->Has(node.identifierName)) {
AddCompletionsForChildrenVariablesOf(
&variablesContainer->Get(node.identifierName),
node.childIdentifierNameLocation,
node.childIdentifierName);
}
} else {
// Complete a root variable of the object.
// Don't attempt to complete children variables if there is
// already a dot written (`MyVariable.`).
bool eagerlyCompleteIfPossible =
!node.identifierNameDotLocation.IsValid();
AddCompletionsForObjectOrGroupVariablesMatchingSearch(
objectsContainersList,
objectName,
node.identifierName,
node.identifierNameLocation,
eagerlyCompleteIfPossible);
}
AddCompletionsForObjectOrGroupVariablesMatchingSearch(
objectsContainersList,
objectName,
node.identifierName,
node.identifierNameLocation);
}
} else {
// Object function, behavior name, variable, object variable.
if (IsCaretOn(node.identifierNameLocation)) {
// Don't attempt to complete children variables if there is
// already a dot written (`MyVariable.`).
bool eagerlyCompleteIfPossible =
!node.identifierNameDotLocation.IsValid();
// Is this the proper position?
AddCompletionsForAllIdentifiersMatchingSearch(
node.identifierName,
type,
node.identifierNameLocation,
eagerlyCompleteIfPossible);
node.identifierName, type, node.identifierNameLocation);
if (!node.identifierNameDotLocation.IsValid()) {
completions.push_back(
ExpressionCompletionDescription::ForExpressionWithPrefix(
@@ -634,57 +586,27 @@ class GD_CORE_API ExpressionCompletionFinder
}
} else if (IsCaretOn(node.identifierNameDotLocation) ||
IsCaretOn(node.childIdentifierNameLocation)) {
// Might be:
// - An object variable, object behavior or object expression.
// - Or a variable with a child.
projectScopedContainers.MatchIdentifierWithName<void>(
node.identifierName,
[&]() {
// This is an object.
const gd::String& objectName = node.identifierName;
AddCompletionsForObjectOrGroupVariablesMatchingSearch(
objectsContainersList,
objectName,
node.childIdentifierName,
node.childIdentifierNameLocation,
true);
const gd::String& objectName = node.identifierName;
completions.push_back(
ExpressionCompletionDescription::ForBehaviorWithPrefix(
node.childIdentifierName,
node.childIdentifierNameLocation.GetStartPosition(),
node.childIdentifierNameLocation.GetEndPosition(),
objectName));
completions.push_back(
ExpressionCompletionDescription::ForExpressionWithPrefix(
type,
node.childIdentifierName,
node.childIdentifierNameLocation.GetStartPosition(),
node.childIdentifierNameLocation.GetEndPosition(),
objectName));
},
[&]() {
// This is a variable.
VariableAndItsParent variableAndItsParent =
gd::ExpressionVariableParentFinder::GetLastParentOfNode(
platform, projectScopedContainers, node);
AddCompletionsForChildrenVariablesOf(
variableAndItsParent,
node.childIdentifierNameLocation,
node.childIdentifierName);
},
[&]() {
// Ignore properties here.
// There is no support for "children" of properties.
},
[&]() {
// Ignore parameters here.
// There is no support for "children" of parameters.
},
[&]() {
// Ignore unrecognised identifiers here.
});
// Might be an object variable, object behavior or object expression:
AddCompletionsForObjectOrGroupVariablesMatchingSearch(
objectsContainersList,
objectName,
node.childIdentifierName,
node.childIdentifierNameLocation);
completions.push_back(
ExpressionCompletionDescription::ForBehaviorWithPrefix(
node.childIdentifierName,
node.childIdentifierNameLocation.GetStartPosition(),
node.childIdentifierNameLocation.GetEndPosition(),
objectName));
completions.push_back(
ExpressionCompletionDescription::ForExpressionWithPrefix(
type,
node.childIdentifierName,
node.childIdentifierNameLocation.GetStartPosition(),
node.childIdentifierNameLocation.GetEndPosition(),
objectName));
}
}
}
@@ -814,8 +736,7 @@ class GD_CORE_API ExpressionCompletionFinder
auto type = gd::ExpressionTypeFinder::GetType(
platform, projectScopedContainers, rootType, node);
AddCompletionsForAllIdentifiersMatchingSearch(
node.text, type, node.location);
AddCompletionsForAllIdentifiersMatchingSearch(node.text, type, node.location);
completions.push_back(
ExpressionCompletionDescription::ForExpressionWithPrefix(
type,
@@ -834,96 +755,10 @@ class GD_CORE_API ExpressionCompletionFinder
(inclusive && searchedPosition <= location.GetEndPosition())));
}
/**
* A slightly less strict check than `gd::Project::IsNameSafe` as child
* variables can be completed even if they start with a number.
*/
bool IsIdentifierSafe(const gd::String& name) {
if (name.empty()) return false;
for (auto character : name) {
if (!GrammarTerminals::IsAllowedInIdentifier(character)) {
return false;
}
}
return true;
}
void AddCompletionsForChildrenVariablesOf(
VariableAndItsParent variableAndItsParent,
const ExpressionParserLocation& location,
gd::String eagerlyCompleteForVariableName = "") {
if (variableAndItsParent.parentVariable) {
AddCompletionsForChildrenVariablesOf(variableAndItsParent.parentVariable,
location,
eagerlyCompleteForVariableName);
} else if (variableAndItsParent.parentVariablesContainer) {
AddCompletionsForVariablesMatchingSearch(
*variableAndItsParent.parentVariablesContainer, "", location);
}
}
void AddCompletionsForChildrenVariablesOf(
const gd::Variable* variable,
const ExpressionParserLocation& location,
gd::String eagerlyCompleteForVariableName = "") {
if (!variable) return;
if (variable->GetType() == gd::Variable::Structure) {
for (const auto& name : variable->GetAllChildrenNames()) {
if (!IsIdentifierSafe(name)) continue;
const auto& childVariable = variable->GetChild(name);
ExpressionCompletionDescription description(
ExpressionCompletionDescription::Variable,
location.GetStartPosition(),
location.GetEndPosition());
description.SetCompletion(name);
description.SetVariableType(childVariable.GetType());
completions.push_back(description);
if (name == eagerlyCompleteForVariableName) {
AddEagerCompletionForVariableChildren(childVariable, name, location);
}
}
} else {
// TODO: we could do a "comment only completion" to indicate that nothing
// can/should be completed?
}
}
void AddEagerCompletionForVariableChildren(
const gd::Variable& variable,
const gd::String& variableName,
const ExpressionParserLocation& location) {
if (variable.GetType() == gd::Variable::Structure) {
gd::String prefix = variableName + ".";
for (const auto& name : variable.GetAllChildrenNames()) {
gd::String completion =
IsIdentifierSafe(name)
? (prefix + name)
: (variableName + "[" +
gd::ExpressionParser2NodePrinter::PrintStringLiteral(name) +
"]");
const auto& childVariable = variable.GetChild(name);
ExpressionCompletionDescription description(
ExpressionCompletionDescription::Variable,
location.GetStartPosition(),
location.GetEndPosition());
description.SetCompletion(completion);
description.SetVariableType(childVariable.GetType());
completions.push_back(description);
}
}
}
void AddCompletionsForVariablesMatchingSearch(
const gd::VariablesContainer& variablesContainer,
const gd::String& search,
const ExpressionParserLocation& location,
bool eagerlyCompleteIfExactMatch = false) {
const ExpressionParserLocation& location) {
variablesContainer.ForEachVariableMatchingSearch(
search,
[&](const gd::String& variableName, const gd::Variable& variable) {
@@ -934,11 +769,6 @@ class GD_CORE_API ExpressionCompletionFinder
description.SetCompletion(variableName);
description.SetVariableType(variable.GetType());
completions.push_back(description);
if (eagerlyCompleteIfExactMatch && variableName == search) {
AddEagerCompletionForVariableChildren(
variable, variableName, location);
}
});
}
@@ -946,8 +776,7 @@ class GD_CORE_API ExpressionCompletionFinder
const gd::ObjectsContainersList& objectsContainersList,
const gd::String& objectOrGroupName,
const gd::String& search,
const ExpressionParserLocation& location,
bool eagerlyCompleteIfExactMatch) {
const ExpressionParserLocation& location) {
objectsContainersList.ForEachObjectOrGroupVariableMatchingSearch(
objectOrGroupName,
search,
@@ -959,11 +788,6 @@ class GD_CORE_API ExpressionCompletionFinder
description.SetCompletion(variableName);
description.SetVariableType(variable.GetType());
completions.push_back(description);
if (eagerlyCompleteIfExactMatch && variableName == search) {
AddEagerCompletionForVariableChildren(
variable, variableName, location);
}
});
}
@@ -971,27 +795,25 @@ class GD_CORE_API ExpressionCompletionFinder
const gd::String& search,
const gd::String& type,
const ExpressionParserLocation& location) {
projectScopedContainers.GetObjectsContainersList()
.ForEachNameMatchingSearch(
search,
[&](const gd::String& name,
const gd::ObjectConfiguration* objectConfiguration) {
ExpressionCompletionDescription description(
ExpressionCompletionDescription::Object,
location.GetStartPosition(),
location.GetEndPosition());
description.SetObjectConfiguration(objectConfiguration);
description.SetCompletion(name);
description.SetType(type);
completions.push_back(description);
});
projectScopedContainers.GetObjectsContainersList().ForEachNameMatchingSearch(
search,
[&](const gd::String& name,
const gd::ObjectConfiguration* objectConfiguration) {
ExpressionCompletionDescription description(
ExpressionCompletionDescription::Object,
location.GetStartPosition(),
location.GetEndPosition());
description.SetObjectConfiguration(objectConfiguration);
description.SetCompletion(name);
description.SetType(type);
completions.push_back(description);
});
}
void AddCompletionsForObjectsAndVariablesMatchingSearch(
const gd::String& search,
const gd::String& type,
const ExpressionParserLocation& location,
bool eagerlyCompleteIfExactMatch) {
const ExpressionParserLocation& location) {
projectScopedContainers.ForEachIdentifierMatchingSearch(
search,
[&](const gd::String& objectName,
@@ -1013,11 +835,6 @@ class GD_CORE_API ExpressionCompletionFinder
description.SetCompletion(variableName);
description.SetVariableType(variable.GetType());
completions.push_back(description);
if (eagerlyCompleteIfExactMatch && variableName == search) {
AddEagerCompletionForVariableChildren(
variable, variableName, location);
}
},
[&](const gd::NamedPropertyDescriptor& property) {
// Ignore properties here.
@@ -1028,7 +845,7 @@ class GD_CORE_API ExpressionCompletionFinder
}
void AddCompletionsForAllIdentifiersMatchingSearch(const gd::String& search,
const gd::String& type) {
const gd::String& type) {
AddCompletionsForAllIdentifiersMatchingSearch(
search,
type,
@@ -1038,8 +855,7 @@ class GD_CORE_API ExpressionCompletionFinder
void AddCompletionsForAllIdentifiersMatchingSearch(
const gd::String& search,
const gd::String& type,
const ExpressionParserLocation& location,
bool eagerlyCompleteIfExactMatch = false) {
const ExpressionParserLocation& location) {
projectScopedContainers.ForEachIdentifierMatchingSearch(
search,
[&](const gd::String& objectName,
@@ -1061,11 +877,6 @@ class GD_CORE_API ExpressionCompletionFinder
description.SetCompletion(variableName);
description.SetVariableType(variable.GetType());
completions.push_back(description);
if (eagerlyCompleteIfExactMatch && variableName == search) {
AddEagerCompletionForVariableChildren(
variable, variableName, location);
}
},
[&](const gd::NamedPropertyDescriptor& property) {
ExpressionCompletionDescription description(
@@ -1093,14 +904,11 @@ class GD_CORE_API ExpressionCompletionFinder
const gd::String& rootType_,
size_t searchedPosition_,
gd::ExpressionNode* maybeParentNodeAtLocation_)
: searchedPosition(searchedPosition_),
maybeParentNodeAtLocation(maybeParentNodeAtLocation_),
platform(platform_),
: platform(platform_),
projectScopedContainers(projectScopedContainers_),
rootType(rootType_),
rootObjectName("") // Always empty, might be changed if variable fields
// in the editor are changed to use completion.
{};
searchedPosition(searchedPosition_),
maybeParentNodeAtLocation(maybeParentNodeAtLocation_){};
std::vector<ExpressionCompletionDescription> completions;
size_t searchedPosition;
@@ -1109,7 +917,6 @@ class GD_CORE_API ExpressionCompletionFinder
const gd::Platform& platform;
const gd::ProjectScopedContainers& projectScopedContainers;
const gd::String rootType;
const gd::String rootObjectName;
};
} // namespace gd

View File

@@ -263,17 +263,11 @@ ExpressionValidator::Type ExpressionValidator::ValidateFunction(
}
if (gd::MetadataProvider::IsBadExpressionMetadata(metadata)) {
if (function.functionName.empty()) {
RaiseError("invalid_function_name",
_("Enter the name of the function to call."),
function.location);
} else {
RaiseError("invalid_function_name",
RaiseError("invalid_function_name",
_("Cannot find an expression with this name: ") +
function.functionName + "\n" +
_("Double check that you've not made any typo in the name."),
function.location);
}
return returnType;
}

View File

@@ -1,374 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#include <memory>
#include <vector>
#include "GDCore/Events/Parsers/ExpressionParser2Node.h"
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/Metadata/ObjectMetadata.h"
#include "GDCore/Extensions/Metadata/ParameterMetadata.h"
#include "GDCore/Project/ProjectScopedContainers.h"
#include "GDCore/Project/Variable.h"
#include "GDCore/Tools/Localization.h"
namespace gd {
class Expression;
class ObjectsContainer;
class Platform;
class ParameterMetadata;
class ExpressionMetadata;
} // namespace gd
namespace gd {
/**
* \brief Contains a variables container or a variable. Useful
* to refer to the parent of a variable (which can be a VariablesContainer
* or another Variable).
*/
struct VariableAndItsParent {
const gd::VariablesContainer* parentVariablesContainer;
const gd::Variable* parentVariable;
};
/**
* \brief Find the last parent (i.e: the variables container) of a node
* representing a variable.
*
* Useful for completions, to know which variables can be entered in a node.
*
* \see gd::ExpressionParser2
*/
class GD_CORE_API ExpressionVariableParentFinder
: public ExpressionParser2NodeWorker {
public:
static VariableAndItsParent GetLastParentOfNode(
const gd::Platform& platform,
const gd::ProjectScopedContainers& projectScopedContainers,
gd::ExpressionNode& node) {
gd::ExpressionVariableParentFinder typeFinder(platform,
projectScopedContainers);
node.Visit(typeFinder);
return typeFinder.variableAndItsParent;
}
virtual ~ExpressionVariableParentFinder(){};
protected:
ExpressionVariableParentFinder(
const gd::Platform& platform_,
const gd::ProjectScopedContainers& projectScopedContainers_)
: platform(platform_),
projectScopedContainers(projectScopedContainers_),
variableNode(nullptr),
thisIsALegacyPrescopedVariable(false),
bailOutBecauseEmptyVariableName(false),
legacyPrescopedVariablesContainer(nullptr),
variableAndItsParent{} {};
void OnVisitSubExpressionNode(SubExpressionNode& node) override {}
void OnVisitOperatorNode(OperatorNode& node) override {}
void OnVisitUnaryOperatorNode(UnaryOperatorNode& node) override {}
void OnVisitNumberNode(NumberNode& node) override {}
void OnVisitTextNode(TextNode& node) override {}
void OnVisitVariableNode(VariableNode& node) override {
if (variableNode != nullptr) {
// This is not possible
return;
}
variableNode = &node;
// Check if the parent is a function call, in which we might be dealing
// with a legacy pre-scoped variable parameter:
if (node.parent) node.parent->Visit(*this);
if (thisIsALegacyPrescopedVariable) {
// The node represents a variable name, and the variables container
// containing it was identified in the FunctionCallNode.
childVariableNames.insert(childVariableNames.begin(), node.name);
if (legacyPrescopedVariablesContainer)
variableAndItsParent = WalkUntilLastParent(
*legacyPrescopedVariablesContainer, childVariableNames);
} else {
// Otherwise, the identifier is to be interpreted as usual:
// it can be an object (on which a variable is accessed),
// or a variable.
projectScopedContainers.MatchIdentifierWithName<void>(
node.name,
[&]() {
// This is an object.
const auto* variablesContainer =
projectScopedContainers.GetObjectsContainersList()
.GetObjectOrGroupVariablesContainer(node.name);
if (variablesContainer)
variableAndItsParent =
WalkUntilLastParent(*variablesContainer, childVariableNames);
},
[&]() {
// This is a variable.
if (projectScopedContainers.GetVariablesContainersList().Has(
node.name)) {
variableAndItsParent = WalkUntilLastParent(
projectScopedContainers.GetVariablesContainersList().Get(
node.name),
childVariableNames);
}
},
[&]() {
// Ignore properties here.
// There is no support for "children" of properties.
},
[&]() {
// Ignore parameters here.
// There is no support for "children" of parameters.
},
[&]() {
// Ignore unrecognised identifiers here.
});
}
}
void OnVisitVariableAccessorNode(VariableAccessorNode& node) override {
if (node.name.empty() && node.child) {
// A variable accessor should always have a name if it has a child (i.e:
// another accessor). While the parser may have generated an empty name,
// flag this so we avoid finding a wrong parent (and so, run the risk of
// giving wrong autocompletions).
bailOutBecauseEmptyVariableName = true;
}
childVariableNames.insert(childVariableNames.begin(), node.name);
if (node.parent) node.parent->Visit(*this);
}
void OnVisitIdentifierNode(IdentifierNode& node) override {
if (variableNode != nullptr) {
// This is not possible
return;
}
// This node is not necessarily a variable node.
// It will be checked when visiting the FunctionCallNode, just after.
variableNode = &node;
// Check if the parent is a function call, in which we might be dealing
// with a legacy pre-scoped variable parameter:
if (node.parent) node.parent->Visit(*this);
if (thisIsALegacyPrescopedVariable) {
// The identifier represents a variable name, and the variables container
// containing it was identified in the FunctionCallNode.
if (!node.childIdentifierName.empty())
childVariableNames.insert(childVariableNames.begin(),
node.childIdentifierName);
childVariableNames.insert(childVariableNames.begin(),
node.identifierName);
if (legacyPrescopedVariablesContainer)
variableAndItsParent = WalkUntilLastParent(
*legacyPrescopedVariablesContainer, childVariableNames);
} else {
// Otherwise, the identifier is to be interpreted as usual:
// it can be an object (on which a variable is accessed),
// or a variable.
projectScopedContainers.MatchIdentifierWithName<void>(
node.identifierName,
[&]() {
// This is an object.
if (!node.childIdentifierName.empty())
childVariableNames.insert(childVariableNames.begin(),
node.childIdentifierName);
const auto* variablesContainer =
projectScopedContainers.GetObjectsContainersList()
.GetObjectOrGroupVariablesContainer(node.identifierName);
if (variablesContainer)
variableAndItsParent =
WalkUntilLastParent(*variablesContainer, childVariableNames);
},
[&]() {
// This is a variable.
if (!node.childIdentifierName.empty())
childVariableNames.insert(childVariableNames.begin(),
node.childIdentifierName);
if (projectScopedContainers.GetVariablesContainersList().Has(
node.identifierName)) {
variableAndItsParent = WalkUntilLastParent(
projectScopedContainers.GetVariablesContainersList().Get(
node.identifierName),
childVariableNames);
}
},
[&]() {
// Ignore properties here.
// There is no support for "children" of properties.
},
[&]() {
// Ignore parameters here.
// There is no support for "children" of properties.
},
[&]() {
// Ignore unrecognised identifiers here.
});
}
}
void OnVisitEmptyNode(EmptyNode& node) override {}
void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode& node) override {}
void OnVisitVariableBracketAccessorNode(
VariableBracketAccessorNode& node) override {
// Add a child with an empty name, which will be interpreted as
// "take the first child/item of the structure/array".
childVariableNames.insert(childVariableNames.begin(), "");
if (node.parent) node.parent->Visit(*this);
}
void OnVisitFunctionCallNode(FunctionCallNode& functionCall) override {
if (variableNode == nullptr) {
return;
}
int parameterIndex = -1;
for (int i = 0; i < functionCall.parameters.size(); i++) {
if (functionCall.parameters.at(i).get() == variableNode) {
parameterIndex = i;
break;
}
}
if (parameterIndex < 0) {
return;
}
const auto& objectsContainersList =
projectScopedContainers.GetObjectsContainersList();
const gd::ParameterMetadata* parameterMetadata =
MetadataProvider::GetFunctionCallParameterMetadata(
platform, objectsContainersList, functionCall, parameterIndex);
if (parameterMetadata == nullptr) return; // Unexpected
// Support for legacy pre-scoped variables:
if (parameterMetadata->GetValueTypeMetadata().IsLegacyPreScopedVariable()) {
if (parameterMetadata->GetType() == "objectvar") {
// Legacy convention where a "objectvar"
// parameter represents a variable of the object represented by the
// previous "object" parameter. The object on which the function is
// called is returned if no previous parameters are objects.
gd::String objectName = functionCall.objectName;
for (int previousIndex = parameterIndex - 1; previousIndex >= 0;
previousIndex--) {
const gd::ParameterMetadata* previousParameterMetadata =
MetadataProvider::GetFunctionCallParameterMetadata(
platform, objectsContainersList, functionCall, previousIndex);
if (previousParameterMetadata != nullptr &&
gd::ParameterMetadata::IsObject(
previousParameterMetadata->GetType())) {
auto previousParameterNode =
functionCall.parameters[previousIndex].get();
IdentifierNode* objectNode =
dynamic_cast<IdentifierNode*>(previousParameterNode);
objectName = objectNode->identifierName;
break;
}
}
legacyPrescopedVariablesContainer =
projectScopedContainers.GetObjectsContainersList()
.GetObjectOrGroupVariablesContainer(objectName);
thisIsALegacyPrescopedVariable = true;
} else if (parameterMetadata->GetType() == "scenevar") {
legacyPrescopedVariablesContainer =
projectScopedContainers.GetVariablesContainersList()
.GetBottomMostVariablesContainer();
thisIsALegacyPrescopedVariable = true;
} else if (parameterMetadata->GetType() == "globalvar") {
legacyPrescopedVariablesContainer =
projectScopedContainers.GetVariablesContainersList()
.GetTopMostVariablesContainer();
thisIsALegacyPrescopedVariable = true;
}
} else {
thisIsALegacyPrescopedVariable = false;
legacyPrescopedVariablesContainer = nullptr;
}
}
private:
VariableAndItsParent WalkUntilLastParent(
const gd::Variable& variable,
const std::vector<gd::String>& childVariableNames,
size_t startIndex = 0) {
if (bailOutBecauseEmptyVariableName)
return {}; // Do not even attempt to find the parent if we had an issue
// when visiting nodes.
const gd::Variable* currentVariable = &variable;
// Walk until size - 1 as we want the last parent.
for (size_t index = startIndex; index + 1 < childVariableNames.size();
++index) {
const gd::String& childName = childVariableNames[index];
if (childName.empty()) {
if (currentVariable->GetChildrenCount() == 0) {
// The array or structure is empty, we can't walk through it - there
// is no "parent".
return {};
}
if (currentVariable->GetType() == gd::Variable::Array) {
currentVariable = &currentVariable->GetAtIndex(0);
} else {
currentVariable =
currentVariable->GetAllChildren().begin()->second.get();
}
} else {
if (!currentVariable->HasChild(childName)) {
// Non existing child - there is no "parent".
return {};
}
currentVariable = &currentVariable->GetChild(childName);
}
}
// Return the last parent of the chain of variables (so not the last
// variable but the one before it).
return {.parentVariable = currentVariable};
}
VariableAndItsParent WalkUntilLastParent(
const gd::VariablesContainer& variablesContainer,
const std::vector<gd::String>& childVariableNames) {
if (bailOutBecauseEmptyVariableName)
return {}; // Do not even attempt to find the parent if we had an issue
// when visiting nodes.
if (childVariableNames.empty())
return {}; // There is no "parent" to the variables container itself.
const gd::String& firstChildName = *childVariableNames.begin();
const gd::Variable* variable = variablesContainer.Has(firstChildName)
? &variablesContainer.Get(firstChildName)
: nullptr;
if (childVariableNames.size() == 1 || !variable)
return {// Only one child: the parent is the variables container itself.
.parentVariablesContainer = &variablesContainer};
return WalkUntilLastParent(*variable, childVariableNames, 1);
}
gd::ExpressionNode* variableNode;
std::vector<gd::String> childVariableNames;
bool thisIsALegacyPrescopedVariable;
bool bailOutBecauseEmptyVariableName;
const gd::VariablesContainer* legacyPrescopedVariablesContainer;
VariableAndItsParent variableAndItsParent;
const gd::Platform& platform;
const gd::ProjectScopedContainers& projectScopedContainers;
};
} // namespace gd

View File

@@ -1,222 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2023 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "ObjectAssetSerializer.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
#include "GDCore/Extensions/Metadata/BehaviorMetadata.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/Platform.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/IDE/Project/AssetResourcePathCleaner.h"
#include "GDCore/IDE/Project/ResourcesInUseHelper.h"
#include "GDCore/IDE/Project/ResourcesRenamer.h"
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/CustomBehavior.h"
#include "GDCore/Project/EventsFunctionsExtension.h"
#include "GDCore/Project/Layout.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Project/PropertyDescriptor.h"
#include "GDCore/Serialization/SerializerElement.h"
#include "GDCore/Tools/Log.h"
namespace gd {
gd::String
ObjectAssetSerializer::GetObjectExtensionName(const gd::Object &object) {
const gd::String &type = object.GetType();
const auto separatorIndex =
type.find(PlatformExtension::GetNamespaceSeparator());
return separatorIndex != std::string::npos ? type.substr(0, separatorIndex)
: "";
}
void ObjectAssetSerializer::SerializeTo(
gd::Project &project, const gd::Object &object,
const gd::String &objectFullName, SerializerElement &element,
std::map<gd::String, gd::String> &resourcesFileNameMap) {
auto cleanObject = object.Clone();
cleanObject->GetVariables().Clear();
cleanObject->GetEffects().Clear();
for (auto &&behaviorName : cleanObject->GetAllBehaviorNames()) {
cleanObject->RemoveBehavior(behaviorName);
}
gd::String extensionName = GetObjectExtensionName(*cleanObject);
std::map<gd::String, gd::String> resourcesNameReverseMap;
gd::ObjectAssetSerializer::RenameObjectResourceFiles(
project, *cleanObject, "", objectFullName, resourcesFileNameMap,
resourcesNameReverseMap);
element.SetAttribute("id", "");
element.SetAttribute("name", "");
element.SetAttribute("license", "");
if (project.HasEventsFunctionsExtensionNamed(extensionName)) {
auto &extension = project.GetEventsFunctionsExtension(extensionName);
element.SetAttribute("description", extension.GetShortDescription());
}
element.SetAttribute("gdevelopVersion", "");
element.SetAttribute("version", "");
element.SetIntAttribute("animationsCount", 1);
element.SetIntAttribute("maxFramesCount", 1);
// TODO Find the right object dimensions.
element.SetIntAttribute("width", 0);
element.SetIntAttribute("height", 0);
SerializerElement &authorsElement = element.AddChild("authors");
authorsElement.ConsiderAsArrayOf("author");
SerializerElement &tagsElement = element.AddChild("tags");
tagsElement.ConsiderAsArrayOf("tag");
SerializerElement &objectAssetsElement = element.AddChild("objectAssets");
objectAssetsElement.ConsiderAsArrayOf("objectAsset");
SerializerElement &objectAssetElement =
objectAssetsElement.AddChild("objectAsset");
cleanObject->SerializeTo(objectAssetElement.AddChild("object"));
SerializerElement &resourcesElement =
objectAssetElement.AddChild("resources");
resourcesElement.ConsiderAsArrayOf("resource");
auto &resourcesManager = project.GetResourcesManager();
gd::ResourcesInUseHelper resourcesInUse(resourcesManager);
cleanObject->GetConfiguration().ExposeResources(resourcesInUse);
for (auto &&newResourceName : resourcesInUse.GetAllResources()) {
if (newResourceName.length() == 0) {
continue;
}
auto &resource = resourcesManager.GetResource(
resourcesNameReverseMap.find(newResourceName) !=
resourcesNameReverseMap.end()
? resourcesNameReverseMap[newResourceName]
: newResourceName);
SerializerElement &resourceElement = resourcesElement.AddChild("resource");
resource.SerializeTo(resourceElement);
// Override name and file because the project and the asset don't use the
// same one.
resourceElement.SetAttribute("kind", resource.GetKind());
resourceElement.SetAttribute("name", newResourceName);
auto &oldFilePath = resource.GetFile();
resourceElement.SetAttribute("file",
resourcesFileNameMap.find(oldFilePath) !=
resourcesFileNameMap.end()
? resourcesFileNameMap[oldFilePath]
: oldFilePath);
}
SerializerElement &requiredExtensionsElement =
objectAssetElement.AddChild("requiredExtensions");
requiredExtensionsElement.ConsiderAsArrayOf("requiredExtension");
if (project.HasEventsFunctionsExtensionNamed(extensionName)) {
SerializerElement &requiredExtensionElement =
requiredExtensionsElement.AddChild("requiredExtension");
requiredExtensionElement.SetAttribute("extensionName", extensionName);
requiredExtensionElement.SetAttribute("extensionVersion", "1.0.0");
}
// TODO This can be removed when the asset script no longer require it.
SerializerElement &customizationElement =
objectAssetElement.AddChild("customization");
customizationElement.ConsiderAsArrayOf("empty");
}
void ObjectAssetSerializer::RenameObjectResourceFiles(
gd::Project &project, gd::Object &object,
const gd::String &destinationDirectory, const gd::String &objectFullName,
std::map<gd::String, gd::String> &resourcesFileNameMap,
std::map<gd::String, gd::String> &resourcesNameReverseMap) {
gd::AssetResourcePathCleaner assetResourcePathCleaner(
project.GetResourcesManager(), resourcesFileNameMap,
resourcesNameReverseMap);
object.GetConfiguration().ExposeResources(assetResourcePathCleaner);
// Use asset store script naming conventions for sprite resource files.
if (object.GetConfiguration().GetType() == "Sprite") {
gd::SpriteObject &spriteConfiguration =
dynamic_cast<gd::SpriteObject &>(object.GetConfiguration());
std::map<gd::String, gd::String> normalizedFileNames;
for (std::size_t animationIndex = 0;
animationIndex < spriteConfiguration.GetAnimationsCount();
animationIndex++) {
auto &animation = spriteConfiguration.GetAnimation(animationIndex);
auto &direction = animation.GetDirection(0);
const gd::String &animationName =
animation.GetName().empty()
? gd::String::From(animationIndex)
: animation.GetName().FindAndReplace("_", " ", true);
// Search frames that share the same resource.
std::map<gd::String, std::vector<int>> frameIndexes;
for (std::size_t frameIndex = 0; frameIndex < direction.GetSpritesCount();
frameIndex++) {
auto &frame = direction.GetSprite(frameIndex);
if (frameIndexes.find(frame.GetImageName()) == frameIndexes.end()) {
std::vector<int> emptyVector;
frameIndexes[frame.GetImageName()] = emptyVector;
}
auto &indexes = frameIndexes[frame.GetImageName()];
indexes.push_back(frameIndex);
}
for (std::size_t frameIndex = 0; frameIndex < direction.GetSpritesCount();
frameIndex++) {
auto &frame = direction.GetSprite(frameIndex);
auto oldName = frame.GetImageName();
if (normalizedFileNames.find(oldName) != normalizedFileNames.end()) {
gd::LogWarning("The resource \"" + oldName +
"\" is shared by several animations.");
continue;
}
gd::String newName = objectFullName;
if (spriteConfiguration.GetAnimationsCount() > 1) {
newName += "_" + animationName;
}
if (direction.GetSpritesCount() > 1) {
newName += "_";
auto &indexes = frameIndexes[frame.GetImageName()];
for (size_t i = 0; i < indexes.size(); i++) {
newName += gd::String::From(indexes.at(i) + 1);
if (i < indexes.size() - 1) {
newName += ";";
}
}
}
gd::String extension = oldName.substr(oldName.find_last_of("."));
newName += extension;
frame.SetImageName(newName);
normalizedFileNames[oldName] = newName;
}
}
for (std::map<gd::String, gd::String>::const_iterator it =
resourcesFileNameMap.begin();
it != resourcesFileNameMap.end(); ++it) {
if (!it->first.empty()) {
gd::String originFile = it->first;
gd::String destinationFile = it->second;
resourcesFileNameMap[originFile] = normalizedFileNames[destinationFile];
}
}
auto clonedResourcesNameReverseMap = resourcesNameReverseMap;
resourcesNameReverseMap.clear();
for (std::map<gd::String, gd::String>::const_iterator it =
clonedResourcesNameReverseMap.begin();
it != clonedResourcesNameReverseMap.end(); ++it) {
if (!it->first.empty()) {
gd::String newResourceName = it->first;
gd::String oldResourceName = it->second;
resourcesNameReverseMap[normalizedFileNames[newResourceName]] =
oldResourceName;
}
}
}
}
} // namespace gd

View File

@@ -1,64 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2023 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#include <map>
#include <vector>
#include "GDCore/String.h"
namespace gd {
class Object;
class ExtensionDependency;
class PropertyDescriptor;
class Project;
class Layout;
class ArbitraryResourceWorker;
class InitialInstance;
class SerializerElement;
class EffectsContainer;
class AbstractFileSystem;
} // namespace gd
namespace gd {
/**
* \brief Serialize objects into an asset for the store.
*
* \ingroup IDE
*/
class GD_CORE_API ObjectAssetSerializer {
public:
/**
* \brief Serialize an object into an asset.
*
* \param project The project that contains the object and its resources.
* It's not actually modified.
* \param object The object to serialize as an asset.
* \param objectFullName The object name with spaces instead of PascalCase.
* \param element The element where the asset is serialize.
* \param resourcesFileNameMap The map from project resource file paths to
* asset resource file paths.
*/
static void
SerializeTo(gd::Project &project, const gd::Object &object,
const gd::String &objectFullName, SerializerElement &element,
std::map<gd::String, gd::String> &resourcesFileNameMap);
~ObjectAssetSerializer(){};
private:
ObjectAssetSerializer(){};
static void RenameObjectResourceFiles(
gd::Project &project, gd::Object &object,
const gd::String &destinationDirectory, const gd::String &objectFullName,
std::map<gd::String, gd::String> &resourcesFileNameMap,
std::map<gd::String, gd::String> &resourcesNameReverseMap);
static gd::String GetObjectExtensionName(const gd::Object &object);
};
} // namespace gd

View File

@@ -52,16 +52,6 @@ void ArbitraryResourceWorker::ExposeModel3D(gd::String& resourceName){
// do.
};
void ArbitraryResourceWorker::ExposeAtlas(gd::String& resourceName){
// Nothing to do by default - each child class can define here the action to
// do.
};
void ArbitraryResourceWorker::ExposeSpine(gd::String& resourceName){
// Nothing to do by default - each child class can define here the action to
// do.
};
void ArbitraryResourceWorker::ExposeVideo(gd::String& videoName){
// Nothing to do by default - each child class can define here the action to
// do.
@@ -73,10 +63,14 @@ void ArbitraryResourceWorker::ExposeBitmapFont(gd::String& bitmapFontName){
};
void ArbitraryResourceWorker::ExposeAudio(gd::String& audioName) {
if (resourcesManager->HasResource(audioName) &&
resourcesManager->GetResource(audioName).GetKind() == "audio") {
// Nothing to do, the audio is a reference to a proper resource.
return;
for (auto resources : GetResources()) {
if (!resources) continue;
if (resources->HasResource(audioName) &&
resources->GetResource(audioName).GetKind() == "audio") {
// Nothing to do, the audio is a reference to a proper resource.
return;
}
}
// For compatibility with older projects (where events were referring to files
@@ -86,10 +80,14 @@ void ArbitraryResourceWorker::ExposeAudio(gd::String& audioName) {
};
void ArbitraryResourceWorker::ExposeFont(gd::String& fontName) {
if (resourcesManager->HasResource(fontName) &&
resourcesManager->GetResource(fontName).GetKind() == "font") {
// Nothing to do, the font is a reference to a proper resource.
return;
for (auto resources : GetResources()) {
if (!resources) continue;
if (resources->HasResource(fontName) &&
resources->GetResource(fontName).GetKind() == "font") {
// Nothing to do, the font is a reference to a proper resource.
return;
}
}
// For compatibility with older projects (where events were referring to files
@@ -98,7 +96,12 @@ void ArbitraryResourceWorker::ExposeFont(gd::String& fontName) {
ExposeFile(fontName);
};
void ArbitraryResourceWorker::ExposeResources() {
void ArbitraryResourceWorker::ExposeResources(
gd::ResourcesManager* resourcesManager) {
if (!resourcesManager) return;
resourcesManagers.push_back(resourcesManager);
std::vector<gd::String> resources = resourcesManager->GetAllResourceNames();
for (std::size_t i = 0; i < resources.size(); i++) {
if (resourcesManager->GetResource(resources[i]).UseFile())
@@ -107,6 +110,9 @@ void ArbitraryResourceWorker::ExposeResources() {
}
void ArbitraryResourceWorker::ExposeEmbeddeds(gd::String& resourceName) {
if (resourcesManagers.empty()) return;
gd::ResourcesManager* resourcesManager = resourcesManagers[0];
gd::Resource& resource = resourcesManager->GetResource(resourceName);
if (!resource.GetMetadata().empty()) {
@@ -130,7 +136,6 @@ void ArbitraryResourceWorker::ExposeEmbeddeds(gd::String& resourceName) {
gd::String potentiallyUpdatedTargetResourceName = targetResourceName;
ExposeResourceWithType(targetResource.GetKind(), potentiallyUpdatedTargetResourceName);
ExposeEmbeddeds(potentiallyUpdatedTargetResourceName);
if (potentiallyUpdatedTargetResourceName != targetResourceName) {
// The resource name was renamed. Also update the mapping.
@@ -171,7 +176,6 @@ void ArbitraryResourceWorker::ExposeResourceWithType(
}
if (resourceType == "tilemap") {
ExposeTilemap(resourceName);
ExposeEmbeddeds(resourceName);
return;
}
if (resourceType == "tileset") {
@@ -180,21 +184,12 @@ void ArbitraryResourceWorker::ExposeResourceWithType(
}
if (resourceType == "json") {
ExposeJson(resourceName);
ExposeEmbeddeds(resourceName);
return;
}
if (resourceType == "video") {
ExposeVideo(resourceName);
return;
}
if (resourceType == "atlas") {
ExposeAtlas(resourceName);
return;
}
if (resourceType == "spine") {
ExposeSpine(resourceName);
return;
}
gd::LogError("Unexpected resource type: " + resourceType + " for: " + resourceName);
return;
}
@@ -248,12 +243,10 @@ bool ResourceWorkerInEventsWorker::DoVisitInstruction(gd::Instruction& instructi
} else if (parameterMetadata.GetType() == "jsonResource") {
gd::String updatedParameterValue = parameterValue;
worker.ExposeJson(updatedParameterValue);
worker.ExposeEmbeddeds(updatedParameterValue);
instruction.SetParameter(parameterIndex, updatedParameterValue);
} else if (parameterMetadata.GetType() == "tilemapResource") {
gd::String updatedParameterValue = parameterValue;
worker.ExposeTilemap(updatedParameterValue);
worker.ExposeEmbeddeds(updatedParameterValue);
instruction.SetParameter(parameterIndex, updatedParameterValue);
} else if (parameterMetadata.GetType() == "tilesetResource") {
gd::String updatedParameterValue = parameterValue;
@@ -263,14 +256,6 @@ bool ResourceWorkerInEventsWorker::DoVisitInstruction(gd::Instruction& instructi
gd::String updatedParameterValue = parameterValue;
worker.ExposeModel3D(updatedParameterValue);
instruction.SetParameter(parameterIndex, updatedParameterValue);
} else if (parameterMetadata.GetType() == "atlasResource") {
gd::String updatedParameterValue = parameterValue;
worker.ExposeAtlas(updatedParameterValue);
instruction.SetParameter(parameterIndex, updatedParameterValue);
} else if (parameterMetadata.GetType() == "spineResource") {
gd::String updatedParameterValue = parameterValue;
worker.ExposeSpine(updatedParameterValue);
instruction.SetParameter(parameterIndex, updatedParameterValue);
}
});

View File

@@ -42,9 +42,8 @@ namespace gd {
* \ingroup IDE
*/
class GD_CORE_API ArbitraryResourceWorker {
public:
ArbitraryResourceWorker(gd::ResourcesManager &resourcesManager_)
: resourcesManager(&resourcesManager_){};
public:
ArbitraryResourceWorker(){};
virtual ~ArbitraryResourceWorker();
/**
@@ -53,7 +52,7 @@ public:
* first to ensure that resources are known so that images, shaders & audio
* can make reference to them.
*/
void ExposeResources();
void ExposeResources(gd::ResourcesManager *resourcesManager);
/**
* \brief Expose a resource from a given type.
@@ -96,16 +95,6 @@ public:
* \brief Expose a 3D model, which is always a reference to a "model3D" resource.
*/
virtual void ExposeModel3D(gd::String &resourceName);
/**
* \brief Expose an atlas, which is always a reference to a "atlas" resource.
*/
virtual void ExposeAtlas(gd::String &resourceName);
/**
* \brief Expose an spine, which is always a reference to a "spine" resource.
*/
virtual void ExposeSpine(gd::String &resourceName);
/**
* \brief Expose a video, which is always a reference to a "video" resource.
@@ -133,8 +122,10 @@ public:
*/
virtual void ExposeEmbeddeds(gd::String &resourceName);
protected:
gd::ResourcesManager * resourcesManager;
protected:
const std::vector<gd::ResourcesManager *> &GetResources() {
return resourcesManagers;
};
private:
/**
@@ -142,6 +133,8 @@ protected:
* exposed as file (see ExposeFile).
*/
void ExposeResource(gd::Resource &resource);
std::vector<gd::ResourcesManager *> resourcesManagers;
};
/**

View File

@@ -1,74 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2023 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "AssetResourcePathCleaner.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Project/ResourcesManager.h"
#include "GDCore/String.h"
namespace gd {
void AssetResourcePathCleaner::ExposeImage(gd::String &imageName) {
ExposeResourceAsFile(imageName);
}
void AssetResourcePathCleaner::ExposeAudio(gd::String &audioName) {
ExposeResourceAsFile(audioName);
}
void AssetResourcePathCleaner::ExposeFont(gd::String &fontName) {
ExposeResourceAsFile(fontName);
}
void AssetResourcePathCleaner::ExposeJson(gd::String &jsonName) {
ExposeResourceAsFile(jsonName);
}
void AssetResourcePathCleaner::ExposeTilemap(gd::String &tilemapName) {
ExposeResourceAsFile(tilemapName);
}
void AssetResourcePathCleaner::ExposeTileset(gd::String &tilesetName) {
ExposeResourceAsFile(tilesetName);
}
void AssetResourcePathCleaner::ExposeVideo(gd::String &videoName) {
ExposeResourceAsFile(videoName);
}
void AssetResourcePathCleaner::ExposeBitmapFont(gd::String &bitmapFontName) {
ExposeResourceAsFile(bitmapFontName);
}
void AssetResourcePathCleaner::ExposeResourceAsFile(gd::String &resourceName) {
auto &resource = resourcesManager->GetResource(resourceName);
gd::String file = resource.GetFile();
ExposeFile(file);
resourcesNameReverseMap[file] = resourceName;
resourceName = file;
}
void AssetResourcePathCleaner::ExposeFile(gd::String &resourceFilePath) {
size_t slashPos = resourceFilePath.find_last_of("/");
size_t antiSlashPos = resourceFilePath.find_last_of("\\");
size_t baseNamePos =
slashPos == String::npos
? antiSlashPos == String::npos ? 0 : (antiSlashPos + 1)
: antiSlashPos == String::npos ? (slashPos + 1)
: slashPos > antiSlashPos ? (slashPos + 1)
: (antiSlashPos + 1);
gd::String baseName =
baseNamePos != 0
? resourceFilePath.substr(baseNamePos, resourceFilePath.length())
: resourceFilePath;
resourcesFileNameMap[resourceFilePath] = baseName;
resourceFilePath = baseName;
}
} // namespace gd

View File

@@ -1,65 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2023 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
#include "GDCore/IDE/Project/ResourcesMergingHelper.h"
#include "GDCore/String.h"
#include <map>
#include <memory>
#include <vector>
namespace gd {
class AbstractFileSystem;
class Project;
} // namespace gd
namespace gd {
/**
* \brief AssetResourcePathCleaner is used when exporting an object as an asset.
* It removes the folder from the path.
*
* \see ArbitraryResourceWorker
*
* \ingroup IDE
*/
class GD_CORE_API AssetResourcePathCleaner : public ArbitraryResourceWorker {
public:
AssetResourcePathCleaner(
gd::ResourcesManager &resourcesManager,
std::map<gd::String, gd::String> &resourcesFileNameMap_,
std::map<gd::String, gd::String> &resourcesNameReverseMap_)
: ArbitraryResourceWorker(resourcesManager),
resourcesFileNameMap(resourcesFileNameMap_),
resourcesNameReverseMap(resourcesNameReverseMap_){};
virtual ~AssetResourcePathCleaner(){};
void ExposeImage(gd::String &imageName) override;
void ExposeAudio(gd::String &audioName) override;
void ExposeFont(gd::String &fontName) override;
void ExposeJson(gd::String &jsonName) override;
void ExposeTilemap(gd::String &tilemapName) override;
void ExposeTileset(gd::String &tilesetName) override;
void ExposeVideo(gd::String &videoName) override;
void ExposeBitmapFont(gd::String &bitmapFontName) override;
void ExposeFile(gd::String &resource) override;
protected:
void ExposeResourceAsFile(gd::String &resourceName);
/**
* New file names that can be accessed by their original name.
*/
std::map<gd::String, gd::String> &resourcesFileNameMap;
/**
* Original resource names that can be accessed by their new name.
*/
std::map<gd::String, gd::String> &resourcesNameReverseMap;
};
} // namespace gd

View File

@@ -6,7 +6,7 @@
namespace gd {
void ObjectsUsingResourceCollector::DoVisitObject(gd::Object& object) {
gd::ResourceNameMatcher resourceNameMatcher(*resourcesManager, resourceName);
gd::ResourceNameMatcher resourceNameMatcher(resourceName);
object.GetConfiguration().ExposeResources(resourceNameMatcher);
if (resourceNameMatcher.AnyResourceMatches()) {

View File

@@ -4,7 +4,8 @@
* reserved. This project is released under the MIT License.
*/
#pragma once
#ifndef ProjectObjectsUsingResourceCollector_H
#define ProjectObjectsUsingResourceCollector_H
#include <vector>
@@ -20,10 +21,9 @@ namespace gd {
class GD_CORE_API ObjectsUsingResourceCollector
: public ArbitraryObjectsWorker {
public:
ObjectsUsingResourceCollector(gd::ResourcesManager &resourcesManager_,
const gd::String &resourceName_)
: resourcesManager(&resourcesManager_), resourceName(resourceName_){};
public:
ObjectsUsingResourceCollector(const gd::String& resourceName_)
: resourceName(resourceName_){};
virtual ~ObjectsUsingResourceCollector();
std::vector<gd::String>& GetObjectNames() { return objectNames; }
@@ -33,16 +33,12 @@ public:
std::vector<gd::String> objectNames;
gd::String resourceName;
gd::ResourcesManager *resourcesManager;
};
class GD_CORE_API ResourceNameMatcher : public ArbitraryResourceWorker {
public:
ResourceNameMatcher(gd::ResourcesManager &resourcesManager,
const gd::String &resourceName_)
: resourceName(resourceName_),
matchesResourceName(false), gd::ArbitraryResourceWorker(
resourcesManager){};
public:
ResourceNameMatcher(const gd::String& resourceName_)
: resourceName(resourceName_), matchesResourceName(false){};
virtual ~ResourceNameMatcher(){};
bool AnyResourceMatches() { return matchesResourceName; }
@@ -79,12 +75,6 @@ public:
virtual void ExposeModel3D(gd::String& otherResourceName) override {
MatchResourceName(otherResourceName);
};
virtual void ExposeAtlas(gd::String& otherResourceName) override {
MatchResourceName(otherResourceName);
};
virtual void ExposeSpine(gd::String& otherResourceName) override {
MatchResourceName(otherResourceName);
};
void MatchResourceName(gd::String& otherResourceName) {
if (otherResourceName == resourceName) matchesResourceName = true;
@@ -95,3 +85,5 @@ public:
};
}; // namespace gd
#endif // ProjectObjectsUsingResourceCollector_H

View File

@@ -18,9 +18,8 @@ namespace gd {
std::vector<gd::String> ProjectResourcesAdder::GetAllUseless(
gd::Project& project, const gd::String& resourceType) {
std::vector<gd::String> unusedResources;
// Search for resources used in the project
gd::ResourcesInUseHelper resourcesInUse(project.GetResourcesManager());
gd::ResourcesInUseHelper resourcesInUse;
gd::ResourceExposer::ExposeWholeProjectResources(project, resourcesInUse);
std::set<gd::String>& usedResources = resourcesInUse.GetAll(resourceType);

View File

@@ -25,29 +25,8 @@ bool ProjectResourcesCopier::CopyAllResourcesTo(
bool updateOriginalProject,
bool preserveAbsoluteFilenames,
bool preserveDirectoryStructure) {
if (updateOriginalProject) {
gd::ProjectResourcesCopier::CopyAllResourcesTo(
originalProject, originalProject, fs, destinationDirectory,
preserveAbsoluteFilenames, preserveDirectoryStructure);
} else {
gd::Project clonedProject = originalProject;
gd::ProjectResourcesCopier::CopyAllResourcesTo(
originalProject, clonedProject, fs, destinationDirectory,
preserveAbsoluteFilenames, preserveDirectoryStructure);
}
return true;
}
bool ProjectResourcesCopier::CopyAllResourcesTo(
gd::Project& originalProject,
gd::Project& clonedProject,
AbstractFileSystem& fs,
gd::String destinationDirectory,
bool preserveAbsoluteFilenames,
bool preserveDirectoryStructure) {
// Check if there are some resources with absolute filenames
gd::ResourcesAbsolutePathChecker absolutePathChecker(originalProject.GetResourcesManager(), fs);
gd::ResourcesAbsolutePathChecker absolutePathChecker(fs);
gd::ResourceExposer::ExposeWholeProjectResources(originalProject, absolutePathChecker);
auto projectDirectory = fs.DirNameFrom(originalProject.GetProjectFile());
@@ -55,14 +34,19 @@ bool ProjectResourcesCopier::CopyAllResourcesTo(
<< destinationDirectory << "..." << std::endl;
// Get the resources to be copied
gd::ResourcesMergingHelper resourcesMergingHelper(
clonedProject.GetResourcesManager(), fs);
gd::ResourcesMergingHelper resourcesMergingHelper(fs);
resourcesMergingHelper.SetBaseDirectory(projectDirectory);
resourcesMergingHelper.PreserveDirectoriesStructure(
preserveDirectoryStructure);
resourcesMergingHelper.PreserveAbsoluteFilenames(preserveAbsoluteFilenames);
gd::ResourceExposer::ExposeWholeProjectResources(clonedProject,
resourcesMergingHelper);
resourcesMergingHelper.PreserveAbsoluteFilenames(
preserveAbsoluteFilenames);
if (updateOriginalProject) {
gd::ResourceExposer::ExposeWholeProjectResources(originalProject, resourcesMergingHelper);
} else {
std::shared_ptr<gd::Project> project(new gd::Project(originalProject));
gd::ResourceExposer::ExposeWholeProjectResources(*project, resourcesMergingHelper);
}
// Copy resources
map<gd::String, gd::String>& resourcesNewFilename =

View File

@@ -3,10 +3,9 @@
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#ifndef PROJECTRESOURCESCOPIER_H
#define PROJECTRESOURCESCOPIER_H
#include "GDCore/String.h"
namespace gd {
class Project;
class AbstractFileSystem;
@@ -48,14 +47,8 @@ class GD_CORE_API ProjectResourcesCopier {
bool updateOriginalProject,
bool preserveAbsoluteFilenames = true,
bool preserveDirectoryStructure = true);
private:
static bool CopyAllResourcesTo(gd::Project& originalProject,
gd::Project& clonedProject,
gd::AbstractFileSystem& fs,
gd::String destinationDirectory,
bool preserveAbsoluteFilenames = true,
bool preserveDirectoryStructure = true);
};
} // namespace gd
#endif // PROJECTRESOURCESCOPIER_H

View File

@@ -3,7 +3,8 @@
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#ifndef RESOURCESABSOLUTEPATHCHECKER_H
#define RESOURCESABSOLUTEPATHCHECKER_H
#include "GDCore/IDE/AbstractFileSystem.h"
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
@@ -21,10 +22,10 @@ namespace gd {
*/
class GD_CORE_API ResourcesAbsolutePathChecker
: public ArbitraryResourceWorker {
public:
ResourcesAbsolutePathChecker(gd::ResourcesManager &resourcesManager,
AbstractFileSystem &fileSystem)
: ArbitraryResourceWorker(resourcesManager), hasAbsoluteFilenames(false),
public:
ResourcesAbsolutePathChecker(AbstractFileSystem& fileSystem)
: ArbitraryResourceWorker(),
hasAbsoluteFilenames(false),
fs(fileSystem){};
virtual ~ResourcesAbsolutePathChecker(){};
@@ -46,3 +47,5 @@ public:
};
} // namespace gd
#endif // RESOURCESABSOLUTEPATHCHECKER_H

View File

@@ -1,25 +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 "ResourcesInUseHelper.h"
namespace gd {
const std::vector<gd::String> ResourcesInUseHelper::resourceTypes = {
"image", "audio", "font", "json", "tilemap",
"tileset", "video", "bitmapFont", "model3D"};
const std::vector<gd::String> &ResourcesInUseHelper::GetAllResources() {
allResources.clear();
for (auto &&resourceType : gd::ResourcesInUseHelper::resourceTypes) {
for (auto &&resourceName : GetAll(resourceType)) {
allResources.push_back(resourceName);
}
}
return allResources;
}
} // namespace gd

View File

@@ -4,7 +4,9 @@
* reserved. This project is released under the MIT License.
*/
#pragma once
#if defined(GD_IDE_ONLY)
#ifndef IMAGESUSEDINVENTORIZER_H
#define IMAGESUSEDINVENTORIZER_H
#include <set>
#include <vector>
@@ -31,12 +33,10 @@ std::set<gd::String> & usedImages = resourcesInUse.GetAllImages();
* \ingroup IDE
*/
class ResourcesInUseHelper : public gd::ArbitraryResourceWorker {
public:
ResourcesInUseHelper(gd::ResourcesManager &resourcesManager)
: gd::ArbitraryResourceWorker(resourcesManager){};
public:
ResourcesInUseHelper() : gd::ArbitraryResourceWorker(){};
virtual ~ResourcesInUseHelper(){};
const std::vector<gd::String>& GetAllResources();
std::set<gd::String>& GetAllImages() { return GetAll("image"); };
std::set<gd::String>& GetAllAudios() { return GetAll("audio"); };
std::set<gd::String>& GetAllFonts() { return GetAll("font"); };
@@ -46,8 +46,6 @@ public:
std::set<gd::String>& GetAllVideos() { return GetAll("video"); };
std::set<gd::String>& GetAllBitmapFonts() { return GetAll("bitmapFont"); };
std::set<gd::String>& GetAll3DModels() { return GetAll("model3D"); };
std::set<gd::String>& GetAllAtlases() { return GetAll("atlas"); };
std::set<gd::String>& GetAllSpines() { return GetAll("spine"); };
std::set<gd::String>& GetAll(const gd::String& resourceType) {
if (resourceType == "image") return allImages;
if (resourceType == "audio") return allAudios;
@@ -58,8 +56,6 @@ public:
if (resourceType == "video") return allVideos;
if (resourceType == "bitmapFont") return allBitmapFonts;
if (resourceType == "model3D") return allModel3Ds;
if (resourceType == "atlas") return allAtlases;
if (resourceType == "spine") return allSpines;
return emptyResources;
};
@@ -67,42 +63,35 @@ public:
virtual void ExposeFile(gd::String& resource) override{
/*Don't care, we just list resource names*/
};
virtual void ExposeImage(gd::String& resourceName) override {
allImages.insert(resourceName);
virtual void ExposeImage(gd::String& imageResourceName) override {
allImages.insert(imageResourceName);
};
virtual void ExposeAudio(gd::String& resourceName) override {
allAudios.insert(resourceName);
virtual void ExposeAudio(gd::String& audioResourceName) override {
allAudios.insert(audioResourceName);
};
virtual void ExposeFont(gd::String& resourceName) override {
allFonts.insert(resourceName);
virtual void ExposeFont(gd::String& fontResourceName) override {
allFonts.insert(fontResourceName);
};
virtual void ExposeJson(gd::String& resourceName) override {
allJsons.insert(resourceName);
virtual void ExposeJson(gd::String& jsonResourceName) override {
allJsons.insert(jsonResourceName);
};
virtual void ExposeTilemap(gd::String& resourceName) override {
allTilemaps.insert(resourceName);
virtual void ExposeTilemap(gd::String& tilemapResourceName) override {
allTilemaps.insert(tilemapResourceName);
};
virtual void ExposeTileset(gd::String& resourceName) override {
allTilesets.insert(resourceName);
virtual void ExposeTileset(gd::String& tilesetResourceName) override {
allTilesets.insert(tilesetResourceName);
};
virtual void ExposeVideo(gd::String& resourceName) override {
allVideos.insert(resourceName);
virtual void ExposeVideo(gd::String& videoResourceName) override {
allVideos.insert(videoResourceName);
};
virtual void ExposeBitmapFont(gd::String& resourceName) override {
allBitmapFonts.insert(resourceName);
virtual void ExposeBitmapFont(gd::String& bitmapFontResourceName) override {
allBitmapFonts.insert(bitmapFontResourceName);
};
virtual void ExposeModel3D(gd::String& resourceName) override {
allModel3Ds.insert(resourceName);
};
virtual void ExposeAtlas(gd::String& resourceName) override {
allAtlases.insert(resourceName);
};
virtual void ExposeSpine(gd::String& resourceName) override {
allSpines.insert(resourceName);
};
protected:
std::vector<gd::String> allResources;
std::set<gd::String> allImages;
std::set<gd::String> allAudios;
std::set<gd::String> allFonts;
@@ -112,11 +101,10 @@ public:
std::set<gd::String> allVideos;
std::set<gd::String> allBitmapFonts;
std::set<gd::String> allModel3Ds;
std::set<gd::String> allAtlases;
std::set<gd::String> allSpines;
std::set<gd::String> emptyResources;
static const std::vector<gd::String> resourceTypes;
};
} // namespace gd
#endif // IMAGESUSEDINVENTORIZER_H
#endif

View File

@@ -28,7 +28,7 @@ void ResourcesMergingHelper::ExposeFile(gd::String& resourceFilename) {
auto stripToFilenameOnly = [&]() {
fs.MakeAbsolute(resourceFullFilename, baseDirectory);
SetNewFilename(resourceFullFilename, fs.FileNameFrom(resourceFullFilename));
resourceFilename = newFilenames[resourceFullFilename];
resourceFilename = oldFilenames[resourceFullFilename];
};
// if we do not want to preserve the folders at all,
@@ -45,7 +45,7 @@ void ResourcesMergingHelper::ExposeFile(gd::String& resourceFilename) {
gd::String relativeFilename = resourceFullFilename;
if (fs.MakeRelative(relativeFilename, baseDirectory)) {
SetNewFilename(resourceFullFilename, relativeFilename);
resourceFilename = newFilenames[resourceFullFilename];
resourceFilename = oldFilenames[resourceFullFilename];
} else {
// The filename cannot be made relative. Consider that it is absolute.
// Just strip the filename to its file part
@@ -63,7 +63,7 @@ void ResourcesMergingHelper::ExposeFile(gd::String& resourceFilename) {
void ResourcesMergingHelper::SetNewFilename(gd::String oldFilename,
gd::String newFilename) {
if (newFilenames.find(oldFilename) != newFilenames.end()) return;
if (oldFilenames.find(oldFilename) != oldFilenames.end()) return;
// Extract baseName and extension from the new filename
size_t extensionPos = newFilename.find_last_of(".");
@@ -80,13 +80,13 @@ void ResourcesMergingHelper::SetNewFilename(gd::String oldFilename,
gd::NewNameGenerator::Generate(
baseName,
[this, extension](const gd::String& newBaseName) {
return oldFilenames.find(newBaseName + extension) !=
oldFilenames.end();
return newFilenames.find(newBaseName + extension) !=
newFilenames.end();
}) +
extension;
newFilenames[oldFilename] = finalFilename;
oldFilenames[finalFilename] = oldFilename;
oldFilenames[oldFilename] = finalFilename;
newFilenames[finalFilename] = oldFilename;
}
void ResourcesMergingHelper::SetBaseDirectory(

View File

@@ -28,11 +28,11 @@ namespace gd {
* \ingroup IDE
*/
class GD_CORE_API ResourcesMergingHelper : public ArbitraryResourceWorker {
public:
ResourcesMergingHelper(gd::ResourcesManager &resourcesManager,
gd::AbstractFileSystem &fileSystem)
: ArbitraryResourceWorker(resourcesManager),
preserveDirectoriesStructure(false), preserveAbsoluteFilenames(false),
public:
ResourcesMergingHelper(gd::AbstractFileSystem& fileSystem)
: ArbitraryResourceWorker(),
preserveDirectoriesStructure(false),
preserveAbsoluteFilenames(false),
fs(fileSystem){};
virtual ~ResourcesMergingHelper(){};
@@ -64,25 +64,19 @@ public:
* the Base Directory.
*/
std::map<gd::String, gd::String>& GetAllResourcesOldAndNewFilename() {
return newFilenames;
return oldFilenames;
};
/**
* Resources merging helper collects all resources filenames and update these
* filenames.
*/
void ExposeFile(gd::String& resource) override;
virtual void ExposeFile(gd::String& resource) override;
protected:
void SetNewFilename(gd::String oldFilename, gd::String newFilename);
/**
* Original file names that can be accessed by their new name.
*/
std::map<gd::String, gd::String> oldFilenames;
/**
* New file names that can be accessed by their original name.
*/
std::map<gd::String, gd::String> newFilenames;
gd::String baseDirectory;
bool preserveDirectoriesStructure; ///< If set to true, the directory

View File

@@ -22,16 +22,13 @@ namespace gd {
*/
class ResourcesRenamer : public gd::ArbitraryResourceWorker {
public:
/**
* @brief Constructor taking the map from old name to new name.
* @param oldToNewNames_ A map associating to a resource name the new name to
* use.
*/
ResourcesRenamer(gd::ResourcesManager &resourcesManager,
const std::map<gd::String, gd::String> &oldToNewNames_)
: gd::ArbitraryResourceWorker(resourcesManager),
oldToNewNames(oldToNewNames_){};
/**
* @brief Constructor taking the map from old name to new name.
* @param oldToNewNames_ A map associating to a resource name the new name to
* use.
*/
ResourcesRenamer(const std::map<gd::String, gd::String>& oldToNewNames_)
: gd::ArbitraryResourceWorker(), oldToNewNames(oldToNewNames_){};
virtual ~ResourcesRenamer(){};
virtual void ExposeFile(gd::String& resourceFileName) override{
@@ -65,12 +62,6 @@ class ResourcesRenamer : public gd::ArbitraryResourceWorker {
virtual void ExposeModel3D(gd::String& resourceName) override {
RenameIfNeeded(resourceName);
};
virtual void ExposeAtlas(gd::String& resourceName) override {
RenameIfNeeded(resourceName);
};
virtual void ExposeSpine(gd::String& resourceName) override {
RenameIfNeeded(resourceName);
};
private:
void RenameIfNeeded(gd::String& resourceName) {

View File

@@ -13,16 +13,14 @@
namespace gd {
std::set<gd::String> SceneResourcesFinder::FindProjectResources(gd::Project &project) {
gd::SceneResourcesFinder resourceWorker(project.GetResourcesManager());
gd::SceneResourcesFinder resourceWorker;
gd::ResourceExposer::ExposeProjectResources(project, resourceWorker);
return resourceWorker.resourceNames;
}
std::set<gd::String> SceneResourcesFinder::FindSceneResources(gd::Project &project,
gd::Layout &layout) {
gd::SceneResourcesFinder resourceWorker(project.GetResourcesManager());
gd::SceneResourcesFinder resourceWorker;
gd::ResourceExposer::ExposeLayoutResources(project, layout, resourceWorker);
return resourceWorker.resourceNames;
}

View File

@@ -44,8 +44,7 @@ public:
virtual ~SceneResourcesFinder(){};
private:
SceneResourcesFinder(gd::ResourcesManager &resourcesManager)
: gd::ArbitraryResourceWorker(resourcesManager){};
SceneResourcesFinder() : gd::ArbitraryResourceWorker(){};
void AddUsedResource(gd::String &resourceName);
@@ -80,12 +79,6 @@ private:
void ExposeModel3D(gd::String &resourceName) override {
AddUsedResource(resourceName);
};
void ExposeAtlas(gd::String &resourceName) override {
AddUsedResource(resourceName);
};
void ExposeSpine(gd::String &resourceName) override {
AddUsedResource(resourceName);
};
std::set<gd::String> resourceNames;
};

View File

@@ -128,7 +128,11 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
} else {
gd::Instruction action;
action.SetType("SetReturn" + numberOrString);
action.AddParameter(property.GetName());
gd::String receiver = isBehavior ? "Object.Behavior::" : "Object.";
gd::String propertyPrefix =
(isSharedProperties ? "SharedProperty" : "Property");
action.AddParameter(receiver + propertyPrefix + property.GetName() +
"()");
event.GetActions().Insert(action, 0);
}
}
@@ -229,13 +233,15 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
gd::Instruction action;
action.SetType(setterType);
action.AddParameter("Object");
gd::String parameterGetterCall =
"GetArgumentAs" + numberOrString + "(\"Value\")";
if (isBehavior) {
action.AddParameter("Behavior");
action.AddParameter("=");
action.AddParameter("Value");
action.AddParameter(parameterGetterCall);
} else {
action.AddParameter("=");
action.AddParameter("Value");
action.AddParameter(parameterGetterCall);
}
event.GetActions().Insert(action, 0);
}

View File

@@ -33,8 +33,10 @@ void ResourceExposer::ExposeWholeProjectResources(gd::Project& project, gd::Arbi
// traverse the whole project (this time for events) and ExposeProjectEffects
// (this time for effects).
gd::ResourcesManager* resourcesManager = &(project.GetResourcesManager());
// Expose any project resources as files.
worker.ExposeResources();
worker.ExposeResources(resourcesManager);
project.GetPlatformSpecificAssets().ExposeResources(worker);

View File

@@ -16,8 +16,8 @@
#include "GDCore/IDE/Events/BehaviorTypeRenamer.h"
#include "GDCore/IDE/Events/CustomObjectTypeRenamer.h"
#include "GDCore/IDE/Events/EventsBehaviorRenamer.h"
#include "GDCore/IDE/Events/EventsPropertyReplacer.h"
#include "GDCore/IDE/Events/EventsRefactorer.h"
#include "GDCore/IDE/Events/EventsPropertyReplacer.h"
#include "GDCore/IDE/Events/EventsVariableReplacer.h"
#include "GDCore/IDE/Events/ExpressionsParameterMover.h"
#include "GDCore/IDE/Events/ExpressionsRenamer.h"
@@ -138,8 +138,7 @@ void WholeProjectRefactorer::EnsureObjectEventsFunctionsProperParameters(
}
}
VariablesChangeset
WholeProjectRefactorer::ComputeChangesetForVariablesContainer(
VariablesChangeset WholeProjectRefactorer::ComputeChangesetForVariablesContainer(
gd::Project &project,
const gd::SerializerElement &oldSerializedVariablesContainer,
const gd::VariablesContainer &newVariablesContainer) {
@@ -150,9 +149,9 @@ WholeProjectRefactorer::ComputeChangesetForVariablesContainer(
if (oldVariablesContainer.GetPersistentUuid() !=
newVariablesContainer.GetPersistentUuid()) {
gd::LogWarning(_(
"Called ComputeChangesetForVariablesContainer on variables containers "
"that are different - they can't be compared."));
gd::LogWarning(
_("Called ComputeChangesetForVariablesContainer on variables containers "
"that are different - they can't be compared."));
return changeset;
}
@@ -193,11 +192,14 @@ WholeProjectRefactorer::ComputeChangesetForVariablesContainer(
}
void WholeProjectRefactorer::ApplyRefactoringForVariablesContainer(
gd::Project &project, const gd::VariablesContainer &newVariablesContainer,
const gd::VariablesChangeset &changeset) {
gd::Project &project,
const gd::VariablesContainer &newVariablesContainer,
const gd::VariablesChangeset& changeset) {
gd::EventsVariableReplacer eventsVariableReplacer(
project.GetCurrentPlatform(), newVariablesContainer,
changeset.oldToNewVariableNames, changeset.removedVariableNames);
project.GetCurrentPlatform(),
newVariablesContainer,
changeset.oldToNewVariableNames,
changeset.removedVariableNames);
gd::ProjectBrowserHelper::ExposeProjectEvents(project,
eventsVariableReplacer);
}
@@ -741,14 +743,14 @@ void WholeProjectRefactorer::RenameEventsBasedBehaviorProperty(
EventsBasedBehavior::GetPropertyExpressionName(newPropertyName));
gd::ProjectBrowserHelper::ExposeProjectEvents(project, expressionRenamer);
std::unordered_map<gd::String, gd::String> oldToNewPropertyNames = {
{oldPropertyName, newPropertyName}};
std::unordered_map<gd::String, gd::String> oldToNewPropertyNames = {{oldPropertyName, newPropertyName}};
std::unordered_set<gd::String> removedPropertyNames;
gd::EventsPropertyReplacer eventsPropertyReplacer(
project.GetCurrentPlatform(), properties, oldToNewPropertyNames,
removedPropertyNames);
gd::ProjectBrowserHelper::ExposeProjectEvents(project,
eventsPropertyReplacer);
project.GetCurrentPlatform(),
properties,
oldToNewPropertyNames,
removedPropertyNames);
gd::ProjectBrowserHelper::ExposeProjectEvents(project, eventsPropertyReplacer);
gd::InstructionsTypeRenamer actionRenamer = gd::InstructionsTypeRenamer(
project,
@@ -811,14 +813,14 @@ void WholeProjectRefactorer::RenameEventsBasedBehaviorSharedProperty(
EventsBasedBehavior::GetSharedPropertyExpressionName(newPropertyName));
gd::ProjectBrowserHelper::ExposeProjectEvents(project, expressionRenamer);
std::unordered_map<gd::String, gd::String> oldToNewPropertyNames = {
{oldPropertyName, newPropertyName}};
std::unordered_map<gd::String, gd::String> oldToNewPropertyNames = {{oldPropertyName, newPropertyName}};
std::unordered_set<gd::String> removedPropertyNames;
gd::EventsPropertyReplacer eventsPropertyReplacer(
project.GetCurrentPlatform(), properties, oldToNewPropertyNames,
removedPropertyNames);
gd::ProjectBrowserHelper::ExposeProjectEvents(project,
eventsPropertyReplacer);
project.GetCurrentPlatform(),
properties,
oldToNewPropertyNames,
removedPropertyNames);
gd::ProjectBrowserHelper::ExposeProjectEvents(project, eventsPropertyReplacer);
gd::InstructionsTypeRenamer actionRenamer = gd::InstructionsTypeRenamer(
project,
@@ -868,14 +870,14 @@ void WholeProjectRefactorer::RenameEventsBasedObjectProperty(
EventsBasedObject::GetPropertyExpressionName(newPropertyName));
gd::ProjectBrowserHelper::ExposeProjectEvents(project, expressionRenamer);
std::unordered_map<gd::String, gd::String> oldToNewPropertyNames = {
{oldPropertyName, newPropertyName}};
std::unordered_map<gd::String, gd::String> oldToNewPropertyNames = {{oldPropertyName, newPropertyName}};
std::unordered_set<gd::String> removedPropertyNames;
gd::EventsPropertyReplacer eventsPropertyReplacer(
project.GetCurrentPlatform(), properties, oldToNewPropertyNames,
removedPropertyNames);
gd::ProjectBrowserHelper::ExposeProjectEvents(project,
eventsPropertyReplacer);
project.GetCurrentPlatform(),
properties,
oldToNewPropertyNames,
removedPropertyNames);
gd::ProjectBrowserHelper::ExposeProjectEvents(project, eventsPropertyReplacer);
gd::InstructionsTypeRenamer actionRenamer = gd::InstructionsTypeRenamer(
project,
@@ -1349,6 +1351,7 @@ void WholeProjectRefactorer::DoRenameBehavior(
gd::Project &project, const gd::String &oldBehaviorType,
const gd::String &newBehaviorType,
const gd::ProjectBrowser &projectBrowser) {
// Rename behavior in required behavior properties
auto requiredBehaviorRenamer =
gd::RequiredBehaviorRenamer(oldBehaviorType, newBehaviorType);
@@ -1375,6 +1378,7 @@ void WholeProjectRefactorer::DoRenameBehavior(
void WholeProjectRefactorer::DoRenameObject(
gd::Project &project, const gd::String &oldObjectType,
const gd::String &newObjectType, const gd::ProjectBrowser &projectBrowser) {
// Rename object type in objects lists.
auto customObjectTypeRenamer =
gd::CustomObjectTypeRenamer(oldObjectType, newObjectType);
@@ -1394,8 +1398,7 @@ void WholeProjectRefactorer::DoRenameObject(
void WholeProjectRefactorer::ObjectOrGroupRemovedInLayout(
gd::Project &project, gd::Layout &layout, const gd::String &objectName,
bool isObjectGroup, bool removeEventsAndGroups) {
auto projectScopedContainers = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForProjectAndLayout(project, layout);
auto projectScopedContainers = gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, layout);
// Remove object in the current layout
if (removeEventsAndGroups) {
@@ -1444,8 +1447,7 @@ void WholeProjectRefactorer::ObjectOrGroupRenamedInLayout(
if (oldName == newName || newName.empty() || oldName.empty())
return;
auto projectScopedContainers = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForProjectAndLayout(project, layout);
auto projectScopedContainers = gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, layout);
// Rename object in the current layout
gd::EventsRefactorer::RenameObjectInEvents(
@@ -1534,19 +1536,10 @@ void WholeProjectRefactorer::RenameLayer(gd::Project &project,
const gd::String &newName) {
if (oldName == newName || newName.empty() || oldName.empty())
return;
gd::ProjectElementRenamer projectElementRenamer(project.GetCurrentPlatform(),
"layer", oldName, newName);
gd::ProjectBrowserHelper::ExposeLayoutEventsAndExternalEvents(
project, layout, projectElementRenamer);
layout.GetInitialInstances().MoveInstancesToLayer(oldName, newName);
std::vector<gd::String> externalLayoutsNames =
GetAssociatedExternalLayouts(project, layout);
for (gd::String name : externalLayoutsNames) {
auto &externalLayout = project.GetExternalLayout(name);
externalLayout.GetInitialInstances().MoveInstancesToLayer(oldName, newName);
}
gd::ProjectBrowserHelper::ExposeLayoutEventsAndExternalEvents(project, layout,
projectElementRenamer);
}
void WholeProjectRefactorer::RenameLayerEffect(gd::Project &project,
@@ -1559,8 +1552,8 @@ void WholeProjectRefactorer::RenameLayerEffect(gd::Project &project,
gd::ProjectElementRenamer projectElementRenamer(
project.GetCurrentPlatform(), "layerEffectName", oldName, newName);
projectElementRenamer.SetLayerConstraint(layer.GetName());
gd::ProjectBrowserHelper::ExposeLayoutEventsAndExternalEvents(
project, layout, projectElementRenamer);
gd::ProjectBrowserHelper::ExposeLayoutEventsAndExternalEvents(project, layout,
projectElementRenamer);
}
void WholeProjectRefactorer::RenameObjectAnimation(gd::Project &project,
@@ -1573,8 +1566,8 @@ void WholeProjectRefactorer::RenameObjectAnimation(gd::Project &project,
gd::ProjectElementRenamer projectElementRenamer(
project.GetCurrentPlatform(), "objectAnimationName", oldName, newName);
projectElementRenamer.SetObjectConstraint(object.GetName());
gd::ProjectBrowserHelper::ExposeLayoutEventsAndExternalEvents(
project, layout, projectElementRenamer);
gd::ProjectBrowserHelper::ExposeLayoutEventsAndExternalEvents(project, layout,
projectElementRenamer);
}
void WholeProjectRefactorer::RenameObjectPoint(gd::Project &project,
@@ -1587,8 +1580,8 @@ void WholeProjectRefactorer::RenameObjectPoint(gd::Project &project,
gd::ProjectElementRenamer projectElementRenamer(
project.GetCurrentPlatform(), "objectPointName", oldName, newName);
projectElementRenamer.SetObjectConstraint(object.GetName());
gd::ProjectBrowserHelper::ExposeLayoutEventsAndExternalEvents(
project, layout, projectElementRenamer);
gd::ProjectBrowserHelper::ExposeLayoutEventsAndExternalEvents(project, layout,
projectElementRenamer);
}
void WholeProjectRefactorer::RenameObjectEffect(gd::Project &project,
@@ -1601,8 +1594,8 @@ void WholeProjectRefactorer::RenameObjectEffect(gd::Project &project,
gd::ProjectElementRenamer projectElementRenamer(
project.GetCurrentPlatform(), "objectEffectName", oldName, newName);
projectElementRenamer.SetObjectConstraint(object.GetName());
gd::ProjectBrowserHelper::ExposeLayoutEventsAndExternalEvents(
project, layout, projectElementRenamer);
gd::ProjectBrowserHelper::ExposeLayoutEventsAndExternalEvents(project, layout,
projectElementRenamer);
}
void WholeProjectRefactorer::ObjectOrGroupRemovedInEventsBasedObject(
@@ -1624,12 +1617,9 @@ void WholeProjectRefactorer::ObjectOrGroupRemovedInEventsFunction(
gd::ObjectsContainer &globalObjectsContainer,
gd::ObjectsContainer &objectsContainer, const gd::String &objectName,
bool isObjectGroup, bool removeEventsAndGroups) {
// In theory we should pass a ProjectScopedContainers to this function so it
// does not have to construct one. In practice, this is ok because we only
// deal with objects.
auto projectScopedContainers =
gd::ProjectScopedContainers::MakeNewProjectScopedContainersFor(
globalObjectsContainer, objectsContainer);
// In theory we should pass a ProjectScopedContainers to this function so it does not have to construct one.
// In practice, this is ok because we only deal with objects.
auto projectScopedContainers = gd::ProjectScopedContainers::MakeNewProjectScopedContainersFor(globalObjectsContainer, objectsContainer);
if (removeEventsAndGroups) {
gd::EventsRefactorer::RemoveObjectInEvents(
@@ -1665,12 +1655,9 @@ void WholeProjectRefactorer::ObjectOrGroupRenamedInEventsFunction(
gd::ObjectsContainer &globalObjectsContainer,
gd::ObjectsContainer &objectsContainer, const gd::String &oldName,
const gd::String &newName, bool isObjectGroup) {
// In theory we should pass a ProjectScopedContainers to this function so it
// does not have to construct one. In practice, this is ok because we only
// deal with objects.
auto projectScopedContainers =
gd::ProjectScopedContainers::MakeNewProjectScopedContainersFor(
globalObjectsContainer, objectsContainer);
// In theory we should pass a ProjectScopedContainers to this function so it does not have to construct one.
// In practice, this is ok because we only deal with objects.
auto projectScopedContainers = gd::ProjectScopedContainers::MakeNewProjectScopedContainersFor(globalObjectsContainer, objectsContainer);
gd::EventsRefactorer::RenameObjectInEvents(
project.GetCurrentPlatform(), projectScopedContainers,
@@ -1718,7 +1705,7 @@ void WholeProjectRefactorer::GlobalObjectOrGroupRemoved(
if (layout.HasObjectNamed(objectName))
continue;
ObjectOrGroupRemovedInLayout(project, layout, objectName, isObjectGroup,
ObjectOrGroupRemovedInLayout(project, layout, objectName, isObjectGroup,
removeEventsAndGroups);
}
}
@@ -1766,8 +1753,7 @@ size_t WholeProjectRefactorer::GetLayoutAndExternalLayoutLayerInstancesCount(
GetAssociatedExternalLayouts(project, layout);
for (gd::String name : externalLayoutsNames) {
auto &externalLayout = project.GetExternalLayout(name);
count +=
externalLayout.GetInitialInstances().GetLayerInstancesCount(layerName);
count += externalLayout.GetInitialInstances().GetLayerInstancesCount(layerName);
}
return count;
}

View File

@@ -155,10 +155,6 @@ void CustomObjectConfiguration::ExposeResources(gd::ArbitraryResourceWorker& wor
worker.ExposeBitmapFont(newPropertyValue);
} else if (resourceType == "model3D") {
worker.ExposeModel3D(newPropertyValue);
} else if (resourceType == "atlas") {
worker.ExposeAtlas(newPropertyValue);
} else if (resourceType == "spine") {
worker.ExposeSpine(newPropertyValue);
}
if (newPropertyValue != oldPropertyValue) {

View File

@@ -39,7 +39,6 @@ void Layer::SetCameraCount(std::size_t n) {
void Layer::SerializeTo(SerializerElement& element) const {
element.SetAttribute("name", GetName());
element.SetAttribute("renderingType", GetRenderingType());
element.SetAttribute("cameraType", GetCameraType());
element.SetAttribute("visibility", GetVisibility());
element.SetAttribute("isLocked", IsLocked());
element.SetAttribute("isLightingLayer", IsLightingLayer());
@@ -79,7 +78,6 @@ void Layer::SerializeTo(SerializerElement& element) const {
void Layer::UnserializeFrom(const SerializerElement& element) {
SetName(element.GetStringAttribute("name", "", "Name"));
SetRenderingType(element.GetStringAttribute("renderingType", ""));
SetCameraType(element.GetStringAttribute("cameraType", "perspective"));
SetVisibility(element.GetBoolAttribute("visibility", true, "Visibility"));
SetLocked(element.GetBoolAttribute("isLocked", false));
SetLightingLayer(element.GetBoolAttribute("isLightingLayer", false));

View File

@@ -104,17 +104,10 @@ class GD_CORE_API Layer {
const gd::String& GetName() const { return name; }
const gd::String& GetRenderingType() const { return renderingType; }
void SetRenderingType(const gd::String& renderingType_) {
renderingType = renderingType_;
}
const gd::String& GetCameraType() const { return cameraType; }
void SetCameraType(const gd::String& cameraType_) {
cameraType = cameraType_;
}
/**
* \brief Change if layer is displayed or not
*/
@@ -275,7 +268,6 @@ class GD_CORE_API Layer {
gd::String name; ///< The name of the layer
gd::String renderingType; ///< The rendering type: "" (empty), "2d", "3d" or
///< "2d+3d".
gd::String cameraType;
bool isVisible; ///< True if the layer is visible
bool isLocked; ///< True if the layer is locked
bool isLightingLayer; ///< True if the layer is used to display lights and

View File

@@ -17,7 +17,7 @@ LoadingScreen::LoadingScreen()
backgroundFadeInDuration(0.2),
minDuration(1.5),
logoAndProgressFadeInDuration(0.2),
logoAndProgressLogoFadeInDelay(0),
logoAndProgressLogoFadeInDelay(0.2),
showProgressBar(true),
progressBarMinWidth(40),
progressBarMaxWidth(200),

View File

@@ -113,7 +113,7 @@ bool ObjectsContainersList::HasObjectWithVariableNamed(
return false;
}
bool ObjectsContainersList::HasObjectOrGroupVariablesContainer(
bool ObjectsContainersList::HasVariablesContainer(
const gd::String& objectOrGroupName,
const gd::VariablesContainer& variablesContainer) const {
for (auto it = objectsContainers.rbegin(); it != objectsContainers.rend();
@@ -123,31 +123,8 @@ bool ObjectsContainersList::HasObjectOrGroupVariablesContainer(
&(*it)->GetObject(objectOrGroupName).GetVariables();
}
if ((*it)->GetObjectGroups().Has(objectOrGroupName)) {
// For groups, we consider that the first object of the group defines the
// variables available for this group. Note that this is slightly
// different than other methods where a group is considered as the
// "intersection" of all of its objects.
const auto& objectNames =
(*it)->GetObjectGroups().Get(objectOrGroupName).GetAllObjectsNames();
if (!objectNames.empty()) {
return HasObjectVariablesContainer(objectNames[0], variablesContainer);
}
return false;
}
}
return false;
}
bool ObjectsContainersList::HasObjectVariablesContainer(
const gd::String& objectName,
const gd::VariablesContainer& variablesContainer) const {
for (auto it = objectsContainers.rbegin(); it != objectsContainers.rend();
++it) {
if ((*it)->HasObjectNamed(objectName)) {
return &variablesContainer ==
&(*it)->GetObject(objectName).GetVariables();
// Could be adapted if objects groups have variables in the future.
// This would allow handling the renaming of variables of an object group.
}
}
@@ -163,30 +140,8 @@ ObjectsContainersList::GetObjectOrGroupVariablesContainer(
return &(*it)->GetObject(objectOrGroupName).GetVariables();
}
if ((*it)->GetObjectGroups().Has(objectOrGroupName)) {
// For groups, we consider that the first object of the group defines the
// variables available for this group. Note that this is slightly
// different than other methods where a group is considered as the
// "intersection" of all of its objects.
const auto& objectNames =
(*it)->GetObjectGroups().Get(objectOrGroupName).GetAllObjectsNames();
if (!objectNames.empty()) {
return GetObjectVariablesContainer(objectNames[0]);
}
return nullptr;
}
}
return nullptr;
}
const gd::VariablesContainer*
ObjectsContainersList::GetObjectVariablesContainer(
const gd::String& objectName) const {
for (auto it = objectsContainers.rbegin(); it != objectsContainers.rend();
++it) {
if ((*it)->HasObjectNamed(objectName)) {
return &(*it)->GetObject(objectName).GetVariables();
// Could be adapted if objects groups have variables in the future.
// This would allow handling the renaming of variables of an object group.
}
}
@@ -195,6 +150,7 @@ ObjectsContainersList::GetObjectVariablesContainer(
gd::Variable::Type ObjectsContainersList::GetTypeOfObjectOrGroupVariable(
const gd::String& objectOrGroupName, const gd::String& variableName) const {
for (auto it = objectsContainers.rbegin(); it != objectsContainers.rend();
++it) {
if ((*it)->HasObjectNamed(objectOrGroupName)) {
@@ -226,12 +182,13 @@ gd::Variable::Type ObjectsContainersList::GetTypeOfObjectOrGroupVariable(
return Variable::Type::Number;
}
gd::Variable::Type ObjectsContainersList::GetTypeOfObjectVariable(
const gd::String& objectName, const gd::String& variableName) const {
gd::Variable::Type ObjectsContainersList::GetTypeOfObjectVariable(const gd::String& objectName, const gd::String& variableName) const {
for (auto it = objectsContainers.rbegin(); it != objectsContainers.rend();
++it) {
if ((*it)->HasObjectNamed(objectName)) {
const auto& variables = (*it)->GetObject(objectName).GetVariables();
const auto& variables =
(*it)->GetObject(objectName).GetVariables();
return variables.Get(variableName).GetType();
}

View File

@@ -61,7 +61,7 @@ class GD_CORE_API ObjectsContainersList {
* \brief Check if the specified object or group has the specified variables
* container.
*/
bool HasObjectOrGroupVariablesContainer(
bool HasVariablesContainer(
const gd::String& objectOrGroupName,
const gd::VariablesContainer& variablesContainer) const;
@@ -165,13 +165,6 @@ class GD_CORE_API ObjectsContainersList {
bool HasObjectWithVariableNamed(const gd::String& objectName,
const gd::String& variableName) const;
bool HasObjectVariablesContainer(
const gd::String& objectName,
const gd::VariablesContainer& variablesContainer) const;
const gd::VariablesContainer* GetObjectVariablesContainer(
const gd::String& objectName) const;
gd::Variable::Type GetTypeOfObjectVariable(const gd::String& objectName, const gd::String& variableName) const;
void ForEachObjectVariableMatchingSearch(

View File

@@ -30,9 +30,6 @@ void PropertyDescriptor::SerializeTo(SerializerElement& element) const {
extraInformationElement.AddChild("").SetStringValue(information);
}
element.AddChild("hidden").SetBoolValue(hidden);
if (deprecated) {
element.AddChild("deprecated").SetBoolValue(deprecated);
}
}
void PropertyDescriptor::UnserializeFrom(const SerializerElement& element) {
@@ -61,9 +58,6 @@ void PropertyDescriptor::UnserializeFrom(const SerializerElement& element) {
hidden = element.HasChild("hidden")
? element.GetChild("hidden").GetBoolValue()
: false;
deprecated = element.HasChild("deprecated")
? element.GetChild("deprecated").GetBoolValue()
: false;
}
void PropertyDescriptor::SerializeValuesTo(SerializerElement& element) const {

View File

@@ -30,16 +30,12 @@ class GD_CORE_API PropertyDescriptor {
* \param propertyValue The value of the property.
*/
PropertyDescriptor(gd::String propertyValue)
: currentValue(propertyValue), type("string"), label(""), hidden(false),
deprecated(false),
measurementUnit(gd::MeasurementUnit::GetUndefined()) {}
: currentValue(propertyValue), type("string"), label(""), hidden(false), measurementUnit(gd::MeasurementUnit::GetUndefined()) {}
/**
* \brief Empty constructor creating an empty property to be displayed.
*/
PropertyDescriptor()
: hidden(false), deprecated(false),
measurementUnit(gd::MeasurementUnit::GetUndefined()){};
PropertyDescriptor() : hidden(false), measurementUnit(gd::MeasurementUnit::GetUndefined()) {};
/**
* \brief Destructor
@@ -146,19 +142,6 @@ class GD_CORE_API PropertyDescriptor {
*/
bool IsHidden() const { return hidden; }
/**
* \brief Set if the property is deprecated.
*/
PropertyDescriptor& SetDeprecated(bool enable = true) {
deprecated = enable;
return *this;
}
/**
* \brief Check if the property is deprecated.
*/
bool IsDeprecated() const { return deprecated; }
/** \name Serialization
*/
///@{
@@ -196,7 +179,6 @@ class GD_CORE_API PropertyDescriptor {
///< choices, if a property is a displayed as a combo
///< box.
bool hidden;
bool deprecated;
gd::MeasurementUnit measurementUnit; //< The unit of measurement of the property vale.
};

View File

@@ -93,10 +93,6 @@ std::shared_ptr<Resource> ResourcesManager::CreateResource(
return std::make_shared<BitmapFontResource>();
else if (kind == "model3D")
return std::make_shared<Model3DResource>();
else if (kind == "atlas")
return std::make_shared<AtlasResource>();
else if (kind == "spine")
return std::make_shared<SpineResource>();
std::cout << "Bad resource created (type: " << kind << ")" << std::endl;
return std::make_shared<Resource>();
@@ -760,20 +756,6 @@ void Model3DResource::SerializeTo(SerializerElement& element) const {
element.SetAttribute("file", GetFile());
}
void AtlasResource::SetFile(const gd::String& newFile) {
file = NormalizePathSeparator(newFile);
}
void AtlasResource::UnserializeFrom(const SerializerElement& element) {
SetUserAdded(element.GetBoolAttribute("userAdded"));
SetFile(element.GetStringAttribute("file"));
}
void AtlasResource::SerializeTo(SerializerElement& element) const {
element.SetAttribute("userAdded", IsUserAdded());
element.SetAttribute("file", GetFile());
}
ResourceFolder::ResourceFolder(const ResourceFolder& other) { Init(other); }
ResourceFolder& ResourceFolder::operator=(const ResourceFolder& other) {

View File

@@ -373,21 +373,6 @@ class GD_CORE_API JsonResource : public Resource {
gd::String file;
};
/**
* \brief Describe a spine json file used by a project.
*
* \see Resource
* \ingroup ResourcesManagement
*/
class GD_CORE_API SpineResource : public JsonResource {
public:
SpineResource() : JsonResource() { SetKind("spine"); };
virtual ~SpineResource(){};
virtual SpineResource* Clone() const override {
return new SpineResource(*this);
}
};
/**
* \brief Describe a tilemap file used by a project.
*
@@ -522,32 +507,6 @@ class GD_CORE_API Model3DResource : public Resource {
gd::String file;
};
/**
* \brief Describe an atlas file used by a project.
*
* \see Resource
* \ingroup ResourcesManagement
*/
class GD_CORE_API AtlasResource : public Resource {
public:
AtlasResource() : Resource() { SetKind("atlas"); };
virtual ~AtlasResource(){};
virtual AtlasResource* Clone() const override {
return new AtlasResource(*this);
}
virtual const gd::String& GetFile() const override { return file; };
virtual void SetFile(const gd::String& newFile) override;
virtual bool UseFile() const override { return true; }
void SerializeTo(SerializerElement& element) const override;
void UnserializeFrom(const SerializerElement& element) override;
private:
gd::String file;
};
/**
* \brief Inventory all resources used by a project
*

View File

@@ -403,11 +403,6 @@ String String::LowerCase() const
return lowerCasedStr;
}
String String::CapitalizeFirstLetter() const
{
return size() < 1 ? *this : substr(0, 1).UpperCase() + substr(1);
}
String String::FindAndReplace(String search, String replacement, bool all) const
{
gd::String result(*this);

View File

@@ -522,11 +522,6 @@ public:
*/
String LowerCase() const;
/**
* \brief Returns the string with the first letter in upper case.
*/
String CapitalizeFirstLetter() const;
/**
* \brief Searches a string for a specified substring and returns a new string where all occurrences of this substring is replaced.
* \param search The string that will be replaced by the new string.

View File

@@ -29,9 +29,7 @@
#include "GDCore/Project/ExternalEvents.h"
class ArbitraryResourceWorkerTest : public gd::ArbitraryResourceWorker {
public:
ArbitraryResourceWorkerTest(gd::ResourcesManager &resourcesManager)
: ArbitraryResourceWorker(resourcesManager){};
public:
virtual void ExposeFile(gd::String& file) { files.push_back(file); };
virtual void ExposeImage(gd::String& imageName) {
images.push_back(imageName);
@@ -61,7 +59,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res3", "path/to/file3.png", "image");
project.GetResourcesManager().AddResource(
"res4", "path/to/file4.png", "audio");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
gd::ResourceExposer::ExposeWholeProjectResources(project, worker);
REQUIRE(worker.files.size() == 4);
@@ -83,7 +81,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res3", "path/to/file3.png", "image");
project.GetResourcesManager().AddResource(
"res4", "path/to/file4.png", "audio");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
gd::SpriteObject spriteConfiguration;
gd::Animation anim;
@@ -128,7 +126,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res3", "path/to/file3.png", "image");
project.GetResourcesManager().AddResource(
"res4", "path/to/file4.png", "audio");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
auto& layout = project.InsertNewLayout("Scene", 0);
@@ -163,7 +161,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res3", "path/to/file3.fnt", "bitmapFont");
project.GetResourcesManager().AddResource(
"res4", "path/to/file4.png", "audio");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
auto& layout = project.InsertNewLayout("Scene", 0);
@@ -198,7 +196,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res3", "path/to/file3.fnt", "bitmapFont");
project.GetResourcesManager().AddResource(
"res4", "path/to/file4.png", "audio");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
auto& externalEvents = project.InsertNewExternalEvents("MyExternalEvents", 0);
@@ -234,7 +232,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res2", "path/to/file2.png", "image");
project.GetResourcesManager().AddResource(
"res3", "path/to/file3.png", "image");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
auto& extension = project.InsertNewEventsFunctionsExtension("MyEventExtension", 0);
auto& function = extension.InsertNewEventsFunction("MyFreeFunction", 0);
@@ -271,7 +269,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res2", "path/to/file2.png", "image");
project.GetResourcesManager().AddResource(
"res3", "path/to/file3.png", "image");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
auto& extension = project.InsertNewEventsFunctionsExtension("MyEventExtension", 0);
auto& behavior = extension.GetEventsBasedBehaviors().InsertNew("MyBehavior", 0);
@@ -309,7 +307,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res2", "path/to/file2.png", "image");
project.GetResourcesManager().AddResource(
"res3", "path/to/file3.png", "image");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
auto& extension = project.InsertNewEventsFunctionsExtension("MyEventExtension", 0);
auto& object = extension.GetEventsBasedObjects().InsertNew("MyObject", 0);
@@ -347,7 +345,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res2", "path/to/file2.png", "image");
project.GetResourcesManager().AddResource(
"res3", "path/to/file3.png", "image");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
auto& layout = project.InsertNewLayout("Scene", 0);
layout.InsertNewLayer("MyLayer", 0);
@@ -373,7 +371,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res2", "path/to/file2.png", "image");
project.GetResourcesManager().AddResource(
"res3", "path/to/file3.png", "image");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
auto& layout = project.InsertNewLayout("Scene", 0);
layout.InsertNewLayer("MyLayer", 0);
@@ -404,7 +402,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res3", "path/to/file3.png", "image");
project.GetResourcesManager().AddResource(
"res4", "path/to/file4.png", "audio");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
auto& layout = project.InsertNewLayout("Scene", 0);
@@ -427,7 +425,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res3", "path/to/file3.png", "image");
project.GetResourcesManager().AddResource(
"res4", "path/to/file4.png", "audio");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
auto& layout = project.InsertNewLayout("Scene", 0);
@@ -461,7 +459,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res3", "path/to/file3.fnt", "bitmapFont");
project.GetResourcesManager().AddResource(
"res4", "path/to/file4.png", "audio");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
auto& layout = project.InsertNewLayout("Scene", 0);
@@ -496,7 +494,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res3", "path/to/file3.fnt", "bitmapFont");
project.GetResourcesManager().AddResource(
"res4", "path/to/file4.png", "audio");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
auto& layout = project.InsertNewLayout("MyScene", 0);
auto& externalEvents = project.InsertNewExternalEvents("MyExternalEvents", 0);
@@ -532,7 +530,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res3", "path/to/file3.fnt", "bitmapFont");
project.GetResourcesManager().AddResource(
"res4", "path/to/file4.png", "audio");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
auto& layout = project.InsertNewLayout("MyScene", 0);
auto& externalEvents = project.InsertNewExternalEvents("MyExternalEvents", 0);
@@ -574,7 +572,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res3", "path/to/file3.fnt", "bitmapFont");
project.GetResourcesManager().AddResource(
"res4", "path/to/file4.png", "audio");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
auto& layout = project.InsertNewLayout("Scene", 0);
auto& externalEventsA = project.InsertNewExternalEvents("MyExternalEventsA", 0);
@@ -621,7 +619,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res3", "path/to/file3.fnt", "bitmapFont");
project.GetResourcesManager().AddResource(
"res4", "path/to/file4.png", "audio");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
auto& layout = project.InsertNewLayout("MyScene", 0);
auto& otherLayout = project.InsertNewLayout("MyOtherScene", 0);
@@ -656,7 +654,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res3", "path/to/file3.fnt", "bitmapFont");
project.GetResourcesManager().AddResource(
"res4", "path/to/file4.png", "audio");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
auto& layout = project.InsertNewLayout("MyScene", 0);
auto& otherLayout = project.InsertNewLayout("MyOtherScene", 0);
@@ -698,7 +696,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res3", "path/to/file3.fnt", "bitmapFont");
project.GetResourcesManager().AddResource(
"res4", "path/to/file4.png", "audio");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
auto& layout = project.InsertNewLayout("MyScene", 0);
@@ -742,7 +740,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res2", "path/to/file2.png", "image");
project.GetResourcesManager().AddResource(
"res3", "path/to/file3.png", "image");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
auto& extension = project.InsertNewEventsFunctionsExtension("MyEventExtension", 0);
auto& function = extension.InsertNewEventsFunction("MyFreeFunction", 0);
@@ -782,7 +780,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res2", "path/to/file2.png", "image");
project.GetResourcesManager().AddResource(
"res3", "path/to/file3.png", "image");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
auto& extension = project.InsertNewEventsFunctionsExtension("MyEventExtension", 0);
auto& behavior = extension.GetEventsBasedBehaviors().InsertNew("MyBehavior", 0);
@@ -823,7 +821,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res2", "path/to/file2.png", "image");
project.GetResourcesManager().AddResource(
"res3", "path/to/file3.png", "image");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
auto& extension = project.InsertNewEventsFunctionsExtension("MyEventExtension", 0);
auto& object = extension.GetEventsBasedObjects().InsertNew("MyObject", 0);
@@ -864,7 +862,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res2", "path/to/file2.png", "image");
project.GetResourcesManager().AddResource(
"res3", "path/to/file3.png", "image");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
auto& layout = project.InsertNewLayout("Scene", 0);
layout.InsertNewLayer("MyLayer", 0);
@@ -889,7 +887,7 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
"res2", "path/to/file2.png", "image");
project.GetResourcesManager().AddResource(
"res3", "path/to/file3.png", "image");
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
ArbitraryResourceWorkerTest worker;
auto& layout = project.InsertNewLayout("Scene", 0);
layout.InsertNewLayer("MyLayer", 0);

View File

@@ -489,7 +489,7 @@ void SetupProjectWithDummyPlatform(gd::Project& project,
"Effect",
_("Apply visual effects to objects."),
"",
"res/actions/effect_black.svg", "EffectBehavior",
"res/actions/effect24.png", "EffectBehavior",
std::make_shared<gd::Behavior>(),
std::make_shared<gd::BehaviorsSharedData>())
.SetHidden();

View File

@@ -1252,49 +1252,6 @@ TEST_CASE("ExpressionCodeGenerator", "[common][events]") {
"MySpriteObject.getObjectStringWith2ObjectParam(fakeObjectListOf_"
"Object1, fakeObjectListOf_Object2) ?? \"\"");
}
SECTION("Edge cases (variables with object name in objectvar parameter)") {
SECTION("Simple case") {
gd::String output = gd::ExpressionCodeGenerator::GenerateExpressionCode(
codeGenerator,
context,
"objectvar", // We suppose we generate an "objectvar" parameter.
"MyOtherSpriteObject", // This "variable name" is the same as an object name (but this is valid).
"MySpriteObject" // The object owning the variable: MySpriteObject.
);
// This seems "obvious", but we had cases where MyOtherSpriteObject could have been interpreted as an object
// when the code generation is not properly recognizing "objectvar".
REQUIRE(output == "getVariableForObject(MySpriteObject, MyOtherSpriteObject)");
}
SECTION("With child variable") {
gd::String output = gd::ExpressionCodeGenerator::GenerateExpressionCode(
codeGenerator,
context,
"objectvar", // We suppose we generate an "objectvar" parameter.
"MyOtherSpriteObject.Child", // This "variable name" is the same as an object name (but this is valid).
"MySpriteObject" // The object owning the variable: MySpriteObject.
);
// This seems "obvious", but we had cases where MyOtherSpriteObject could have been interpreted as an object
// when the code generation is not properly recognizing "objectvar".
REQUIRE(output == "getVariableForObject(MySpriteObject, MyOtherSpriteObject).getChild(\"Child\")");
}
SECTION("With child and grandchild variable") {
gd::String output = gd::ExpressionCodeGenerator::GenerateExpressionCode(
codeGenerator,
context,
"objectvar", // We suppose we generate an "objectvar" parameter.
"MyOtherSpriteObject.Child.Grandchild", // This "variable name" is the same as an object name (but this is valid).
"MySpriteObject" // The object owning the variable: MySpriteObject.
);
// This seems "obvious", but we had cases where MyOtherSpriteObject could have been interpreted as an object
// when the code generation is not properly recognizing "objectvar".
REQUIRE(output == "getVariableForObject(MySpriteObject, MyOtherSpriteObject).getChild(\"Child\").getChild(\"Grandchild\")");
}
}
SECTION("Mixed test (1)") {
{
auto node = parser.ParseExpression("-+-MyExtension::MouseX(,)");

View File

@@ -11,7 +11,6 @@
#include "GDCore/IDE/Events/ExpressionValidator.h"
#include "GDCore/IDE/Events/ExpressionTypeFinder.h"
#include "GDCore/IDE/Events/ExpressionVariableOwnerFinder.h"
#include "GDCore/IDE/Events/ExpressionVariableParentFinder.h"
#include "GDCore/Project/Layout.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Project/ProjectScopedContainers.h"
@@ -203,23 +202,6 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
auto node = parser.ParseExpression("abcd[0]");
REQUIRE(node != nullptr);
// Also check that if we try to find the last parent of node, it is not defined.
auto lastParentOfNode = gd::ExpressionVariableParentFinder::GetLastParentOfNode(
platform, projectScopedContainers, *node);
REQUIRE(lastParentOfNode.parentVariable == nullptr);
REQUIRE(lastParentOfNode.parentVariablesContainer == nullptr);
gd::ExpressionValidator validator(platform, projectScopedContainers, "string");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"No object, variable or property with this name found.");
REQUIRE(validator.GetFatalErrors()[0]->GetStartPosition() == 0);
}
{
auto node = parser.ParseExpression("abcd[0].efg");
REQUIRE(node != nullptr);
gd::ExpressionValidator validator(platform, projectScopedContainers, "string");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
@@ -231,12 +213,6 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
auto node = parser.ParseExpression("abcd.efg.hij");
REQUIRE(node != nullptr);
// Also check that if we try to find the last parent of node, it is not defined.
auto lastParentOfNode = gd::ExpressionVariableParentFinder::GetLastParentOfNode(
platform, projectScopedContainers, *node);
REQUIRE(lastParentOfNode.parentVariable == nullptr);
REQUIRE(lastParentOfNode.parentVariablesContainer == nullptr);
gd::ExpressionValidator validator(platform, projectScopedContainers, "string");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
@@ -785,12 +761,6 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
auto node = parser.ParseExpression("abcd.efg.hij");
REQUIRE(node != nullptr);
// Also check that if we try to find the last parent of node, it is not defined.
auto lastParentOfNode = gd::ExpressionVariableParentFinder::GetLastParentOfNode(
platform, projectScopedContainers, *node);
REQUIRE(lastParentOfNode.parentVariable == nullptr);
REQUIRE(lastParentOfNode.parentVariablesContainer == nullptr);
gd::ExpressionValidator validator(platform, projectScopedContainers, "number");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
@@ -1524,12 +1494,6 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
auto node =
parser.ParseExpression("MyNonExistingSceneVariable");
// Also check that if we try to find the last parent of node, it is not defined.
auto lastParentOfNode = gd::ExpressionVariableParentFinder::GetLastParentOfNode(
platform, projectScopedContainers, *node);
REQUIRE(lastParentOfNode.parentVariable == nullptr);
REQUIRE(lastParentOfNode.parentVariablesContainer == nullptr);
gd::ExpressionValidator validator(platform, projectScopedContainers, "number|string");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
@@ -1551,25 +1515,6 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
}
}
SECTION("Invalid scene variables (2 levels, variable and child do not exist)") {
{
auto node =
parser.ParseExpression("MyNonExistingSceneVariable.MyNonExistingChild");
// Also check that if we try to find the last parent of node, it is not defined.
auto lastParentOfNode = gd::ExpressionVariableParentFinder::GetLastParentOfNode(
platform, projectScopedContainers, *node);
REQUIRE(lastParentOfNode.parentVariable == nullptr);
REQUIRE(lastParentOfNode.parentVariablesContainer == nullptr);
gd::ExpressionValidator validator(platform, projectScopedContainers, "number|string");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"You must enter a number or a text, wrapped inside double quotes (example: \"Hello world\"), or a variable name.");
}
}
SECTION("Valid object variables (1 level)") {
{
auto node =
@@ -1640,12 +1585,6 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
auto node =
parser.ParseExpression("MyNonExistingSpriteObject.MyVariable");
// Also check that if we try to find the last parent of node, it is not defined.
auto lastParentOfNode = gd::ExpressionVariableParentFinder::GetLastParentOfNode(
platform, projectScopedContainers, *node);
REQUIRE(lastParentOfNode.parentVariable == nullptr);
REQUIRE(lastParentOfNode.parentVariablesContainer == nullptr);
gd::ExpressionValidator validator(platform, projectScopedContainers, "number|string");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
@@ -1667,21 +1606,6 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
}
}
SECTION("Invalid object variables (empty variable name, extra dot)") {
{
auto node =
parser.ParseExpression("MySpriteObjects..");
gd::ExpressionValidator validator(platform, projectScopedContainers, "number|string");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 2);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"A name should be entered after the dot.");
REQUIRE(validator.GetFatalErrors()[1]->GetMessage() ==
"A name should be entered after the dot.");
}
}
SECTION("Invalid object variables (object group, partially existing variable)") {
{
auto node =
@@ -1766,42 +1690,6 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
"An object variable or expression should be entered.");
}
}
SECTION("Invalid object variables (extra dot)") {
{
auto node =
parser.ParseExpression("MySpriteObject.MyVariable.");
gd::ExpressionValidator validator(platform, projectScopedContainers, "number|string");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"A name should be entered after the dot.");
}
}
SECTION("Invalid object variables (extra dot after brackets)") {
{
auto node =
parser.ParseExpression("MySpriteObject.MyVariable[\"MyChild\"].");
gd::ExpressionValidator validator(platform, projectScopedContainers, "number|string");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"A name should be entered after the dot.");
}
}
SECTION("Invalid object variables (extra dot before brackets)") {
{
auto node =
parser.ParseExpression("MySpriteObject.MyVariable.[\"MyChild\"]");
gd::ExpressionValidator validator(platform, projectScopedContainers, "number|string");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"A name should be entered after the dot.");
}
}
SECTION("Valid property") {
gd::PropertiesContainer propertiesContainer(gd::EventsFunctionsContainer::Extension);
@@ -2268,14 +2156,6 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
dynamic_cast<gd::IdentifierNode &>(*node);
REQUIRE(identifierNode.identifierName == "MyObject");
REQUIRE(identifierNode.childIdentifierName == "");
gd::ExpressionValidator validator(platform, projectScopedContainers, "number");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 2);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"A name should be entered after the dot.");
REQUIRE(validator.GetFatalErrors()[1]->GetMessage() ==
"An object variable or expression should be entered.");
}
SECTION("Unfinished object function name of type string with parentheses") {
@@ -2287,14 +2167,6 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
REQUIRE(objectFunctionCall.objectName == "MyObject");
REQUIRE(objectFunctionCall.functionName == "");
REQUIRE(type == "string");
gd::ExpressionValidator validator(platform, projectScopedContainers, "number");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 2);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"A name should be entered after the dot.");
REQUIRE(validator.GetFatalErrors()[1]->GetMessage() ==
"Enter the name of the function to call.");
}
SECTION("Unfinished object function name of type number with parentheses") {
@@ -2321,19 +2193,6 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
REQUIRE(type == "number|string");
}
SECTION("Unfinished object function/variable name with multiple dots") {
auto node = parser.ParseExpression("MyObject..");
REQUIRE(node != nullptr);
gd::ExpressionValidator validator(platform, projectScopedContainers, "number");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 2);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"A name should be entered after the dot.");
REQUIRE(validator.GetFatalErrors()[1]->GetMessage() ==
"A name should be entered after the dot.");
}
SECTION("Unfinished object behavior name") {
auto node = parser.ParseExpression("MyObject.MyBehavior::");
REQUIRE(node != nullptr);
@@ -2342,12 +2201,6 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
REQUIRE(objectFunctionName.objectName == "MyObject");
REQUIRE(objectFunctionName.objectFunctionOrBehaviorName == "MyBehavior");
REQUIRE(objectFunctionName.behaviorFunctionName == "");
gd::ExpressionValidator validator(platform, projectScopedContainers, "number");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"An opening parenthesis was expected here to call a function.");
}
SECTION("Unfinished object behavior name of type string with parentheses") {
@@ -2360,12 +2213,6 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
REQUIRE(objectFunctionName.behaviorName == "MyBehavior");
REQUIRE(objectFunctionName.functionName == "");
REQUIRE(type == "string");
gd::ExpressionValidator validator(platform, projectScopedContainers, "number");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"Enter the name of the function to call.");
}
SECTION("Unfinished object behavior name of type number with parentheses") {
@@ -2651,8 +2498,10 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
// TODO: The error message could be improved
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"Enter the name of the function to call.");
"Cannot find an expression with this name: \nDouble "
"check that you've not made any typo in the name.");
REQUIRE(validator.GetFatalErrors()[0]->GetStartPosition() == 0);
REQUIRE(validator.GetFatalErrors()[0]->GetEndPosition() == 25);
}
@@ -2960,8 +2809,8 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
// as ExpressionVariableOwnerFinder depends on this parameter type
// information.
auto node = parser.ParseExpression(
"MyExtension::GetStringWith2ObjectParamAnd2ObjectVarParam(MySpriteObject, "
"MyVariable, MySpriteObject2, MyVariable2)");
"MyExtension::GetStringWith2ObjectParamAnd2ObjectVarParam(MyObject1, "
"MyVar1, MyObject2, MyVar2)");
REQUIRE(node != nullptr);
auto &functionNode = dynamic_cast<gd::FunctionCallNode &>(*node);
auto &identifierObject1Node =
@@ -2973,25 +2822,17 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
auto &variable2Node =
dynamic_cast<gd::IdentifierNode &>(*functionNode.parameters[3]);
REQUIRE(identifierObject1Node.identifierName == "MySpriteObject");
REQUIRE(identifierObject2Node.identifierName == "MySpriteObject2");
REQUIRE(variable1Node.identifierName == "MyVariable");
REQUIRE(variable2Node.identifierName == "MyVariable2");
REQUIRE(identifierObject1Node.identifierName == "MyObject1");
REQUIRE(identifierObject2Node.identifierName == "MyObject2");
REQUIRE(variable1Node.identifierName == "MyVar1");
REQUIRE(variable2Node.identifierName == "MyVar2");
auto variable1ObjectName = gd::ExpressionVariableOwnerFinder::GetObjectName(
platform, objectsContainersList, "", variable1Node);
REQUIRE(variable1ObjectName == "MySpriteObject");
REQUIRE(variable1ObjectName == "MyObject1");
auto variable2ObjectName = gd::ExpressionVariableOwnerFinder::GetObjectName(
platform, objectsContainersList, "", variable2Node);
REQUIRE(variable2ObjectName == "MySpriteObject2");
// Also check the ability to find the last parent of the variables:
auto lastParentOfVariable1Node = gd::ExpressionVariableParentFinder::GetLastParentOfNode(
platform, projectScopedContainers, variable1Node);
REQUIRE(lastParentOfVariable1Node.parentVariablesContainer == &mySpriteObject.GetVariables());
auto lastParentOfVariable2Node = gd::ExpressionVariableParentFinder::GetLastParentOfNode(
platform, projectScopedContainers, variable2Node);
REQUIRE(lastParentOfVariable2Node.parentVariablesContainer == &mySpriteObject2.GetVariables());
REQUIRE(variable2ObjectName == "MyObject2");
gd::ExpressionValidator validator(platform, projectScopedContainers, "string");
node->Visit(validator);
@@ -3002,8 +2843,8 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
SECTION("Valid function call with 2 object variable from the same object") {
{
auto node = parser.ParseExpression(
"MyExtension::GetStringWith1ObjectParamAnd2ObjectVarParam(MySpriteObject, "
"MyVariable, MyVariable2)");
"MyExtension::GetStringWith1ObjectParamAnd2ObjectVarParam(MyObject1, "
"MyVar1, MyVar2)");
REQUIRE(node != nullptr);
auto &functionNode = dynamic_cast<gd::FunctionCallNode &>(*node);
auto &identifierObject1Node =
@@ -3013,24 +2854,16 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
auto &variable2Node =
dynamic_cast<gd::IdentifierNode &>(*functionNode.parameters[2]);
REQUIRE(identifierObject1Node.identifierName == "MySpriteObject");
REQUIRE(variable1Node.identifierName == "MyVariable");
REQUIRE(variable2Node.identifierName == "MyVariable2");
REQUIRE(identifierObject1Node.identifierName == "MyObject1");
REQUIRE(variable1Node.identifierName == "MyVar1");
REQUIRE(variable2Node.identifierName == "MyVar2");
auto variable1ObjectName = gd::ExpressionVariableOwnerFinder::GetObjectName(
platform, objectsContainersList, "", variable1Node);
REQUIRE(variable1ObjectName == "MySpriteObject");
REQUIRE(variable1ObjectName == "MyObject1");
auto variable2ObjectName = gd::ExpressionVariableOwnerFinder::GetObjectName(
platform, objectsContainersList, "", variable2Node);
REQUIRE(variable2ObjectName == "MySpriteObject");
// Also check the ability to find the last parent of the variables:
auto lastParentOfVariable1Node = gd::ExpressionVariableParentFinder::GetLastParentOfNode(
platform, projectScopedContainers, variable1Node);
REQUIRE(lastParentOfVariable1Node.parentVariablesContainer == &mySpriteObject.GetVariables());
auto lastParentOfVariable2Node = gd::ExpressionVariableParentFinder::GetLastParentOfNode(
platform, projectScopedContainers, variable2Node);
REQUIRE(lastParentOfVariable2Node.parentVariablesContainer == &mySpriteObject.GetVariables());
REQUIRE(variable2ObjectName == "MyObject1");
gd::ExpressionValidator validator(platform, projectScopedContainers, "string");
node->Visit(validator);
@@ -3041,23 +2874,18 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
SECTION("Valid object function call with 1 object variable from the object of the function") {
{
auto node = parser.ParseExpression(
"MySpriteObject.GetObjectVariableAsNumber(MyVariable)");
"MySpriteObject.GetObjectVariableAsNumber(MyVar1)");
REQUIRE(node != nullptr);
auto &functionNode = dynamic_cast<gd::FunctionCallNode &>(*node);
auto &variable1Node =
dynamic_cast<gd::IdentifierNode &>(*functionNode.parameters[0]);
REQUIRE(variable1Node.identifierName == "MyVariable");
REQUIRE(variable1Node.identifierName == "MyVar1");
auto variable1ObjectName = gd::ExpressionVariableOwnerFinder::GetObjectName(
platform, objectsContainersList, "MySpriteObject", variable1Node);
REQUIRE(variable1ObjectName == "MySpriteObject");
// Also check the ability to find the last parent of the variable:
auto lastParentOfVariable1Node = gd::ExpressionVariableParentFinder::GetLastParentOfNode(
platform, projectScopedContainers, variable1Node);
REQUIRE(lastParentOfVariable1Node.parentVariablesContainer == &mySpriteObject.GetVariables());
gd::ExpressionValidator validator(platform, projectScopedContainers, "number");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 0);
@@ -3067,24 +2895,19 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
SECTION("Valid object function call with 1 object variable from the object of the function with a child") {
{
auto node = parser.ParseExpression(
"MySpriteObject.GetObjectVariableAsNumber(MyVariable.MyChild)");
"MySpriteObject.GetObjectVariableAsNumber(MyVar1.MyChild)");
REQUIRE(node != nullptr);
auto &functionNode = dynamic_cast<gd::FunctionCallNode &>(*node);
auto &variable1Node =
dynamic_cast<gd::IdentifierNode &>(*functionNode.parameters[0]);
REQUIRE(variable1Node.identifierName == "MyVariable");
REQUIRE(variable1Node.identifierName == "MyVar1");
REQUIRE(variable1Node.childIdentifierName == "MyChild");
auto variable1ObjectName = gd::ExpressionVariableOwnerFinder::GetObjectName(
platform, objectsContainersList, "MySpriteObject", variable1Node);
REQUIRE(variable1ObjectName == "MySpriteObject");
// Also check the ability to find the last parent of the variable:
auto lastParentOfVariable1Node = gd::ExpressionVariableParentFinder::GetLastParentOfNode(
platform, projectScopedContainers, variable1Node);
REQUIRE(lastParentOfVariable1Node.parentVariable == &mySpriteObject.GetVariables().Get("MyVariable"));
gd::ExpressionValidator validator(platform, projectScopedContainers, "number");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 0);

View File

@@ -1,148 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
/**
* @file Tests covering common features of GDevelop Core.
*/
#include "GDCore/IDE/ObjectAssetSerializer.h"
#include "DummyPlatform.h"
#include "GDCore/CommonTools.h"
#include "GDCore/Events/Builtin/StandardEvent.h"
#include "GDCore/Events/Event.h"
#include "GDCore/Events/EventsList.h"
#include "GDCore/Events/Serialization.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
#include "GDCore/Extensions/Platform.h"
#include "GDCore/Project/CustomObjectConfiguration.h"
#include "GDCore/Project/EventsFunctionsExtension.h"
#include "GDCore/Project/Layout.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/ObjectsContainer.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Project/Variable.h"
#include "GDCore/Serialization/Serializer.h"
#include "GDCore/Tools/SystemStats.h"
#include "GDCore/Tools/VersionWrapper.h"
#include "catch.hpp"
#include <string>
using namespace gd;
TEST_CASE("ObjectAssetSerializer", "[common]") {
SECTION("Can serialize custom objects as assets") {
gd::Platform platform;
gd::Project project;
SetupProjectWithDummyPlatform(project, platform);
auto &eventsExtension =
project.InsertNewEventsFunctionsExtension("MyEventsExtension", 0);
auto &eventsBasedObject = eventsExtension.GetEventsBasedObjects().InsertNew(
"MyEventsBasedObject", 0);
eventsBasedObject.SetFullName("My events based object");
eventsBasedObject.SetDescription("An events based object for test");
eventsBasedObject.InsertNewObject(project, "MyExtension::Sprite", "MyChild",
0);
auto &resourceManager = project.GetResourcesManager();
gd::ImageResource imageResource;
imageResource.SetName("assets/Idle.png");
imageResource.SetFile("assets/Idle.png");
imageResource.SetSmooth(true);
resourceManager.AddResource(imageResource);
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
gd::Object &object = layout.InsertNewObject(
project, "MyEventsExtension::MyEventsBasedObject", "MyObject", 0);
auto &configuration = object.GetConfiguration();
auto *customObjectConfiguration =
dynamic_cast<gd::CustomObjectConfiguration *>(&configuration);
auto *spriteConfiguration = dynamic_cast<gd::SpriteObject *>(
&customObjectConfiguration->GetChildObjectConfiguration("MyChild"));
REQUIRE(spriteConfiguration != nullptr);
{
gd::Animation animation;
animation.SetName("Idle");
animation.SetDirectionsCount(1);
auto &direction = animation.GetDirection(0);
gd::Sprite frame;
frame.SetImageName("assets/Idle.png");
direction.AddSprite(frame);
spriteConfiguration->AddAnimation(animation);
}
SerializerElement assetElement;
std::map<gd::String, gd::String> resourcesFileNameMap;
ObjectAssetSerializer::SerializeTo(project, object, "My Object",
assetElement, resourcesFileNameMap);
// This mapping is used to copy resource files.
REQUIRE(resourcesFileNameMap.find("assets/Idle.png") !=
resourcesFileNameMap.end());
REQUIRE(resourcesFileNameMap["assets/Idle.png"] == "Idle.png");
// Check that the project is left untouched.
REQUIRE(resourceManager.HasResource("assets/Idle.png"));
REQUIRE(resourceManager.GetResource("assets/Idle.png").GetFile() ==
"assets/Idle.png");
REQUIRE(!resourceManager.HasResource("Idle.png"));
REQUIRE(assetElement.HasChild("objectAssets"));
auto &objectAssetsElement = assetElement.GetChild("objectAssets");
objectAssetsElement.ConsiderAsArrayOf("objectAsset");
REQUIRE(objectAssetsElement.GetChildrenCount() == 1);
auto &objectAssetElement = objectAssetsElement.GetChild(0);
REQUIRE(objectAssetElement.HasChild("requiredExtensions"));
auto &requiredExtensionsElement =
objectAssetElement.GetChild("requiredExtensions");
requiredExtensionsElement.ConsiderAsArrayOf("requiredExtension");
REQUIRE(requiredExtensionsElement.GetChildrenCount() == 1);
auto &requiredExtensionElement = requiredExtensionsElement.GetChild(0);
REQUIRE(requiredExtensionElement.GetStringAttribute("extensionName") ==
"MyEventsExtension");
// Resources are renamed according to asset script naming conventions.
REQUIRE(objectAssetElement.HasChild("resources"));
auto &resourcesElement = objectAssetElement.GetChild("resources");
resourcesElement.ConsiderAsArrayOf("resource");
REQUIRE(resourcesElement.GetChildrenCount() == 1);
{
auto &resourceElement = resourcesElement.GetChild(0);
REQUIRE(resourceElement.GetStringAttribute("name") == "Idle.png");
REQUIRE(resourceElement.GetStringAttribute("file") == "Idle.png");
REQUIRE(resourceElement.GetStringAttribute("kind") == "image");
REQUIRE(resourceElement.GetBoolAttribute("smoothed") == true);
}
// Resources used in object configuration are updated.
REQUIRE(objectAssetElement.HasChild("object"));
auto &objectElement = objectAssetElement.GetChild("object");
REQUIRE(objectElement.GetStringAttribute("name") == "MyObject");
REQUIRE(objectElement.GetStringAttribute("type") ==
"MyEventsExtension::MyEventsBasedObject");
auto &childrenContentElement = objectElement.GetChild("childrenContent");
REQUIRE(childrenContentElement.HasChild("MyChild"));
auto &childElement = childrenContentElement.GetChild("MyChild");
REQUIRE(childElement.HasChild("animations"));
auto &animationsElement = childElement.GetChild("animations");
animationsElement.ConsiderAsArrayOf("animation");
REQUIRE(animationsElement.GetChildrenCount() == 1);
auto &animationElement = animationsElement.GetChild(0);
REQUIRE(animationElement.GetStringAttribute("name") == "Idle");
auto &directionsElement = animationElement.GetChild("directions");
directionsElement.ConsiderAsArrayOf("direction");
REQUIRE(directionsElement.GetChildrenCount() == 1);
auto &directionElement = directionsElement.GetChild(0);
auto &spritesElement = directionElement.GetChild("sprites");
spritesElement.ConsiderAsArrayOf("sprite");
REQUIRE(spritesElement.GetChildrenCount() == 1);
auto &spriteElement = spritesElement.GetChild(0);
REQUIRE(spriteElement.GetStringAttribute("image") == "Idle.png");
}
}

View File

@@ -91,7 +91,8 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
auto &getterAction = getterEvent.GetActions().at(0);
REQUIRE(getterAction.GetType() == "SetReturnNumber");
REQUIRE(getterAction.GetParametersCount() == 1);
REQUIRE(getterAction.GetParameter(0).GetPlainString() == "MovementAngle");
REQUIRE(getterAction.GetParameter(0).GetPlainString() ==
"Object.Behavior::PropertyMovementAngle()");
}
{
auto &setter =
@@ -123,7 +124,8 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
REQUIRE(setterAction.GetParameter(0).GetPlainString() == "Object");
REQUIRE(setterAction.GetParameter(1).GetPlainString() == "Behavior");
REQUIRE(setterAction.GetParameter(2).GetPlainString() == "=");
REQUIRE(setterAction.GetParameter(3).GetPlainString() == "Value");
REQUIRE(setterAction.GetParameter(3).GetPlainString() ==
"GetArgumentAsNumber(\"Value\")");
}
}
@@ -341,7 +343,8 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
auto &getterAction = getterEvent.GetActions().at(0);
REQUIRE(getterAction.GetType() == "SetReturnNumber");
REQUIRE(getterAction.GetParametersCount() == 1);
REQUIRE(getterAction.GetParameter(0).GetPlainString() == "MovementAngle");
REQUIRE(getterAction.GetParameter(0).GetPlainString() ==
"Object.PropertyMovementAngle()");
}
{
auto &setter =
@@ -372,7 +375,8 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
REQUIRE(setterAction.GetParametersCount() == 3);
REQUIRE(setterAction.GetParameter(0).GetPlainString() == "Object");
REQUIRE(setterAction.GetParameter(1).GetPlainString() == "=");
REQUIRE(setterAction.GetParameter(2).GetPlainString() == "Value");
REQUIRE(setterAction.GetParameter(2).GetPlainString() ==
"GetArgumentAsNumber(\"Value\")");
}
}
@@ -574,7 +578,8 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
auto &getterAction = getterEvent.GetActions().at(0);
REQUIRE(getterAction.GetType() == "SetReturnNumber");
REQUIRE(getterAction.GetParametersCount() == 1);
REQUIRE(getterAction.GetParameter(0).GetPlainString() == "MovementAngle");
REQUIRE(getterAction.GetParameter(0).GetPlainString() ==
"Object.Behavior::SharedPropertyMovementAngle()");
}
{
auto &setter =

View File

@@ -65,11 +65,11 @@ class MockFileSystem : public gd::AbstractFileSystem {
TEST_CASE("ResourcesMergingHelper", "[common]") {
SECTION("Basics") {
gd::Project project;
MockFileSystem fs;
gd::ResourcesMergingHelper resourcesMerger(project.GetResourcesManager(), fs);
gd::ResourcesMergingHelper resourcesMerger(fs);
resourcesMerger.SetBaseDirectory("/game/base/folder/");
gd::Project project;
project.GetResourcesManager().AddResource("Image1", "/image1.png", "image");
project.GetResourcesManager().AddResource("Image2", "image2.png", "image");
project.GetResourcesManager().AddResource("Audio1", "audio1.png", "audio");
@@ -90,12 +90,12 @@ TEST_CASE("ResourcesMergingHelper", "[common]") {
"FileNameFrom(MakeAbsolute(subfolder/image3.png))");
}
SECTION("Can preserve directories structure") {
gd::Project project;
MockFileSystem fs;
gd::ResourcesMergingHelper resourcesMerger(project.GetResourcesManager(), fs);
gd::ResourcesMergingHelper resourcesMerger(fs);
resourcesMerger.SetBaseDirectory("/game/base/folder/");
resourcesMerger.PreserveDirectoriesStructure(true);
gd::Project project;
project.GetResourcesManager().AddResource("Image1", "/image1.png", "image");
project.GetResourcesManager().AddResource("Image2", "image2.png", "image");
project.GetResourcesManager().AddResource("Audio1", "audio1.png", "audio");

View File

@@ -15,10 +15,11 @@
TEST_CASE("ResourcesRenamer", "[common]") {
SECTION("It renames resources that are exposed") {
gd::Project project;
std::map<gd::String, gd::String> renamings = {
{"Resource1", "RenamedResource1"}};
gd::ResourcesRenamer resourcesRenamer(project.GetResourcesManager(), renamings);
gd::ResourcesRenamer resourcesRenamer(renamings);
gd::Project project;
// Add "classic", plain resources.
gd::ImageResource resource1;
@@ -44,10 +45,11 @@ TEST_CASE("ResourcesRenamer", "[common]") {
}
SECTION("It renames embedded resources") {
gd::Project project;
std::map<gd::String, gd::String> renamings = {
{"Resource1", "RenamedResource1"}};
gd::ResourcesRenamer resourcesRenamer(project.GetResourcesManager(), renamings);
gd::ResourcesRenamer resourcesRenamer(renamings);
gd::Project project;
// Add "classic", plain resources.
gd::ImageResource resource1;

View File

@@ -201,34 +201,39 @@ TEST_CASE("WholeProjectRefactorer::ApplyRefactoringForVariablesContainer",
"MyRenamedGlobalStructureVariable");
project.GetVariables().Rename("SharedVariableName",
"RenamedGlobalVariableFromASharedName");
auto changeset =
gd::WholeProjectRefactorer::ComputeChangesetForVariablesContainer(
project,
originalSerializedProjectVariables,
project.GetVariables());
auto changeset = gd::WholeProjectRefactorer::ComputeChangesetForVariablesContainer(
project,
originalSerializedProjectVariables,
project.GetVariables());
gd::WholeProjectRefactorer::ApplyRefactoringForVariablesContainer(
project, project.GetVariables(), changeset);
project,
project.GetVariables(),
changeset);
layout1.GetVariables().Rename("MySceneVariable", "MyRenamedSceneVariable");
layout1.GetVariables().Rename("MySceneStructureVariable",
"MyRenamedSceneStructureVariable");
changeset =
gd::WholeProjectRefactorer::ComputeChangesetForVariablesContainer(
project, originalSerializedLayoutVariables, layout1.GetVariables());
changeset = gd::WholeProjectRefactorer::ComputeChangesetForVariablesContainer(
project,
originalSerializedLayoutVariables,
layout1.GetVariables());
gd::WholeProjectRefactorer::ApplyRefactoringForVariablesContainer(
project, layout1.GetVariables(), changeset);
project,
layout1.GetVariables(),
changeset);
object1.GetVariables().Rename("MyObjectVariable",
"MyRenamedObjectVariable");
object1.GetVariables().Rename("MyObjectStructureVariable",
"MyRenamedObjectStructureVariable");
changeset =
gd::WholeProjectRefactorer::ComputeChangesetForVariablesContainer(
project,
originalSerializedObject1Variables,
object1.GetVariables());
changeset = gd::WholeProjectRefactorer::ComputeChangesetForVariablesContainer(
project,
originalSerializedObject1Variables,
object1.GetVariables());
gd::WholeProjectRefactorer::ApplyRefactoringForVariablesContainer(
project, object1.GetVariables(), changeset);
project,
object1.GetVariables(),
changeset);
// Check the first layout is updated.
// clang-format off
@@ -324,182 +329,6 @@ TEST_CASE("WholeProjectRefactorer::ApplyRefactoringForVariablesContainer",
gd::Serializer::ToJSON(originalSerializedLayout2));
}
}
SECTION("Variable renamed (object group)") {
gd::Project project;
gd::Platform platform;
SetupProjectWithDummyPlatform(project, platform);
auto &layout1 = project.InsertNewLayout("Layout1", 0);
gd::StandardEvent &event =
dynamic_cast<gd::StandardEvent &>(layout1.GetEvents().InsertNewEvent(
project, "BuiltinCommonInstructions::Standard"));
gd::RepeatEvent &repeatEvent =
dynamic_cast<gd::RepeatEvent &>(layout1.GetEvents().InsertNewEvent(
project, "BuiltinCommonInstructions::Repeat"));
// Declare variables in objects.
auto &object1 =
layout1.InsertNewObject(project, "MyExtension::Sprite", "Object1", 0);
object1.GetVariables().InsertNew("MyObjectVariable");
object1.GetVariables()
.InsertNew("MyObjectStructureVariable")
.GetChild("MyChild")
.SetValue(123);
auto &object2 =
layout1.InsertNewObject(project, "MyExtension::Sprite", "Object2", 0);
object2.GetVariables().InsertNew("MyObjectVariable");
object2.GetVariables()
.InsertNew("MyObjectStructureVariable")
.GetChild("MyChild")
.SetValue(123);
auto& group = layout1.GetObjectGroups().InsertNew("MyObjectGroup");
group.AddObject("Object1");
group.AddObject("Object2");
// Create an event using the variables.
// clang-format off
{
gd::Instruction action;
action.SetType("MyExtension::DoSomething");
action.SetParametersCount(1);
action.SetParameter(
0,
gd::Expression(
"1 + "
"Object1.MyObjectVariable + "
"Object2.MyObjectVariable + "
"MyObjectGroup.MyObjectVariable + "
"Object1.MyObjectStructureVariable.MyChild + "
"Object2.MyObjectStructureVariable.MyChild + "
"MyObjectGroup.MyObjectStructureVariable.MyChild"));
event.GetActions().Insert(action);
}
// Expressions with "old" "scenevar", "globalvar", "objectvar":
{
gd::Instruction action;
action.SetType("MyExtension::DoSomething");
action.SetParametersCount(1);
action.SetParameter(
0,
gd::Expression(
// "objectvar" (in a free expression):
"1 + "
"MyExtension::GetStringWith2ObjectParamAnd2ObjectVarParam(Object1, MyObjectVariable, Object2, MyObjectVariable) + "
"MyExtension::GetStringWith2ObjectParamAnd2ObjectVarParam(MyObjectGroup, MyObjectVariable, MyObjectGroup, MyObjectVariable) + "
"MyExtension::GetStringWith2ObjectParamAnd2ObjectVarParam(Object1, MyObjectStructureVariable.MyChild, Object2, MyObjectStructureVariable.MyChild) + "
"MyExtension::GetStringWith2ObjectParamAnd2ObjectVarParam(MyObjectGroup, MyObjectStructureVariable.MyChild, MyObjectGroup, MyObjectStructureVariable.MyChild) + "
// "objectvar" (using the name of the object being called):
"Object1.GetObjectVariableAsNumber(MyObjectVariable) + "
"Object2.GetObjectVariableAsNumber(MyObjectVariable) + "
"MyObjectGroup.GetObjectVariableAsNumber(MyObjectVariable) + "
"Object1.GetObjectVariableAsNumber(MyObjectStructureVariable.MyChild) + "
"Object2.GetObjectVariableAsNumber(MyObjectStructureVariable.MyChild) + "
"MyObjectGroup.GetObjectVariableAsNumber(MyObjectStructureVariable.MyChild) + "
"Object1.GetObjectVariableAsNumber(MyObjectStructureVariable.MyChild.GrandChild) + "
"Object2.GetObjectVariableAsNumber(MyObjectStructureVariable.MyChild.GrandChild) + "
"MyObjectGroup.GetObjectVariableAsNumber(MyObjectStructureVariable.MyChild.GrandChild)"));
event.GetActions().Insert(action);
}
{
gd::Instruction action;
action.SetType("MyExtension::DoSomethingWithLegacyPreScopedVariables");
action.SetParametersCount(4);
action.SetParameter(0, gd::Expression("MySceneVariable"));
action.SetParameter(1, gd::Expression("MyGlobalVariable"));
action.SetParameter(2, gd::Expression("MyObjectGroup"));
action.SetParameter(3, gd::Expression("MyObjectVariable"));
event.GetActions().Insert(action);
}
repeatEvent.SetRepeatExpression("1 + Object1.MyObjectVariable + Object2.MyObjectVariable + MyObjectGroup.MyObjectVariable");
// clang-format on
// Do a copy of layout1 to ensure other scene is unchanged after the
// refactoring.
gd::Layout layout2 = layout1;
layout2.SetName("Layout2");
project.InsertLayout(layout2, 1);
gd::SerializerElement originalSerializedLayout2;
layout2.SerializeTo(originalSerializedLayout2);
// Do the changes and launch the refactoring.
project.GetVariables().ResetPersistentUuid();
layout1.GetVariables().ResetPersistentUuid();
object1.ResetPersistentUuid();
gd::SerializerElement originalSerializedObject1Variables;
object1.GetVariables().SerializeTo(originalSerializedObject1Variables);
object1.GetVariables().Rename("MyObjectVariable",
"MyRenamedObjectVariable");
object1.GetVariables().Rename("MyObjectStructureVariable",
"MyRenamedObjectStructureVariable");
auto changeset =
gd::WholeProjectRefactorer::ComputeChangesetForVariablesContainer(
project,
originalSerializedObject1Variables,
object1.GetVariables());
gd::WholeProjectRefactorer::ApplyRefactoringForVariablesContainer(
project, object1.GetVariables(), changeset);
// Check the first layout is updated.
// clang-format off
{
// Updated direct access to variables:
REQUIRE(event.GetActions()[0].GetParameter(0).GetPlainString() ==
"1 + "
"Object1.MyRenamedObjectVariable + "
"Object2.MyObjectVariable + "
"MyObjectGroup.MyRenamedObjectVariable + "
"Object1.MyRenamedObjectStructureVariable.MyChild + "
"Object2.MyObjectStructureVariable.MyChild + "
"MyObjectGroup.MyRenamedObjectStructureVariable.MyChild"
);
// Updated access to variables using the legacy "pre-scoped" "scenevar",
// "globalvar" and "objectvar" parameters in expressions:
REQUIRE(event.GetActions()[1].GetParameter(0).GetPlainString() ==
"1 + "
// Multiple "objectvar" parameters in a free function:
"MyExtension::GetStringWith2ObjectParamAnd2ObjectVarParam(Object1, MyRenamedObjectVariable, Object2, MyObjectVariable) + "
"MyExtension::GetStringWith2ObjectParamAnd2ObjectVarParam(MyObjectGroup, MyRenamedObjectVariable, MyObjectGroup, MyRenamedObjectVariable) + "
// Multiple "objectvar" parameters in a free function, with child
// variable:
"MyExtension::GetStringWith2ObjectParamAnd2ObjectVarParam(Object1, MyRenamedObjectStructureVariable.MyChild, Object2, MyObjectStructureVariable.MyChild) + "
"MyExtension::GetStringWith2ObjectParamAnd2ObjectVarParam(MyObjectGroup, MyRenamedObjectStructureVariable.MyChild, MyObjectGroup, MyRenamedObjectStructureVariable.MyChild) + "
// Single "objectvar" from the object being accessed:
"Object1.GetObjectVariableAsNumber(MyRenamedObjectVariable) + "
"Object2.GetObjectVariableAsNumber(MyObjectVariable) + "
"MyObjectGroup.GetObjectVariableAsNumber(MyRenamedObjectVariable) + "
// Single "objectvar" from the object being accessed, with child
// variales:
"Object1.GetObjectVariableAsNumber(MyRenamedObjectStructureVariable.MyChild) + "
"Object2.GetObjectVariableAsNumber(MyObjectStructureVariable.MyChild) + "
"MyObjectGroup.GetObjectVariableAsNumber(MyRenamedObjectStructureVariable.MyChild) + "
"Object1.GetObjectVariableAsNumber(MyRenamedObjectStructureVariable.MyChild.GrandChild) + "
"Object2.GetObjectVariableAsNumber(MyObjectStructureVariable.MyChild.GrandChild) + "
"MyObjectGroup.GetObjectVariableAsNumber(MyRenamedObjectStructureVariable.MyChild.GrandChild)");
// Updated "objectvar" parameters of an
// instruction:
REQUIRE(event.GetActions()[2].GetParameter(2).GetPlainString() ==
"MyObjectGroup");
REQUIRE(event.GetActions()[2].GetParameter(3).GetPlainString() ==
"MyRenamedObjectVariable");
}
REQUIRE(repeatEvent.GetRepeatExpression() == "1 + Object1.MyRenamedObjectVariable + Object2.MyObjectVariable + MyObjectGroup.MyRenamedObjectVariable");
// clang-format on
// Check the other layout is untouched.
{
gd::SerializerElement serializedLayout2;
layout2.SerializeTo(serializedLayout2);
REQUIRE(gd::Serializer::ToJSON(serializedLayout2) ==
gd::Serializer::ToJSON(originalSerializedLayout2));
}
}
SECTION("Variable removed (project, layout, object)") {
gd::Project project;
gd::Platform platform;
@@ -666,31 +495,36 @@ TEST_CASE("WholeProjectRefactorer::ApplyRefactoringForVariablesContainer",
project.GetVariables().Remove("MyGlobalVariable");
project.GetVariables().Remove("MyGlobalStructureVariable");
project.GetVariables().Remove("SharedVariableName");
auto changeset =
gd::WholeProjectRefactorer::ComputeChangesetForVariablesContainer(
project,
originalSerializedProjectVariables,
project.GetVariables());
auto changeset = gd::WholeProjectRefactorer::ComputeChangesetForVariablesContainer(
project,
originalSerializedProjectVariables,
project.GetVariables());
gd::WholeProjectRefactorer::ApplyRefactoringForVariablesContainer(
project, project.GetVariables(), changeset);
project,
project.GetVariables(),
changeset);
layout1.GetVariables().Remove("MySceneVariable");
layout1.GetVariables().Remove("MySceneStructureVariable");
changeset =
gd::WholeProjectRefactorer::ComputeChangesetForVariablesContainer(
project, originalSerializedLayoutVariables, layout1.GetVariables());
changeset = gd::WholeProjectRefactorer::ComputeChangesetForVariablesContainer(
project,
originalSerializedLayoutVariables,
layout1.GetVariables());
gd::WholeProjectRefactorer::ApplyRefactoringForVariablesContainer(
project, layout1.GetVariables(), changeset);
project,
layout1.GetVariables(),
changeset);
object1.GetVariables().Remove("MyObjectVariable");
object1.GetVariables().Remove("MyObjectStructureVariable");
changeset =
gd::WholeProjectRefactorer::ComputeChangesetForVariablesContainer(
project,
originalSerializedObject1Variables,
object1.GetVariables());
changeset = gd::WholeProjectRefactorer::ComputeChangesetForVariablesContainer(
project,
originalSerializedObject1Variables,
object1.GetVariables());
gd::WholeProjectRefactorer::ApplyRefactoringForVariablesContainer(
project, object1.GetVariables(), changeset);
project,
object1.GetVariables(),
changeset);
// Check the first layout is updated.
{

View File

@@ -3474,72 +3474,6 @@ TEST_CASE("RenameLayer", "[common]") {
"MyExtension::CameraCenterX(\"layerA\")");
}
SECTION("Renaming a layer also moves the instances on this layer and of the associated external layouts") {
gd::Project project;
gd::Platform platform;
SetupProjectWithDummyPlatform(project, platform);
auto &layout = project.InsertNewLayout("My layout", 0);
auto &otherLayout = project.InsertNewLayout("My other layout", 1);
layout.InsertNewLayer("My layer", 0);
otherLayout.InsertNewLayer("My layer", 0);
auto &externalLayout =
project.InsertNewExternalLayout("My external layout", 0);
auto &otherExternalLayout =
project.InsertNewExternalLayout("My other external layout", 0);
externalLayout.SetAssociatedLayout("My layout");
otherExternalLayout.SetAssociatedLayout("My other layout");
auto &initialInstances = layout.GetInitialInstances();
auto &initialInstance1 = initialInstances.InsertNewInitialInstance();
initialInstance1.SetLayer("My layer");
auto &initialInstance2 = initialInstances.InsertNewInitialInstance();
initialInstance2.SetLayer("My layer");
auto &initialInstance3 = initialInstances.InsertNewInitialInstance();
initialInstance3.SetLayer("");
auto &externalInitialInstances = externalLayout.GetInitialInstances();
auto &externalInitialInstance1 = externalInitialInstances.InsertNewInitialInstance();
externalInitialInstance1.SetLayer("My layer");
auto &externalInitialInstance2 = externalInitialInstances.InsertNewInitialInstance();
externalInitialInstance2.SetLayer("My layer");
auto &externalInitialInstance3 = externalInitialInstances.InsertNewInitialInstance();
externalInitialInstance3.SetLayer("");
auto &otherInitialInstances = otherLayout.GetInitialInstances();
auto &otherInitialInstance1 = otherInitialInstances.InsertNewInitialInstance();
otherInitialInstance1.SetLayer("My layer");
auto &otherExternalInitialInstances = otherExternalLayout.GetInitialInstances();
auto &otherExternalInitialInstance1 = otherExternalInitialInstances.InsertNewInitialInstance();
otherExternalInitialInstance1.SetLayer("My layer");
REQUIRE(initialInstance1.GetLayer() == "My layer");
REQUIRE(initialInstance2.GetLayer() == "My layer");
REQUIRE(initialInstance3.GetLayer() == "");
REQUIRE(externalInitialInstance1.GetLayer() == "My layer");
REQUIRE(externalInitialInstance2.GetLayer() == "My layer");
REQUIRE(externalInitialInstance3.GetLayer() == "");
REQUIRE(otherInitialInstance1.GetLayer() == "My layer");
REQUIRE(otherExternalInitialInstance1.GetLayer() == "My layer");
gd::WholeProjectRefactorer::RenameLayer(project, layout, "My layer", "My new layer");
// Instances on the renamed layer are moved to the new layer.
REQUIRE(initialInstance1.GetLayer() == "My new layer");
REQUIRE(initialInstance2.GetLayer() == "My new layer");
REQUIRE(initialInstance3.GetLayer() == "");
// Instances on the renamed layer of external layouts are moved to the new layer.
REQUIRE(externalInitialInstance1.GetLayer() == "My new layer");
REQUIRE(externalInitialInstance2.GetLayer() == "My new layer");
REQUIRE(externalInitialInstance3.GetLayer() == "");
// Instances on the renamed layer of other layouts & external layouts are not moved.
REQUIRE(otherInitialInstance1.GetLayer() == "My layer");
REQUIRE(otherExternalInitialInstance1.GetLayer() == "My layer");
}
SECTION("Can rename a layer when a layer parameter is empty") {
gd::Project project;
gd::Platform platform;

View File

@@ -1 +0,0 @@
Spine/pixi-spine

View File

@@ -61,30 +61,13 @@ namespace gdjs {
this.light.intensity = value;
}
}
getDoubleParameter(parameterName: string): number {
if (parameterName === 'intensity') {
return this.light.intensity;
}
return 0;
}
updateStringParameter(parameterName: string, value: string): void {
if (parameterName === 'color') {
this.light.color.setHex(
this.light.color = new THREE.Color(
gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value)
);
}
}
updateColorParameter(parameterName: string, value: number): void {
if (parameterName === 'color') {
this.light.color.setHex(value);
}
}
getColorParameter(parameterName: string): number {
if (parameterName === 'color') {
return this.light.color.getHex();
}
return 0;
}
updateBooleanParameter(parameterName: string, value: boolean): void {}
})();
}

View File

@@ -74,16 +74,6 @@ namespace gdjs {
this.updateRotation();
}
}
getDoubleParameter(parameterName: string): number {
if (parameterName === 'intensity') {
return this.light.intensity;
} else if (parameterName === 'elevation') {
return this.elevation;
} else if (parameterName === 'rotation') {
return this.rotation;
}
return 0;
}
updateStringParameter(parameterName: string, value: string): void {
if (parameterName === 'color') {
this.light.color = new THREE.Color(
@@ -95,17 +85,6 @@ namespace gdjs {
this.updateRotation();
}
}
updateColorParameter(parameterName: string, value: number): void {
if (parameterName === 'color') {
this.light.color.setHex(value);
}
}
getColorParameter(parameterName: string): number {
if (parameterName === 'color') {
return this.light.color.getHex();
}
return 0;
}
updateBooleanParameter(parameterName: string, value: boolean): void {}
updateRotation() {
if (this.top === 'Z+') {
@@ -114,7 +93,7 @@ namespace gdjs {
this.rotationObject.rotation.y = -gdjs.toRad(this.elevation);
} else {
// 0° becomes a light from Z+.
this.rotationObject.rotation.y = gdjs.toRad(this.rotation - 90);
this.rotationObject.rotation.y = gdjs.toRad(this.rotation) - 90;
this.rotationObject.rotation.z = -gdjs.toRad(this.elevation);
}
}

View File

@@ -58,12 +58,6 @@ namespace gdjs {
this.fog.density = value;
}
}
getDoubleParameter(parameterName: string): number {
if (parameterName === 'density') {
return this.fog.density;
}
return 0;
}
updateStringParameter(parameterName: string, value: string): void {
if (parameterName === 'color') {
this.fog.color = new THREE.Color(
@@ -71,17 +65,6 @@ namespace gdjs {
);
}
}
updateColorParameter(parameterName: string, value: number): void {
if (parameterName === 'color') {
this.fog.color.setHex(value);
}
}
getColorParameter(parameterName: string): number {
if (parameterName === 'color') {
return this.fog.color.getHex();
}
return 0;
}
updateBooleanParameter(parameterName: string, value: boolean): void {}
})();
}

View File

@@ -74,16 +74,6 @@ namespace gdjs {
this.updateRotation();
}
}
getDoubleParameter(parameterName: string): number {
if (parameterName === 'intensity') {
return this.light.intensity;
} else if (parameterName === 'elevation') {
return this.elevation;
} else if (parameterName === 'rotation') {
return this.rotation;
}
return 0;
}
updateStringParameter(parameterName: string, value: string): void {
if (parameterName === 'skyColor') {
this.light.color = new THREE.Color(
@@ -100,23 +90,6 @@ namespace gdjs {
this.updateRotation();
}
}
updateColorParameter(parameterName: string, value: number): void {
if (parameterName === 'skyColor') {
this.light.color.setHex(value);
}
if (parameterName === 'groundColor') {
this.light.groundColor.setHex(value);
}
}
getColorParameter(parameterName: string): number {
if (parameterName === 'skyColor') {
return this.light.color.getHex();
}
if (parameterName === 'groundColor') {
return this.light.groundColor.getHex();
}
return 0;
}
updateBooleanParameter(parameterName: string, value: boolean): void {}
updateRotation() {
if (this.top === 'Z+') {
@@ -125,7 +98,7 @@ namespace gdjs {
this.rotationObject.rotation.y = -gdjs.toRad(this.elevation);
} else {
// 0° becomes a light from Z+.
this.rotationObject.rotation.y = gdjs.toRad(this.rotation - 90);
this.rotationObject.rotation.y = gdjs.toRad(this.rotation) - 90;
this.rotationObject.rotation.z = -gdjs.toRad(this.elevation);
}
}

View File

@@ -1,5 +1,4 @@
//@ts-check
/// <reference path="../JsExtensionTypes.d.ts" />
// @flow
/**
* This is a declaration of an extension for GDevelop 5.
*
@@ -13,9 +12,18 @@
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
*/
/** @type {ExtensionModule} */
/*::
// Import types to allow Flow to do static type checking on this file.
// Extensions declaration are typed using Flow (like the editor), but the files
// for the game engine are checked with TypeScript annotations.
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
*/
module.exports = {
createExtension: function (_, gd) {
createExtension: function (
_ /*: (string) => string */,
gd /*: libGDevelop */
) {
const extension = new gd.PlatformExtension();
extension
.setExtensionInformation(
@@ -56,7 +64,7 @@ module.exports = {
_('Position'),
'res/conditions/3d_box.svg'
)
.addParameter('object', _('3D object'), '', false)
.addParameter('object', _('3D object'))
.addParameter('behavior', _('Behavior'), 'Base3DBehavior')
.useStandardParameters('number', gd.ParameterOptions.makeNewOptions())
.setFunctionName('setZ')
@@ -72,7 +80,7 @@ module.exports = {
_('Position/Center'),
'res/conditions/3d_box.svg'
)
.addParameter('object', _('3D object'), '', false)
.addParameter('object', _('3D object'))
.addParameter('behavior', _('Behavior'), 'Base3DBehavior')
.useStandardParameters('number', gd.ParameterOptions.makeNewOptions())
.setFunctionName('setCenterZInScene')
@@ -88,7 +96,7 @@ module.exports = {
_('Size'),
'res/conditions/3d_box.svg'
)
.addParameter('object', _('3D object'), '', false)
.addParameter('object', _('3D object'))
.addParameter('behavior', _('Behavior'), 'Base3DBehavior')
.useStandardParameters('number', gd.ParameterOptions.makeNewOptions())
.setFunctionName('setDepth')
@@ -104,7 +112,7 @@ module.exports = {
_('Size'),
'res/conditions/3d_box.svg'
)
.addParameter('object', _('3D object'), '', false)
.addParameter('object', _('3D object'))
.addParameter('behavior', _('Behavior'), 'Base3DBehavior')
.useStandardParameters(
'number',
@@ -126,7 +134,7 @@ module.exports = {
'res/conditions/3d_box.svg',
'res/conditions/3d_box.svg'
)
.addParameter('object', _('3D object'), '', false)
.addParameter('object', _('3D object'))
.addParameter('behavior', _('Behavior'), 'Base3DBehavior')
.addParameter('yesorno', _('Activate flipping'))
.markAsSimple()
@@ -142,7 +150,7 @@ module.exports = {
'res/conditions/3d_box.svg',
'res/conditions/3d_box.svg'
)
.addParameter('object', _('3D object'), '', false)
.addParameter('object', _('3D object'))
.addParameter('behavior', _('Behavior'), 'Base3DBehavior')
.setFunctionName('isFlippedZ');
@@ -156,7 +164,7 @@ module.exports = {
_('Angle'),
'res/conditions/3d_box.svg'
)
.addParameter('object', _('3D object'), '', false)
.addParameter('object', _('3D object'))
.addParameter('behavior', _('Behavior'), 'Base3DBehavior')
.useStandardParameters('number', gd.ParameterOptions.makeNewOptions())
.setFunctionName('setRotationX')
@@ -172,7 +180,7 @@ module.exports = {
_('Angle'),
'res/conditions/3d_box.svg'
)
.addParameter('object', _('3D object'), '', false)
.addParameter('object', _('3D object'))
.addParameter('behavior', _('Behavior'), 'Base3DBehavior')
.useStandardParameters('number', gd.ParameterOptions.makeNewOptions())
.setFunctionName('setRotationY')
@@ -190,7 +198,7 @@ module.exports = {
'res/conditions/3d_box.svg',
'res/conditions/3d_box.svg'
)
.addParameter('object', _('3D object'), '', false)
.addParameter('object', _('3D object'))
.addParameter('behavior', _('Behavior'), 'Base3DBehavior')
.addParameter('number', _('Rotation angle'), '', false)
.markAsAdvanced()
@@ -208,7 +216,7 @@ module.exports = {
'res/conditions/3d_box.svg',
'res/conditions/3d_box.svg'
)
.addParameter('object', _('3D object'), '', false)
.addParameter('object', _('3D object'))
.addParameter('behavior', _('Behavior'), 'Base3DBehavior')
.addParameter('number', _('Rotation angle'), '', false)
.markAsAdvanced()
@@ -226,7 +234,7 @@ module.exports = {
'res/conditions/3d_box.svg',
'res/conditions/3d_box.svg'
)
.addParameter('object', _('3D object'), '', false)
.addParameter('object', _('3D object'))
.addParameter('behavior', _('Behavior'), 'Base3DBehavior')
.addParameter('number', _('Rotation angle'), '', false)
.markAsAdvanced()
@@ -239,7 +247,7 @@ module.exports = {
'Model3DObject',
_('3D Model'),
_('An animated 3D model.'),
'JsPlatform/Extensions/3d_model.svg',
'JsPlatform/Extensions/3d_box.svg',
new gd.Model3DObjectConfiguration()
)
.setCategoryFullName(_('General'))
@@ -493,7 +501,7 @@ module.exports = {
'res/actions/flipX24.png',
'res/actions/flipX.png'
)
.addParameter('object', _('3D model'), 'Model3DObject', false)
.addParameter('object', _('3D model'), 'Model3DObject')
.addParameter('yesorno', _('Activate flipping'))
.setHidden()
.markAsSimple()
@@ -510,7 +518,7 @@ module.exports = {
'res/actions/flipY24.png',
'res/actions/flipY.png'
)
.addParameter('object', _('3D model'), 'Model3DObject', false)
.addParameter('object', _('3D model'), 'Model3DObject')
.addParameter('yesorno', _('Activate flipping'))
.setHidden()
.markAsSimple()
@@ -527,7 +535,7 @@ module.exports = {
'res/conditions/3d_box.svg',
'res/conditions/3d_box.svg'
)
.addParameter('object', _('3D model'), 'Model3DObject', false)
.addParameter('object', _('3D model'), 'Model3DObject')
.addParameter('yesorno', _('Activate flipping'))
.markAsSimple()
.setHidden()
@@ -544,7 +552,7 @@ module.exports = {
'res/actions/flipX24.png',
'res/actions/flipX.png'
)
.addParameter('object', _('3D model'), 'Model3DObject', false)
.addParameter('object', _('3D model'), 'Model3DObject')
.setHidden()
.setFunctionName('isFlippedX');
@@ -559,7 +567,7 @@ module.exports = {
'res/actions/flipY24.png',
'res/actions/flipY.png'
)
.addParameter('object', _('3D model'), 'Model3DObject', false)
.addParameter('object', _('3D model'), 'Model3DObject')
.setHidden()
.setFunctionName('isFlippedY');
@@ -574,7 +582,7 @@ module.exports = {
'res/conditions/3d_box.svg',
'res/conditions/3d_box.svg'
)
.addParameter('object', _('3D model'), 'Model3DObject', false)
.addParameter('object', _('3D model'), 'Model3DObject')
.setHidden()
.setFunctionName('isFlippedZ');
@@ -682,7 +690,7 @@ module.exports = {
_('Animations and images'),
'res/actions/animation24.png'
)
.addParameter('object', _('3D model'), 'Model3DObject', false)
.addParameter('object', _('3D model'), 'Model3DObject')
.useStandardParameters('number', gd.ParameterOptions.makeNewOptions())
.markAsSimple()
.setHidden()
@@ -700,7 +708,7 @@ module.exports = {
_('Animations and images'),
'res/actions/animation24.png'
)
.addParameter('object', _('3D model'), 'Model3DObject', false)
.addParameter('object', _('3D model'), 'Model3DObject')
.useStandardParameters(
'objectAnimationName',
gd.ParameterOptions.makeNewOptions().setDescription(
@@ -723,7 +731,7 @@ module.exports = {
'res/actions/animation24.png',
'res/actions/animation.png'
)
.addParameter('object', _('3D model'), 'Model3DObject', false)
.addParameter('object', _('3D model'), 'Model3DObject')
.markAsSimple()
.setHidden()
.setFunctionName('pauseAnimation');
@@ -739,7 +747,7 @@ module.exports = {
'res/actions/animation24.png',
'res/actions/animation.png'
)
.addParameter('object', _('3D model'), 'Model3DObject', false)
.addParameter('object', _('3D model'), 'Model3DObject')
.markAsSimple()
.setHidden()
.setFunctionName('resumeAnimation');
@@ -757,7 +765,7 @@ module.exports = {
_('Animations and images'),
'res/actions/animation24.png'
)
.addParameter('object', _('3D model'), 'Model3DObject', false)
.addParameter('object', _('3D model'), 'Model3DObject')
.useStandardParameters(
'number',
gd.ParameterOptions.makeNewOptions().setDescription(_('Speed scale'))
@@ -778,7 +786,7 @@ module.exports = {
'res/conditions/animation24.png',
'res/conditions/animation.png'
)
.addParameter('object', _('3D model'), 'Model3DObject', false)
.addParameter('object', _('3D model'), 'Model3DObject')
.markAsSimple()
.setHidden()
.setFunctionName('isAnimationPaused');
@@ -796,13 +804,14 @@ module.exports = {
'res/conditions/animation24.png',
'res/conditions/animation.png'
)
.addParameter('object', _('3D model'), 'Model3DObject', false)
.addParameter('object', _('3D model'), 'Model3DObject')
.markAsSimple()
.setHidden()
.setFunctionName('hasAnimationEnded');
}
const Cube3DObject = new gd.ObjectJsImplementation();
// $FlowExpectedError - ignore Flow warning as we're creating an object
Cube3DObject.updateProperty = function (
objectContent,
propertyName,
@@ -851,6 +860,7 @@ module.exports = {
return false;
};
// $FlowExpectedError - ignore Flow warning as we're creating an object
Cube3DObject.getProperties = function (objectContent) {
const objectProperties = new gd.MapStringPropertyDescriptor();
@@ -1090,6 +1100,7 @@ module.exports = {
})
);
// $FlowExpectedError
Cube3DObject.updateInitialInstanceProperty = function (
objectContent,
instance,
@@ -1101,6 +1112,7 @@ module.exports = {
return false;
};
// $FlowExpectedError
Cube3DObject.getInitialInstanceProperties = function (
content,
instance,
@@ -1352,7 +1364,7 @@ module.exports = {
'res/actions/flipX24.png',
'res/actions/flipX.png'
)
.addParameter('object', _('3D cube'), 'Cube3DObject', false)
.addParameter('object', _('3D cube'), 'Cube3DObject')
.addParameter('yesorno', _('Activate flipping'))
.markAsSimple()
.setHidden()
@@ -1369,7 +1381,7 @@ module.exports = {
'res/actions/flipY24.png',
'res/actions/flipY.png'
)
.addParameter('object', _('3D cube'), 'Cube3DObject', false)
.addParameter('object', _('3D cube'), 'Cube3DObject')
.addParameter('yesorno', _('Activate flipping'))
.markAsSimple()
.setHidden()
@@ -1386,7 +1398,7 @@ module.exports = {
'res/conditions/3d_box.svg',
'res/conditions/3d_box.svg'
)
.addParameter('object', _('3D cube'), 'Cube3DObject', false)
.addParameter('object', _('3D cube'), 'Cube3DObject')
.addParameter('yesorno', _('Activate flipping'))
.markAsSimple()
.setHidden()
@@ -1403,7 +1415,7 @@ module.exports = {
'res/actions/flipX24.png',
'res/actions/flipX.png'
)
.addParameter('object', _('3D cube'), 'Cube3DObject', false)
.addParameter('object', _('3D cube'), 'Cube3DObject')
.setHidden()
.setFunctionName('isFlippedX');
@@ -1418,7 +1430,7 @@ module.exports = {
'res/actions/flipY24.png',
'res/actions/flipY.png'
)
.addParameter('object', _('3D cube'), 'Cube3DObject', false)
.addParameter('object', _('3D cube'), 'Cube3DObject')
.setHidden()
.setFunctionName('isFlippedY');
@@ -1433,7 +1445,7 @@ module.exports = {
'res/conditions/3d_box.svg',
'res/conditions/3d_box.svg'
)
.addParameter('object', _('3D cube'), 'Cube3DObject', false)
.addParameter('object', _('3D cube'), 'Cube3DObject')
.setHidden()
.setFunctionName('isFlippedZ');
@@ -1653,7 +1665,7 @@ module.exports = {
'Change the camera rotation to look at an object. The camera top always face the screen.'
),
_('Change the camera rotation of _PARAM2_ to look at _PARAM1_'),
_('Layers and cameras'),
_("Layers and cameras"),
'res/conditions/3d_box.svg',
'res/conditions/3d_box.svg'
)
@@ -1942,7 +1954,10 @@ module.exports = {
* But it is recommended to create tests for the behaviors/objects properties you created
* to avoid mistakes.
*/
runExtensionSanityTests: function (gd, extension) {
runExtensionSanityTests: function (
gd /*: libGDevelop */,
extension /*: gdPlatformExtension*/
) {
return [];
},
/**
@@ -1950,13 +1965,17 @@ module.exports = {
*
* Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
*/
registerEditorConfigurations: function (objectsEditorService) {},
registerEditorConfigurations: function (
objectsEditorService /*: ObjectsEditorService */
) {},
/**
* Register renderers for instance of objects on the scene editor.
*
* Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
*/
registerInstanceRenderers: function (objectsRenderingService) {
registerInstanceRenderers: function (
objectsRenderingService /*: ObjectsRenderingService */
) {
const RenderedInstance = objectsRenderingService.RenderedInstance;
const Rendered3DInstance = objectsRenderingService.Rendered3DInstance;
const PIXI = objectsRenderingService.PIXI;
@@ -1964,25 +1983,39 @@ module.exports = {
const THREE_ADDONS = objectsRenderingService.THREE_ADDONS;
const materialIndexToFaceIndex = {
// $FlowFixMe
0: 3,
// $FlowFixMe
1: 2,
// $FlowFixMe
2: 5,
// $FlowFixMe
3: 4,
// $FlowFixMe
4: 0,
// $FlowFixMe
5: 1,
};
const noRepeatTextureVertexIndexToUvMapping = {
// $FlowFixMe
0: [0, 0],
// $FlowFixMe
1: [1, 0],
// $FlowFixMe
2: [0, 1],
// $FlowFixMe
3: [1, 1],
};
const noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ = {
// $FlowFixMe
0: [0, 1],
// $FlowFixMe
1: [0, 0],
// $FlowFixMe
2: [1, 1],
// $FlowFixMe
3: [1, 0],
};
@@ -2662,7 +2695,7 @@ module.exports = {
}
static getThumbnail(project, resourcesLoader, objectConfiguration) {
return 'JsPlatform/Extensions/3d_model.svg';
return 'JsPlatform/Extensions/3d_box.svg';
}
getOriginX() {
@@ -2703,9 +2736,6 @@ module.exports = {
originalDepth,
keepAspectRatio
) {
// These formulas are also used in:
// - gdjs.Model3DRuntimeObject3DRenderer._updateDefaultTransformation
// - Model3DEditor.modelSize
threeObject.rotation.set(
(rotationX * Math.PI) / 180,
(rotationY * Math.PI) / 180,

View File

@@ -60,14 +60,6 @@ namespace gdjs {
this.fog.far = value;
}
}
getDoubleParameter(parameterName: string): number {
if (parameterName === 'near') {
return this.fog.near;
} else if (parameterName === 'far') {
return this.fog.far;
}
return 0;
}
updateStringParameter(parameterName: string, value: string): void {
if (parameterName === 'color') {
this.fog.color = new THREE.Color(
@@ -75,17 +67,6 @@ namespace gdjs {
);
}
}
updateColorParameter(parameterName: string, value: number): void {
if (parameterName === 'color') {
this.fog.color.setHex(value);
}
}
getColorParameter(parameterName: string): number {
if (parameterName === 'color') {
return this.fog.color.getHex();
}
return 0;
}
updateBooleanParameter(parameterName: string, value: boolean): void {}
})();
}

View File

@@ -113,6 +113,10 @@ namespace gdjs {
);
}
if (this.isNeedingLifecycleFunctions()) {
this.getLifecycleSleepState().wakeUp();
}
// *ALWAYS* call `this.onCreated()` at the very end of your object constructor.
this.onCreated();
}
@@ -194,6 +198,10 @@ namespace gdjs {
}
}
isNeedingLifecycleFunctions(): boolean {
return super.isNeedingLifecycleFunctions() || this._animations.length > 0;
}
update(instanceContainer: gdjs.RuntimeInstanceContainer): void {
const elapsedTime = this.getElapsedTime() / 1000;
this._renderer.updateAnimation(elapsedTime * this._animationSpeedScale);

View File

@@ -147,9 +147,6 @@ namespace gdjs {
originalDepth: float,
keepAspectRatio: boolean
) {
// These formulas are also used in:
// - Model3DEditor.modelSize
// - Model3DRendered2DInstance
threeObject.rotation.set(
gdjs.toRad(rotationX),
gdjs.toRad(rotationY),

View File

@@ -11,12 +11,7 @@ namespace gdjs {
const layer = runtimeScene.getLayer(layerName);
const layerRenderer = layer.getRenderer();
const threeCamera = layerRenderer.getThreeCamera();
const fov =
threeCamera instanceof THREE.OrthographicCamera
? null
: threeCamera
? threeCamera.fov
: assumedFovIn2D;
const fov = threeCamera ? threeCamera.fov : assumedFovIn2D;
return layer.getCameraZ(fov, cameraIndex);
};
@@ -29,12 +24,7 @@ namespace gdjs {
const layer = runtimeScene.getLayer(layerName);
const layerRenderer = layer.getRenderer();
const threeCamera = layerRenderer.getThreeCamera();
const fov =
threeCamera instanceof THREE.OrthographicCamera
? null
: threeCamera
? threeCamera.fov
: assumedFovIn2D;
const fov = threeCamera ? threeCamera.fov : assumedFovIn2D;
layer.setCameraZ(z, fov, cameraIndex);
};
@@ -223,10 +213,8 @@ namespace gdjs {
const layerRenderer = layer.getRenderer();
const threeCamera = layerRenderer.getThreeCamera();
if (!threeCamera) return assumedFovIn2D;
return threeCamera instanceof THREE.OrthographicCamera
? 0
: threeCamera.fov;
if (!threeCamera) return 45;
return threeCamera.fov;
};
export const setFov = (
@@ -239,8 +227,7 @@ namespace gdjs {
const layerRenderer = layer.getRenderer();
const threeCamera = layerRenderer.getThreeCamera();
if (!threeCamera || threeCamera instanceof THREE.OrthographicCamera)
return;
if (!threeCamera) return;
threeCamera.fov = Math.min(Math.max(angle, 0), 180);
layerRenderer.setThreeCameraDirty(true);

View File

@@ -1,5 +1,4 @@
//@ts-check
/// <reference path="../JsExtensionTypes.d.ts" />
// @flow
/**
* This is a declaration of an extension for GDevelop 5.
*
@@ -13,9 +12,18 @@
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
*/
/** @type {ExtensionModule} */
/*::
// Import types to allow Flow to do static type checking on this file.
// Extensions declaration are typed using Flow (like the editor), but the files
// for the game engine are checked with TypeScript annotations.
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
*/
module.exports = {
createExtension: function (_, gd) {
createExtension: function (
_ /*: (string) => string */,
gd /*: libGDevelop */
) {
const extension = new gd.PlatformExtension();
extension
.setExtensionInformation(
@@ -781,7 +789,10 @@ module.exports = {
return extension;
},
runExtensionSanityTests: function (gd, extension) {
runExtensionSanityTests: function (
gd /*: libGDevelop */,
extension /*: gdPlatformExtension*/
) {
return [];
},
};

View File

@@ -1,5 +1,4 @@
//@ts-check
/// <reference path="../JsExtensionTypes.d.ts" />
// @flow
/**
* This is a declaration of an extension for GDevelop 5.
*
@@ -13,9 +12,11 @@
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
*/
/** @type {ExtensionModule} */
module.exports = {
createExtension: function (_, gd) {
createExtension: function (
_ /*: (string) => string */,
gd /*: libGDevelop */
) {
const extension = new gd.PlatformExtension();
extension
.setExtensionInformation(
@@ -709,7 +710,10 @@ module.exports = {
return extension;
},
runExtensionSanityTests: function (gd, extension) {
runExtensionSanityTests: function (
gd /*: libGDevelop */,
extension /*: gdPlatformExtension*/
) {
return [];
},
};

View File

@@ -1,5 +1,4 @@
//@ts-check
/// <reference path="../JsExtensionTypes.d.ts" />
// @flow
/**
* This is a declaration of an extension for GDevelop 5.
*
@@ -13,11 +12,20 @@
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
*/
/*::
// Import types to allow Flow to do static type checking on this file.
// Extensions declaration are typed using Flow (like the editor), but the files
// for the game engine are checked with TypeScript annotations.
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
*/
const stringifyOptions = (options) => '["' + options.join('","') + '"]';
/** @type {ExtensionModule} */
module.exports = {
createExtension: function (_, gd) {
createExtension: function (
_ /*: (string) => string */,
gd /*: libGDevelop */
) {
const extension = new gd.PlatformExtension();
extension
.setExtensionInformation(
@@ -34,6 +42,7 @@ module.exports = {
.setIcon('JsPlatform/Extensions/bbcode32.png');
var objectBBText = new gd.ObjectJsImplementation();
// $FlowExpectedError
objectBBText.updateProperty = function (
objectContent,
propertyName,
@@ -50,6 +59,7 @@ module.exports = {
return false;
};
// $FlowExpectedError
objectBBText.getProperties = function (objectContent) {
const objectProperties = new gd.MapStringPropertyDescriptor();
@@ -127,6 +137,7 @@ module.exports = {
})
);
// $FlowExpectedError
objectBBText.updateInitialInstanceProperty = function (
objectContent,
instance,
@@ -137,6 +148,7 @@ module.exports = {
) {
return false;
};
// $FlowExpectedError
objectBBText.getInitialInstanceProperties = function (
content,
instance,
@@ -445,7 +457,10 @@ module.exports = {
* But it is recommended to create tests for the behaviors/objects properties you created
* to avoid mistakes.
*/
runExtensionSanityTests: function (gd, extension) {
runExtensionSanityTests: function (
gd /*: libGDevelop */,
extension /*: gdPlatformExtension*/
) {
return [];
},
/**
@@ -453,7 +468,9 @@ module.exports = {
*
* Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
*/
registerEditorConfigurations: function (objectsEditorService) {
registerEditorConfigurations: function (
objectsEditorService /*: ObjectsEditorService */
) {
objectsEditorService.registerEditorConfiguration(
'BBText::BBText',
objectsEditorService.getDefaultObjectJsImplementationPropertiesEditor({
@@ -466,7 +483,9 @@ module.exports = {
*
* Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
*/
registerInstanceRenderers: function (objectsRenderingService) {
registerInstanceRenderers: function (
objectsRenderingService /*: ObjectsRenderingService */
) {
const RenderedInstance = objectsRenderingService.RenderedInstance;
const PIXI = objectsRenderingService.PIXI;
const MultiStyleText = objectsRenderingService.requireModule(

View File

@@ -1,5 +1,4 @@
//@ts-check
/// <reference path="../JsExtensionTypes.d.ts" />
// @flow
/**
* This is a declaration of an extension for GDevelop 5.
*
@@ -13,9 +12,18 @@
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
*/
/** @type {ExtensionModule} */
/*::
// Import types to allow Flow to do static type checking on this file.
// Extensions declaration are typed using Flow (like the editor), but the files
// for the game engine are checked with TypeScript annotations.
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
*/
module.exports = {
createExtension: function (_, gd) {
createExtension: function (
_ /*: (string) => string */,
gd /*: libGDevelop */
) {
const extension = new gd.PlatformExtension();
extension
.setExtensionInformation(
@@ -34,6 +42,7 @@ module.exports = {
.setIcon('JsPlatform/Extensions/bitmapfont32.png');
const bitmapTextObject = new gd.ObjectJsImplementation();
// $FlowExpectedError
bitmapTextObject.updateProperty = function (
objectContent,
propertyName,
@@ -50,6 +59,7 @@ module.exports = {
return false;
};
// $FlowExpectedError
bitmapTextObject.getProperties = function (objectContent) {
const objectProperties = new gd.MapStringPropertyDescriptor();
@@ -129,6 +139,7 @@ module.exports = {
})
);
// $FlowExpectedError
bitmapTextObject.updateInitialInstanceProperty = function (
objectContent,
instance,
@@ -139,6 +150,7 @@ module.exports = {
) {
return false;
};
// $FlowExpectedError
bitmapTextObject.getInitialInstanceProperties = function (
content,
instance,
@@ -164,7 +176,7 @@ module.exports = {
'Extensions/BitmapText/bitmaptextruntimeobject-pixi-renderer.js'
)
.setCategoryFullName(_('Text'))
.addDefaultBehavior('TextContainerCapability::TextContainerBehavior')
.addDefaultBehavior("TextContainerCapability::TextContainerBehavior")
.addDefaultBehavior('EffectCapability::EffectBehavior')
.addDefaultBehavior('OpacityCapability::OpacityBehavior')
.addDefaultBehavior('ScalableCapability::ScalableBehavior');
@@ -315,33 +327,33 @@ module.exports = {
.getCodeExtraInformation()
.setFunctionName('setBitmapFontAndTextureAtlasResourceName');
object
.addAction(
'SetBitmapFontAndTextureAtlasResourceName2',
_('Bitmap files resources'),
_('Change the Bitmap Font and/or the atlas image used by the object.'),
_(
'Set the bitmap font of _PARAM0_ to _PARAM1_ and the atlas to _PARAM2_'
),
'',
'res/actions/font24.png',
'res/actions/font.png'
)
.addParameter('object', _('Bitmap text'), 'BitmapTextObject', false)
.addParameter(
'bitmapFontResource',
_('Bitmap font resource name'),
'',
false
)
.addParameter(
'imageResource',
_('Texture atlas resource name'),
'',
false
)
.getCodeExtraInformation()
.setFunctionName('setBitmapFontAndTextureAtlasResourceName');
object
.addAction(
'SetBitmapFontAndTextureAtlasResourceName2',
_('Bitmap files resources'),
_('Change the Bitmap Font and/or the atlas image used by the object.'),
_(
'Set the bitmap font of _PARAM0_ to _PARAM1_ and the atlas to _PARAM2_'
),
'',
'res/actions/font24.png',
'res/actions/font.png'
)
.addParameter('object', _('Bitmap text'), 'BitmapTextObject', false)
.addParameter(
'bitmapFontResource',
_('Bitmap font resource name'),
'',
false
)
.addParameter(
'imageResource',
_('Texture atlas resource name'),
'',
false
)
.getCodeExtraInformation()
.setFunctionName('setBitmapFontAndTextureAtlasResourceName');
object
.addExpressionAndCondition(
@@ -439,7 +451,10 @@ module.exports = {
* But it is recommended to create tests for the behaviors/objects properties you created
* to avoid mistakes.
*/
runExtensionSanityTests: function (gd, extension) {
runExtensionSanityTests: function (
gd /*: libGDevelop */,
extension /*: gdPlatformExtension*/
) {
return [];
},
/**
@@ -447,7 +462,9 @@ module.exports = {
*
* Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
*/
registerEditorConfigurations: function (objectsEditorService) {
registerEditorConfigurations: function (
objectsEditorService /*: ObjectsEditorService */
) {
objectsEditorService.registerEditorConfiguration(
'BitmapText::BitmapTextObject',
objectsEditorService.getDefaultObjectJsImplementationPropertiesEditor({
@@ -460,7 +477,9 @@ module.exports = {
*
* Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change.
*/
registerInstanceRenderers: function (objectsRenderingService) {
registerInstanceRenderers: function (
objectsRenderingService /*: ObjectsRenderingService */
) {
const RenderedInstance = objectsRenderingService.RenderedInstance;
const PIXI = objectsRenderingService.PIXI;

View File

@@ -26,7 +26,6 @@ set(
TextEntryObject
TextObject
TiledSpriteObject
Spine
TopDownMovementBehavior)
# Automatically add all listed extensions

View File

@@ -1,5 +1,4 @@
//@ts-check
/// <reference path="../JsExtensionTypes.d.ts" />
// @flow
/**
* This is a declaration of an extension for GDevelop 5.
*
@@ -13,9 +12,18 @@
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
*/
/** @type {ExtensionModule} */
/*::
// Import types to allow Flow to do static type checking on this file.
// Extensions declaration are typed using Flow (like the editor), but the files
// for the game engine are checked with TypeScript annotations.
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
*/
module.exports = {
createExtension: function (_, gd) {
createExtension: function (
_ /*: (string) => string */,
gd /*: libGDevelop */
) {
const extension = new gd.PlatformExtension();
extension
.setExtensionInformation(
@@ -106,7 +114,10 @@ module.exports = {
return extension;
},
runExtensionSanityTests: function (gd, extension) {
runExtensionSanityTests: function (
gd /*: libGDevelop */,
extension /*: gdPlatformExtension*/
) {
return [];
},
};

View File

@@ -1,5 +1,4 @@
//@ts-check
/// <reference path="../JsExtensionTypes.d.ts" />
// @flow
/**
* This is a declaration of an extension for GDevelop 5.
*
@@ -13,389 +12,450 @@
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
*/
/** @type {ExtensionModule} */
/*::
// Import types to allow Flow to do static type checking on this file.
// Extensions declaration are typed using Flow (like the editor), but the files
// for the game engine are checked with TypeScript annotations.
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
*/
module.exports = {
createExtension: function (_, gd) {
createExtension: function(_/*: (string) => string */, gd/*: libGDevelop */) {
const extension = new gd.PlatformExtension();
extension
.setExtensionInformation(
'DeviceSensors',
_('Device sensors'),
_('Allow the game to access the sensors of a mobile device.'),
'Matthias Meike',
'Open source (MIT License)'
)
.setExtensionHelpPath('/all-features/device-sensors')
.setCategory('Input');
extension
.addInstructionOrExpressionGroupMetadata(_('Device sensors'))
.setIcon('JsPlatform/Extensions/orientation_active32.png');
extension.setExtensionInformation(
"DeviceSensors",
_("Device sensors"),
_(
"Allow the game to access the sensors of a mobile device."
),
"Matthias Meike",
"Open source (MIT License)"
).setExtensionHelpPath("/all-features/device-sensors")
.setCategory('Input');
extension.addInstructionOrExpressionGroupMetadata(_("Device sensors"))
.setIcon("JsPlatform/Extensions/orientation_active32.png");
extension
.addCondition(
'OrientationSensorActive',
_('Sensor active'),
"OrientationSensorActive",
_("Sensor active"),
_(
'The condition is true if the device orientation sensor is currently active'
"The condition is true if the device orientation sensor is currently active"
),
_('Orientation sensor is active'),
_('Orientation'),
'JsPlatform/Extensions/orientation_active32.png',
'JsPlatform/Extensions/orientation_active32.png'
_("Orientation sensor is active"),
_("Orientation"),
"JsPlatform/Extensions/orientation_active32.png",
"JsPlatform/Extensions/orientation_active32.png"
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.orientation.isActive');
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.orientation.isActive");
extension
extension
.addCondition(
'OrientationAlpha',
_('Compare the value of orientation alpha'),
_('Compare the value of orientation alpha. (Range: 0 to 360°)'),
_('the orientation alpha'),
_('Orientation'),
'JsPlatform/Extensions/orientation_alpha32.png',
'JsPlatform/Extensions/orientation_alpha32.png'
"OrientationAlpha",
_("Compare the value of orientation alpha"),
_(
"Compare the value of orientation alpha. (Range: 0 to 360°)"
),
_("the orientation alpha"),
_("Orientation"),
"JsPlatform/Extensions/orientation_alpha32.png",
"JsPlatform/Extensions/orientation_alpha32.png"
)
.addParameter('relationalOperator', _('Sign of the test'), 'number')
.addParameter('expression', _('Value'))
.addParameter("relationalOperator", _("Sign of the test"), "number")
.addParameter("expression", _("Value"))
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.orientation.getOrientationAlpha');
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.orientation.getOrientationAlpha");
extension
extension
.addCondition(
'OrientationBeta',
_('Compare the value of orientation beta'),
_('Compare the value of orientation beta. (Range: -180 to 180°)'),
_('the orientation beta'),
_('Orientation'),
'JsPlatform/Extensions/orientation_beta32.png',
'JsPlatform/Extensions/orientation_beta32.png'
"OrientationBeta",
_("Compare the value of orientation beta"),
_(
"Compare the value of orientation beta. (Range: -180 to 180°)"
),
_("the orientation beta"),
_("Orientation"),
"JsPlatform/Extensions/orientation_beta32.png",
"JsPlatform/Extensions/orientation_beta32.png"
)
.addParameter('relationalOperator', _('Sign of the test'), 'number')
.addParameter('expression', _('Value'))
.addParameter("relationalOperator", _("Sign of the test"), "number")
.addParameter("expression", _("Value"))
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.orientation.getOrientationBeta');
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.orientation.getOrientationBeta");
extension
extension
.addCondition(
'OrientationGamma',
_('Compare the value of orientation gamma'),
_('Compare the value of orientation gamma. (Range: -90 to 90°)'),
_('the orientation gamma'),
_('Orientation'),
'JsPlatform/Extensions/orientation_gamma32.png',
'JsPlatform/Extensions/orientation_gamma32.png'
"OrientationGamma",
_("Compare the value of orientation gamma"),
_(
"Compare the value of orientation gamma. (Range: -90 to 90°)"
),
_("the orientation gamma"),
_("Orientation"),
"JsPlatform/Extensions/orientation_gamma32.png",
"JsPlatform/Extensions/orientation_gamma32.png"
)
.addParameter('relationalOperator', _('Sign of the test'), 'number')
.addParameter('expression', _('Value'))
.addParameter("relationalOperator", _("Sign of the test"), "number")
.addParameter("expression", _("Value"))
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.orientation.getOrientationGamma');
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.orientation.getOrientationGamma");
extension
.addAction(
'ActivateOrientationListener',
_('Activate orientation sensor'),
_('Activate the orientation sensor. (remember to turn it off again)'),
_('Activate the orientation sensor.'),
_('Orientation'),
'JsPlatform/Extensions/orientation_active32.png',
'JsPlatform/Extensions/orientation_active32.png'
"ActivateOrientationListener",
_("Activate orientation sensor"),
_("Activate the orientation sensor. (remember to turn it off again)"),
_("Activate the orientation sensor."),
_("Orientation"),
"JsPlatform/Extensions/orientation_active32.png",
"JsPlatform/Extensions/orientation_active32.png"
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName(
'gdjs.deviceSensors.orientation.activateOrientationSensor'
);
.getCodeExtraInformation()
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.orientation.activateOrientationSensor");
extension
.addAction(
'DeactivateOrientationListener',
_('Deactivate orientation sensor'),
_('Deactivate the orientation sensor.'),
_('Deactivate the orientation sensor.'),
_('Orientation'),
'JsPlatform/Extensions/orientation_inactive32.png',
'JsPlatform/Extensions/orientation_inactive32.png'
"DeactivateOrientationListener",
_("Deactivate orientation sensor"),
_("Deactivate the orientation sensor."),
_("Deactivate the orientation sensor."),
_("Orientation"),
"JsPlatform/Extensions/orientation_inactive32.png",
"JsPlatform/Extensions/orientation_inactive32.png"
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName(
'gdjs.deviceSensors.orientation.deactivateOrientationSensor'
);
.getCodeExtraInformation()
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.orientation.deactivateOrientationSensor");
extension
.addExpression(
'OrientationAbsolute',
_('Is Absolute'),
_('Get if the devices orientation is absolute and not relative'),
_('Orientation'),
'JsPlatform/Extensions/orientation_absolute16.png'
"OrientationAbsolute",
_("Is Absolute"),
_("Get if the devices orientation is absolute and not relative"),
_("Orientation"),
"JsPlatform/Extensions/orientation_absolute16.png"
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.orientation.getOrientationAbsolute');
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.orientation.getOrientationAbsolute");
extension
.addExpression(
'OrientationAlpha',
_('Alpha value'),
_('Get the devices orientation Alpha (compass)'),
_('Orientation'),
'JsPlatform/Extensions/orientation_alpha16.png'
"OrientationAlpha",
_("Alpha value"),
_("Get the devices orientation Alpha (compass)"),
_("Orientation"),
"JsPlatform/Extensions/orientation_alpha16.png"
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.orientation.getOrientationAlpha');
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.orientation.getOrientationAlpha");
extension
.addExpression(
'OrientationBeta',
_('Beta value'),
_('Get the devices orientation Beta'),
_('Orientation'),
'JsPlatform/Extensions/orientation_beta16.png'
"OrientationBeta",
_("Beta value"),
_("Get the devices orientation Beta"),
_("Orientation"),
"JsPlatform/Extensions/orientation_beta16.png"
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.orientation.getOrientationBeta');
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.orientation.getOrientationBeta");
extension
.addExpression(
'OrientationGamma',
_('Gamma value'),
_('Get the devices orientation Gamma value'),
_('Orientation'),
'JsPlatform/Extensions/orientation_gamma16.png'
"OrientationGamma",
_("Gamma value"),
_("Get the devices orientation Gamma value"),
_("Orientation"),
"JsPlatform/Extensions/orientation_gamma16.png"
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.orientation.getOrientationGamma');
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.orientation.getOrientationGamma");
extension
extension
.addCondition(
'MotionSensorActive',
_('Sensor active'),
"MotionSensorActive",
_("Sensor active"),
_(
'The condition is true if the device motion sensor is currently active'
"The condition is true if the device motion sensor is currently active"
),
_('Motion sensor is active'),
_('Motion'),
'JsPlatform/Extensions/motion_active32.png',
'JsPlatform/Extensions/motion_active32.png'
_("Motion sensor is active"),
_("Motion"),
"JsPlatform/Extensions/motion_active32.png",
"JsPlatform/Extensions/motion_active32.png"
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.motion.isActive');
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.motion.isActive");
extension
extension
.addCondition(
'RotationAlpha',
_('Compare the value of rotation alpha'),
"RotationAlpha",
_("Compare the value of rotation alpha"),
_(
'Compare the value of rotation alpha. (Note: few devices support this sensor)'
"Compare the value of rotation alpha. (Note: few devices support this sensor)"
),
_('the rotation alpha'),
_('Motion'),
'JsPlatform/Extensions/motion_rotation_alpha32.png',
'JsPlatform/Extensions/motion_rotation_alpha32.png'
_("the rotation alpha"),
_("Motion"),
"JsPlatform/Extensions/motion_rotation_alpha32.png",
"JsPlatform/Extensions/motion_rotation_alpha32.png"
)
.addParameter('relationalOperator', _('Sign of the test'), 'number')
.addParameter('expression', _('Value (m/s²)'))
.addParameter("relationalOperator", _("Sign of the test"), "number")
.addParameter("expression", _("Value (m/s²)"))
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.motion.getRotationAlpha');
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.motion.getRotationAlpha");
extension
extension
.addCondition(
'RotationBeta',
_('Compare the value of rotation beta'),
"RotationBeta",
_("Compare the value of rotation beta"),
_(
'Compare the value of rotation beta. (Note: few devices support this sensor)'
"Compare the value of rotation beta. (Note: few devices support this sensor)"
),
_('the rotation beta'),
_('Motion'),
'JsPlatform/Extensions/motion_rotation_beta32.png',
'JsPlatform/Extensions/motion_rotation_beta32.png'
_("the rotation beta"),
_("Motion"),
"JsPlatform/Extensions/motion_rotation_beta32.png",
"JsPlatform/Extensions/motion_rotation_beta32.png"
)
.addParameter('relationalOperator', _('Sign of the test'), 'number')
.addParameter('expression', _('Value (m/s²)'))
.addParameter("relationalOperator", _("Sign of the test"), "number")
.addParameter("expression", _("Value (m/s²)"))
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.motion.getRotationBeta');
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.motion.getRotationBeta");
extension
extension
.addCondition(
'RotationGamma',
_('Compare the value of rotation gamma'),
"RotationGamma",
_("Compare the value of rotation gamma"),
_(
'Compare the value of rotation gamma. (Note: few devices support this sensor)'
"Compare the value of rotation gamma. (Note: few devices support this sensor)"
),
_('the rotation gamma'),
_('Motion'),
'JsPlatform/Extensions/motion_rotation_gamma32.png',
'JsPlatform/Extensions/motion_rotation_gamma32.png'
_("the rotation gamma"),
_("Motion"),
"JsPlatform/Extensions/motion_rotation_gamma32.png",
"JsPlatform/Extensions/motion_rotation_gamma32.png"
)
.addParameter('relationalOperator', _('Sign of the test'), 'number')
.addParameter('expression', _('Value (m/s²)'))
.addParameter("relationalOperator", _("Sign of the test"), "number")
.addParameter("expression", _("Value (m/s²)"))
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.motion.getRotationGamma');
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.motion.getRotationGamma");
extension
extension
.addCondition(
'AccelerationX',
_('Compare the value of acceleration on X-axis'),
_('Compare the value of acceleration on the X-axis (m/s²).'),
_('the acceleration X'),
_('Motion'),
'JsPlatform/Extensions/motion_acceleration_x32.png',
'JsPlatform/Extensions/motion_acceleration_x32.png'
"AccelerationX",
_("Compare the value of acceleration on X-axis"),
_(
"Compare the value of acceleration on the X-axis (m/s²)."
),
_("the acceleration X"),
_("Motion"),
"JsPlatform/Extensions/motion_acceleration_x32.png",
"JsPlatform/Extensions/motion_acceleration_x32.png"
)
.addParameter('relationalOperator', _('Sign of the test'), 'number')
.addParameter('expression', _('Value (m/s²)'))
.addParameter("relationalOperator", _("Sign of the test"), "number")
.addParameter("expression", _("Value (m/s²)"))
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.motion.getAccelerationX');
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.motion.getAccelerationX");
extension
extension
.addCondition(
'AccelerationY',
_('Compare the value of acceleration on Y-axis'),
_('Compare the value of acceleration on the Y-axis (m/s²).'),
_('the acceleration Y'),
_('Motion'),
'JsPlatform/Extensions/motion_acceleration_y32.png',
'JsPlatform/Extensions/motion_acceleration_y32.png'
"AccelerationY",
_("Compare the value of acceleration on Y-axis"),
_(
"Compare the value of acceleration on the Y-axis (m/s²)."
),
_("the acceleration Y"),
_("Motion"),
"JsPlatform/Extensions/motion_acceleration_y32.png",
"JsPlatform/Extensions/motion_acceleration_y32.png"
)
.addParameter('relationalOperator', _('Sign of the test'), 'number')
.addParameter('expression', _('Value (m/s²)'))
.addParameter("relationalOperator", _("Sign of the test"), "number")
.addParameter("expression", _("Value (m/s²)"))
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.motion.getAccelerationY');
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.motion.getAccelerationY");
extension
extension
.addCondition(
'AccelerationZ',
_('Compare the value of acceleration on Z-axis'),
_('Compare the value of acceleration on the Z-axis (m/s²).'),
_('the acceleration Z'),
_('Motion'),
'JsPlatform/Extensions/motion_acceleration_z32.png',
'JsPlatform/Extensions/motion_acceleration_z32.png'
"AccelerationZ",
_("Compare the value of acceleration on Z-axis"),
_(
"Compare the value of acceleration on the Z-axis (m/s²)."
),
_("the acceleration Z"),
_("Motion"),
"JsPlatform/Extensions/motion_acceleration_z32.png",
"JsPlatform/Extensions/motion_acceleration_z32.png"
)
.addParameter('relationalOperator', _('Sign of the test'), 'number')
.addParameter('expression', _('Value (m/s²)'))
.addParameter("relationalOperator", _("Sign of the test"), "number")
.addParameter("expression", _("Value (m/s²)"))
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.motion.getAccelerationZ');
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.motion.getAccelerationZ");
extension
.addAction(
'ActivateMotionListener',
_('Activate motion sensor'),
_('Activate the motion sensor. (remember to turn it off again)'),
_('Activate the motion sensor.'),
_('Motion'),
'JsPlatform/Extensions/motion_active32.png',
'JsPlatform/Extensions/motion_active32.png'
"ActivateMotionListener",
_("Activate motion sensor"),
_("Activate the motion sensor. (remember to turn it off again)"),
_("Activate the motion sensor."),
_("Motion"),
"JsPlatform/Extensions/motion_active32.png",
"JsPlatform/Extensions/motion_active32.png"
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.motion.activateMotionSensor');
.getCodeExtraInformation()
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.motion.activateMotionSensor");
extension
.addAction(
'DeactivateMotionListener',
_('Deactivate motion sensor'),
_('Deactivate the motion sensor.'),
_('Deactivate the motion sensor.'),
_('Motion'),
'JsPlatform/Extensions/motion_inactive32.png',
'JsPlatform/Extensions/motion_inactive32.png'
"DeactivateMotionListener",
_("Deactivate motion sensor"),
_("Deactivate the motion sensor."),
_("Deactivate the motion sensor."),
_("Motion"),
"JsPlatform/Extensions/motion_inactive32.png",
"JsPlatform/Extensions/motion_inactive32.png"
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.motion.deactivateMotionSensor');
.getCodeExtraInformation()
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.motion.deactivateMotionSensor");
extension
.addExpression(
'RotationAlpha',
_('Alpha value'),
_('Get the devices rotation Alpha'),
_('Motion'),
'JsPlatform/Extensions/motion_rotation_alpha16.png'
"RotationAlpha",
_("Alpha value"),
_("Get the devices rotation Alpha"),
_("Motion"),
"JsPlatform/Extensions/motion_rotation_alpha16.png"
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.motion.getRotationAlpha');
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.motion.getRotationAlpha");
extension
.addExpression(
'RotationBeta',
_('Beta value'),
_('Get the devices rotation Beta'),
_('Motion'),
'JsPlatform/Extensions/motion_rotation_beta16.png'
"RotationBeta",
_("Beta value"),
_("Get the devices rotation Beta"),
_("Motion"),
"JsPlatform/Extensions/motion_rotation_beta16.png"
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.motion.getRotationBeta');
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.motion.getRotationBeta");
extension
.addExpression(
'RotationGamma',
_('Gamma value'),
_('Get the devices rotation Gamma'),
_('Motion'),
'JsPlatform/Extensions/motion_rotation_gamma16.png'
"RotationGamma",
_("Gamma value"),
_("Get the devices rotation Gamma"),
_("Motion"),
"JsPlatform/Extensions/motion_rotation_gamma16.png"
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.motion.getRotationGamma');
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.motion.getRotationGamma");
extension
extension
.addExpression(
'AccelerationX',
_('Acceleration X value'),
_('Get the devices acceleration on the X-axis (m/s²)'),
_('Motion'),
'JsPlatform/Extensions/motion_acceleration_x16.png'
"AccelerationX",
_("Acceleration X value"),
_("Get the devices acceleration on the X-axis (m/s²)"),
_("Motion"),
"JsPlatform/Extensions/motion_acceleration_x16.png"
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.motion.getAccelerationX');
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.motion.getAccelerationX");
extension
extension
.addExpression(
'AccelerationY',
_('Acceleration Y value'),
_('Get the devices acceleration on the Y-axis (m/s²)'),
_('Motion'),
'JsPlatform/Extensions/motion_acceleration_y16.png'
"AccelerationY",
_("Acceleration Y value"),
_("Get the devices acceleration on the Y-axis (m/s²)"),
_("Motion"),
"JsPlatform/Extensions/motion_acceleration_y16.png"
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.motion.getAccelerationY');
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.motion.getAccelerationY");
extension
extension
.addExpression(
'AccelerationZ',
_('Acceleration Z value'),
_('Get the devices acceleration on the Z-axis (m/s²)'),
_('Motion'),
'JsPlatform/Extensions/motion_acceleration_z16.png'
"AccelerationZ",
_("Acceleration Z value"),
_("Get the devices acceleration on the Z-axis (m/s²)"),
_("Motion"),
"JsPlatform/Extensions/motion_acceleration_z16.png"
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/DeviceSensors/devicesensortools.js')
.setFunctionName('gdjs.deviceSensors.motion.getAccelerationZ');
.setIncludeFile(
"Extensions/DeviceSensors/devicesensortools.js"
)
.setFunctionName("gdjs.deviceSensors.motion.getAccelerationZ");
return extension;
},
runExtensionSanityTests: function (gd, extension) {
return [];
},
runExtensionSanityTests: function(gd /*: libGDevelop */, extension /*: gdPlatformExtension*/) { return []; },
};

View File

@@ -1,5 +1,4 @@
//@ts-check
/// <reference path="../JsExtensionTypes.d.ts" />
// @flow
/**
* This is a declaration of an extension for GDevelop 5.
*
@@ -13,9 +12,18 @@
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
*/
/** @type {ExtensionModule} */
/*::
// Import types to allow Flow to do static type checking on this file.
// Extensions declaration are typed using Flow (like the editor), but the files
// for the game engine are checked with TypeScript annotations.
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
*/
module.exports = {
createExtension: function (_, gd) {
createExtension: function (
_ /*: (string) => string */,
gd /*: libGDevelop */
) {
const extension = new gd.PlatformExtension();
extension
.setExtensionInformation(
@@ -28,9 +36,8 @@ module.exports = {
)
.setExtensionHelpPath('/all-features/device-vibration')
.setCategory('User interface');
extension
.addInstructionOrExpressionGroupMetadata(_('Device vibration'))
.setIcon('JsPlatform/Extensions/vibration_start32.png');
extension.addInstructionOrExpressionGroupMetadata(_("Device vibration"))
.setIcon("JsPlatform/Extensions/vibration_start32.png");
extension
.addDependency()
@@ -92,7 +99,10 @@ module.exports = {
return extension;
},
runExtensionSanityTests: function (gd, extension) {
runExtensionSanityTests: function (
gd /*: libGDevelop */,
extension /*: gdPlatformExtension*/
) {
return [];
},
};

View File

@@ -1,5 +1,4 @@
//@ts-check
/// <reference path="../JsExtensionTypes.d.ts" />
// @flow
/**
* This is a declaration of an extension for GDevelop 5.
*
@@ -13,9 +12,18 @@
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
*/
/** @type {ExtensionModule} */
/*::
// Import types to allow Flow to do static type checking on this file.
// Extensions declaration are typed using Flow (like the editor), but the files
// for the game engine are checked with TypeScript annotations.
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
*/
module.exports = {
createExtension: function (_, gd) {
createExtension: function (
_ /*: (string) => string */,
gd /*: libGDevelop */
) {
const extension = new gd.PlatformExtension();
extension
.setExtensionInformation(
@@ -713,7 +721,10 @@ module.exports = {
return extension;
},
runExtensionSanityTests: function (gd, extension) {
runExtensionSanityTests: function (
gd /*: libGDevelop */,
extension /*: gdPlatformExtension*/
) {
return [];
},
};

View File

@@ -1,5 +1,4 @@
//@ts-check
/// <reference path="../JsExtensionTypes.d.ts" />
// @flow
/**
* This is a declaration of an extension for GDevelop 5.
*
@@ -13,20 +12,28 @@
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
*/
/** @type {ExtensionModule} */
/*::
// Import types to allow Flow to do static type checking on this file.
// Extensions declaration are typed using Flow (like the editor), but the files
// for the game engine are checked with TypeScript annotations.
import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'
*/
module.exports = {
createExtension: function (_, gd) {
createExtension: function (
_ /*: (string) => string */,
gd /*: libGDevelop */
) {
const extension = new gd.PlatformExtension();
extension
.setExtensionInformation(
'Effects',
'Effects',
'Lots of different effects to be used in your game.',
'Various contributors from PixiJS, PixiJS filters and GDevelop',
'MIT'
)
.setCategory('Visual effect')
.setExtensionHelpPath('/interface/scene-editor/layer-effects');
extension.setExtensionInformation(
'Effects',
'Effects',
'Lots of different effects to be used in your game.',
'Various contributors from PixiJS, PixiJS filters and GDevelop',
'MIT'
)
.setCategory('Visual effect')
.setExtensionHelpPath('/interface/scene-editor/layer-effects');
// You can declare an effect here. Please order the effects by alphabetical order.
// This file is for common effects that are well-known/"battle-tested". If you have an
@@ -223,11 +230,7 @@ module.exports = {
const blurEffect = extension
.addEffect('Blur')
.setFullName(_('Blur (Gaussian, slow - prefer to use Kawase blur)'))
.setDescription(
_(
'Blur the rendered image. This is slow, so prefer to use Kawase blur in most cases.'
)
)
.setDescription(_('Blur the rendered image. This is slow, so prefer to use Kawase blur in most cases.'))
.markAsOnlyWorkingFor2D()
.addIncludeFile('Extensions/Effects/blur-pixi-filter.js');
const blurProperties = blurEffect.getProperties();
@@ -725,11 +728,13 @@ module.exports = {
const hslAdjustmentEffect = extension
.addEffect('HslAdjustment')
.setFullName(_('HSL Adjustment'))
.setDescription(_('Adjust hue, saturation and lightness.'))
.markAsOnlyWorkingFor2D()
.addIncludeFile(
'Extensions/Effects/pixi-filters/filter-hsl-adjustment.js'
.setDescription(
_(
'Adjust hue, saturation and lightness.'
)
)
.markAsOnlyWorkingFor2D()
.addIncludeFile('Extensions/Effects/pixi-filters/filter-hsl-adjustment.js')
.addIncludeFile('Extensions/Effects/hsl-adjustment-pixi-filter.js');
const hslAdjustmentProperties = hslAdjustmentEffect.getProperties();
hslAdjustmentProperties
@@ -762,9 +767,7 @@ module.exports = {
.addEffect('KawaseBlur')
.setFullName(_('Blur (Kawase, fast)'))
.setDescription(
_(
'Blur the rendered image, with much better performance than Gaussian blur.'
)
_('Blur the rendered image, with much better performance than Gaussian blur.')
)
.markAsOnlyWorkingFor2D()
.addIncludeFile('Extensions/Effects/pixi-filters/filter-kawase-blur.js')
@@ -813,7 +816,9 @@ module.exports = {
const motionBlurEffect = extension
.addEffect('MotionBlur')
.setFullName(_('Motion Blur'))
.setDescription(_('Blur the rendered image to give a feeling of speed.'))
.setDescription(
_('Blur the rendered image to give a feeling of speed.')
)
.markAsOnlyWorkingFor2D()
.addIncludeFile('Extensions/Effects/pixi-filters/filter-motion-blur.js')
.addIncludeFile('Extensions/Effects/motion-blur-pixi-filter.js');
@@ -1169,9 +1174,7 @@ module.exports = {
.setValue('0')
.setLabel(_('Elapsed time'))
.setType('number')
.setDescription(
'It can be set back to 0 to play the shockwave animation again.'
);
.setDescription('It can be set back to 0 to play the shockwave animation again.');
shockwaveEffectProperties
.getOrCreate('speed')
.setValue('500')
@@ -1308,7 +1311,10 @@ module.exports = {
return extension;
},
runExtensionSanityTests: function (gd, extension) {
runExtensionSanityTests: function (
gd /*: libGDevelop */,
extension /*: gdPlatformExtension*/
) {
return [];
},
};

View File

@@ -31,47 +31,11 @@ namespace gdjs {
adjustmentFilter.alpha = value;
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const adjustmentFilter = (filter as unknown) as PIXI.filters.AdjustmentFilter;
if (parameterName === 'gamma') {
return adjustmentFilter.gamma;
}
if (parameterName === 'saturation') {
return adjustmentFilter.saturation;
}
if (parameterName === 'contrast') {
return adjustmentFilter.contrast;
}
if (parameterName === 'brightness') {
return adjustmentFilter.brightness;
}
if (parameterName === 'red') {
return adjustmentFilter.red;
}
if (parameterName === 'green') {
return adjustmentFilter.green;
}
if (parameterName === 'blue') {
return adjustmentFilter.blue;
}
if (parameterName === 'alpha') {
return adjustmentFilter.alpha;
}
return 0;
}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateColorParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
): void {}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
return 0;
}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,

View File

@@ -27,41 +27,11 @@ namespace gdjs {
advancedBloomFilter.padding = value;
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const advancedBloomFilter = (filter as unknown) as PIXI.filters.AdvancedBloomFilter;
if (parameterName === 'threshold') {
return advancedBloomFilter.threshold;
}
if (parameterName === 'bloomScale') {
return advancedBloomFilter.bloomScale;
}
if (parameterName === 'brightness') {
return advancedBloomFilter.brightness;
}
if (parameterName === 'blur') {
return advancedBloomFilter.blur;
}
if (parameterName === 'quality') {
return advancedBloomFilter.quality;
}
if (parameterName === 'padding') {
return advancedBloomFilter.padding;
}
return 0;
}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateColorParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
): void {}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
return 0;
}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,

View File

@@ -17,26 +17,11 @@ namespace gdjs {
asciiFilter.size = value;
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const asciiFilter = (filter as unknown) as PIXI.filters.AsciiFilter;
if (parameterName === 'size') {
return asciiFilter.size;
}
return 0;
}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateColorParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
): void {}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
return 0;
}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,

View File

@@ -1,8 +1,4 @@
namespace gdjs {
interface BevelFilterExtra {
/** It's defined for the configuration but not for the filter. */
distance: number;
}
gdjs.PixiFiltersTools.registerFilterCreator(
'Bevel',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
@@ -16,13 +12,13 @@ namespace gdjs {
parameterName: string,
value: number
) {
const bevelFilter = (filter as unknown) as PIXI.filters.BevelFilter &
BevelFilterExtra;
const bevelFilter = (filter as unknown) as PIXI.filters.BevelFilter;
if (parameterName === 'rotation') {
bevelFilter.rotation = value;
} else if (parameterName === 'thickness') {
bevelFilter.thickness = value;
} else if (parameterName === 'distance') {
// @ts-ignore
bevelFilter.distance = value;
} else if (parameterName === 'lightAlpha') {
bevelFilter.lightAlpha = value;
@@ -30,33 +26,12 @@ namespace gdjs {
bevelFilter.shadowAlpha = value;
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const bevelFilter = (filter as unknown) as PIXI.filters.BevelFilter &
BevelFilterExtra;
if (parameterName === 'rotation') {
return bevelFilter.rotation;
}
if (parameterName === 'thickness') {
return bevelFilter.thickness;
}
if (parameterName === 'distance') {
return bevelFilter.distance;
}
if (parameterName === 'lightAlpha') {
return bevelFilter.lightAlpha;
}
if (parameterName === 'shadowAlpha') {
return bevelFilter.shadowAlpha;
}
return 0;
}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {
const bevelFilter = (filter as unknown) as PIXI.filters.BevelFilter &
BevelFilterExtra;
const bevelFilter = (filter as unknown) as PIXI.filters.BevelFilter;
if (parameterName === 'lightColor') {
bevelFilter.lightColor = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(
value
@@ -68,30 +43,6 @@ namespace gdjs {
);
}
}
updateColorParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
): void {
const bevelFilter = (filter as unknown) as PIXI.filters.BevelFilter &
BevelFilterExtra;
if (parameterName === 'lightColor') {
bevelFilter.lightColor = value;
}
if (parameterName === 'shadowColor') {
bevelFilter.shadowColor = value;
}
}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
const bevelFilter = (filter as unknown) as PIXI.filters.BevelFilter;
if (parameterName === 'lightColor') {
return bevelFilter.lightColor;
}
if (parameterName === 'shadowColor') {
return bevelFilter.shadowColor;
}
return 0;
}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,

View File

@@ -19,26 +19,11 @@ namespace gdjs {
}
colorMatrix.alpha = gdjs.PixiFiltersTools.clampValue(value, 0, 1);
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const colorMatrix = (filter as unknown) as PIXI.ColorMatrixFilter;
if (parameterName === 'opacity') {
return colorMatrix.alpha;
}
return 0;
}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateColorParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
): void {}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
return 0;
}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,

View File

@@ -19,29 +19,11 @@ namespace gdjs {
blendingModeFilter.blendMode = value;
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const blendingModeFilter = (filter as unknown) as PIXI.AlphaFilter;
if (parameterName === 'alpha') {
return blendingModeFilter.alpha;
}
if (parameterName === 'blendmode') {
return blendingModeFilter.blendMode;
}
return 0;
}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateColorParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
): void {}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
return 0;
}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,

View File

@@ -25,22 +25,11 @@ namespace gdjs {
}
filter[parameterName] = value;
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
return filter[parameterName] || 0;
}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateColorParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
): void {}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
return 0;
}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,

View File

@@ -1,8 +1,4 @@
namespace gdjs {
interface BrightnessFilterExtra {
/** It allows to get back the value as the filter uses a matrix. */
__brightness: number;
}
gdjs.PixiFiltersTools.registerFilterCreator(
'Brightness',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
@@ -17,36 +13,20 @@ namespace gdjs {
parameterName: string,
value: number
) {
const brightnessFilter = (filter as unknown) as PIXI.ColorMatrixFilter &
BrightnessFilterExtra;
const brightnessFilter = (filter as unknown) as PIXI.ColorMatrixFilter;
if (parameterName !== 'brightness') {
return;
}
const brightness = gdjs.PixiFiltersTools.clampValue(value, 0, 1);
brightnessFilter.__brightness = brightness;
brightnessFilter.brightness(brightness, false);
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const brightnessFilter = (filter as unknown) as PIXI.ColorMatrixFilter &
BrightnessFilterExtra;
if (parameterName === 'brightness') {
return brightnessFilter.__brightness;
}
return 0;
brightnessFilter.brightness(
gdjs.PixiFiltersTools.clampValue(value, 0, 1),
false
);
}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateColorParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
): void {}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
return 0;
}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,

View File

@@ -27,35 +27,11 @@ namespace gdjs {
);
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const bulgePinchFilter = (filter as unknown) as PIXI.filters.BulgePinchFilter;
if (parameterName === 'centerX') {
return bulgePinchFilter.center[0];
}
if (parameterName === 'centerY') {
return bulgePinchFilter.center[1];
}
if (parameterName === 'radius') {
return bulgePinchFilter.radius;
}
if (parameterName === 'strength') {
return bulgePinchFilter.strength;
}
return 0;
}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateColorParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
): void {}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
return 0;
}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,

View File

@@ -34,26 +34,11 @@ namespace gdjs {
);
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const colorMapFilter = (filter as unknown) as PIXI.filters.ColorMapFilter;
if (parameterName === 'mix') {
return colorMapFilter.mix;
}
return 0;
}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateColorParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
): void {}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
return 0;
}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,

View File

@@ -1,10 +1,4 @@
namespace gdjs {
interface ColorReplaceFilterExtra {
/** It's only set to a number. */
originalColor: number;
/** It's only set to a number. */
newColor: number;
}
gdjs.PixiFiltersTools.registerFilterCreator(
'ColorReplace',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
@@ -18,27 +12,17 @@ namespace gdjs {
parameterName: string,
value: number
) {
const colorReplaceFilter = (filter as unknown) as PIXI.filters.ColorReplaceFilter &
ColorReplaceFilterExtra;
const colorReplaceFilter = (filter as unknown) as PIXI.filters.ColorReplaceFilter;
if (parameterName === 'epsilon') {
colorReplaceFilter.epsilon = value;
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const colorReplaceFilter = (filter as unknown) as PIXI.filters.ColorReplaceFilter &
ColorReplaceFilterExtra;
if (parameterName === 'epsilon') {
return colorReplaceFilter.epsilon;
}
return 0;
}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {
const colorReplaceFilter = (filter as unknown) as PIXI.filters.ColorReplaceFilter &
ColorReplaceFilterExtra;
const colorReplaceFilter = (filter as unknown) as PIXI.filters.ColorReplaceFilter;
if (parameterName === 'originalColor') {
colorReplaceFilter.originalColor = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(
value
@@ -49,29 +33,6 @@ namespace gdjs {
);
}
}
updateColorParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
): void {
const colorReplaceFilter = (filter as unknown) as PIXI.filters.ColorReplaceFilter &
ColorReplaceFilterExtra;
if (parameterName === 'originalColor') {
colorReplaceFilter.originalColor = value;
} else if (parameterName === 'newColor') {
colorReplaceFilter.newColor = value;
}
}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
const colorReplaceFilter = (filter as unknown) as PIXI.filters.ColorReplaceFilter &
ColorReplaceFilterExtra;
if (parameterName === 'originalColor') {
return colorReplaceFilter.originalColor;
} else if (parameterName === 'newColor') {
return colorReplaceFilter.newColor;
}
return 0;
}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,

View File

@@ -1,32 +1,25 @@
// @ts-nocheck - TODO: fix typings in this file
namespace gdjs {
interface CRTFilterExtra {
_animationTimer: number;
animationSpeed: number;
animationFrequency: number;
}
gdjs.PixiFiltersTools.registerFilterCreator(
'CRT',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(layer, effectData) {
const filter = new PIXI.filters.CRTFilter();
const crtFilter = (filter as unknown) as PIXI.filters.CRTFilter &
CRTFilterExtra;
const crtFilter = new PIXI.filters.CRTFilter();
crtFilter._animationTimer = 0;
return crtFilter;
}
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {
const crtFilter = (filter as unknown) as PIXI.filters.CRTFilter &
CRTFilterExtra;
if (crtFilter.animationSpeed !== 0) {
if (filter.animationSpeed !== 0) {
// Multiply by 10 so that the default value is a sensible speed
crtFilter.time +=
(target.getElapsedTime() / 1000) * 10 * crtFilter.animationSpeed;
filter.time +=
(target.getElapsedTime() / 1000) * 10 * filter.animationSpeed;
}
if (crtFilter.animationFrequency !== 0) {
crtFilter._animationTimer += target.getElapsedTime() / 1000;
if (crtFilter._animationTimer >= 1 / crtFilter.animationFrequency) {
crtFilter.seed = Math.random();
crtFilter._animationTimer = 0;
if (filter.animationFrequency !== 0) {
filter._animationTimer += target.getElapsedTime() / 1000;
if (filter._animationTimer >= 1 / filter.animationFrequency) {
filter.seed = Math.random();
filter._animationTimer = 0;
}
}
}
@@ -35,91 +28,42 @@ namespace gdjs {
parameterName: string,
value: number
) {
const crtFilter = (filter as unknown) as PIXI.filters.CRTFilter &
CRTFilterExtra;
if (parameterName === 'lineWidth') {
crtFilter.lineWidth = value;
filter.lineWidth = value;
} else if (parameterName === 'lineContrast') {
crtFilter.lineContrast = value;
filter.lineContrast = value;
} else if (parameterName === 'noise') {
crtFilter.noise = value;
filter.noise = value;
} else if (parameterName === 'curvature') {
crtFilter.curvature = value;
filter.curvature = value;
} else if (parameterName === 'noiseSize') {
crtFilter.noiseSize = value;
filter.noiseSize = value;
} else if (parameterName === 'vignetting') {
crtFilter.vignetting = value;
filter.vignetting = value;
} else if (parameterName === 'vignettingAlpha') {
crtFilter.vignettingAlpha = value;
filter.vignettingAlpha = value;
} else if (parameterName === 'vignettingBlur') {
crtFilter.vignettingBlur = value;
filter.vignettingBlur = value;
} else if (parameterName === 'animationSpeed') {
crtFilter.animationSpeed = value;
filter.animationSpeed = value;
} else if (parameterName === 'animationFrequency') {
crtFilter.animationFrequency = value;
filter.animationFrequency = value;
} else if (parameterName === 'padding') {
crtFilter.padding = value;
filter.padding = value;
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const crtFilter = (filter as unknown) as PIXI.filters.CRTFilter &
CRTFilterExtra;
if (parameterName === 'lineWidth') {
return crtFilter.lineWidth;
}
if (parameterName === 'lineContrast') {
return crtFilter.lineContrast;
}
if (parameterName === 'noise') {
return crtFilter.noise;
}
if (parameterName === 'curvature') {
return crtFilter.curvature;
}
if (parameterName === 'noiseSize') {
return crtFilter.noiseSize;
}
if (parameterName === 'vignetting') {
return crtFilter.vignetting;
}
if (parameterName === 'vignettingAlpha') {
return crtFilter.vignettingAlpha;
}
if (parameterName === 'vignettingBlur') {
return crtFilter.vignettingBlur;
}
if (parameterName === 'animationSpeed') {
return crtFilter.animationSpeed;
}
if (parameterName === 'animationFrequency') {
return crtFilter.animationFrequency;
}
if (parameterName === 'padding') {
return crtFilter.padding;
}
return 0;
}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateColorParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
): void {}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
return 0;
}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {
const crtFilter = (filter as unknown) as PIXI.filters.CRTFilter;
if (parameterName === 'verticalLine') {
crtFilter.verticalLine = value;
filter.verticalLine = value;
}
}
})()

View File

@@ -29,29 +29,11 @@ namespace gdjs {
displacementFilter.scale.y = value;
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const displacementFilter = (filter as unknown) as PIXI.DisplacementFilter;
if (parameterName === 'scaleX') {
return displacementFilter.scale.x;
}
if (parameterName === 'scaleY') {
return displacementFilter.scale.y;
}
return 0;
}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateColorParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
): void {}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
return 0;
}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,

View File

@@ -19,29 +19,11 @@ namespace gdjs {
dotFilter.angle = value;
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const dotFilter = (filter as unknown) as PIXI.filters.DotFilter;
if (parameterName === 'scale') {
return dotFilter.scale;
}
if (parameterName === 'angle') {
return dotFilter.angle;
}
return 0;
}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateColorParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
): void {}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
return 0;
}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,

View File

@@ -27,28 +27,6 @@ namespace gdjs {
dropShadowFilter.padding = value;
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const dropShadowFilter = (filter as unknown) as PIXI.filters.DropShadowFilter;
if (parameterName === 'blur') {
return dropShadowFilter.blur;
}
if (parameterName === 'quality') {
return dropShadowFilter.quality;
}
if (parameterName === 'alpha') {
return dropShadowFilter.alpha;
}
if (parameterName === 'distance') {
return dropShadowFilter.distance;
}
if (parameterName === 'rotation') {
return dropShadowFilter.rotation;
}
if (parameterName === 'padding') {
return dropShadowFilter.padding;
}
return 0;
}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
@@ -61,23 +39,6 @@ namespace gdjs {
);
}
}
updateColorParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
): void {
const dropShadowFilter = (filter as unknown) as PIXI.filters.DropShadowFilter;
if (parameterName === 'color') {
dropShadowFilter.color = value;
}
}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
const dropShadowFilter = (filter as unknown) as PIXI.filters.DropShadowFilter;
if (parameterName === 'color') {
return dropShadowFilter.color;
}
return 0;
}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,

View File

@@ -1,29 +1,20 @@
// @ts-nocheck - TODO: fix typings in this file
namespace gdjs {
interface GlitchFilterExtra {
_animationTimer: number;
animationFrequency: number;
}
gdjs.PixiFiltersTools.registerFilterCreator(
'Glitch',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(layer, effectData) {
const filter = new PIXI.filters.GlitchFilter();
const glitchFilter = (filter as unknown) as PIXI.filters.GlitchFilter &
GlitchFilterExtra;
const glitchFilter = new PIXI.filters.GlitchFilter();
glitchFilter._animationTimer = 0;
return glitchFilter;
}
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {
const glitchFilter = (filter as unknown) as PIXI.filters.GlitchFilter &
GlitchFilterExtra;
if (glitchFilter.animationFrequency !== 0) {
glitchFilter._animationTimer += target.getElapsedTime() / 1000;
if (
glitchFilter._animationTimer >=
1 / glitchFilter.animationFrequency
) {
glitchFilter.seed = Math.random();
glitchFilter._animationTimer = 0;
if (filter.animationFrequency !== 0) {
filter._animationTimer += target.getElapsedTime() / 1000;
if (filter._animationTimer >= 1 / filter.animationFrequency) {
filter.seed = Math.random();
filter._animationTimer = 0;
}
}
}
@@ -32,102 +23,46 @@ namespace gdjs {
parameterName: string,
value: number
) {
const glitchFilter = (filter as unknown) as PIXI.filters.GlitchFilter &
GlitchFilterExtra;
if (parameterName === 'slices') {
glitchFilter.slices = value;
filter.slices = value;
} else if (parameterName === 'offset') {
glitchFilter.offset = value;
filter.offset = value;
} else if (parameterName === 'direction') {
glitchFilter.direction = value;
filter.direction = value;
} else if (parameterName === 'fillMode') {
glitchFilter.fillMode = value;
filter.fillMode = value;
} else if (parameterName === 'minSize') {
glitchFilter.minSize = value;
filter.minSize = value;
} else if (parameterName === 'sampleSize') {
glitchFilter.sampleSize = value;
filter.sampleSize = value;
} else if (parameterName === 'redX') {
glitchFilter.red.x = value;
filter.red.x = value;
} else if (parameterName === 'redY') {
glitchFilter.red.y = value;
filter.red.y = value;
} else if (parameterName === 'greenX') {
glitchFilter.green.x = value;
filter.green.x = value;
} else if (parameterName === 'greenY') {
glitchFilter.green.y = value;
filter.green.y = value;
} else if (parameterName === 'blueX') {
glitchFilter.blue.x = value;
filter.blue.x = value;
} else if (parameterName === 'blueY') {
glitchFilter.blue.y = value;
filter.blue.y = value;
} else if (parameterName === 'animationFrequency') {
glitchFilter.animationFrequency = value;
filter.animationFrequency = value;
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const glitchFilter = (filter as unknown) as PIXI.filters.GlitchFilter &
GlitchFilterExtra;
if (parameterName === 'slices') {
return glitchFilter.slices;
}
if (parameterName === 'offset') {
return glitchFilter.offset;
}
if (parameterName === 'direction') {
return glitchFilter.direction;
}
if (parameterName === 'fillMode') {
return glitchFilter.fillMode;
}
if (parameterName === 'minSize') {
return glitchFilter.minSize;
}
if (parameterName === 'sampleSize') {
return glitchFilter.sampleSize;
}
if (parameterName === 'redX') {
return glitchFilter.red.x;
}
if (parameterName === 'redY') {
return glitchFilter.red.y;
}
if (parameterName === 'greenX') {
return glitchFilter.green.x;
}
if (parameterName === 'greenY') {
return glitchFilter.green.y;
}
if (parameterName === 'blueX') {
return glitchFilter.blue.x;
}
if (parameterName === 'blueY') {
return glitchFilter.blue.y;
}
if (parameterName === 'animationFrequency') {
return glitchFilter.animationFrequency;
}
return 0;
}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateColorParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
): void {}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
return 0;
}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {
const glitchFilter = (filter as unknown) as PIXI.filters.GlitchFilter &
GlitchFilterExtra;
if (parameterName === 'average') {
glitchFilter.average = value;
filter.average = value;
}
}
})()

View File

@@ -1,7 +1,4 @@
namespace gdjs {
interface GlowFilterExtra {
distance: number;
}
gdjs.PixiFiltersTools.registerFilterCreator(
'Glow',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
@@ -15,60 +12,26 @@ namespace gdjs {
parameterName: string,
value: number
) {
const glowFilter = (filter as unknown) as PIXI.filters.GlowFilter &
GlowFilterExtra;
const glowFilter = (filter as unknown) as PIXI.filters.GlowFilter;
if (parameterName === 'innerStrength') {
glowFilter.innerStrength = value;
} else if (parameterName === 'outerStrength') {
glowFilter.outerStrength = value;
} else if (parameterName === 'distance') {
// @ts-ignore
glowFilter.distance = value;
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const glowFilter = (filter as unknown) as PIXI.filters.GlowFilter &
GlowFilterExtra;
if (parameterName === 'innerStrength') {
return glowFilter.innerStrength;
}
if (parameterName === 'outerStrength') {
return glowFilter.outerStrength;
}
if (parameterName === 'distance') {
return glowFilter.distance;
}
return 0;
}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {
const glowFilter = (filter as unknown) as PIXI.filters.GlowFilter &
GlowFilterExtra;
const glowFilter = (filter as unknown) as PIXI.filters.GlowFilter;
if (parameterName === 'color') {
glowFilter.color = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
}
}
updateColorParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
): void {
const glowFilter = (filter as unknown) as PIXI.filters.GlowFilter &
GlowFilterExtra;
if (parameterName === 'color') {
glowFilter.color = value;
}
}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
const glowFilter = (filter as unknown) as PIXI.filters.GlowFilter &
GlowFilterExtra;
if (parameterName === 'color') {
return glowFilter.color;
}
return 0;
}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,

View File

@@ -1,10 +1,6 @@
// @ts-nocheck - TODO: fix typings in this file
namespace gdjs {
interface GodrayFilterExtra {
animationSpeed: number;
light: number;
x: number;
y: number;
}
gdjs.PixiFiltersTools.registerFilterCreator(
'Godray',
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
@@ -13,11 +9,9 @@ namespace gdjs {
return godrayFilter;
}
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {
const godrayFilter = (filter as unknown) as PIXI.filters.GodrayFilter &
GodrayFilterExtra;
if (godrayFilter.animationSpeed !== 0) {
godrayFilter.time +=
(target.getElapsedTime() / 1000) * godrayFilter.animationSpeed;
if (filter.animationSpeed !== 0) {
filter.time +=
(target.getElapsedTime() / 1000) * filter.animationSpeed;
}
}
updateDoubleParameter(
@@ -25,77 +19,36 @@ namespace gdjs {
parameterName: string,
value: number
) {
const godrayFilter = (filter as unknown) as PIXI.filters.GodrayFilter &
GodrayFilterExtra;
if (parameterName === 'lacunarity') {
godrayFilter.lacunarity = value;
filter.lacunarity = value;
} else if (parameterName === 'angle') {
godrayFilter.angle = value;
filter.angle = value;
} else if (parameterName === 'gain') {
godrayFilter.gain = value;
filter.gain = value;
} else if (parameterName === 'light') {
godrayFilter.light = value;
filter.light = value;
} else if (parameterName === 'x') {
godrayFilter.x = value;
filter.x = value;
} else if (parameterName === 'y') {
godrayFilter.y = value;
filter.y = value;
} else if (parameterName === 'animationSpeed') {
godrayFilter.animationSpeed = value;
filter.animationSpeed = value;
} else if (parameterName === 'padding') {
godrayFilter.padding = value;
filter.padding = value;
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const godrayFilter = (filter as unknown) as PIXI.filters.GodrayFilter &
GodrayFilterExtra;
if (parameterName === 'lacunarity') {
return godrayFilter.lacunarity;
}
if (parameterName === 'angle') {
return godrayFilter.angle;
}
if (parameterName === 'gain') {
return godrayFilter.gain;
}
if (parameterName === 'light') {
return godrayFilter.light;
}
if (parameterName === 'x') {
return godrayFilter.x;
}
if (parameterName === 'y') {
return godrayFilter.y;
}
if (parameterName === 'animationSpeed') {
return godrayFilter.animationSpeed;
}
if (parameterName === 'padding') {
return godrayFilter.padding;
}
return 0;
}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateColorParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
): void {}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
return 0;
}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,
value: boolean
) {
const godrayFilter = (filter as unknown) as PIXI.filters.GodrayFilter &
GodrayFilterExtra;
if (parameterName === 'parallel') {
godrayFilter.parallel = value;
filter.parallel = value;
}
}
})()

View File

@@ -23,35 +23,11 @@ namespace gdjs {
hslAdjustmentFilter.alpha = value;
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const hslAdjustmentFilter = filter as PIXI.filters.HslAdjustmentFilter;
if (parameterName === 'hue') {
return hslAdjustmentFilter.hue;
}
if (parameterName === 'saturation') {
return hslAdjustmentFilter.saturation;
}
if (parameterName === 'lightness') {
return hslAdjustmentFilter.lightness;
}
if (parameterName === 'alpha') {
return hslAdjustmentFilter.alpha;
}
return 0;
}
updateStringParameter(
filter: PIXI.Filter,
parameterName: string,
value: string
) {}
updateColorParameter(
filter: PIXI.Filter,
parameterName: string,
value: number
): void {}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
return 0;
}
updateBooleanParameter(
filter: PIXI.Filter,
parameterName: string,

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