mirror of
https://github.com/Heretek-AI/GDevelop-Heretek.git
synced 2026-10-12 02:02:42 +00:00
Allow to override behavior properties on object instances (#8171)
* For now, this is limited to instances inside custom objects. This will be made available in the future for all instances in scenes if this works well.
This commit is contained in:
@@ -1032,6 +1032,8 @@ void WholeProjectRefactorer::RenameEventsBasedBehaviorProperty(
|
||||
behaviorType, oldPropertyName, newPropertyName);
|
||||
projectBrowser.ExposeObjects(project, behaviorPropertyRenamer);
|
||||
|
||||
// TODO Rename the property in behavior overridings of InitialInstances.
|
||||
|
||||
if (properties.Get(oldPropertyName).GetType() == "Behavior") {
|
||||
// This is a property representing another behavior that must exist on the
|
||||
// object.
|
||||
|
||||
@@ -14,8 +14,8 @@ BehaviorConfigurationContainer::~BehaviorConfigurationContainer(){};
|
||||
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> BehaviorConfigurationContainer::GetProperties() const {
|
||||
return GetProperties(content);
|
||||
};
|
||||
return GetProperties(content);
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> BehaviorConfigurationContainer::GetProperties(
|
||||
const gd::SerializerElement& behaviorContent) const {
|
||||
|
||||
@@ -81,7 +81,6 @@ class GD_CORE_API BehaviorConfigurationContainer {
|
||||
* behavior
|
||||
*
|
||||
* \return false if the new value cannot be set
|
||||
* \see gd::InitialInstance
|
||||
*/
|
||||
bool UpdateProperty(const gd::String& name, const gd::String& value) {
|
||||
return UpdateProperty(content, name, value);
|
||||
@@ -98,11 +97,42 @@ class GD_CORE_API BehaviorConfigurationContainer {
|
||||
return RenameProperty(content, oldName, newName);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Called when the IDE wants to remove a custom property from the
|
||||
* behavior
|
||||
*
|
||||
* \see gd::InitialInstance
|
||||
*/
|
||||
void RemoveProperty(const gd::String &name) {
|
||||
content.RemoveChild(name);
|
||||
content.RemoveAttribute(name);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Called to check if a property is overriden.
|
||||
*
|
||||
* \see gd::InitialInstance
|
||||
*/
|
||||
bool HasPropertyValue(const gd::String name) const {
|
||||
return content.HasChild(name) || content.HasAttribute(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Called to initialize the content with the default properties
|
||||
* for the behavior.
|
||||
*/
|
||||
virtual void InitializeContent() { InitializeContent(content); };
|
||||
virtual void InitializeContent() {
|
||||
InitializeContent(content);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Called to remove all properties values for the behavior.
|
||||
*
|
||||
* \see gd::InitialInstance
|
||||
*/
|
||||
void ClearContent() {
|
||||
content.Clear();
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Serialize the behavior content.
|
||||
@@ -202,7 +232,6 @@ class GD_CORE_API BehaviorConfigurationContainer {
|
||||
* behavior
|
||||
*
|
||||
* \return false if the new value cannot be set
|
||||
* \see gd::InitialInstance
|
||||
*/
|
||||
virtual bool UpdateProperty(gd::SerializerElement& behaviorContent,
|
||||
const gd::String& name,
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival ([email protected]). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/Project/BehaviorsContainer.h"
|
||||
|
||||
#include "GDCore/Extensions/Metadata/BehaviorMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/CustomBehavior.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/Project/QuickCustomization.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
#include "GDCore/Tools/UUID/UUID.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
BehaviorsContainer::~BehaviorsContainer() {}
|
||||
|
||||
BehaviorsContainer::BehaviorsContainer(bool isOverriding_)
|
||||
: isOverriding(isOverriding_) {}
|
||||
|
||||
void BehaviorsContainer::Init(const gd::BehaviorsContainer &behaviorsContainer) {
|
||||
isOverriding = behaviorsContainer.isOverriding;
|
||||
behaviors = gd::Clone(behaviorsContainer.behaviors);
|
||||
}
|
||||
|
||||
std::vector<gd::String> BehaviorsContainer::GetAllBehaviorNames() const {
|
||||
std::vector<gd::String> allNameIdentifiers;
|
||||
|
||||
for (auto &it : behaviors)
|
||||
allNameIdentifiers.push_back(it.first);
|
||||
|
||||
return allNameIdentifiers;
|
||||
}
|
||||
|
||||
void BehaviorsContainer::RemoveBehavior(const gd::String &name) {
|
||||
behaviors.erase(name);
|
||||
}
|
||||
|
||||
bool BehaviorsContainer::RenameBehavior(const gd::String &name,
|
||||
const gd::String &newName) {
|
||||
if (behaviors.find(name) == behaviors.end() ||
|
||||
behaviors.find(newName) != behaviors.end())
|
||||
return false;
|
||||
|
||||
std::unique_ptr<Behavior> aut = std::move(behaviors.find(name)->second);
|
||||
behaviors.erase(name);
|
||||
behaviors[newName] = std::move(aut);
|
||||
behaviors[newName]->SetName(newName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
gd::Behavior &BehaviorsContainer::GetBehavior(const gd::String &name) {
|
||||
return *behaviors.find(name)->second;
|
||||
}
|
||||
|
||||
const gd::Behavior &
|
||||
BehaviorsContainer::GetBehavior(const gd::String &name) const {
|
||||
return *behaviors.find(name)->second;
|
||||
}
|
||||
|
||||
bool BehaviorsContainer::HasBehaviorNamed(const gd::String &name) const {
|
||||
return behaviors.find(name) != behaviors.end();
|
||||
}
|
||||
|
||||
gd::Behavior *BehaviorsContainer::AddNewBehavior(const gd::Project &project,
|
||||
const gd::String &type,
|
||||
const gd::String &name) {
|
||||
auto initializeAndAdd = [this,
|
||||
&name](std::unique_ptr<gd::Behavior> behavior) {
|
||||
if (isOverriding) {
|
||||
// We don't call the Initialize method for behavior overridings because they
|
||||
// should have no property value initially.
|
||||
behavior->ClearContent();
|
||||
}
|
||||
else {
|
||||
behavior->InitializeContent();
|
||||
}
|
||||
this->behaviors[name] = std::move(behavior);
|
||||
return this->behaviors[name].get();
|
||||
};
|
||||
|
||||
if (project.HasEventsBasedBehavior(type)) {
|
||||
return initializeAndAdd(
|
||||
gd::make_unique<CustomBehavior>(name, project, type));
|
||||
} else {
|
||||
const gd::BehaviorMetadata &behaviorMetadata =
|
||||
gd::MetadataProvider::GetBehaviorMetadata(project.GetCurrentPlatform(),
|
||||
type);
|
||||
if (gd::MetadataProvider::IsBadBehaviorMetadata(behaviorMetadata)) {
|
||||
gd::LogWarning("Tried to create a behavior with an unknown type: " +
|
||||
type);
|
||||
// It's probably an events-based behavior that was removed.
|
||||
// Create a custom behavior to preserve the properties values.
|
||||
return initializeAndAdd(
|
||||
gd::make_unique<CustomBehavior>(name, project, type));
|
||||
}
|
||||
std::unique_ptr<gd::Behavior> behavior(behaviorMetadata.Get().Clone());
|
||||
behavior->SetName(name);
|
||||
return initializeAndAdd(std::move(behavior));
|
||||
}
|
||||
}
|
||||
|
||||
void BehaviorsContainer::UnserializeFrom(gd::Project &project,
|
||||
const SerializerElement &element) {
|
||||
element.ConsiderAsArrayOf("behavior", "automatism");
|
||||
for (std::size_t i = 0; i < element.GetChildrenCount(); ++i) {
|
||||
SerializerElement &behaviorElement = element.GetChild(i);
|
||||
|
||||
gd::String type = behaviorElement.GetStringAttribute("type").FindAndReplace(
|
||||
"Automatism", "Behavior"); // Compatibility with GD <= 4
|
||||
gd::String name = behaviorElement.GetStringAttribute("name");
|
||||
|
||||
auto behavior = gd::BehaviorsContainer::AddNewBehavior(project, type, name);
|
||||
// Compatibility with GD <= 4.0.98
|
||||
// If there is only one child called "content" (in addition to "type" and
|
||||
// "name"), it's the content of a JavaScript behavior. Move the content
|
||||
// out of the "content" object (to put it directly at the root of the
|
||||
// behavior element).
|
||||
if (behaviorElement.HasChild("content") &&
|
||||
behaviorElement.GetAllChildren().size() == 3) {
|
||||
SerializerElement &contentElement = behaviorElement.GetChild("content");
|
||||
|
||||
// Physics2 Behavior was using "type" for the type of the body. The name
|
||||
// conflicts with the behavior "type". Rename it.
|
||||
if (contentElement.HasChild("type")) {
|
||||
contentElement.AddChild("bodyType")
|
||||
.SetValue(contentElement.GetChild("type").GetStringValue());
|
||||
contentElement.RemoveChild("type");
|
||||
}
|
||||
|
||||
behavior->UnserializeFrom(contentElement);
|
||||
}
|
||||
// end of compatibility code
|
||||
else {
|
||||
behavior->UnserializeFrom(behaviorElement);
|
||||
}
|
||||
|
||||
bool isFolded = behaviorElement.GetBoolAttribute("isFolded", false);
|
||||
behavior->SetFolded(isFolded);
|
||||
|
||||
// Handle Quick Customization info.
|
||||
if (behaviorElement.HasChild("propertiesQuickCustomizationVisibilities")) {
|
||||
behavior->GetPropertiesQuickCustomizationVisibilities().UnserializeFrom(
|
||||
behaviorElement.GetChild("propertiesQuickCustomizationVisibilities"));
|
||||
}
|
||||
if (behaviorElement.HasChild("quickCustomizationVisibility")) {
|
||||
behavior->SetQuickCustomizationVisibility(
|
||||
QuickCustomization::StringAsVisibility(
|
||||
behaviorElement.GetStringAttribute(
|
||||
"quickCustomizationVisibility")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BehaviorsContainer::SerializeTo(SerializerElement &element) const {
|
||||
element.ConsiderAsArrayOf("behavior");
|
||||
std::vector<gd::String> allBehaviors = GetAllBehaviorNames();
|
||||
for (std::size_t i = 0; i < allBehaviors.size(); ++i) {
|
||||
const gd::Behavior &behavior = GetBehavior(allBehaviors[i]);
|
||||
// Default behaviors are added at the object creation according to
|
||||
// metadata. They don't need to be serialized.
|
||||
// During the export, all behaviors are set as not default by
|
||||
// `BehaviorDefaultFlagClearer` because the Runtime needs all the behaviors.
|
||||
if (behavior.IsDefaultBehavior()) {
|
||||
continue;
|
||||
}
|
||||
SerializerElement &behaviorElement = element.AddChild("behavior");
|
||||
|
||||
behavior.SerializeTo(behaviorElement);
|
||||
behaviorElement.RemoveChild("type"); // The content can contain type or
|
||||
// name properties, remove them.
|
||||
behaviorElement.RemoveChild("name");
|
||||
behaviorElement.RemoveChild("isFolded");
|
||||
behaviorElement.SetAttribute("type", behavior.GetTypeName());
|
||||
behaviorElement.SetAttribute("name", behavior.GetName());
|
||||
if (behavior.IsFolded())
|
||||
behaviorElement.SetAttribute("isFolded", true);
|
||||
|
||||
// Handle Quick Customization info.
|
||||
behaviorElement.RemoveChild("propertiesQuickCustomizationVisibilities");
|
||||
const QuickCustomizationVisibilitiesContainer
|
||||
&propertiesQuickCustomizationVisibilities =
|
||||
behavior.GetPropertiesQuickCustomizationVisibilities();
|
||||
if (!propertiesQuickCustomizationVisibilities.IsEmpty()) {
|
||||
propertiesQuickCustomizationVisibilities.SerializeTo(
|
||||
behaviorElement.AddChild("propertiesQuickCustomizationVisibilities"));
|
||||
}
|
||||
const QuickCustomization::Visibility visibility =
|
||||
behavior.GetQuickCustomizationVisibility();
|
||||
if (visibility != QuickCustomization::Visibility::Default) {
|
||||
behaviorElement.SetAttribute(
|
||||
"quickCustomizationVisibility",
|
||||
QuickCustomization::VisibilityAsString(visibility));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival ([email protected]). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/EffectsContainer.h"
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
#include "GDCore/Project/VariablesContainer.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Tools/MakeUnique.h"
|
||||
#include "GDCore/Vector2.h"
|
||||
|
||||
namespace gd {
|
||||
class PropertyDescriptor;
|
||||
class Project;
|
||||
class Layout;
|
||||
class ArbitraryResourceWorker;
|
||||
class InitialInstance;
|
||||
class SerializerElement;
|
||||
class EffectsContainer;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Represent an behaviors container of a platform
|
||||
*
|
||||
* \ingroup PlatformDefinition
|
||||
*/
|
||||
class GD_CORE_API BehaviorsContainer {
|
||||
public:
|
||||
/**
|
||||
* Create a new behaviors container with the name passed as argument.
|
||||
*/
|
||||
BehaviorsContainer(bool isOverriding = false);
|
||||
|
||||
/**
|
||||
* Copy constructor. Calls Init().
|
||||
*/
|
||||
BehaviorsContainer(const gd::BehaviorsContainer &behaviorsContainer) {
|
||||
Init(behaviorsContainer);
|
||||
};
|
||||
|
||||
/**
|
||||
* Assignment operator. Calls Init().
|
||||
*/
|
||||
BehaviorsContainer &
|
||||
operator=(const gd::BehaviorsContainer &behaviorsContainer) {
|
||||
if ((this) != &behaviorsContainer)
|
||||
Init(behaviorsContainer);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~BehaviorsContainer();
|
||||
|
||||
/** \name Behaviors management
|
||||
* Members functions related to behaviors management.
|
||||
*/
|
||||
///@{
|
||||
|
||||
/**
|
||||
* \brief Return a vector containing the names of all the behaviors used by
|
||||
* the behaviors container
|
||||
*/
|
||||
std::vector<gd::String> GetAllBehaviorNames() const;
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the content of the behavior called \a name.
|
||||
*/
|
||||
Behavior &GetBehavior(const gd::String &name);
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the content of the behavior called \a name.
|
||||
*/
|
||||
const Behavior &GetBehavior(const gd::String &name) const;
|
||||
|
||||
/**
|
||||
* \brief Return true if behaviors container has a behavior called \a name.
|
||||
*/
|
||||
bool HasBehaviorNamed(const gd::String &name) const;
|
||||
|
||||
/**
|
||||
* \brief Remove behavior called \a name
|
||||
*/
|
||||
void RemoveBehavior(const gd::String &name);
|
||||
|
||||
/**
|
||||
* \brief Change the name of behavior called name to newName.
|
||||
* \return true if name was successfully changed
|
||||
*/
|
||||
bool RenameBehavior(const gd::String &name, const gd::String &newName);
|
||||
|
||||
/**
|
||||
* \brief Add the behavior of the specified \a type with the specified \a
|
||||
* name.
|
||||
*
|
||||
* The project's current platform is used to initialize the content.
|
||||
*
|
||||
* \return A pointer to the newly added behavior content. NULL if the creation
|
||||
* failed.
|
||||
*/
|
||||
gd::Behavior *AddNewBehavior(const gd::Project &project,
|
||||
const gd::String &type, const gd::String &name);
|
||||
|
||||
/**
|
||||
* \brief Get a read-only access to the map containing the behaviors with
|
||||
* their properties.
|
||||
*/
|
||||
const std::map<gd::String, std::unique_ptr<gd::Behavior>> &
|
||||
GetAllBehaviorContents() const {
|
||||
return behaviors;
|
||||
};
|
||||
///@}
|
||||
|
||||
/** \name Serialization
|
||||
* Members functions related to serialization of the behaviors container
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Serialize the behaviors container.
|
||||
* \see DoSerializeTo
|
||||
*/
|
||||
void SerializeTo(SerializerElement &element) const;
|
||||
|
||||
/**
|
||||
* \brief Unserialize the behaviors container.
|
||||
* \see DoUnserializeFrom
|
||||
*/
|
||||
void UnserializeFrom(gd::Project &project, const SerializerElement &element);
|
||||
|
||||
protected:
|
||||
bool isOverriding = false;
|
||||
std::map<gd::String, std::unique_ptr<gd::Behavior>>
|
||||
behaviors; ///< Contains all behaviors and their properties for the
|
||||
///< behaviors container. Behavior contents are the ownership
|
||||
///< of the behaviors container.
|
||||
|
||||
/**
|
||||
* Initialize behaviors container using another behaviors container. Used by
|
||||
* copy-ctor and assign-op. Don't forget to update me if members were changed!
|
||||
*
|
||||
* It's needed because there is no default copy for a map of unique_ptr like
|
||||
* behaviors and it must be a deep copy.
|
||||
*/
|
||||
void Init(const gd::BehaviorsContainer &behaviorsContainer);
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
@@ -66,7 +66,7 @@ void EventsBasedObjectVariant::UnserializeFrom(
|
||||
} else {
|
||||
layers.Reset();
|
||||
}
|
||||
initialInstances.UnserializeFrom(element.GetChild("instances"));
|
||||
initialInstances.UnserializeFrom(project, element.GetChild("instances"));
|
||||
editorSettings.UnserializeFrom(element.GetChild("editionSettings"));
|
||||
}
|
||||
|
||||
|
||||
@@ -12,9 +12,10 @@
|
||||
|
||||
namespace gd {
|
||||
|
||||
void ExternalLayout::UnserializeFrom(const SerializerElement& element) {
|
||||
void ExternalLayout::UnserializeFrom(gd::Project &project,
|
||||
const SerializerElement &element) {
|
||||
name = element.GetStringAttribute("name", "", "Name");
|
||||
instances.UnserializeFrom(element.GetChild("instances", 0, "Instances"));
|
||||
instances.UnserializeFrom(project, element.GetChild("instances", 0, "Instances"));
|
||||
editorSettings.UnserializeFrom(element.GetChild("editionSettings"));
|
||||
associatedLayout = element.GetStringAttribute("associatedLayout");
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef GDCORE_EXTERNALLAYOUT_H
|
||||
#define GDCORE_EXTERNALLAYOUT_H
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "GDCore/Project/InitialInstancesContainer.h"
|
||||
@@ -86,7 +86,7 @@ class GD_CORE_API ExternalLayout {
|
||||
/**
|
||||
* \brief Unserialize the external layout.
|
||||
*/
|
||||
void UnserializeFrom(const SerializerElement& element);
|
||||
void UnserializeFrom(gd::Project &project, const SerializerElement& element);
|
||||
///@}
|
||||
|
||||
private:
|
||||
@@ -98,4 +98,3 @@ class GD_CORE_API ExternalLayout {
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_EXTERNALLAYOUT_H
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/Tools/UUID/UUID.h"
|
||||
#include "GDCore/Extensions/Metadata/BehaviorMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Project/CustomBehavior.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
@@ -20,29 +24,12 @@ gd::String* InitialInstance::badStringPropertyValue = NULL;
|
||||
|
||||
InitialInstance::InitialInstance()
|
||||
: objectName(""),
|
||||
x(0),
|
||||
y(0),
|
||||
z(0),
|
||||
angle(0),
|
||||
rotationX(0),
|
||||
rotationY(0),
|
||||
zOrder(0),
|
||||
opacity(255),
|
||||
layer(""),
|
||||
flippedX(false),
|
||||
flippedY(false),
|
||||
flippedZ(false),
|
||||
customSize(false),
|
||||
customDepth(false),
|
||||
width(0),
|
||||
height(0),
|
||||
depth(0),
|
||||
locked(false),
|
||||
sealed(false),
|
||||
keepRatio(true),
|
||||
persistentUuid(UUID::MakeUuid4()) {}
|
||||
persistentUuid(UUID::MakeUuid4()),
|
||||
behaviorOverridings(true) {}
|
||||
|
||||
void InitialInstance::UnserializeFrom(const SerializerElement& element) {
|
||||
void InitialInstance::UnserializeFrom(gd::Project &project,
|
||||
const SerializerElement &element) {
|
||||
SetObjectName(element.GetStringAttribute("name", "", "nom"));
|
||||
SetX(element.GetDoubleAttribute("x"));
|
||||
SetY(element.GetDoubleAttribute("y"));
|
||||
@@ -131,6 +118,11 @@ void InitialInstance::UnserializeFrom(const SerializerElement& element) {
|
||||
GetVariables().UnserializeFrom(
|
||||
element.GetChild("initialVariables", 0, "InitialVariables"));
|
||||
}
|
||||
|
||||
if (element.HasChild("behaviorOverridings")) {
|
||||
behaviorOverridings.UnserializeFrom(
|
||||
project, element.GetChild("behaviorOverridings"));
|
||||
}
|
||||
}
|
||||
|
||||
void InitialInstance::SerializeTo(SerializerElement& element) const {
|
||||
@@ -178,6 +170,10 @@ void InitialInstance::SerializeTo(SerializerElement& element) const {
|
||||
}
|
||||
|
||||
GetVariables().SerializeTo(element.AddChild("initialVariables"));
|
||||
|
||||
if (!behaviorOverridings.GetAllBehaviorContents().empty()) {
|
||||
behaviorOverridings.SerializeTo(element.AddChild("behaviorOverridings"));
|
||||
}
|
||||
}
|
||||
|
||||
InitialInstance& InitialInstance::ResetPersistentUuid() {
|
||||
@@ -243,4 +239,70 @@ void InitialInstance::SetRawStringProperty(const gd::String& name,
|
||||
stringProperties[name] = value;
|
||||
}
|
||||
|
||||
bool InitialInstance::HasAnyOverriddenProperty(const gd::Object &object) {
|
||||
for (auto &behaviorOverridingPair : behaviorOverridings.GetAllBehaviorContents()) {
|
||||
auto &behaviorName = behaviorOverridingPair.first;
|
||||
if (HasAnyOverriddenPropertyForBehavior(object.GetBehavior(behaviorName))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InitialInstance::HasAnyOverriddenPropertyForBehavior(
|
||||
const gd::Behavior &behavior) {
|
||||
auto &behaviorName = behavior.GetName();
|
||||
if (!HasBehaviorOverridingNamed(behaviorName)) {
|
||||
return false;
|
||||
}
|
||||
auto &behaviorOverriding = GetBehaviorOverriding(behaviorName);
|
||||
if (behaviorOverriding.GetContent().IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
const auto &overridingProperties = behaviorOverriding.GetProperties();
|
||||
for (auto &propertyPair : behavior.GetProperties()) {
|
||||
auto &propertyName = propertyPair.first;
|
||||
auto &behaviorProperty = propertyPair.second;
|
||||
|
||||
if (behaviorProperty.GetType() != "Behavior" &&
|
||||
behaviorOverriding.HasPropertyValue(propertyName) &&
|
||||
overridingProperties.find(propertyName) !=
|
||||
overridingProperties.end() &&
|
||||
overridingProperties.at(propertyName).GetValue() !=
|
||||
behaviorProperty.GetValue()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
gd::Behavior &InitialInstance::GetBehaviorOverriding(const gd::String &name) {
|
||||
return behaviorOverridings.GetBehavior(name);
|
||||
}
|
||||
|
||||
const gd::Behavior &
|
||||
InitialInstance::GetBehaviorOverriding(const gd::String &name) const {
|
||||
return behaviorOverridings.GetBehavior(name);
|
||||
}
|
||||
|
||||
bool InitialInstance::HasBehaviorOverridingNamed(const gd::String &name) const {
|
||||
return behaviorOverridings.HasBehaviorNamed(name);
|
||||
}
|
||||
|
||||
void InitialInstance::RemoveBehaviorOverriding(const gd::String &name) {
|
||||
behaviorOverridings.RemoveBehavior(name);
|
||||
}
|
||||
|
||||
bool InitialInstance::RenameBehaviorOverriding(const gd::String &name,
|
||||
const gd::String &newName) {
|
||||
return behaviorOverridings.RenameBehavior(name, newName);
|
||||
}
|
||||
|
||||
gd::Behavior *
|
||||
InitialInstance::AddNewBehaviorOverriding(const gd::Project &project,
|
||||
const gd::String &type,
|
||||
const gd::String &name) {
|
||||
return behaviorOverridings.AddNewBehavior(project, type, name);
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
||||
@@ -9,12 +9,15 @@
|
||||
#include <map>
|
||||
|
||||
#include "GDCore/Project/VariablesContainer.h"
|
||||
#include "GDCore/Project/BehaviorsContainer.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class PropertyDescriptor;
|
||||
class Project;
|
||||
class Layout;
|
||||
class ObjectsContainer;
|
||||
class Object;
|
||||
class Behavior;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
@@ -286,6 +289,67 @@ class GD_CORE_API InitialInstance {
|
||||
gd::VariablesContainer& GetVariables() { return initialVariables; }
|
||||
///@}
|
||||
|
||||
/** \name Behavior management
|
||||
* Members functions related to behavior overridings management.
|
||||
*/
|
||||
///@{
|
||||
|
||||
/**
|
||||
* \brief Return `true` if any property from the overriding has a different
|
||||
* value from any behavior.
|
||||
*/
|
||||
bool HasAnyOverriddenProperty(const gd::Object &object);
|
||||
|
||||
/**
|
||||
* \brief Return `true` if any property from the overriding has a different
|
||||
* value from the given behavior.
|
||||
*/
|
||||
bool HasAnyOverriddenPropertyForBehavior(const gd::Behavior &behavior);
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the content of the overriding of of the
|
||||
* behavior called \a name.
|
||||
*/
|
||||
Behavior &GetBehaviorOverriding(const gd::String &name);
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the content of the overriding of the behavior
|
||||
* called \a name.
|
||||
*/
|
||||
const Behavior &GetBehaviorOverriding(const gd::String &name) const;
|
||||
|
||||
/**
|
||||
* \brief Return true if the object instance overrides the object behavior
|
||||
* called \a name.
|
||||
*/
|
||||
bool HasBehaviorOverridingNamed(const gd::String &name) const;
|
||||
|
||||
/**
|
||||
* \brief Remove the behavior overrides for the behavior called \a name
|
||||
*/
|
||||
void RemoveBehaviorOverriding(const gd::String &name);
|
||||
|
||||
/**
|
||||
* \brief Change the name of behavior called name to newName.
|
||||
* \return true if name was successfully changed
|
||||
*/
|
||||
bool RenameBehaviorOverriding(const gd::String &name,
|
||||
const gd::String &newName);
|
||||
|
||||
/**
|
||||
* \brief Add the behavior of the specified \a type with the specified \a
|
||||
* name.
|
||||
*
|
||||
* The project's current platform is used to initialize the content.
|
||||
*
|
||||
* \return A pointer to the newly added behavior content. NULL if the creation
|
||||
* failed.
|
||||
*/
|
||||
gd::Behavior *AddNewBehaviorOverriding(const gd::Project &project,
|
||||
const gd::String &type,
|
||||
const gd::String &name);
|
||||
///@}
|
||||
|
||||
/** \name Others properties management
|
||||
* Members functions related to exposing others properties of the instance.
|
||||
*
|
||||
@@ -365,7 +429,8 @@ class GD_CORE_API InitialInstance {
|
||||
/**
|
||||
* \brief Unserialize the instances container.
|
||||
*/
|
||||
virtual void UnserializeFrom(const SerializerElement& element);
|
||||
virtual void UnserializeFrom(gd::Project &project,
|
||||
const SerializerElement &element);
|
||||
|
||||
/**
|
||||
* \brief Reset the persistent UUID used to recognize
|
||||
@@ -376,8 +441,8 @@ class GD_CORE_API InitialInstance {
|
||||
/**
|
||||
* \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:
|
||||
@@ -388,32 +453,36 @@ class GD_CORE_API InitialInstance {
|
||||
std::map<gd::String, gd::String>
|
||||
stringProperties; ///< More data which can be used by the object
|
||||
|
||||
gd::String objectName; ///< Object name
|
||||
double x; ///< Instance X position
|
||||
double y; ///< Instance Y position
|
||||
double z; ///< Instance Z position (for a 3D object)
|
||||
double angle; ///< Instance angle on Z axis
|
||||
double rotationX; ///< Instance angle on X axis (for a 3D object)
|
||||
double rotationY; ///< Instance angle on Y axis (for a 3D object)
|
||||
int zOrder; ///< Instance Z order (for a 2D object)
|
||||
int opacity; ///< Instance opacity
|
||||
bool flippedX; ///< True if the instance is flipped on X axis
|
||||
bool flippedY; ///< True if the instance is flipped on Y axis
|
||||
bool flippedZ; ///< True if the instance is flipped on Z axis
|
||||
gd::String layer; ///< Instance layer
|
||||
bool customSize; ///< True if object has a custom width and height
|
||||
bool customDepth; ///< True if object has a custom depth
|
||||
double width; ///< Instance custom width
|
||||
double height; ///< Instance custom height
|
||||
double depth; ///< Instance custom depth
|
||||
gd::String objectName; ///< Object name
|
||||
double x = 0; ///< Instance X position
|
||||
double y = 0; ///< Instance Y position
|
||||
double z = 0; ///< Instance Z position (for a 3D object)
|
||||
double angle = 0; ///< Instance angle on Z axis
|
||||
double rotationX = 0; ///< Instance angle on X axis (for a 3D object)
|
||||
double rotationY = 0; ///< Instance angle on Y axis (for a 3D object)
|
||||
int zOrder = 0; ///< Instance Z order (for a 2D object)
|
||||
int opacity = 255; ///< Instance opacity
|
||||
bool flippedX = false; ///< True if the instance is flipped on X axis
|
||||
bool flippedY = false; ///< True if the instance is flipped on Y axis
|
||||
bool flippedZ = false; ///< True if the instance is flipped on Z axis
|
||||
gd::String layer; ///< Instance layer
|
||||
bool customSize = false; ///< True if object has a custom width and height
|
||||
bool customDepth = false; ///< True if object has a custom depth
|
||||
double width = 0; ///< Instance custom width
|
||||
double height = 0; ///< Instance custom height
|
||||
double depth = 0; ///< 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
|
||||
bool keepRatio; ///< True if the instance's dimensions
|
||||
/// should keep the same ratio.
|
||||
gd::BehaviorsContainer
|
||||
behaviorOverridings; ///< Contains all behavior property overriding for
|
||||
///< the instance. Behavior contents are the
|
||||
///< ownership of the instance.
|
||||
bool locked = false; ///< True if the instance is locked
|
||||
bool sealed = false; ///< True if the instance is sealed
|
||||
bool keepRatio = true; ///< True if the instance's dimensions
|
||||
/// should keep the same ratio.
|
||||
mutable gd::String persistentUuid; ///< A persistent random version 4 UUID,
|
||||
/// useful for hot reloading.
|
||||
|
||||
|
||||
@@ -25,13 +25,13 @@ std::size_t InitialInstancesContainer::GetInstancesCount() const {
|
||||
}
|
||||
|
||||
void InitialInstancesContainer::UnserializeFrom(
|
||||
const SerializerElement& element) {
|
||||
gd::Project &project, const SerializerElement &element) {
|
||||
initialInstances.clear();
|
||||
|
||||
element.ConsiderAsArrayOf("instance", "Objet");
|
||||
for (std::size_t i = 0; i < element.GetChildrenCount(); ++i) {
|
||||
gd::InitialInstance instance;
|
||||
instance.UnserializeFrom(element.GetChild(i));
|
||||
instance.UnserializeFrom(project, element.GetChild(i));
|
||||
initialInstances.push_back(instance);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,10 +187,11 @@ class GD_CORE_API InitialInstancesContainer {
|
||||
/**
|
||||
* \brief Unserialize the instances container.
|
||||
*/
|
||||
virtual void UnserializeFrom(const SerializerElement &element);
|
||||
virtual void UnserializeFrom(gd::Project &project,
|
||||
const SerializerElement &element);
|
||||
///@}
|
||||
|
||||
private:
|
||||
private:
|
||||
void RemoveInstanceIf(
|
||||
std::function<bool(const gd::InitialInstance &)> predicate);
|
||||
|
||||
|
||||
@@ -334,7 +334,7 @@ void Layout::UnserializeFrom(gd::Project& project,
|
||||
objectsContainer.AddMissingObjectsInRootFolder();
|
||||
|
||||
initialInstances.UnserializeFrom(
|
||||
element.GetChild("instances", 0, "Positions"));
|
||||
project, element.GetChild("instances", 0, "Positions"));
|
||||
variables.UnserializeFrom(element.GetChild("variables", 0, "Variables"));
|
||||
|
||||
layers.UnserializeLayersFrom(element.GetChild("layers", 0, "Layers"));
|
||||
|
||||
+12
-141
@@ -51,7 +51,7 @@ void Object::CopyWithoutConfiguration(const gd::Object& object) {
|
||||
assetStoreId = object.assetStoreId;
|
||||
objectVariables = object.objectVariables;
|
||||
effectsContainer = object.effectsContainer;
|
||||
behaviors = gd::Clone(object.behaviors);
|
||||
behaviors = object.behaviors;
|
||||
}
|
||||
|
||||
gd::ObjectConfiguration& Object::GetConfiguration() { return *configuration; }
|
||||
@@ -61,69 +61,31 @@ const gd::ObjectConfiguration& Object::GetConfiguration() const {
|
||||
}
|
||||
|
||||
std::vector<gd::String> Object::GetAllBehaviorNames() const {
|
||||
std::vector<gd::String> allNameIdentifiers;
|
||||
|
||||
for (auto& it : behaviors) allNameIdentifiers.push_back(it.first);
|
||||
|
||||
return allNameIdentifiers;
|
||||
return behaviors.GetAllBehaviorNames();
|
||||
}
|
||||
|
||||
void Object::RemoveBehavior(const gd::String& name) { behaviors.erase(name); }
|
||||
void Object::RemoveBehavior(const gd::String& name) { behaviors.RemoveBehavior(name); }
|
||||
|
||||
bool Object::RenameBehavior(const gd::String& name, const gd::String& newName) {
|
||||
if (behaviors.find(name) == behaviors.end() ||
|
||||
behaviors.find(newName) != behaviors.end())
|
||||
return false;
|
||||
|
||||
std::unique_ptr<Behavior> aut = std::move(behaviors.find(name)->second);
|
||||
behaviors.erase(name);
|
||||
behaviors[newName] = std::move(aut);
|
||||
behaviors[newName]->SetName(newName);
|
||||
|
||||
return true;
|
||||
return behaviors.RenameBehavior(name, newName);
|
||||
}
|
||||
|
||||
gd::Behavior& Object::GetBehavior(const gd::String& name) {
|
||||
return *behaviors.find(name)->second;
|
||||
return behaviors.GetBehavior(name);
|
||||
}
|
||||
|
||||
const gd::Behavior& Object::GetBehavior(const gd::String& name) const {
|
||||
return *behaviors.find(name)->second;
|
||||
return behaviors.GetBehavior(name);
|
||||
}
|
||||
|
||||
bool Object::HasBehaviorNamed(const gd::String& name) const {
|
||||
return behaviors.find(name) != behaviors.end();
|
||||
return behaviors.HasBehaviorNamed(name);
|
||||
}
|
||||
|
||||
gd::Behavior* Object::AddNewBehavior(const gd::Project& project,
|
||||
const gd::String& type,
|
||||
const gd::String& name) {
|
||||
auto initializeAndAdd = [this,
|
||||
&name](std::unique_ptr<gd::Behavior> behavior) {
|
||||
behavior->InitializeContent();
|
||||
this->behaviors[name] = std::move(behavior);
|
||||
return this->behaviors[name].get();
|
||||
};
|
||||
|
||||
if (project.HasEventsBasedBehavior(type)) {
|
||||
return initializeAndAdd(
|
||||
gd::make_unique<CustomBehavior>(name, project, type));
|
||||
} else {
|
||||
const gd::BehaviorMetadata& behaviorMetadata =
|
||||
gd::MetadataProvider::GetBehaviorMetadata(project.GetCurrentPlatform(),
|
||||
type);
|
||||
if (gd::MetadataProvider::IsBadBehaviorMetadata(behaviorMetadata)) {
|
||||
gd::LogWarning("Tried to create a behavior with an unknown type: " +
|
||||
type + " on object " + GetName() + "!");
|
||||
// It's probably an events-based behavior that was removed.
|
||||
// Create a custom behavior to preserve the properties values.
|
||||
return initializeAndAdd(
|
||||
gd::make_unique<CustomBehavior>(name, project, type));
|
||||
}
|
||||
std::unique_ptr<gd::Behavior> behavior(behaviorMetadata.Get().Clone());
|
||||
behavior->SetName(name);
|
||||
return initializeAndAdd(std::move(behavior));
|
||||
}
|
||||
return behaviors.AddNewBehavior(project, type, name);
|
||||
}
|
||||
|
||||
void Object::UnserializeFrom(gd::Project& project,
|
||||
@@ -145,7 +107,7 @@ void Object::UnserializeFrom(gd::Project& project,
|
||||
// Compatibility with GD <= 3.3
|
||||
if (element.HasChild("Automatism")) {
|
||||
for (std::size_t i = 0; i < element.GetChildrenCount("Automatism"); ++i) {
|
||||
SerializerElement& behaviorElement = element.GetChild("Automatism", i);
|
||||
SerializerElement &behaviorElement = element.GetChild("Automatism", i);
|
||||
|
||||
gd::String type = behaviorElement.GetStringAttribute("type", "", "Type")
|
||||
.FindAndReplace("Automatism", "Behavior");
|
||||
@@ -157,59 +119,9 @@ void Object::UnserializeFrom(gd::Project& project,
|
||||
}
|
||||
// End of compatibility code
|
||||
else {
|
||||
SerializerElement& behaviorsElement =
|
||||
SerializerElement &behaviorsElement =
|
||||
element.GetChild("behaviors", 0, "automatisms");
|
||||
behaviorsElement.ConsiderAsArrayOf("behavior", "automatism");
|
||||
for (std::size_t i = 0; i < behaviorsElement.GetChildrenCount(); ++i) {
|
||||
SerializerElement& behaviorElement = behaviorsElement.GetChild(i);
|
||||
|
||||
gd::String type =
|
||||
behaviorElement.GetStringAttribute("type").FindAndReplace(
|
||||
"Automatism", "Behavior"); // Compatibility with GD <= 4
|
||||
gd::String name = behaviorElement.GetStringAttribute("name");
|
||||
|
||||
auto behavior = gd::Object::AddNewBehavior(project, type, name);
|
||||
// Compatibility with GD <= 4.0.98
|
||||
// If there is only one child called "content" (in addition to "type" and
|
||||
// "name"), it's the content of a JavaScript behavior. Move the content
|
||||
// out of the "content" object (to put it directly at the root of the
|
||||
// behavior element).
|
||||
if (behaviorElement.HasChild("content") &&
|
||||
behaviorElement.GetAllChildren().size() == 3) {
|
||||
SerializerElement& contentElement = behaviorElement.GetChild("content");
|
||||
|
||||
// Physics2 Behavior was using "type" for the type of the body. The name
|
||||
// conflicts with the behavior "type". Rename it.
|
||||
if (contentElement.HasChild("type")) {
|
||||
contentElement.AddChild("bodyType")
|
||||
.SetValue(contentElement.GetChild("type").GetStringValue());
|
||||
contentElement.RemoveChild("type");
|
||||
}
|
||||
|
||||
behavior->UnserializeFrom(contentElement);
|
||||
}
|
||||
// end of compatibility code
|
||||
else {
|
||||
behavior->UnserializeFrom(behaviorElement);
|
||||
}
|
||||
|
||||
bool isFolded = behaviorElement.GetBoolAttribute("isFolded", false);
|
||||
behavior->SetFolded(isFolded);
|
||||
|
||||
// Handle Quick Customization info.
|
||||
if (behaviorElement.HasChild(
|
||||
"propertiesQuickCustomizationVisibilities")) {
|
||||
behavior->GetPropertiesQuickCustomizationVisibilities().UnserializeFrom(
|
||||
behaviorElement.GetChild(
|
||||
"propertiesQuickCustomizationVisibilities"));
|
||||
}
|
||||
if (behaviorElement.HasChild("quickCustomizationVisibility")) {
|
||||
behavior->SetQuickCustomizationVisibility(
|
||||
QuickCustomization::StringAsVisibility(
|
||||
behaviorElement.GetStringAttribute(
|
||||
"quickCustomizationVisibility")));
|
||||
}
|
||||
}
|
||||
behaviors.UnserializeFrom(project, behaviorsElement);
|
||||
}
|
||||
|
||||
configuration->UnserializeFrom(project, element);
|
||||
@@ -224,48 +136,7 @@ void Object::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("type", GetType());
|
||||
objectVariables.SerializeTo(element.AddChild("variables"));
|
||||
effectsContainer.SerializeTo(element.AddChild("effects"));
|
||||
|
||||
SerializerElement& behaviorsElement = element.AddChild("behaviors");
|
||||
behaviorsElement.ConsiderAsArrayOf("behavior");
|
||||
std::vector<gd::String> allBehaviors = GetAllBehaviorNames();
|
||||
for (std::size_t i = 0; i < allBehaviors.size(); ++i) {
|
||||
const gd::Behavior& behavior = GetBehavior(allBehaviors[i]);
|
||||
// Default behaviors are added at the object creation according to
|
||||
// metadata. They don't need to be serialized.
|
||||
// During the export, all behaviors are set as not default by
|
||||
// `BehaviorDefaultFlagClearer` because the Runtime needs all the behaviors.
|
||||
if (behavior.IsDefaultBehavior()) {
|
||||
continue;
|
||||
}
|
||||
SerializerElement& behaviorElement = behaviorsElement.AddChild("behavior");
|
||||
|
||||
behavior.SerializeTo(behaviorElement);
|
||||
behaviorElement.RemoveChild("type"); // The content can contain type or
|
||||
// name properties, remove them.
|
||||
behaviorElement.RemoveChild("name");
|
||||
behaviorElement.RemoveChild("isFolded");
|
||||
behaviorElement.SetAttribute("type", behavior.GetTypeName());
|
||||
behaviorElement.SetAttribute("name", behavior.GetName());
|
||||
if (behavior.IsFolded()) behaviorElement.SetAttribute("isFolded", true);
|
||||
|
||||
// Handle Quick Customization info.
|
||||
behaviorElement.RemoveChild("propertiesQuickCustomizationVisibilities");
|
||||
const QuickCustomizationVisibilitiesContainer&
|
||||
propertiesQuickCustomizationVisibilities =
|
||||
behavior.GetPropertiesQuickCustomizationVisibilities();
|
||||
if (!propertiesQuickCustomizationVisibilities.IsEmpty()) {
|
||||
propertiesQuickCustomizationVisibilities.SerializeTo(
|
||||
behaviorElement.AddChild("propertiesQuickCustomizationVisibilities"));
|
||||
}
|
||||
const QuickCustomization::Visibility visibility =
|
||||
behavior.GetQuickCustomizationVisibility();
|
||||
if (visibility != QuickCustomization::Visibility::Default) {
|
||||
behaviorElement.SetAttribute(
|
||||
"quickCustomizationVisibility",
|
||||
QuickCustomization::VisibilityAsString(visibility));
|
||||
}
|
||||
}
|
||||
|
||||
behaviors.SerializeTo(element.AddChild("behaviors"));
|
||||
configuration->SerializeTo(element);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorsContainer.h"
|
||||
#include "GDCore/Project/EffectsContainer.h"
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
#include "GDCore/Project/VariablesContainer.h"
|
||||
@@ -180,7 +181,7 @@ class GD_CORE_API Object {
|
||||
*/
|
||||
const std::map<gd::String, std::unique_ptr<gd::Behavior>>&
|
||||
GetAllBehaviorContents() const {
|
||||
return behaviors;
|
||||
return behaviors.GetAllBehaviorContents();
|
||||
};
|
||||
///@}
|
||||
|
||||
@@ -253,10 +254,10 @@ class GD_CORE_API Object {
|
||||
gd::String assetStoreId; ///< The ID of the asset if the object comes from
|
||||
///< the store.
|
||||
std::unique_ptr<gd::ObjectConfiguration> configuration;
|
||||
std::map<gd::String, std::unique_ptr<gd::Behavior>>
|
||||
behaviors; ///< Contains all behaviors and their properties for the
|
||||
///< object. Behavior contents are the ownership of the
|
||||
///< object.
|
||||
gd::BehaviorsContainer
|
||||
behaviors; ///< Contains all behaviors and their properties for the
|
||||
///< object. Behavior contents are the ownership of the
|
||||
///< object.
|
||||
gd::VariablesContainer
|
||||
objectVariables; ///< List of the variables of the object
|
||||
gd::EffectsContainer
|
||||
|
||||
@@ -915,7 +915,7 @@ void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
|
||||
gd::ExternalLayout& newExternalLayout =
|
||||
InsertNewExternalLayout("", GetExternalLayoutsCount());
|
||||
newExternalLayout.UnserializeFrom(externalLayoutElement);
|
||||
newExternalLayout.UnserializeFrom(*this, externalLayoutElement);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -283,6 +283,19 @@ void SerializerElement::RemoveChild(const gd::String& name) {
|
||||
}
|
||||
}
|
||||
|
||||
void SerializerElement::Clear() {
|
||||
children.clear();
|
||||
attributes.clear();
|
||||
}
|
||||
|
||||
bool SerializerElement::IsEmpty() {
|
||||
return children.empty() && attributes.empty();
|
||||
}
|
||||
|
||||
void SerializerElement::RemoveAttribute(const gd::String& name) {
|
||||
attributes.erase(name);
|
||||
}
|
||||
|
||||
void SerializerElement::Init(const gd::SerializerElement& other) {
|
||||
valueUndefined = other.valueUndefined;
|
||||
elementValue = other.elementValue;
|
||||
|
||||
@@ -329,6 +329,12 @@ class GD_CORE_API SerializerElement {
|
||||
*/
|
||||
bool HasAttribute(const gd::String &name) const;
|
||||
|
||||
/**
|
||||
* \brief Remove the attribute with the specified name
|
||||
* \param name The name of the attribute to remove.
|
||||
*/
|
||||
void RemoveAttribute(const gd::String& name);
|
||||
|
||||
/**
|
||||
* \brief Return all the attributes of the element.
|
||||
*/
|
||||
@@ -438,6 +444,13 @@ class GD_CORE_API SerializerElement {
|
||||
*/
|
||||
void RemoveChild(const gd::String &name);
|
||||
|
||||
/**
|
||||
* \brief Remove all children and attributes.
|
||||
*/
|
||||
void Clear();
|
||||
|
||||
bool IsEmpty();
|
||||
|
||||
/**
|
||||
* \brief Return all the children of the element.
|
||||
*/
|
||||
|
||||
@@ -20,6 +20,62 @@
|
||||
#include "GDCore/Extensions/Metadata/ParameterOptions.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
class BehaviorWithProperties : public gd::Behavior {
|
||||
public:
|
||||
BehaviorWithProperties(
|
||||
const gd::String& name, const gd::String& type)
|
||||
: Behavior(name, type) {};
|
||||
virtual ~BehaviorWithProperties(){};
|
||||
virtual std::unique_ptr<gd::Behavior> Clone() const override {
|
||||
return gd::make_unique<BehaviorWithProperties>(*this);
|
||||
}
|
||||
|
||||
virtual std::map<gd::String, gd::PropertyDescriptor> GetProperties(
|
||||
const gd::SerializerElement& behaviorContent) const override {
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties["numberProperty"]
|
||||
.SetLabel("Number property")
|
||||
.SetValue(
|
||||
gd::String::From(behaviorContent.GetChild("numberProperty").GetDoubleValue()))
|
||||
.SetType("Number");
|
||||
properties["stringProperty"]
|
||||
.SetLabel("String property")
|
||||
.SetValue(
|
||||
behaviorContent.GetChild("stringProperty").GetStringValue())
|
||||
.SetType("String");
|
||||
properties["booleanProperty"]
|
||||
.SetLabel("Boolean property")
|
||||
.SetValue(
|
||||
behaviorContent.GetChild("booleanProperty").GetBoolValue() ? "true" : "false")
|
||||
.SetType("Boolean");
|
||||
return properties;
|
||||
}
|
||||
virtual bool UpdateProperty(gd::SerializerElement& behaviorContent,
|
||||
const gd::String& name,
|
||||
const gd::String& value) override {
|
||||
auto &element = behaviorContent.AddChild(name);
|
||||
if (name == "numberProperty") {
|
||||
element.SetDoubleValue(value.To<double>());
|
||||
return true;
|
||||
}
|
||||
if (name == "stringProperty") {
|
||||
element.SetStringValue(value);
|
||||
return true;
|
||||
}
|
||||
if (name == "booleanProperty") {
|
||||
element.SetBoolValue(value == "1");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
virtual void InitializeContent(
|
||||
gd::SerializerElement& behaviorContent) override {
|
||||
behaviorContent.AddChild("numberProperty").SetDoubleValue(123);
|
||||
behaviorContent.AddChild("stringProperty").SetStringValue("ABC");
|
||||
behaviorContent.AddChild("booleanProperty").SetBoolValue(true);
|
||||
}
|
||||
};
|
||||
|
||||
// TODO Remove these 2 classes and write the test with events based behaviors.
|
||||
class BehaviorWithRequiredBehaviorProperty : public gd::Behavior {
|
||||
public:
|
||||
@@ -564,7 +620,7 @@ void SetupProjectWithDummyPlatform(gd::Project& project,
|
||||
"Group",
|
||||
"Icon.png",
|
||||
"MyBehavior",
|
||||
gd::make_unique<gd::Behavior>(
|
||||
gd::make_unique<BehaviorWithProperties>(
|
||||
"Behavior", "MyExtension::MyBehavior"),
|
||||
gd::make_unique<gd::BehaviorsSharedData>());
|
||||
behavior
|
||||
|
||||
@@ -12,18 +12,109 @@
|
||||
#include <initializer_list>
|
||||
#include <map>
|
||||
|
||||
#include "DummyPlatform.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Project/InitialInstance.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/Tools/VersionWrapper.h"
|
||||
|
||||
TEST_CASE("InitialInstance", "[common][instances]") {
|
||||
gd::InitialInstance instance;
|
||||
|
||||
SECTION("GetRawDoubleProperty") {
|
||||
gd::InitialInstance instance;
|
||||
REQUIRE(instance.GetRawDoubleProperty("NotExistingProperty") == 0);
|
||||
}
|
||||
|
||||
SECTION("GetRawStringProperty") {
|
||||
gd::InitialInstance instance;
|
||||
REQUIRE(instance.GetRawStringProperty("NotExistingProperty") == "");
|
||||
}
|
||||
|
||||
SECTION("Can create an instance without behavior property overriding") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::FakeObjectWithDefaultBehavior", "MyObject", 0);
|
||||
object.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
REQUIRE(object.HasBehaviorNamed("MyBehavior") == true);
|
||||
gd::Behavior &behavior = object.GetBehavior("MyBehavior");
|
||||
|
||||
gd::InitialInstance instance;
|
||||
instance.SetObjectName("MyObject");
|
||||
REQUIRE(instance.HasAnyOverriddenProperty(object) == false);
|
||||
REQUIRE(instance.HasAnyOverriddenPropertyForBehavior(behavior) == false);
|
||||
REQUIRE(instance.HasBehaviorOverridingNamed("MyBehavior") == false);
|
||||
}
|
||||
|
||||
SECTION("Can add and remove behavior property overridings on an instance") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::FakeObjectWithDefaultBehavior", "MyObject", 0);
|
||||
object.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
REQUIRE(object.HasBehaviorNamed("MyBehavior") == true);
|
||||
gd::Behavior &behavior = object.GetBehavior("MyBehavior");
|
||||
|
||||
gd::InitialInstance instance;
|
||||
instance.SetObjectName("MyObject");
|
||||
instance.AddNewBehaviorOverriding(project, "MyExtension::MyBehavior",
|
||||
"MyBehavior");
|
||||
REQUIRE(instance.HasBehaviorOverridingNamed("MyBehavior") == true);
|
||||
gd::Behavior &behaviorOverriding =
|
||||
instance.GetBehaviorOverriding("MyBehavior");
|
||||
|
||||
// The behavior overriding is empty by default.
|
||||
REQUIRE(instance.HasAnyOverriddenProperty(object) == false);
|
||||
REQUIRE(instance.HasAnyOverriddenPropertyForBehavior(behavior) == false);
|
||||
REQUIRE(behaviorOverriding.HasPropertyValue("numberProperty") == false);
|
||||
REQUIRE(behaviorOverriding.HasPropertyValue("stringProperty") == false);
|
||||
REQUIRE(behaviorOverriding.HasPropertyValue("booleanProperty") == false);
|
||||
|
||||
// Add some behavior property overridings
|
||||
behaviorOverriding.UpdateProperty("numberProperty", "456");
|
||||
REQUIRE(
|
||||
behaviorOverriding.GetProperties().at("numberProperty").GetValue() ==
|
||||
"456");
|
||||
REQUIRE(behaviorOverriding.HasPropertyValue("numberProperty") == true);
|
||||
REQUIRE(instance.HasAnyOverriddenProperty(object) == true);
|
||||
REQUIRE(instance.HasAnyOverriddenPropertyForBehavior(behavior) == true);
|
||||
|
||||
behaviorOverriding.UpdateProperty("stringProperty", "DEF");
|
||||
REQUIRE(
|
||||
behaviorOverriding.GetProperties().at("stringProperty").GetValue() ==
|
||||
"DEF");
|
||||
REQUIRE(behaviorOverriding.HasPropertyValue("stringProperty") == true);
|
||||
|
||||
behaviorOverriding.UpdateProperty("booleanProperty", "false");
|
||||
REQUIRE(behaviorOverriding.HasPropertyValue("booleanProperty") == true);
|
||||
REQUIRE(
|
||||
behaviorOverriding.GetProperties().at("booleanProperty").GetValue() ==
|
||||
"false");
|
||||
|
||||
// The user set back original values from the object behavior.
|
||||
// The IDE removes the behavior property overridings accordingly.
|
||||
behaviorOverriding.RemoveProperty("numberProperty");
|
||||
REQUIRE(behaviorOverriding.HasPropertyValue("numberProperty") == false);
|
||||
behaviorOverriding.RemoveProperty("stringProperty");
|
||||
REQUIRE(behaviorOverriding.HasPropertyValue("stringProperty") == false);
|
||||
behaviorOverriding.RemoveProperty("booleanProperty");
|
||||
REQUIRE(behaviorOverriding.HasPropertyValue("booleanProperty") == false);
|
||||
|
||||
// No more property is overriden
|
||||
REQUIRE(instance.HasAnyOverriddenPropertyForBehavior(behavior) == false);
|
||||
REQUIRE(instance.HasAnyOverriddenProperty(object) == false);
|
||||
|
||||
// The IDE removes the behavior overriding accordingly.
|
||||
instance.RemoveBehaviorOverriding("MyBehavior");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,9 +70,10 @@ namespace gdjs {
|
||||
|
||||
constructor(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
objectData: gdjs.Object3DData
|
||||
objectData: gdjs.Object3DData,
|
||||
instanceData: InstanceData | undefined
|
||||
) {
|
||||
super(instanceContainer, objectData);
|
||||
super(instanceContainer, objectData, instanceData);
|
||||
// TODO Should 0 be replaced by 0.01 instead of using the default value?
|
||||
this._width = this._originalWidth = getValidDimensionValue(
|
||||
objectData.content.width
|
||||
|
||||
@@ -174,7 +174,7 @@ namespace gdjs {
|
||||
this.object = owner;
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
// Nothing to update.
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -84,9 +84,10 @@ namespace gdjs {
|
||||
|
||||
constructor(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
objectData: Cube3DObjectData
|
||||
objectData: Cube3DObjectData,
|
||||
instanceData?: InstanceData
|
||||
) {
|
||||
super(instanceContainer, objectData);
|
||||
super(instanceContainer, objectData, instanceData);
|
||||
this._shouldUseTransparentTexture =
|
||||
objectData.content.enableTextureTransparency || false;
|
||||
this._facesOrientation = objectData.content.facesOrientation || 'Y';
|
||||
|
||||
@@ -44,9 +44,10 @@ namespace gdjs {
|
||||
|
||||
constructor(
|
||||
parent: gdjs.RuntimeInstanceContainer,
|
||||
objectData: gdjs.Object3DData & gdjs.CustomObjectConfiguration
|
||||
objectData: gdjs.Object3DData & gdjs.CustomObjectConfiguration,
|
||||
instanceData?: InstanceData
|
||||
) {
|
||||
super(parent, objectData);
|
||||
super(parent, objectData, instanceData);
|
||||
}
|
||||
|
||||
protected override _createRender() {
|
||||
|
||||
@@ -114,9 +114,10 @@ namespace gdjs {
|
||||
|
||||
constructor(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
objectData: Model3DObjectData
|
||||
objectData: Model3DObjectData,
|
||||
instanceData?: InstanceData
|
||||
) {
|
||||
super(instanceContainer, objectData);
|
||||
super(instanceContainer, objectData, instanceData);
|
||||
this._data = objectData;
|
||||
this._modelResourceName = objectData.content.modelResourceName;
|
||||
this._animations = objectData.content.animations;
|
||||
|
||||
@@ -68,32 +68,24 @@ namespace gdjs {
|
||||
: behaviorData.useLegacyBottomAndRightAnchors;
|
||||
}
|
||||
|
||||
override updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
if (oldBehaviorData.leftEdgeAnchor !== newBehaviorData.leftEdgeAnchor) {
|
||||
this._leftEdgeAnchor = newBehaviorData.leftEdgeAnchor;
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
if (behaviorData.leftEdgeAnchor !== undefined) {
|
||||
this._leftEdgeAnchor = behaviorData.leftEdgeAnchor;
|
||||
}
|
||||
if (oldBehaviorData.rightEdgeAnchor !== newBehaviorData.rightEdgeAnchor) {
|
||||
this._rightEdgeAnchor = newBehaviorData.rightEdgeAnchor;
|
||||
if (behaviorData.rightEdgeAnchor !== undefined) {
|
||||
this._rightEdgeAnchor = behaviorData.rightEdgeAnchor;
|
||||
}
|
||||
if (oldBehaviorData.topEdgeAnchor !== newBehaviorData.topEdgeAnchor) {
|
||||
this._topEdgeAnchor = newBehaviorData.topEdgeAnchor;
|
||||
if (behaviorData.topEdgeAnchor !== undefined) {
|
||||
this._topEdgeAnchor = behaviorData.topEdgeAnchor;
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.bottomEdgeAnchor !== newBehaviorData.bottomEdgeAnchor
|
||||
) {
|
||||
this._bottomEdgeAnchor = newBehaviorData.bottomEdgeAnchor;
|
||||
if (behaviorData.bottomEdgeAnchor !== undefined) {
|
||||
this._bottomEdgeAnchor = behaviorData.bottomEdgeAnchor;
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.useLegacyTrajectory !==
|
||||
newBehaviorData.useLegacyTrajectory
|
||||
) {
|
||||
if (behaviorData.useLegacyTrajectory !== undefined) {
|
||||
this._useLegacyBottomAndRightAnchors =
|
||||
newBehaviorData.useLegacyBottomAndRightAnchors;
|
||||
behaviorData.useLegacyBottomAndRightAnchors;
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.relativeToOriginalWindowSize !==
|
||||
newBehaviorData.relativeToOriginalWindowSize
|
||||
) {
|
||||
if (behaviorData.relativeToOriginalWindowSize !== undefined) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// @ts-check
|
||||
describe('gdjs.AnchorRuntimeBehavior', () => {
|
||||
it('can fill a custom object with an child', async () => {
|
||||
it('can fill a custom object with a child', async () => {
|
||||
const runtimeGame = await gdjs.getPixiRuntimeGameWithAssets();
|
||||
const runtimeScene = new gdjs.TestRuntimeScene(runtimeGame);
|
||||
// The corresponding event-based object declaration is done by
|
||||
@@ -44,4 +44,109 @@ describe('gdjs.AnchorRuntimeBehavior', () => {
|
||||
expect(childObject.getWidth()).to.equal(2000);
|
||||
expect(childObject.getHeight()).to.equal(3000);
|
||||
});
|
||||
|
||||
it('can anchor 2 instances of the same object left and right', async () => {
|
||||
const runtimeGame = await gdjs.getPixiRuntimeGameWithAssets({
|
||||
customObjectInstances: [
|
||||
{
|
||||
angle: 0,
|
||||
customSize: true,
|
||||
height: 64,
|
||||
layer: '',
|
||||
name: 'MySprite',
|
||||
persistentUuid: '668db48d-4e12-4b6f-aa6b-f73b74bf608e',
|
||||
width: 32,
|
||||
x: 0,
|
||||
y: 0,
|
||||
zOrder: 1,
|
||||
numberProperties: [],
|
||||
stringProperties: [],
|
||||
initialVariables: [],
|
||||
behaviorOverridings: [
|
||||
// Magnet on the left
|
||||
{
|
||||
name: 'AnchorBehavior',
|
||||
type: 'AnchorBehavior::AnchorBehavior',
|
||||
rightEdgeAnchor: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
angle: 0,
|
||||
customSize: true,
|
||||
height: 64,
|
||||
layer: '',
|
||||
name: 'MySprite',
|
||||
persistentUuid: '668db48d-4e12-4b6f-aa6b-f73b74bf608e',
|
||||
width: 32,
|
||||
x: 32,
|
||||
y: 0,
|
||||
zOrder: 1,
|
||||
numberProperties: [],
|
||||
stringProperties: [],
|
||||
initialVariables: [],
|
||||
behaviorOverridings: [
|
||||
// Magnet on the right
|
||||
{
|
||||
name: 'AnchorBehavior',
|
||||
type: 'AnchorBehavior::AnchorBehavior',
|
||||
leftEdgeAnchor: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
const runtimeScene = new gdjs.TestRuntimeScene(runtimeGame);
|
||||
// The corresponding event-based object declaration is done by
|
||||
// getPixiRuntimeGame.
|
||||
const customObject = new gdjs.CustomRuntimeObject2D(runtimeScene, {
|
||||
name: 'MyCustomObject',
|
||||
type: 'MyExtension::MyLayoutedEventsBasedObject',
|
||||
variant: '',
|
||||
variables: [],
|
||||
behaviors: [],
|
||||
effects: [],
|
||||
content: {},
|
||||
childrenContent: {},
|
||||
isInnerAreaFollowingParentSize: false,
|
||||
});
|
||||
runtimeScene.addObject(customObject);
|
||||
customObject.setPosition(500, 250);
|
||||
|
||||
const childObjects = customObject
|
||||
.getChildrenContainer()
|
||||
.getObjects('MySprite');
|
||||
if (!childObjects || childObjects.length === 0) {
|
||||
throw new Error("Can't get child objects.");
|
||||
}
|
||||
const leftChildObject = childObjects[0];
|
||||
const rightChildObject = childObjects[1];
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
// The child object keeps its initial location.
|
||||
expect(leftChildObject.getX()).to.equal(0);
|
||||
expect(leftChildObject.getY()).to.equal(0);
|
||||
expect(leftChildObject.getWidth()).to.equal(32);
|
||||
expect(leftChildObject.getHeight()).to.equal(64);
|
||||
|
||||
expect(rightChildObject.getX()).to.equal(32);
|
||||
expect(rightChildObject.getY()).to.equal(0);
|
||||
expect(rightChildObject.getWidth()).to.equal(32);
|
||||
expect(rightChildObject.getHeight()).to.equal(64);
|
||||
|
||||
customObject.setWidth(200);
|
||||
customObject.setHeight(300);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(leftChildObject.getX()).to.equal(0);
|
||||
expect(leftChildObject.getY()).to.equal(0);
|
||||
expect(leftChildObject.getWidth()).to.equal(32);
|
||||
expect(leftChildObject.getHeight()).to.equal(300);
|
||||
|
||||
expect(rightChildObject.getX()).to.equal(32 + 200 - 64);
|
||||
expect(rightChildObject.getY()).to.equal(0);
|
||||
expect(rightChildObject.getWidth()).to.equal(32);
|
||||
expect(rightChildObject.getHeight()).to.equal(300);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -87,9 +87,10 @@ namespace gdjs {
|
||||
*/
|
||||
constructor(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
objectData: BBTextObjectData
|
||||
objectData: BBTextObjectData,
|
||||
instanceData?: InstanceData
|
||||
) {
|
||||
super(instanceContainer, objectData);
|
||||
super(instanceContainer, objectData, instanceData);
|
||||
// @ts-ignore - parseFloat should not be required, but GDevelop 5.0 beta 92 and below were storing it as a string.
|
||||
this._opacity = parseFloat(objectData.content.opacity);
|
||||
this._text = objectData.content.text;
|
||||
|
||||
@@ -88,9 +88,10 @@ namespace gdjs {
|
||||
*/
|
||||
constructor(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
objectData: BitmapTextObjectData
|
||||
objectData: BitmapTextObjectData,
|
||||
instanceData?: InstanceData
|
||||
) {
|
||||
super(instanceContainer, objectData);
|
||||
super(instanceContainer, objectData, instanceData);
|
||||
|
||||
this._opacity = objectData.content.opacity;
|
||||
this._text = objectData.content.text;
|
||||
|
||||
@@ -24,15 +24,12 @@ namespace gdjs {
|
||||
this._hasBeenOnScreen = false;
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
if (oldBehaviorData.extraBorder !== newBehaviorData.extraBorder) {
|
||||
this._extraBorder = newBehaviorData.extraBorder;
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
if (behaviorData.extraBorder !== undefined) {
|
||||
this._extraBorder = behaviorData.extraBorder;
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.unseenGraceDistance !==
|
||||
newBehaviorData.unseenGraceDistance
|
||||
) {
|
||||
this._unseenGraceDistance = newBehaviorData.unseenGraceDistance;
|
||||
if (behaviorData.unseenGraceDistance !== undefined) {
|
||||
this._unseenGraceDistance = behaviorData.unseenGraceDistance;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace gdjs {
|
||||
this._checkCollisionMask = behaviorData.checkCollisionMask ? true : false;
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
// Nothing to update.
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -26,9 +26,9 @@ namespace gdjs {
|
||||
logger.log('DummyRuntimeBehavior was created for object:', owner);
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
if (oldBehaviorData.property1 !== newBehaviorData.property1) {
|
||||
this._textToSet = newBehaviorData.property1;
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
if (behaviorData.property1 !== undefined) {
|
||||
this._textToSet = behaviorData.property1;
|
||||
}
|
||||
|
||||
// Return true to specify that the new behavior data have been applied
|
||||
|
||||
@@ -15,9 +15,13 @@ namespace gdjs {
|
||||
// @ts-expect-error ts-migrate(2564) FIXME: Property 'opacity' has no initializer and is not d... Remove this comment to see the full error message
|
||||
opacity: float;
|
||||
|
||||
constructor(instanceContainer: gdjs.RuntimeInstanceContainer, objectData) {
|
||||
constructor(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
objectData,
|
||||
instanceData?: InstanceData
|
||||
) {
|
||||
// *ALWAYS* call the base gdjs.RuntimeObject constructor.
|
||||
super(instanceContainer, objectData);
|
||||
super(instanceContainer, objectData, instanceData);
|
||||
this._property1 = objectData.content.property1;
|
||||
this._renderer = new gdjs.DummyRuntimeObjectRenderer(
|
||||
this,
|
||||
|
||||
@@ -32,9 +32,9 @@ namespace gdjs {
|
||||
logger.log('The shared data are:', sharedData);
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
if (oldBehaviorData.property1 !== newBehaviorData.property1) {
|
||||
this._textToSet = newBehaviorData.property1;
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
if (behaviorData.property1 !== undefined) {
|
||||
this._textToSet = behaviorData.property1;
|
||||
}
|
||||
|
||||
// Return true to specify that the new behavior data have been applied
|
||||
|
||||
@@ -52,9 +52,10 @@ namespace gdjs {
|
||||
|
||||
constructor(
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
lightObjectData: LightObjectData
|
||||
lightObjectData: LightObjectData,
|
||||
instanceData?: InstanceData
|
||||
) {
|
||||
super(runtimeScene, lightObjectData);
|
||||
super(runtimeScene, lightObjectData, instanceData);
|
||||
this._radius =
|
||||
lightObjectData.content.radius > 0 ? lightObjectData.content.radius : 1;
|
||||
this._color = gdjs.rgbOrHexToRGBColor(lightObjectData.content.color);
|
||||
|
||||
@@ -54,76 +54,112 @@ describe('gdjs.LinksManager', function () {
|
||||
|
||||
const manager = gdjs.LinksManager.getManager(runtimeScene);
|
||||
|
||||
const object1A = new gdjs.RuntimeObject(runtimeScene, {
|
||||
name: object1Names[0],
|
||||
type: '',
|
||||
behaviors: [],
|
||||
variables: [],
|
||||
effects: [],
|
||||
});
|
||||
const object1B = new gdjs.RuntimeObject(runtimeScene, {
|
||||
name: object1Names[1],
|
||||
type: '',
|
||||
behaviors: [],
|
||||
variables: [],
|
||||
effects: [],
|
||||
});
|
||||
const object1A = new gdjs.RuntimeObject(
|
||||
runtimeScene,
|
||||
{
|
||||
name: object1Names[0],
|
||||
type: '',
|
||||
behaviors: [],
|
||||
variables: [],
|
||||
effects: [],
|
||||
},
|
||||
undefined
|
||||
);
|
||||
const object1B = new gdjs.RuntimeObject(
|
||||
runtimeScene,
|
||||
{
|
||||
name: object1Names[1],
|
||||
type: '',
|
||||
behaviors: [],
|
||||
variables: [],
|
||||
effects: [],
|
||||
},
|
||||
undefined
|
||||
);
|
||||
|
||||
const object1C = new gdjs.RuntimeObject(runtimeScene, {
|
||||
name: object1Names[2],
|
||||
type: '',
|
||||
behaviors: [],
|
||||
variables: [],
|
||||
effects: [],
|
||||
});
|
||||
const object1C = new gdjs.RuntimeObject(
|
||||
runtimeScene,
|
||||
{
|
||||
name: object1Names[2],
|
||||
type: '',
|
||||
behaviors: [],
|
||||
variables: [],
|
||||
effects: [],
|
||||
},
|
||||
undefined
|
||||
);
|
||||
|
||||
const object2A = new gdjs.RuntimeObject(runtimeScene, {
|
||||
name: object2Names[0],
|
||||
type: '',
|
||||
behaviors: [],
|
||||
variables: [],
|
||||
effects: [],
|
||||
});
|
||||
const object2A = new gdjs.RuntimeObject(
|
||||
runtimeScene,
|
||||
{
|
||||
name: object2Names[0],
|
||||
type: '',
|
||||
behaviors: [],
|
||||
variables: [],
|
||||
effects: [],
|
||||
},
|
||||
undefined
|
||||
);
|
||||
|
||||
const object2B = new gdjs.RuntimeObject(runtimeScene, {
|
||||
name: object2Names[1],
|
||||
type: '',
|
||||
behaviors: [],
|
||||
variables: [],
|
||||
effects: [],
|
||||
});
|
||||
const object2B = new gdjs.RuntimeObject(
|
||||
runtimeScene,
|
||||
{
|
||||
name: object2Names[1],
|
||||
type: '',
|
||||
behaviors: [],
|
||||
variables: [],
|
||||
effects: [],
|
||||
},
|
||||
undefined
|
||||
);
|
||||
|
||||
const object2C = new gdjs.RuntimeObject(runtimeScene, {
|
||||
name: object2Names[2],
|
||||
type: '',
|
||||
behaviors: [],
|
||||
variables: [],
|
||||
effects: [],
|
||||
});
|
||||
const object2C = new gdjs.RuntimeObject(
|
||||
runtimeScene,
|
||||
{
|
||||
name: object2Names[2],
|
||||
type: '',
|
||||
behaviors: [],
|
||||
variables: [],
|
||||
effects: [],
|
||||
},
|
||||
undefined
|
||||
);
|
||||
|
||||
const object3A = new gdjs.RuntimeObject(runtimeScene, {
|
||||
name: object3Names[0],
|
||||
type: '',
|
||||
behaviors: [],
|
||||
variables: [],
|
||||
effects: [],
|
||||
});
|
||||
const object3A = new gdjs.RuntimeObject(
|
||||
runtimeScene,
|
||||
{
|
||||
name: object3Names[0],
|
||||
type: '',
|
||||
behaviors: [],
|
||||
variables: [],
|
||||
effects: [],
|
||||
},
|
||||
undefined
|
||||
);
|
||||
|
||||
const object3B = new gdjs.RuntimeObject(runtimeScene, {
|
||||
name: object3Names[1],
|
||||
type: '',
|
||||
behaviors: [],
|
||||
variables: [],
|
||||
effects: [],
|
||||
});
|
||||
const object3B = new gdjs.RuntimeObject(
|
||||
runtimeScene,
|
||||
{
|
||||
name: object3Names[1],
|
||||
type: '',
|
||||
behaviors: [],
|
||||
variables: [],
|
||||
effects: [],
|
||||
},
|
||||
undefined
|
||||
);
|
||||
|
||||
const object3C = new gdjs.RuntimeObject(runtimeScene, {
|
||||
name: object3Names[2],
|
||||
type: '',
|
||||
behaviors: [],
|
||||
variables: [],
|
||||
effects: [],
|
||||
});
|
||||
const object3C = new gdjs.RuntimeObject(
|
||||
runtimeScene,
|
||||
{
|
||||
name: object3Names[2],
|
||||
type: '',
|
||||
behaviors: [],
|
||||
variables: [],
|
||||
effects: [],
|
||||
},
|
||||
undefined
|
||||
);
|
||||
|
||||
runtimeScene.addObject(object1A);
|
||||
runtimeScene.addObject(object1B);
|
||||
|
||||
@@ -74,9 +74,10 @@ namespace gdjs {
|
||||
*/
|
||||
constructor(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
panelSpriteObjectData: PanelSpriteObjectData
|
||||
panelSpriteObjectData: PanelSpriteObjectData,
|
||||
instanceData?: InstanceData
|
||||
) {
|
||||
super(instanceContainer, panelSpriteObjectData);
|
||||
super(instanceContainer, panelSpriteObjectData, instanceData);
|
||||
this._objectData = panelSpriteObjectData;
|
||||
this._rBorder = panelSpriteObjectData.rightMargin;
|
||||
this._lBorder = panelSpriteObjectData.leftMargin;
|
||||
|
||||
@@ -180,9 +180,10 @@ namespace gdjs {
|
||||
*/
|
||||
constructor(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
particleObjectData: ParticleEmitterObjectData
|
||||
particleObjectData: ParticleEmitterObjectData,
|
||||
instanceData?: InstanceData
|
||||
) {
|
||||
super(instanceContainer, particleObjectData);
|
||||
super(instanceContainer, particleObjectData, instanceData);
|
||||
this._renderer = new gdjs.ParticleEmitterObjectRenderer(
|
||||
instanceContainer,
|
||||
this,
|
||||
|
||||
@@ -126,12 +126,12 @@ namespace gdjs {
|
||||
//The owner is not yet fully constructed.
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
if (oldBehaviorData.impassable !== newBehaviorData.impassable) {
|
||||
this.setImpassable(newBehaviorData.impassable);
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
if (behaviorData.impassable !== undefined) {
|
||||
this.setImpassable(behaviorData.impassable);
|
||||
}
|
||||
if (oldBehaviorData.cost !== newBehaviorData.cost) {
|
||||
this.setCost(newBehaviorData.cost);
|
||||
if (behaviorData.cost !== undefined) {
|
||||
this.setCost(behaviorData.cost);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -93,45 +93,42 @@ namespace gdjs {
|
||||
);
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
if (oldBehaviorData.allowDiagonals !== newBehaviorData.allowDiagonals) {
|
||||
this.allowDiagonals(newBehaviorData.allowDiagonals);
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
if (behaviorData.allowDiagonals !== undefined) {
|
||||
this.allowDiagonals(behaviorData.allowDiagonals);
|
||||
}
|
||||
if (oldBehaviorData.acceleration !== newBehaviorData.acceleration) {
|
||||
this.setAcceleration(newBehaviorData.acceleration);
|
||||
if (behaviorData.acceleration !== undefined) {
|
||||
this.setAcceleration(behaviorData.acceleration);
|
||||
}
|
||||
if (oldBehaviorData.maxSpeed !== newBehaviorData.maxSpeed) {
|
||||
this.setMaxSpeed(newBehaviorData.maxSpeed);
|
||||
if (behaviorData.maxSpeed !== undefined) {
|
||||
this.setMaxSpeed(behaviorData.maxSpeed);
|
||||
}
|
||||
if (oldBehaviorData.angularMaxSpeed !== newBehaviorData.angularMaxSpeed) {
|
||||
this.setAngularMaxSpeed(newBehaviorData.angularMaxSpeed);
|
||||
if (behaviorData.angularMaxSpeed !== undefined) {
|
||||
this.setAngularMaxSpeed(behaviorData.angularMaxSpeed);
|
||||
}
|
||||
if (oldBehaviorData.rotateObject !== newBehaviorData.rotateObject) {
|
||||
this.setRotateObject(newBehaviorData.rotateObject);
|
||||
if (behaviorData.rotateObject !== undefined) {
|
||||
this.setRotateObject(behaviorData.rotateObject);
|
||||
}
|
||||
if (oldBehaviorData.angleOffset !== newBehaviorData.angleOffset) {
|
||||
this.setAngleOffset(newBehaviorData.angleOffset);
|
||||
if (behaviorData.angleOffset !== undefined) {
|
||||
this.setAngleOffset(behaviorData.angleOffset);
|
||||
}
|
||||
if (oldBehaviorData.cellWidth !== newBehaviorData.cellWidth) {
|
||||
this.setCellWidth(newBehaviorData.cellWidth);
|
||||
if (behaviorData.cellWidth !== undefined) {
|
||||
this.setCellWidth(behaviorData.cellWidth);
|
||||
}
|
||||
if (oldBehaviorData.cellHeight !== newBehaviorData.cellHeight) {
|
||||
this.setCellHeight(newBehaviorData.cellHeight);
|
||||
if (behaviorData.cellHeight !== undefined) {
|
||||
this.setCellHeight(behaviorData.cellHeight);
|
||||
}
|
||||
if (oldBehaviorData.gridOffsetX !== newBehaviorData.gridOffsetX) {
|
||||
this._gridOffsetX = newBehaviorData.gridOffsetX;
|
||||
if (behaviorData.gridOffsetX !== undefined) {
|
||||
this._gridOffsetX = behaviorData.gridOffsetX;
|
||||
}
|
||||
if (oldBehaviorData.gridOffsetY !== newBehaviorData.gridOffsetY) {
|
||||
this._gridOffsetY = newBehaviorData.gridOffsetY;
|
||||
if (behaviorData.gridOffsetY !== undefined) {
|
||||
this._gridOffsetY = behaviorData.gridOffsetY;
|
||||
}
|
||||
if (oldBehaviorData.extraBorder !== newBehaviorData.extraBorder) {
|
||||
this.setExtraBorder(newBehaviorData.extraBorder);
|
||||
if (behaviorData.extraBorder !== undefined) {
|
||||
this.setExtraBorder(behaviorData.extraBorder);
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.smoothingMaxCellGap !==
|
||||
newBehaviorData.smoothingMaxCellGap
|
||||
) {
|
||||
this._smoothingMaxCellGap = newBehaviorData.smoothingMaxCellGap;
|
||||
if (behaviorData.smoothingMaxCellGap !== undefined) {
|
||||
this._smoothingMaxCellGap = behaviorData.smoothingMaxCellGap;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -62,29 +62,33 @@ describe('gdjs.PathfindingRuntimeBehavior', function () {
|
||||
};
|
||||
|
||||
const addPlayer = (runtimeScene, allowDiagonals) => {
|
||||
const player = new gdjs.RuntimeObject(runtimeScene, {
|
||||
name: 'player',
|
||||
type: '',
|
||||
behaviors: [
|
||||
{
|
||||
type: 'PathfindingBehavior::PathfindingBehavior',
|
||||
name: 'auto1',
|
||||
// @ts-ignore - properties are not typed
|
||||
allowDiagonals: allowDiagonals,
|
||||
acceleration: 400,
|
||||
maxSpeed: 200,
|
||||
angularMaxSpeed: 180,
|
||||
rotateObject: false,
|
||||
angleOffset: 0,
|
||||
cellWidth: 20,
|
||||
cellHeight: 20,
|
||||
extraBorder: 0,
|
||||
collisionMethod: true,
|
||||
},
|
||||
],
|
||||
effects: [],
|
||||
variables: [],
|
||||
});
|
||||
const player = new gdjs.RuntimeObject(
|
||||
runtimeScene,
|
||||
{
|
||||
name: 'player',
|
||||
type: '',
|
||||
behaviors: [
|
||||
{
|
||||
type: 'PathfindingBehavior::PathfindingBehavior',
|
||||
name: 'auto1',
|
||||
// @ts-ignore - properties are not typed
|
||||
allowDiagonals: allowDiagonals,
|
||||
acceleration: 400,
|
||||
maxSpeed: 200,
|
||||
angularMaxSpeed: 180,
|
||||
rotateObject: false,
|
||||
angleOffset: 0,
|
||||
cellWidth: 20,
|
||||
cellHeight: 20,
|
||||
extraBorder: 0,
|
||||
collisionMethod: true,
|
||||
},
|
||||
],
|
||||
effects: [],
|
||||
variables: [],
|
||||
},
|
||||
undefined
|
||||
);
|
||||
player.getWidth = function () {
|
||||
return 90;
|
||||
};
|
||||
@@ -96,20 +100,24 @@ describe('gdjs.PathfindingRuntimeBehavior', function () {
|
||||
};
|
||||
|
||||
const addObstacle = (runtimeScene) => {
|
||||
const obstacle = new gdjs.RuntimeObject(runtimeScene, {
|
||||
name: 'obstacle',
|
||||
type: '',
|
||||
behaviors: [
|
||||
{
|
||||
type: 'PathfindingBehavior::PathfindingObstacleBehavior',
|
||||
// @ts-ignore - properties are not typed
|
||||
impassable: true,
|
||||
cost: 2,
|
||||
},
|
||||
],
|
||||
effects: [],
|
||||
variables: [],
|
||||
});
|
||||
const obstacle = new gdjs.RuntimeObject(
|
||||
runtimeScene,
|
||||
{
|
||||
name: 'obstacle',
|
||||
type: '',
|
||||
behaviors: [
|
||||
{
|
||||
type: 'PathfindingBehavior::PathfindingObstacleBehavior',
|
||||
// @ts-ignore - properties are not typed
|
||||
impassable: true,
|
||||
cost: 2,
|
||||
},
|
||||
],
|
||||
effects: [],
|
||||
variables: [],
|
||||
},
|
||||
undefined
|
||||
);
|
||||
obstacle.getWidth = function () {
|
||||
return 100;
|
||||
};
|
||||
|
||||
@@ -65,30 +65,34 @@ describe('gdjs.PathfindingRuntimeBehavior', function () {
|
||||
};
|
||||
|
||||
const addPlayer = (runtimeScene) => {
|
||||
const player = new gdjs.RuntimeObject(runtimeScene, {
|
||||
name: 'player',
|
||||
type: '',
|
||||
behaviors: [
|
||||
{
|
||||
type: 'PathfindingBehavior::PathfindingBehavior',
|
||||
name: 'auto1',
|
||||
// @ts-ignore - properties are not typed
|
||||
allowDiagonals: allowDiagonals,
|
||||
acceleration: 400,
|
||||
maxSpeed: 200,
|
||||
angularMaxSpeed: 180,
|
||||
rotateObject: false,
|
||||
angleOffset: 0,
|
||||
cellWidth: 20,
|
||||
cellHeight: 20,
|
||||
extraBorder: 0,
|
||||
smoothingMaxCellGap: smoothingMaxCellGap,
|
||||
collisionMethod: collisionMethod,
|
||||
},
|
||||
],
|
||||
effects: [],
|
||||
variables: [],
|
||||
});
|
||||
const player = new gdjs.RuntimeObject(
|
||||
runtimeScene,
|
||||
{
|
||||
name: 'player',
|
||||
type: '',
|
||||
behaviors: [
|
||||
{
|
||||
type: 'PathfindingBehavior::PathfindingBehavior',
|
||||
name: 'auto1',
|
||||
// @ts-ignore - properties are not typed
|
||||
allowDiagonals: allowDiagonals,
|
||||
acceleration: 400,
|
||||
maxSpeed: 200,
|
||||
angularMaxSpeed: 180,
|
||||
rotateObject: false,
|
||||
angleOffset: 0,
|
||||
cellWidth: 20,
|
||||
cellHeight: 20,
|
||||
extraBorder: 0,
|
||||
smoothingMaxCellGap: smoothingMaxCellGap,
|
||||
collisionMethod: collisionMethod,
|
||||
},
|
||||
],
|
||||
effects: [],
|
||||
variables: [],
|
||||
},
|
||||
undefined
|
||||
);
|
||||
player.getWidth = function () {
|
||||
return 90;
|
||||
};
|
||||
@@ -100,20 +104,24 @@ describe('gdjs.PathfindingRuntimeBehavior', function () {
|
||||
};
|
||||
|
||||
const addObstacle = (runtimeScene) => {
|
||||
const obstacle = new gdjs.RuntimeObject(runtimeScene, {
|
||||
name: 'obstacle',
|
||||
type: '',
|
||||
behaviors: [
|
||||
{
|
||||
type: 'PathfindingBehavior::PathfindingObstacleBehavior',
|
||||
// @ts-ignore - properties are not typed
|
||||
impassable: true,
|
||||
cost: 2,
|
||||
},
|
||||
],
|
||||
effects: [],
|
||||
variables: [],
|
||||
});
|
||||
const obstacle = new gdjs.RuntimeObject(
|
||||
runtimeScene,
|
||||
{
|
||||
name: 'obstacle',
|
||||
type: '',
|
||||
behaviors: [
|
||||
{
|
||||
type: 'PathfindingBehavior::PathfindingObstacleBehavior',
|
||||
// @ts-ignore - properties are not typed
|
||||
impassable: true,
|
||||
cost: 2,
|
||||
},
|
||||
],
|
||||
effects: [],
|
||||
variables: [],
|
||||
},
|
||||
undefined
|
||||
);
|
||||
obstacle.getWidth = function () {
|
||||
return 100;
|
||||
};
|
||||
|
||||
@@ -443,69 +443,69 @@ namespace gdjs {
|
||||
return tempb2Vec2Sec;
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
if (oldBehaviorData.bullet !== newBehaviorData.bullet) {
|
||||
this.setBullet(newBehaviorData.bullet);
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
if (behaviorData.bullet !== undefined) {
|
||||
this.setBullet(behaviorData.bullet);
|
||||
}
|
||||
if (oldBehaviorData.fixedRotation !== newBehaviorData.fixedRotation) {
|
||||
this.setFixedRotation(newBehaviorData.fixedRotation);
|
||||
if (behaviorData.fixedRotation !== undefined) {
|
||||
this.setFixedRotation(behaviorData.fixedRotation);
|
||||
}
|
||||
if (oldBehaviorData.canSleep !== newBehaviorData.canSleep) {
|
||||
this.setSleepingAllowed(newBehaviorData.canSleep);
|
||||
if (behaviorData.canSleep !== undefined) {
|
||||
this.setSleepingAllowed(behaviorData.canSleep);
|
||||
}
|
||||
if (oldBehaviorData.shapeDimensionA !== newBehaviorData.shapeDimensionA) {
|
||||
this.shapeDimensionA = newBehaviorData.shapeDimensionA;
|
||||
if (behaviorData.shapeDimensionA !== undefined) {
|
||||
this.shapeDimensionA = behaviorData.shapeDimensionA;
|
||||
this.recreateShape();
|
||||
}
|
||||
if (oldBehaviorData.shapeDimensionB !== newBehaviorData.shapeDimensionB) {
|
||||
this.shapeDimensionB = newBehaviorData.shapeDimensionB;
|
||||
if (behaviorData.shapeDimensionB !== undefined) {
|
||||
this.shapeDimensionB = behaviorData.shapeDimensionB;
|
||||
this.recreateShape();
|
||||
}
|
||||
if (oldBehaviorData.shapeOffsetX !== newBehaviorData.shapeOffsetX) {
|
||||
this.shapeOffsetX = newBehaviorData.shapeOffsetX;
|
||||
if (behaviorData.shapeOffsetX !== undefined) {
|
||||
this.shapeOffsetX = behaviorData.shapeOffsetX;
|
||||
this.recreateShape();
|
||||
}
|
||||
if (oldBehaviorData.shapeOffsetY !== newBehaviorData.shapeOffsetY) {
|
||||
this.shapeOffsetY = newBehaviorData.shapeOffsetY;
|
||||
if (behaviorData.shapeOffsetY !== undefined) {
|
||||
this.shapeOffsetY = behaviorData.shapeOffsetY;
|
||||
this.recreateShape();
|
||||
}
|
||||
if (oldBehaviorData.polygonOrigin !== newBehaviorData.polygonOrigin) {
|
||||
this.polygonOrigin = newBehaviorData.polygonOrigin;
|
||||
if (behaviorData.polygonOrigin !== undefined) {
|
||||
this.polygonOrigin = behaviorData.polygonOrigin;
|
||||
this.recreateShape();
|
||||
}
|
||||
if (oldBehaviorData.density !== newBehaviorData.density) {
|
||||
this.setDensity(newBehaviorData.density);
|
||||
if (behaviorData.density !== undefined) {
|
||||
this.setDensity(behaviorData.density);
|
||||
}
|
||||
if (oldBehaviorData.friction !== newBehaviorData.friction) {
|
||||
this.setFriction(newBehaviorData.friction);
|
||||
if (behaviorData.friction !== undefined) {
|
||||
this.setFriction(behaviorData.friction);
|
||||
}
|
||||
if (oldBehaviorData.restitution !== newBehaviorData.restitution) {
|
||||
this.setRestitution(newBehaviorData.restitution);
|
||||
if (behaviorData.restitution !== undefined) {
|
||||
this.setRestitution(behaviorData.restitution);
|
||||
}
|
||||
if (oldBehaviorData.linearDamping !== newBehaviorData.linearDamping) {
|
||||
this.setLinearDamping(newBehaviorData.linearDamping);
|
||||
if (behaviorData.linearDamping !== undefined) {
|
||||
this.setLinearDamping(behaviorData.linearDamping);
|
||||
}
|
||||
if (oldBehaviorData.angularDamping !== newBehaviorData.angularDamping) {
|
||||
this.setAngularDamping(newBehaviorData.angularDamping);
|
||||
if (behaviorData.angularDamping !== undefined) {
|
||||
this.setAngularDamping(behaviorData.angularDamping);
|
||||
}
|
||||
if (oldBehaviorData.gravityScale !== newBehaviorData.gravityScale) {
|
||||
this.setGravityScale(newBehaviorData.gravityScale);
|
||||
if (behaviorData.gravityScale !== undefined) {
|
||||
this.setGravityScale(behaviorData.gravityScale);
|
||||
}
|
||||
|
||||
// TODO: make these properties updatable.
|
||||
if (oldBehaviorData.layers !== newBehaviorData.layers) {
|
||||
if (behaviorData.layers !== undefined) {
|
||||
return false;
|
||||
}
|
||||
if (oldBehaviorData.masks !== newBehaviorData.masks) {
|
||||
if (behaviorData.masks !== undefined) {
|
||||
return false;
|
||||
}
|
||||
if (oldBehaviorData.vertices !== newBehaviorData.vertices) {
|
||||
if (behaviorData.vertices !== undefined) {
|
||||
return false;
|
||||
}
|
||||
if (oldBehaviorData.bodyType !== newBehaviorData.bodyType) {
|
||||
if (behaviorData.bodyType !== undefined) {
|
||||
return false;
|
||||
}
|
||||
if (oldBehaviorData.shape !== newBehaviorData.shape) {
|
||||
if (behaviorData.shape !== undefined) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -459,54 +459,54 @@ namespace gdjs {
|
||||
return tempQuat;
|
||||
}
|
||||
|
||||
override updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
if (oldBehaviorData.bullet !== newBehaviorData.bullet) {
|
||||
this.setBullet(newBehaviorData.bullet);
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
if (behaviorData.bullet !== undefined) {
|
||||
this.setBullet(behaviorData.bullet);
|
||||
}
|
||||
if (oldBehaviorData.fixedRotation !== newBehaviorData.fixedRotation) {
|
||||
this.setFixedRotation(newBehaviorData.fixedRotation);
|
||||
if (behaviorData.fixedRotation !== undefined) {
|
||||
this.setFixedRotation(behaviorData.fixedRotation);
|
||||
}
|
||||
if (oldBehaviorData.shapeDimensionA !== newBehaviorData.shapeDimensionA) {
|
||||
this.shapeDimensionA = newBehaviorData.shapeDimensionA;
|
||||
if (behaviorData.shapeDimensionA !== undefined) {
|
||||
this.shapeDimensionA = behaviorData.shapeDimensionA;
|
||||
this._needToRecreateShape = true;
|
||||
}
|
||||
if (oldBehaviorData.shapeDimensionB !== newBehaviorData.shapeDimensionB) {
|
||||
this.shapeDimensionB = newBehaviorData.shapeDimensionB;
|
||||
if (behaviorData.shapeDimensionB !== undefined) {
|
||||
this.shapeDimensionB = behaviorData.shapeDimensionB;
|
||||
this._needToRecreateShape = true;
|
||||
}
|
||||
if (oldBehaviorData.density !== newBehaviorData.density) {
|
||||
this.setDensity(newBehaviorData.density);
|
||||
if (behaviorData.density !== undefined) {
|
||||
this.setDensity(behaviorData.density);
|
||||
}
|
||||
if (oldBehaviorData.friction !== newBehaviorData.friction) {
|
||||
this.setFriction(newBehaviorData.friction);
|
||||
if (behaviorData.friction !== undefined) {
|
||||
this.setFriction(behaviorData.friction);
|
||||
}
|
||||
if (oldBehaviorData.restitution !== newBehaviorData.restitution) {
|
||||
this.setRestitution(newBehaviorData.restitution);
|
||||
if (behaviorData.restitution !== undefined) {
|
||||
this.setRestitution(behaviorData.restitution);
|
||||
}
|
||||
if (oldBehaviorData.linearDamping !== newBehaviorData.linearDamping) {
|
||||
this.setLinearDamping(newBehaviorData.linearDamping);
|
||||
if (behaviorData.linearDamping !== undefined) {
|
||||
this.setLinearDamping(behaviorData.linearDamping);
|
||||
}
|
||||
if (oldBehaviorData.angularDamping !== newBehaviorData.angularDamping) {
|
||||
this.setAngularDamping(newBehaviorData.angularDamping);
|
||||
if (behaviorData.angularDamping !== undefined) {
|
||||
this.setAngularDamping(behaviorData.angularDamping);
|
||||
}
|
||||
if (oldBehaviorData.gravityScale !== newBehaviorData.gravityScale) {
|
||||
this.setGravityScale(newBehaviorData.gravityScale);
|
||||
if (behaviorData.gravityScale !== undefined) {
|
||||
this.setGravityScale(behaviorData.gravityScale);
|
||||
}
|
||||
|
||||
// TODO: make these properties updatable.
|
||||
if (oldBehaviorData.layers !== newBehaviorData.layers) {
|
||||
if (behaviorData.layers !== undefined) {
|
||||
return false;
|
||||
}
|
||||
if (oldBehaviorData.masks !== newBehaviorData.masks) {
|
||||
if (behaviorData.masks !== undefined) {
|
||||
return false;
|
||||
}
|
||||
if (oldBehaviorData.vertices !== newBehaviorData.vertices) {
|
||||
if (behaviorData.vertices !== undefined) {
|
||||
return false;
|
||||
}
|
||||
if (oldBehaviorData.bodyType !== newBehaviorData.bodyType) {
|
||||
if (behaviorData.bodyType !== undefined) {
|
||||
return false;
|
||||
}
|
||||
if (oldBehaviorData.shape !== newBehaviorData.shape) {
|
||||
if (behaviorData.shape !== undefined) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -212,97 +212,78 @@ namespace gdjs {
|
||||
return this._physics3D;
|
||||
}
|
||||
|
||||
override updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
if (oldBehaviorData.steerAngleMax !== newBehaviorData.steerAngleMax) {
|
||||
this.setSteerAngleMax(newBehaviorData.steerAngleMax);
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
if (behaviorData.steerAngleMax !== undefined) {
|
||||
this.setSteerAngleMax(behaviorData.steerAngleMax);
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.beginningSteerSpeed !==
|
||||
newBehaviorData.beginningSteerSpeed
|
||||
) {
|
||||
this.setBeginningSteerSpeed(newBehaviorData.beginningSteerSpeed);
|
||||
if (behaviorData.beginningSteerSpeed !== undefined) {
|
||||
this.setBeginningSteerSpeed(behaviorData.beginningSteerSpeed);
|
||||
}
|
||||
if (oldBehaviorData.endSteerSpeed !== newBehaviorData.endSteerSpeed) {
|
||||
this.setEndSteerSpeed(newBehaviorData.endSteerSpeed);
|
||||
if (behaviorData.endSteerSpeed !== undefined) {
|
||||
this.setEndSteerSpeed(behaviorData.endSteerSpeed);
|
||||
}
|
||||
if (oldBehaviorData.engineTorqueMax !== newBehaviorData.engineTorqueMax) {
|
||||
this.setEngineTorqueMax(newBehaviorData.engineTorqueMax);
|
||||
if (behaviorData.engineTorqueMax !== undefined) {
|
||||
this.setEngineTorqueMax(behaviorData.engineTorqueMax);
|
||||
}
|
||||
if (oldBehaviorData.engineSpeedMax !== newBehaviorData.engineSpeedMax) {
|
||||
this.setEngineSpeedMax(newBehaviorData.engineSpeedMax);
|
||||
if (behaviorData.engineSpeedMax !== undefined) {
|
||||
this.setEngineSpeedMax(behaviorData.engineSpeedMax);
|
||||
}
|
||||
if (oldBehaviorData.engineInertia !== newBehaviorData.engineInertia) {
|
||||
this.setEngineInertia(newBehaviorData.engineInertia);
|
||||
if (behaviorData.engineInertia !== undefined) {
|
||||
this.setEngineInertia(behaviorData.engineInertia);
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.reverseGearRatio1 !== newBehaviorData.reverseGearRatio1
|
||||
) {
|
||||
this.setGearRatio(-1, newBehaviorData.reverseGearRatio1);
|
||||
if (behaviorData.reverseGearRatio1 !== undefined) {
|
||||
this.setGearRatio(-1, behaviorData.reverseGearRatio1);
|
||||
}
|
||||
if (oldBehaviorData.gearRatio1 !== newBehaviorData.gearRatio1) {
|
||||
this.setGearRatio(1, newBehaviorData.gearRatio1);
|
||||
if (behaviorData.gearRatio1 !== undefined) {
|
||||
this.setGearRatio(1, behaviorData.gearRatio1);
|
||||
}
|
||||
if (oldBehaviorData.gearRatio2 !== newBehaviorData.gearRatio2) {
|
||||
this.setGearRatio(2, newBehaviorData.gearRatio2);
|
||||
if (behaviorData.gearRatio2 !== undefined) {
|
||||
this.setGearRatio(2, behaviorData.gearRatio2);
|
||||
}
|
||||
if (oldBehaviorData.gearRatio3 !== newBehaviorData.gearRatio3) {
|
||||
this.setGearRatio(3, newBehaviorData.gearRatio3);
|
||||
if (behaviorData.gearRatio3 !== undefined) {
|
||||
this.setGearRatio(3, behaviorData.gearRatio3);
|
||||
}
|
||||
if (oldBehaviorData.gearRatio4 !== newBehaviorData.gearRatio4) {
|
||||
this.setGearRatio(4, newBehaviorData.gearRatio4);
|
||||
if (behaviorData.gearRatio4 !== undefined) {
|
||||
this.setGearRatio(4, behaviorData.gearRatio4);
|
||||
}
|
||||
if (oldBehaviorData.gearRatio5 !== newBehaviorData.gearRatio5) {
|
||||
this.setGearRatio(5, newBehaviorData.gearRatio5);
|
||||
if (behaviorData.gearRatio5 !== undefined) {
|
||||
this.setGearRatio(5, behaviorData.gearRatio5);
|
||||
}
|
||||
if (oldBehaviorData.gearRatio6 !== newBehaviorData.gearRatio6) {
|
||||
this.setGearRatio(6, newBehaviorData.gearRatio6);
|
||||
if (behaviorData.gearRatio6 !== undefined) {
|
||||
this.setGearRatio(6, behaviorData.gearRatio6);
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.backWheelOffsetX !== newBehaviorData.backWheelOffsetX
|
||||
) {
|
||||
this.setBackWheelOffsetX(newBehaviorData.backWheelOffsetX);
|
||||
if (behaviorData.backWheelOffsetX !== undefined) {
|
||||
this.setBackWheelOffsetX(behaviorData.backWheelOffsetX);
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.frontWheelOffsetX !== newBehaviorData.frontWheelOffsetX
|
||||
) {
|
||||
this.setFrontWheelOffsetX(newBehaviorData.frontWheelOffsetX);
|
||||
if (behaviorData.frontWheelOffsetX !== undefined) {
|
||||
this.setFrontWheelOffsetX(behaviorData.frontWheelOffsetX);
|
||||
}
|
||||
if (oldBehaviorData.wheelOffsetY !== newBehaviorData.wheelOffsetY) {
|
||||
this.setWheelOffsetY(newBehaviorData.wheelOffsetY);
|
||||
if (behaviorData.wheelOffsetY !== undefined) {
|
||||
this.setWheelOffsetY(behaviorData.wheelOffsetY);
|
||||
}
|
||||
if (oldBehaviorData.wheelOffsetZ !== newBehaviorData.wheelOffsetZ) {
|
||||
this.setWheelOffsetZ(newBehaviorData.wheelOffsetZ);
|
||||
if (behaviorData.wheelOffsetZ !== undefined) {
|
||||
this.setWheelOffsetZ(behaviorData.wheelOffsetZ);
|
||||
}
|
||||
if (oldBehaviorData.wheelRadius !== newBehaviorData.wheelRadius) {
|
||||
this.setWheelRadius(newBehaviorData.wheelRadius);
|
||||
if (behaviorData.wheelRadius !== undefined) {
|
||||
this.setWheelRadius(behaviorData.wheelRadius);
|
||||
}
|
||||
if (oldBehaviorData.wheelWidth !== newBehaviorData.wheelWidth) {
|
||||
this.setWheelWidth(newBehaviorData.wheelWidth);
|
||||
if (behaviorData.wheelWidth !== undefined) {
|
||||
this.setWheelWidth(behaviorData.wheelWidth);
|
||||
}
|
||||
if (oldBehaviorData.brakeTorqueMax !== newBehaviorData.brakeTorqueMax) {
|
||||
this.setBrakeTorqueMax(newBehaviorData.brakeTorqueMax);
|
||||
if (behaviorData.brakeTorqueMax !== undefined) {
|
||||
this.setBrakeTorqueMax(behaviorData.brakeTorqueMax);
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.handBrakeTorqueMax !==
|
||||
newBehaviorData.handBrakeTorqueMax
|
||||
) {
|
||||
this.setHandBrakeTorqueMax(newBehaviorData.handBrakeTorqueMax);
|
||||
if (behaviorData.handBrakeTorqueMax !== undefined) {
|
||||
this.setHandBrakeTorqueMax(behaviorData.handBrakeTorqueMax);
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.hasBackWheelDrive !== newBehaviorData.hasBackWheelDrive
|
||||
) {
|
||||
this.setBackWheelDrive(newBehaviorData.hasBackWheelDrive);
|
||||
if (behaviorData.hasBackWheelDrive !== undefined) {
|
||||
this.setBackWheelDrive(behaviorData.hasBackWheelDrive);
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.hasFrontWheelDrive !==
|
||||
newBehaviorData.hasFrontWheelDrive
|
||||
) {
|
||||
this.setFrontWheelDrive(newBehaviorData.hasFrontWheelDrive);
|
||||
if (behaviorData.hasFrontWheelDrive !== undefined) {
|
||||
this.setFrontWheelDrive(behaviorData.hasFrontWheelDrive);
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.pitchRollAngleMax !== newBehaviorData.pitchRollAngleMax
|
||||
) {
|
||||
this.setPitchRollAngleMax(newBehaviorData.pitchRollAngleMax);
|
||||
if (behaviorData.pitchRollAngleMax !== undefined) {
|
||||
this.setPitchRollAngleMax(behaviorData.pitchRollAngleMax);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -263,61 +263,44 @@ namespace gdjs {
|
||||
return this._physics3D;
|
||||
}
|
||||
|
||||
override updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
if (oldBehaviorData.gravity !== newBehaviorData.gravity) {
|
||||
this.setGravity(newBehaviorData.gravity);
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
if (behaviorData.gravity !== undefined) {
|
||||
this.setGravity(behaviorData.gravity);
|
||||
}
|
||||
if (oldBehaviorData.maxFallingSpeed !== newBehaviorData.maxFallingSpeed) {
|
||||
this.setMaxFallingSpeed(newBehaviorData.maxFallingSpeed);
|
||||
if (behaviorData.maxFallingSpeed !== undefined) {
|
||||
this.setMaxFallingSpeed(behaviorData.maxFallingSpeed);
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.forwardAcceleration !==
|
||||
newBehaviorData.forwardAcceleration
|
||||
) {
|
||||
this.setForwardAcceleration(newBehaviorData.forwardAcceleration);
|
||||
if (behaviorData.forwardAcceleration !== undefined) {
|
||||
this.setForwardAcceleration(behaviorData.forwardAcceleration);
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.forwardDeceleration !==
|
||||
newBehaviorData.forwardDeceleration
|
||||
) {
|
||||
this.setForwardDeceleration(newBehaviorData.forwardDeceleration);
|
||||
if (behaviorData.forwardDeceleration !== undefined) {
|
||||
this.setForwardDeceleration(behaviorData.forwardDeceleration);
|
||||
}
|
||||
if (oldBehaviorData.forwardSpeedMax !== newBehaviorData.forwardSpeedMax) {
|
||||
this.setForwardSpeedMax(newBehaviorData.forwardSpeedMax);
|
||||
if (behaviorData.forwardSpeedMax !== undefined) {
|
||||
this.setForwardSpeedMax(behaviorData.forwardSpeedMax);
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.sidewaysAcceleration !==
|
||||
newBehaviorData.sidewaysAcceleration
|
||||
) {
|
||||
this.setSidewaysAcceleration(newBehaviorData.sidewaysAcceleration);
|
||||
if (behaviorData.sidewaysAcceleration !== undefined) {
|
||||
this.setSidewaysAcceleration(behaviorData.sidewaysAcceleration);
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.sidewaysDeceleration !==
|
||||
newBehaviorData.sidewaysDeceleration
|
||||
) {
|
||||
this.setSidewaysDeceleration(newBehaviorData.sidewaysDeceleration);
|
||||
if (behaviorData.sidewaysDeceleration !== undefined) {
|
||||
this.setSidewaysDeceleration(behaviorData.sidewaysDeceleration);
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.sidewaysSpeedMax !== newBehaviorData.sidewaysSpeedMax
|
||||
) {
|
||||
this.setSidewaysSpeedMax(newBehaviorData.sidewaysSpeedMax);
|
||||
if (behaviorData.sidewaysSpeedMax !== undefined) {
|
||||
this.setSidewaysSpeedMax(behaviorData.sidewaysSpeedMax);
|
||||
}
|
||||
if (oldBehaviorData.jumpSustainTime !== newBehaviorData.jumpSustainTime) {
|
||||
this.setJumpSustainTime(newBehaviorData.jumpSustainTime);
|
||||
if (behaviorData.jumpSustainTime !== undefined) {
|
||||
this.setJumpSustainTime(behaviorData.jumpSustainTime);
|
||||
}
|
||||
if (oldBehaviorData.jumpHeight !== newBehaviorData.jumpHeight) {
|
||||
this.setJumpSpeed(this.getJumpSpeedToReach(newBehaviorData.jumpHeight));
|
||||
if (behaviorData.jumpHeight !== undefined) {
|
||||
this.setJumpSpeed(this.getJumpSpeedToReach(behaviorData.jumpHeight));
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.shouldBindObjectAndForwardAngle !==
|
||||
newBehaviorData.shouldBindObjectAndForwardAngle
|
||||
) {
|
||||
if (behaviorData.shouldBindObjectAndForwardAngle !== undefined) {
|
||||
this.setShouldBindObjectAndForwardAngle(
|
||||
newBehaviorData.shouldBindObjectAndForwardAngle
|
||||
behaviorData.shouldBindObjectAndForwardAngle
|
||||
);
|
||||
}
|
||||
if (oldBehaviorData.stairHeightMax !== newBehaviorData.stairHeightMax) {
|
||||
this.setStairHeightMax(newBehaviorData.stairHeightMax);
|
||||
if (behaviorData.stairHeightMax !== undefined) {
|
||||
this.setStairHeightMax(behaviorData.stairHeightMax);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -181,29 +181,29 @@ namespace gdjs {
|
||||
}
|
||||
|
||||
//See b2Vec2 method
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
if (oldBehaviorData.dynamic !== newBehaviorData.dynamic) {
|
||||
if (newBehaviorData.dynamic) {
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
if (behaviorData.dynamic !== undefined) {
|
||||
if (behaviorData.dynamic) {
|
||||
this.setDynamic();
|
||||
} else {
|
||||
this.setStatic();
|
||||
}
|
||||
}
|
||||
if (oldBehaviorData.angularDamping !== newBehaviorData.angularDamping) {
|
||||
this.setAngularDamping(newBehaviorData.angularDamping);
|
||||
if (behaviorData.angularDamping !== undefined) {
|
||||
this.setAngularDamping(behaviorData.angularDamping);
|
||||
}
|
||||
if (oldBehaviorData.linearDamping !== newBehaviorData.linearDamping) {
|
||||
this.setLinearDamping(newBehaviorData.linearDamping);
|
||||
if (behaviorData.linearDamping !== undefined) {
|
||||
this.setLinearDamping(behaviorData.linearDamping);
|
||||
}
|
||||
if (oldBehaviorData.isBullet !== newBehaviorData.isBullet) {
|
||||
if (newBehaviorData.isBullet) {
|
||||
if (behaviorData.isBullet !== undefined) {
|
||||
if (behaviorData.isBullet) {
|
||||
this.setAsBullet();
|
||||
} else {
|
||||
this.dontSetAsBullet();
|
||||
}
|
||||
}
|
||||
if (oldBehaviorData.fixedRotation !== newBehaviorData.fixedRotation) {
|
||||
if (newBehaviorData.fixedRotation) {
|
||||
if (behaviorData.fixedRotation !== undefined) {
|
||||
if (behaviorData.fixedRotation) {
|
||||
this.setFixedRotation();
|
||||
} else {
|
||||
this.setFreeRotation();
|
||||
@@ -211,19 +211,16 @@ namespace gdjs {
|
||||
}
|
||||
|
||||
// TODO: make these properties updatable.
|
||||
if (oldBehaviorData.massDensity !== newBehaviorData.massDensity) {
|
||||
if (behaviorData.massDensity !== undefined) {
|
||||
return false;
|
||||
}
|
||||
if (oldBehaviorData.averageFriction !== newBehaviorData.averageFriction) {
|
||||
if (behaviorData.averageFriction !== undefined) {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.averageRestitution !==
|
||||
newBehaviorData.averageRestitution
|
||||
) {
|
||||
if (behaviorData.averageRestitution !== undefined) {
|
||||
return false;
|
||||
}
|
||||
if (oldBehaviorData.shapeType !== newBehaviorData.shapeType) {
|
||||
if (behaviorData.shapeType !== undefined) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -368,56 +368,45 @@ namespace gdjs {
|
||||
this._ignoreDefaultControlsAsSyncedByNetwork = !options.keepControl;
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
if (oldBehaviorData.gravity !== newBehaviorData.gravity) {
|
||||
this.setGravity(newBehaviorData.gravity);
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
if (behaviorData.gravity !== undefined) {
|
||||
this.setGravity(behaviorData.gravity);
|
||||
}
|
||||
if (oldBehaviorData.maxFallingSpeed !== newBehaviorData.maxFallingSpeed) {
|
||||
this.setMaxFallingSpeed(newBehaviorData.maxFallingSpeed);
|
||||
if (behaviorData.maxFallingSpeed !== undefined) {
|
||||
this.setMaxFallingSpeed(behaviorData.maxFallingSpeed);
|
||||
}
|
||||
if (oldBehaviorData.acceleration !== newBehaviorData.acceleration) {
|
||||
this.setAcceleration(newBehaviorData.acceleration);
|
||||
if (behaviorData.acceleration !== undefined) {
|
||||
this.setAcceleration(behaviorData.acceleration);
|
||||
}
|
||||
if (oldBehaviorData.deceleration !== newBehaviorData.deceleration) {
|
||||
this.setDeceleration(newBehaviorData.deceleration);
|
||||
if (behaviorData.deceleration !== undefined) {
|
||||
this.setDeceleration(behaviorData.deceleration);
|
||||
}
|
||||
if (oldBehaviorData.maxSpeed !== newBehaviorData.maxSpeed) {
|
||||
this.setMaxSpeed(newBehaviorData.maxSpeed);
|
||||
if (behaviorData.maxSpeed !== undefined) {
|
||||
this.setMaxSpeed(behaviorData.maxSpeed);
|
||||
}
|
||||
if (oldBehaviorData.jumpSpeed !== newBehaviorData.jumpSpeed) {
|
||||
this.setJumpSpeed(newBehaviorData.jumpSpeed);
|
||||
if (behaviorData.jumpSpeed !== undefined) {
|
||||
this.setJumpSpeed(behaviorData.jumpSpeed);
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.canGrabPlatforms !== newBehaviorData.canGrabPlatforms
|
||||
) {
|
||||
this.setCanGrabPlatforms(newBehaviorData.canGrabPlatforms);
|
||||
if (behaviorData.canGrabPlatforms !== undefined) {
|
||||
this.setCanGrabPlatforms(behaviorData.canGrabPlatforms);
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.canGrabWithoutMoving !==
|
||||
newBehaviorData.canGrabWithoutMoving
|
||||
) {
|
||||
this._canGrabWithoutMoving = newBehaviorData.canGrabWithoutMoving;
|
||||
if (behaviorData.canGrabWithoutMoving !== undefined) {
|
||||
this._canGrabWithoutMoving = behaviorData.canGrabWithoutMoving;
|
||||
}
|
||||
if (oldBehaviorData.yGrabOffset !== newBehaviorData.yGrabOffset) {
|
||||
this._yGrabOffset = newBehaviorData.yGrabOffset;
|
||||
if (behaviorData.yGrabOffset !== undefined) {
|
||||
this._yGrabOffset = behaviorData.yGrabOffset;
|
||||
}
|
||||
if (oldBehaviorData.xGrabTolerance !== newBehaviorData.xGrabTolerance) {
|
||||
this._xGrabTolerance = newBehaviorData.xGrabTolerance;
|
||||
if (behaviorData.xGrabTolerance !== undefined) {
|
||||
this._xGrabTolerance = behaviorData.xGrabTolerance;
|
||||
}
|
||||
if (oldBehaviorData.jumpSustainTime !== newBehaviorData.jumpSustainTime) {
|
||||
this.setJumpSustainTime(newBehaviorData.jumpSustainTime);
|
||||
if (behaviorData.jumpSustainTime !== undefined) {
|
||||
this.setJumpSustainTime(behaviorData.jumpSustainTime);
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.useLegacyTrajectory !==
|
||||
newBehaviorData.useLegacyTrajectory
|
||||
) {
|
||||
this._useLegacyTrajectory = newBehaviorData.useLegacyTrajectory;
|
||||
if (behaviorData.useLegacyTrajectory !== undefined) {
|
||||
this._useLegacyTrajectory = behaviorData.useLegacyTrajectory;
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.canGoDownFromJumpthru !==
|
||||
newBehaviorData.canGoDownFromJumpthru
|
||||
) {
|
||||
this._canGoDownFromJumpthru = newBehaviorData.canGoDownFromJumpthru;
|
||||
if (behaviorData.canGoDownFromJumpthru !== undefined) {
|
||||
this._canGoDownFromJumpthru = behaviorData.canGoDownFromJumpthru;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -146,15 +146,15 @@ namespace gdjs {
|
||||
this._manager = PlatformObjectsManager.getManager(instanceContainer);
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
if (oldBehaviorData.platformType !== newBehaviorData.platformType) {
|
||||
this.changePlatformType(newBehaviorData.platformType);
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
if (behaviorData.platformType !== undefined) {
|
||||
this.changePlatformType(behaviorData.platformType);
|
||||
}
|
||||
if (oldBehaviorData.canBeGrabbed !== newBehaviorData.canBeGrabbed) {
|
||||
this._canBeGrabbed = newBehaviorData.canBeGrabbed;
|
||||
if (behaviorData.canBeGrabbed !== undefined) {
|
||||
this._canBeGrabbed = behaviorData.canBeGrabbed;
|
||||
}
|
||||
if (oldBehaviorData.yGrabOffset !== newBehaviorData.yGrabOffset) {
|
||||
this._yGrabOffset = newBehaviorData.yGrabOffset;
|
||||
if (behaviorData.yGrabOffset !== undefined) {
|
||||
this._yGrabOffset = behaviorData.yGrabOffset;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -100,9 +100,10 @@ namespace gdjs {
|
||||
*/
|
||||
constructor(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
shapePainterObjectData: ShapePainterObjectData
|
||||
shapePainterObjectData: ShapePainterObjectData,
|
||||
instanceData?: InstanceData
|
||||
) {
|
||||
super(instanceContainer, shapePainterObjectData);
|
||||
super(instanceContainer, shapePainterObjectData, instanceData);
|
||||
this._fillColor =
|
||||
typeof shapePainterObjectData.fillColor === 'string'
|
||||
? gdjs.rgbOrHexStringToNumber(shapePainterObjectData.fillColor)
|
||||
|
||||
@@ -68,9 +68,10 @@ namespace gdjs {
|
||||
*/
|
||||
constructor(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
objectData: SpineObjectData
|
||||
objectData: SpineObjectData,
|
||||
instanceData?: InstanceData
|
||||
) {
|
||||
super(instanceContainer, objectData);
|
||||
super(instanceContainer, objectData, instanceData);
|
||||
|
||||
this._animations = objectData.content.animations;
|
||||
this._originalScale = objectData.content.scale;
|
||||
|
||||
@@ -19,9 +19,10 @@ namespace gdjs {
|
||||
*/
|
||||
constructor(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
textEntryObjectData: ObjectData
|
||||
textEntryObjectData: ObjectData,
|
||||
instanceData?: InstanceData
|
||||
) {
|
||||
super(instanceContainer, textEntryObjectData);
|
||||
super(instanceContainer, textEntryObjectData, instanceData);
|
||||
this._renderer = new gdjs.TextEntryRuntimeObjectRenderer(this);
|
||||
|
||||
// *ALWAYS* call `this.onCreated()` at the very end of your object constructor.
|
||||
|
||||
@@ -134,9 +134,10 @@ namespace gdjs {
|
||||
|
||||
constructor(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
objectData: TextInputObjectData
|
||||
objectData: TextInputObjectData,
|
||||
instanceData?: InstanceData
|
||||
) {
|
||||
super(instanceContainer, objectData);
|
||||
super(instanceContainer, objectData, instanceData);
|
||||
|
||||
this._string = objectData.content.initialValue;
|
||||
this._placeholder = objectData.content.placeholder;
|
||||
|
||||
@@ -134,9 +134,10 @@ namespace gdjs {
|
||||
*/
|
||||
constructor(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
textObjectData: TextObjectData
|
||||
textObjectData: TextObjectData,
|
||||
instanceData?: InstanceData
|
||||
) {
|
||||
super(instanceContainer, textObjectData);
|
||||
super(instanceContainer, textObjectData, instanceData);
|
||||
const content = textObjectData.content;
|
||||
this._characterSize = Math.max(1, content.characterSize);
|
||||
this._fontName = content.font;
|
||||
|
||||
@@ -71,9 +71,10 @@ namespace gdjs {
|
||||
|
||||
constructor(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
objectData: ObjectData & SimpleTileMapObjectDataType
|
||||
objectData: ObjectData & SimpleTileMapObjectDataType,
|
||||
instanceData?: InstanceData
|
||||
) {
|
||||
super(instanceContainer, objectData);
|
||||
super(instanceContainer, objectData, instanceData);
|
||||
this._atlasImage = objectData.content.atlasImage;
|
||||
this._rowCount = objectData.content.rowCount;
|
||||
this._columnCount = objectData.content.columnCount;
|
||||
|
||||
@@ -88,8 +88,12 @@ namespace gdjs {
|
||||
*/
|
||||
private _transformationIsUpToDate: boolean = false;
|
||||
|
||||
constructor(instanceContainer: gdjs.RuntimeInstanceContainer, objectData) {
|
||||
super(instanceContainer, objectData);
|
||||
constructor(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
objectData,
|
||||
instanceData?: InstanceData
|
||||
) {
|
||||
super(instanceContainer, objectData, instanceData);
|
||||
this._tilemapJsonFile = objectData.content.tilemapJsonFile;
|
||||
this._tilesetJsonFile = objectData.content.tilesetJsonFile;
|
||||
this._collisionMaskTag = objectData.content.collisionMaskTag;
|
||||
|
||||
@@ -65,9 +65,10 @@ namespace gdjs {
|
||||
|
||||
constructor(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
objectData: TilemapObjectData
|
||||
objectData: TilemapObjectData,
|
||||
instanceData?: InstanceData
|
||||
) {
|
||||
super(instanceContainer, objectData);
|
||||
super(instanceContainer, objectData, instanceData);
|
||||
this._tilemapJsonFile = objectData.content.tilemapJsonFile;
|
||||
this._tilesetJsonFile = objectData.content.tilesetJsonFile;
|
||||
this._tilemapAtlasImage = objectData.content.tilemapAtlasImage;
|
||||
|
||||
@@ -63,9 +63,10 @@ namespace gdjs {
|
||||
*/
|
||||
constructor(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
tiledSpriteObjectData: TiledSpriteObjectData
|
||||
tiledSpriteObjectData: TiledSpriteObjectData,
|
||||
instanceData?: InstanceData
|
||||
) {
|
||||
super(instanceContainer, tiledSpriteObjectData);
|
||||
super(instanceContainer, tiledSpriteObjectData, instanceData);
|
||||
this._objectData = tiledSpriteObjectData;
|
||||
this._renderer = new gdjs.TiledSpriteRuntimeObjectRenderer(
|
||||
this,
|
||||
|
||||
@@ -184,49 +184,42 @@ namespace gdjs {
|
||||
this._ignoreDefaultControlsAsSyncedByNetwork = !options.keepControl;
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
if (oldBehaviorData.allowDiagonals !== newBehaviorData.allowDiagonals) {
|
||||
this._allowDiagonals = newBehaviorData.allowDiagonals;
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
if (behaviorData.allowDiagonals !== undefined) {
|
||||
this._allowDiagonals = behaviorData.allowDiagonals;
|
||||
}
|
||||
if (oldBehaviorData.acceleration !== newBehaviorData.acceleration) {
|
||||
this._acceleration = newBehaviorData.acceleration;
|
||||
if (behaviorData.acceleration !== undefined) {
|
||||
this._acceleration = behaviorData.acceleration;
|
||||
}
|
||||
if (oldBehaviorData.deceleration !== newBehaviorData.deceleration) {
|
||||
this._deceleration = newBehaviorData.deceleration;
|
||||
if (behaviorData.deceleration !== undefined) {
|
||||
this._deceleration = behaviorData.deceleration;
|
||||
}
|
||||
if (oldBehaviorData.maxSpeed !== newBehaviorData.maxSpeed) {
|
||||
this._maxSpeed = newBehaviorData.maxSpeed;
|
||||
if (behaviorData.maxSpeed !== undefined) {
|
||||
this._maxSpeed = behaviorData.maxSpeed;
|
||||
}
|
||||
if (oldBehaviorData.angularMaxSpeed !== newBehaviorData.angularMaxSpeed) {
|
||||
this._angularMaxSpeed = newBehaviorData.angularMaxSpeed;
|
||||
if (behaviorData.angularMaxSpeed !== undefined) {
|
||||
this._angularMaxSpeed = behaviorData.angularMaxSpeed;
|
||||
}
|
||||
if (oldBehaviorData.rotateObject !== newBehaviorData.rotateObject) {
|
||||
this._rotateObject = newBehaviorData.rotateObject;
|
||||
if (behaviorData.rotateObject !== undefined) {
|
||||
this._rotateObject = behaviorData.rotateObject;
|
||||
}
|
||||
if (oldBehaviorData.angleOffset !== newBehaviorData.angleOffset) {
|
||||
this._angleOffset = newBehaviorData.angleOffset;
|
||||
if (behaviorData.angleOffset !== undefined) {
|
||||
this._angleOffset = behaviorData.angleOffset;
|
||||
}
|
||||
if (behaviorData.ignoreDefaultControls !== undefined) {
|
||||
this._ignoreDefaultControls = behaviorData.ignoreDefaultControls;
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.ignoreDefaultControls !==
|
||||
newBehaviorData.ignoreDefaultControls
|
||||
) {
|
||||
this._ignoreDefaultControls = newBehaviorData.ignoreDefaultControls;
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.platformType !== newBehaviorData.platformType ||
|
||||
oldBehaviorData.customIsometryAngle !==
|
||||
newBehaviorData.customIsometryAngle
|
||||
behaviorData.platformType !== undefined ||
|
||||
behaviorData.customIsometryAngle !== undefined
|
||||
) {
|
||||
this.setViewpoint(
|
||||
newBehaviorData.platformType,
|
||||
newBehaviorData.customIsometryAngle
|
||||
behaviorData.platformType,
|
||||
behaviorData.customIsometryAngle
|
||||
);
|
||||
}
|
||||
if (
|
||||
oldBehaviorData.movementAngleOffset !==
|
||||
newBehaviorData.movementAngleOffset
|
||||
) {
|
||||
this._movementAngleOffset = newBehaviorData.movementAngleOffset;
|
||||
if (behaviorData.movementAngleOffset !== undefined) {
|
||||
this._movementAngleOffset = behaviorData.movementAngleOffset;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -390,10 +390,7 @@ namespace gdjs {
|
||||
super(instanceContainer, behaviorData, owner);
|
||||
}
|
||||
|
||||
updateFromBehaviorData(
|
||||
oldBehaviorData: BehaviorData,
|
||||
newBehaviorData: BehaviorData
|
||||
): boolean {
|
||||
override applyBehaviorOverriding(behaviorData: BehaviorData): boolean {
|
||||
// Nothing to update.
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -70,9 +70,10 @@ namespace gdjs {
|
||||
*/
|
||||
constructor(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
videoObjectData: VideoObjectData
|
||||
videoObjectData: VideoObjectData,
|
||||
instanceData?: InstanceData
|
||||
) {
|
||||
super(instanceContainer, videoObjectData);
|
||||
super(instanceContainer, videoObjectData, instanceData);
|
||||
this._opacity = videoObjectData.content.opacity;
|
||||
this._loop = videoObjectData.content.loop;
|
||||
this._volume = videoObjectData.content.volume;
|
||||
|
||||
@@ -207,7 +207,7 @@ CODE_NAMESPACE.RUNTIME_BEHAVIOR_CLASSNAME = class RUNTIME_BEHAVIOR_CLASSNAME ext
|
||||
}
|
||||
|
||||
// Hot-reload:
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData) {
|
||||
applyBehaviorOverriding(behaviorOverriding) {
|
||||
UPDATE_FROM_BEHAVIOR_DATA_CODE
|
||||
|
||||
return true;
|
||||
@@ -396,8 +396,8 @@ gd::String BehaviorCodeGenerator::GenerateUpdatePropertyFromBehaviorDataCode(
|
||||
const gd::EventsBasedBehavior& eventsBasedBehavior,
|
||||
const gd::NamedPropertyDescriptor& property) {
|
||||
return gd::String(R"jscode_template(
|
||||
if (oldBehaviorData.PROPERTY_NAME !== newBehaviorData.PROPERTY_NAME)
|
||||
this._behaviorData.PROPERTY_NAME = newBehaviorData.PROPERTY_NAME;)jscode_template")
|
||||
if (behaviorOverriding.PROPERTY_NAME !== undefined)
|
||||
this._behaviorData.PROPERTY_NAME = behaviorOverriding.PROPERTY_NAME;)jscode_template")
|
||||
.FindAndReplace("PROPERTY_NAME", property.GetName());
|
||||
}
|
||||
|
||||
|
||||
@@ -204,8 +204,8 @@ CODE_NAMESPACE = CODE_NAMESPACE || {};
|
||||
* Object generated from OBJECT_FULL_NAME
|
||||
*/
|
||||
CODE_NAMESPACE.RUNTIME_OBJECT_CLASSNAME = class RUNTIME_OBJECT_CLASSNAME extends RUNTIME_OBJECT_BASE_CLASS_NAME {
|
||||
constructor(parentInstanceContainer, objectData) {
|
||||
super(parentInstanceContainer, objectData);
|
||||
constructor(parentInstanceContainer, objectData, instanceData) {
|
||||
super(parentInstanceContainer, objectData, instanceData);
|
||||
this._parentInstanceContainer = parentInstanceContainer;
|
||||
|
||||
this._onceTriggers = new gdjs.OnceTriggers();
|
||||
|
||||
@@ -103,9 +103,10 @@ namespace gdjs {
|
||||
*/
|
||||
constructor(
|
||||
parent: gdjs.RuntimeInstanceContainer,
|
||||
objectData: ObjectData & CustomObjectConfiguration
|
||||
objectData: ObjectData & CustomObjectConfiguration,
|
||||
instanceData: InstanceData | undefined
|
||||
) {
|
||||
super(parent, objectData);
|
||||
super(parent, objectData, instanceData);
|
||||
this._type = objectData.type;
|
||||
this._instanceContainer = new gdjs.CustomRuntimeObjectInstanceContainer(
|
||||
parent,
|
||||
|
||||
@@ -6,9 +6,10 @@ namespace gdjs {
|
||||
export class CustomRuntimeObject2D extends gdjs.CustomRuntimeObject {
|
||||
constructor(
|
||||
parent: gdjs.RuntimeInstanceContainer,
|
||||
objectData: ObjectData & CustomObjectConfiguration
|
||||
objectData: ObjectData & CustomObjectConfiguration,
|
||||
instanceData?: InstanceData
|
||||
) {
|
||||
super(parent, objectData);
|
||||
super(parent, objectData, instanceData);
|
||||
}
|
||||
|
||||
protected override _createRender(): gdjs.CustomRuntimeObject2DRenderer {
|
||||
|
||||
@@ -70,8 +70,11 @@ namespace gdjs {
|
||||
this._orderedLayers.length = 0;
|
||||
}
|
||||
|
||||
createObject(objectName: string): gdjs.RuntimeObject | null {
|
||||
const result = super.createObject(objectName);
|
||||
override createObject(
|
||||
objectName: string,
|
||||
instanceData?: InstanceData
|
||||
): gdjs.RuntimeObject | null {
|
||||
const result = super.createObject(objectName, instanceData);
|
||||
this._customObject.onChildrenLocationChanged();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -5071,9 +5071,10 @@ namespace gdjs {
|
||||
|
||||
constructor(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
objectData: gdjs.Object3DData
|
||||
objectData: gdjs.Object3DData,
|
||||
instanceData?: InstanceData
|
||||
) {
|
||||
super(instanceContainer, objectData);
|
||||
super(instanceContainer, objectData, instanceData);
|
||||
this._renderer = new UnknownRuntimeObjectRenderer(
|
||||
this,
|
||||
instanceContainer
|
||||
|
||||
@@ -357,7 +357,7 @@ namespace gdjs {
|
||||
continue;
|
||||
}
|
||||
|
||||
const newObject = this.createObject(objectName);
|
||||
const newObject = this.createObject(objectName, instanceData);
|
||||
if (newObject !== null) {
|
||||
if (shouldTrackByPersistentUuid) {
|
||||
// Give the object the same persistentUuid as the instance, so that
|
||||
@@ -660,7 +660,10 @@ namespace gdjs {
|
||||
* @param objectName The name of the object to be created
|
||||
* @return The created object
|
||||
*/
|
||||
createObject(objectName: string): gdjs.RuntimeObject | null {
|
||||
createObject(
|
||||
objectName: string,
|
||||
instanceData?: InstanceData
|
||||
): gdjs.RuntimeObject | null {
|
||||
if (
|
||||
!this._objectsCtor.containsKey(objectName) ||
|
||||
!this._objects.containsKey(objectName)
|
||||
@@ -685,7 +688,7 @@ namespace gdjs {
|
||||
const ctor = this._objectsCtor.get(objectName);
|
||||
let obj;
|
||||
if (!cache || cache.length === 0) {
|
||||
obj = new ctor(this, objectData);
|
||||
obj = new ctor(this, objectData, instanceData);
|
||||
} else {
|
||||
// Reuse an objet destroyed before. If there is an object in the cache,
|
||||
// then it means it does support reinitialization.
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace gdjs {
|
||||
return false;
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
// Nothing to update.
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace gdjs {
|
||||
return false;
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
// Nothing to update.
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace gdjs {
|
||||
return false;
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
// Nothing to update.
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace gdjs {
|
||||
return false;
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
// Nothing to update.
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace gdjs {
|
||||
return false;
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
// Nothing to update.
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace gdjs {
|
||||
return false;
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
// Nothing to update.
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace gdjs {
|
||||
return false;
|
||||
}
|
||||
|
||||
updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {
|
||||
override applyBehaviorOverriding(behaviorData): boolean {
|
||||
// Nothing to update.
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -79,6 +79,22 @@ namespace gdjs {
|
||||
oldBehaviorData: BehaviorData,
|
||||
newBehaviorData: BehaviorData
|
||||
): boolean {
|
||||
const diffBehaviorData = {
|
||||
name: newBehaviorData.name,
|
||||
type: newBehaviorData.type,
|
||||
};
|
||||
for (const key in diffBehaviorData) {
|
||||
const oldValue = oldBehaviorData[key];
|
||||
const newValue = newBehaviorData[key];
|
||||
if (newValue !== oldValue) {
|
||||
diffBehaviorData[key] = newValue;
|
||||
}
|
||||
}
|
||||
// If not redefined, mark by default the hot-reload as failed.
|
||||
return this.applyBehaviorOverriding(diffBehaviorData);
|
||||
}
|
||||
|
||||
applyBehaviorOverriding(behaviorOverriding: BehaviorData): boolean {
|
||||
// If not redefined, mark by default the hot-reload as failed.
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -240,7 +240,8 @@ namespace gdjs {
|
||||
*/
|
||||
constructor(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
objectData: ObjectData
|
||||
objectData: ObjectData,
|
||||
instanceData: InstanceData | undefined
|
||||
) {
|
||||
this.name = objectData.name || '';
|
||||
this.type = objectData.type || '';
|
||||
@@ -275,6 +276,15 @@ namespace gdjs {
|
||||
}
|
||||
this._behaviorsTable.put(autoData.name, behavior);
|
||||
}
|
||||
if (instanceData && instanceData.behaviorOverridings) {
|
||||
for (const behaviorOverriding of instanceData.behaviorOverridings) {
|
||||
const behavior = this.getBehavior(behaviorOverriding.name);
|
||||
if (!behavior) {
|
||||
continue;
|
||||
}
|
||||
behavior.applyBehaviorOverriding(behaviorOverriding);
|
||||
}
|
||||
}
|
||||
this._timers = new Hashtable();
|
||||
}
|
||||
|
||||
|
||||
@@ -73,9 +73,10 @@ namespace gdjs {
|
||||
*/
|
||||
constructor(
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer,
|
||||
spriteObjectData: ObjectData & SpriteObjectDataType
|
||||
spriteObjectData: ObjectData & SpriteObjectDataType,
|
||||
instanceData?: InstanceData
|
||||
) {
|
||||
super(instanceContainer, spriteObjectData);
|
||||
super(instanceContainer, spriteObjectData, instanceData);
|
||||
this._updateIfNotVisible = !!spriteObjectData.updateIfNotVisible;
|
||||
this._preScale = spriteObjectData.preScale || 1;
|
||||
this._renderer = new gdjs.SpriteRuntimeObjectRenderer(
|
||||
|
||||
Vendored
+1
@@ -450,6 +450,7 @@ declare interface InstanceData extends InstancePersistentUuidData {
|
||||
numberProperties: InstanceNumberProperty[];
|
||||
stringProperties: InstanceStringProperty[];
|
||||
initialVariables: RootVariableData[];
|
||||
behaviorOverridings?: Array<BehaviorData & any>;
|
||||
}
|
||||
|
||||
declare interface InstanceNumberProperty {
|
||||
|
||||
@@ -4,14 +4,18 @@
|
||||
* Create and return a game with a few assets loaded, to be used in tests
|
||||
* needing real images.
|
||||
* @internal
|
||||
* @param props {?{customObjectInstances?: Array<InstanceData>}}
|
||||
* @returns {Promise<gdjs.RuntimeGame>} A promise resolving with the game with loaded assets.
|
||||
*/
|
||||
gdjs.getPixiRuntimeGameWithAssets = () => {
|
||||
if (gdjs.getPixiRuntimeGameWithAssets._pixiRuntimeGameWithAssetsPromise) {
|
||||
gdjs.getPixiRuntimeGameWithAssets = (props = null) => {
|
||||
if (
|
||||
gdjs.getPixiRuntimeGameWithAssets._pixiRuntimeGameWithAssetsPromise &&
|
||||
!props
|
||||
) {
|
||||
return gdjs.getPixiRuntimeGameWithAssets._pixiRuntimeGameWithAssetsPromise;
|
||||
}
|
||||
|
||||
var runtimeGame = new gdjs.RuntimeGame({
|
||||
const runtimeGame = new gdjs.RuntimeGame({
|
||||
variables: [],
|
||||
properties: {
|
||||
adaptGameResolutionAtRuntime: true,
|
||||
@@ -77,19 +81,19 @@ gdjs.getPixiRuntimeGameWithAssets = () => {
|
||||
title: '',
|
||||
variables: [],
|
||||
usedResources: [],
|
||||
uiSettings: {
|
||||
grid: false,
|
||||
gridType: 'rectangular',
|
||||
gridWidth: 10,
|
||||
gridHeight: 10,
|
||||
gridDepth: 10,
|
||||
gridOffsetX: 0,
|
||||
gridOffsetY: 0,
|
||||
gridOffsetZ: 0,
|
||||
gridColor: 0,
|
||||
gridAlpha: 1,
|
||||
snap: false,
|
||||
}
|
||||
uiSettings: {
|
||||
grid: false,
|
||||
gridType: 'rectangular',
|
||||
gridWidth: 10,
|
||||
gridHeight: 10,
|
||||
gridDepth: 10,
|
||||
gridOffsetX: 0,
|
||||
gridOffsetY: 0,
|
||||
gridOffsetZ: 0,
|
||||
gridColor: 0,
|
||||
gridAlpha: 1,
|
||||
snap: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
externalLayouts: [],
|
||||
@@ -207,7 +211,7 @@ gdjs.getPixiRuntimeGameWithAssets = () => {
|
||||
],
|
||||
},
|
||||
],
|
||||
instances: [
|
||||
instances: (props && props.customObjectInstances) || [
|
||||
{
|
||||
angle: 0,
|
||||
customSize: true,
|
||||
@@ -242,20 +246,23 @@ gdjs.getPixiRuntimeGameWithAssets = () => {
|
||||
],
|
||||
});
|
||||
|
||||
gdjs.getPixiRuntimeGameWithAssets._pixiRuntimeGameWithAssetsPromise =
|
||||
new Promise((resolve) => {
|
||||
runtimeGame.loadAllAssets(
|
||||
() => {
|
||||
console.info('Done loading assets for test game');
|
||||
const pixiRuntimeGameWithAssetsPromise = new Promise((resolve) => {
|
||||
runtimeGame.loadAllAssets(
|
||||
() => {
|
||||
console.info('Done loading assets for test game');
|
||||
|
||||
resolve(runtimeGame);
|
||||
},
|
||||
() => {
|
||||
/* Ignore progress */
|
||||
}
|
||||
);
|
||||
});
|
||||
return gdjs.getPixiRuntimeGameWithAssets._pixiRuntimeGameWithAssetsPromise;
|
||||
resolve(runtimeGame);
|
||||
},
|
||||
() => {
|
||||
/* Ignore progress */
|
||||
}
|
||||
);
|
||||
});
|
||||
if (!props) {
|
||||
gdjs.getPixiRuntimeGameWithAssets._pixiRuntimeGameWithAssetsPromise =
|
||||
pixiRuntimeGameWithAssetsPromise;
|
||||
}
|
||||
return pixiRuntimeGameWithAssetsPromise;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -61,7 +61,7 @@ describe('gdjs.CustomRuntimeObject', function () {
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
});
|
||||
instanceContainer.addObject(customObject);
|
||||
return customObject;
|
||||
|
||||
@@ -805,7 +805,9 @@ interface Behavior {
|
||||
|
||||
[Value] MapStringPropertyDescriptor GetProperties();
|
||||
boolean UpdateProperty([Const] DOMString name, [Const] DOMString value);
|
||||
void RemoveProperty([Const] DOMString name);
|
||||
void InitializeContent();
|
||||
boolean HasPropertyValue([Const] DOMString name);
|
||||
|
||||
void SerializeTo([Ref] SerializerElement element);
|
||||
void UnserializeFrom([Const, Ref] SerializerElement element);
|
||||
@@ -1055,7 +1057,7 @@ interface ExternalLayout {
|
||||
[Ref] EditorSettings GetAssociatedEditorSettings();
|
||||
|
||||
void SerializeTo([Ref] SerializerElement element);
|
||||
void UnserializeFrom([Const, Ref] SerializerElement element);
|
||||
void UnserializeFrom([Ref] Project project, [Const, Ref] SerializerElement element);
|
||||
};
|
||||
|
||||
interface Effect {
|
||||
@@ -1492,8 +1494,17 @@ interface InitialInstance {
|
||||
|
||||
[Ref] VariablesContainer GetVariables();
|
||||
|
||||
boolean HasAnyOverriddenProperty([Const, Ref] gdObject obj);
|
||||
boolean HasAnyOverriddenPropertyForBehavior([Const, Ref] Behavior behavior);
|
||||
|
||||
boolean HasBehaviorOverridingNamed([Const] DOMString name);
|
||||
Behavior AddNewBehaviorOverriding([Ref] Project project, [Const] DOMString type, [Const] DOMString name);
|
||||
[Ref] Behavior GetBehaviorOverriding([Const] DOMString name);
|
||||
void RemoveBehaviorOverriding([Const] DOMString name);
|
||||
boolean RenameBehaviorOverriding([Const] DOMString oldName, [Const] DOMString name);
|
||||
|
||||
void SerializeTo([Ref] SerializerElement element);
|
||||
void UnserializeFrom([Const, Ref] SerializerElement element);
|
||||
void UnserializeFrom([Ref] Project project, [Const, Ref] SerializerElement element);
|
||||
};
|
||||
|
||||
interface InitialInstancesContainer {
|
||||
@@ -1518,7 +1529,7 @@ interface InitialInstancesContainer {
|
||||
[Ref] InitialInstance InsertInitialInstance([Const, Ref] InitialInstance inst);
|
||||
|
||||
void SerializeTo([Ref] SerializerElement element);
|
||||
void UnserializeFrom([Const, Ref] SerializerElement element);
|
||||
void UnserializeFrom([Ref] Project project, [Const, Ref] SerializerElement element);
|
||||
};
|
||||
|
||||
interface HighestZOrderFinder {
|
||||
|
||||
@@ -809,7 +809,7 @@ describe('libGD.js', function () {
|
||||
let initialInstance2 = layout
|
||||
.getInitialInstances()
|
||||
.insertNewInitialInstance();
|
||||
initialInstance2.unserializeFrom(element);
|
||||
initialInstance2.unserializeFrom(project, element);
|
||||
expect(initialInstance2.getObjectName()).toBe('MySpriteObject');
|
||||
expect(initialInstance2.getX()).toBe(150);
|
||||
expect(initialInstance2.getY()).toBe(140);
|
||||
@@ -863,7 +863,7 @@ describe('libGD.js', function () {
|
||||
const migratedInstance = layout
|
||||
.getInitialInstances()
|
||||
.insertNewInitialInstance();
|
||||
migratedInstance.unserializeFrom(element);
|
||||
migratedInstance.unserializeFrom(project, element);
|
||||
|
||||
element.delete();
|
||||
expect(migratedInstance.getX()).toBe(-100);
|
||||
@@ -902,7 +902,7 @@ describe('libGD.js', function () {
|
||||
const instanceWithJustDepth = layout
|
||||
.getInitialInstances()
|
||||
.insertNewInitialInstance();
|
||||
instanceWithJustDepth.unserializeFrom(element);
|
||||
instanceWithJustDepth.unserializeFrom(project, element);
|
||||
|
||||
element.delete();
|
||||
expect(instanceWithJustDepth.getX()).toBe(-100);
|
||||
@@ -950,7 +950,7 @@ describe('libGD.js', function () {
|
||||
const initialInstance2 = layout
|
||||
.getInitialInstances()
|
||||
.insertNewInitialInstance();
|
||||
initialInstance2.unserializeFrom(element);
|
||||
initialInstance2.unserializeFrom(project, element);
|
||||
expect(initialInstance2.getX()).toBe(40);
|
||||
expect(initialInstance2.getY()).toBe(41);
|
||||
expect(initialInstance2.getZ()).toBe(42);
|
||||
@@ -975,7 +975,7 @@ describe('libGD.js', function () {
|
||||
|
||||
// The UUID must persist across serializations.
|
||||
const initialInstance2 = new gd.InitialInstance();
|
||||
initialInstance2.unserializeFrom(element);
|
||||
initialInstance2.unserializeFrom(project, element);
|
||||
|
||||
let element2 = new gd.SerializerElement();
|
||||
initialInstance.serializeTo(element2);
|
||||
|
||||
Vendored
+12
-3
@@ -692,7 +692,9 @@ export class Behavior extends EmscriptenObject {
|
||||
getTypeName(): string;
|
||||
getProperties(): MapStringPropertyDescriptor;
|
||||
updateProperty(name: string, value: string): boolean;
|
||||
removeProperty(name: string): void;
|
||||
initializeContent(): void;
|
||||
hasPropertyValue(name: string): boolean;
|
||||
serializeTo(element: SerializerElement): void;
|
||||
unserializeFrom(element: SerializerElement): void;
|
||||
isFolded(): boolean;
|
||||
@@ -866,7 +868,7 @@ export class ExternalLayout extends EmscriptenObject {
|
||||
getInitialInstances(): InitialInstancesContainer;
|
||||
getAssociatedEditorSettings(): EditorSettings;
|
||||
serializeTo(element: SerializerElement): void;
|
||||
unserializeFrom(element: SerializerElement): void;
|
||||
unserializeFrom(project: Project, element: SerializerElement): void;
|
||||
}
|
||||
|
||||
export class Effect extends EmscriptenObject {
|
||||
@@ -1233,8 +1235,15 @@ export class InitialInstance extends EmscriptenObject {
|
||||
setRawDoubleProperty(name: string, value: number): void;
|
||||
setRawStringProperty(name: string, value: string): void;
|
||||
getVariables(): VariablesContainer;
|
||||
hasAnyOverriddenProperty(obj: gdObject): boolean;
|
||||
hasAnyOverriddenPropertyForBehavior(behavior: Behavior): boolean;
|
||||
hasBehaviorOverridingNamed(name: string): boolean;
|
||||
addNewBehaviorOverriding(project: Project, type: string, name: string): Behavior;
|
||||
getBehaviorOverriding(name: string): Behavior;
|
||||
removeBehaviorOverriding(name: string): void;
|
||||
renameBehaviorOverriding(oldName: string, name: string): boolean;
|
||||
serializeTo(element: SerializerElement): void;
|
||||
unserializeFrom(element: SerializerElement): void;
|
||||
unserializeFrom(project: Project, element: SerializerElement): void;
|
||||
}
|
||||
|
||||
export class InitialInstancesContainer extends EmscriptenObject {
|
||||
@@ -1255,7 +1264,7 @@ export class InitialInstancesContainer extends EmscriptenObject {
|
||||
insertNewInitialInstance(): InitialInstance;
|
||||
insertInitialInstance(inst: InitialInstance): InitialInstance;
|
||||
serializeTo(element: SerializerElement): void;
|
||||
unserializeFrom(element: SerializerElement): void;
|
||||
unserializeFrom(project: Project, element: SerializerElement): void;
|
||||
}
|
||||
|
||||
export class HighestZOrderFinder extends EmscriptenObject {
|
||||
|
||||
@@ -6,7 +6,9 @@ declare class gdBehavior {
|
||||
getTypeName(): string;
|
||||
getProperties(): gdMapStringPropertyDescriptor;
|
||||
updateProperty(name: string, value: string): boolean;
|
||||
removeProperty(name: string): void;
|
||||
initializeContent(): void;
|
||||
hasPropertyValue(name: string): boolean;
|
||||
serializeTo(element: gdSerializerElement): void;
|
||||
unserializeFrom(element: gdSerializerElement): void;
|
||||
isFolded(): boolean;
|
||||
|
||||
@@ -8,7 +8,7 @@ declare class gdExternalLayout {
|
||||
getInitialInstances(): gdInitialInstancesContainer;
|
||||
getAssociatedEditorSettings(): gdEditorSettings;
|
||||
serializeTo(element: gdSerializerElement): void;
|
||||
unserializeFrom(element: gdSerializerElement): void;
|
||||
unserializeFrom(project: gdProject, element: gdSerializerElement): void;
|
||||
delete(): void;
|
||||
ptr: number;
|
||||
};
|
||||
@@ -58,8 +58,15 @@ declare class gdInitialInstance {
|
||||
setRawDoubleProperty(name: string, value: number): void;
|
||||
setRawStringProperty(name: string, value: string): void;
|
||||
getVariables(): gdVariablesContainer;
|
||||
hasAnyOverriddenProperty(obj: gdObject): boolean;
|
||||
hasAnyOverriddenPropertyForBehavior(behavior: gdBehavior): boolean;
|
||||
hasBehaviorOverridingNamed(name: string): boolean;
|
||||
addNewBehaviorOverriding(project: gdProject, type: string, name: string): gdBehavior;
|
||||
getBehaviorOverriding(name: string): gdBehavior;
|
||||
removeBehaviorOverriding(name: string): void;
|
||||
renameBehaviorOverriding(oldName: string, name: string): boolean;
|
||||
serializeTo(element: gdSerializerElement): void;
|
||||
unserializeFrom(element: gdSerializerElement): void;
|
||||
unserializeFrom(project: gdProject, element: gdSerializerElement): void;
|
||||
delete(): void;
|
||||
ptr: number;
|
||||
};
|
||||
@@ -17,7 +17,7 @@ declare class gdInitialInstancesContainer {
|
||||
insertNewInitialInstance(): gdInitialInstance;
|
||||
insertInitialInstance(inst: gdInitialInstance): gdInitialInstance;
|
||||
serializeTo(element: gdSerializerElement): void;
|
||||
unserializeFrom(element: gdSerializerElement): void;
|
||||
unserializeFrom(project: gdProject, element: gdSerializerElement): void;
|
||||
delete(): void;
|
||||
ptr: number;
|
||||
};
|
||||
@@ -29,7 +29,11 @@ const BehaviorPropertiesEditor = ({
|
||||
propertiesMapToSchema({
|
||||
properties: behavior.getProperties(),
|
||||
defaultValueProperties: behaviorMetadata.getProperties(),
|
||||
getProperties: instance => instance.getProperties(),
|
||||
getPropertyValue: (instance, name) =>
|
||||
instance
|
||||
.getProperties()
|
||||
.get(name)
|
||||
.getValue(),
|
||||
onUpdateProperty: (instance, name, value) => {
|
||||
instance.updateProperty(name, value);
|
||||
},
|
||||
|
||||
@@ -395,6 +395,7 @@ export const useManageObjectBehaviors = ({
|
||||
// Renaming a behavior is something that is really rare anyway! :)
|
||||
|
||||
if (object.hasBehaviorNamed(newName)) return;
|
||||
// TODO Add a refactor operation to update the behavior name in overridings of object instances
|
||||
object.renameBehavior(behavior.getName(), newName);
|
||||
onUpdate();
|
||||
if (onBehaviorsUpdated) onBehaviorsUpdated();
|
||||
@@ -419,6 +420,7 @@ export const useManageObjectBehaviors = ({
|
||||
const answer = Window.showConfirmDialog(message);
|
||||
|
||||
if (answer) {
|
||||
// TODO Add a refactor operation to remove the behavior overridings in object instances
|
||||
object.removeBehavior(behaviorName);
|
||||
dependentBehaviors.forEach(name => object.removeBehavior(name));
|
||||
if (onSizeUpdated) onSizeUpdated();
|
||||
|
||||
@@ -162,7 +162,7 @@ export const CompactPropertiesEditorByVisibility = ({
|
||||
instances: Instances,
|
||||
preventWrap?: boolean,
|
||||
removeSpacers?: boolean,
|
||||
customizeBasicSchema?: Schema => Schema,
|
||||
customizeBasicSchema?: (Schema => Schema) | null,
|
||||
placeholder: React.Node,
|
||||
onRefreshAllFields: () => void,
|
||||
|
||||
|
||||
@@ -15,13 +15,13 @@ const styles = {
|
||||
textOverflow: 'ellipsis',
|
||||
lineHeight: '17px',
|
||||
maxHeight: 34, // 2 * lineHeight to limit to 2 lines.
|
||||
opacity: 0.7,
|
||||
},
|
||||
};
|
||||
type Props = {|
|
||||
label: string,
|
||||
markdownDescription?: ?string,
|
||||
field: React.Node,
|
||||
labelColor?: 'primary' | 'secondary',
|
||||
|};
|
||||
|
||||
const CompactPropertiesEditorRowField = (props: Props) => {
|
||||
@@ -52,7 +52,11 @@ const CompactPropertiesEditorRowField = (props: Props) => {
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Text noMargin style={styles.label}>
|
||||
<Text
|
||||
noMargin
|
||||
style={styles.label}
|
||||
color={props.labelColor === 'primary' ? 'primary' : 'secondary'}
|
||||
>
|
||||
{props.label}
|
||||
</Text>
|
||||
</Tooltip>
|
||||
|
||||
@@ -146,6 +146,23 @@ const getFieldEndAdornmentIcon = ({
|
||||
return null;
|
||||
};
|
||||
|
||||
const isFieldHighlighted = ({
|
||||
instances,
|
||||
field,
|
||||
}: {|
|
||||
instances: Instances,
|
||||
field: ValueField,
|
||||
|}): any => {
|
||||
if (!instances[0]) {
|
||||
console.warn(
|
||||
'isFieldHighlighted was called with an empty list of instances (or containing undefined). This is a bug that should be fixed.'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
return field.isHighlighted ? field.isHighlighted(instances[0]) : false;
|
||||
};
|
||||
|
||||
const getFieldLabel = ({
|
||||
instances,
|
||||
field,
|
||||
@@ -247,6 +264,9 @@ const CompactPropertiesEditor = ({
|
||||
}}
|
||||
disabled={getDisabled({ instances, field })}
|
||||
fullWidth
|
||||
labelColor={
|
||||
isFieldHighlighted({ instances, field }) ? 'primary' : 'secondary'
|
||||
}
|
||||
/>
|
||||
);
|
||||
} else if (field.valueType === 'number') {
|
||||
@@ -306,6 +326,11 @@ const CompactPropertiesEditor = ({
|
||||
{...otherCommonProps}
|
||||
/>
|
||||
}
|
||||
labelColor={
|
||||
isFieldHighlighted({ instances, field })
|
||||
? 'primary'
|
||||
: 'secondary'
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -332,6 +357,9 @@ const CompactPropertiesEditor = ({
|
||||
}}
|
||||
/>
|
||||
}
|
||||
labelColor={
|
||||
isFieldHighlighted({ instances, field }) ? 'primary' : 'secondary'
|
||||
}
|
||||
/>
|
||||
);
|
||||
} else if (field.valueType === 'enumIcon') {
|
||||
@@ -372,6 +400,9 @@ const CompactPropertiesEditor = ({
|
||||
value={getFieldValue({ instances, field })}
|
||||
label={getFieldLabel({ instances, field })}
|
||||
markdownDescription={getFieldDescription(field)}
|
||||
labelColor={
|
||||
isFieldHighlighted({ instances, field }) ? 'primary' : 'secondary'
|
||||
}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
@@ -426,12 +457,17 @@ const CompactPropertiesEditor = ({
|
||||
label={getFieldLabel({ instances, field })}
|
||||
markdownDescription={getFieldDescription(field)}
|
||||
field={<CompactSemiControlledTextField {...otherCommonProps} />}
|
||||
labelColor={
|
||||
isFieldHighlighted({ instances, field })
|
||||
? 'primary'
|
||||
: 'secondary'
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
[instances, onFieldChanged, getFieldDescription]
|
||||
[instances, getFieldDescription, onFieldChanged]
|
||||
);
|
||||
|
||||
const renderSelectField = React.useCallback(
|
||||
@@ -457,7 +493,7 @@ const CompactPropertiesEditor = ({
|
||||
compactSelectField = (
|
||||
<CompactSelectField
|
||||
key={field.name}
|
||||
value={getFieldValue({ instances, field })}
|
||||
value={'' + getFieldValue({ instances, field })}
|
||||
id={field.name}
|
||||
onChange={(newValue: string) => {
|
||||
instances.forEach(i => setValue(i, parseFloat(newValue) || 0));
|
||||
@@ -466,7 +502,7 @@ const CompactPropertiesEditor = ({
|
||||
hasImpactOnAllOtherFields: field.hasImpactOnAllOtherFields,
|
||||
});
|
||||
}}
|
||||
disabled={field.disabled}
|
||||
disabled={getDisabled({ instances, field })}
|
||||
>
|
||||
{children}
|
||||
</CompactSelectField>
|
||||
@@ -507,10 +543,13 @@ const CompactPropertiesEditor = ({
|
||||
label={getFieldLabel({ instances, field })}
|
||||
markdownDescription={getFieldDescription(field)}
|
||||
field={compactSelectField}
|
||||
labelColor={
|
||||
isFieldHighlighted({ instances, field }) ? 'primary' : 'secondary'
|
||||
}
|
||||
/>
|
||||
);
|
||||
},
|
||||
[instances, onFieldChanged, getFieldDescription]
|
||||
[instances, getFieldDescription, onFieldChanged]
|
||||
);
|
||||
|
||||
const renderButton = React.useCallback(
|
||||
@@ -619,6 +658,9 @@ const CompactPropertiesEditor = ({
|
||||
}}
|
||||
/>
|
||||
}
|
||||
labelColor={
|
||||
isFieldHighlighted({ instances, field }) ? 'primary' : 'secondary'
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -652,6 +694,9 @@ const CompactPropertiesEditor = ({
|
||||
}}
|
||||
/>
|
||||
}
|
||||
labelColor={
|
||||
isFieldHighlighted({ instances, field }) ? 'primary' : 'secondary'
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -40,7 +40,6 @@ export const enumerateEffectsMetadata = (
|
||||
// Convert the effect type properties to a PropertiesEditor Schema.
|
||||
const parametersSchema: Schema = effectPropertiesMapToSchema({
|
||||
defaultValueProperties: effectMetadata.getProperties(),
|
||||
getProperties: instance => effectMetadata.getProperties(),
|
||||
});
|
||||
return {
|
||||
extension,
|
||||
|
||||
@@ -31,9 +31,28 @@ import TileSetVisualizer, {
|
||||
type TileMapTileSelection,
|
||||
} from '../TileSetVisualizer';
|
||||
import Add from '../../UI/CustomSvgIcons/Add';
|
||||
import {
|
||||
TopLevelCollapsibleSection,
|
||||
CollapsibleSubPanel,
|
||||
type TitleBarButton,
|
||||
} from '../../ObjectEditor/CompactObjectPropertiesEditor';
|
||||
import { ColumnStackLayout } from '../../UI/Layout';
|
||||
import Link from '../../UI/Link';
|
||||
import { CompactBehaviorPropertiesEditor } from '../../ObjectEditor/CompactObjectPropertiesEditor/CompactBehaviorPropertiesEditor';
|
||||
import { IconContainer } from '../../UI/IconContainer';
|
||||
import { getHelpLink } from '../../Utils/HelpLink';
|
||||
import Window from '../../Utils/Window';
|
||||
import { type ResourceManagementProps } from '../../ResourcesList/ResourceSource';
|
||||
import EmptyMessage from '../../UI/EmptyMessage';
|
||||
|
||||
const gd: libGDevelop = global.gd;
|
||||
|
||||
const notOverridableBehaviorTypes = [
|
||||
'Physics2::Physics2Behavior',
|
||||
'Physics3D::Physics3DBehavior',
|
||||
'PhysicsBehavior::PhysicsBehavior',
|
||||
];
|
||||
|
||||
export const styles = {
|
||||
icon: {
|
||||
fontSize: 18,
|
||||
@@ -41,14 +60,56 @@ export const styles = {
|
||||
scrollView: { paddingTop: marginsSize },
|
||||
};
|
||||
|
||||
const behaviorsHelpLink = getHelpLink('/behaviors');
|
||||
|
||||
const noRefreshOfAllFields = () => {
|
||||
console.warn(
|
||||
"An instance tried to refresh all fields, but the editor doesn't support it."
|
||||
);
|
||||
};
|
||||
|
||||
export const StatefulCollapsibleSubPanel = ({
|
||||
renderContent,
|
||||
isInitiallyFolded,
|
||||
onToggleFolded,
|
||||
title,
|
||||
titleIcon,
|
||||
titleBarButtons,
|
||||
}: {|
|
||||
renderContent: () => React.Node,
|
||||
isInitiallyFolded: boolean,
|
||||
onToggleFolded?: () => void,
|
||||
titleIcon?: ?React.Node,
|
||||
title: string,
|
||||
titleBarButtons?: Array<TitleBarButton>,
|
||||
|}) => {
|
||||
const [isFolded, setIsFolded] = React.useState(isInitiallyFolded);
|
||||
|
||||
const toggleFolded = React.useCallback(
|
||||
() => {
|
||||
setIsFolded(isFolded => !isFolded);
|
||||
if (onToggleFolded) {
|
||||
onToggleFolded();
|
||||
}
|
||||
},
|
||||
[onToggleFolded]
|
||||
);
|
||||
|
||||
return (
|
||||
<CollapsibleSubPanel
|
||||
renderContent={renderContent}
|
||||
isFolded={isFolded}
|
||||
toggleFolded={toggleFolded}
|
||||
title={title}
|
||||
titleIcon={titleIcon}
|
||||
titleBarButtons={titleBarButtons}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
type Props = {|
|
||||
project: gdProject,
|
||||
resourceManagementProps: ResourceManagementProps,
|
||||
layout?: ?gdLayout,
|
||||
objectsContainer: gdObjectsContainer,
|
||||
globalObjectsContainer: gdObjectsContainer | null,
|
||||
@@ -65,12 +126,14 @@ type Props = {|
|
||||
tileMapTileSelection: ?TileMapTileSelection,
|
||||
onSelectTileMapTile: (?TileMapTileSelection) => void,
|
||||
isVariableListLocked: boolean,
|
||||
canOverrideBehaviorProperties: boolean,
|
||||
|};
|
||||
|
||||
export const CompactInstancePropertiesEditor = ({
|
||||
instances,
|
||||
i18n,
|
||||
project,
|
||||
resourceManagementProps,
|
||||
layout,
|
||||
objectsContainer,
|
||||
globalObjectsContainer,
|
||||
@@ -85,12 +148,13 @@ export const CompactInstancePropertiesEditor = ({
|
||||
tileMapTileSelection,
|
||||
onSelectTileMapTile,
|
||||
isVariableListLocked,
|
||||
canOverrideBehaviorProperties,
|
||||
}: Props) => {
|
||||
const forceUpdate = useForceUpdate();
|
||||
const instance = instances[0];
|
||||
const variablesListRef = React.useRef<?VariablesListInterface>(null);
|
||||
|
||||
const scrollViewRef = React.useRef<?ScrollViewInterface>(null);
|
||||
const instance = instances[0];
|
||||
/**
|
||||
* TODO: multiple instances support for variables list. Expected behavior should be:
|
||||
* - if instances of different objects, do not show
|
||||
@@ -105,12 +169,18 @@ export const CompactInstancePropertiesEditor = ({
|
||||
}
|
||||
}, []);
|
||||
|
||||
const { object, instanceSchema } = React.useMemo<{|
|
||||
const { object, instanceSchema, allVisibleBehaviors } = React.useMemo<{|
|
||||
object?: gdObject,
|
||||
instanceSchema?: Schema,
|
||||
allVisibleBehaviors: Array<string>,
|
||||
|}>(
|
||||
() => {
|
||||
if (!instance) return { object: undefined, instanceSchema: undefined };
|
||||
if (!instance)
|
||||
return {
|
||||
object: undefined,
|
||||
instanceSchema: undefined,
|
||||
allVisibleBehaviors: [],
|
||||
};
|
||||
|
||||
const associatedObjectName = instance.getObjectName();
|
||||
const object = getObjectByName(
|
||||
@@ -122,7 +192,21 @@ export const CompactInstancePropertiesEditor = ({
|
||||
globalObjectsContainer || objectsContainer,
|
||||
objectsContainer
|
||||
);
|
||||
if (!object) return { object: undefined, instanceSchema: undefined };
|
||||
if (!object)
|
||||
return {
|
||||
object: undefined,
|
||||
instanceSchema: undefined,
|
||||
allVisibleBehaviors: [],
|
||||
};
|
||||
|
||||
const allVisibleBehaviors = object
|
||||
.getAllBehaviorNames()
|
||||
.toJSArray()
|
||||
.map(behaviorName => object.getBehavior(behaviorName))
|
||||
.filter(behavior => !behavior.isDefaultBehavior())
|
||||
// We don't keep the behaviors directly because they may be destroyed
|
||||
// if the object is rebuilt from a serialization.
|
||||
.map(behavior => behavior.getName());
|
||||
|
||||
const objectMetadata = gd.MetadataProvider.getObjectMetadata(
|
||||
project.getCurrentPlatform(),
|
||||
@@ -142,11 +226,14 @@ export const CompactInstancePropertiesEditor = ({
|
||||
properties,
|
||||
// We can't access default values for instance custom properties.
|
||||
defaultValueProperties: null,
|
||||
getProperties: (instance: gdInitialInstance) =>
|
||||
instance.getCustomProperties(
|
||||
globalObjectsContainer || objectsContainer,
|
||||
objectsContainer
|
||||
),
|
||||
getPropertyValue: (instance: gdInitialInstance, name: string) =>
|
||||
instance
|
||||
.getCustomProperties(
|
||||
globalObjectsContainer || objectsContainer,
|
||||
objectsContainer
|
||||
)
|
||||
.get(name)
|
||||
.getValue(),
|
||||
onUpdateProperty: (instance: gdInitialInstance, name, value) =>
|
||||
instance.updateCustomProperty(
|
||||
name,
|
||||
@@ -174,6 +261,7 @@ export const CompactInstancePropertiesEditor = ({
|
||||
return {
|
||||
object,
|
||||
instanceSchema,
|
||||
allVisibleBehaviors,
|
||||
};
|
||||
},
|
||||
[
|
||||
@@ -189,6 +277,10 @@ export const CompactInstancePropertiesEditor = ({
|
||||
]
|
||||
);
|
||||
|
||||
const [isBehaviorsFolded, setIsBehaviorsFolded] = React.useState(
|
||||
object ? !instance.hasAnyOverriddenProperty(object) : true
|
||||
);
|
||||
|
||||
const shouldDisplayTileSetVisualizer =
|
||||
!!object && object.getType() === 'TileMap::SimpleTileMap';
|
||||
|
||||
@@ -263,6 +355,113 @@ export const CompactInstancePropertiesEditor = ({
|
||||
</Column>
|
||||
</>
|
||||
)}
|
||||
{object && canOverrideBehaviorProperties ? (
|
||||
<TopLevelCollapsibleSection
|
||||
title={<Trans>Behaviors</Trans>}
|
||||
isFolded={isBehaviorsFolded}
|
||||
toggleFolded={() => setIsBehaviorsFolded(!isBehaviorsFolded)}
|
||||
renderContent={() => (
|
||||
<ColumnStackLayout noMargin>
|
||||
{!allVisibleBehaviors.length && (
|
||||
<Text size="body2" align="center" color="secondary">
|
||||
<Trans>
|
||||
There are no{' '}
|
||||
<Link
|
||||
href={behaviorsHelpLink}
|
||||
onClick={() =>
|
||||
Window.openExternalURL(behaviorsHelpLink)
|
||||
}
|
||||
>
|
||||
behaviors
|
||||
</Link>{' '}
|
||||
on this object instance.
|
||||
</Trans>
|
||||
</Text>
|
||||
)}
|
||||
{allVisibleBehaviors.map(behaviorName => {
|
||||
const behavior = object.getBehavior(behaviorName);
|
||||
const behaviorTypeName = behavior.getTypeName();
|
||||
const behaviorMetadata = gd.MetadataProvider.getBehaviorMetadata(
|
||||
gd.JsPlatform.get(),
|
||||
behaviorTypeName
|
||||
);
|
||||
const behaviorOverriding = instance.hasBehaviorOverridingNamed(
|
||||
behaviorName
|
||||
)
|
||||
? instance.getBehaviorOverriding(behaviorName)
|
||||
: null;
|
||||
|
||||
const iconUrl = behaviorMetadata.getIconFilename();
|
||||
|
||||
return (
|
||||
<StatefulCollapsibleSubPanel
|
||||
key={behavior.ptr}
|
||||
renderContent={
|
||||
notOverridableBehaviorTypes.includes(
|
||||
behavior.getTypeName()
|
||||
)
|
||||
? () => (
|
||||
<Column expand>
|
||||
<EmptyMessage>
|
||||
<Trans>
|
||||
This behavior can't be setup per instance.
|
||||
</Trans>
|
||||
</EmptyMessage>
|
||||
</Column>
|
||||
)
|
||||
: () => (
|
||||
<CompactBehaviorPropertiesEditor
|
||||
project={project}
|
||||
behaviorMetadata={behaviorMetadata}
|
||||
behavior={behavior}
|
||||
behaviorOverriding={behaviorOverriding}
|
||||
object={object}
|
||||
initialInstance={instance}
|
||||
onBehaviorUpdated={() => {
|
||||
if (
|
||||
instance.hasBehaviorOverridingNamed(
|
||||
behaviorName
|
||||
) &&
|
||||
!instance.hasAnyOverriddenPropertyForBehavior(
|
||||
behavior
|
||||
)
|
||||
) {
|
||||
instance.removeBehaviorOverriding(
|
||||
behaviorName
|
||||
);
|
||||
// Update the view to stop using
|
||||
// the removed behavior overriding.
|
||||
forceUpdate();
|
||||
}
|
||||
}}
|
||||
resourceManagementProps={
|
||||
resourceManagementProps
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
isInitiallyFolded={
|
||||
!instance.hasAnyOverriddenPropertyForBehavior(
|
||||
behavior
|
||||
)
|
||||
}
|
||||
titleIcon={
|
||||
iconUrl ? (
|
||||
<IconContainer
|
||||
src={iconUrl}
|
||||
alt={behaviorMetadata.getFullName()}
|
||||
size={16}
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
title={behavior.getName()}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</ColumnStackLayout>
|
||||
)}
|
||||
/>
|
||||
) : null}
|
||||
{object && shouldDisplayVariablesList ? (
|
||||
<>
|
||||
<Separator />
|
||||
|
||||
@@ -6,12 +6,14 @@ import { type InstancesEditorSettings } from './InstancesEditorSettings';
|
||||
const gd: libGDevelop = global.gd;
|
||||
|
||||
export const addSerializedInstances = ({
|
||||
project,
|
||||
instancesContainer,
|
||||
copyReferential,
|
||||
serializedInstances,
|
||||
addInstancesInTheForeground = false,
|
||||
doesObjectExistInContext,
|
||||
}: {|
|
||||
project: gdProject,
|
||||
instancesContainer: gdInitialInstancesContainer,
|
||||
copyReferential: [number, number],
|
||||
serializedInstances: Array<Object>,
|
||||
@@ -29,7 +31,12 @@ export const addSerializedInstances = ({
|
||||
const newInstances = serializedInstances
|
||||
.map(serializedInstance => {
|
||||
const instance = new gd.InitialInstance();
|
||||
unserializeFromJSObject(instance, serializedInstance);
|
||||
unserializeFromJSObject(
|
||||
instance,
|
||||
serializedInstance,
|
||||
'unserializeFrom',
|
||||
project
|
||||
);
|
||||
if (!doesObjectExistInContext(instance.getObjectName())) return null;
|
||||
instance.setX(instance.getX() - copyReferential[0]);
|
||||
instance.setY(instance.getY() - copyReferential[1]);
|
||||
@@ -65,6 +72,7 @@ export const addSerializedInstances = ({
|
||||
};
|
||||
|
||||
type Props = {|
|
||||
project: gdProject,
|
||||
instances: gdInitialInstancesContainer,
|
||||
instancesEditorSettings: InstancesEditorSettings,
|
||||
|};
|
||||
@@ -74,12 +82,14 @@ type Props = {|
|
||||
* which are real instances but can be deleted as long as they are not "committed".
|
||||
*/
|
||||
export default class InstancesAdder {
|
||||
_project: gdProject;
|
||||
_instances: gdInitialInstancesContainer;
|
||||
_temporaryInstances: Array<gdInitialInstance>;
|
||||
_instancesEditorSettings: InstancesEditorSettings;
|
||||
_zOrderFinder = new gd.HighestZOrderFinder();
|
||||
|
||||
constructor({ instances, instancesEditorSettings }: Props) {
|
||||
constructor({ project, instances, instancesEditorSettings }: Props) {
|
||||
this._project = project;
|
||||
this._instances = instances;
|
||||
this._instancesEditorSettings = instancesEditorSettings;
|
||||
this._temporaryInstances = [];
|
||||
@@ -103,6 +113,7 @@ export default class InstancesAdder {
|
||||
doesObjectExistInContext: string => boolean,
|
||||
|}): Array<gdInitialInstance> => {
|
||||
const instances = addSerializedInstances({
|
||||
project: this._project,
|
||||
instancesContainer: this._instances,
|
||||
copyReferential,
|
||||
serializedInstances,
|
||||
|
||||
@@ -431,6 +431,7 @@ export default class InstancesEditor extends Component<Props, State> {
|
||||
});
|
||||
|
||||
this._instancesAdder = new InstancesAdder({
|
||||
project: this.props.project,
|
||||
instances: this.props.initialInstances,
|
||||
instancesEditorSettings: this.props.instancesEditorSettings,
|
||||
});
|
||||
|
||||
+5
-2
@@ -59,8 +59,11 @@ export const ChildObjectPropertiesEditor = ({
|
||||
return propertiesMapToSchema({
|
||||
properties: childObjectConfigurationAsGd.getProperties(),
|
||||
defaultValueProperties: null,
|
||||
getProperties: ({ object, objectConfiguration }) =>
|
||||
objectConfiguration.getProperties(),
|
||||
getPropertyValue: ({ object, objectConfiguration }, name) =>
|
||||
objectConfiguration
|
||||
.getProperties()
|
||||
.get(name)
|
||||
.getValue(),
|
||||
onUpdateProperty: ({ object, objectConfiguration }, name, value) =>
|
||||
objectConfiguration.updateProperty(name, value),
|
||||
visibility: 'All',
|
||||
|
||||
+83
-12
@@ -59,6 +59,8 @@ export const CompactBehaviorPropertiesEditor = ({
|
||||
behaviorMetadata,
|
||||
behavior,
|
||||
object,
|
||||
behaviorOverriding,
|
||||
initialInstance,
|
||||
onOpenFullEditor,
|
||||
onBehaviorUpdated,
|
||||
resourceManagementProps,
|
||||
@@ -67,7 +69,9 @@ export const CompactBehaviorPropertiesEditor = ({
|
||||
behaviorMetadata: gdBehaviorMetadata,
|
||||
behavior: gdBehavior,
|
||||
object: gdObject,
|
||||
onOpenFullEditor: () => void,
|
||||
behaviorOverriding: gdBehavior | null,
|
||||
initialInstance: gdInitialInstance | null,
|
||||
onOpenFullEditor?: () => void,
|
||||
onBehaviorUpdated: () => void,
|
||||
resourceManagementProps: ResourceManagementProps,
|
||||
|}) => {
|
||||
@@ -80,10 +84,67 @@ export const CompactBehaviorPropertiesEditor = ({
|
||||
if (schemaRecomputeTrigger) {
|
||||
// schemaRecomputeTrigger allows to invalidate the schema when required.
|
||||
}
|
||||
if (initialInstance) {
|
||||
const behaviorProperties = behavior.getProperties();
|
||||
return propertiesMapToSchema({
|
||||
properties: behaviorProperties,
|
||||
defaultValueProperties: behaviorProperties,
|
||||
getPropertyValue: (instance, propertyName) => {
|
||||
const behaviorName = behavior.getName();
|
||||
if (
|
||||
initialInstance.hasBehaviorOverridingNamed(behaviorName) &&
|
||||
initialInstance
|
||||
.getBehaviorOverriding(behaviorName)
|
||||
.hasPropertyValue(propertyName)
|
||||
) {
|
||||
const behaviorOverriding = initialInstance.getBehaviorOverriding(
|
||||
behaviorName
|
||||
);
|
||||
return behaviorOverriding
|
||||
.getProperties()
|
||||
.get(propertyName)
|
||||
.getValue();
|
||||
}
|
||||
return behavior
|
||||
.getProperties()
|
||||
.get(propertyName)
|
||||
.getValue();
|
||||
},
|
||||
onUpdateProperty: (instance, name, value) => {
|
||||
const behaviorName = behavior.getName();
|
||||
const behaviorOverriding = initialInstance.hasBehaviorOverridingNamed(
|
||||
behaviorName
|
||||
)
|
||||
? initialInstance.getBehaviorOverriding(behaviorName)
|
||||
: initialInstance.addNewBehaviorOverriding(
|
||||
project,
|
||||
behavior.getTypeName(),
|
||||
behaviorName
|
||||
);
|
||||
const behaviorProperties = behavior.getProperties();
|
||||
const inheritedValue = behaviorProperties.has(name)
|
||||
? behaviorProperties.get(name).getValue()
|
||||
: null;
|
||||
if (inheritedValue === value) {
|
||||
behaviorOverriding.removeProperty(name);
|
||||
} else {
|
||||
behaviorOverriding.updateProperty(name, value);
|
||||
}
|
||||
},
|
||||
object,
|
||||
visibility: 'All',
|
||||
showcaseNonDefaultValues: true,
|
||||
});
|
||||
}
|
||||
const behaviorMetadataProperties = behaviorMetadata.getProperties();
|
||||
return propertiesMapToSchema({
|
||||
properties: behavior.getProperties(),
|
||||
defaultValueProperties: behaviorMetadata.getProperties(),
|
||||
getProperties: instance => instance.getProperties(),
|
||||
properties: behaviorMetadataProperties,
|
||||
defaultValueProperties: behaviorMetadataProperties,
|
||||
getPropertyValue: (instance, name) =>
|
||||
instance
|
||||
.getProperties()
|
||||
.get(name)
|
||||
.getValue(),
|
||||
onUpdateProperty: (instance, name, value) => {
|
||||
instance.updateProperty(name, value);
|
||||
},
|
||||
@@ -91,7 +152,14 @@ export const CompactBehaviorPropertiesEditor = ({
|
||||
visibility: 'All',
|
||||
});
|
||||
},
|
||||
[schemaRecomputeTrigger, behavior, behaviorMetadata, object]
|
||||
[
|
||||
schemaRecomputeTrigger,
|
||||
initialInstance,
|
||||
behavior,
|
||||
behaviorMetadata,
|
||||
object,
|
||||
project,
|
||||
]
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -104,13 +172,16 @@ export const CompactBehaviorPropertiesEditor = ({
|
||||
onInstancesModified={onBehaviorUpdated}
|
||||
resourceManagementProps={resourceManagementProps}
|
||||
placeholder={<Trans>Nothing to configure for this behavior.</Trans>}
|
||||
customizeBasicSchema={schema =>
|
||||
getSchemaWithOpenFullEditorButton({
|
||||
schema,
|
||||
fullEditorLabel,
|
||||
behavior,
|
||||
onOpenFullEditor,
|
||||
})
|
||||
customizeBasicSchema={
|
||||
onOpenFullEditor
|
||||
? schema =>
|
||||
getSchemaWithOpenFullEditorButton({
|
||||
schema,
|
||||
fullEditorLabel,
|
||||
behavior,
|
||||
onOpenFullEditor,
|
||||
})
|
||||
: null
|
||||
}
|
||||
onRefreshAllFields={forceRecomputeSchema}
|
||||
/>
|
||||
|
||||
@@ -89,14 +89,14 @@ const objectVariablesHelpLink = getHelpLink(
|
||||
'/all-features/variables/object-variables'
|
||||
);
|
||||
|
||||
type TitleBarButton = {|
|
||||
export type TitleBarButton = {|
|
||||
id: string,
|
||||
icon: any,
|
||||
label?: MessageDescriptor,
|
||||
onClick?: () => void,
|
||||
|};
|
||||
|
||||
const CollapsibleSubPanel = ({
|
||||
export const CollapsibleSubPanel = ({
|
||||
renderContent,
|
||||
isFolded,
|
||||
toggleFolded,
|
||||
@@ -157,7 +157,7 @@ const CollapsibleSubPanel = ({
|
||||
</Paper>
|
||||
);
|
||||
|
||||
const TopLevelCollapsibleSection = ({
|
||||
export const TopLevelCollapsibleSection = ({
|
||||
title,
|
||||
isFolded,
|
||||
toggleFolded,
|
||||
@@ -173,7 +173,7 @@ const TopLevelCollapsibleSection = ({
|
||||
renderContent: () => React.Node,
|
||||
renderContentAsHiddenWhenFolded?: boolean,
|
||||
noContentMargin?: boolean,
|
||||
onOpenFullEditor: () => void,
|
||||
onOpenFullEditor?: () => void,
|
||||
onAdd?: (() => void) | null,
|
||||
|}) => (
|
||||
<>
|
||||
@@ -193,9 +193,11 @@ const TopLevelCollapsibleSection = ({
|
||||
</Text>
|
||||
</LineStackLayout>
|
||||
<Line alignItems="center" noMargin>
|
||||
<IconButton size="small" onClick={onOpenFullEditor}>
|
||||
<ShareExternal style={styles.icon} />
|
||||
</IconButton>
|
||||
{onOpenFullEditor && (
|
||||
<IconButton size="small" onClick={onOpenFullEditor}>
|
||||
<ShareExternal style={styles.icon} />
|
||||
</IconButton>
|
||||
)}
|
||||
{onAdd && (
|
||||
<IconButton size="small" onClick={onAdd}>
|
||||
<Add style={styles.icon} />
|
||||
@@ -492,8 +494,11 @@ export const CompactObjectPropertiesEditor = ({
|
||||
? customObjectEventsBasedObject.getPropertyDescriptors()
|
||||
: // We can't access default values for built-in objects.
|
||||
null,
|
||||
getProperties: ({ objectConfiguration }) =>
|
||||
objectConfiguration.getProperties(),
|
||||
getPropertyValue: ({ objectConfiguration }, name) =>
|
||||
objectConfiguration
|
||||
.getProperties()
|
||||
.get(name)
|
||||
.getValue(),
|
||||
onUpdateProperty: ({ objectConfiguration }, name, value) => {
|
||||
objectConfiguration.updateProperty(name, value);
|
||||
onObjectsModified([object]);
|
||||
@@ -749,6 +754,8 @@ export const CompactObjectPropertiesEditor = ({
|
||||
project={project}
|
||||
behaviorMetadata={behaviorMetadata}
|
||||
behavior={behavior}
|
||||
behaviorOverriding={null}
|
||||
initialInstance={null}
|
||||
object={object}
|
||||
onBehaviorUpdated={() => {}}
|
||||
resourceManagementProps={resourceManagementProps}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user