mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
1 Commits
feat/touch
...
cursor/add
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1ec6ea68fe |
@@ -329,6 +329,7 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
|
||||
condition.SetParameters(parameters);
|
||||
}
|
||||
|
||||
gd::EventsCodeGenerator::CheckBehaviorParameters(condition, instrInfos);
|
||||
// Verify that there are no mismatches between object type in parameters.
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
|
||||
if (ParameterMetadata::IsObject(instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
@@ -356,11 +357,6 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
|
||||
}
|
||||
}
|
||||
}
|
||||
bool isAnyBehaviorMissing =
|
||||
gd::EventsCodeGenerator::CheckBehaviorParameters(condition, instrInfos);
|
||||
if (isAnyBehaviorMissing) {
|
||||
return "/* Missing behavior - skipped. */";
|
||||
}
|
||||
|
||||
if (instrInfos.IsObjectInstruction()) {
|
||||
gd::String objectName = condition.GetParameter(0).GetPlainString();
|
||||
@@ -492,16 +488,14 @@ gd::String EventsCodeGenerator::GenerateConditionsListCode(
|
||||
return outputCode;
|
||||
}
|
||||
|
||||
bool EventsCodeGenerator::CheckBehaviorParameters(
|
||||
void EventsCodeGenerator::CheckBehaviorParameters(
|
||||
const gd::Instruction &instruction,
|
||||
const gd::InstructionMetadata &instrInfos) {
|
||||
bool isAnyBehaviorMissing = false;
|
||||
gd::ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
gd::ParameterMetadataTools::IterateOverParameters(
|
||||
instruction.GetParameters(), instrInfos.parameters,
|
||||
[this, &isAnyBehaviorMissing,
|
||||
&instrInfos](const gd::ParameterMetadata ¶meterMetadata,
|
||||
const gd::Expression ¶meterValue, size_t parameterIndex,
|
||||
const gd::String &lastObjectName, size_t lastObjectIndex) {
|
||||
[this](const gd::ParameterMetadata ¶meterMetadata,
|
||||
const gd::Expression ¶meterValue,
|
||||
const gd::String &lastObjectName) {
|
||||
if (ParameterMetadata::IsBehavior(parameterMetadata.GetType())) {
|
||||
const gd::String &behaviorName = parameterValue.GetPlainString();
|
||||
const gd::String &actualBehaviorType =
|
||||
@@ -512,25 +506,13 @@ bool EventsCodeGenerator::CheckBehaviorParameters(
|
||||
|
||||
if (!expectedBehaviorType.empty() &&
|
||||
actualBehaviorType != expectedBehaviorType) {
|
||||
const auto &objectParameterMetadata =
|
||||
instrInfos.GetParameter(lastObjectIndex);
|
||||
// Event functions crash if some objects in a group are missing
|
||||
// the required behaviors, since they lose reference to the original
|
||||
// objects. Missing behaviors are considered "fatal" only for
|
||||
// ObjectList parameters, in order to minimize side effects on
|
||||
// built-in functions.
|
||||
if (objectParameterMetadata.GetType() == "objectList") {
|
||||
isAnyBehaviorMissing = true;
|
||||
}
|
||||
gd::ProjectDiagnostic projectDiagnostic(
|
||||
gd::ProjectDiagnostic::ErrorType::MissingBehavior, "",
|
||||
actualBehaviorType, expectedBehaviorType, lastObjectName);
|
||||
if (diagnosticReport)
|
||||
diagnosticReport->Add(projectDiagnostic);
|
||||
if (diagnosticReport) diagnosticReport->Add(projectDiagnostic);
|
||||
}
|
||||
}
|
||||
});
|
||||
return isAnyBehaviorMissing;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -570,6 +552,7 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
action.SetParameters(parameters);
|
||||
}
|
||||
|
||||
gd::EventsCodeGenerator::CheckBehaviorParameters(action, instrInfos);
|
||||
// Verify that there are no mismatches between object type in parameters.
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
|
||||
if (ParameterMetadata::IsObject(instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
@@ -596,11 +579,6 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
}
|
||||
}
|
||||
}
|
||||
bool isAnyBehaviorMissing =
|
||||
gd::EventsCodeGenerator::CheckBehaviorParameters(action, instrInfos);
|
||||
if (isAnyBehaviorMissing) {
|
||||
return "/* Missing behavior - skipped. */";
|
||||
}
|
||||
|
||||
// Call free function first if available
|
||||
if (instrInfos.IsObjectInstruction()) {
|
||||
@@ -791,7 +769,7 @@ gd::String EventsCodeGenerator::GenerateActionsListCode(
|
||||
} else {
|
||||
outputCode += actionCode;
|
||||
}
|
||||
outputCode += "}\n";
|
||||
outputCode += "}";
|
||||
}
|
||||
|
||||
return outputCode;
|
||||
|
@@ -837,7 +837,7 @@ protected:
|
||||
virtual gd::String GenerateGetBehaviorNameCode(
|
||||
const gd::String& behaviorName);
|
||||
|
||||
bool CheckBehaviorParameters(
|
||||
void CheckBehaviorParameters(
|
||||
const gd::Instruction &instruction,
|
||||
const gd::InstructionMetadata &instrInfos);
|
||||
|
||||
|
@@ -18,19 +18,19 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAnimatableExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("AnimatableCapability",
|
||||
_("Objects with animations"),
|
||||
_("Actions and conditions for objects having animations (sprite, 3D models...)."),
|
||||
_("Animate objects."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Objects with animations"))
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Animatable capability"))
|
||||
.SetIcon("res/actions/animation24.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Animations and images"))
|
||||
.SetIcon("res/actions/animation24.png");
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"AnimatableBehavior",
|
||||
_("Objects with animations"),
|
||||
_("Animatable capability"),
|
||||
"Animation",
|
||||
_("Actions and conditions for objects having animations (sprite, 3D models...).."),
|
||||
"",
|
||||
|
@@ -18,7 +18,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsEffectExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("EffectCapability",
|
||||
_("Objects with effects"),
|
||||
_("Effect capability"),
|
||||
_("Actions/conditions to enable/disable and change parameters of visual effects applied on objects."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
@@ -28,7 +28,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsEffectExtension(
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"EffectBehavior",
|
||||
_("Objects with effects"),
|
||||
_("Effect capability"),
|
||||
"Effect",
|
||||
_("Actions/conditions to enable/disable and change parameters of visual effects applied on objects."),
|
||||
"",
|
||||
|
@@ -18,7 +18,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFlippableExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("FlippableCapability",
|
||||
_("Flippable objects"),
|
||||
_("Flippable capability"),
|
||||
_("Actions/conditions for objects which can be flipped horizontally or vertically."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
@@ -28,7 +28,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFlippableExtension(
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"FlippableBehavior",
|
||||
_("Flippable objects"),
|
||||
_("Flippable capability"),
|
||||
"Flippable",
|
||||
_("Actions/conditions for objects which can be flipped horizontally or vertically."),
|
||||
"",
|
||||
|
@@ -18,13 +18,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsOpacityExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("OpacityCapability",
|
||||
_("Objects with opacity"),
|
||||
_("Opacity capability"),
|
||||
_("Action/condition/expression to change or "
|
||||
"check the opacity of an object (0-255)."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Objects with opacity"))
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Opacity capability"))
|
||||
.SetIcon("res/actions/opacity24.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Visibility"))
|
||||
.SetIcon("res/actions/opacity24.png");
|
||||
@@ -32,7 +32,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsOpacityExtension(
|
||||
gd::BehaviorMetadata& aut =
|
||||
extension
|
||||
.AddBehavior("OpacityBehavior",
|
||||
_("Objects with opacity"),
|
||||
_("Opacity capability"),
|
||||
"Opacity",
|
||||
_("Action/condition/expression to change or check the "
|
||||
"opacity of an object (0-255)."),
|
||||
|
@@ -18,7 +18,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsResizableExtension(
|
||||
extension
|
||||
.SetExtensionInformation(
|
||||
"ResizableCapability",
|
||||
_("Resizable objects"),
|
||||
_("Resizable capability"),
|
||||
_("Change or compare the size (width/height) of an object which can "
|
||||
"be resized (i.e: most objects)."),
|
||||
"Florian Rival",
|
||||
@@ -30,7 +30,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsResizableExtension(
|
||||
gd::BehaviorMetadata &aut =
|
||||
extension
|
||||
.AddBehavior("ResizableBehavior",
|
||||
_("Resizable objects"),
|
||||
_("Resizable capability"),
|
||||
"Resizable",
|
||||
_("Change or compare the size (width/height) of an "
|
||||
"object which can be resized (i.e: most objects)."),
|
||||
|
@@ -18,13 +18,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsScalableExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("ScalableCapability",
|
||||
_("Scalable objects"),
|
||||
_("Scalable capability"),
|
||||
_("Actions/conditions/expression to change or "
|
||||
"check the scale of an object (default: 1)."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Scalable objects"))
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Scalable capability"))
|
||||
.SetIcon("res/actions/scale24_black.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Size")).SetIcon(
|
||||
"res/actions/scale24_black.png");
|
||||
@@ -32,7 +32,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsScalableExtension(
|
||||
gd::BehaviorMetadata& aut =
|
||||
extension
|
||||
.AddBehavior("ScalableBehavior",
|
||||
_("Scalable objects"),
|
||||
_("Scalable capability"),
|
||||
"Scale",
|
||||
_("Actions/conditions/expression to change or check the "
|
||||
"scale of an object (default: 1)."),
|
||||
|
@@ -18,17 +18,17 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTextContainerExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("TextContainerCapability",
|
||||
_("Objects containing a text"),
|
||||
_("Text capability"),
|
||||
_("Allows an object to contain a text, usually shown on screen, that can be modified."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Objects containing a text"))
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Text capability"))
|
||||
.SetIcon("res/conditions/text24_black.png");
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"TextContainerBehavior",
|
||||
_("Objects containing a text"),
|
||||
_("Text capability"),
|
||||
"Text",
|
||||
_("Allows an object to contain a text, usually shown on screen, that can be modified."),
|
||||
"",
|
||||
|
@@ -52,25 +52,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
|
||||
.SetHidden();
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
"KeyFromTextPressed",
|
||||
_("Key pressed"),
|
||||
_("Check if a key is pressed. This stays true as long as "
|
||||
"the key is held down. To check if a key was pressed during "
|
||||
"the frame, use \"Key just pressed\" instead."),
|
||||
_("_PARAM1_ key is pressed"),
|
||||
"",
|
||||
"res/conditions/keyboard24.png",
|
||||
"res/conditions/keyboard.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("keyboardKey", _("Key to check"))
|
||||
.MarkAsSimple();
|
||||
|
||||
extension
|
||||
.AddCondition("KeyFromTextJustPressed",
|
||||
_("Key just pressed"),
|
||||
_("Check if a key was just pressed."),
|
||||
_("_PARAM1_ key was just pressed"),
|
||||
.AddCondition("KeyFromTextPressed",
|
||||
_("Key pressed"),
|
||||
_("Check if a key is pressed"),
|
||||
_("_PARAM1_ key is pressed"),
|
||||
"",
|
||||
"res/conditions/keyboard24.png",
|
||||
"res/conditions/keyboard.png")
|
||||
@@ -81,7 +66,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
|
||||
extension
|
||||
.AddCondition("KeyFromTextReleased",
|
||||
_("Key released"),
|
||||
_("Check if a key was just released."),
|
||||
_("Check if a key was just released"),
|
||||
_("_PARAM1_ key is released"),
|
||||
"",
|
||||
"res/conditions/keyboard24.png",
|
||||
|
@@ -298,19 +298,6 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the behavior can be used on objects from event-based objects.
|
||||
*/
|
||||
bool IsRelevantForChildObjects() const { return isRelevantForChildObjects; }
|
||||
|
||||
/**
|
||||
* Set that behavior can't be used on objects from event-based objects.
|
||||
*/
|
||||
BehaviorMetadata &MarkAsIrrelevantForChildObjects() {
|
||||
isRelevantForChildObjects = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
QuickCustomization::Visibility GetQuickCustomizationVisibility() const {
|
||||
return quickCustomizationVisibility;
|
||||
}
|
||||
@@ -406,7 +393,6 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
|
||||
mutable std::vector<gd::String> requiredBehaviors;
|
||||
bool isPrivate = false;
|
||||
bool isHidden = false;
|
||||
bool isRelevantForChildObjects = true;
|
||||
gd::String openFullEditorLabel;
|
||||
QuickCustomization::Visibility quickCustomizationVisibility = QuickCustomization::Visibility::Default;
|
||||
|
||||
|
@@ -277,10 +277,6 @@ class GD_CORE_API MetadataProvider {
|
||||
return &metadata == &badObjectInfo;
|
||||
}
|
||||
|
||||
static bool IsBadEffectMetadata(const gd::EffectMetadata& metadata) {
|
||||
return &metadata == &badEffectMetadata;
|
||||
}
|
||||
|
||||
virtual ~MetadataProvider();
|
||||
|
||||
private:
|
||||
|
@@ -194,8 +194,7 @@ void ParameterMetadataTools::IterateOverParameters(
|
||||
[&fn](const gd::ParameterMetadata& parameterMetadata,
|
||||
const gd::Expression& parameterValue,
|
||||
size_t parameterIndex,
|
||||
const gd::String& lastObjectName,
|
||||
size_t lastObjectIndex) {
|
||||
const gd::String& lastObjectName) {
|
||||
fn(parameterMetadata, parameterValue, lastObjectName);
|
||||
});
|
||||
}
|
||||
@@ -206,10 +205,8 @@ void ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
std::function<void(const gd::ParameterMetadata& parameterMetadata,
|
||||
const gd::Expression& parameterValue,
|
||||
size_t parameterIndex,
|
||||
const gd::String& lastObjectName,
|
||||
size_t lastObjectIndex)> fn) {
|
||||
const gd::String& lastObjectName)> fn) {
|
||||
gd::String lastObjectName = "";
|
||||
size_t lastObjectIndex = 0;
|
||||
for (std::size_t pNb = 0; pNb < parametersMetadata.GetParametersCount();
|
||||
++pNb) {
|
||||
const gd::ParameterMetadata ¶meterMetadata =
|
||||
@@ -221,17 +218,15 @@ void ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
? Expression(parameterMetadata.GetDefaultValue())
|
||||
: parameterValue;
|
||||
|
||||
fn(parameterMetadata, parameterValueOrDefault, pNb, lastObjectName, lastObjectIndex);
|
||||
fn(parameterMetadata, parameterValueOrDefault, pNb, lastObjectName);
|
||||
|
||||
// Memorize the last object name. By convention, parameters that require
|
||||
// an object (mainly, "objectvar" and "behavior") should be placed after
|
||||
// the object in the list of parameters (if possible, just after).
|
||||
// Search "lastObjectName" in the codebase for other place where this
|
||||
// convention is enforced.
|
||||
if (gd::ParameterMetadata::IsObject(parameterMetadata.GetType())) {
|
||||
if (gd::ParameterMetadata::IsObject(parameterMetadata.GetType()))
|
||||
lastObjectName = parameterValueOrDefault.GetPlainString();
|
||||
lastObjectIndex = pNb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -64,8 +64,7 @@ class GD_CORE_API ParameterMetadataTools {
|
||||
std::function<void(const gd::ParameterMetadata& parameterMetadata,
|
||||
const gd::Expression& parameterValue,
|
||||
size_t parameterIndex,
|
||||
const gd::String& lastObjectName,
|
||||
size_t lastObjectIndex)> fn);
|
||||
const gd::String& lastObjectName)> fn);
|
||||
|
||||
/**
|
||||
* Iterate over the parameters of a FunctionCallNode.
|
||||
|
@@ -813,13 +813,6 @@ gd::String PlatformExtension::GetObjectFullType(const gd::String& extensionName,
|
||||
return extensionName + separator + objectName;
|
||||
}
|
||||
|
||||
gd::String PlatformExtension::GetVariantFullType(const gd::String& extensionName,
|
||||
const gd::String& objectName,
|
||||
const gd::String& variantName) {
|
||||
const auto& separator = GetNamespaceSeparator();
|
||||
return extensionName + separator + objectName + separator + variantName;
|
||||
}
|
||||
|
||||
gd::String PlatformExtension::GetExtensionFromFullObjectType(
|
||||
const gd::String& type) {
|
||||
const auto separatorIndex =
|
||||
|
@@ -663,10 +663,6 @@ class GD_CORE_API PlatformExtension {
|
||||
static gd::String GetObjectFullType(const gd::String& extensionName,
|
||||
const gd::String& objectName);
|
||||
|
||||
static gd::String GetVariantFullType(const gd::String& extensionName,
|
||||
const gd::String& objectName,
|
||||
const gd::String& variantName);
|
||||
|
||||
static gd::String GetExtensionFromFullObjectType(const gd::String& type);
|
||||
|
||||
static gd::String GetObjectNameFromFullObjectType(const gd::String& type);
|
||||
|
@@ -29,7 +29,7 @@ bool BehaviorParametersFiller::DoVisitInstruction(gd::Instruction &instruction,
|
||||
instruction.GetParameters(), metadata.GetParameters(),
|
||||
[&](const gd::ParameterMetadata ¶meterMetadata,
|
||||
const gd::Expression ¶meterValue, size_t parameterIndex,
|
||||
const gd::String &lastObjectName, size_t lastObjectIndex) {
|
||||
const gd::String &lastObjectName) {
|
||||
if (parameterMetadata.GetValueTypeMetadata().IsBehavior() &&
|
||||
parameterValue.GetPlainString().length() == 0) {
|
||||
|
||||
|
@@ -108,10 +108,12 @@ bool EventsBehaviorRenamer::DoVisitInstruction(gd::Instruction& instruction,
|
||||
platform, instruction.GetType());
|
||||
|
||||
gd::ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
instruction.GetParameters(), metadata.GetParameters(),
|
||||
[&](const gd::ParameterMetadata ¶meterMetadata,
|
||||
const gd::Expression ¶meterValue, size_t parameterIndex,
|
||||
const gd::String &lastObjectName, size_t lastObjectIndex) {
|
||||
instruction.GetParameters(),
|
||||
metadata.GetParameters(),
|
||||
[&](const gd::ParameterMetadata& parameterMetadata,
|
||||
const gd::Expression& parameterValue,
|
||||
size_t parameterIndex,
|
||||
const gd::String& lastObjectName) {
|
||||
const gd::String& type = parameterMetadata.GetType();
|
||||
|
||||
if (gd::ParameterMetadata::IsBehavior(type)) {
|
||||
|
@@ -183,10 +183,12 @@ bool EventsParameterReplacer::DoVisitInstruction(gd::Instruction& instruction,
|
||||
platform, instruction.GetType());
|
||||
|
||||
gd::ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
instruction.GetParameters(), metadata.GetParameters(),
|
||||
[&](const gd::ParameterMetadata ¶meterMetadata,
|
||||
const gd::Expression ¶meterValue, size_t parameterIndex,
|
||||
const gd::String &lastObjectName, size_t lastObjectIndex) {
|
||||
instruction.GetParameters(),
|
||||
metadata.GetParameters(),
|
||||
[&](const gd::ParameterMetadata& parameterMetadata,
|
||||
const gd::Expression& parameterValue,
|
||||
size_t parameterIndex,
|
||||
const gd::String& lastObjectName) {
|
||||
if (!gd::EventsParameterReplacer::CanContainParameter(
|
||||
parameterMetadata.GetValueTypeMetadata())) {
|
||||
return;
|
||||
|
@@ -217,10 +217,12 @@ bool EventsPropertyReplacer::DoVisitInstruction(gd::Instruction& instruction,
|
||||
bool shouldDeleteInstruction = false;
|
||||
|
||||
gd::ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
instruction.GetParameters(), metadata.GetParameters(),
|
||||
[&](const gd::ParameterMetadata ¶meterMetadata,
|
||||
const gd::Expression ¶meterValue, size_t parameterIndex,
|
||||
const gd::String &lastObjectName, size_t lastObjectIndex) {
|
||||
instruction.GetParameters(),
|
||||
metadata.GetParameters(),
|
||||
[&](const gd::ParameterMetadata& parameterMetadata,
|
||||
const gd::Expression& parameterValue,
|
||||
size_t parameterIndex,
|
||||
const gd::String& lastObjectName) {
|
||||
if (!gd::EventsPropertyReplacer::CanContainProperty(
|
||||
parameterMetadata.GetValueTypeMetadata())) {
|
||||
return;
|
||||
|
@@ -334,7 +334,7 @@ private:
|
||||
instruction.GetParameters(), metadata.GetParameters(),
|
||||
[&](const gd::ParameterMetadata ¶meterMetadata,
|
||||
const gd::Expression ¶meterValue, size_t parameterIndex,
|
||||
const gd::String &lastObjectName, size_t lastObjectIndex) {
|
||||
const gd::String &lastObjectName) {
|
||||
if (!gd::EventsObjectReplacer::CanContainObject(
|
||||
parameterMetadata.GetValueTypeMetadata())) {
|
||||
return;
|
||||
|
@@ -42,16 +42,18 @@ bool EventsVariableInstructionTypeSwitcher::DoVisitInstruction(gd::Instruction&
|
||||
platform, instruction.GetType());
|
||||
|
||||
gd::ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
instruction.GetParameters(), metadata.GetParameters(),
|
||||
[&](const gd::ParameterMetadata ¶meterMetadata,
|
||||
const gd::Expression ¶meterValue, size_t parameterIndex,
|
||||
const gd::String &lastObjectName, size_t lastObjectIndex) {
|
||||
instruction.GetParameters(),
|
||||
metadata.GetParameters(),
|
||||
[&](const gd::ParameterMetadata& parameterMetadata,
|
||||
const gd::Expression& parameterValue,
|
||||
size_t parameterIndex,
|
||||
const gd::String& lastObjectName) {
|
||||
const gd::String& type = parameterMetadata.GetType();
|
||||
|
||||
if (!gd::ParameterMetadata::IsExpression("variable", type) ||
|
||||
!gd::VariableInstructionSwitcher::IsSwitchableVariableInstruction(
|
||||
instruction.GetType())) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
const auto variableName =
|
||||
gd::ExpressionVariableNameFinder::GetVariableName(
|
||||
@@ -70,11 +72,10 @@ bool EventsVariableInstructionTypeSwitcher::DoVisitInstruction(gd::Instruction&
|
||||
.GetObjectOrGroupVariablesContainer(lastObjectName);
|
||||
}
|
||||
} else if (type == "variableOrProperty") {
|
||||
variablesContainer =
|
||||
&GetProjectScopedContainers()
|
||||
.GetVariablesContainersList()
|
||||
.GetVariablesContainerFromVariableOrPropertyName(
|
||||
variableName);
|
||||
variablesContainer =
|
||||
&GetProjectScopedContainers()
|
||||
.GetVariablesContainersList()
|
||||
.GetVariablesContainerFromVariableOrPropertyName(variableName);
|
||||
} else {
|
||||
if (GetProjectScopedContainers().GetVariablesContainersList().Has(
|
||||
variableName)) {
|
||||
|
@@ -448,10 +448,12 @@ bool EventsVariableReplacer::DoVisitInstruction(gd::Instruction& instruction,
|
||||
bool shouldDeleteInstruction = false;
|
||||
|
||||
gd::ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
instruction.GetParameters(), metadata.GetParameters(),
|
||||
[&](const gd::ParameterMetadata ¶meterMetadata,
|
||||
const gd::Expression ¶meterValue, size_t parameterIndex,
|
||||
const gd::String &lastObjectName, size_t lastObjectIndex) {
|
||||
instruction.GetParameters(),
|
||||
metadata.GetParameters(),
|
||||
[&](const gd::ParameterMetadata& parameterMetadata,
|
||||
const gd::Expression& parameterValue,
|
||||
size_t parameterIndex,
|
||||
const gd::String& lastObjectName) {
|
||||
const gd::String& type = parameterMetadata.GetType();
|
||||
|
||||
if (!gd::ParameterMetadata::IsExpression("variable", type) &&
|
||||
|
@@ -150,7 +150,7 @@ bool ProjectElementRenamer::DoVisitInstruction(gd::Instruction &instruction,
|
||||
instruction.GetParameters(), metadata.GetParameters(),
|
||||
[&](const gd::ParameterMetadata ¶meterMetadata,
|
||||
const gd::Expression ¶meterValue, size_t parameterIndex,
|
||||
const gd::String &lastObjectName, size_t lastObjectIndex) {
|
||||
const gd::String &lastObjectName) {
|
||||
if (parameterMetadata.GetType() == "layer") {
|
||||
if (parameterValue.GetPlainString().length() < 2) {
|
||||
// This is either the base layer or an invalid layer name.
|
||||
|
@@ -1,23 +0,0 @@
|
||||
#include "UsedObjectTypeFinder.h"
|
||||
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/IDE/ProjectBrowserHelper.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
bool UsedObjectTypeFinder::ScanProject(gd::Project &project,
|
||||
const gd::String &objectType) {
|
||||
UsedObjectTypeFinder worker(project, objectType);
|
||||
gd::ProjectBrowserHelper::ExposeProjectObjects(project, worker);
|
||||
return worker.hasFoundObjectType;
|
||||
};
|
||||
|
||||
void UsedObjectTypeFinder::DoVisitObject(gd::Object &object) {
|
||||
if (!hasFoundObjectType && object.GetType() == objectType) {
|
||||
hasFoundObjectType = true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gd
|
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <set>
|
||||
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
|
||||
#include "GDCore/Extensions/Metadata/SourceFileMetadata.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
class Project;
|
||||
class Object;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
class GD_CORE_API UsedObjectTypeFinder : public ArbitraryObjectsWorker {
|
||||
public:
|
||||
static bool ScanProject(gd::Project &project, const gd::String &objectType);
|
||||
|
||||
private:
|
||||
UsedObjectTypeFinder(gd::Project &project_, const gd::String &objectType_)
|
||||
: project(project_), objectType(objectType_){};
|
||||
gd::Project &project;
|
||||
const gd::String &objectType;
|
||||
bool hasFoundObjectType = false;
|
||||
|
||||
// Object Visitor
|
||||
void DoVisitObject(gd::Object &object) override;
|
||||
};
|
||||
|
||||
}; // namespace gd
|
@@ -76,7 +76,6 @@ void ObjectAssetSerializer::SerializeTo(
|
||||
|
||||
double width = 0;
|
||||
double height = 0;
|
||||
std::unordered_set<gd::String> alreadyUsedVariantIdentifiers;
|
||||
if (project.HasEventsBasedObject(object.GetType())) {
|
||||
SerializerElement &variantsElement =
|
||||
objectAssetElement.AddChild("variants");
|
||||
@@ -88,6 +87,7 @@ void ObjectAssetSerializer::SerializeTo(
|
||||
height = variant->GetAreaMaxY() - variant->GetAreaMinY();
|
||||
}
|
||||
|
||||
std::unordered_set<gd::String> alreadyUsedVariantIdentifiers;
|
||||
gd::ObjectAssetSerializer::SerializeUsedVariantsTo(
|
||||
project, object, variantsElement, alreadyUsedVariantIdentifiers);
|
||||
}
|
||||
@@ -114,24 +114,14 @@ void ObjectAssetSerializer::SerializeTo(
|
||||
resourceElement.SetAttribute("name", resource.GetName());
|
||||
}
|
||||
|
||||
std::unordered_set<gd::String> usedExtensionNames;
|
||||
usedExtensionNames.insert(extensionName);
|
||||
for (auto &usedVariantIdentifier : alreadyUsedVariantIdentifiers) {
|
||||
usedExtensionNames.insert(PlatformExtension::GetExtensionFromFullObjectType(
|
||||
usedVariantIdentifier));
|
||||
}
|
||||
SerializerElement &requiredExtensionsElement =
|
||||
objectAssetElement.AddChild("requiredExtensions");
|
||||
requiredExtensionsElement.ConsiderAsArrayOf("requiredExtension");
|
||||
for (auto &usedExtensionName : usedExtensionNames) {
|
||||
if (project.HasEventsFunctionsExtensionNamed(usedExtensionName)) {
|
||||
auto &extension = project.GetEventsFunctionsExtension(usedExtensionName);
|
||||
SerializerElement &requiredExtensionElement =
|
||||
requiredExtensionsElement.AddChild("requiredExtension");
|
||||
requiredExtensionElement.SetAttribute("extensionName", usedExtensionName);
|
||||
requiredExtensionElement.SetAttribute("extensionVersion",
|
||||
extension.GetVersion());
|
||||
}
|
||||
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.
|
||||
|
@@ -227,11 +227,12 @@ bool ResourceWorkerInEventsWorker::DoVisitInstruction(gd::Instruction& instructi
|
||||
platform, instruction.GetType());
|
||||
|
||||
gd::ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
instruction.GetParameters(), metadata.GetParameters(),
|
||||
[this, &instruction](
|
||||
const gd::ParameterMetadata ¶meterMetadata,
|
||||
const gd::Expression ¶meterExpression, size_t parameterIndex,
|
||||
const gd::String &lastObjectName, size_t lastObjectIndex) {
|
||||
instruction.GetParameters(),
|
||||
metadata.GetParameters(),
|
||||
[this, &instruction](const gd::ParameterMetadata& parameterMetadata,
|
||||
const gd::Expression& parameterExpression,
|
||||
size_t parameterIndex,
|
||||
const gd::String& lastObjectName) {
|
||||
const String& parameterValue = parameterExpression.GetPlainString();
|
||||
if (parameterMetadata.GetType() == "fontResource") {
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
|
@@ -7,6 +7,7 @@
|
||||
#include <map>
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/IDE/AbstractFileSystem.h"
|
||||
#include "GDCore/IDE/Project/ResourcesAbsolutePathChecker.h"
|
||||
#include "GDCore/IDE/Project/ResourcesMergingHelper.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
@@ -25,37 +26,42 @@ bool ProjectResourcesCopier::CopyAllResourcesTo(
|
||||
bool preserveAbsoluteFilenames,
|
||||
bool preserveDirectoryStructure) {
|
||||
if (updateOriginalProject) {
|
||||
gd::ProjectResourcesCopier::AdaptFilePathsAndCopyAllResourcesTo(
|
||||
originalProject, fs, destinationDirectory, preserveAbsoluteFilenames,
|
||||
preserveDirectoryStructure);
|
||||
gd::ProjectResourcesCopier::CopyAllResourcesTo(
|
||||
originalProject, originalProject, fs, destinationDirectory,
|
||||
preserveAbsoluteFilenames, preserveDirectoryStructure);
|
||||
} else {
|
||||
gd::Project clonedProject = originalProject;
|
||||
gd::ProjectResourcesCopier::AdaptFilePathsAndCopyAllResourcesTo(
|
||||
clonedProject, fs, destinationDirectory, preserveAbsoluteFilenames,
|
||||
preserveDirectoryStructure);
|
||||
gd::ProjectResourcesCopier::CopyAllResourcesTo(
|
||||
originalProject, clonedProject, fs, destinationDirectory,
|
||||
preserveAbsoluteFilenames, preserveDirectoryStructure);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ProjectResourcesCopier::AdaptFilePathsAndCopyAllResourcesTo(
|
||||
gd::Project& project,
|
||||
bool ProjectResourcesCopier::CopyAllResourcesTo(
|
||||
gd::Project& originalProject,
|
||||
gd::Project& clonedProject,
|
||||
AbstractFileSystem& fs,
|
||||
gd::String destinationDirectory,
|
||||
bool preserveAbsoluteFilenames,
|
||||
bool preserveDirectoryStructure) {
|
||||
|
||||
auto projectDirectory = fs.DirNameFrom(project.GetProjectFile());
|
||||
// Check if there are some resources with absolute filenames
|
||||
gd::ResourcesAbsolutePathChecker absolutePathChecker(originalProject.GetResourcesManager(), fs);
|
||||
gd::ResourceExposer::ExposeWholeProjectResources(originalProject, absolutePathChecker);
|
||||
|
||||
auto projectDirectory = fs.DirNameFrom(originalProject.GetProjectFile());
|
||||
std::cout << "Copying all resources from " << projectDirectory << " to "
|
||||
<< destinationDirectory << "..." << std::endl;
|
||||
|
||||
// Get the resources to be copied
|
||||
gd::ResourcesMergingHelper resourcesMergingHelper(
|
||||
project.GetResourcesManager(), fs);
|
||||
clonedProject.GetResourcesManager(), fs);
|
||||
resourcesMergingHelper.SetBaseDirectory(projectDirectory);
|
||||
resourcesMergingHelper.PreserveDirectoriesStructure(
|
||||
preserveDirectoryStructure);
|
||||
resourcesMergingHelper.PreserveAbsoluteFilenames(preserveAbsoluteFilenames);
|
||||
gd::ResourceExposer::ExposeWholeProjectResources(project,
|
||||
gd::ResourceExposer::ExposeWholeProjectResources(clonedProject,
|
||||
resourcesMergingHelper);
|
||||
|
||||
// Copy resources
|
||||
|
@@ -50,10 +50,12 @@ class GD_CORE_API ProjectResourcesCopier {
|
||||
bool preserveDirectoryStructure = true);
|
||||
|
||||
private:
|
||||
static bool AdaptFilePathsAndCopyAllResourcesTo(
|
||||
gd::Project &project, gd::AbstractFileSystem &fs,
|
||||
gd::String destinationDirectory, bool preserveAbsoluteFilenames = true,
|
||||
bool preserveDirectoryStructure = true);
|
||||
static bool CopyAllResourcesTo(gd::Project& originalProject,
|
||||
gd::Project& clonedProject,
|
||||
gd::AbstractFileSystem& fs,
|
||||
gd::String destinationDirectory,
|
||||
bool preserveAbsoluteFilenames = true,
|
||||
bool preserveDirectoryStructure = true);
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
17
Core/GDCore/IDE/Project/ResourcesAbsolutePathChecker.cpp
Normal file
17
Core/GDCore/IDE/Project/ResourcesAbsolutePathChecker.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#include "ResourcesAbsolutePathChecker.h"
|
||||
#include "GDCore/IDE/AbstractFileSystem.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
void ResourcesAbsolutePathChecker::ExposeFile(gd::String& resourceFilename) {
|
||||
if (fs.IsAbsolute(resourceFilename)) hasAbsoluteFilenames = true;
|
||||
}
|
||||
|
||||
} // namespace gd
|
48
Core/GDCore/IDE/Project/ResourcesAbsolutePathChecker.h
Normal file
48
Core/GDCore/IDE/Project/ResourcesAbsolutePathChecker.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "GDCore/IDE/AbstractFileSystem.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Helper used to check if a project has at least a resource with an
|
||||
* absolute filename.
|
||||
*
|
||||
* \see ArbitraryResourceWorker
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class GD_CORE_API ResourcesAbsolutePathChecker
|
||||
: public ArbitraryResourceWorker {
|
||||
public:
|
||||
ResourcesAbsolutePathChecker(gd::ResourcesManager &resourcesManager,
|
||||
AbstractFileSystem &fileSystem)
|
||||
: ArbitraryResourceWorker(resourcesManager), hasAbsoluteFilenames(false),
|
||||
fs(fileSystem){};
|
||||
virtual ~ResourcesAbsolutePathChecker(){};
|
||||
|
||||
/**
|
||||
* Return true if there is at least a resource with an absolute filename.
|
||||
*/
|
||||
bool HasResourceWithAbsoluteFilenames() const {
|
||||
return hasAbsoluteFilenames;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if there is a resource with an absolute path
|
||||
*/
|
||||
virtual void ExposeFile(gd::String& resource);
|
||||
|
||||
private:
|
||||
bool hasAbsoluteFilenames;
|
||||
AbstractFileSystem& fs;
|
||||
};
|
||||
|
||||
} // namespace gd
|
@@ -22,14 +22,6 @@ void ResourcesMergingHelper::ExposeFile(gd::String& resourceFilename) {
|
||||
resourceFullFilename = gd::AbstractFileSystem::NormalizeSeparator(
|
||||
resourceFullFilename); // Protect against \ on Linux.
|
||||
|
||||
if (shouldUseOriginalAbsoluteFilenames) {
|
||||
// There is no need to fill `newFilenames` and `oldFilenames` since the file
|
||||
// location stays the same.
|
||||
fs.MakeAbsolute(resourceFullFilename, baseDirectory);
|
||||
resourceFilename = resourceFullFilename;
|
||||
return;
|
||||
}
|
||||
|
||||
// In the case of absolute filenames that we don't want to preserve, or
|
||||
// in the case of copying files without preserving relative folders, the new
|
||||
// names will be generated from the filename alone (with collision protection).
|
||||
|
@@ -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 RESOURCESMERGINGHELPER_H
|
||||
#define RESOURCESMERGINGHELPER_H
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@@ -57,15 +58,6 @@ public:
|
||||
preserveAbsoluteFilenames = preserveAbsoluteFilenames_;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Set if the absolute filenames of original files must be used for
|
||||
* any resource.
|
||||
*/
|
||||
void SetShouldUseOriginalAbsoluteFilenames(
|
||||
bool shouldUseOriginalAbsoluteFilenames_ = true) {
|
||||
shouldUseOriginalAbsoluteFilenames = shouldUseOriginalAbsoluteFilenames_;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Return a map containing the resources old absolute filename as key,
|
||||
* and the resources new filenames as value. The new filenames are relative to
|
||||
@@ -101,13 +93,10 @@ public:
|
||||
///< absolute (C:\MyFile.png will not be
|
||||
///< transformed into a relative filename
|
||||
///< (MyFile.png).
|
||||
/**
|
||||
* Set to true if the absolute filenames of original files must be used for
|
||||
* any resource.
|
||||
*/
|
||||
bool shouldUseOriginalAbsoluteFilenames = false;
|
||||
gd::AbstractFileSystem&
|
||||
fs; ///< The gd::AbstractFileSystem used to manipulate files.
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // RESOURCESMERGINGHELPER_H
|
||||
|
@@ -6,7 +6,6 @@
|
||||
#include "SceneResourcesFinder.h"
|
||||
|
||||
#include "GDCore/IDE/ResourceExposer.h"
|
||||
#include "GDCore/Project/EventsBasedObjectVariant.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
@@ -28,14 +27,6 @@ std::set<gd::String> SceneResourcesFinder::FindSceneResources(gd::Project &proje
|
||||
return resourceWorker.resourceNames;
|
||||
}
|
||||
|
||||
std::set<gd::String> SceneResourcesFinder::FindEventsBasedObjectVariantResources(gd::Project &project,
|
||||
gd::EventsBasedObjectVariant &variant) {
|
||||
gd::SceneResourcesFinder resourceWorker(project.GetResourcesManager());
|
||||
|
||||
gd::ResourceExposer::ExposeEventsBasedObjectVariantResources(project, variant, resourceWorker);
|
||||
return resourceWorker.resourceNames;
|
||||
}
|
||||
|
||||
void SceneResourcesFinder::AddUsedResource(gd::String &resourceName) {
|
||||
if (resourceName.empty()) {
|
||||
return;
|
||||
|
@@ -15,7 +15,6 @@ namespace gd {
|
||||
class Project;
|
||||
class Layout;
|
||||
class SerializerElement;
|
||||
class EventsBasedObjectVariant;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
@@ -28,7 +27,7 @@ namespace gd {
|
||||
class SceneResourcesFinder : private gd::ArbitraryResourceWorker {
|
||||
public:
|
||||
/**
|
||||
* @brief Find resource usages in a given scene.
|
||||
* @brief Find resource usages in a given scenes.
|
||||
*
|
||||
* It doesn't include resources used globally.
|
||||
*/
|
||||
@@ -42,13 +41,6 @@ public:
|
||||
*/
|
||||
static std::set<gd::String> FindProjectResources(gd::Project &project);
|
||||
|
||||
/**
|
||||
* @brief Find resource usages in a given events-based object variant.
|
||||
*/
|
||||
static std::set<gd::String>
|
||||
FindEventsBasedObjectVariantResources(gd::Project &project,
|
||||
gd::EventsBasedObjectVariant &variant);
|
||||
|
||||
virtual ~SceneResourcesFinder(){};
|
||||
|
||||
private:
|
||||
|
@@ -332,12 +332,6 @@ void ProjectBrowserHelper::ExposeLayoutObjects(gd::Layout &layout,
|
||||
worker.Launch(layout.GetObjects());
|
||||
}
|
||||
|
||||
void ProjectBrowserHelper::ExposeEventsBasedObjectVariantObjects(
|
||||
gd::EventsBasedObjectVariant &eventsBasedObjectVariant,
|
||||
gd::ArbitraryObjectsWorker &worker) {
|
||||
worker.Launch(eventsBasedObjectVariant.GetObjects());
|
||||
}
|
||||
|
||||
void ProjectBrowserHelper::ExposeProjectFunctions(
|
||||
gd::Project &project, gd::ArbitraryEventsFunctionsWorker &worker) {
|
||||
|
||||
|
@@ -13,7 +13,6 @@ class EventsFunctionsExtension;
|
||||
class EventsFunction;
|
||||
class EventsBasedBehavior;
|
||||
class EventsBasedObject;
|
||||
class EventsBasedObjectVariant;
|
||||
class ArbitraryEventsWorker;
|
||||
class ArbitraryEventsWorkerWithContext;
|
||||
class ArbitraryEventsFunctionsWorker;
|
||||
@@ -208,17 +207,6 @@ public:
|
||||
static void ExposeLayoutObjects(gd::Layout &layout,
|
||||
gd::ArbitraryObjectsWorker &worker);
|
||||
|
||||
/**
|
||||
* \brief Call the specified worker on all ObjectContainers of the
|
||||
* events-based object variant.
|
||||
*
|
||||
* This should be the preferred way to traverse all the objects of an
|
||||
* events-based object variant.
|
||||
*/
|
||||
static void ExposeEventsBasedObjectVariantObjects(
|
||||
gd::EventsBasedObjectVariant &eventsBasedObjectVariant,
|
||||
gd::ArbitraryObjectsWorker &worker);
|
||||
|
||||
/**
|
||||
* \brief Call the specified worker on all FunctionsContainers of the project
|
||||
* (global, layouts...)
|
||||
|
@@ -248,13 +248,12 @@ gd::String PropertyFunctionGenerator::GetStringifiedExtraInfo(
|
||||
gd::String arrayString;
|
||||
arrayString += "[";
|
||||
bool isFirst = true;
|
||||
for (const auto &choice : property.GetChoices()) {
|
||||
for (const gd::String &choice : property.GetExtraInfo()) {
|
||||
if (!isFirst) {
|
||||
arrayString += ",";
|
||||
}
|
||||
isFirst = false;
|
||||
// TODO Handle labels (and search "choice label")
|
||||
arrayString += "\"" + choice.GetValue() + "\"";
|
||||
arrayString += "\"" + choice + "\"";
|
||||
}
|
||||
arrayString += "]";
|
||||
return arrayString;
|
||||
|
@@ -75,17 +75,6 @@ void ResourceExposer::ExposeProjectResources(
|
||||
// Expose global objects configuration resources
|
||||
auto objectWorker = gd::GetResourceWorkerOnObjects(project, worker);
|
||||
objectWorker.Launch(project.GetObjects());
|
||||
|
||||
// Exposed extension event resources
|
||||
// Note that using resources in extensions is very unlikely and probably not
|
||||
// worth the effort of something smart.
|
||||
auto eventWorker = gd::GetResourceWorkerOnEvents(project, worker);
|
||||
for (std::size_t e = 0; e < project.GetEventsFunctionsExtensionsCount();
|
||||
e++) {
|
||||
auto &eventsFunctionsExtension = project.GetEventsFunctionsExtension(e);
|
||||
gd::ProjectBrowserHelper::ExposeEventsFunctionsExtensionEvents(
|
||||
project, eventsFunctionsExtension, eventWorker);
|
||||
}
|
||||
}
|
||||
|
||||
void ResourceExposer::ExposeLayoutResources(
|
||||
@@ -114,34 +103,16 @@ void ResourceExposer::ExposeLayoutResources(
|
||||
auto eventWorker = gd::GetResourceWorkerOnEvents(project, worker);
|
||||
gd::ProjectBrowserHelper::ExposeLayoutEventsAndDependencies(
|
||||
project, layout, eventWorker);
|
||||
}
|
||||
|
||||
void ResourceExposer::ExposeEventsBasedObjectVariantResources(
|
||||
gd::Project &project,
|
||||
gd::EventsBasedObjectVariant &eventsBasedObjectVariant,
|
||||
gd::ArbitraryResourceWorker &worker) {
|
||||
// Expose object configuration resources
|
||||
auto objectWorker = gd::GetResourceWorkerOnObjects(project, worker);
|
||||
gd::ProjectBrowserHelper::ExposeEventsBasedObjectVariantObjects(
|
||||
eventsBasedObjectVariant, objectWorker);
|
||||
|
||||
// Expose layer effect resources
|
||||
auto &layers = eventsBasedObjectVariant.GetLayers();
|
||||
for (std::size_t layerIndex = 0; layerIndex < layers.GetLayersCount();
|
||||
layerIndex++) {
|
||||
auto &layer = layers.GetLayer(layerIndex);
|
||||
|
||||
auto &effects = layer.GetEffects();
|
||||
for (size_t effectIndex = 0; effectIndex < effects.GetEffectsCount();
|
||||
effectIndex++) {
|
||||
auto &effect = effects.GetEffect(effectIndex);
|
||||
gd::ResourceExposer::ExposeEffectResources(project.GetCurrentPlatform(),
|
||||
effect, worker);
|
||||
}
|
||||
// Exposed extension event resources
|
||||
// Note that using resources in extensions is very unlikely and probably not
|
||||
// worth the effort of something smart.
|
||||
for (std::size_t e = 0; e < project.GetEventsFunctionsExtensionsCount();
|
||||
e++) {
|
||||
auto &eventsFunctionsExtension = project.GetEventsFunctionsExtension(e);
|
||||
gd::ProjectBrowserHelper::ExposeEventsFunctionsExtensionEvents(
|
||||
project, eventsFunctionsExtension, eventWorker);
|
||||
}
|
||||
// We don't check the events because it would cost too much to do it for every
|
||||
// variant. Resource usage in events-based object events and their
|
||||
// dependencies should be rare.
|
||||
}
|
||||
|
||||
void ResourceExposer::ExposeEffectResources(
|
||||
|
@@ -9,11 +9,10 @@ namespace gd {
|
||||
class Platform;
|
||||
class Project;
|
||||
class ArbitraryResourceWorker;
|
||||
class EventsBasedObjectVariant;
|
||||
class EventsFunctionsExtension;
|
||||
class Effect;
|
||||
class Layout;
|
||||
} // namespace gd
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
@@ -21,7 +20,7 @@ namespace gd {
|
||||
* \brief
|
||||
*/
|
||||
class GD_CORE_API ResourceExposer {
|
||||
public:
|
||||
public:
|
||||
/**
|
||||
* \brief Called ( e.g. during compilation ) so as to inventory internal
|
||||
* resources, sometimes update their filename or any other work or resources.
|
||||
@@ -51,14 +50,6 @@ public:
|
||||
gd::Layout &layout,
|
||||
gd::ArbitraryResourceWorker &worker);
|
||||
|
||||
/**
|
||||
* @brief Expose the resources used in a given events-based object variant.
|
||||
*/
|
||||
static void ExposeEventsBasedObjectVariantResources(
|
||||
gd::Project &project,
|
||||
gd::EventsBasedObjectVariant &eventsBasedObjectVariant,
|
||||
gd::ArbitraryResourceWorker &worker);
|
||||
|
||||
/**
|
||||
* @brief Expose the resources used in a given effect.
|
||||
*/
|
||||
|
@@ -37,7 +37,6 @@ void EventsBasedObjectVariant::SerializeTo(SerializerElement &element) const {
|
||||
|
||||
layers.SerializeLayersTo(element.AddChild("layers"));
|
||||
initialInstances.SerializeTo(element.AddChild("instances"));
|
||||
editorSettings.SerializeTo(element.AddChild("editionSettings"));
|
||||
}
|
||||
|
||||
void EventsBasedObjectVariant::UnserializeFrom(
|
||||
@@ -67,7 +66,6 @@ void EventsBasedObjectVariant::UnserializeFrom(
|
||||
layers.Reset();
|
||||
}
|
||||
initialInstances.UnserializeFrom(element.GetChild("instances"));
|
||||
editorSettings.UnserializeFrom(element.GetChild("editionSettings"));
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "GDCore/IDE/Dialogs/LayoutEditorCanvas/EditorSettings.h"
|
||||
#include "GDCore/Project/InitialInstancesContainer.h"
|
||||
#include "GDCore/Project/LayersContainer.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
@@ -200,19 +199,6 @@ public:
|
||||
const gd::String &GetAssetStoreOriginalName() const {
|
||||
return assetStoreOriginalName;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* \brief Get the user settings for the IDE.
|
||||
*/
|
||||
const gd::EditorSettings& GetAssociatedEditorSettings() const {
|
||||
return editorSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the user settings for the IDE.
|
||||
*/
|
||||
gd::EditorSettings& GetAssociatedEditorSettings() { return editorSettings; }
|
||||
|
||||
void SerializeTo(SerializerElement &element) const;
|
||||
|
||||
@@ -238,7 +224,6 @@ private:
|
||||
* store.
|
||||
*/
|
||||
gd::String assetStoreOriginalName;
|
||||
gd::EditorSettings editorSettings;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -60,18 +60,6 @@ void InitialInstance::UnserializeFrom(const SerializerElement& element) {
|
||||
} else {
|
||||
SetHasCustomDepth(false);
|
||||
}
|
||||
if (element.HasChild("defaultWidth") ||
|
||||
element.HasAttribute("defaultWidth")) {
|
||||
defaultWidth = element.GetDoubleAttribute("defaultWidth");
|
||||
}
|
||||
if (element.HasChild("defaultHeight") ||
|
||||
element.HasAttribute("defaultHeight")) {
|
||||
defaultHeight = element.GetDoubleAttribute("defaultHeight");
|
||||
}
|
||||
if (element.HasChild("defaultDepth") ||
|
||||
element.HasAttribute("defaultDepth")) {
|
||||
defaultDepth = element.GetDoubleAttribute("defaultDepth");
|
||||
}
|
||||
SetZOrder(element.GetIntAttribute("zOrder", 0, "plan"));
|
||||
SetOpacity(element.GetIntAttribute("opacity", 255));
|
||||
SetLayer(element.GetStringAttribute("layer"));
|
||||
@@ -86,51 +74,45 @@ void InitialInstance::UnserializeFrom(const SerializerElement& element) {
|
||||
if (persistentUuid.empty()) ResetPersistentUuid();
|
||||
|
||||
numberProperties.clear();
|
||||
if (element.HasChild("numberProperties", "floatInfos")) {
|
||||
const SerializerElement& numberPropertiesElement =
|
||||
element.GetChild("numberProperties", 0, "floatInfos");
|
||||
numberPropertiesElement.ConsiderAsArrayOf("property", "Info");
|
||||
for (std::size_t j = 0; j < numberPropertiesElement.GetChildrenCount(); ++j) {
|
||||
gd::String name =
|
||||
numberPropertiesElement.GetChild(j).GetStringAttribute("name");
|
||||
double value =
|
||||
numberPropertiesElement.GetChild(j).GetDoubleAttribute("value");
|
||||
const SerializerElement& numberPropertiesElement =
|
||||
element.GetChild("numberProperties", 0, "floatInfos");
|
||||
numberPropertiesElement.ConsiderAsArrayOf("property", "Info");
|
||||
for (std::size_t j = 0; j < numberPropertiesElement.GetChildrenCount(); ++j) {
|
||||
gd::String name =
|
||||
numberPropertiesElement.GetChild(j).GetStringAttribute("name");
|
||||
double value =
|
||||
numberPropertiesElement.GetChild(j).GetDoubleAttribute("value");
|
||||
|
||||
// Compatibility with GD <= 5.1.164
|
||||
if (name == "z") {
|
||||
SetZ(value);
|
||||
} else if (name == "rotationX") {
|
||||
SetRotationX(value);
|
||||
} else if (name == "rotationY") {
|
||||
SetRotationY(value);
|
||||
} else if (name == "depth") {
|
||||
SetHasCustomDepth(true);
|
||||
SetCustomDepth(value);
|
||||
}
|
||||
// end of compatibility code
|
||||
else {
|
||||
numberProperties[name] = value;
|
||||
}
|
||||
// Compatibility with GD <= 5.1.164
|
||||
if (name == "z") {
|
||||
SetZ(value);
|
||||
} else if (name == "rotationX") {
|
||||
SetRotationX(value);
|
||||
} else if (name == "rotationY") {
|
||||
SetRotationY(value);
|
||||
} else if (name == "depth") {
|
||||
SetHasCustomDepth(true);
|
||||
SetCustomDepth(value);
|
||||
}
|
||||
// end of compatibility code
|
||||
else {
|
||||
numberProperties[name] = value;
|
||||
}
|
||||
}
|
||||
|
||||
stringProperties.clear();
|
||||
if (element.HasChild("stringProperties", "stringInfos")) {
|
||||
const SerializerElement& stringPropElement =
|
||||
element.GetChild("stringProperties", 0, "stringInfos");
|
||||
stringPropElement.ConsiderAsArrayOf("property", "Info");
|
||||
for (std::size_t j = 0; j < stringPropElement.GetChildrenCount(); ++j) {
|
||||
gd::String name = stringPropElement.GetChild(j).GetStringAttribute("name");
|
||||
gd::String value =
|
||||
stringPropElement.GetChild(j).GetStringAttribute("value");
|
||||
stringProperties[name] = value;
|
||||
}
|
||||
const SerializerElement& stringPropElement =
|
||||
element.GetChild("stringProperties", 0, "stringInfos");
|
||||
stringPropElement.ConsiderAsArrayOf("property", "Info");
|
||||
for (std::size_t j = 0; j < stringPropElement.GetChildrenCount(); ++j) {
|
||||
gd::String name = stringPropElement.GetChild(j).GetStringAttribute("name");
|
||||
gd::String value =
|
||||
stringPropElement.GetChild(j).GetStringAttribute("value");
|
||||
stringProperties[name] = value;
|
||||
}
|
||||
|
||||
if (element.HasChild("initialVariables", "InitialVariables")) {
|
||||
GetVariables().UnserializeFrom(
|
||||
element.GetChild("initialVariables", 0, "InitialVariables"));
|
||||
}
|
||||
GetVariables().UnserializeFrom(
|
||||
element.GetChild("initialVariables", 0, "InitialVariables"));
|
||||
}
|
||||
|
||||
void InitialInstance::SerializeTo(SerializerElement& element) const {
|
||||
@@ -151,8 +133,6 @@ void InitialInstance::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("width", GetCustomWidth());
|
||||
element.SetAttribute("height", GetCustomHeight());
|
||||
if (HasCustomDepth()) element.SetAttribute("depth", GetCustomDepth());
|
||||
// defaultWidth, defaultHeight and defaultDepth are not serialized
|
||||
// because they are evaluated by InGameEditor.
|
||||
if (IsLocked()) element.SetAttribute("locked", IsLocked());
|
||||
if (IsSealed()) element.SetAttribute("sealed", IsSealed());
|
||||
if (ShouldKeepRatio()) element.SetAttribute("keepRatio", ShouldKeepRatio());
|
||||
|
@@ -219,13 +219,6 @@ class GD_CORE_API InitialInstance {
|
||||
double GetCustomDepth() const { return depth; }
|
||||
void SetCustomDepth(double depth_) { depth = depth_; }
|
||||
|
||||
double GetDefaultWidth() const { return defaultWidth; }
|
||||
double GetDefaultHeight() const { return defaultHeight; }
|
||||
double GetDefaultDepth() const { return defaultDepth; }
|
||||
void SetDefaultWidth(double width_) { defaultWidth = width_; }
|
||||
void SetDefaultHeight(double height_) { defaultHeight = height_; }
|
||||
void SetDefaultDepth(double depth_) { defaultDepth = depth_; }
|
||||
|
||||
/**
|
||||
* \brief Return true if the instance is locked and cannot be moved in the
|
||||
* IDE.
|
||||
@@ -373,11 +366,7 @@ class GD_CORE_API InitialInstance {
|
||||
*/
|
||||
InitialInstance& ResetPersistentUuid();
|
||||
|
||||
/**
|
||||
* \brief Reset the persistent UUID used to recognize
|
||||
* the same initial instance between serialization.
|
||||
*/
|
||||
const gd::String& GetPersistentUuid() const { return persistentUuid; }
|
||||
const gd::String& GetPersistentUuid() const { return persistentUuid; }
|
||||
///@}
|
||||
|
||||
private:
|
||||
@@ -406,9 +395,6 @@ class GD_CORE_API InitialInstance {
|
||||
double width; ///< Instance custom width
|
||||
double height; ///< Instance custom height
|
||||
double depth; ///< Instance custom depth
|
||||
double defaultWidth = 0; ///< Instance default width as reported by InGameEditor
|
||||
double defaultHeight = 0; ///< Instance default height as reported by InGameEditor
|
||||
double defaultDepth = 0; ///< Instance default depth as reported by InGameEditor
|
||||
gd::VariablesContainer initialVariables; ///< Instance specific variables
|
||||
bool locked; ///< True if the instance is locked
|
||||
bool sealed; ///< True if the instance is sealed
|
||||
|
@@ -23,7 +23,6 @@ Layer::Layer()
|
||||
camera3DNearPlaneDistance(3),
|
||||
camera3DFarPlaneDistance(10000),
|
||||
camera3DFieldOfView(45),
|
||||
camera2DPlaneMaxDrawingDistance(5000),
|
||||
ambientLightColorR(200),
|
||||
ambientLightColorG(200),
|
||||
ambientLightColorB(200) {}
|
||||
@@ -57,8 +56,6 @@ void Layer::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("camera3DFarPlaneDistance",
|
||||
GetCamera3DFarPlaneDistance());
|
||||
element.SetAttribute("camera3DFieldOfView", GetCamera3DFieldOfView());
|
||||
element.SetAttribute("camera2DPlaneMaxDrawingDistance",
|
||||
GetCamera2DPlaneMaxDrawingDistance());
|
||||
|
||||
SerializerElement& camerasElement = element.AddChild("cameras");
|
||||
camerasElement.ConsiderAsArrayOf("camera");
|
||||
@@ -102,8 +99,6 @@ void Layer::UnserializeFrom(const SerializerElement& element) {
|
||||
"camera3DFarPlaneDistance", 10000, "threeDFarPlaneDistance"));
|
||||
SetCamera3DFieldOfView(element.GetDoubleAttribute(
|
||||
"camera3DFieldOfView", 45, "threeDFieldOfView"));
|
||||
SetCamera2DPlaneMaxDrawingDistance(element.GetDoubleAttribute(
|
||||
"camera2DPlaneMaxDrawingDistance", 5000));
|
||||
|
||||
cameras.clear();
|
||||
SerializerElement& camerasElement = element.GetChild("cameras");
|
||||
|
@@ -182,8 +182,6 @@ class GD_CORE_API Layer {
|
||||
}
|
||||
double GetCamera3DFieldOfView() const { return camera3DFieldOfView; }
|
||||
void SetCamera3DFieldOfView(double angle) { camera3DFieldOfView = angle; }
|
||||
double GetCamera2DPlaneMaxDrawingDistance() const { return camera2DPlaneMaxDrawingDistance; }
|
||||
void SetCamera2DPlaneMaxDrawingDistance(double distance) { camera2DPlaneMaxDrawingDistance = distance; }
|
||||
///@}
|
||||
|
||||
/** \name Cameras
|
||||
@@ -294,7 +292,6 @@ class GD_CORE_API Layer {
|
||||
double camera3DNearPlaneDistance; ///< 3D camera frustum near plan distance
|
||||
double camera3DFarPlaneDistance; ///< 3D camera frustum far plan distance
|
||||
double camera3DFieldOfView; ///< 3D camera field of view (fov) in degrees
|
||||
double camera2DPlaneMaxDrawingDistance; ///< Max drawing distance of the 2D plane when in the 3D world
|
||||
unsigned int ambientLightColorR; ///< Ambient light color Red component
|
||||
unsigned int ambientLightColorG; ///< Ambient light color Green component
|
||||
unsigned int ambientLightColorB; ///< Ambient light color Blue component
|
||||
|
@@ -730,8 +730,6 @@ void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
SetPackageName(propElement.GetStringAttribute("packageName"));
|
||||
SetTemplateSlug(propElement.GetStringAttribute("templateSlug"));
|
||||
SetOrientation(propElement.GetStringAttribute("orientation", "default"));
|
||||
SetEffectsHiddenInEditor(
|
||||
propElement.GetBoolAttribute("areEffectsHiddenInEditor", false));
|
||||
SetFolderProject(propElement.GetBoolAttribute("folderProject"));
|
||||
SetLastCompilationDirectory(propElement
|
||||
.GetChild("latestCompilationDirectory",
|
||||
@@ -1111,10 +1109,6 @@ void Project::SerializeTo(SerializerElement& element) const {
|
||||
propElement.SetAttribute("packageName", packageName);
|
||||
propElement.SetAttribute("templateSlug", templateSlug);
|
||||
propElement.SetAttribute("orientation", orientation);
|
||||
if (areEffectsHiddenInEditor) {
|
||||
propElement.SetBoolAttribute("areEffectsHiddenInEditor",
|
||||
areEffectsHiddenInEditor);
|
||||
}
|
||||
platformSpecificAssets.SerializeTo(
|
||||
propElement.AddChild("platformSpecificAssets"));
|
||||
loadingScreen.SerializeTo(propElement.AddChild("loadingScreen"));
|
||||
@@ -1156,8 +1150,6 @@ void Project::SerializeTo(SerializerElement& element) const {
|
||||
// end of compatibility code
|
||||
|
||||
extensionProperties.SerializeTo(propElement.AddChild("extensionProperties"));
|
||||
|
||||
playableDevicesElement.AddChild("").SetStringValue("mobile");
|
||||
|
||||
SerializerElement& platformsElement = propElement.AddChild("platforms");
|
||||
platformsElement.ConsiderAsArrayOf("platform");
|
||||
@@ -1327,8 +1319,6 @@ void Project::Init(const gd::Project& game) {
|
||||
|
||||
sceneResourcesPreloading = game.sceneResourcesPreloading;
|
||||
sceneResourcesUnloading = game.sceneResourcesUnloading;
|
||||
|
||||
areEffectsHiddenInEditor = game.areEffectsHiddenInEditor;
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -506,20 +506,6 @@ class GD_CORE_API Project {
|
||||
*/
|
||||
void SetCurrentPlatform(const gd::String& platformName);
|
||||
|
||||
/**
|
||||
* Check if the effects are shown.
|
||||
*/
|
||||
bool AreEffectsHiddenInEditor() const { return areEffectsHiddenInEditor; }
|
||||
|
||||
/**
|
||||
* Define the project as playable on a mobile.
|
||||
* \param enable True When false effects are not shown and a default light is
|
||||
* used for 3D layers.
|
||||
*/
|
||||
void SetEffectsHiddenInEditor(bool enable = true) {
|
||||
areEffectsHiddenInEditor = enable;
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
/** \name Factory method
|
||||
@@ -1179,9 +1165,6 @@ class GD_CORE_API Project {
|
||||
mutable unsigned int gdBuildVersion =
|
||||
0; ///< The GD build version used the last
|
||||
///< time the project was saved.
|
||||
bool areEffectsHiddenInEditor =
|
||||
false; ///< When false effects are not shown and a default light is used
|
||||
///< for 3D layers.
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -34,20 +34,6 @@ void PropertyDescriptor::SerializeTo(SerializerElement& element) const {
|
||||
}
|
||||
}
|
||||
|
||||
if (!choices.empty()
|
||||
// Compatibility with GD <= 5.5.239
|
||||
|| !extraInformation.empty()
|
||||
// end of compatibility code
|
||||
) {
|
||||
SerializerElement &choicesElement = element.AddChild("choices");
|
||||
choicesElement.ConsiderAsArrayOf("choice");
|
||||
for (const auto &choice : choices) {
|
||||
auto &choiceElement = choicesElement.AddChild("Choice");
|
||||
choiceElement.SetStringAttribute("value", choice.GetValue());
|
||||
choiceElement.SetStringAttribute("label", choice.GetLabel());
|
||||
}
|
||||
}
|
||||
|
||||
if (hidden) {
|
||||
element.AddChild("hidden").SetBoolValue(hidden);
|
||||
}
|
||||
@@ -70,9 +56,7 @@ void PropertyDescriptor::UnserializeFrom(const SerializerElement& element) {
|
||||
currentValue = element.GetChild("value").GetStringValue();
|
||||
type = element.GetChild("type").GetStringValue();
|
||||
if (type == "Number") {
|
||||
gd::String unitName = element.HasChild("unit")
|
||||
? element.GetChild("unit").GetStringValue()
|
||||
: "";
|
||||
gd::String unitName = element.GetChild("unit").GetStringValue();
|
||||
measurementUnit =
|
||||
gd::MeasurementUnit::HasDefaultMeasurementUnitNamed(unitName)
|
||||
? measurementUnit =
|
||||
@@ -96,26 +80,6 @@ void PropertyDescriptor::UnserializeFrom(const SerializerElement& element) {
|
||||
extraInformationElement.GetChild(i).GetStringValue());
|
||||
}
|
||||
|
||||
if (element.HasChild("choices")) {
|
||||
choices.clear();
|
||||
const SerializerElement &choicesElement = element.GetChild("choices");
|
||||
choicesElement.ConsiderAsArrayOf("choice");
|
||||
for (std::size_t i = 0; i < choicesElement.GetChildrenCount(); ++i) {
|
||||
auto &choiceElement = choicesElement.GetChild(i);
|
||||
AddChoice(choiceElement.GetStringAttribute("value"),
|
||||
choiceElement.GetStringAttribute("label"));
|
||||
}
|
||||
}
|
||||
// Compatibility with GD <= 5.5.239
|
||||
else if (type == "Choice") {
|
||||
choices.clear();
|
||||
for (auto &choiceValue : extraInformation) {
|
||||
AddChoice(choiceValue, choiceValue);
|
||||
}
|
||||
extraInformation.clear();
|
||||
}
|
||||
// end of compatibility code
|
||||
|
||||
hidden = element.HasChild("hidden")
|
||||
? element.GetChild("hidden").GetBoolValue()
|
||||
: false;
|
||||
|
@@ -116,11 +116,6 @@ class GD_CORE_API PropertyDescriptor {
|
||||
return *this;
|
||||
}
|
||||
|
||||
PropertyDescriptor& ClearChoices() {
|
||||
choices.clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
PropertyDescriptor& AddChoice(const gd::String& value,
|
||||
const gd::String& label) {
|
||||
choices.push_back(PropertyDescriptorChoice(value, label));
|
||||
|
@@ -764,6 +764,129 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
|
||||
REQUIRE(worker.audios[0] == "res4");
|
||||
}
|
||||
|
||||
SECTION("Can find resource usages in event-based functions") {
|
||||
gd::Project project;
|
||||
gd::Platform platform;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
project.GetResourcesManager().AddResource(
|
||||
"res1", "path/to/file1.png", "image");
|
||||
project.GetResourcesManager().AddResource(
|
||||
"res2", "path/to/file2.png", "image");
|
||||
project.GetResourcesManager().AddResource(
|
||||
"res3", "path/to/file3.png", "image");
|
||||
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
|
||||
|
||||
auto& extension = project.InsertNewEventsFunctionsExtension("MyEventExtension", 0);
|
||||
auto &function = extension.GetEventsFunctions().InsertNewEventsFunction(
|
||||
"MyFreeFunction", 0);
|
||||
|
||||
gd::StandardEvent standardEvent;
|
||||
gd::Instruction instruction;
|
||||
instruction.SetType("MyExtension::DoSomethingWithResources");
|
||||
instruction.SetParametersCount(3);
|
||||
instruction.SetParameter(0, "res3");
|
||||
instruction.SetParameter(1, "res1");
|
||||
instruction.SetParameter(2, "res4");
|
||||
standardEvent.GetActions().Insert(instruction);
|
||||
function.GetEvents().InsertEvent(standardEvent);
|
||||
|
||||
auto& layout = project.InsertNewLayout("MyScene", 0);
|
||||
|
||||
// MyEventExtension::MyFreeFunction doesn't need to be actually used in
|
||||
// events because the implementation is naive.
|
||||
|
||||
gd::ResourceExposer::ExposeLayoutResources(project, layout, worker);
|
||||
REQUIRE(worker.bitmapFonts.size() == 1);
|
||||
REQUIRE(worker.bitmapFonts[0] == "res3");
|
||||
REQUIRE(worker.images.size() == 1);
|
||||
REQUIRE(worker.images[0] == "res1");
|
||||
REQUIRE(worker.audios.size() == 1);
|
||||
REQUIRE(worker.audios[0] == "res4");
|
||||
}
|
||||
|
||||
SECTION("Can find resource usages in event-based behavior functions") {
|
||||
gd::Project project;
|
||||
gd::Platform platform;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
project.GetResourcesManager().AddResource(
|
||||
"res1", "path/to/file1.png", "image");
|
||||
project.GetResourcesManager().AddResource(
|
||||
"res2", "path/to/file2.png", "image");
|
||||
project.GetResourcesManager().AddResource(
|
||||
"res3", "path/to/file3.png", "image");
|
||||
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
|
||||
|
||||
auto& extension = project.InsertNewEventsFunctionsExtension("MyEventExtension", 0);
|
||||
auto& behavior = extension.GetEventsBasedBehaviors().InsertNew("MyBehavior", 0);
|
||||
auto& function = behavior.GetEventsFunctions().InsertNewEventsFunction("MyFunction", 0);
|
||||
|
||||
gd::StandardEvent standardEvent;
|
||||
gd::Instruction instruction;
|
||||
instruction.SetType("MyExtension::DoSomethingWithResources");
|
||||
instruction.SetParametersCount(3);
|
||||
instruction.SetParameter(0, "res3");
|
||||
instruction.SetParameter(1, "res1");
|
||||
instruction.SetParameter(2, "res4");
|
||||
standardEvent.GetActions().Insert(instruction);
|
||||
function.GetEvents().InsertEvent(standardEvent);
|
||||
|
||||
auto& layout = project.InsertNewLayout("MyScene", 0);
|
||||
|
||||
// MyEventExtension::MyBehavior::MyFunction doesn't need to be actually used in
|
||||
// events because the implementation is naive.
|
||||
|
||||
gd::ResourceExposer::ExposeLayoutResources(project, layout, worker);
|
||||
REQUIRE(worker.bitmapFonts.size() == 1);
|
||||
REQUIRE(worker.bitmapFonts[0] == "res3");
|
||||
REQUIRE(worker.images.size() == 1);
|
||||
REQUIRE(worker.images[0] == "res1");
|
||||
REQUIRE(worker.audios.size() == 1);
|
||||
REQUIRE(worker.audios[0] == "res4");
|
||||
}
|
||||
|
||||
SECTION("Can find resource usages in event-based object functions") {
|
||||
gd::Project project;
|
||||
gd::Platform platform;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
project.GetResourcesManager().AddResource(
|
||||
"res1", "path/to/file1.png", "image");
|
||||
project.GetResourcesManager().AddResource(
|
||||
"res2", "path/to/file2.png", "image");
|
||||
project.GetResourcesManager().AddResource(
|
||||
"res3", "path/to/file3.png", "image");
|
||||
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
|
||||
|
||||
auto& extension = project.InsertNewEventsFunctionsExtension("MyEventExtension", 0);
|
||||
auto& object = extension.GetEventsBasedObjects().InsertNew("MyObject", 0);
|
||||
auto& function = object.GetEventsFunctions().InsertNewEventsFunction("MyFunction", 0);
|
||||
|
||||
gd::StandardEvent standardEvent;
|
||||
gd::Instruction instruction;
|
||||
instruction.SetType("MyExtension::DoSomethingWithResources");
|
||||
instruction.SetParametersCount(3);
|
||||
instruction.SetParameter(0, "res3");
|
||||
instruction.SetParameter(1, "res1");
|
||||
instruction.SetParameter(2, "res4");
|
||||
standardEvent.GetActions().Insert(instruction);
|
||||
function.GetEvents().InsertEvent(standardEvent);
|
||||
|
||||
auto& layout = project.InsertNewLayout("MyScene", 0);
|
||||
|
||||
// MyEventExtension::MyObject::MyFunction doesn't need to be actually used in
|
||||
// events because the implementation is naive.
|
||||
|
||||
gd::ResourceExposer::ExposeLayoutResources(project, layout, worker);
|
||||
REQUIRE(worker.bitmapFonts.size() == 1);
|
||||
REQUIRE(worker.bitmapFonts[0] == "res3");
|
||||
REQUIRE(worker.images.size() == 1);
|
||||
REQUIRE(worker.images[0] == "res1");
|
||||
REQUIRE(worker.audios.size() == 1);
|
||||
REQUIRE(worker.audios[0] == "res4");
|
||||
}
|
||||
|
||||
SECTION("Can find resource usages in layer effects") {
|
||||
gd::Project project;
|
||||
gd::Platform platform;
|
||||
|
@@ -139,8 +139,8 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
|
||||
.SetLabel("Dot shape")
|
||||
.SetDescription("The shape is used for collision.")
|
||||
.SetGroup("Movement");
|
||||
property.AddChoice("DotShape", "Dot shape");
|
||||
property.AddChoice("BoundingDisk", "Bounding disk");
|
||||
property.GetExtraInfo().push_back("Dot shape");
|
||||
property.GetExtraInfo().push_back("Bounding disk");
|
||||
|
||||
gd::PropertyFunctionGenerator::GenerateBehaviorGetterAndSetter(
|
||||
project, extension, behavior, property, false);
|
||||
@@ -157,7 +157,7 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
|
||||
gd::EventsFunction::ExpressionAndCondition);
|
||||
REQUIRE(getter.GetExpressionType().GetName() == "stringWithSelector");
|
||||
REQUIRE(getter.GetExpressionType().GetExtraInfo() ==
|
||||
"[\"DotShape\",\"BoundingDisk\"]");
|
||||
"[\"Dot shape\",\"Bounding disk\"]");
|
||||
}
|
||||
|
||||
SECTION("Can generate functions for a boolean property in a behavior") {
|
||||
@@ -386,8 +386,8 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
|
||||
.SetLabel("Dot shape")
|
||||
.SetDescription("The shape is used for collision.")
|
||||
.SetGroup("Movement");
|
||||
property.AddChoice("DotShape", "Dot shape");
|
||||
property.AddChoice("BoundingDisk", "Bounding disk");
|
||||
property.GetExtraInfo().push_back("Dot shape");
|
||||
property.GetExtraInfo().push_back("Bounding disk");
|
||||
|
||||
gd::PropertyFunctionGenerator::GenerateObjectGetterAndSetter(
|
||||
project, extension, object, property);
|
||||
@@ -404,7 +404,7 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
|
||||
gd::EventsFunction::ExpressionAndCondition);
|
||||
REQUIRE(getter.GetExpressionType().GetName() == "stringWithSelector");
|
||||
REQUIRE(getter.GetExpressionType().GetExtraInfo() ==
|
||||
"[\"DotShape\",\"BoundingDisk\"]");
|
||||
"[\"Dot shape\",\"Bounding disk\"]");
|
||||
}
|
||||
|
||||
SECTION("Can generate functions for a boolean property in an object") {
|
||||
|
@@ -147,9 +147,15 @@ namespace gdjs {
|
||||
if (initialInstanceData.depth !== undefined) {
|
||||
this.setDepth(initialInstanceData.depth);
|
||||
}
|
||||
this.flipX(!!initialInstanceData.flippedX);
|
||||
this.flipY(!!initialInstanceData.flippedY);
|
||||
this.flipZ(!!initialInstanceData.flippedZ);
|
||||
if (initialInstanceData.flippedX) {
|
||||
this.flipX(initialInstanceData.flippedX);
|
||||
}
|
||||
if (initialInstanceData.flippedY) {
|
||||
this.flipY(initialInstanceData.flippedY);
|
||||
}
|
||||
if (initialInstanceData.flippedZ) {
|
||||
this.flipZ(initialInstanceData.flippedZ);
|
||||
}
|
||||
}
|
||||
|
||||
setX(x: float): void {
|
||||
@@ -316,18 +322,6 @@ namespace gdjs {
|
||||
this.setAngle(gdjs.toDegrees(mesh.rotation.z));
|
||||
}
|
||||
|
||||
override getOriginalWidth(): float {
|
||||
return this._originalWidth;
|
||||
}
|
||||
|
||||
override getOriginalHeight(): float {
|
||||
return this._originalHeight;
|
||||
}
|
||||
|
||||
getOriginalDepth(): float {
|
||||
return this._originalDepth;
|
||||
}
|
||||
|
||||
getWidth(): float {
|
||||
return this._width;
|
||||
}
|
||||
@@ -374,6 +368,31 @@ namespace gdjs {
|
||||
this.getRenderer().updateSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the width of the object for a scale of 1.
|
||||
*
|
||||
* It can't be 0.
|
||||
*/
|
||||
_getOriginalWidth(): float {
|
||||
return this._originalWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the height of the object for a scale of 1.
|
||||
*
|
||||
* It can't be 0.
|
||||
*/
|
||||
_getOriginalHeight(): float {
|
||||
return this._originalHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the object size on the Z axis (called "depth") when the scale equals 1.
|
||||
*/
|
||||
_getOriginalDepth(): float {
|
||||
return this._originalDepth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the width of the object for a scale of 1.
|
||||
*/
|
||||
|
@@ -11,8 +11,6 @@ namespace gdjs {
|
||||
this._object = runtimeObject;
|
||||
this._threeObject3D = threeObject3D;
|
||||
this._threeObject3D.rotation.order = 'ZYX';
|
||||
//@ts-ignore
|
||||
this._threeObject3D.gdjsRuntimeObject = runtimeObject;
|
||||
|
||||
instanceContainer
|
||||
.getLayer('')
|
||||
|
@@ -115,12 +115,6 @@ namespace gdjs {
|
||||
* Rotations around X and Y are not taken into account.
|
||||
*/
|
||||
getUnrotatedAABBMaxZ(): number;
|
||||
|
||||
/**
|
||||
* Return the depth of the object before any custom size is applied.
|
||||
* @return The depth of the object
|
||||
*/
|
||||
getOriginalDepth(): float;
|
||||
}
|
||||
|
||||
export interface Object3DDataContent {
|
||||
@@ -137,11 +131,7 @@ namespace gdjs {
|
||||
export namespace Base3DHandler {
|
||||
export const is3D = (
|
||||
object: gdjs.RuntimeObject
|
||||
): object is gdjs.RuntimeObject &
|
||||
gdjs.Base3DHandler &
|
||||
gdjs.Resizable &
|
||||
gdjs.Scalable &
|
||||
gdjs.Flippable => {
|
||||
): object is gdjs.RuntimeObject & gdjs.Base3DHandler => {
|
||||
//@ts-ignore We are checking if the methods are present.
|
||||
return object.getZ && object.setZ;
|
||||
};
|
||||
@@ -253,10 +243,6 @@ namespace gdjs {
|
||||
getUnrotatedAABBMaxZ(): number {
|
||||
return this.object.getUnrotatedAABBMaxZ();
|
||||
}
|
||||
|
||||
getOriginalDepth(): float {
|
||||
return this.object.getOriginalDepth();
|
||||
}
|
||||
}
|
||||
|
||||
gdjs.registerBehavior('Scene3D::Base3DBehavior', gdjs.Base3DBehavior);
|
||||
|
@@ -74,9 +74,15 @@ namespace gdjs {
|
||||
if (initialInstanceData.depth !== undefined) {
|
||||
this.setDepth(initialInstanceData.depth);
|
||||
}
|
||||
this.flipX(!!initialInstanceData.flippedX);
|
||||
this.flipY(!!initialInstanceData.flippedY);
|
||||
this.flipZ(!!initialInstanceData.flippedZ);
|
||||
if (initialInstanceData.flippedX) {
|
||||
this.flipX(initialInstanceData.flippedX);
|
||||
}
|
||||
if (initialInstanceData.flippedY) {
|
||||
this.flipY(initialInstanceData.flippedY);
|
||||
}
|
||||
if (initialInstanceData.flippedZ) {
|
||||
this.flipZ(initialInstanceData.flippedZ);
|
||||
}
|
||||
}
|
||||
|
||||
getNetworkSyncData(): CustomObject3DNetworkSyncDataType {
|
||||
@@ -309,10 +315,6 @@ namespace gdjs {
|
||||
return this._maxZ - this._minZ;
|
||||
}
|
||||
|
||||
getOriginalDepth(): float {
|
||||
return this._instanceContainer._getInitialInnerAreaDepth();
|
||||
}
|
||||
|
||||
override _updateUntransformedHitBoxes(): void {
|
||||
super._updateUntransformedHitBoxes();
|
||||
|
||||
|
@@ -162,12 +162,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('object', _('3D object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'Base3DBehavior')
|
||||
.useStandardParameters(
|
||||
'number',
|
||||
gd.ParameterOptions.makeNewOptions().setDescription(
|
||||
_('Angle (in degrees)')
|
||||
)
|
||||
)
|
||||
.useStandardParameters('number', gd.ParameterOptions.makeNewOptions())
|
||||
.setFunctionName('setRotationX')
|
||||
.setGetter('getRotationX');
|
||||
|
||||
@@ -183,12 +178,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('object', _('3D object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'Base3DBehavior')
|
||||
.useStandardParameters(
|
||||
'number',
|
||||
gd.ParameterOptions.makeNewOptions().setDescription(
|
||||
_('Angle (in degrees)')
|
||||
)
|
||||
)
|
||||
.useStandardParameters('number', gd.ParameterOptions.makeNewOptions())
|
||||
.setFunctionName('setRotationY')
|
||||
.setGetter('getRotationY');
|
||||
|
||||
@@ -206,7 +196,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('object', _('3D object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'Base3DBehavior')
|
||||
.addParameter('number', _('Angle to add (in degrees)'), '', false)
|
||||
.addParameter('number', _('Rotation angle'), '', false)
|
||||
.markAsAdvanced()
|
||||
.setFunctionName('turnAroundX');
|
||||
|
||||
@@ -224,7 +214,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('object', _('3D object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'Base3DBehavior')
|
||||
.addParameter('number', _('Angle to add (in degrees)'), '', false)
|
||||
.addParameter('number', _('Rotation angle'), '', false)
|
||||
.markAsAdvanced()
|
||||
.setFunctionName('turnAroundY');
|
||||
|
||||
@@ -242,7 +232,7 @@ module.exports = {
|
||||
)
|
||||
.addParameter('object', _('3D object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'Base3DBehavior')
|
||||
.addParameter('number', _('Angle to add (in degrees)'), '', false)
|
||||
.addParameter('number', _('Rotation angle'), '', false)
|
||||
.markAsAdvanced()
|
||||
.setFunctionName('turnAroundZ');
|
||||
}
|
||||
@@ -604,12 +594,7 @@ module.exports = {
|
||||
'res/conditions/3d_box.svg'
|
||||
)
|
||||
.addParameter('object', _('3D model'), 'Model3DObject', false)
|
||||
.useStandardParameters(
|
||||
'number',
|
||||
gd.ParameterOptions.makeNewOptions().setDescription(
|
||||
_('Angle (in degrees)')
|
||||
)
|
||||
)
|
||||
.useStandardParameters('number', gd.ParameterOptions.makeNewOptions())
|
||||
.setHidden()
|
||||
.setFunctionName('setRotationX')
|
||||
.setGetter('getRotationX');
|
||||
@@ -626,12 +611,7 @@ module.exports = {
|
||||
'res/conditions/3d_box.svg'
|
||||
)
|
||||
.addParameter('object', _('3D model'), 'Model3DObject', false)
|
||||
.useStandardParameters(
|
||||
'number',
|
||||
gd.ParameterOptions.makeNewOptions().setDescription(
|
||||
_('Angle (in degrees)')
|
||||
)
|
||||
)
|
||||
.useStandardParameters('number', gd.ParameterOptions.makeNewOptions())
|
||||
.setHidden()
|
||||
.setFunctionName('setRotationY')
|
||||
.setGetter('getRotationY');
|
||||
@@ -650,7 +630,7 @@ module.exports = {
|
||||
'res/conditions/3d_box.svg'
|
||||
)
|
||||
.addParameter('object', _('3D model'), 'Model3DObject', false)
|
||||
.addParameter('number', _('Angle to add (in degrees)'), '', false)
|
||||
.addParameter('number', _('Rotation angle'), '', false)
|
||||
.markAsAdvanced()
|
||||
.setHidden()
|
||||
.setFunctionName('turnAroundX');
|
||||
@@ -669,7 +649,7 @@ module.exports = {
|
||||
'res/conditions/3d_box.svg'
|
||||
)
|
||||
.addParameter('object', _('3D model'), 'Model3DObject', false)
|
||||
.addParameter('number', _('Angle to add (in degrees)'), '', false)
|
||||
.addParameter('number', _('Rotation angle'), '', false)
|
||||
.markAsAdvanced()
|
||||
.setHidden()
|
||||
.setFunctionName('turnAroundY');
|
||||
@@ -688,7 +668,7 @@ module.exports = {
|
||||
'res/conditions/3d_box.svg'
|
||||
)
|
||||
.addParameter('object', _('3D model'), 'Model3DObject', false)
|
||||
.addParameter('number', _('Angle to add (in degrees)'), '', false)
|
||||
.addParameter('number', _('Rotation angle'), '', false)
|
||||
.markAsAdvanced()
|
||||
.setHidden()
|
||||
.setFunctionName('turnAroundZ');
|
||||
@@ -1513,12 +1493,7 @@ module.exports = {
|
||||
'res/conditions/3d_box.svg'
|
||||
)
|
||||
.addParameter('object', _('3D cube'), 'Cube3DObject', false)
|
||||
.useStandardParameters(
|
||||
'number',
|
||||
gd.ParameterOptions.makeNewOptions().setDescription(
|
||||
_('Angle (in degrees)')
|
||||
)
|
||||
)
|
||||
.useStandardParameters('number', gd.ParameterOptions.makeNewOptions())
|
||||
.setFunctionName('setRotationX')
|
||||
.setHidden()
|
||||
.setGetter('getRotationX');
|
||||
@@ -1535,12 +1510,7 @@ module.exports = {
|
||||
'res/conditions/3d_box.svg'
|
||||
)
|
||||
.addParameter('object', _('3D cube'), 'Cube3DObject', false)
|
||||
.useStandardParameters(
|
||||
'number',
|
||||
gd.ParameterOptions.makeNewOptions().setDescription(
|
||||
_('Angle (in degrees)')
|
||||
)
|
||||
)
|
||||
.useStandardParameters('number', gd.ParameterOptions.makeNewOptions())
|
||||
.setFunctionName('setRotationY')
|
||||
.setHidden()
|
||||
.setGetter('getRotationY');
|
||||
@@ -1908,9 +1878,7 @@ module.exports = {
|
||||
.addEffect('AmbientLight')
|
||||
.setFullName(_('Ambient light'))
|
||||
.setDescription(
|
||||
_(
|
||||
'A light that illuminates all objects from every direction. Often used along with a Directional light (though a Hemisphere light can be used instead of an Ambient light).'
|
||||
)
|
||||
_('A light that illuminates all objects from every direction.')
|
||||
)
|
||||
.markAsNotWorkingForObjects()
|
||||
.markAsOnlyWorkingFor3D()
|
||||
@@ -1931,11 +1899,7 @@ module.exports = {
|
||||
const effect = extension
|
||||
.addEffect('DirectionalLight')
|
||||
.setFullName(_('Directional light'))
|
||||
.setDescription(
|
||||
_(
|
||||
"A very far light source like the sun. This is the light to use for casting shadows for 3D objects (other lights won't emit shadows). Often used along with a Hemisphere light."
|
||||
)
|
||||
)
|
||||
.setDescription(_('A very far light source like the sun.'))
|
||||
.markAsNotWorkingForObjects()
|
||||
.markAsOnlyWorkingFor3D()
|
||||
.addIncludeFile('Extensions/3D/DirectionalLight.js');
|
||||
@@ -2019,7 +1983,7 @@ module.exports = {
|
||||
.setFullName(_('Hemisphere light'))
|
||||
.setDescription(
|
||||
_(
|
||||
'A light that illuminates objects from every direction with a gradient. Often used along with a Directional light.'
|
||||
'A light that illuminates objects from every direction with a gradient.'
|
||||
)
|
||||
)
|
||||
.markAsNotWorkingForObjects()
|
||||
@@ -2063,48 +2027,6 @@ module.exports = {
|
||||
.setType('number')
|
||||
.setGroup(_('Orientation'));
|
||||
}
|
||||
{
|
||||
const effect = extension
|
||||
.addEffect('Skybox')
|
||||
.setFullName(_('Skybox'))
|
||||
.setDescription(
|
||||
_('Display a background on a cube surrounding the scene.')
|
||||
)
|
||||
.markAsNotWorkingForObjects()
|
||||
.markAsOnlyWorkingFor3D()
|
||||
.addIncludeFile('Extensions/3D/Skybox.js');
|
||||
const properties = effect.getProperties();
|
||||
properties
|
||||
.getOrCreate('rightFaceResourceName')
|
||||
.setType('resource')
|
||||
.addExtraInfo('image')
|
||||
.setLabel(_('Right face (X+)'));
|
||||
properties
|
||||
.getOrCreate('leftFaceResourceName')
|
||||
.setType('resource')
|
||||
.addExtraInfo('image')
|
||||
.setLabel(_('Left face (X-)'));
|
||||
properties
|
||||
.getOrCreate('bottomFaceResourceName')
|
||||
.setType('resource')
|
||||
.addExtraInfo('image')
|
||||
.setLabel(_('Bottom face (Y+)'));
|
||||
properties
|
||||
.getOrCreate('topFaceResourceName')
|
||||
.setType('resource')
|
||||
.addExtraInfo('image')
|
||||
.setLabel(_('Top face (Y-)'));
|
||||
properties
|
||||
.getOrCreate('frontFaceResourceName')
|
||||
.setType('resource')
|
||||
.addExtraInfo('image')
|
||||
.setLabel(_('Front face (Z+)'));
|
||||
properties
|
||||
.getOrCreate('backFaceResourceName')
|
||||
.setType('resource')
|
||||
.addExtraInfo('image')
|
||||
.setLabel(_('Back face (Z-)'));
|
||||
}
|
||||
{
|
||||
const effect = extension
|
||||
.addEffect('HueAndSaturation')
|
||||
|
@@ -278,9 +278,9 @@ namespace gdjs {
|
||||
rotationX,
|
||||
rotationY,
|
||||
rotationZ,
|
||||
this.getOriginalWidth(),
|
||||
this.getOriginalHeight(),
|
||||
this.getOriginalDepth(),
|
||||
this._getOriginalWidth(),
|
||||
this._getOriginalHeight(),
|
||||
this._getOriginalDepth(),
|
||||
keepAspectRatio
|
||||
);
|
||||
}
|
||||
|
@@ -1,102 +0,0 @@
|
||||
namespace gdjs {
|
||||
interface SkyboxFilterNetworkSyncData {}
|
||||
gdjs.PixiFiltersTools.registerFilterCreator(
|
||||
'Scene3D::Skybox',
|
||||
new (class implements gdjs.PixiFiltersTools.FilterCreator {
|
||||
makeFilter(
|
||||
target: EffectsTarget,
|
||||
effectData: EffectData
|
||||
): gdjs.PixiFiltersTools.Filter {
|
||||
if (typeof THREE === 'undefined') {
|
||||
return new gdjs.PixiFiltersTools.EmptyFilter();
|
||||
}
|
||||
return new (class implements gdjs.PixiFiltersTools.Filter {
|
||||
_cubeTexture: THREE.CubeTexture;
|
||||
_oldBackground:
|
||||
| THREE.CubeTexture
|
||||
| THREE.Texture
|
||||
| THREE.Color
|
||||
| null = null;
|
||||
_isEnabled: boolean = false;
|
||||
|
||||
constructor() {
|
||||
this._cubeTexture = target
|
||||
.getRuntimeScene()
|
||||
.getGame()
|
||||
.getImageManager()
|
||||
.getThreeCubeTexture(
|
||||
effectData.stringParameters.rightFaceResourceName,
|
||||
effectData.stringParameters.leftFaceResourceName,
|
||||
effectData.stringParameters.topFaceResourceName,
|
||||
effectData.stringParameters.bottomFaceResourceName,
|
||||
effectData.stringParameters.frontFaceResourceName,
|
||||
effectData.stringParameters.backFaceResourceName
|
||||
);
|
||||
}
|
||||
|
||||
isEnabled(target: EffectsTarget): boolean {
|
||||
return this._isEnabled;
|
||||
}
|
||||
setEnabled(target: EffectsTarget, enabled: boolean): boolean {
|
||||
if (this._isEnabled === enabled) {
|
||||
return true;
|
||||
}
|
||||
if (enabled) {
|
||||
return this.applyEffect(target);
|
||||
} else {
|
||||
return this.removeEffect(target);
|
||||
}
|
||||
}
|
||||
applyEffect(target: EffectsTarget): boolean {
|
||||
const scene = target.get3DRendererObject() as
|
||||
| THREE.Scene
|
||||
| null
|
||||
| undefined;
|
||||
if (!scene) {
|
||||
return false;
|
||||
}
|
||||
// TODO Add a background stack in LayerPixiRenderer to allow
|
||||
// filters to stack them.
|
||||
this._oldBackground = scene.background;
|
||||
scene.background = this._cubeTexture;
|
||||
if (!scene.environment) {
|
||||
scene.environment = this._cubeTexture;
|
||||
}
|
||||
this._isEnabled = true;
|
||||
return true;
|
||||
}
|
||||
removeEffect(target: EffectsTarget): boolean {
|
||||
const scene = target.get3DRendererObject() as
|
||||
| THREE.Scene
|
||||
| null
|
||||
| undefined;
|
||||
if (!scene) {
|
||||
return false;
|
||||
}
|
||||
scene.background = this._oldBackground;
|
||||
scene.environment = null;
|
||||
this._isEnabled = false;
|
||||
return true;
|
||||
}
|
||||
updatePreRender(target: gdjs.EffectsTarget): any {}
|
||||
updateDoubleParameter(parameterName: string, value: number): void {}
|
||||
getDoubleParameter(parameterName: string): number {
|
||||
return 0;
|
||||
}
|
||||
updateStringParameter(parameterName: string, value: string): void {}
|
||||
updateColorParameter(parameterName: string, value: number): void {}
|
||||
getColorParameter(parameterName: string): number {
|
||||
return 0;
|
||||
}
|
||||
updateBooleanParameter(parameterName: string, value: boolean): void {}
|
||||
getNetworkSyncData(): SkyboxFilterNetworkSyncData {
|
||||
return {};
|
||||
}
|
||||
updateFromNetworkSyncData(
|
||||
syncData: SkyboxFilterNetworkSyncData
|
||||
): void {}
|
||||
})();
|
||||
}
|
||||
})()
|
||||
);
|
||||
}
|
@@ -473,14 +473,7 @@ namespace gdjs {
|
||||
this._parentOldMaxY = instanceContainer.getUnrotatedViewportMaxY();
|
||||
}
|
||||
|
||||
doStepPostEvents(instanceContainer: gdjs.RuntimeInstanceContainer) {
|
||||
// Custom objects can be resized during the events step.
|
||||
// The anchor constraints must be applied on child-objects after the parent events.
|
||||
const isChildObject = instanceContainer !== instanceContainer.getScene();
|
||||
if (isChildObject) {
|
||||
this.doStepPreEvents(instanceContainer);
|
||||
}
|
||||
}
|
||||
doStepPostEvents(instanceContainer: gdjs.RuntimeInstanceContainer) {}
|
||||
|
||||
private _convertCoords(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
|
@@ -94,6 +94,16 @@ module.exports = {
|
||||
.setLabel(_('Vertical alignment'))
|
||||
.setGroup(_('Appearance'));
|
||||
|
||||
if (!objectContent.lineHeight) {
|
||||
objectContent.lineHeight = 0;
|
||||
}
|
||||
objectProperties
|
||||
.getOrCreate('lineHeight')
|
||||
.setValue(objectContent.lineHeight.toString())
|
||||
.setType('number')
|
||||
.setLabel(_('Line height (0 = default)'))
|
||||
.setGroup(_('Font'));
|
||||
|
||||
objectProperties
|
||||
.getOrCreate('fontFamily')
|
||||
.setValue(objectContent.fontFamily)
|
||||
@@ -394,6 +404,19 @@ module.exports = {
|
||||
expressionLabel: _('Get the wrapping width'),
|
||||
expressionDescription: _('Get the wrapping width'),
|
||||
},
|
||||
{
|
||||
functionName: 'LineHeight',
|
||||
iconPath: 'res/actions/characterSize24.png',
|
||||
type: 'number',
|
||||
instructionLabel: _('Line height'),
|
||||
paramLabel: _('Line height (0 = default)'),
|
||||
conditionDescription: _('Compare the base line height of the text.'),
|
||||
conditionSentence: _('the base line height'),
|
||||
actionDescription: _('Set base line height'),
|
||||
actionSentence: _('the base line height'),
|
||||
expressionLabel: _('Get the base line height'),
|
||||
expressionDescription: _('Get the base line height'),
|
||||
},
|
||||
];
|
||||
|
||||
addSettersAndGettersToObject(object, setterAndGetterProperties, 'BBText');
|
||||
|
@@ -32,6 +32,7 @@ namespace gdjs {
|
||||
wordWrap: runtimeObject._wrapping,
|
||||
wordWrapWidth: runtimeObject._wrappingWidth,
|
||||
align: runtimeObject._textAlign as PIXI.TextStyleAlign | undefined,
|
||||
lineHeight: runtimeObject._lineHeight > 0 ? runtimeObject._lineHeight : undefined,
|
||||
},
|
||||
});
|
||||
instanceContainer
|
||||
@@ -102,6 +103,13 @@ namespace gdjs {
|
||||
this._pixiObject.dirty = true;
|
||||
}
|
||||
|
||||
updateLineHeight(): void {
|
||||
//@ts-ignore Private member usage.
|
||||
this._pixiObject.textStyles.default.lineHeight =
|
||||
this._object._lineHeight;
|
||||
this._pixiObject.dirty = true;
|
||||
}
|
||||
|
||||
updatePosition(): void {
|
||||
if (this._object.isWrapping() && this._pixiObject.width !== 0) {
|
||||
const alignmentX =
|
||||
|
@@ -20,6 +20,8 @@ namespace gdjs {
|
||||
/** Alignment of the text: "left", "center" or "right" */
|
||||
align: 'left' | 'center' | 'right';
|
||||
verticalTextAlignment: 'top' | 'center' | 'bottom';
|
||||
/** Line height for multiline text (0 = default) */
|
||||
lineHeight: number;
|
||||
};
|
||||
};
|
||||
export type BBTextObjectData = ObjectData & BBTextObjectDataType;
|
||||
@@ -35,6 +37,7 @@ namespace gdjs {
|
||||
align: string;
|
||||
vta: string;
|
||||
hidden: boolean;
|
||||
lh: number;
|
||||
};
|
||||
|
||||
export type BBTextObjectNetworkSyncData = ObjectNetworkSyncData &
|
||||
@@ -61,6 +64,7 @@ namespace gdjs {
|
||||
|
||||
_textAlign: string;
|
||||
_verticalTextAlignment: string;
|
||||
_lineHeight: float;
|
||||
|
||||
_renderer: gdjs.BBTextRuntimeObjectRenderer;
|
||||
|
||||
@@ -87,6 +91,7 @@ namespace gdjs {
|
||||
this._textAlign = objectData.content.align;
|
||||
this._verticalTextAlignment =
|
||||
objectData.content.verticalTextAlignment || 'top';
|
||||
this._lineHeight = objectData.content.lineHeight || 0;
|
||||
this.hidden = !objectData.content.visible;
|
||||
|
||||
this._renderer = new gdjs.BBTextRuntimeObjectRenderer(
|
||||
@@ -142,6 +147,11 @@ namespace gdjs {
|
||||
newObjectData.content.verticalTextAlignment
|
||||
);
|
||||
}
|
||||
if (
|
||||
oldObjectData.content.lineHeight !== newObjectData.content.lineHeight
|
||||
) {
|
||||
this.setLineHeight(newObjectData.content.lineHeight);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -158,6 +168,7 @@ namespace gdjs {
|
||||
align: this._textAlign,
|
||||
vta: this._verticalTextAlignment,
|
||||
hidden: this.hidden,
|
||||
lh: this._lineHeight,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -196,6 +207,9 @@ namespace gdjs {
|
||||
if (this.hidden !== undefined) {
|
||||
this.hide(networkSyncData.hidden);
|
||||
}
|
||||
if (networkSyncData.lh !== undefined) {
|
||||
this.setLineHeight(networkSyncData.lh);
|
||||
}
|
||||
}
|
||||
|
||||
override extraInitializationFromInitialInstance(
|
||||
@@ -397,6 +411,23 @@ namespace gdjs {
|
||||
: 0)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get line height of the BBText object.
|
||||
* @return line height (0 = default)
|
||||
*/
|
||||
getLineHeight(): number {
|
||||
return this._lineHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set line height of the BBText object.
|
||||
* @param value line height (0 = default)
|
||||
*/
|
||||
setLineHeight(value: float): void {
|
||||
this._lineHeight = value;
|
||||
this._renderer.updateLineHeight();
|
||||
}
|
||||
}
|
||||
// @ts-ignore
|
||||
gdjs.registerObject('BBText::BBText', gdjs.BBTextRuntimeObject);
|
||||
|
@@ -218,11 +218,9 @@ namespace gdjs {
|
||||
this.setWrappingWidth(initialInstanceData.width);
|
||||
this.setWrapping(true);
|
||||
}
|
||||
this.setOpacity(
|
||||
initialInstanceData.opacity === undefined
|
||||
? 255
|
||||
: initialInstanceData.opacity
|
||||
);
|
||||
if (initialInstanceData.opacity !== undefined) {
|
||||
this.setOpacity(initialInstanceData.opacity);
|
||||
}
|
||||
}
|
||||
|
||||
override onDestroyed(): void {
|
||||
|
@@ -388,9 +388,6 @@ namespace gdjs {
|
||||
|
||||
return new gdjs.PromiseTask(
|
||||
(async () => {
|
||||
if (runtimeScene.getGame().isInGameEdition()) {
|
||||
return;
|
||||
}
|
||||
const scoreSavingState = (_scoreSavingStateByLeaderboard[
|
||||
leaderboardId
|
||||
] =
|
||||
@@ -426,9 +423,6 @@ namespace gdjs {
|
||||
) =>
|
||||
new gdjs.PromiseTask(
|
||||
(async () => {
|
||||
if (runtimeScene.getGame().isInGameEdition()) {
|
||||
return;
|
||||
}
|
||||
const playerId = gdjs.playerAuthentication.getUserId();
|
||||
const playerToken = gdjs.playerAuthentication.getUserToken();
|
||||
if (!playerId || !playerToken) {
|
||||
@@ -753,9 +747,6 @@ namespace gdjs {
|
||||
leaderboardId: string,
|
||||
displayLoader: boolean
|
||||
) {
|
||||
if (runtimeScene.getGame().isInGameEdition()) {
|
||||
return;
|
||||
}
|
||||
// First ensure we're not trying to display multiple times the same leaderboard (in which case
|
||||
// we "de-duplicate" the request to display it).
|
||||
if (leaderboardId === _requestedLeaderboardId) {
|
||||
|
@@ -1841,9 +1841,6 @@ namespace gdjs {
|
||||
displayLoader: boolean,
|
||||
openLobbiesPageIfFailure: boolean
|
||||
) => {
|
||||
if (runtimeScene.getGame().isInGameEdition()) {
|
||||
return;
|
||||
}
|
||||
if (isQuickJoiningTooFast()) {
|
||||
return;
|
||||
}
|
||||
@@ -1863,9 +1860,6 @@ namespace gdjs {
|
||||
displayLoader: boolean,
|
||||
openLobbiesPageIfFailure: boolean
|
||||
) => {
|
||||
if (runtimeScene.getGame().isInGameEdition()) {
|
||||
return;
|
||||
}
|
||||
if (isQuickJoiningTooFast()) {
|
||||
return;
|
||||
}
|
||||
@@ -1899,9 +1893,6 @@ namespace gdjs {
|
||||
export const openLobbiesWindow = async (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) => {
|
||||
if (runtimeScene.getGame().isInGameEdition()) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
isLobbiesWindowOpen(runtimeScene) ||
|
||||
gdjs.playerAuthentication.isAuthenticationWindowOpen()
|
||||
|
@@ -389,15 +389,26 @@ namespace gdjs {
|
||||
this.updatePosition();
|
||||
}
|
||||
|
||||
setColor(rgbOrHexColor: string): void {
|
||||
const tint = gdjs.rgbOrHexStringToNumber(rgbOrHexColor);
|
||||
this._centerSprite.tint = tint;
|
||||
setColor(rgbColor): void {
|
||||
const colors = rgbColor.split(';');
|
||||
if (colors.length < 3) {
|
||||
return;
|
||||
}
|
||||
this._centerSprite.tint = gdjs.rgbToHexNumber(
|
||||
parseInt(colors[0], 10),
|
||||
parseInt(colors[1], 10),
|
||||
parseInt(colors[2], 10)
|
||||
);
|
||||
for (
|
||||
let borderCounter = 0;
|
||||
borderCounter < this._borderSprites.length;
|
||||
borderCounter++
|
||||
) {
|
||||
this._borderSprites[borderCounter].tint = tint;
|
||||
this._borderSprites[borderCounter].tint = gdjs.rgbToHexNumber(
|
||||
parseInt(colors[0], 10),
|
||||
parseInt(colors[1], 10),
|
||||
parseInt(colors[2], 10)
|
||||
);
|
||||
}
|
||||
this._spritesContainer.cacheAsBitmap = false;
|
||||
}
|
||||
@@ -405,11 +416,11 @@ namespace gdjs {
|
||||
getColor() {
|
||||
const rgb = new PIXI.Color(this._centerSprite.tint).toRgbArray();
|
||||
return (
|
||||
Math.round(rgb[0] * 255) +
|
||||
Math.floor(rgb[0] * 255) +
|
||||
';' +
|
||||
Math.round(rgb[1] * 255) +
|
||||
Math.floor(rgb[1] * 255) +
|
||||
';' +
|
||||
Math.round(rgb[2] * 255)
|
||||
Math.floor(rgb[2] * 255)
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -53,8 +53,6 @@ namespace gdjs {
|
||||
|
||||
_renderer: gdjs.PanelSpriteRuntimeObjectRenderer;
|
||||
|
||||
_objectData: PanelSpriteObjectData;
|
||||
|
||||
/**
|
||||
* @param instanceContainer The container the object belongs to.
|
||||
* @param panelSpriteObjectData The initial properties of the object
|
||||
@@ -64,7 +62,6 @@ namespace gdjs {
|
||||
panelSpriteObjectData: PanelSpriteObjectData
|
||||
) {
|
||||
super(instanceContainer, panelSpriteObjectData);
|
||||
this._objectData = panelSpriteObjectData;
|
||||
this._rBorder = panelSpriteObjectData.rightMargin;
|
||||
this._lBorder = panelSpriteObjectData.leftMargin;
|
||||
this._tBorder = panelSpriteObjectData.topMargin;
|
||||
@@ -87,7 +84,6 @@ namespace gdjs {
|
||||
oldObjectData: PanelSpriteObjectData,
|
||||
newObjectData: PanelSpriteObjectData
|
||||
): boolean {
|
||||
this._objectData = newObjectData;
|
||||
if (oldObjectData.width !== newObjectData.width) {
|
||||
this.setWidth(newObjectData.width);
|
||||
}
|
||||
@@ -167,11 +163,9 @@ namespace gdjs {
|
||||
this.setWidth(initialInstanceData.width);
|
||||
this.setHeight(initialInstanceData.height);
|
||||
}
|
||||
this.setOpacity(
|
||||
initialInstanceData.opacity === undefined
|
||||
? 255
|
||||
: initialInstanceData.opacity
|
||||
);
|
||||
if (initialInstanceData.opacity !== undefined) {
|
||||
this.setOpacity(initialInstanceData.opacity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -250,14 +244,6 @@ namespace gdjs {
|
||||
this.setHeight(newHeight);
|
||||
}
|
||||
|
||||
override getOriginalWidth(): float {
|
||||
return this._objectData.width;
|
||||
}
|
||||
|
||||
override getOriginalHeight(): float {
|
||||
return this._objectData.height;
|
||||
}
|
||||
|
||||
setOpacity(opacity: float): void {
|
||||
if (opacity < 0) {
|
||||
opacity = 0;
|
||||
|
@@ -21,11 +21,7 @@ module.exports = {
|
||||
.setExtensionInformation(
|
||||
'Physics2',
|
||||
_('2D Physics Engine'),
|
||||
"The 2D physics engine simulates realistic object physics, with gravity, forces, collisions, joints, etc. It's perfect for 2D games that need to have realistic behaving objects and a gameplay centered around it.\n" +
|
||||
'\n' +
|
||||
'Objects like floors or wall objects should usually be set to "Static" as type. Objects that should be moveable are usually "Dynamic" (default). "Kinematic" objects (typically, players or controlled characters) are only moved by their "linear velocity" and "angular velocity" - they can interact with other objects but only these other objects will move.\n' +
|
||||
'\n' +
|
||||
'Forces (and impulses) are expressed in all conditions/expressions/actions of the 2D physics engine in Newtons (N). Typical values for a force are 10-200 N. One meter is 100 pixels by default in the game (check the world scale). Mass is expressed in kilograms (kg).',
|
||||
"The 2D physics engine simulates realistic object physics, with gravity, forces, collisions, joints, etc. It's perfect for 2D games that need to have realistic behaving objects and a gameplay centered around it.",
|
||||
'Florian Rival, Franco Maciel',
|
||||
'MIT'
|
||||
)
|
||||
@@ -531,7 +527,6 @@ module.exports = {
|
||||
physics2Behavior,
|
||||
sharedData
|
||||
)
|
||||
.markAsIrrelevantForChildObjects()
|
||||
.setIncludeFile('Extensions/Physics2Behavior/physics2runtimebehavior.js')
|
||||
.addIncludeFile('Extensions/Physics2Behavior/Box2D_v2.3.1_min.wasm.js')
|
||||
.addRequiredFile('Extensions/Physics2Behavior/Box2D_v2.3.1_min.wasm.wasm')
|
||||
|
@@ -21,11 +21,7 @@ module.exports = {
|
||||
.setExtensionInformation(
|
||||
'Physics3D',
|
||||
_('3D physics engine'),
|
||||
"The 3D physics engine simulates realistic object physics, with gravity, forces, collisions, joints, etc. It's perfect for almost all 3D games.\n" +
|
||||
'\n' +
|
||||
'Objects like floors or wall objects should usually be set to "Static" as type. Objects that should be moveable are usually "Dynamic" (default). "Kinematic" objects (typically, players or controlled characters) are only moved by their "linear velocity" and "angular velocity" - they can interact with other objects but only these other objects will move.\n' +
|
||||
'\n' +
|
||||
'Forces (and impulses) are expressed in all conditions/expressions/actions of the 3D physics engine in Newtons (N). Typical values for a force are 10-200 N. One meter is 100 pixels by default in the game (check the world scale). Mass is expressed in kilograms (kg).',
|
||||
"The 3D physics engine simulates realistic object physics, with gravity, forces, collisions, joints, etc. It's perfect for almost all 3D games.",
|
||||
'Florian Rival',
|
||||
'MIT'
|
||||
)
|
||||
@@ -679,7 +675,6 @@ module.exports = {
|
||||
behavior,
|
||||
sharedData
|
||||
)
|
||||
.markAsIrrelevantForChildObjects()
|
||||
.addIncludeFile(
|
||||
'Extensions/Physics3DBehavior/Physics3DRuntimeBehavior.js'
|
||||
)
|
||||
@@ -2048,12 +2043,7 @@ module.exports = {
|
||||
'PhysicsCharacter3D',
|
||||
_('3D physics character'),
|
||||
'PhysicsCharacter3D',
|
||||
_(
|
||||
'Allow an object to jump and run on platforms that have the 3D physics behavior' +
|
||||
'(and which are generally set to "Static" as type, unless the platform is animated/moved in events).\n' +
|
||||
'\n' +
|
||||
'This behavior is usually used with one or more "mapper" behavior to let the player move it.'
|
||||
),
|
||||
_('Jump and run on platforms.'),
|
||||
'',
|
||||
'JsPlatform/Extensions/physics_character3d.svg',
|
||||
'PhysicsCharacter3D',
|
||||
@@ -2622,7 +2612,7 @@ module.exports = {
|
||||
'JumpSustainTime',
|
||||
_('Jump sustain time'),
|
||||
_(
|
||||
'the jump sustain time of an object. This is the time during which keeping the jump button held allow the initial jump speed to be maintained'
|
||||
'the jump sustain time of an object. This is the time during which keeping the jump button held allow the initial jump speed to be maintained.'
|
||||
),
|
||||
_('the jump sustain time'),
|
||||
_('Character configuration'),
|
||||
@@ -3310,11 +3300,7 @@ module.exports = {
|
||||
'PhysicsCar3D',
|
||||
_('3D physics car'),
|
||||
'PhysicsCar3D',
|
||||
_(
|
||||
"Simulate a realistic car using the 3D physics engine. This is mostly useful for the car controlled by the player (it's usually too complex for other cars in a game).\n" +
|
||||
'\n' +
|
||||
'This behavior is usually used with one or more "mapper" behavior to let the player move it.'
|
||||
),
|
||||
_('Simulate a realistic car using the 3D physics engine.'),
|
||||
'',
|
||||
'JsPlatform/Extensions/physics_car3d.svg',
|
||||
'PhysicsCar3D',
|
||||
|
@@ -37,8 +37,7 @@ void DeclarePhysicsBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
"res/physics-deprecated32.png",
|
||||
"PhysicsBehavior",
|
||||
std::make_shared<PhysicsBehavior>(),
|
||||
std::make_shared<ScenePhysicsDatas>())
|
||||
.MarkAsIrrelevantForChildObjects();
|
||||
std::make_shared<ScenePhysicsDatas>());
|
||||
|
||||
aut.AddAction("SetStatic",
|
||||
("Make the object static"),
|
||||
|
@@ -647,9 +647,6 @@ namespace gdjs {
|
||||
export const displayAuthenticationBanner = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
if (runtimeScene.getGame().isInGameEdition()) {
|
||||
return;
|
||||
}
|
||||
if (_authenticationBanner) {
|
||||
// Banner already displayed, ensure it's visible.
|
||||
_authenticationBanner.style.opacity = '1';
|
||||
@@ -1045,10 +1042,6 @@ namespace gdjs {
|
||||
): gdjs.PromiseTask<{ status: 'logged' | 'errored' | 'dismissed' }> =>
|
||||
new gdjs.PromiseTask(
|
||||
new Promise((resolve) => {
|
||||
if (runtimeScene.getGame().isInGameEdition()) {
|
||||
resolve({ status: 'dismissed' });
|
||||
}
|
||||
|
||||
// Create the authentication container for the player to wait.
|
||||
const domElementContainer = runtimeScene
|
||||
.getGame()
|
||||
|
@@ -196,8 +196,12 @@ namespace gdjs {
|
||||
* @param initialInstanceData The extra parameters
|
||||
*/
|
||||
extraInitializationFromInitialInstance(initialInstanceData: InstanceData) {
|
||||
this.flipX(!!initialInstanceData.flippedX);
|
||||
this.flipY(!!initialInstanceData.flippedY);
|
||||
if (initialInstanceData.flippedX) {
|
||||
this.flipX(initialInstanceData.flippedX);
|
||||
}
|
||||
if (initialInstanceData.flippedY) {
|
||||
this.flipY(initialInstanceData.flippedY);
|
||||
}
|
||||
}
|
||||
|
||||
stepBehaviorsPreEvents(instanceContainer: gdjs.RuntimeInstanceContainer) {
|
||||
|
@@ -202,22 +202,28 @@ namespace gdjs {
|
||||
this._loadingSpineAtlases.clear();
|
||||
}
|
||||
|
||||
unloadResource(resourceData: ResourceData): void {
|
||||
const loadedSpineAtlas = this._loadedSpineAtlases.getFromName(
|
||||
resourceData.name
|
||||
);
|
||||
if (loadedSpineAtlas) {
|
||||
loadedSpineAtlas.dispose();
|
||||
this._loadedSpineAtlases.delete(resourceData);
|
||||
}
|
||||
/**
|
||||
* Unload the specified list of resources:
|
||||
* this clears the Spine atlases loaded in this manager.
|
||||
*
|
||||
* Usually called when scene resoures are unloaded.
|
||||
*
|
||||
* @param resourcesList The list of specific resources
|
||||
*/
|
||||
unloadResourcesList(resourcesList: ResourceData[]): void {
|
||||
resourcesList.forEach((resourceData) => {
|
||||
const loadedSpineAtlas = this._loadedSpineAtlases.get(resourceData);
|
||||
if (loadedSpineAtlas) {
|
||||
loadedSpineAtlas.dispose();
|
||||
this._loadedSpineAtlases.delete(resourceData);
|
||||
}
|
||||
|
||||
const loadingSpineAtlas = this._loadingSpineAtlases.getFromName(
|
||||
resourceData.name
|
||||
);
|
||||
if (loadingSpineAtlas) {
|
||||
loadingSpineAtlas.then((atl) => atl.dispose());
|
||||
this._loadingSpineAtlases.delete(resourceData);
|
||||
}
|
||||
const loadingSpineAtlas = this._loadingSpineAtlases.get(resourceData);
|
||||
if (loadingSpineAtlas) {
|
||||
loadingSpineAtlas.then((atl) => atl.dispose());
|
||||
this._loadingSpineAtlases.delete(resourceData);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -127,11 +127,21 @@ namespace gdjs {
|
||||
this._loadedSpines.clear();
|
||||
}
|
||||
|
||||
unloadResource(resourceData: ResourceData): void {
|
||||
const loadedSpine = this._loadedSpines.get(resourceData);
|
||||
if (loadedSpine) {
|
||||
this._loadedSpines.delete(resourceData);
|
||||
}
|
||||
/**
|
||||
* Unload the specified list of resources:
|
||||
* this clears the Spine skeleton data loaded in this manager.
|
||||
*
|
||||
* Usually called when scene resoures are unloaded.
|
||||
*
|
||||
* @param resourcesList The list of specific resources
|
||||
*/
|
||||
unloadResourcesList(resourcesList: ResourceData[]): void {
|
||||
resourcesList.forEach((resourceData) => {
|
||||
const loadedSpine = this._loadedSpines.get(resourceData);
|
||||
if (loadedSpine) {
|
||||
this._loadedSpines.delete(resourceData);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -199,13 +199,15 @@ namespace gdjs {
|
||||
this.setSize(initialInstanceData.width, initialInstanceData.height);
|
||||
this.invalidateHitboxes();
|
||||
}
|
||||
this.setOpacity(
|
||||
initialInstanceData.opacity === undefined
|
||||
? 255
|
||||
: initialInstanceData.opacity
|
||||
);
|
||||
this.flipX(!!initialInstanceData.flippedX);
|
||||
this.flipY(!!initialInstanceData.flippedY);
|
||||
if (initialInstanceData.opacity !== undefined) {
|
||||
this.setOpacity(initialInstanceData.opacity);
|
||||
}
|
||||
if (initialInstanceData.flippedX) {
|
||||
this.flipX(initialInstanceData.flippedX);
|
||||
}
|
||||
if (initialInstanceData.flippedY) {
|
||||
this.flipY(initialInstanceData.flippedY);
|
||||
}
|
||||
}
|
||||
|
||||
getDrawableX(): number {
|
||||
|
@@ -141,9 +141,7 @@ namespace gdjs {
|
||||
);
|
||||
this._borderOpacity = objectData.content.borderOpacity;
|
||||
this._borderWidth = objectData.content.borderWidth;
|
||||
this._disabled = instanceContainer.getGame().isInGameEdition()
|
||||
? true
|
||||
: objectData.content.disabled;
|
||||
this._disabled = objectData.content.disabled;
|
||||
this._readOnly = objectData.content.readOnly;
|
||||
this._spellCheck =
|
||||
objectData.content.spellCheck !== undefined
|
||||
@@ -331,11 +329,9 @@ namespace gdjs {
|
||||
this.setHeight(initialInstanceData.height);
|
||||
this._renderer.updatePadding();
|
||||
}
|
||||
this.setOpacity(
|
||||
initialInstanceData.opacity === undefined
|
||||
? 255
|
||||
: initialInstanceData.opacity
|
||||
);
|
||||
if (initialInstanceData.opacity !== undefined) {
|
||||
this.setOpacity(initialInstanceData.opacity);
|
||||
}
|
||||
}
|
||||
|
||||
onScenePaused(runtimeScene: gdjs.RuntimeScene): void {
|
||||
@@ -565,9 +561,6 @@ namespace gdjs {
|
||||
}
|
||||
|
||||
setDisabled(value: boolean) {
|
||||
if (this.getInstanceContainer().getGame().isInGameEdition()) {
|
||||
return;
|
||||
}
|
||||
this._disabled = value;
|
||||
this._renderer.updateDisabled();
|
||||
}
|
||||
|
@@ -454,8 +454,8 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
|
||||
_("Line height"),
|
||||
_("the line height of a text object"),
|
||||
_("the line height"),
|
||||
"",
|
||||
"res/actions/font24.png")
|
||||
_("Font"),
|
||||
"res/conditions/characterSize24.png")
|
||||
.AddParameter("object", _("Object"), "Text")
|
||||
.UseStandardParameters("number", gd::ParameterOptions::MakeNewOptions());
|
||||
|
||||
|
@@ -38,6 +38,14 @@ class TextObjectJsExtension : public gd::PlatformExtension {
|
||||
GetAllExpressionsForObject("TextObject::Text")["FontSize"]
|
||||
.SetFunctionName("getCharacterSize");
|
||||
|
||||
GetAllActionsForObject("TextObject::Text")["TextObject::Text::SetLineHeight"]
|
||||
.SetFunctionName("setLineHeight")
|
||||
.SetGetter("getLineHeight");
|
||||
GetAllConditionsForObject("TextObject::Text")["TextObject::Text::LineHeight"]
|
||||
.SetFunctionName("getLineHeight");
|
||||
GetAllExpressionsForObject("TextObject::Text")["LineHeight"]
|
||||
.SetFunctionName("getLineHeight");
|
||||
|
||||
GetAllActionsForObject("TextObject::Text")["TextObject::Font"]
|
||||
.SetFunctionName("setFontName");
|
||||
|
||||
@@ -96,14 +104,6 @@ class TextObjectJsExtension : public gd::PlatformExtension {
|
||||
.SetFunctionName("setOutlineThickness")
|
||||
.SetGetter("getOutlineThickness");
|
||||
|
||||
GetAllExpressionsForObject("TextObject::Text")["LineHeight"]
|
||||
.SetFunctionName("getLineHeight");
|
||||
GetAllConditionsForObject("TextObject::Text")["TextObject::Text::LineHeight"]
|
||||
.SetFunctionName("getLineHeight");
|
||||
GetAllActionsForObject("TextObject::Text")["TextObject::Text::SetLineHeight"]
|
||||
.SetFunctionName("setLineHeight")
|
||||
.SetGetter("getLineHeight");
|
||||
|
||||
GetAllActionsForObject("TextObject::Text")["TextObject::ShowShadow"]
|
||||
.SetFunctionName("showShadow");
|
||||
GetAllConditionsForObject("TextObject::Text")["TextObject::Text::IsShadowEnabled"]
|
||||
|
@@ -20,7 +20,6 @@ using namespace std;
|
||||
TextObject::TextObject()
|
||||
: text("Text"),
|
||||
characterSize(20),
|
||||
lineHeight(0),
|
||||
fontName(""),
|
||||
smoothed(true),
|
||||
bold(false),
|
||||
@@ -37,7 +36,8 @@ TextObject::TextObject()
|
||||
shadowOpacity(127),
|
||||
shadowAngle(90),
|
||||
shadowDistance(4),
|
||||
shadowBlurRadius(2) {}
|
||||
shadowBlurRadius(2),
|
||||
lineHeight(0) {}
|
||||
|
||||
TextObject::~TextObject() {};
|
||||
|
||||
@@ -51,10 +51,6 @@ bool TextObject::UpdateProperty(const gd::String& propertyName,
|
||||
characterSize = newValue.To<double>();
|
||||
return true;
|
||||
}
|
||||
if (propertyName == "lineHeight") {
|
||||
lineHeight = newValue.To<double>();
|
||||
return true;
|
||||
}
|
||||
if (propertyName == "font") {
|
||||
fontName = newValue;
|
||||
return true;
|
||||
@@ -115,6 +111,10 @@ bool TextObject::UpdateProperty(const gd::String& propertyName,
|
||||
shadowBlurRadius = newValue.To<double>();
|
||||
return true;
|
||||
}
|
||||
if (propertyName == "lineHeight") {
|
||||
lineHeight = newValue.To<double>();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -134,13 +134,6 @@ std::map<gd::String, gd::PropertyDescriptor> TextObject::GetProperties() const {
|
||||
.SetMeasurementUnit(gd::MeasurementUnit::GetPixel())
|
||||
.SetGroup(_("Font"));
|
||||
|
||||
objectProperties["lineHeight"]
|
||||
.SetValue(gd::String::From(lineHeight))
|
||||
.SetType("number")
|
||||
.SetLabel(_("Line height"))
|
||||
.SetMeasurementUnit(gd::MeasurementUnit::GetPixel())
|
||||
.SetGroup(_("Font"));
|
||||
|
||||
objectProperties["font"]
|
||||
.SetValue(fontName)
|
||||
.SetType("resource")
|
||||
@@ -267,6 +260,13 @@ std::map<gd::String, gd::PropertyDescriptor> TextObject::GetProperties() const {
|
||||
.SetAdvanced()
|
||||
.SetQuickCustomizationVisibility(gd::QuickCustomization::Hidden);
|
||||
|
||||
objectProperties["lineHeight"]
|
||||
.SetValue(gd::String::From(lineHeight))
|
||||
.SetType("number")
|
||||
.SetLabel(_("Line height"))
|
||||
.SetMeasurementUnit(gd::MeasurementUnit::GetPixel())
|
||||
.SetGroup(_("Font"));
|
||||
|
||||
return objectProperties;
|
||||
}
|
||||
|
||||
@@ -283,7 +283,6 @@ void TextObject::DoUnserializeFrom(gd::Project& project,
|
||||
SetCharacterSize(content.GetChild("characterSize", 0, "CharacterSize")
|
||||
.GetValue()
|
||||
.GetInt());
|
||||
SetLineHeight(content.GetDoubleAttribute("lineHeight", 0));
|
||||
smoothed = content.GetBoolAttribute("smoothed");
|
||||
bold = content.GetBoolAttribute("bold");
|
||||
italic = content.GetBoolAttribute("italic");
|
||||
@@ -317,6 +316,8 @@ void TextObject::DoUnserializeFrom(gd::Project& project,
|
||||
SetShadowAngle(content.GetIntAttribute("shadowAngle", 90));
|
||||
SetShadowDistance(content.GetIntAttribute("shadowDistance", 4));
|
||||
SetShadowBlurRadius(content.GetIntAttribute("shadowBlurRadius", 2));
|
||||
|
||||
SetLineHeight(content.GetDoubleAttribute("lineHeight", 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,7 +353,6 @@ void TextObject::DoSerializeTo(gd::SerializerElement& element) const {
|
||||
content.AddChild("textAlignment").SetValue(GetTextAlignment());
|
||||
content.AddChild("verticalTextAlignment").SetValue(GetVerticalTextAlignment());
|
||||
content.AddChild("characterSize").SetValue(GetCharacterSize());
|
||||
content.AddChild("lineHeight").SetValue(GetLineHeight());
|
||||
content.AddChild("color").SetValue(GetColor());
|
||||
|
||||
content.SetAttribute("smoothed", smoothed);
|
||||
@@ -370,6 +370,7 @@ void TextObject::DoSerializeTo(gd::SerializerElement& element) const {
|
||||
content.SetAttribute("shadowAngle", shadowAngle);
|
||||
content.SetAttribute("shadowDistance", shadowDistance);
|
||||
content.SetAttribute("shadowBlurRadius", shadowBlurRadius);
|
||||
content.SetAttribute("lineHeight", lineHeight);
|
||||
}
|
||||
|
||||
void TextObject::ExposeResources(gd::ArbitraryResourceWorker& worker) {
|
||||
|
@@ -49,12 +49,6 @@ class GD_EXTENSION_API TextObject : public gd::ObjectConfiguration {
|
||||
*/
|
||||
inline double GetCharacterSize() const { return characterSize; };
|
||||
|
||||
/** \brief Change the line height. */
|
||||
inline void SetLineHeight(double value) { lineHeight = value; };
|
||||
|
||||
/** \brief Get the line height. */
|
||||
inline double GetLineHeight() const { return lineHeight; };
|
||||
|
||||
/** \brief Return the name of the font resource used for the text.
|
||||
*/
|
||||
inline const gd::String& GetFontName() const { return fontName; };
|
||||
@@ -119,6 +113,9 @@ class GD_EXTENSION_API TextObject : public gd::ObjectConfiguration {
|
||||
void SetShadowBlurRadius(double value) { shadowBlurRadius = value; };
|
||||
double GetShadowBlurRadius() const { return shadowBlurRadius; };
|
||||
|
||||
void SetLineHeight(double value) { lineHeight = value; };
|
||||
double GetLineHeight() const { return lineHeight; };
|
||||
|
||||
private:
|
||||
virtual void DoUnserializeFrom(gd::Project& project,
|
||||
const gd::SerializerElement& element) override;
|
||||
@@ -126,7 +123,6 @@ class GD_EXTENSION_API TextObject : public gd::ObjectConfiguration {
|
||||
|
||||
gd::String text;
|
||||
double characterSize;
|
||||
double lineHeight;
|
||||
gd::String fontName;
|
||||
bool smoothed;
|
||||
bool bold, italic, underlined;
|
||||
@@ -144,4 +140,5 @@ class GD_EXTENSION_API TextObject : public gd::ObjectConfiguration {
|
||||
double shadowAngle;
|
||||
double shadowDistance;
|
||||
double shadowBlurRadius;
|
||||
double lineHeight;
|
||||
};
|
||||
|
@@ -64,6 +64,7 @@ namespace gdjs {
|
||||
style.wordWrap = this._object._wrapping;
|
||||
style.wordWrapWidth = this._object._wrappingWidth;
|
||||
style.breakWords = true;
|
||||
style.lineHeight = this._object._lineHeight > 0 ? this._object._lineHeight : undefined;
|
||||
style.stroke = gdjs.rgbToHexNumber(
|
||||
this._object._outlineColor[0],
|
||||
this._object._outlineColor[1],
|
||||
@@ -86,7 +87,6 @@ namespace gdjs {
|
||||
? style.dropShadowDistance + style.dropShadowBlur
|
||||
: 0;
|
||||
style.padding = Math.ceil(this._object._padding + extraPaddingForShadow);
|
||||
style.lineHeight = this._object._lineHeight;
|
||||
|
||||
// Prevent spikey outlines by adding a miter limit
|
||||
style.miterLimit = 3;
|
||||
|
@@ -22,8 +22,7 @@ namespace gdjs {
|
||||
text: string;
|
||||
textAlignment: string;
|
||||
verticalTextAlignment: string;
|
||||
/** The line height */
|
||||
lineHeight: float;
|
||||
lineHeight: number;
|
||||
|
||||
isOutlineEnabled: boolean;
|
||||
outlineThickness: float;
|
||||
@@ -36,6 +35,7 @@ namespace gdjs {
|
||||
shadowDistance: float;
|
||||
shadowAngle: float;
|
||||
shadowBlurRadius: float;
|
||||
lineHeight: float;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -92,6 +92,7 @@ namespace gdjs {
|
||||
_wrapping: boolean = false;
|
||||
// A wrapping of 1 makes games crash on Firefox
|
||||
_wrappingWidth: float = 100;
|
||||
_lineHeight: float;
|
||||
|
||||
_isOutlineEnabled: boolean;
|
||||
_outlineThickness: float;
|
||||
@@ -104,9 +105,8 @@ namespace gdjs {
|
||||
_shadowAngle: float;
|
||||
_shadowBlur: float;
|
||||
|
||||
_lineHeight: float;
|
||||
|
||||
_padding: integer = 5;
|
||||
_lineHeight: float = 0;
|
||||
_str: string;
|
||||
_renderer: gdjs.TextRuntimeObjectRenderer;
|
||||
|
||||
@@ -133,6 +133,7 @@ namespace gdjs {
|
||||
this._str = content.text;
|
||||
this._textAlign = content.textAlignment || 'left';
|
||||
this._verticalTextAlignment = content.verticalTextAlignment || 'top';
|
||||
this._lineHeight = content.lineHeight || 0;
|
||||
|
||||
this._isOutlineEnabled = content.isOutlineEnabled;
|
||||
this._outlineThickness = content.outlineThickness;
|
||||
@@ -144,7 +145,6 @@ namespace gdjs {
|
||||
this._shadowDistance = content.shadowDistance;
|
||||
this._shadowBlur = content.shadowBlurRadius;
|
||||
this._shadowAngle = content.shadowAngle;
|
||||
this._lineHeight = content.lineHeight || 0;
|
||||
|
||||
this._renderer = new gdjs.TextRuntimeObjectRenderer(
|
||||
this,
|
||||
@@ -217,8 +217,8 @@ namespace gdjs {
|
||||
if (oldContent.shadowBlurRadius !== newContent.shadowBlurRadius) {
|
||||
this.setShadowBlurRadius(newContent.shadowBlurRadius);
|
||||
}
|
||||
if ((oldContent.lineHeight || 0) !== (newContent.lineHeight || 0)) {
|
||||
this.setLineHeight(newContent.lineHeight || 0);
|
||||
if (oldContent.lineHeight !== newContent.lineHeight) {
|
||||
this.setLineHeight(newContent.lineHeight);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -247,8 +247,8 @@ namespace gdjs {
|
||||
shd: this._shadowDistance,
|
||||
sha: this._shadowAngle,
|
||||
shb: this._shadowBlur,
|
||||
lh: this._lineHeight,
|
||||
pad: this._padding,
|
||||
lh: this._lineHeight,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -322,21 +322,19 @@ namespace gdjs {
|
||||
if (networkSyncData.shb !== undefined) {
|
||||
this.setShadowBlurRadius(networkSyncData.shb);
|
||||
}
|
||||
if (networkSyncData.lh !== undefined) {
|
||||
this.setLineHeight(networkSyncData.lh);
|
||||
}
|
||||
if (networkSyncData.pad !== undefined) {
|
||||
this.setPadding(networkSyncData.pad);
|
||||
}
|
||||
if (networkSyncData.lh !== undefined) {
|
||||
this.setLineHeight(networkSyncData.lh);
|
||||
}
|
||||
}
|
||||
|
||||
override getRendererObject() {
|
||||
return this._renderer.getRendererObject();
|
||||
}
|
||||
|
||||
override updatePreRender(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer
|
||||
): void {
|
||||
override update(instanceContainer: gdjs.RuntimeInstanceContainer): void {
|
||||
this._renderer.ensureUpToDate();
|
||||
}
|
||||
|
||||
@@ -354,11 +352,9 @@ namespace gdjs {
|
||||
} else {
|
||||
this.setWrapping(false);
|
||||
}
|
||||
this.setOpacity(
|
||||
initialInstanceData.opacity === undefined
|
||||
? 255
|
||||
: initialInstanceData.opacity
|
||||
);
|
||||
if (initialInstanceData.opacity !== undefined) {
|
||||
this.setOpacity(initialInstanceData.opacity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -461,22 +457,6 @@ namespace gdjs {
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line height of the text.
|
||||
*/
|
||||
getLineHeight(): float {
|
||||
return this._lineHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the line height of the text.
|
||||
* @param value The new line height for the text.
|
||||
*/
|
||||
setLineHeight(value: float): void {
|
||||
this._lineHeight = value;
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the resource to use for the font.
|
||||
* @param fontResourceName The name of the font resource.
|
||||
@@ -606,10 +586,16 @@ namespace gdjs {
|
||||
|
||||
/**
|
||||
* Change the text color.
|
||||
* @param rgbOrHexColor color as a "R;G;B" string, for example: "255;0;0"
|
||||
* @param colorString color as a "R;G;B" string, for example: "255;0;0"
|
||||
*/
|
||||
setColor(rgbOrHexColor: string): void {
|
||||
this._color = gdjs.rgbOrHexToRGBColor(rgbOrHexColor);
|
||||
setColor(colorString: string): void {
|
||||
const color = colorString.split(';');
|
||||
if (color.length < 3) {
|
||||
return;
|
||||
}
|
||||
this._color[0] = parseInt(color[0], 10);
|
||||
this._color[1] = parseInt(color[1], 10);
|
||||
this._color[2] = parseInt(color[2], 10);
|
||||
this._useGradient = false;
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
@@ -718,12 +704,18 @@ namespace gdjs {
|
||||
|
||||
/**
|
||||
* Set the outline for the text object.
|
||||
* @param rgbOrHexColor color as a "R;G;B" string, for example: "255;0;0"
|
||||
* @param str color as a "R;G;B" string, for example: "255;0;0"
|
||||
* @param thickness thickness of the outline (0 = disabled)
|
||||
* @deprecated Prefer independent setters.
|
||||
*/
|
||||
setOutline(rgbOrHexColor: string, thickness: number): void {
|
||||
this._outlineColor = gdjs.rgbOrHexToRGBColor(rgbOrHexColor);
|
||||
setOutline(str: string, thickness: number): void {
|
||||
const color = str.split(';');
|
||||
if (color.length < 3) {
|
||||
return;
|
||||
}
|
||||
this._outlineColor[0] = parseInt(color[0], 10);
|
||||
this._outlineColor[1] = parseInt(color[1], 10);
|
||||
this._outlineColor[2] = parseInt(color[2], 10);
|
||||
this._outlineThickness = thickness;
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
@@ -765,19 +757,25 @@ namespace gdjs {
|
||||
|
||||
/**
|
||||
* Set the shadow for the text object.
|
||||
* @param rgbOrHexColor color as a "R;G;B" string, for example: "255;0;0"
|
||||
* @param str color as a "R;G;B" string, for example: "255;0;0"
|
||||
* @param distance distance between the shadow and the text, in pixels.
|
||||
* @param blur amount of shadow blur, in pixels.
|
||||
* @param angle shadow offset direction, in degrees.
|
||||
* @deprecated Prefer independent setters.
|
||||
*/
|
||||
setShadow(
|
||||
rgbOrHexColor: string,
|
||||
str: string,
|
||||
distance: number,
|
||||
blur: integer,
|
||||
angle: float
|
||||
): void {
|
||||
this._shadowColor = gdjs.rgbOrHexToRGBColor(rgbOrHexColor);
|
||||
const color = str.split(';');
|
||||
if (color.length < 3) {
|
||||
return;
|
||||
}
|
||||
this._shadowColor[0] = parseInt(color[0], 10);
|
||||
this._shadowColor[1] = parseInt(color[1], 10);
|
||||
this._shadowColor[2] = parseInt(color[2], 10);
|
||||
this._shadowDistance = distance;
|
||||
this._shadowBlur = blur;
|
||||
this._shadowAngle = angle;
|
||||
@@ -890,18 +888,38 @@ namespace gdjs {
|
||||
strThirdColor: string,
|
||||
strFourthColor: string
|
||||
): void {
|
||||
const colorFirst = strFirstColor.split(';');
|
||||
const colorSecond = strSecondColor.split(';');
|
||||
const colorThird = strThirdColor.split(';');
|
||||
const colorFourth = strFourthColor.split(';');
|
||||
this._gradient = [];
|
||||
if (strFirstColor) {
|
||||
this._gradient.push(gdjs.rgbOrHexToRGBColor(strFirstColor));
|
||||
if (colorFirst.length == 3) {
|
||||
this._gradient.push([
|
||||
parseInt(colorFirst[0], 10),
|
||||
parseInt(colorFirst[1], 10),
|
||||
parseInt(colorFirst[2], 10),
|
||||
]);
|
||||
}
|
||||
if (strSecondColor) {
|
||||
this._gradient.push(gdjs.rgbOrHexToRGBColor(strSecondColor));
|
||||
if (colorSecond.length == 3) {
|
||||
this._gradient.push([
|
||||
parseInt(colorSecond[0], 10),
|
||||
parseInt(colorSecond[1], 10),
|
||||
parseInt(colorSecond[2], 10),
|
||||
]);
|
||||
}
|
||||
if (strThirdColor) {
|
||||
this._gradient.push(gdjs.rgbOrHexToRGBColor(strThirdColor));
|
||||
if (colorThird.length == 3) {
|
||||
this._gradient.push([
|
||||
parseInt(colorThird[0], 10),
|
||||
parseInt(colorThird[1], 10),
|
||||
parseInt(colorThird[2], 10),
|
||||
]);
|
||||
}
|
||||
if (strFourthColor) {
|
||||
this._gradient.push(gdjs.rgbOrHexToRGBColor(strFourthColor));
|
||||
if (colorFourth.length == 3) {
|
||||
this._gradient.push([
|
||||
parseInt(colorFourth[0], 10),
|
||||
parseInt(colorFourth[1], 10),
|
||||
parseInt(colorFourth[2], 10),
|
||||
]);
|
||||
}
|
||||
this._gradientType = strGradientType;
|
||||
this._useGradient = this._gradient.length > 1 ? true : false;
|
||||
@@ -924,6 +942,23 @@ namespace gdjs {
|
||||
this._padding = value;
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line height of the text object.
|
||||
* @return the line height
|
||||
*/
|
||||
getLineHeight(): number {
|
||||
return this._lineHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the line height of the text object.
|
||||
* @param value the line height
|
||||
*/
|
||||
setLineHeight(value: float): void {
|
||||
this._lineHeight = value;
|
||||
this._renderer.updateStyle();
|
||||
}
|
||||
}
|
||||
gdjs.registerObject('TextObject::Text', gdjs.TextRuntimeObject);
|
||||
}
|
||||
|
@@ -205,11 +205,9 @@ namespace gdjs {
|
||||
this.setWidth(initialInstanceData.width);
|
||||
this.setHeight(initialInstanceData.height);
|
||||
}
|
||||
this.setOpacity(
|
||||
initialInstanceData.opacity === undefined
|
||||
? 255
|
||||
: initialInstanceData.opacity
|
||||
);
|
||||
if (initialInstanceData.opacity !== undefined) {
|
||||
this.setOpacity(initialInstanceData.opacity);
|
||||
}
|
||||
|
||||
// 4. Update position (calculations based on renderer's dimensions).
|
||||
this._renderer.updatePosition();
|
||||
@@ -417,14 +415,6 @@ namespace gdjs {
|
||||
return this._renderer.getHeight();
|
||||
}
|
||||
|
||||
override getOriginalWidth(): float {
|
||||
return this._renderer.getTileMapWidth();
|
||||
}
|
||||
|
||||
override getOriginalHeight(): float {
|
||||
return this._renderer.getTileMapHeight();
|
||||
}
|
||||
|
||||
getScaleX(): float {
|
||||
return this._renderer.getScaleX();
|
||||
}
|
||||
|
@@ -193,11 +193,9 @@ namespace gdjs {
|
||||
this.setWidth(initialInstanceData.width);
|
||||
this.setHeight(initialInstanceData.height);
|
||||
}
|
||||
this.setOpacity(
|
||||
initialInstanceData.opacity === undefined
|
||||
? 255
|
||||
: initialInstanceData.opacity
|
||||
);
|
||||
if (initialInstanceData.opacity !== undefined) {
|
||||
this.setOpacity(initialInstanceData.opacity);
|
||||
}
|
||||
}
|
||||
|
||||
private _updateTileMap(): void {
|
||||
@@ -339,14 +337,6 @@ namespace gdjs {
|
||||
this.setHeight(newHeight);
|
||||
}
|
||||
|
||||
override getOriginalWidth(): float {
|
||||
return this._renderer.getTileMapWidth();
|
||||
}
|
||||
|
||||
override getOriginalHeight(): float {
|
||||
return this._renderer.getTileMapHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the scale of the object (or the geometric mean of the X and Y scale in case they are different).
|
||||
*
|
||||
|
@@ -92,18 +92,28 @@ namespace gdjs {
|
||||
-this._object._yOffset % this._tiledSprite.texture.height;
|
||||
}
|
||||
|
||||
setColor(rgbOrHexColor: string): void {
|
||||
this._tiledSprite.tint = gdjs.rgbOrHexStringToNumber(rgbOrHexColor);
|
||||
setColor(rgbColor: string): void {
|
||||
const colors = rgbColor.split(';');
|
||||
if (colors.length < 3) {
|
||||
return;
|
||||
}
|
||||
this._tiledSprite.tint =
|
||||
'0x' +
|
||||
gdjs.rgbToHex(
|
||||
parseInt(colors[0], 10),
|
||||
parseInt(colors[1], 10),
|
||||
parseInt(colors[2], 10)
|
||||
);
|
||||
}
|
||||
|
||||
getColor() {
|
||||
const rgb = new PIXI.Color(this._tiledSprite.tint).toRgbArray();
|
||||
return (
|
||||
Math.round(rgb[0] * 255) +
|
||||
Math.floor(rgb[0] * 255) +
|
||||
';' +
|
||||
Math.round(rgb[1] * 255) +
|
||||
Math.floor(rgb[1] * 255) +
|
||||
';' +
|
||||
Math.round(rgb[2] * 255)
|
||||
Math.floor(rgb[2] * 255)
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -42,8 +42,6 @@ namespace gdjs {
|
||||
|
||||
_renderer: gdjs.TiledSpriteRuntimeObjectRenderer;
|
||||
|
||||
_objectData: TiledSpriteObjectData;
|
||||
|
||||
/**
|
||||
* @param instanceContainer The container the object belongs to.
|
||||
* @param tiledSpriteObjectData The initial properties of the object
|
||||
@@ -53,7 +51,6 @@ namespace gdjs {
|
||||
tiledSpriteObjectData: TiledSpriteObjectData
|
||||
) {
|
||||
super(instanceContainer, tiledSpriteObjectData);
|
||||
this._objectData = tiledSpriteObjectData;
|
||||
this._renderer = new gdjs.TiledSpriteRuntimeObjectRenderer(
|
||||
this,
|
||||
instanceContainer,
|
||||
@@ -69,7 +66,6 @@ namespace gdjs {
|
||||
}
|
||||
|
||||
updateFromObjectData(oldObjectData, newObjectData): boolean {
|
||||
this._objectData = newObjectData;
|
||||
if (oldObjectData.texture !== newObjectData.texture) {
|
||||
this.setTexture(newObjectData.texture, this.getRuntimeScene());
|
||||
}
|
||||
@@ -130,11 +126,9 @@ namespace gdjs {
|
||||
this.setWidth(initialInstanceData.width);
|
||||
this.setHeight(initialInstanceData.height);
|
||||
}
|
||||
this.setOpacity(
|
||||
initialInstanceData.opacity === undefined
|
||||
? 255
|
||||
: initialInstanceData.opacity
|
||||
);
|
||||
if (initialInstanceData.opacity !== undefined) {
|
||||
this.setOpacity(initialInstanceData.opacity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -226,14 +220,6 @@ namespace gdjs {
|
||||
this.setHeight(height);
|
||||
}
|
||||
|
||||
override getOriginalWidth(): float {
|
||||
return this._objectData.width;
|
||||
}
|
||||
|
||||
override getOriginalHeight(): float {
|
||||
return this._objectData.height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the offset on the X-axis when displaying the image of the Tiled Sprite object.
|
||||
* @param xOffset The new offset on the X-axis.
|
||||
|
@@ -347,21 +347,17 @@ describe('gdjs.TweenRuntimeBehavior', () => {
|
||||
// Check that there is no NaN.
|
||||
for (let i = 0; i < 11; i++) {
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
// The tween tries to set the camera zoom to 0, but it has no effect
|
||||
// because it doesn't make sense.
|
||||
expect(camera.getCameraZoom(runtimeScene, '', 0)).to.be(1);
|
||||
expect(camera.getCameraZoom(runtimeScene, '', 0)).to.be(0);
|
||||
}
|
||||
});
|
||||
|
||||
it('can tween a layer camera zoom from 0', () => {
|
||||
// The zoom stays at 1 because 0 doesn't make sense.
|
||||
camera.setCameraZoom(runtimeScene, 0, '', 0);
|
||||
// Here, it actually tweens from 1 to 1.
|
||||
tween.tweenCameraZoom2(runtimeScene, 'MyTween', 1, '', 'linear', 0.25);
|
||||
// A camera zoom of 0 doesn't make sense.
|
||||
// Check that there is no NaN.
|
||||
for (let i = 0; i < 11; i++) {
|
||||
expect(camera.getCameraZoom(runtimeScene, '', 0)).to.be(1);
|
||||
expect(camera.getCameraZoom(runtimeScene, '', 0)).to.be(0);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
}
|
||||
expect(camera.getCameraZoom(runtimeScene, '', 0)).to.be(1);
|
||||
|
@@ -145,7 +145,6 @@ describe('gdjs.TweenRuntimeBehavior', () => {
|
||||
shadowDistance: 4,
|
||||
shadowAngle: 90,
|
||||
shadowBlurRadius: 2,
|
||||
lineHeight: 0,
|
||||
},
|
||||
});
|
||||
runtimeScene.addObject(object);
|
||||
|
@@ -145,7 +145,6 @@ describe('gdjs.TweenRuntimeBehavior', () => {
|
||||
shadowDistance: 4,
|
||||
shadowAngle: 90,
|
||||
shadowBlurRadius: 2,
|
||||
lineHeight: 0,
|
||||
},
|
||||
});
|
||||
runtimeScene.addObject(object);
|
||||
|
@@ -1326,11 +1326,11 @@ namespace gdjs {
|
||||
lightness
|
||||
);
|
||||
owner.setColor(
|
||||
Math.round(rgbFromHslColor[0]) +
|
||||
Math.floor(rgbFromHslColor[0]) +
|
||||
';' +
|
||||
Math.round(rgbFromHslColor[1]) +
|
||||
Math.floor(rgbFromHslColor[1]) +
|
||||
';' +
|
||||
Math.round(rgbFromHslColor[2])
|
||||
Math.floor(rgbFromHslColor[2])
|
||||
);
|
||||
};
|
||||
} else {
|
||||
@@ -1439,11 +1439,12 @@ namespace gdjs {
|
||||
if (!isColorable(this.owner)) return;
|
||||
const owner = this.owner;
|
||||
|
||||
const rgbFromColor = gdjs.rgbOrHexToRGBColor(owner.getColor());
|
||||
const rgbFromColor: string[] = owner.getColor().split(';');
|
||||
if (rgbFromColor.length < 3) return;
|
||||
const hslFromColor = gdjs.evtTools.tween.rgbToHsl(
|
||||
rgbFromColor[0],
|
||||
rgbFromColor[1],
|
||||
rgbFromColor[2]
|
||||
parseFloat(rgbFromColor[0]),
|
||||
parseFloat(rgbFromColor[1]),
|
||||
parseFloat(rgbFromColor[2])
|
||||
);
|
||||
|
||||
const toH = animateHue ? toHue : hslFromColor[0];
|
||||
@@ -1473,11 +1474,11 @@ namespace gdjs {
|
||||
);
|
||||
|
||||
owner.setColor(
|
||||
Math.round(rgbFromHslColor[0]) +
|
||||
Math.floor(rgbFromHslColor[0]) +
|
||||
';' +
|
||||
Math.round(rgbFromHslColor[1]) +
|
||||
Math.floor(rgbFromHslColor[1]) +
|
||||
';' +
|
||||
Math.round(rgbFromHslColor[2])
|
||||
Math.floor(rgbFromHslColor[2])
|
||||
);
|
||||
},
|
||||
|
||||
|
@@ -146,11 +146,9 @@ namespace gdjs {
|
||||
this.setWidth(initialInstanceData.width);
|
||||
this.setHeight(initialInstanceData.height);
|
||||
}
|
||||
this.setOpacity(
|
||||
initialInstanceData.opacity === undefined
|
||||
? 255
|
||||
: initialInstanceData.opacity
|
||||
);
|
||||
if (initialInstanceData.opacity !== undefined) {
|
||||
this.setOpacity(initialInstanceData.opacity);
|
||||
}
|
||||
}
|
||||
|
||||
onDestroyed(): void {
|
||||
|
@@ -145,19 +145,16 @@ gd::String EventsCodeGenerator::GenerateEventsFunctionCode(
|
||||
gd::DiagnosticReport diagnosticReport;
|
||||
codeGenerator.SetDiagnosticReport(&diagnosticReport);
|
||||
|
||||
// Generate the code setting up the context of the function.
|
||||
gd::String fullPreludeCode = "let scopeInstanceContainer = null;\n" +
|
||||
codeGenerator.GenerateFreeEventsFunctionContext(
|
||||
eventsFunctionsExtension, eventsFunction,
|
||||
"runtimeScene.getOnceTriggers()");
|
||||
|
||||
gd::String output = GenerateEventsListCompleteFunctionCode(
|
||||
codeGenerator, codeGenerator.GetCodeNamespaceAccessor() + "func",
|
||||
codeGenerator.GenerateEventsFunctionParameterDeclarationsList(
|
||||
eventsFunction.GetParametersForEvents(
|
||||
eventsFunctionsExtension.GetEventsFunctions()),
|
||||
0, true),
|
||||
fullPreludeCode, eventsFunction.GetEvents(), "",
|
||||
codeGenerator.GenerateFreeEventsFunctionContext(
|
||||
eventsFunctionsExtension, eventsFunction,
|
||||
"runtimeScene.getOnceTriggers()"),
|
||||
eventsFunction.GetEvents(), "",
|
||||
codeGenerator.GenerateEventsFunctionReturn(eventsFunction));
|
||||
|
||||
// TODO: the editor should pass the diagnostic report and display it to the
|
||||
@@ -212,7 +209,6 @@ gd::String EventsCodeGenerator::GenerateBehaviorEventsFunctionCode(
|
||||
// TODO: this should be renamed to "instanceContainer" and have the code generation
|
||||
// adapted for this (rely less on `gdjs.RuntimeScene`, and more on `RuntimeInstanceContainer`).
|
||||
"var runtimeScene = this._runtimeScene;\n" +
|
||||
"let scopeInstanceContainer = null;\n" +
|
||||
// By convention of Behavior Events Function, the object is accessible
|
||||
// as a parameter called "Object", and thisObjectList is an array
|
||||
// containing it (for faster access, without having to go through the
|
||||
@@ -298,7 +294,6 @@ gd::String EventsCodeGenerator::GenerateObjectEventsFunctionCode(
|
||||
// TODO: this should be renamed to "instanceContainer" and have the code generation
|
||||
// adapted for this (rely less on `gdjs.RuntimeScene`, and more on `RuntimeInstanceContainer`).
|
||||
"var runtimeScene = this._instanceContainer;\n" +
|
||||
"let scopeInstanceContainer = this._instanceContainer;\n" +
|
||||
// By convention of Object Events Function, the object is accessible
|
||||
// as a parameter called "Object", and thisObjectList is an array
|
||||
// containing it (for faster access, without having to go through the
|
||||
@@ -629,11 +624,7 @@ gd::String EventsCodeGenerator::GenerateEventsFunctionContext(
|
||||
// the cost of creating/storing it for each events function might not
|
||||
// be worth it.
|
||||
" if (objectsList) {\n" +
|
||||
" const object = parentEventsFunctionContext && "
|
||||
// Check if `objectName` is not a child object and is passed by
|
||||
// parameter from a parent instance container.
|
||||
"!(scopeInstanceContainer && "
|
||||
"scopeInstanceContainer.isObjectRegistered(objectName)) ?\n" +
|
||||
" const object = parentEventsFunctionContext ?\n" +
|
||||
" "
|
||||
"parentEventsFunctionContext.createObject(objectsList.firstKey()) "
|
||||
":\n" +
|
||||
@@ -643,7 +634,7 @@ gd::String EventsCodeGenerator::GenerateEventsFunctionContext(
|
||||
" objectsList.get(objectsList.firstKey()).push(object);\n" +
|
||||
" "
|
||||
"eventsFunctionContext._objectArraysMap[objectName].push(object);\n" +
|
||||
" }\n" + " return object;\n" + " }\n" +
|
||||
" }\n" + " return object;" + " }\n" +
|
||||
// Unknown object, don't create anything:
|
||||
" return null;\n" +
|
||||
" },\n"
|
||||
@@ -655,11 +646,7 @@ gd::String EventsCodeGenerator::GenerateEventsFunctionContext(
|
||||
"eventsFunctionContext._objectsMap[objectName];\n" +
|
||||
" let count = 0;\n" + " if (objectsList) {\n" +
|
||||
" for(const objectName in objectsList.items)\n" +
|
||||
" count += parentEventsFunctionContext && "
|
||||
// Check if `objectName` is not a child object and is passed by
|
||||
// parameter from a parent instance container.
|
||||
"!(scopeInstanceContainer && "
|
||||
"scopeInstanceContainer.isObjectRegistered(objectName)) ?\n" +
|
||||
" count += parentEventsFunctionContext ?\n" +
|
||||
"parentEventsFunctionContext.getInstancesCountOnScene(objectName) "
|
||||
":\n" +
|
||||
" runtimeScene.getInstancesCountOnScene(objectName);\n" +
|
||||
|
@@ -841,23 +841,13 @@ CommonInstructionsExtension::CommonInstructionsExtension() {
|
||||
event.GetParameterObjects(),
|
||||
parentContext.GetCurrentObject());
|
||||
|
||||
if (realObjects.size() == 1) {
|
||||
parentContext.ObjectsListNeeded(realObjects[0]);
|
||||
callingCode += "var objects = [];\n";
|
||||
for (unsigned int i = 0; i < realObjects.size(); ++i) {
|
||||
parentContext.ObjectsListNeeded(realObjects[i]);
|
||||
callingCode +=
|
||||
"const objects = " +
|
||||
codeGenerator.GetObjectListName(realObjects[0], parentContext) +
|
||||
";\n";
|
||||
} else {
|
||||
// Groups are rarely used in JS events so it's fine to make
|
||||
// allocations.
|
||||
callingCode += "const objects = [];\n";
|
||||
for (unsigned int i = 0; i < realObjects.size(); ++i) {
|
||||
parentContext.ObjectsListNeeded(realObjects[i]);
|
||||
callingCode += "objects.push.apply(objects," +
|
||||
codeGenerator.GetObjectListName(realObjects[i],
|
||||
parentContext) +
|
||||
");\n";
|
||||
}
|
||||
"objects.push.apply(objects," +
|
||||
codeGenerator.GetObjectListName(realObjects[i], parentContext) +
|
||||
");\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -18,8 +18,6 @@ KeyboardExtension::KeyboardExtension() {
|
||||
"gdjs.evtTools.input.wasKeyReleased");
|
||||
GetAllConditions()["KeyFromTextPressed"].SetFunctionName(
|
||||
"gdjs.evtTools.input.isKeyPressed");
|
||||
GetAllConditions()["KeyFromTextJustPressed"].SetFunctionName(
|
||||
"gdjs.evtTools.input.wasKeyJustPressed");
|
||||
GetAllConditions()["KeyFromTextReleased"].SetFunctionName(
|
||||
"gdjs.evtTools.input.wasKeyReleased");
|
||||
GetAllConditions()["AnyKeyPressed"].SetFunctionName(
|
||||
|
@@ -18,9 +18,6 @@
|
||||
#include "GDCore/IDE/Project/ProjectResourcesCopier.h"
|
||||
#include "GDCore/IDE/Project/SceneResourcesFinder.h"
|
||||
#include "GDCore/IDE/ProjectStripper.h"
|
||||
#include "GDCore/Project/EventsBasedObject.h"
|
||||
#include "GDCore/Project/EventsBasedObjectVariant.h"
|
||||
#include "GDCore/Project/EventsFunctionsExtension.h"
|
||||
#include "GDCore/Project/ExternalEvents.h"
|
||||
#include "GDCore/Project/ExternalLayout.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
@@ -50,7 +47,7 @@ Exporter::~Exporter() {}
|
||||
bool Exporter::ExportProjectForPixiPreview(
|
||||
const PreviewExportOptions &options) {
|
||||
ExporterHelper helper(fs, gdjsRoot, codeOutputDir);
|
||||
return helper.ExportProjectForPixiPreview(options, includesFiles);
|
||||
return helper.ExportProjectForPixiPreview(options);
|
||||
}
|
||||
|
||||
bool Exporter::ExportWholePixiProject(const ExportOptions &options) {
|
||||
@@ -83,7 +80,7 @@ bool Exporter::ExportWholePixiProject(const ExportOptions &options) {
|
||||
|
||||
// Prepare the export directory
|
||||
fs.MkDir(exportDir);
|
||||
includesFiles.clear();
|
||||
std::vector<gd::String> includesFiles;
|
||||
std::vector<gd::String> resourcesFiles;
|
||||
|
||||
// Export the resources (before generating events as some resources
|
||||
@@ -101,7 +98,6 @@ bool Exporter::ExportWholePixiProject(const ExportOptions &options) {
|
||||
helper.AddLibsInclude(
|
||||
/*pixiRenderers=*/true,
|
||||
usedExtensionsResult.Has3DObjects(),
|
||||
/*isInGameEditor=*/false,
|
||||
/*includeWebsocketDebuggerClient=*/false,
|
||||
/*includeWindowMessageDebuggerClient=*/false,
|
||||
/*includeMinimalDebuggerClient=*/false,
|
||||
@@ -124,7 +120,7 @@ bool Exporter::ExportWholePixiProject(const ExportOptions &options) {
|
||||
helper.ExportEffectIncludes(exportedProject, includesFiles);
|
||||
|
||||
// Export events
|
||||
if (!helper.ExportScenesEventsCode(exportedProject,
|
||||
if (!helper.ExportEventsCode(exportedProject,
|
||||
codeOutputDir,
|
||||
includesFiles,
|
||||
wholeProjectDiagnosticReport,
|
||||
@@ -134,10 +130,29 @@ bool Exporter::ExportWholePixiProject(const ExportOptions &options) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto projectUsedResources =
|
||||
gd::SceneResourcesFinder::FindProjectResources(exportedProject);
|
||||
std::unordered_map<gd::String, std::set<gd::String>> scenesUsedResources;
|
||||
for (std::size_t layoutIndex = 0;
|
||||
layoutIndex < exportedProject.GetLayoutsCount();
|
||||
layoutIndex++) {
|
||||
auto &layout = exportedProject.GetLayout(layoutIndex);
|
||||
scenesUsedResources[layout.GetName()] =
|
||||
gd::SceneResourcesFinder::FindSceneResources(exportedProject, layout);
|
||||
}
|
||||
|
||||
// Strip the project (*after* generating events as the events may use
|
||||
// stripped things like objects groups...)...
|
||||
gd::ProjectStripper::StripProjectForExport(exportedProject);
|
||||
|
||||
//...and export it
|
||||
gd::SerializerElement noRuntimeGameOptions;
|
||||
helper.ExportProjectData(fs, exportedProject, codeOutputDir + "/data.js",
|
||||
noRuntimeGameOptions);
|
||||
helper.ExportProjectData(fs,
|
||||
exportedProject,
|
||||
codeOutputDir + "/data.js",
|
||||
noRuntimeGameOptions,
|
||||
projectUsedResources,
|
||||
scenesUsedResources);
|
||||
includesFiles.push_back(codeOutputDir + "/data.js");
|
||||
|
||||
helper.ExportIncludesAndLibs(includesFiles, exportDir, false);
|
||||
@@ -200,18 +215,4 @@ bool Exporter::ExportWholePixiProject(const ExportOptions &options) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Exporter::SerializeProjectData(const gd::Project &project,
|
||||
const PreviewExportOptions &options,
|
||||
gd::SerializerElement &projectDataElement) {
|
||||
ExporterHelper::SerializeProjectData(fs, project, options,
|
||||
projectDataElement);
|
||||
}
|
||||
|
||||
void Exporter::SerializeRuntimeGameOptions(
|
||||
const PreviewExportOptions &options,
|
||||
gd::SerializerElement &runtimeGameOptionsElement) {
|
||||
ExporterHelper::SerializeRuntimeGameOptions(
|
||||
fs, gdjsRoot, options, includesFiles, runtimeGameOptionsElement);
|
||||
}
|
||||
|
||||
} // namespace gdjs
|
||||
|
@@ -16,7 +16,6 @@ class Project;
|
||||
class Layout;
|
||||
class ExternalLayout;
|
||||
class AbstractFileSystem;
|
||||
class SerializerElement;
|
||||
} // namespace gd
|
||||
namespace gdjs {
|
||||
struct PreviewExportOptions;
|
||||
@@ -65,33 +64,7 @@ class Exporter {
|
||||
codeOutputDir = codeOutputDir_;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Serialize a project without its events to JSON
|
||||
*
|
||||
* \param project The project to be exported
|
||||
* \param options The content of the extra configuration
|
||||
* \param projectDataElement The element where the project data is serialized
|
||||
*/
|
||||
void SerializeProjectData(const gd::Project &project,
|
||||
const PreviewExportOptions &options,
|
||||
gd::SerializerElement &projectDataElement);
|
||||
|
||||
/**
|
||||
* \brief Serialize the content of the extra configuration to store
|
||||
* in gdjs.runtimeGameOptions to JSON
|
||||
*
|
||||
* \warning `ExportProjectForPixiPreview` must be called first to serialize
|
||||
* the list of scripts files.
|
||||
*
|
||||
* \param options The content of the extra configuration
|
||||
* \param runtimeGameOptionsElement The element where the game options are
|
||||
* serialized
|
||||
*/
|
||||
void
|
||||
SerializeRuntimeGameOptions(const PreviewExportOptions &options,
|
||||
gd::SerializerElement &runtimeGameOptionsElement);
|
||||
|
||||
private:
|
||||
private:
|
||||
gd::AbstractFileSystem&
|
||||
fs; ///< The abstract file system to be used for exportation.
|
||||
gd::String lastError; ///< The last error that occurred.
|
||||
@@ -99,8 +72,6 @@ private:
|
||||
gdjsRoot; ///< The root directory of GDJS, used to copy runtime files.
|
||||
gd::String codeOutputDir; ///< The directory where JS code is outputted. Will
|
||||
///< be then copied to the final output directory.
|
||||
std::vector<gd::String>
|
||||
includesFiles; ///< The list of scripts files - useful for hot-reloading
|
||||
};
|
||||
|
||||
} // namespace gdjs
|
||||
|
@@ -28,13 +28,10 @@
|
||||
#include "GDCore/IDE/Events/UsedExtensionsFinder.h"
|
||||
#include "GDCore/IDE/ExportedDependencyResolver.h"
|
||||
#include "GDCore/IDE/Project/ProjectResourcesCopier.h"
|
||||
#include "GDCore/IDE/Project/ResourcesMergingHelper.h"
|
||||
#include "GDCore/IDE/Project/SceneResourcesFinder.h"
|
||||
#include "GDCore/IDE/ProjectStripper.h"
|
||||
#include "GDCore/IDE/ResourceExposer.h"
|
||||
#include "GDCore/IDE/SceneNameMangler.h"
|
||||
#include "GDCore/Project/EventsBasedObject.h"
|
||||
#include "GDCore/Project/EventsBasedObjectVariant.h"
|
||||
#include "GDCore/Project/EventsFunctionsExtension.h"
|
||||
#include "GDCore/Project/ExternalEvents.h"
|
||||
#include "GDCore/Project/ExternalLayout.h"
|
||||
@@ -61,6 +58,7 @@ double GetTimeSpent(double previousTime) { return GetTimeNow() - previousTime; }
|
||||
double LogTimeSpent(const gd::String &name, double previousTime) {
|
||||
gd::LogStatus(name + " took " + gd::String::From(GetTimeSpent(previousTime)) +
|
||||
"ms");
|
||||
std::cout << std::endl;
|
||||
return GetTimeNow();
|
||||
}
|
||||
} // namespace
|
||||
@@ -106,297 +104,128 @@ ExporterHelper::ExporterHelper(gd::AbstractFileSystem &fileSystem,
|
||||
: fs(fileSystem), gdjsRoot(gdjsRoot_), codeOutputDir(codeOutputDir_) {};
|
||||
|
||||
bool ExporterHelper::ExportProjectForPixiPreview(
|
||||
const PreviewExportOptions &options,
|
||||
std::vector<gd::String> &includesFiles) {
|
||||
|
||||
if (options.isInGameEdition && !options.shouldReloadProjectData &&
|
||||
!options.shouldReloadLibraries && !options.shouldGenerateScenesEventsCode) {
|
||||
gd::LogStatus("Skip project export entirely");
|
||||
return "";
|
||||
}
|
||||
|
||||
const PreviewExportOptions &options) {
|
||||
double previousTime = GetTimeNow();
|
||||
fs.MkDir(options.exportPath);
|
||||
if (options.shouldClearExportFolder) {
|
||||
fs.ClearDir(options.exportPath);
|
||||
}
|
||||
includesFiles.clear();
|
||||
fs.ClearDir(options.exportPath);
|
||||
std::vector<gd::String> includesFiles;
|
||||
std::vector<gd::String> resourcesFiles;
|
||||
|
||||
// TODO Try to remove side effects to avoid the copy
|
||||
// that destroys the AST in cache.
|
||||
gd::Project exportedProject = options.project;
|
||||
const gd::Project &immutableProject = options.project;
|
||||
previousTime = LogTimeSpent("Project cloning", previousTime);
|
||||
const gd::Project &immutableProject = exportedProject;
|
||||
|
||||
if (options.isInGameEdition) {
|
||||
if (options.shouldReloadProjectData || options.shouldGenerateScenesEventsCode) {
|
||||
auto projectDirectory = fs.DirNameFrom(exportedProject.GetProjectFile());
|
||||
gd::ResourcesMergingHelper resourcesMergingHelper(
|
||||
exportedProject.GetResourcesManager(), fs);
|
||||
resourcesMergingHelper.SetBaseDirectory(projectDirectory);
|
||||
resourcesMergingHelper.SetShouldUseOriginalAbsoluteFilenames();
|
||||
gd::ResourceExposer::ExposeWholeProjectResources(exportedProject,
|
||||
resourcesMergingHelper);
|
||||
|
||||
previousTime = LogTimeSpent("Resource path resolving", previousTime);
|
||||
if (options.fullLoadingScreen) {
|
||||
// Use project properties fallback to set empty properties
|
||||
if (exportedProject.GetAuthorIds().empty() &&
|
||||
!options.fallbackAuthorId.empty()) {
|
||||
exportedProject.GetAuthorIds().push_back(options.fallbackAuthorId);
|
||||
}
|
||||
if (exportedProject.GetAuthorUsernames().empty() &&
|
||||
!options.fallbackAuthorUsername.empty()) {
|
||||
exportedProject.GetAuthorUsernames().push_back(
|
||||
options.fallbackAuthorUsername);
|
||||
}
|
||||
gd::LogStatus("Resource export is skipped");
|
||||
} else {
|
||||
// Export resources (*before* generating events as some resources filenames
|
||||
// may be updated)
|
||||
ExportResources(fs, exportedProject, options.exportPath);
|
||||
|
||||
previousTime = LogTimeSpent("Resource export", previousTime);
|
||||
// Most of the time, we skip the logo and minimum duration so that
|
||||
// the preview start as soon as possible.
|
||||
exportedProject.GetLoadingScreen()
|
||||
.ShowGDevelopLogoDuringLoadingScreen(false)
|
||||
.SetMinDuration(0);
|
||||
exportedProject.GetWatermark().ShowGDevelopWatermark(false);
|
||||
}
|
||||
|
||||
if (options.shouldReloadProjectData || options.shouldGenerateScenesEventsCode) {
|
||||
// Compatibility with GD <= 5.0-beta56
|
||||
// Stay compatible with text objects declaring their font as just a filename
|
||||
// without a font resource - by manually adding these resources.
|
||||
AddDeprecatedFontFilesToFontResources(
|
||||
fs, exportedProject.GetResourcesManager(), options.exportPath);
|
||||
// end of compatibility code
|
||||
// Export resources (*before* generating events as some resources filenames
|
||||
// may be updated)
|
||||
ExportResources(fs, exportedProject, options.exportPath);
|
||||
|
||||
previousTime = LogTimeSpent("Resource export", previousTime);
|
||||
|
||||
// Compatibility with GD <= 5.0-beta56
|
||||
// Stay compatible with text objects declaring their font as just a filename
|
||||
// without a font resource - by manually adding these resources.
|
||||
AddDeprecatedFontFilesToFontResources(
|
||||
fs, exportedProject.GetResourcesManager(), options.exportPath);
|
||||
// end of compatibility code
|
||||
|
||||
auto usedExtensionsResult =
|
||||
gd::UsedExtensionsFinder::ScanProject(exportedProject);
|
||||
|
||||
// Export engine libraries
|
||||
AddLibsInclude(/*pixiRenderers=*/true,
|
||||
usedExtensionsResult.Has3DObjects(),
|
||||
/*includeWebsocketDebuggerClient=*/
|
||||
!options.websocketDebuggerServerAddress.empty(),
|
||||
/*includeWindowMessageDebuggerClient=*/
|
||||
options.useWindowMessageDebuggerClient,
|
||||
/*includeMinimalDebuggerClient=*/
|
||||
options.useMinimalDebuggerClient,
|
||||
/*includeCaptureManager=*/
|
||||
!options.captureOptions.IsEmpty(),
|
||||
/*includeInAppTutorialMessage*/
|
||||
!options.inAppTutorialMessageInPreview.empty(),
|
||||
immutableProject.GetLoadingScreen().GetGDevelopLogoStyle(),
|
||||
includesFiles);
|
||||
|
||||
// Export files for free function, object and behaviors
|
||||
for (const auto &includeFile : usedExtensionsResult.GetUsedIncludeFiles()) {
|
||||
InsertUnique(includesFiles, includeFile);
|
||||
}
|
||||
for (const auto &requiredFile : usedExtensionsResult.GetUsedRequiredFiles()) {
|
||||
InsertUnique(resourcesFiles, requiredFile);
|
||||
}
|
||||
|
||||
std::vector<gd::SourceFileMetadata> noUsedSourceFiles;
|
||||
std::vector<gd::SourceFileMetadata> &usedSourceFiles = noUsedSourceFiles;
|
||||
if (options.shouldReloadLibraries) {
|
||||
auto usedExtensionsResult =
|
||||
gd::UsedExtensionsFinder::ScanProject(exportedProject);
|
||||
usedSourceFiles = usedExtensionsResult.GetUsedSourceFiles();
|
||||
// Export effects (after engine libraries as they auto-register themselves to
|
||||
// the engine)
|
||||
ExportEffectIncludes(exportedProject, includesFiles);
|
||||
|
||||
// Export engine libraries
|
||||
AddLibsInclude(/*pixiRenderers=*/true,
|
||||
/*pixiInThreeRenderers=*/
|
||||
usedExtensionsResult.Has3DObjects(),
|
||||
/*isInGameEdition=*/
|
||||
options.isInGameEdition,
|
||||
/*includeWebsocketDebuggerClient=*/
|
||||
!options.websocketDebuggerServerAddress.empty(),
|
||||
/*includeWindowMessageDebuggerClient=*/
|
||||
options.useWindowMessageDebuggerClient,
|
||||
/*includeMinimalDebuggerClient=*/
|
||||
options.useMinimalDebuggerClient,
|
||||
/*includeCaptureManager=*/
|
||||
!options.captureOptions.IsEmpty(),
|
||||
/*includeInAppTutorialMessage*/
|
||||
!options.inAppTutorialMessageInPreview.empty(),
|
||||
immutableProject.GetLoadingScreen().GetGDevelopLogoStyle(),
|
||||
includesFiles);
|
||||
previousTime = LogTimeSpent("Include files export", previousTime);
|
||||
|
||||
// Export files for free function, object and behaviors
|
||||
for (const auto &includeFile : usedExtensionsResult.GetUsedIncludeFiles()) {
|
||||
InsertUnique(includesFiles, includeFile);
|
||||
}
|
||||
for (const auto &requiredFile : usedExtensionsResult.GetUsedRequiredFiles()) {
|
||||
InsertUnique(resourcesFiles, requiredFile);
|
||||
}
|
||||
if (options.isInGameEdition) {
|
||||
// TODO Scan the objects and events of event-based objects
|
||||
// (it could be an alternative method ScanProjectAndEventsBasedObjects in
|
||||
// UsedExtensionsFinder).
|
||||
// This is already done by UsedExtensionsFinder, but maybe it shouldn't.
|
||||
|
||||
// Export all event-based objects because they can be edited even if they
|
||||
// are not used yet.
|
||||
for (std::size_t e = 0;
|
||||
e < exportedProject.GetEventsFunctionsExtensionsCount(); e++) {
|
||||
auto &eventsFunctionsExtension =
|
||||
exportedProject.GetEventsFunctionsExtension(e);
|
||||
|
||||
for (auto &&eventsBasedObjectUniquePtr :
|
||||
eventsFunctionsExtension.GetEventsBasedObjects()
|
||||
.GetInternalVector()) {
|
||||
auto eventsBasedObject = eventsBasedObjectUniquePtr.get();
|
||||
|
||||
auto metadata = gd::MetadataProvider::GetExtensionAndObjectMetadata(
|
||||
exportedProject.GetCurrentPlatform(),
|
||||
gd::PlatformExtension::GetObjectFullType(
|
||||
eventsFunctionsExtension.GetName(),
|
||||
eventsBasedObject->GetName()));
|
||||
for (auto &&includeFile : metadata.GetMetadata().includeFiles) {
|
||||
InsertUnique(includesFiles, includeFile);
|
||||
}
|
||||
for (auto &behaviorType :
|
||||
metadata.GetMetadata().GetDefaultBehaviors()) {
|
||||
auto behaviorMetadata =
|
||||
gd::MetadataProvider::GetExtensionAndBehaviorMetadata(
|
||||
exportedProject.GetCurrentPlatform(), behaviorType);
|
||||
for (auto &&includeFile :
|
||||
behaviorMetadata.GetMetadata().includeFiles) {
|
||||
InsertUnique(includesFiles, includeFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Export effects (after engine libraries as they auto-register themselves to
|
||||
// the engine)
|
||||
ExportEffectIncludes(exportedProject, includesFiles);
|
||||
|
||||
previousTime = LogTimeSpent("Include files export", previousTime);
|
||||
}
|
||||
else {
|
||||
gd::LogStatus("Include files export is skipped");
|
||||
}
|
||||
|
||||
if (options.shouldGenerateScenesEventsCode) {
|
||||
if (!options.projectDataOnlyExport) {
|
||||
gd::WholeProjectDiagnosticReport &wholeProjectDiagnosticReport =
|
||||
options.project.GetWholeProjectDiagnosticReport();
|
||||
wholeProjectDiagnosticReport.Clear();
|
||||
|
||||
// Generate events code
|
||||
if (!ExportScenesEventsCode(immutableProject,
|
||||
if (!ExportEventsCode(immutableProject,
|
||||
codeOutputDir,
|
||||
includesFiles,
|
||||
wholeProjectDiagnosticReport,
|
||||
true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
previousTime = LogTimeSpent("Events code export", previousTime);
|
||||
}
|
||||
else {
|
||||
gd::LogStatus("Events code export is skipped");
|
||||
|
||||
auto projectUsedResources =
|
||||
gd::SceneResourcesFinder::FindProjectResources(exportedProject);
|
||||
std::unordered_map<gd::String, std::set<gd::String>> scenesUsedResources;
|
||||
for (std::size_t layoutIndex = 0;
|
||||
layoutIndex < exportedProject.GetLayoutsCount();
|
||||
layoutIndex++) {
|
||||
auto &layout = exportedProject.GetLayout(layoutIndex);
|
||||
scenesUsedResources[layout.GetName()] =
|
||||
gd::SceneResourcesFinder::FindSceneResources(exportedProject, layout);
|
||||
}
|
||||
|
||||
if (options.shouldReloadProjectData) {
|
||||
|
||||
if (options.fullLoadingScreen) {
|
||||
// Use project properties fallback to set empty properties
|
||||
if (exportedProject.GetAuthorIds().empty() &&
|
||||
!options.fallbackAuthorId.empty()) {
|
||||
exportedProject.GetAuthorIds().push_back(options.fallbackAuthorId);
|
||||
}
|
||||
if (exportedProject.GetAuthorUsernames().empty() &&
|
||||
!options.fallbackAuthorUsername.empty()) {
|
||||
exportedProject.GetAuthorUsernames().push_back(
|
||||
options.fallbackAuthorUsername);
|
||||
}
|
||||
} else {
|
||||
// Most of the time, we skip the logo and minimum duration so that
|
||||
// the preview start as soon as possible.
|
||||
exportedProject.GetLoadingScreen()
|
||||
.ShowGDevelopLogoDuringLoadingScreen(false)
|
||||
.SetMinDuration(0);
|
||||
exportedProject.GetWatermark().ShowGDevelopWatermark(false);
|
||||
}
|
||||
// Strip the project (*after* generating events as the events may use stripped
|
||||
// things (objects groups...))
|
||||
gd::ProjectStripper::StripProjectForExport(exportedProject);
|
||||
exportedProject.SetFirstLayout(options.layoutName);
|
||||
|
||||
gd::SerializerElement runtimeGameOptions;
|
||||
ExporterHelper::SerializeRuntimeGameOptions(fs, gdjsRoot, options,
|
||||
includesFiles, runtimeGameOptions);
|
||||
ExportProjectData(fs,
|
||||
exportedProject,
|
||||
codeOutputDir + "/data.js",
|
||||
runtimeGameOptions);
|
||||
includesFiles.push_back(codeOutputDir + "/data.js");
|
||||
previousTime = LogTimeSpent("Data stripping", previousTime);
|
||||
|
||||
previousTime = LogTimeSpent("Project data export", previousTime);
|
||||
}
|
||||
else {
|
||||
gd::LogStatus("Project data export is skipped");
|
||||
}
|
||||
|
||||
if (options.shouldReloadLibraries) {
|
||||
// Copy all the dependencies and their source maps
|
||||
ExportIncludesAndLibs(includesFiles, options.exportPath, true);
|
||||
ExportIncludesAndLibs(resourcesFiles, options.exportPath, true);
|
||||
|
||||
// TODO Build a full includesFiles list without actually doing export or
|
||||
// generation.
|
||||
if (options.shouldGenerateScenesEventsCode) {
|
||||
// Create the index file
|
||||
if (!ExportIndexFile(exportedProject, gdjsRoot + "/Runtime/index.html",
|
||||
options.exportPath, includesFiles, usedSourceFiles,
|
||||
options.nonRuntimeScriptsCacheBurst,
|
||||
"gdjs.runtimeGameOptions")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
previousTime = LogTimeSpent("Include and libs export", previousTime);
|
||||
} else {
|
||||
gd::LogStatus("Include and libs export is skipped");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
gd::String ExporterHelper::ExportProjectData(
|
||||
gd::AbstractFileSystem &fs, gd::Project &project, gd::String filename,
|
||||
const gd::SerializerElement &runtimeGameOptions) {
|
||||
fs.MkDir(fs.DirNameFrom(filename));
|
||||
|
||||
gd::SerializerElement projectDataElement;
|
||||
ExporterHelper::StriptAndSerializeProjectData(project, projectDataElement);
|
||||
|
||||
// Save the project to JSON
|
||||
gd::String output =
|
||||
"gdjs.projectData = " + gd::Serializer::ToJSON(projectDataElement) +
|
||||
";\ngdjs.runtimeGameOptions = " + gd::Serializer::ToJSON(runtimeGameOptions) +
|
||||
";\n";
|
||||
|
||||
if (!fs.WriteToFile(filename, output))
|
||||
return "Unable to write " + filename;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void ExporterHelper::SerializeRuntimeGameOptions(
|
||||
gd::AbstractFileSystem &fs, const gd::String &gdjsRoot,
|
||||
const PreviewExportOptions &options,
|
||||
std::vector<gd::String> &includesFiles,
|
||||
gd::SerializerElement &runtimeGameOptions) {
|
||||
// Create the setup options passed to the gdjs.RuntimeGame
|
||||
gd::SerializerElement runtimeGameOptions;
|
||||
runtimeGameOptions.AddChild("isPreview").SetBoolValue(true);
|
||||
|
||||
auto &initialRuntimeGameStatus =
|
||||
runtimeGameOptions.AddChild("initialRuntimeGameStatus");
|
||||
initialRuntimeGameStatus.AddChild("sceneName")
|
||||
.SetStringValue(options.layoutName);
|
||||
if (options.isInGameEdition) {
|
||||
initialRuntimeGameStatus.AddChild("isInGameEdition").SetBoolValue(true);
|
||||
initialRuntimeGameStatus.AddChild("editorId").SetValue(options.editorId);
|
||||
if (!options.editorCamera3DCameraMode.empty()) {
|
||||
auto &editorCamera3D =
|
||||
initialRuntimeGameStatus.AddChild("editorCamera3D");
|
||||
editorCamera3D.AddChild("cameraMode").SetStringValue(
|
||||
options.editorCamera3DCameraMode);
|
||||
editorCamera3D.AddChild("positionX")
|
||||
.SetDoubleValue(options.editorCamera3DPositionX);
|
||||
editorCamera3D.AddChild("positionY")
|
||||
.SetDoubleValue(options.editorCamera3DPositionY);
|
||||
editorCamera3D.AddChild("positionZ")
|
||||
.SetDoubleValue(options.editorCamera3DPositionZ);
|
||||
editorCamera3D.AddChild("rotationAngle")
|
||||
.SetDoubleValue(options.editorCamera3DRotationAngle);
|
||||
editorCamera3D.AddChild("elevationAngle")
|
||||
.SetDoubleValue(options.editorCamera3DElevationAngle);
|
||||
editorCamera3D.AddChild("distance")
|
||||
.SetDoubleValue(options.editorCamera3DDistance);
|
||||
}
|
||||
}
|
||||
if (!options.externalLayoutName.empty()) {
|
||||
initialRuntimeGameStatus.AddChild("injectedExternalLayoutName")
|
||||
runtimeGameOptions.AddChild("injectExternalLayout")
|
||||
.SetValue(options.externalLayoutName);
|
||||
|
||||
if (options.isInGameEdition) {
|
||||
initialRuntimeGameStatus.AddChild("skipCreatingInstancesFromScene")
|
||||
.SetBoolValue(true);
|
||||
}
|
||||
}
|
||||
if (!options.eventsBasedObjectType.empty()) {
|
||||
initialRuntimeGameStatus.AddChild("eventsBasedObjectType")
|
||||
.SetValue(options.eventsBasedObjectType);
|
||||
initialRuntimeGameStatus.AddChild("eventsBasedObjectVariantName")
|
||||
.SetValue(options.eventsBasedObjectVariantName);
|
||||
}
|
||||
|
||||
runtimeGameOptions.AddChild("shouldReloadLibraries")
|
||||
.SetBoolValue(options.shouldReloadLibraries);
|
||||
runtimeGameOptions.AddChild("shouldGenerateScenesEventsCode")
|
||||
.SetBoolValue(options.shouldGenerateScenesEventsCode);
|
||||
|
||||
runtimeGameOptions.AddChild("projectDataOnlyExport")
|
||||
.SetBoolValue(options.projectDataOnlyExport);
|
||||
runtimeGameOptions.AddChild("nativeMobileApp")
|
||||
.SetBoolValue(options.nativeMobileApp);
|
||||
runtimeGameOptions.AddChild("websocketDebuggerServerAddress")
|
||||
@@ -468,93 +297,71 @@ void ExporterHelper::SerializeRuntimeGameOptions(
|
||||
|
||||
for (const auto &includeFile : includesFiles) {
|
||||
auto hashIt = options.includeFileHashes.find(includeFile);
|
||||
gd::String scriptSrc = GetExportedIncludeFilename(fs, gdjsRoot, includeFile);
|
||||
gd::String scriptSrc = GetExportedIncludeFilename(includeFile);
|
||||
scriptFilesElement.AddChild("scriptFile")
|
||||
.SetStringAttribute("path", scriptSrc)
|
||||
.SetIntAttribute(
|
||||
"hash",
|
||||
hashIt != options.includeFileHashes.end() ? hashIt->second : 0);
|
||||
}
|
||||
|
||||
// Export the project
|
||||
ExportProjectData(fs,
|
||||
exportedProject,
|
||||
codeOutputDir + "/data.js",
|
||||
runtimeGameOptions,
|
||||
projectUsedResources,
|
||||
scenesUsedResources);
|
||||
includesFiles.push_back(codeOutputDir + "/data.js");
|
||||
|
||||
previousTime = LogTimeSpent("Project data export", previousTime);
|
||||
|
||||
// Copy all the dependencies and their source maps
|
||||
ExportIncludesAndLibs(includesFiles, options.exportPath, true);
|
||||
ExportIncludesAndLibs(resourcesFiles, options.exportPath, true);
|
||||
|
||||
// Create the index file
|
||||
if (!ExportIndexFile(exportedProject,
|
||||
gdjsRoot + "/Runtime/index.html",
|
||||
options.exportPath,
|
||||
includesFiles,
|
||||
usedExtensionsResult.GetUsedSourceFiles(),
|
||||
options.nonRuntimeScriptsCacheBurst,
|
||||
"gdjs.runtimeGameOptions"))
|
||||
return false;
|
||||
|
||||
previousTime = LogTimeSpent("Include and libs export", previousTime);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExporterHelper::SerializeProjectData(gd::AbstractFileSystem &fs,
|
||||
const gd::Project &project,
|
||||
const PreviewExportOptions &options,
|
||||
gd::SerializerElement &rootElement) {
|
||||
gd::Project clonedProject = project;
|
||||
|
||||
// Replace all resource file paths with the one used in exported projects.
|
||||
auto projectDirectory = fs.DirNameFrom(project.GetProjectFile());
|
||||
gd::ResourcesMergingHelper resourcesMergingHelper(
|
||||
clonedProject.GetResourcesManager(), fs);
|
||||
resourcesMergingHelper.SetBaseDirectory(projectDirectory);
|
||||
if (options.isInGameEdition) {
|
||||
resourcesMergingHelper.SetShouldUseOriginalAbsoluteFilenames();
|
||||
} else {
|
||||
resourcesMergingHelper.PreserveDirectoriesStructure(false);
|
||||
resourcesMergingHelper.PreserveAbsoluteFilenames(false);
|
||||
}
|
||||
gd::ResourceExposer::ExposeWholeProjectResources(clonedProject,
|
||||
resourcesMergingHelper);
|
||||
|
||||
ExporterHelper::StriptAndSerializeProjectData(clonedProject, rootElement);
|
||||
}
|
||||
|
||||
void ExporterHelper::StriptAndSerializeProjectData(
|
||||
gd::Project &project, gd::SerializerElement &rootElement) {
|
||||
auto projectUsedResources =
|
||||
gd::SceneResourcesFinder::FindProjectResources(project);
|
||||
std::unordered_map<gd::String, std::set<gd::String>> scenesUsedResources;
|
||||
for (std::size_t layoutIndex = 0;
|
||||
layoutIndex < project.GetLayoutsCount(); layoutIndex++) {
|
||||
auto &layout = project.GetLayout(layoutIndex);
|
||||
scenesUsedResources[layout.GetName()] =
|
||||
gd::SceneResourcesFinder::FindSceneResources(project, layout);
|
||||
}
|
||||
std::unordered_map<gd::String, std::set<gd::String>>
|
||||
eventsBasedObjectVariantsUsedResources;
|
||||
for (std::size_t extensionIndex = 0;
|
||||
extensionIndex < project.GetEventsFunctionsExtensionsCount();
|
||||
extensionIndex++) {
|
||||
auto &eventsFunctionsExtension =
|
||||
project.GetEventsFunctionsExtension(extensionIndex);
|
||||
for (auto &&eventsBasedObject :
|
||||
eventsFunctionsExtension.GetEventsBasedObjects().GetInternalVector()) {
|
||||
|
||||
auto eventsBasedObjectType = gd::PlatformExtension::GetObjectFullType(
|
||||
eventsFunctionsExtension.GetName(), eventsBasedObject->GetName());
|
||||
eventsBasedObjectVariantsUsedResources[eventsBasedObjectType] =
|
||||
gd::SceneResourcesFinder::FindEventsBasedObjectVariantResources(
|
||||
project, eventsBasedObject->GetDefaultVariant());
|
||||
|
||||
for (auto &&eventsBasedObjectVariant :
|
||||
eventsBasedObject->GetVariants().GetInternalVector()) {
|
||||
|
||||
auto variantType = gd::PlatformExtension::GetVariantFullType(
|
||||
eventsFunctionsExtension.GetName(), eventsBasedObject->GetName(),
|
||||
eventsBasedObjectVariant->GetName());
|
||||
eventsBasedObjectVariantsUsedResources[variantType] =
|
||||
gd::SceneResourcesFinder::FindEventsBasedObjectVariantResources(
|
||||
project, *eventsBasedObjectVariant);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Strip the project (*after* generating events as the events may use stripped
|
||||
// things (objects groups...))
|
||||
gd::ProjectStripper::StripProjectForExport(project);
|
||||
gd::String ExporterHelper::ExportProjectData(
|
||||
gd::AbstractFileSystem &fs,
|
||||
gd::Project &project,
|
||||
gd::String filename,
|
||||
const gd::SerializerElement &runtimeGameOptions,
|
||||
std::set<gd::String> &projectUsedResources,
|
||||
std::unordered_map<gd::String, std::set<gd::String>> &scenesUsedResources) {
|
||||
fs.MkDir(fs.DirNameFrom(filename));
|
||||
|
||||
// Save the project to JSON
|
||||
gd::SerializerElement rootElement;
|
||||
project.SerializeTo(rootElement);
|
||||
SerializeUsedResources(rootElement, projectUsedResources, scenesUsedResources,
|
||||
eventsBasedObjectVariantsUsedResources);
|
||||
SerializeUsedResources(
|
||||
rootElement, projectUsedResources, scenesUsedResources);
|
||||
gd::String output =
|
||||
"gdjs.projectData = " + gd::Serializer::ToJSON(rootElement) + ";\n" +
|
||||
"gdjs.runtimeGameOptions = " +
|
||||
gd::Serializer::ToJSON(runtimeGameOptions) + ";\n";
|
||||
|
||||
if (!fs.WriteToFile(filename, output)) return "Unable to write " + filename;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void ExporterHelper::SerializeUsedResources(
|
||||
gd::SerializerElement &rootElement,
|
||||
std::set<gd::String> &projectUsedResources,
|
||||
std::unordered_map<gd::String, std::set<gd::String>> &scenesUsedResources,
|
||||
std::unordered_map<gd::String, std::set<gd::String>>
|
||||
&eventsBasedObjectVariantsUsedResources) {
|
||||
std::unordered_map<gd::String, std::set<gd::String>> &scenesUsedResources) {
|
||||
auto serializeUsedResources =
|
||||
[](gd::SerializerElement &element,
|
||||
std::set<gd::String> &usedResources) -> void {
|
||||
@@ -578,41 +385,6 @@ void ExporterHelper::SerializeUsedResources(
|
||||
auto &layoutUsedResources = scenesUsedResources[layoutName];
|
||||
serializeUsedResources(layoutElement, layoutUsedResources);
|
||||
}
|
||||
|
||||
auto &extensionsElement = rootElement.GetChild("eventsFunctionsExtensions");
|
||||
for (std::size_t extensionIndex = 0;
|
||||
extensionIndex < extensionsElement.GetChildrenCount();
|
||||
extensionIndex++) {
|
||||
auto &extensionElement = extensionsElement.GetChild(extensionIndex);
|
||||
const auto extensionName = extensionElement.GetStringAttribute("name");
|
||||
|
||||
auto &objectsElement = extensionElement.GetChild("eventsBasedObjects");
|
||||
|
||||
for (std::size_t objectIndex = 0;
|
||||
objectIndex < objectsElement.GetChildrenCount(); objectIndex++) {
|
||||
auto &objectElement = objectsElement.GetChild(objectIndex);
|
||||
const auto objectName = objectElement.GetStringAttribute("name");
|
||||
|
||||
auto eventsBasedObjectType =
|
||||
gd::PlatformExtension::GetObjectFullType(extensionName, objectName);
|
||||
auto &objectUsedResources =
|
||||
eventsBasedObjectVariantsUsedResources[eventsBasedObjectType];
|
||||
serializeUsedResources(objectElement, objectUsedResources);
|
||||
|
||||
auto &variantsElement = objectElement.GetChild("variants");
|
||||
for (std::size_t variantIndex = 0;
|
||||
variantIndex < variantsElement.GetChildrenCount(); variantIndex++) {
|
||||
auto &variantElement = variantsElement.GetChild(variantIndex);
|
||||
const auto variantName = variantElement.GetStringAttribute("name");
|
||||
|
||||
auto variantType = gd::PlatformExtension::GetVariantFullType(
|
||||
extensionName, objectName, variantName);
|
||||
auto &variantUsedResources =
|
||||
eventsBasedObjectVariantsUsedResources[variantType];
|
||||
serializeUsedResources(variantElement, variantUsedResources);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ExporterHelper::ExportIndexFile(
|
||||
@@ -1003,7 +775,7 @@ bool ExporterHelper::CompleteIndexFile(
|
||||
gd::String codeFilesIncludes;
|
||||
for (auto &include : includesFiles) {
|
||||
gd::String scriptSrc =
|
||||
GetExportedIncludeFilename(fs, gdjsRoot, include, nonRuntimeScriptsCacheBurst);
|
||||
GetExportedIncludeFilename(include, nonRuntimeScriptsCacheBurst);
|
||||
|
||||
// Sanity check if the file exists - if not skip it to avoid
|
||||
// including it in the list of scripts.
|
||||
@@ -1029,7 +801,6 @@ bool ExporterHelper::CompleteIndexFile(
|
||||
|
||||
void ExporterHelper::AddLibsInclude(bool pixiRenderers,
|
||||
bool pixiInThreeRenderers,
|
||||
bool isInGameEdition,
|
||||
bool includeWebsocketDebuggerClient,
|
||||
bool includeWindowMessageDebuggerClient,
|
||||
bool includeMinimalDebuggerClient,
|
||||
@@ -1106,7 +877,6 @@ void ExporterHelper::AddLibsInclude(bool pixiRenderers,
|
||||
InsertUnique(includesFiles, "debugger-client/hot-reloader.js");
|
||||
InsertUnique(includesFiles, "debugger-client/abstract-debugger-client.js");
|
||||
InsertUnique(includesFiles, "debugger-client/InGameDebugger.js");
|
||||
InsertUnique(includesFiles, "InGameEditor/InGameEditor.js");
|
||||
}
|
||||
if (includeWebsocketDebuggerClient) {
|
||||
InsertUnique(includesFiles, "debugger-client/websocket-debugger-client.js");
|
||||
@@ -1119,16 +889,14 @@ void ExporterHelper::AddLibsInclude(bool pixiRenderers,
|
||||
InsertUnique(includesFiles, "debugger-client/minimal-debugger-client.js");
|
||||
}
|
||||
|
||||
if (pixiInThreeRenderers || isInGameEdition) {
|
||||
if (pixiInThreeRenderers) {
|
||||
InsertUnique(includesFiles, "pixi-renderers/three.js");
|
||||
InsertUnique(includesFiles, "pixi-renderers/ThreeAddons.js");
|
||||
InsertUnique(includesFiles, "pixi-renderers/draco/gltf/draco_decoder.wasm");
|
||||
InsertUnique(includesFiles,
|
||||
"pixi-renderers/draco/gltf/draco_wasm_wrapper.js");
|
||||
// Extensions in JS may use it.
|
||||
InsertUnique(includesFiles, "Extensions/3D/Scene3DTools.js");
|
||||
}
|
||||
if (pixiRenderers || isInGameEdition) {
|
||||
if (pixiRenderers) {
|
||||
InsertUnique(includesFiles, "pixi-renderers/pixi.js");
|
||||
InsertUnique(includesFiles, "pixi-renderers/pixi-filters-tools.js");
|
||||
InsertUnique(includesFiles, "pixi-renderers/runtimegame-pixi-renderer.js");
|
||||
@@ -1152,12 +920,7 @@ void ExporterHelper::AddLibsInclude(bool pixiRenderers,
|
||||
includesFiles,
|
||||
"fontfaceobserver-font-manager/fontfaceobserver-font-manager.js");
|
||||
}
|
||||
if (isInGameEdition) {
|
||||
// `InGameEditor` uses the `is3D` function.
|
||||
InsertUnique(includesFiles, "Extensions/3D/Base3DBehavior.js");
|
||||
InsertUnique(includesFiles, "Extensions/3D/HemisphereLight.js");
|
||||
}
|
||||
if (pixiInThreeRenderers || isInGameEdition) {
|
||||
if (pixiInThreeRenderers) {
|
||||
InsertUnique(includesFiles, "Extensions/3D/A_RuntimeObject3D.js");
|
||||
InsertUnique(includesFiles, "Extensions/3D/A_RuntimeObject3DRenderer.js");
|
||||
InsertUnique(includesFiles, "Extensions/3D/CustomRuntimeObject3D.js");
|
||||
@@ -1195,7 +958,7 @@ bool ExporterHelper::ExportEffectIncludes(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExporterHelper::ExportScenesEventsCode(
|
||||
bool ExporterHelper::ExportEventsCode(
|
||||
const gd::Project &project,
|
||||
gd::String outputDir,
|
||||
std::vector<gd::String> &includesFiles,
|
||||
@@ -1231,7 +994,6 @@ bool ExporterHelper::ExportScenesEventsCode(
|
||||
}
|
||||
|
||||
gd::String ExporterHelper::GetExportedIncludeFilename(
|
||||
gd::AbstractFileSystem &fs, const gd::String &gdjsRoot,
|
||||
const gd::String &include, unsigned int nonRuntimeScriptsCacheBurst) {
|
||||
auto addSearchParameterToUrl = [](const gd::String &url,
|
||||
const gd::String &urlEncodedParameterName,
|
||||
|
@@ -42,9 +42,9 @@ struct PreviewExportOptions {
|
||||
useWindowMessageDebuggerClient(false),
|
||||
useMinimalDebuggerClient(false),
|
||||
nativeMobileApp(false),
|
||||
projectDataOnlyExport(false),
|
||||
fullLoadingScreen(false),
|
||||
isDevelopmentEnvironment(false),
|
||||
isInGameEdition(false),
|
||||
nonRuntimeScriptsCacheBurst(0),
|
||||
inAppTutorialMessageInPreview(""),
|
||||
inAppTutorialMessagePositionInPreview(""),
|
||||
@@ -145,26 +145,6 @@ struct PreviewExportOptions {
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the (optional) events-based object to be instantiated in the scene
|
||||
* at the beginning of the previewed game.
|
||||
*/
|
||||
PreviewExportOptions &SetEventsBasedObjectType(
|
||||
const gd::String &eventsBasedObjectType_) {
|
||||
eventsBasedObjectType = eventsBasedObjectType_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the (optional) events-based object variant to be instantiated in the scene
|
||||
* at the beginning of the previewed game.
|
||||
*/
|
||||
PreviewExportOptions &SetEventsBasedObjectVariantName(
|
||||
const gd::String &eventsBasedObjectVariantName_) {
|
||||
eventsBasedObjectVariantName = eventsBasedObjectVariantName_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the hash associated to an include file. Useful for the preview
|
||||
* hot-reload, to know if a file changed.
|
||||
@@ -176,34 +156,11 @@ struct PreviewExportOptions {
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set if the exported folder should be cleared befor the export.
|
||||
* \brief Set if the export should only export the project data, not
|
||||
* exporting events code.
|
||||
*/
|
||||
PreviewExportOptions &SetShouldClearExportFolder(bool enable) {
|
||||
shouldClearExportFolder = enable;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set if the `ProjectData` must be reloaded.
|
||||
*/
|
||||
PreviewExportOptions &SetShouldReloadProjectData(bool enable) {
|
||||
shouldReloadProjectData = enable;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set if GDJS libraries must be reloaded.
|
||||
*/
|
||||
PreviewExportOptions &SetShouldReloadLibraries(bool enable) {
|
||||
shouldReloadLibraries = enable;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set if the export should export events code.
|
||||
*/
|
||||
PreviewExportOptions &SetShouldGenerateScenesEventsCode(bool enable) {
|
||||
shouldGenerateScenesEventsCode = enable;
|
||||
PreviewExportOptions &SetProjectDataOnlyExport(bool enable) {
|
||||
projectDataOnlyExport = enable;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -225,40 +182,6 @@ struct PreviewExportOptions {
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set if the export is made for being edited in the editor.
|
||||
*/
|
||||
PreviewExportOptions &SetIsInGameEdition(bool enable) {
|
||||
isInGameEdition = enable;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the in-game editor identifier.
|
||||
*/
|
||||
PreviewExportOptions &SetEditorId(const gd::String &editorId_) {
|
||||
editorId = editorId_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the camera state to use in the in-game editor.
|
||||
*/
|
||||
PreviewExportOptions &
|
||||
SetEditorCameraState3D(const gd::String &cameraMode, double positionX,
|
||||
double positionY, double positionZ,
|
||||
double rotationAngle, double elevationAngle,
|
||||
double distance) {
|
||||
editorCamera3DCameraMode = cameraMode;
|
||||
editorCamera3DPositionX = positionX;
|
||||
editorCamera3DPositionY = positionY;
|
||||
editorCamera3DPositionZ = positionZ;
|
||||
editorCamera3DRotationAngle = rotationAngle;
|
||||
editorCamera3DElevationAngle = elevationAngle;
|
||||
editorCamera3DDistance = distance;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief If set to a non zero value, the exported script URLs will have an
|
||||
* extra search parameter added (with the given value) to ensure browser cache
|
||||
@@ -371,8 +294,6 @@ struct PreviewExportOptions {
|
||||
bool useMinimalDebuggerClient;
|
||||
gd::String layoutName;
|
||||
gd::String externalLayoutName;
|
||||
gd::String eventsBasedObjectType;
|
||||
gd::String eventsBasedObjectVariantName;
|
||||
gd::String fallbackAuthorUsername;
|
||||
gd::String fallbackAuthorId;
|
||||
gd::String playerId;
|
||||
@@ -382,21 +303,9 @@ struct PreviewExportOptions {
|
||||
gd::String inAppTutorialMessagePositionInPreview;
|
||||
bool nativeMobileApp;
|
||||
std::map<gd::String, int> includeFileHashes;
|
||||
bool shouldClearExportFolder = true;
|
||||
bool shouldReloadProjectData = true;
|
||||
bool shouldReloadLibraries = true;
|
||||
bool shouldGenerateScenesEventsCode = true;
|
||||
bool projectDataOnlyExport;
|
||||
bool fullLoadingScreen;
|
||||
bool isDevelopmentEnvironment;
|
||||
bool isInGameEdition;
|
||||
gd::String editorId;
|
||||
gd::String editorCamera3DCameraMode;
|
||||
double editorCamera3DPositionX = 0;
|
||||
double editorCamera3DPositionY = 0;
|
||||
double editorCamera3DPositionZ = 0;
|
||||
double editorCamera3DRotationAngle = 0;
|
||||
double editorCamera3DElevationAngle = 0;
|
||||
double editorCamera3DDistance = 0;
|
||||
unsigned int nonRuntimeScriptsCacheBurst;
|
||||
gd::String electronRemoteRequirePath;
|
||||
gd::String gdevelopResourceToken;
|
||||
@@ -470,50 +379,23 @@ class ExporterHelper {
|
||||
const gd::String &GetLastError() const { return lastError; };
|
||||
|
||||
/**
|
||||
* \brief Export a project without its events and options to 2 JS variables
|
||||
* \brief Export a project to JSON
|
||||
*
|
||||
* \param fs The abstract file system to use to write the file
|
||||
* \param project The project to be exported.
|
||||
* \param filename The filename where export the project
|
||||
* \param runtimeGameOptions The content of the extra configuration to store
|
||||
* in gdjs.runtimeGameOptions
|
||||
*
|
||||
* \return Empty string if everything is ok,
|
||||
* in gdjs.runtimeGameOptions \return Empty string if everything is ok,
|
||||
* description of the error otherwise.
|
||||
*/
|
||||
static gd::String
|
||||
ExportProjectData(gd::AbstractFileSystem &fs, gd::Project &project,
|
||||
gd::String filename,
|
||||
const gd::SerializerElement &runtimeGameOptions);
|
||||
|
||||
/**
|
||||
* \brief Serialize a project without its events to JSON
|
||||
*
|
||||
* \param fs The abstract file system to use to write the file
|
||||
* \param project The project to be exported.
|
||||
* \param projectDataElement The element where the project data is serialized
|
||||
*/
|
||||
static void SerializeProjectData(gd::AbstractFileSystem &fs,
|
||||
const gd::Project &project,
|
||||
const PreviewExportOptions &options,
|
||||
gd::SerializerElement &projectDataElement);
|
||||
|
||||
/**
|
||||
* \brief Serialize the content of the extra configuration to store
|
||||
* in gdjs.runtimeGameOptions to JSON
|
||||
*
|
||||
* \param fs The abstract file system to use to write the file
|
||||
* \param options The content of the extra configuration
|
||||
* \param includesFiles The list of scripts files - useful for hot-reloading
|
||||
* \param runtimeGameOptionsElement The element where the game options are
|
||||
* serialized
|
||||
*/
|
||||
static void
|
||||
SerializeRuntimeGameOptions(gd::AbstractFileSystem &fs,
|
||||
const gd::String &gdjsRoot,
|
||||
const PreviewExportOptions &options,
|
||||
std::vector<gd::String> &includesFiles,
|
||||
gd::SerializerElement &runtimeGameOptionsElement);
|
||||
static gd::String ExportProjectData(
|
||||
gd::AbstractFileSystem &fs,
|
||||
gd::Project &project,
|
||||
gd::String filename,
|
||||
const gd::SerializerElement &runtimeGameOptions,
|
||||
std::set<gd::String> &projectUsedResources,
|
||||
std::unordered_map<gd::String, std::set<gd::String>>
|
||||
&layersUsedResources);
|
||||
|
||||
/**
|
||||
* \brief Copy all the resources of the project to to the export directory,
|
||||
@@ -534,7 +416,6 @@ class ExporterHelper {
|
||||
*/
|
||||
void AddLibsInclude(bool pixiRenderers,
|
||||
bool pixiInThreeRenderers,
|
||||
bool isInGameEdition,
|
||||
bool includeWebsocketDebuggerClient,
|
||||
bool includeWindowMessageDebuggerClient,
|
||||
bool includeMinimalDebuggerClient,
|
||||
@@ -572,7 +453,7 @@ class ExporterHelper {
|
||||
* includesFiles A reference to a vector that will be filled with JS files to
|
||||
* be exported along with the project. ( including "codeX.js" files ).
|
||||
*/
|
||||
bool ExportScenesEventsCode(
|
||||
bool ExportEventsCode(
|
||||
const gd::Project &project,
|
||||
gd::String outputDir,
|
||||
std::vector<gd::String> &includesFiles,
|
||||
@@ -697,17 +578,14 @@ class ExporterHelper {
|
||||
* a browser pointing to the preview.
|
||||
*
|
||||
* \param options The options to generate the preview.
|
||||
* \param includesFiles The list of scripts files - useful for hot-reloading
|
||||
*/
|
||||
bool ExportProjectForPixiPreview(const PreviewExportOptions &options,
|
||||
std::vector<gd::String> &includesFiles);
|
||||
bool ExportProjectForPixiPreview(const PreviewExportOptions &options);
|
||||
|
||||
/**
|
||||
* \brief Given an include file, returns the name of the file to reference
|
||||
* in the exported game.
|
||||
*/
|
||||
static gd::String GetExportedIncludeFilename(
|
||||
gd::AbstractFileSystem &fs, const gd::String &gdjsRoot,
|
||||
gd::String GetExportedIncludeFilename(
|
||||
const gd::String &include, unsigned int nonRuntimeScriptsCacheBurst = 0);
|
||||
|
||||
/**
|
||||
@@ -734,22 +612,11 @@ class ExporterHelper {
|
||||
///< be then copied to the final output directory.
|
||||
|
||||
private:
|
||||
static void
|
||||
SerializeUsedResources(gd::SerializerElement &rootElement,
|
||||
std::set<gd::String> &projectUsedResources,
|
||||
std::unordered_map<gd::String, std::set<gd::String>>
|
||||
&layersUsedResources,
|
||||
std::unordered_map<gd::String, std::set<gd::String>>
|
||||
&eventsBasedObjectVariantsUsedResources);
|
||||
|
||||
/**
|
||||
* \brief Stript a project and serialize it to JSON
|
||||
*
|
||||
* \param project The project to be exported.
|
||||
*/
|
||||
static void
|
||||
StriptAndSerializeProjectData(gd::Project &project,
|
||||
gd::SerializerElement &rootElement);
|
||||
static void SerializeUsedResources(
|
||||
gd::SerializerElement &rootElement,
|
||||
std::set<gd::String> &projectUsedResources,
|
||||
std::unordered_map<gd::String, std::set<gd::String>>
|
||||
&layersUsedResources);
|
||||
};
|
||||
|
||||
} // namespace gdjs
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user