mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
23 Commits
remove-fra
...
v5.0.141
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c6c586459c | ||
![]() |
a930011d8d | ||
![]() |
51d723bd3d | ||
![]() |
b63f968011 | ||
![]() |
3387c553d8 | ||
![]() |
441cd20846 | ||
![]() |
f9871bd63d | ||
![]() |
bac11b3818 | ||
![]() |
3e32cb8cea | ||
![]() |
db74a59730 | ||
![]() |
e7d09531b7 | ||
![]() |
97cf19180b | ||
![]() |
5cc999c0a3 | ||
![]() |
5eb0aa9e14 | ||
![]() |
7f528649d7 | ||
![]() |
c4f44daa8c | ||
![]() |
7d00e78628 | ||
![]() |
887ced270a | ||
![]() |
b8e9bc801a | ||
![]() |
7f023e1a58 | ||
![]() |
6606ddb260 | ||
![]() |
a682c1baa8 | ||
![]() |
d581af20e1 |
@@ -28,7 +28,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Movement using forces"))
|
||||
.SetIcon("res/actions/force24.png");
|
||||
|
||||
gd::ObjectMetadata& obj = extension.AddObject<gd::Object>(
|
||||
gd::ObjectMetadata& obj = extension.AddObject<gd::ObjectConfiguration>(
|
||||
"", _("Base object"), _("Base object"), "res/objeticon24.png");
|
||||
|
||||
obj.AddCondition("PosX",
|
||||
|
@@ -25,8 +25,7 @@ namespace gd {
|
||||
|
||||
Animation SpriteObject::badAnimation;
|
||||
|
||||
SpriteObject::SpriteObject(gd::String name_)
|
||||
: Object(name_), updateIfNotVisible(false) {}
|
||||
SpriteObject::SpriteObject() : updateIfNotVisible(false) {}
|
||||
|
||||
SpriteObject::~SpriteObject(){};
|
||||
|
||||
|
@@ -36,11 +36,11 @@ namespace gd {
|
||||
* \see gd::BuiltinExtensionsImplementer::ImplementsSpriteExtension
|
||||
* \ingroup SpriteObjectExtension
|
||||
*/
|
||||
class GD_CORE_API SpriteObject : public gd::Object {
|
||||
class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
|
||||
public:
|
||||
SpriteObject(gd::String name_);
|
||||
SpriteObject();
|
||||
virtual ~SpriteObject();
|
||||
std::unique_ptr<gd::Object> Clone() const override {
|
||||
std::unique_ptr<gd::ObjectConfiguration> Clone() const override {
|
||||
return gd::make_unique<SpriteObject>(*this);
|
||||
}
|
||||
|
||||
|
@@ -23,23 +23,20 @@ ObjectMetadata::ObjectMetadata(const gd::String& extensionNamespace_,
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& icon24x24,
|
||||
std::shared_ptr<gd::Object> blueprintObject_)
|
||||
std::shared_ptr<gd::ObjectConfiguration> blueprintObject_)
|
||||
: ObjectMetadata(extensionNamespace_,
|
||||
name_,
|
||||
fullname_,
|
||||
description_,
|
||||
icon24x24,
|
||||
[blueprintObject_](gd::String name) -> std::unique_ptr<gd::Object> {
|
||||
if (blueprintObject_ == std::shared_ptr<gd::Object>()) {
|
||||
[blueprintObject_]() -> std::unique_ptr<gd::ObjectConfiguration> {
|
||||
if (blueprintObject_ == std::shared_ptr<gd::ObjectConfiguration>()) {
|
||||
gd::LogFatalError(
|
||||
"Error: Unable to create object. Have you declared an extension "
|
||||
"(or ObjectMetadata) without specifying an object as blueprint?");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<gd::Object> newObject = blueprintObject_->Clone();
|
||||
newObject->SetName(name);
|
||||
return newObject;
|
||||
return blueprintObject_->Clone();
|
||||
}) {
|
||||
blueprintObject = blueprintObject_;
|
||||
}
|
||||
@@ -54,7 +51,7 @@ ObjectMetadata::ObjectMetadata(const gd::String& extensionNamespace_,
|
||||
fullname_,
|
||||
description_,
|
||||
icon24x24,
|
||||
[](gd::String name) -> std::unique_ptr<gd::Object> {
|
||||
[]() -> std::unique_ptr<gd::ObjectConfiguration> {
|
||||
gd::LogFatalError(
|
||||
"Error: Event-based objects don't have blueprint. "
|
||||
"This method should not never be called.");
|
||||
|
@@ -13,6 +13,7 @@
|
||||
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class InstructionMetadata;
|
||||
@@ -20,7 +21,7 @@ class MultipleInstructionMetadata;
|
||||
class ExpressionMetadata;
|
||||
} // namespace gd
|
||||
|
||||
typedef std::function<std::unique_ptr<gd::Object>(gd::String name)>
|
||||
typedef std::function<std::unique_ptr<gd::ObjectConfiguration>()>
|
||||
CreateFunPtr;
|
||||
|
||||
namespace gd {
|
||||
@@ -42,7 +43,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& icon24x24_,
|
||||
std::shared_ptr<gd::Object> blueprintObject_);
|
||||
std::shared_ptr<gd::ObjectConfiguration> blueprintObject_);
|
||||
/**
|
||||
* \brief Construct an object metadata, without "blueprint" object
|
||||
*
|
||||
@@ -314,7 +315,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
gd::String categoryFullName;
|
||||
std::set<gd::String> unsupportedBaseObjectCapabilities;
|
||||
|
||||
std::shared_ptr<gd::Object>
|
||||
std::shared_ptr<gd::ObjectConfiguration>
|
||||
blueprintObject; ///< The "blueprint" object to be copied when a new
|
||||
///< object is asked. Can be null in case a creation
|
||||
///< function is passed or for events based objects
|
||||
|
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
|
||||
@@ -92,8 +93,8 @@ std::shared_ptr<gd::PlatformExtension> Platform::GetExtension(
|
||||
return std::shared_ptr<gd::PlatformExtension>();
|
||||
}
|
||||
|
||||
std::unique_ptr<gd::Object> Platform::CreateObject(
|
||||
gd::String type, const gd::String& name) const {
|
||||
std::unique_ptr<gd::ObjectConfiguration> Platform::CreateObjectConfiguration(
|
||||
gd::String type) const {
|
||||
if (creationFunctionTable.find(type) == creationFunctionTable.end()) {
|
||||
gd::LogWarning("Tried to create an object with an unknown type: " + type
|
||||
+ " for platform " + GetName() + "!");
|
||||
@@ -105,11 +106,9 @@ std::unique_ptr<gd::Object> Platform::CreateObject(
|
||||
}
|
||||
|
||||
// Create a new object with the type we want.
|
||||
std::unique_ptr<gd::Object> object =
|
||||
(creationFunctionTable.find(type)->second)(name);
|
||||
object->SetType(type);
|
||||
|
||||
return std::unique_ptr<gd::Object>(std::move(object));
|
||||
auto objectConfiguration = (creationFunctionTable.find(type)->second)();
|
||||
objectConfiguration->SetType(type);
|
||||
return objectConfiguration;
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
|
@@ -16,6 +16,7 @@ namespace gd {
|
||||
class InstructionsMetadataHolder;
|
||||
class Project;
|
||||
class Object;
|
||||
class ObjectConfiguration;
|
||||
class Behavior;
|
||||
class BehaviorMetadata;
|
||||
class ObjectMetadata;
|
||||
@@ -26,7 +27,7 @@ class LayoutEditorCanvas;
|
||||
class ProjectExporter;
|
||||
} // namespace gd
|
||||
|
||||
typedef std::function<std::unique_ptr<gd::Object>(gd::String name)>
|
||||
typedef std::function<std::unique_ptr<gd::ObjectConfiguration>()>
|
||||
CreateFunPtr;
|
||||
|
||||
#undef CreateEvent
|
||||
@@ -146,8 +147,8 @@ class GD_CORE_API Platform {
|
||||
/**
|
||||
* \brief Create an object of given type with the specified name.
|
||||
*/
|
||||
std::unique_ptr<gd::Object> CreateObject(gd::String type,
|
||||
const gd::String& name) const;
|
||||
std::unique_ptr<gd::ObjectConfiguration> CreateObjectConfiguration(
|
||||
gd::String type) const;
|
||||
|
||||
/**
|
||||
* \brief Create an event of given type
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/IDE/PlatformManager.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
@@ -231,7 +232,7 @@ gd::ObjectMetadata& PlatformExtension::AddObject(
|
||||
const gd::String& fullname,
|
||||
const gd::String& description,
|
||||
const gd::String& icon24x24,
|
||||
std::shared_ptr<gd::Object> instance) {
|
||||
std::shared_ptr<gd::ObjectConfiguration> instance) {
|
||||
gd::String nameWithNamespace = GetNameSpace() + name;
|
||||
objectsInfos[nameWithNamespace] = ObjectMetadata(GetNameSpace(),
|
||||
nameWithNamespace,
|
||||
|
@@ -37,9 +37,10 @@ class ArbitraryResourceWorker;
|
||||
class BehaviorsSharedData;
|
||||
class Behavior;
|
||||
class Object;
|
||||
class ObjectConfiguration;
|
||||
} // namespace gd
|
||||
|
||||
typedef std::function<std::unique_ptr<gd::Object>(gd::String name)>
|
||||
typedef std::function<std::unique_ptr<gd::ObjectConfiguration>()>
|
||||
CreateFunPtr;
|
||||
|
||||
namespace gd {
|
||||
@@ -242,7 +243,7 @@ class GD_CORE_API PlatformExtension {
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& icon_,
|
||||
std::shared_ptr<gd::Object> instance);
|
||||
std::shared_ptr<gd::ObjectConfiguration> instance);
|
||||
|
||||
/**
|
||||
* \brief Declare a new events based object as being part of the extension.
|
||||
|
@@ -25,8 +25,8 @@ gd::ObjectMetadata& PlatformExtension::AddObject(const gd::String& name,
|
||||
fullname,
|
||||
description,
|
||||
icon24x24,
|
||||
[](gd::String name) -> std::unique_ptr<gd::Object> {
|
||||
return gd::make_unique<T>(name);
|
||||
[]() -> std::unique_ptr<gd::ObjectConfiguration> {
|
||||
return gd::make_unique<T>();
|
||||
})
|
||||
.SetHelpPath(GetHelpPath());
|
||||
|
||||
|
@@ -1628,19 +1628,18 @@ void WholeProjectRefactorer::ObjectOrGroupRemovedInEventsFunction(
|
||||
|
||||
void WholeProjectRefactorer::ObjectOrGroupRenamedInEventsBasedObject(
|
||||
gd::Project& project,
|
||||
gd::EventsBasedObject& eventsBasedObject,
|
||||
gd::ObjectsContainer& globalObjectsContainer,
|
||||
gd::ObjectsContainer& objectsContainer,
|
||||
gd::EventsBasedObject& eventsBasedObject,
|
||||
const gd::String& oldName,
|
||||
const gd::String& newName,
|
||||
bool isObjectGroup) {
|
||||
for (auto &functionUniquePtr : eventsBasedObject.GetEventsFunctions().GetInternalVector()) {
|
||||
auto function = functionUniquePtr.get();
|
||||
auto *function = functionUniquePtr.get();
|
||||
WholeProjectRefactorer::ObjectOrGroupRenamedInEventsFunction(
|
||||
project,
|
||||
*function,
|
||||
globalObjectsContainer,
|
||||
objectsContainer,
|
||||
eventsBasedObject,
|
||||
oldName,
|
||||
newName,
|
||||
isObjectGroup);
|
||||
|
@@ -333,9 +333,8 @@ class GD_CORE_API WholeProjectRefactorer {
|
||||
*/
|
||||
static void ObjectOrGroupRenamedInEventsBasedObject(
|
||||
gd::Project& project,
|
||||
gd::EventsBasedObject& eventsBasedObject,
|
||||
gd::ObjectsContainer& globalObjectsContainer,
|
||||
gd::ObjectsContainer& objectsContainer,
|
||||
gd::EventsBasedObject& eventsBasedObject,
|
||||
const gd::String& oldName,
|
||||
const gd::String& newName,
|
||||
bool isObjectGroup);
|
||||
|
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "CustomBehavior.h"
|
||||
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
@@ -99,7 +104,7 @@ void CustomBehavior::InitializeContent(gd::SerializerElement &behaviorContent) {
|
||||
const auto &eventsBasedBehavior = project.GetEventsBasedBehavior(GetTypeName());
|
||||
const auto &properties = eventsBasedBehavior.GetPropertyDescriptors();
|
||||
for (auto &&property : properties.GetInternalVector()) {
|
||||
auto element = behaviorContent.AddChild(property->GetName());
|
||||
auto &element = behaviorContent.AddChild(property->GetName());
|
||||
auto propertyType = property->GetType();
|
||||
|
||||
if (propertyType == "String" || propertyType == "Choice" ||
|
||||
|
@@ -1,3 +1,11 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef GDCORE_CUSTOMBEHAVIOR_H
|
||||
#define GDCORE_CUSTOMBEHAVIOR_H
|
||||
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/EventsBasedBehavior.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
@@ -7,6 +15,7 @@
|
||||
|
||||
using namespace gd;
|
||||
|
||||
namespace gd {
|
||||
/**
|
||||
* \brief A gd::Behavior that stores its content in JSON and forward the
|
||||
* properties related functions to Javascript with Emscripten.
|
||||
@@ -37,3 +46,6 @@ private:
|
||||
const Project &project; ///< The project is used to get the
|
||||
///< EventBasedBehavior from the fullType.
|
||||
};
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_CUSTOMBEHAVIOR_H
|
@@ -1,49 +0,0 @@
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/EventsBasedObject.h"
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
||||
using namespace gd;
|
||||
|
||||
/**
|
||||
* \brief A gd::Object that stores its content in JSON and forward the
|
||||
* properties related functions to Javascript with Emscripten.
|
||||
*
|
||||
* It also implements "ExposeResources" to expose the properties of type
|
||||
* "resource".
|
||||
*/
|
||||
class CustomObject : public gd::Object {
|
||||
public:
|
||||
CustomObject(const gd::String &name, const Project& project_, const gd::String &fullType)
|
||||
: Object(name),
|
||||
project(project_) {
|
||||
SetType(fullType);
|
||||
}
|
||||
std::unique_ptr<gd::Object> Clone() const override;
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetProperties() const override;
|
||||
bool UpdateProperty(const gd::String& name, const gd::String& value) override;
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetInitialInstanceProperties(
|
||||
const gd::InitialInstance& instance,
|
||||
gd::Project& project,
|
||||
gd::Layout& scene) override;
|
||||
bool UpdateInitialInstanceProperty(gd::InitialInstance& instance,
|
||||
const gd::String& name,
|
||||
const gd::String& value,
|
||||
gd::Project& project,
|
||||
gd::Layout& scene) override;
|
||||
|
||||
void ExposeResources(gd::ArbitraryResourceWorker& worker) override;
|
||||
|
||||
protected:
|
||||
void DoSerializeTo(SerializerElement& element) const override;
|
||||
void DoUnserializeFrom(Project& project, const SerializerElement& element) override;
|
||||
|
||||
private:
|
||||
const Project& project; ///< The project is used to get the
|
||||
///< EventBasedObject from the fullType.
|
||||
gd::SerializerElement objectContent;
|
||||
};
|
@@ -1,4 +1,9 @@
|
||||
#include "CustomObject.h"
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "CustomObjectConfiguration.h"
|
||||
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
@@ -6,27 +11,62 @@
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
||||
#include <map>
|
||||
#include "GDCore/Tools/Log.h"
|
||||
|
||||
using namespace gd;
|
||||
|
||||
std::unique_ptr<gd::Object> CustomObject::Clone() const {
|
||||
CustomObject* clone = new CustomObject(*this);
|
||||
return std::unique_ptr<gd::Object>(clone);
|
||||
void CustomObjectConfiguration::Init(const gd::CustomObjectConfiguration& objectConfiguration) {
|
||||
project = objectConfiguration.project;
|
||||
objectContent = objectConfiguration.objectContent;
|
||||
|
||||
// There is no default copy for a map of unique_ptr like childObjectConfigurations.
|
||||
childObjectConfigurations.clear();
|
||||
for (auto& it : objectConfiguration.childObjectConfigurations) {
|
||||
childObjectConfigurations[it.first] =
|
||||
gd::make_unique<gd::ObjectConfiguration>(*it.second);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO EBO Extract a class from Object for the object configuration.
|
||||
// This will allow CustomObject to have a ObjectConfiguration composed of
|
||||
// ObjectConfiguration for their children in addition to its own properties.
|
||||
// This will be used by the GUI to display custom editors (for sprites for
|
||||
// instance)
|
||||
std::map<gd::String, gd::PropertyDescriptor> CustomObject::GetProperties() const {
|
||||
gd::ObjectConfiguration CustomObjectConfiguration::badObjectConfiguration;
|
||||
|
||||
std::unique_ptr<gd::ObjectConfiguration> CustomObjectConfiguration::Clone() const {
|
||||
CustomObjectConfiguration* clone = new CustomObjectConfiguration(*this);
|
||||
return std::unique_ptr<gd::ObjectConfiguration>(clone);
|
||||
}
|
||||
|
||||
gd::ObjectConfiguration &CustomObjectConfiguration::GetChildObjectConfiguration(const gd::String &objectName) {
|
||||
if (!project->HasEventsBasedObject(GetType())) {
|
||||
return badObjectConfiguration;
|
||||
}
|
||||
const auto &eventsBasedObject = project->GetEventsBasedObject(GetType());
|
||||
|
||||
if (!eventsBasedObject.HasObjectNamed(objectName)) {
|
||||
gd::LogError("Tried to get the configuration of a child-object:" + objectName
|
||||
+ " that doesn't exist in the event-based object: " + GetType());
|
||||
return badObjectConfiguration;
|
||||
}
|
||||
|
||||
auto &childObject = eventsBasedObject.GetObject(objectName);
|
||||
auto configurationPosition = childObjectConfigurations.find(objectName);
|
||||
if (configurationPosition == childObjectConfigurations.end()) {
|
||||
childObjectConfigurations.insert(std::make_pair(
|
||||
objectName,
|
||||
project->CreateObjectConfiguration(childObject.GetType())));
|
||||
return *(childObjectConfigurations[objectName]);
|
||||
}
|
||||
else {
|
||||
auto &pair = *configurationPosition;
|
||||
auto &configuration = pair.second;
|
||||
return *configuration;
|
||||
}
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> CustomObjectConfiguration::GetProperties() const {
|
||||
auto objectProperties = std::map<gd::String, gd::PropertyDescriptor>();
|
||||
if (!project.HasEventsBasedObject(GetType())) {
|
||||
if (!project->HasEventsBasedObject(GetType())) {
|
||||
return objectProperties;
|
||||
}
|
||||
const auto &eventsBasedObject = project.GetEventsBasedObject(GetType());
|
||||
const auto &eventsBasedObject = project->GetEventsBasedObject(GetType());
|
||||
const auto &properties = eventsBasedObject.GetPropertyDescriptors();
|
||||
|
||||
for (auto &property : properties.GetInternalVector()) {
|
||||
@@ -75,12 +115,12 @@ std::map<gd::String, gd::PropertyDescriptor> CustomObject::GetProperties() const
|
||||
return objectProperties;
|
||||
}
|
||||
|
||||
bool CustomObject::UpdateProperty(const gd::String& propertyName,
|
||||
bool CustomObjectConfiguration::UpdateProperty(const gd::String& propertyName,
|
||||
const gd::String& newValue) {
|
||||
if (!project.HasEventsBasedObject(GetType())) {
|
||||
if (!project->HasEventsBasedObject(GetType())) {
|
||||
return false;
|
||||
}
|
||||
const auto &eventsBasedObject = project.GetEventsBasedObject(GetType());
|
||||
const auto &eventsBasedObject = project->GetEventsBasedObject(GetType());
|
||||
const auto &properties = eventsBasedObject.GetPropertyDescriptors();
|
||||
if (!properties.Has(propertyName)) {
|
||||
return false;
|
||||
@@ -106,14 +146,14 @@ bool CustomObject::UpdateProperty(const gd::String& propertyName,
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor>
|
||||
CustomObject::GetInitialInstanceProperties(
|
||||
CustomObjectConfiguration::GetInitialInstanceProperties(
|
||||
const gd::InitialInstance& instance,
|
||||
gd::Project& project,
|
||||
gd::Layout& scene) {
|
||||
return std::map<gd::String, gd::PropertyDescriptor>();
|
||||
}
|
||||
|
||||
bool CustomObject::UpdateInitialInstanceProperty(
|
||||
bool CustomObjectConfiguration::UpdateInitialInstanceProperty(
|
||||
gd::InitialInstance& instance,
|
||||
const gd::String& name,
|
||||
const gd::String& value,
|
||||
@@ -122,15 +162,29 @@ bool CustomObject::UpdateInitialInstanceProperty(
|
||||
return false;
|
||||
}
|
||||
|
||||
void CustomObject::DoSerializeTo(SerializerElement& arg0) const {
|
||||
arg0.AddChild("content") = objectContent;
|
||||
void CustomObjectConfiguration::DoSerializeTo(SerializerElement& element) const {
|
||||
element.AddChild("content") = objectContent;
|
||||
auto &childrenContentElement = element.AddChild("childrenContent");
|
||||
for (auto &pair : childObjectConfigurations) {
|
||||
auto &childName = pair.first;
|
||||
auto &childConfiguration = pair.second;
|
||||
auto &childElement = childrenContentElement.AddChild(childName);
|
||||
childConfiguration->SerializeTo(childElement);
|
||||
}
|
||||
}
|
||||
void CustomObject::DoUnserializeFrom(Project& arg0,
|
||||
const SerializerElement& arg1) {
|
||||
objectContent = arg1.GetChild("content");
|
||||
void CustomObjectConfiguration::DoUnserializeFrom(Project& project,
|
||||
const SerializerElement& element) {
|
||||
objectContent = element.GetChild("content");
|
||||
auto &childrenContentElement = element.GetChild("childrenContent");
|
||||
for (auto &pair : childrenContentElement.GetAllChildren()) {
|
||||
auto &childName = pair.first;
|
||||
auto &childElement = pair.second;
|
||||
auto &childConfiguration = GetChildObjectConfiguration(childName);
|
||||
childConfiguration.UnserializeFrom(project, *childElement);
|
||||
}
|
||||
}
|
||||
|
||||
void CustomObject::ExposeResources(
|
||||
void CustomObjectConfiguration::ExposeResources(
|
||||
gd::ArbitraryResourceWorker& worker) {
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties = GetProperties();
|
||||
|
||||
@@ -162,4 +216,15 @@ void CustomObject::ExposeResources(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto objectProperties = std::map<gd::String, gd::PropertyDescriptor>();
|
||||
if (!project->HasEventsBasedObject(GetType())) {
|
||||
return;
|
||||
}
|
||||
const auto &eventsBasedObject = project->GetEventsBasedObject(GetType());
|
||||
|
||||
for (auto& childObject : eventsBasedObject.GetObjects()) {
|
||||
auto &configuration = GetChildObjectConfiguration(childObject->GetName());
|
||||
configuration.ExposeResources(worker);
|
||||
}
|
||||
}
|
100
Core/GDCore/Project/CustomObjectConfiguration.h
Normal file
100
Core/GDCore/Project/CustomObjectConfiguration.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef GDCORE_CUSTOMOBJECTCONFIGURATION_H
|
||||
#define GDCORE_CUSTOMOBJECTCONFIGURATION_H
|
||||
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/EventsBasedObject.h"
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
||||
|
||||
using namespace gd;
|
||||
|
||||
namespace gd {
|
||||
/**
|
||||
* \brief A gd::ObjectConfiguration that stores its content in JSON and is
|
||||
* composed of other configuration according to it's object children.
|
||||
*
|
||||
* It also implements "ExposeResources" to expose the properties of type
|
||||
* "resource".
|
||||
*/
|
||||
class CustomObjectConfiguration : public gd::ObjectConfiguration {
|
||||
public:
|
||||
CustomObjectConfiguration(const Project& project_, const String& type_)
|
||||
: project(&project_) {
|
||||
SetType(type_);
|
||||
}
|
||||
std::unique_ptr<gd::ObjectConfiguration> Clone() const override;
|
||||
|
||||
/**
|
||||
* Copy constructor. Calls Init().
|
||||
*/
|
||||
CustomObjectConfiguration(const gd::CustomObjectConfiguration& object)
|
||||
: ObjectConfiguration(object) {
|
||||
Init(object);
|
||||
};
|
||||
|
||||
/**
|
||||
* Assignment operator. Calls Init().
|
||||
*/
|
||||
CustomObjectConfiguration& operator=(const gd::CustomObjectConfiguration& object){
|
||||
if ((this) != &object) {
|
||||
ObjectConfiguration::operator=(object);
|
||||
Init(object);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetProperties() const override;
|
||||
bool UpdateProperty(const gd::String& name, const gd::String& value) override;
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetInitialInstanceProperties(
|
||||
const gd::InitialInstance& instance,
|
||||
gd::Project& project,
|
||||
gd::Layout& scene) override;
|
||||
bool UpdateInitialInstanceProperty(gd::InitialInstance& instance,
|
||||
const gd::String& name,
|
||||
const gd::String& value,
|
||||
gd::Project& project,
|
||||
gd::Layout& scene) override;
|
||||
|
||||
void ExposeResources(gd::ArbitraryResourceWorker& worker) override;
|
||||
|
||||
gd::ObjectConfiguration &GetChildObjectConfiguration(const gd::String& objectName);
|
||||
|
||||
protected:
|
||||
void DoSerializeTo(SerializerElement& element) const override;
|
||||
void DoUnserializeFrom(Project& project, const SerializerElement& element) override;
|
||||
|
||||
private:
|
||||
const Project* project; ///< The project is used to get the
|
||||
///< EventBasedObject from the fullType.
|
||||
gd::SerializerElement objectContent;
|
||||
std::map<gd::String, std::unique_ptr<gd::ObjectConfiguration>> childObjectConfigurations;
|
||||
|
||||
static gd::ObjectConfiguration badObjectConfiguration;
|
||||
|
||||
/**
|
||||
* Initialize configuration using another configuration. 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 childObjectConfigurations
|
||||
* and it must be a deep copy.
|
||||
*/
|
||||
void Init(const gd::CustomObjectConfiguration& object);
|
||||
};
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_CUSTOMOBJECTCONFIGURATION_H
|
@@ -16,7 +16,7 @@ class Project;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
// TODO EBO Add a way to mark some parts of children configuration as readonly.
|
||||
/**
|
||||
* \brief Represents an object that is implemented with events.
|
||||
*
|
||||
|
@@ -117,10 +117,10 @@ std::map<gd::String, gd::PropertyDescriptor>
|
||||
InitialInstance::GetCustomProperties(gd::Project& project, gd::Layout& layout) {
|
||||
// Find an object
|
||||
if (layout.HasObjectNamed(GetObjectName()))
|
||||
return layout.GetObject(GetObjectName())
|
||||
return layout.GetObject(GetObjectName()).GetConfiguration()
|
||||
.GetInitialInstanceProperties(*this, project, layout);
|
||||
else if (project.HasObjectNamed(GetObjectName()))
|
||||
return project.GetObject(GetObjectName())
|
||||
return project.GetObject(GetObjectName()).GetConfiguration()
|
||||
.GetInitialInstanceProperties(*this, project, layout);
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> nothing;
|
||||
@@ -132,10 +132,10 @@ bool InitialInstance::UpdateCustomProperty(const gd::String& name,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout) {
|
||||
if (layout.HasObjectNamed(GetObjectName()))
|
||||
return layout.GetObject(GetObjectName())
|
||||
return layout.GetObject(GetObjectName()).GetConfiguration()
|
||||
.UpdateInitialInstanceProperty(*this, name, value, project, layout);
|
||||
else if (project.HasObjectNamed(GetObjectName()))
|
||||
return project.GetObject(GetObjectName())
|
||||
return project.GetObject(GetObjectName()).GetConfiguration()
|
||||
.UpdateInitialInstanceProperty(*this, name, value, project, layout);
|
||||
|
||||
return false;
|
||||
|
@@ -20,12 +20,23 @@ namespace gd {
|
||||
|
||||
Object::~Object() {}
|
||||
|
||||
Object::Object(const gd::String& name_) : name(name_) {}
|
||||
Object::Object(const gd::String& name_,
|
||||
const gd::String& type_,
|
||||
std::unique_ptr<gd::ObjectConfiguration> configuration_)
|
||||
: name(name_), configuration(std::move(configuration_)) {
|
||||
SetType(type_);
|
||||
}
|
||||
|
||||
Object::Object(const gd::String& name_,
|
||||
const gd::String& type_,
|
||||
gd::ObjectConfiguration* configuration_)
|
||||
: name(name_), configuration(configuration_) {
|
||||
SetType(type_);
|
||||
}
|
||||
|
||||
void Object::Init(const gd::Object& object) {
|
||||
name = object.name;
|
||||
assetStoreId = object.assetStoreId;
|
||||
type = object.type;
|
||||
objectVariables = object.objectVariables;
|
||||
tags = object.tags;
|
||||
effectsContainer = object.effectsContainer;
|
||||
@@ -34,6 +45,16 @@ void Object::Init(const gd::Object& object) {
|
||||
for (auto& it : object.behaviors) {
|
||||
behaviors[it.first] = gd::make_unique<gd::Behavior>(*it.second);
|
||||
}
|
||||
|
||||
configuration = object.configuration->Clone();
|
||||
}
|
||||
|
||||
gd::ObjectConfiguration& Object::GetConfiguration() {
|
||||
return *configuration;
|
||||
}
|
||||
|
||||
const gd::ObjectConfiguration& Object::GetConfiguration() const {
|
||||
return *configuration;
|
||||
}
|
||||
|
||||
std::vector<gd::String> Object::GetAllBehaviorNames() const {
|
||||
@@ -72,11 +93,6 @@ bool Object::HasBehaviorNamed(const gd::String& name) const {
|
||||
return behaviors.find(name) != behaviors.end();
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> Object::GetProperties() const {
|
||||
std::map<gd::String, gd::PropertyDescriptor> nothing;
|
||||
return nothing;
|
||||
}
|
||||
|
||||
gd::Behavior* Object::AddNewBehavior(const gd::Project& project,
|
||||
const gd::String& type,
|
||||
const gd::String& name) {
|
||||
@@ -109,17 +125,9 @@ gd::Behavior* Object::AddNewBehavior(const gd::Project& project,
|
||||
}
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor>
|
||||
Object::GetInitialInstanceProperties(const gd::InitialInstance& instance,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout) {
|
||||
std::map<gd::String, gd::PropertyDescriptor> nothing;
|
||||
return nothing;
|
||||
}
|
||||
|
||||
void Object::UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element) {
|
||||
type = element.GetStringAttribute("type");
|
||||
SetType(element.GetStringAttribute("type"));
|
||||
assetStoreId = element.GetStringAttribute("assetStoreId");
|
||||
name = element.GetStringAttribute("name", name, "nom");
|
||||
tags = element.GetStringAttribute("tags");
|
||||
@@ -186,7 +194,7 @@ void Object::UnserializeFrom(gd::Project& project,
|
||||
}
|
||||
}
|
||||
|
||||
DoUnserializeFrom(project, element);
|
||||
configuration->UnserializeFrom(project, element);
|
||||
}
|
||||
|
||||
void Object::SerializeTo(SerializerElement& element) const {
|
||||
@@ -212,7 +220,7 @@ void Object::SerializeTo(SerializerElement& element) const {
|
||||
behaviorElement.SetAttribute("name", behavior.GetName());
|
||||
}
|
||||
|
||||
DoSerializeTo(element);
|
||||
configuration->SerializeTo(element);
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -11,10 +11,12 @@
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
#include "GDCore/Project/EffectsContainer.h"
|
||||
#include "GDCore/Project/VariablesContainer.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Tools/MakeUnique.h"
|
||||
|
||||
namespace gd {
|
||||
class PropertyDescriptor;
|
||||
class Project;
|
||||
@@ -28,7 +30,7 @@ class EffectsContainer;
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Base class used to represent an object of a platform
|
||||
* \brief Represent an object of a platform
|
||||
*
|
||||
* \ingroup PlatformDefinition
|
||||
*/
|
||||
@@ -36,9 +38,19 @@ class GD_CORE_API Object {
|
||||
public:
|
||||
/**
|
||||
* Create a new object with the name passed as argument.
|
||||
* \param name Object's name
|
||||
*/
|
||||
Object(const gd::String& name);
|
||||
Object(const gd::String& name,
|
||||
const gd::String& type,
|
||||
std::unique_ptr<gd::ObjectConfiguration> configuration);
|
||||
|
||||
/**
|
||||
* Create a new object with the name passed as argument.
|
||||
*
|
||||
* Object takes the ownership of the configuration.
|
||||
*/
|
||||
Object(const gd::String& name,
|
||||
const gd::String& type,
|
||||
gd::ObjectConfiguration* configuration);
|
||||
|
||||
/**
|
||||
* Copy constructor. Calls Init().
|
||||
@@ -70,6 +82,13 @@ class GD_CORE_API Object {
|
||||
return gd::make_unique<gd::Object>(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return the object configuration.
|
||||
*/
|
||||
gd::ObjectConfiguration& GetConfiguration();
|
||||
|
||||
const gd::ObjectConfiguration& GetConfiguration() const;
|
||||
|
||||
/** \name Common properties
|
||||
* Members functions related to common properties
|
||||
*/
|
||||
@@ -93,11 +112,15 @@ class GD_CORE_API Object {
|
||||
|
||||
/** \brief Change the type of the object.
|
||||
*/
|
||||
void SetType(const gd::String& type_) { type = type_; }
|
||||
void SetType(const gd::String& type_) {
|
||||
configuration->SetType(type_);
|
||||
}
|
||||
|
||||
/** \brief Return the type of the object.
|
||||
*/
|
||||
const gd::String& GetType() const { return type; }
|
||||
const gd::String& GetType() const {
|
||||
return configuration->GetType();
|
||||
}
|
||||
|
||||
/** \brief Change the tags of the object.
|
||||
*/
|
||||
@@ -108,92 +131,6 @@ class GD_CORE_API Object {
|
||||
const gd::String& GetTags() const { return tags; }
|
||||
///@}
|
||||
|
||||
/** \name Resources management
|
||||
* Members functions related to managing resources used by the object
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Called ( e.g. during compilation ) so as to inventory internal
|
||||
* resources and sometimes update their filename. Implementation example:
|
||||
* \code
|
||||
* worker.ExposeImage(myImage);
|
||||
* worker.ExposeFile(myResourceFile);
|
||||
* \endcode
|
||||
*
|
||||
* \see ArbitraryResourceWorker
|
||||
*/
|
||||
virtual void ExposeResources(gd::ArbitraryResourceWorker& worker) { return; };
|
||||
|
||||
/**
|
||||
* Redefine this function to return true if your object can use shaders.
|
||||
*/
|
||||
virtual bool SupportShaders() { return false; }
|
||||
///@}
|
||||
|
||||
/** \name Object properties
|
||||
* Reading and updating object properties
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Called when the IDE wants to know about the custom properties of the
|
||||
object.
|
||||
*
|
||||
* Usage example:
|
||||
\code
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties[ToString(_("Text"))].SetValue("Hello world!");
|
||||
|
||||
return properties;
|
||||
\endcode
|
||||
*
|
||||
* \return a std::map with properties names as key.
|
||||
* \see gd::PropertyDescriptor
|
||||
*/
|
||||
virtual std::map<gd::String, gd::PropertyDescriptor> GetProperties() const;
|
||||
|
||||
/**
|
||||
* \brief Called when the IDE wants to update a custom property of the object
|
||||
*
|
||||
* \return false if the new value cannot be set
|
||||
*/
|
||||
virtual bool UpdateProperty(const gd::String& name, const gd::String& value) {
|
||||
return false;
|
||||
};
|
||||
///@}
|
||||
|
||||
/** \name Drawing and editing initial instances
|
||||
* Members functions related to drawing and editing initial instances of this
|
||||
* object
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Called when the IDE wants to know about the custom properties of an
|
||||
* initial instance of this object.
|
||||
*
|
||||
* \return a std::map with properties names as key and values.
|
||||
* \see gd::InitialInstance
|
||||
*/
|
||||
virtual std::map<gd::String, gd::PropertyDescriptor>
|
||||
GetInitialInstanceProperties(const gd::InitialInstance& instance,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout);
|
||||
|
||||
/**
|
||||
* \brief Called when the IDE wants to update a custom property of an initial
|
||||
* instance of this object.
|
||||
*
|
||||
* \return false if the new value cannot be set
|
||||
* \see gd::InitialInstance
|
||||
*/
|
||||
virtual bool UpdateInitialInstanceProperty(gd::InitialInstance& instance,
|
||||
const gd::String& name,
|
||||
const gd::String& value,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout) {
|
||||
return false;
|
||||
};
|
||||
///@}
|
||||
|
||||
/** \name Behaviors management
|
||||
* Members functions related to behaviors management.
|
||||
*/
|
||||
@@ -309,8 +246,7 @@ class GD_CORE_API Object {
|
||||
protected:
|
||||
gd::String name; ///< The full name of the object
|
||||
gd::String assetStoreId; ///< The ID of the asset if the object comes from the store.
|
||||
gd::String type; ///< Which type is the object. ( To test if we can do
|
||||
///< something reserved to some objects with it )
|
||||
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
|
||||
@@ -321,20 +257,12 @@ class GD_CORE_API Object {
|
||||
gd::EffectsContainer
|
||||
effectsContainer; ///< The effects container for the object.
|
||||
|
||||
/**
|
||||
* \brief Derived objects can redefine this method to load custom attributes.
|
||||
*/
|
||||
virtual void DoUnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element){};
|
||||
|
||||
/**
|
||||
* \brief Derived objects can redefine this method to save custom attributes.
|
||||
*/
|
||||
virtual void DoSerializeTo(SerializerElement& element) const {};
|
||||
|
||||
/**
|
||||
* Initialize object using another object. 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::Object& object);
|
||||
};
|
||||
|
47
Core/GDCore/Project/ObjectConfiguration.cpp
Normal file
47
Core/GDCore/Project/ObjectConfiguration.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/Project/ObjectConfiguration.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/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
ObjectConfiguration::~ObjectConfiguration() {}
|
||||
|
||||
ObjectConfiguration::ObjectConfiguration() {}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> ObjectConfiguration::GetProperties() const {
|
||||
std::map<gd::String, gd::PropertyDescriptor> nothing;
|
||||
return nothing;
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor>
|
||||
ObjectConfiguration::GetInitialInstanceProperties(const gd::InitialInstance& instance,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout) {
|
||||
std::map<gd::String, gd::PropertyDescriptor> nothing;
|
||||
return nothing;
|
||||
}
|
||||
|
||||
void ObjectConfiguration::UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element) {
|
||||
DoUnserializeFrom(project, element);
|
||||
}
|
||||
|
||||
void ObjectConfiguration::SerializeTo(SerializerElement& element) const {
|
||||
DoSerializeTo(element);
|
||||
}
|
||||
|
||||
} // namespace gd
|
194
Core/GDCore/Project/ObjectConfiguration.h
Normal file
194
Core/GDCore/Project/ObjectConfiguration.h
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef GDCORE_OBJECTCONFIGURATION_H
|
||||
#define GDCORE_OBJECTCONFIGURATION_H
|
||||
#include "GDCore/Vector2.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/EffectsContainer.h"
|
||||
#include "GDCore/Project/VariablesContainer.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Tools/MakeUnique.h"
|
||||
namespace gd {
|
||||
class PropertyDescriptor;
|
||||
class Project;
|
||||
class Layout;
|
||||
class ArbitraryResourceWorker;
|
||||
class InitialInstance;
|
||||
class SerializerElement;
|
||||
class EffectsContainer;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Base class used to represent an object configuration.
|
||||
* For example, this can be the animations in a sprite, the text, its font,
|
||||
* its color in a Text object, etc...
|
||||
*
|
||||
* \ingroup PlatformDefinition
|
||||
*/
|
||||
class GD_CORE_API ObjectConfiguration {
|
||||
public:
|
||||
/**
|
||||
* Create a new object configuration.
|
||||
*/
|
||||
ObjectConfiguration();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~ObjectConfiguration();
|
||||
|
||||
/**
|
||||
* Must return a pointer to a copy of the configuration. This method is
|
||||
* needed to do polymorphic copies. Just redefine this method in your derived
|
||||
* object class like this:
|
||||
* \code
|
||||
* return gd::make_unique<MyObjectConfiguration>(*this);
|
||||
* \endcode
|
||||
*/
|
||||
virtual std::unique_ptr<gd::ObjectConfiguration> Clone() const {
|
||||
return gd::make_unique<gd::ObjectConfiguration>(*this);
|
||||
}
|
||||
|
||||
/** \brief Change the type of the object.
|
||||
*/
|
||||
void SetType(const gd::String& type_) { type = type_; }
|
||||
|
||||
/** \brief Return the type of the object.
|
||||
*/
|
||||
const gd::String& GetType() const { return type; }
|
||||
|
||||
/** \name Object properties
|
||||
* Reading and updating object configuration properties
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Called when the IDE wants to know about the custom properties of the
|
||||
object configuration.
|
||||
*
|
||||
* Usage example:
|
||||
\code
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties[ToString(_("Text"))].SetValue("Hello world!");
|
||||
|
||||
return properties;
|
||||
\endcode
|
||||
*
|
||||
* \return a std::map with properties names as key.
|
||||
* \see gd::PropertyDescriptor
|
||||
*/
|
||||
virtual std::map<gd::String, gd::PropertyDescriptor> GetProperties() const;
|
||||
|
||||
/**
|
||||
* \brief Called when the IDE wants to update a custom property of the object
|
||||
* configuration.
|
||||
*
|
||||
* \return false if the new value cannot be set
|
||||
*/
|
||||
virtual bool UpdateProperty(const gd::String& name, const gd::String& value) {
|
||||
return false;
|
||||
};
|
||||
///@}
|
||||
|
||||
/** \name Drawing and editing initial instances
|
||||
* Members functions related to drawing and editing initial instances of this
|
||||
* object configuration
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Called when the IDE wants to know about the custom properties of an
|
||||
* initial instance of this object configuration.
|
||||
*
|
||||
* \return a std::map with properties names as key and values.
|
||||
* \see gd::InitialInstance
|
||||
*/
|
||||
virtual std::map<gd::String, gd::PropertyDescriptor>
|
||||
GetInitialInstanceProperties(const gd::InitialInstance& instance,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout);
|
||||
|
||||
/**
|
||||
* \brief Called when the IDE wants to update a custom property of an initial
|
||||
* instance of this object configuration.
|
||||
*
|
||||
* \return false if the new value cannot be set
|
||||
* \see gd::InitialInstance
|
||||
*/
|
||||
virtual bool UpdateInitialInstanceProperty(gd::InitialInstance& instance,
|
||||
const gd::String& name,
|
||||
const gd::String& value,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout) {
|
||||
return false;
|
||||
};
|
||||
///@}
|
||||
|
||||
/** \name Resources management
|
||||
* Members functions related to managing resources used by the object configuration
|
||||
*/
|
||||
///@{
|
||||
|
||||
/**
|
||||
* \brief Called ( e.g. during compilation ) so as to inventory internal
|
||||
* resources and sometimes update their filename. Implementation example:
|
||||
* \code
|
||||
* worker.ExposeImage(myImage);
|
||||
* worker.ExposeFile(myResourceFile);
|
||||
* \endcode
|
||||
*
|
||||
* \see ArbitraryResourceWorker
|
||||
*/
|
||||
virtual void ExposeResources(gd::ArbitraryResourceWorker& worker) { return; };
|
||||
///@}
|
||||
|
||||
/** \name Serialization
|
||||
* Members functions related to serialization of the object configuration
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Serialize the object configuration.
|
||||
* \see DoSerializeTo
|
||||
*/
|
||||
void SerializeTo(SerializerElement& element) const;
|
||||
|
||||
/**
|
||||
* \brief Unserialize the object configuration.
|
||||
* \see DoUnserializeFrom
|
||||
*/
|
||||
void UnserializeFrom(gd::Project& project, const SerializerElement& element);
|
||||
///@}
|
||||
|
||||
protected:
|
||||
gd::String type; ///< Which type of object is represented by this
|
||||
///< configuration.
|
||||
|
||||
/**
|
||||
* \brief Derived object configuration can redefine this method to load
|
||||
* custom attributes.
|
||||
*/
|
||||
virtual void DoUnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element){};
|
||||
|
||||
/**
|
||||
* \brief Derived object configuration can redefine this method to save
|
||||
* custom attributes.
|
||||
*/
|
||||
virtual void DoSerializeTo(SerializerElement& element) const {};
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
/**
|
||||
* Object configurations are usually managed thanks to (smart) pointers.
|
||||
*/
|
||||
using ObjConfSPtr = std::unique_ptr<gd::ObjectConfiguration>;
|
||||
|
||||
#endif // GDCORE_OBJECT_H
|
@@ -23,11 +23,12 @@
|
||||
#include "GDCore/IDE/PlatformManager.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#include "GDCore/Project/EventsFunctionsExtension.h"
|
||||
#include "GDCore/Project/CustomObject.h"
|
||||
#include "GDCore/Project/CustomObjectConfiguration.h"
|
||||
#include "GDCore/Project/ExternalEvents.h"
|
||||
#include "GDCore/Project/ExternalLayout.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
#include "GDCore/Project/ObjectGroupsContainer.h"
|
||||
#include "GDCore/Project/ResourcesManager.h"
|
||||
#include "GDCore/Project/SourceFile.h"
|
||||
@@ -82,12 +83,17 @@ void Project::ResetProjectUuid() { projectUuid = UUID::MakeUuid4(); }
|
||||
std::unique_ptr<gd::Object> Project::CreateObject(
|
||||
const gd::String& type,
|
||||
const gd::String& name) const {
|
||||
return gd::make_unique<Object>(name, type, CreateObjectConfiguration(type));
|
||||
}
|
||||
|
||||
std::unique_ptr<gd::ObjectConfiguration> Project::CreateObjectConfiguration(
|
||||
const gd::String& type) const {
|
||||
if (Project::HasEventsBasedObject(type)) {
|
||||
return gd::make_unique<CustomObject>(name, *this, type);
|
||||
return gd::make_unique<CustomObjectConfiguration>(*this, type);
|
||||
}
|
||||
else {
|
||||
// Create a base object if the type can't be found in the platform.
|
||||
return currentPlatform->CreateObject(type, name);
|
||||
return currentPlatform->CreateObjectConfiguration(type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -940,8 +946,9 @@ void Project::ExposeResources(gd::ArbitraryResourceWorker& worker) {
|
||||
// Add layouts resources
|
||||
for (std::size_t s = 0; s < GetLayoutsCount(); s++) {
|
||||
for (std::size_t j = 0; j < GetLayout(s).GetObjectsCount();
|
||||
++j) // Add objects resources
|
||||
GetLayout(s).GetObject(j).ExposeResources(worker);
|
||||
++j) { // Add objects resources
|
||||
GetLayout(s).GetObject(j).GetConfiguration().ExposeResources(worker);
|
||||
}
|
||||
|
||||
LaunchResourceWorkerOnEvents(*this, GetLayout(s).GetEvents(), worker);
|
||||
}
|
||||
@@ -960,7 +967,7 @@ void Project::ExposeResources(gd::ArbitraryResourceWorker& worker) {
|
||||
|
||||
// Add global objects resources
|
||||
for (std::size_t j = 0; j < GetObjectsCount(); ++j) {
|
||||
GetObject(j).ExposeResources(worker);
|
||||
GetObject(j).GetConfiguration().ExposeResources(worker);
|
||||
}
|
||||
|
||||
// Add loading screen background image if present
|
||||
|
@@ -27,6 +27,7 @@ class EventsFunctionsExtension;
|
||||
class EventsBasedObject;
|
||||
class EventsBasedBehavior;
|
||||
class Object;
|
||||
class ObjectConfiguration;
|
||||
class VariablesContainer;
|
||||
class ArbitraryResourceWorker;
|
||||
class SourceFile;
|
||||
@@ -464,6 +465,14 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
std::unique_ptr<gd::Object> CreateObject(const gd::String& type,
|
||||
const gd::String& name) const;
|
||||
|
||||
/**
|
||||
* Create an object configuration of the given type.
|
||||
*
|
||||
* \param type The type of the object
|
||||
*/
|
||||
std::unique_ptr<gd::ObjectConfiguration> CreateObjectConfiguration(
|
||||
const gd::String& type) const;
|
||||
|
||||
/**
|
||||
* Create an event of the given type.
|
||||
*
|
||||
|
@@ -13,12 +13,14 @@
|
||||
#include "GDCore/IDE/Project/ProjectResourcesAdder.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Events/Builtin/StandardEvent.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/Tools/SystemStats.h"
|
||||
#include "GDCore/Tools/VersionWrapper.h"
|
||||
#include "DummyPlatform.h"
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
class ArbitraryResourceWorkerTest : public gd::ArbitraryResourceWorker {
|
||||
@@ -63,14 +65,15 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
|
||||
"path/to/file4.png") != worker.files.end());
|
||||
|
||||
SECTION("Object using a resource") {
|
||||
gd::SpriteObject obj("myObject");
|
||||
|
||||
gd::SpriteObject spriteConfiguration;
|
||||
gd::Animation anim;
|
||||
gd::Sprite sprite;
|
||||
sprite.SetImageName("res1");
|
||||
anim.SetDirectionsCount(1);
|
||||
anim.GetDirection(0).AddSprite(sprite);
|
||||
obj.AddAnimation(anim);
|
||||
spriteConfiguration.AddAnimation(anim);
|
||||
|
||||
gd::Object obj("myObject", "", spriteConfiguration.Clone());
|
||||
project.InsertObject(obj, 0);
|
||||
|
||||
worker.files.clear();
|
||||
|
@@ -120,12 +120,14 @@ void CheckBehaviorProperty(ObjectsContainer &container) {
|
||||
};
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("ProjectSerialization", "[common]") {
|
||||
// TODO EBO Add similar test cases for events-based objects.
|
||||
TEST_CASE("BehaviorSerialization", "[common]") {
|
||||
|
||||
SECTION("Save and load a project with a custom behavior property value") {
|
||||
gd::Platform platform;
|
||||
gd::Project writtenProject;
|
||||
SetupProject(writtenProject, platform);
|
||||
CheckBehaviorProperty(writtenProject.GetLayout("Scene"));
|
||||
|
||||
SerializerElement projectElement;
|
||||
writtenProject.SerializeTo(projectElement);
|
@@ -7,6 +7,8 @@
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/IDE/Events/ExpressionValidator.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
@@ -98,7 +100,7 @@ void SetupProjectWithDummyPlatform(gd::Project& project,
|
||||
// Create the base object. All objects "inherits" from it.
|
||||
baseObjectExtension->SetExtensionInformation(
|
||||
"BuiltinObject", "Base Object dummy extension", "", "", "");
|
||||
auto& baseObject = baseObjectExtension->AddObject<gd::Object>(
|
||||
auto& baseObject = baseObjectExtension->AddObject<gd::ObjectConfiguration>(
|
||||
"", "Dummy Base Object", "Dummy Base Object", "");
|
||||
|
||||
// Add this expression for all objects. But it requires a "capability".
|
||||
@@ -130,6 +132,18 @@ void SetupProjectWithDummyPlatform(gd::Project& project,
|
||||
.AddParameter("expression", "Parameter 1 (a number)")
|
||||
.SetFunctionName("doSomething");
|
||||
|
||||
extension
|
||||
->AddAction("DoSomethingWithObjects",
|
||||
"Do something",
|
||||
"This does something",
|
||||
"Do something please",
|
||||
"",
|
||||
"",
|
||||
"")
|
||||
.AddParameter("object", _("Object 1 parameter"))
|
||||
.AddParameter("object", _("Object 2 parameter"))
|
||||
.SetFunctionName("doSomethingWithObjects");
|
||||
|
||||
extension
|
||||
->AddAction("DoSomethingWithResources",
|
||||
"Do something with resources",
|
||||
@@ -214,7 +228,7 @@ void SetupProjectWithDummyPlatform(gd::Project& project,
|
||||
.AddParameter("objectvar", _("Variable for object 2"))
|
||||
.SetFunctionName("getStringWith1ObjectParamAnd2ObjectVarParam");
|
||||
|
||||
auto& object = extension->AddObject<gd::Object>(
|
||||
auto& object = extension->AddObject<gd::SpriteObject>(
|
||||
"Sprite", "Dummy Sprite", "Dummy sprite object", "");
|
||||
object
|
||||
.AddExpression("GetObjectVariableAsNumber",
|
||||
@@ -351,7 +365,7 @@ void SetupProjectWithDummyPlatform(gd::Project& project,
|
||||
|
||||
{
|
||||
auto& object = extension
|
||||
->AddObject<gd::Object>(
|
||||
->AddObject<gd::ObjectConfiguration>(
|
||||
"FakeObjectWithUnsupportedCapability",
|
||||
"FakeObjectWithUnsupportedCapability",
|
||||
"This is FakeObjectWithUnsupportedCapability",
|
||||
|
76
Core/tests/EventsExtension.cpp
Normal file
76
Core/tests/EventsExtension.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
/**
|
||||
* @file Tests covering events-based extensions
|
||||
*/
|
||||
#include "GDCore/IDE/WholeProjectRefactorer.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "DummyPlatform.h"
|
||||
#include "GDCore/Events/Builtin/LinkEvent.h"
|
||||
#include "GDCore/Events/Builtin/StandardEvent.h"
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Metadata/ParameterMetadataTools.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/IDE/UnfilledRequiredBehaviorPropertyProblem.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/EventsFunctionsExtension.h"
|
||||
#include "GDCore/Project/ExternalEvents.h"
|
||||
#include "GDCore/Project/ExternalLayout.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/Variable.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
gd::EventsFunctionsExtension &
|
||||
SetupProjectWithEventsFunctionExtension(gd::Project &project) {
|
||||
auto &eventsExtension =
|
||||
project.InsertNewEventsFunctionsExtension("MyEventsExtension", 0);
|
||||
|
||||
// Add an events-based behavior
|
||||
{
|
||||
auto &eventsBasedBehavior =
|
||||
eventsExtension.GetEventsBasedBehaviors().InsertNew(
|
||||
"MyEventsBasedBehavior", 0);
|
||||
eventsBasedBehavior.SetFullName("My events based behavior");
|
||||
eventsBasedBehavior.SetDescription("An events based behavior for test");
|
||||
|
||||
// Add a property
|
||||
eventsBasedBehavior.GetPropertyDescriptors()
|
||||
.InsertNew("MyProperty", 0)
|
||||
.SetValue("123")
|
||||
.SetType("Number");
|
||||
}
|
||||
|
||||
return eventsExtension;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("Events-based extension", "[common]") {
|
||||
SECTION("Behavior property default value") {
|
||||
gd::Project project;
|
||||
gd::Platform platform;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
|
||||
auto &layout1 = project.InsertNewLayout("Layout1", 0);
|
||||
auto &object = layout1.InsertNewObject(project, "MyExtension::Sprite", "Object1", 0);
|
||||
|
||||
// Attach a behavior to an object.
|
||||
auto *behavior = object.AddNewBehavior(project, "MyEventsExtension::MyEventsBasedBehavior", "MyEventsBasedBehavior");
|
||||
behavior->InitializeContent();
|
||||
|
||||
// The behavior has the default value.
|
||||
REQUIRE(behavior->GetProperties().size() == 1);
|
||||
REQUIRE(behavior->GetProperties().at("MyProperty").GetValue() == "123");
|
||||
}
|
||||
}
|
111
Core/tests/ObjectSerialization.cpp
Normal file
111
Core/tests/ObjectSerialization.cpp
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
/**
|
||||
* @file Tests covering serialization to JSON.
|
||||
*/
|
||||
#include "DummyPlatform.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/Builtin/StandardEvent.h"
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Project/EventsFunctionsExtension.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/Variable.h"
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/Tools/SystemStats.h"
|
||||
#include "GDCore/Tools/VersionWrapper.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
using namespace gd;
|
||||
|
||||
namespace {
|
||||
|
||||
void SetupProject(gd::Project &project, gd::Platform &platform) {
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object =
|
||||
layout.InsertNewObject(project, "MyExtension::Sprite", "MyObject", 0);
|
||||
|
||||
auto &configuration = object.GetConfiguration();
|
||||
auto *spriteConfiguration = dynamic_cast<gd::SpriteObject *>(&configuration);
|
||||
REQUIRE(spriteConfiguration != nullptr);
|
||||
gd::Animation animation;
|
||||
animation.SetName("Idle");
|
||||
spriteConfiguration->AddAnimation(animation);
|
||||
};
|
||||
|
||||
void CheckSpriteConfiguration(
|
||||
SerializerElement &objectContainerElement) {
|
||||
};
|
||||
|
||||
void CheckSpriteConfigurationInElement(SerializerElement &projectElement) {
|
||||
auto &layoutsElement = projectElement.GetChild("layouts");
|
||||
layoutsElement.ConsiderAsArrayOf("layout");
|
||||
REQUIRE(layoutsElement.GetChildrenCount() == 1);
|
||||
auto &layoutElement = layoutsElement.GetChild(0);
|
||||
|
||||
REQUIRE(layoutElement.GetStringAttribute("name") == "Scene");
|
||||
REQUIRE(layoutElement.HasChild("objects"));
|
||||
|
||||
auto &objectsElement = layoutElement.GetChild("objects");
|
||||
objectsElement.ConsiderAsArrayOf("object");
|
||||
REQUIRE(objectsElement.GetChildrenCount() == 1);
|
||||
auto &objectElement = objectsElement.GetChild(0);
|
||||
|
||||
REQUIRE(objectElement.GetStringAttribute("name") == "MyObject");
|
||||
REQUIRE(objectElement.GetStringAttribute("type") == "MyExtension::Sprite");
|
||||
|
||||
REQUIRE(objectElement.HasChild("animations"));
|
||||
auto &animationsElement = objectElement.GetChild("animations");
|
||||
animationsElement.ConsiderAsArrayOf("animation");
|
||||
REQUIRE(animationsElement.GetChildrenCount() == 1);
|
||||
auto &animationElement = animationsElement.GetChild(0);
|
||||
|
||||
REQUIRE(animationElement.GetStringAttribute("name") ==
|
||||
"Idle");
|
||||
};
|
||||
|
||||
void CheckSpriteConfiguration(gd::Project &project) {
|
||||
auto &layout = project.GetLayout("Scene");
|
||||
auto &object = layout.GetObject("MyObject");
|
||||
REQUIRE(object.GetName() == "MyObject");
|
||||
REQUIRE(object.GetType() == "MyExtension::Sprite");
|
||||
|
||||
auto &configuration = object.GetConfiguration();
|
||||
auto *spriteConfiguration = dynamic_cast<gd::SpriteObject *>(&configuration);
|
||||
REQUIRE(spriteConfiguration);
|
||||
REQUIRE(spriteConfiguration->GetAnimationsCount() == 1);
|
||||
|
||||
auto &animation = spriteConfiguration->GetAnimation(0);
|
||||
REQUIRE(animation.GetName() == "Idle");
|
||||
};
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("ObjectSerialization", "[common]") {
|
||||
|
||||
SECTION("Save and load a project with a sprite configuration") {
|
||||
gd::Platform platform;
|
||||
gd::Project writtenProject;
|
||||
SetupProject(writtenProject, platform);
|
||||
CheckSpriteConfiguration(writtenProject);
|
||||
|
||||
SerializerElement projectElement;
|
||||
writtenProject.SerializeTo(projectElement);
|
||||
CheckSpriteConfigurationInElement(projectElement);
|
||||
|
||||
gd::Project readProject;
|
||||
readProject.AddPlatform(platform);
|
||||
readProject.UnserializeFrom(projectElement);
|
||||
CheckSpriteConfiguration(readProject);
|
||||
}
|
||||
}
|
@@ -67,7 +67,9 @@ const gd::String &GetEventFirstActionType(const gd::BaseEvent &event) {
|
||||
|
||||
enum TestEvent {
|
||||
FreeFunctionAction,
|
||||
FreeFunctionExpression,
|
||||
FreeFunctionWithExpression,
|
||||
FreeFunctionWithObjects,
|
||||
FreeFunctionWithObjectExpression,
|
||||
|
||||
BehaviorAction,
|
||||
BehaviorPropertyAction,
|
||||
@@ -113,7 +115,7 @@ const void SetupEvents(gd::EventsList &eventList) {
|
||||
if (eventList.GetEventsCount() != FreeFunctionAction) {
|
||||
throw std::logic_error("Invalid events setup");
|
||||
}
|
||||
// Create an event in the layout referring to
|
||||
// Create an event referring to
|
||||
// MyEventsExtension::MyEventsFunction
|
||||
{
|
||||
gd::StandardEvent event;
|
||||
@@ -128,10 +130,10 @@ const void SetupEvents(gd::EventsList &eventList) {
|
||||
eventList.InsertEvent(event);
|
||||
}
|
||||
|
||||
if (eventList.GetEventsCount() != FreeFunctionExpression) {
|
||||
if (eventList.GetEventsCount() != FreeFunctionWithExpression) {
|
||||
throw std::logic_error("Invalid events setup");
|
||||
}
|
||||
// Create an event in the external events referring to
|
||||
// Create an event referring to
|
||||
// MyEventsExtension::MyEventsFunctionExpression
|
||||
{
|
||||
gd::StandardEvent event;
|
||||
@@ -145,6 +147,38 @@ const void SetupEvents(gd::EventsList &eventList) {
|
||||
event.GetActions().Insert(action);
|
||||
eventList.InsertEvent(event);
|
||||
}
|
||||
|
||||
if (eventList.GetEventsCount() != FreeFunctionWithObjects) {
|
||||
throw std::logic_error("Invalid events setup");
|
||||
}
|
||||
// Create an event referring to objects
|
||||
{
|
||||
gd::StandardEvent event;
|
||||
gd::Instruction action;
|
||||
action.SetType("MyExtension::DoSomethingWithObjects");
|
||||
action.SetParametersCount(2);
|
||||
action.SetParameter(0, gd::Expression("ObjectWithMyBehavior"));
|
||||
action.SetParameter(1, gd::Expression("MyCustomObject"));
|
||||
event.GetActions().Insert(action);
|
||||
eventList.InsertEvent(event);
|
||||
}
|
||||
|
||||
if (eventList.GetEventsCount() != FreeFunctionWithObjectExpression) {
|
||||
throw std::logic_error("Invalid events setup");
|
||||
}
|
||||
// Create an event referring to objects in an expression
|
||||
{
|
||||
gd::StandardEvent event;
|
||||
gd::Instruction action;
|
||||
action.SetType("MyExtension::DoSomething");
|
||||
action.SetParametersCount(1);
|
||||
action.SetParameter(
|
||||
0,
|
||||
gd::Expression(
|
||||
"ObjectWithMyBehavior.GetObjectNumber()"));
|
||||
event.GetActions().Insert(action);
|
||||
eventList.InsertEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
// Add some events based behavior usages in events
|
||||
@@ -854,6 +888,30 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
REQUIRE(externalLayout2.GetInitialInstances().HasInstancesOfObject(
|
||||
"GlobalObject3") == true);
|
||||
}
|
||||
|
||||
SECTION("Events") {
|
||||
gd::Project project;
|
||||
gd::Platform platform;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
|
||||
|
||||
auto &layout = project.GetLayout("Scene");
|
||||
|
||||
// Trigger the refactoring after the renaming of an object
|
||||
gd::WholeProjectRefactorer::ObjectOrGroupRenamedInLayout(
|
||||
project, layout, "ObjectWithMyBehavior", "RenamedObjectWithMyBehavior",
|
||||
/* isObjectGroup=*/false);
|
||||
|
||||
// Check object name has been renamed in action parameters.
|
||||
REQUIRE(GetEventFirstActionFirstParameterString(
|
||||
layout.GetEvents().GetEvent(FreeFunctionWithObjects)) ==
|
||||
"RenamedObjectWithMyBehavior");
|
||||
|
||||
// Check object name has been renamed in expressions.
|
||||
REQUIRE(GetEventFirstActionFirstParameterString(
|
||||
layout.GetEvents().GetEvent(FreeFunctionWithObjectExpression)) ==
|
||||
"RenamedObjectWithMyBehavior.GetObjectNumber()");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Object renamed (in events function)") {
|
||||
@@ -894,6 +952,43 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
// Events are not tested
|
||||
}
|
||||
|
||||
SECTION("Object renamed (in events-based object)") {
|
||||
gd::Project project;
|
||||
gd::Platform platform;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
|
||||
|
||||
auto &eventsBasedObject =
|
||||
project.GetEventsFunctionsExtension("MyEventsExtension")
|
||||
.GetEventsBasedObjects()
|
||||
.Get("MyOtherEventsBasedObject");
|
||||
|
||||
// Create the objects container for the events function
|
||||
gd::ObjectsContainer globalObjectsContainer;
|
||||
|
||||
// Trigger the refactoring after the renaming of an object
|
||||
gd::WholeProjectRefactorer::ObjectOrGroupRenamedInEventsBasedObject(
|
||||
project, globalObjectsContainer, eventsBasedObject,
|
||||
"ObjectWithMyBehavior", "RenamedObjectWithMyBehavior",
|
||||
/* isObjectGroup=*/false);
|
||||
|
||||
auto &objectFunctionEvents =
|
||||
eventsBasedObject
|
||||
.GetEventsFunctions()
|
||||
.GetEventsFunction("MyObjectEventsFunction")
|
||||
.GetEvents();
|
||||
|
||||
// Check object name has been renamed in action parameters.
|
||||
REQUIRE(GetEventFirstActionFirstParameterString(
|
||||
objectFunctionEvents.GetEvent(FreeFunctionWithObjects)) ==
|
||||
"RenamedObjectWithMyBehavior");
|
||||
|
||||
// Check object name has been renamed in expressions.
|
||||
REQUIRE(GetEventFirstActionFirstParameterString(
|
||||
objectFunctionEvents.GetEvent(FreeFunctionWithObjectExpression)) ==
|
||||
"RenamedObjectWithMyBehavior.GetObjectNumber()");
|
||||
}
|
||||
|
||||
SECTION("Object deleted (in events function)") {
|
||||
gd::Project project;
|
||||
gd::Platform platform;
|
||||
@@ -948,7 +1043,7 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
|
||||
// Check that events function calls in expressions have been renamed
|
||||
REQUIRE(GetEventFirstActionFirstParameterString(
|
||||
eventsList->GetEvent(FreeFunctionExpression)) ==
|
||||
eventsList->GetEvent(FreeFunctionWithExpression)) ==
|
||||
"1 + MyRenamedExtension::MyEventsFunctionExpression(123, 456)");
|
||||
|
||||
// Check that the type of the behavior was changed in the behaviors of
|
||||
@@ -1137,7 +1232,7 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
for (auto *eventsList : GetEventsLists(project)) {
|
||||
// Check that events function calls in expressions have been renamed
|
||||
REQUIRE(GetEventFirstActionFirstParameterString(
|
||||
eventsList->GetEvent(FreeFunctionExpression)) ==
|
||||
eventsList->GetEvent(FreeFunctionWithExpression)) ==
|
||||
"1 + MyEventsExtension::MyRenamedFunctionExpression(123, 456)");
|
||||
}
|
||||
}
|
||||
@@ -1177,7 +1272,7 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
for (auto *eventsList : GetEventsLists(project)) {
|
||||
// Check that events function calls in expressions have been updated
|
||||
REQUIRE(GetEventFirstActionFirstParameterString(
|
||||
eventsList->GetEvent(FreeFunctionExpression)) ==
|
||||
eventsList->GetEvent(FreeFunctionWithExpression)) ==
|
||||
"1 + MyEventsExtension::MyEventsFunctionExpression(456, 123)");
|
||||
}
|
||||
}
|
||||
|
@@ -454,7 +454,7 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
) {
|
||||
@@ -463,7 +463,7 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
);
|
||||
@@ -507,7 +507,8 @@ module.exports = {
|
||||
* This is called to update the PIXI object on the scene editor
|
||||
*/
|
||||
RenderedBBTextInstance.prototype.update = function () {
|
||||
const properties = this._associatedObject.getProperties();
|
||||
const properties = this._associatedObjectConfiguration
|
||||
.getProperties();
|
||||
|
||||
const rawText = properties.get('text').getValue();
|
||||
if (rawText !== this._pixiObject.text) {
|
||||
|
@@ -589,7 +589,7 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
) {
|
||||
@@ -598,7 +598,7 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
);
|
||||
@@ -634,7 +634,8 @@ module.exports = {
|
||||
|
||||
// This is called to update the PIXI object on the scene editor
|
||||
RenderedBitmapTextInstance.prototype.update = function () {
|
||||
const properties = this._associatedObject.getProperties();
|
||||
const properties = this._associatedObjectConfiguration
|
||||
.getProperties();
|
||||
|
||||
// Update the rendered text properties (note: Pixi is only
|
||||
// applying changes if there were changed).
|
||||
|
@@ -506,7 +506,7 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
) {
|
||||
@@ -515,7 +515,7 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
);
|
||||
@@ -549,7 +549,7 @@ module.exports = {
|
||||
*/
|
||||
RenderedDummyObjectInstance.prototype.update = function () {
|
||||
// Read a property from the object
|
||||
const property1Value = this._associatedObject
|
||||
const property1Value = this._associatedObjectConfiguration
|
||||
.getProperties()
|
||||
.get('My first property')
|
||||
.getValue();
|
||||
|
@@ -269,7 +269,7 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
) {
|
||||
@@ -278,19 +278,19 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
);
|
||||
this._radius = parseFloat(
|
||||
this._associatedObject
|
||||
this._associatedObjectConfiguration
|
||||
.getProperties(this.project)
|
||||
.get('radius')
|
||||
.getValue()
|
||||
);
|
||||
if (this._radius <= 0) this._radius = 1;
|
||||
const colorHex = objectsRenderingService.rgbOrHexToHexNumber(
|
||||
this._associatedObject
|
||||
this._associatedObjectConfiguration
|
||||
.getProperties(this.project)
|
||||
.get('color')
|
||||
.getValue()
|
||||
|
@@ -33,24 +33,16 @@ class PanelSpriteObjectJsExtension : public gd::PlatformExtension {
|
||||
GetAllActionsForObject(
|
||||
"PanelSpriteObject::PanelSprite")["PanelSpriteObject::SetOpacity"]
|
||||
.SetFunctionName("setOpacity")
|
||||
.SetGetter("getOpacity")
|
||||
.SetIncludeFile(
|
||||
"Extensions/PanelSpriteObject/panelspriteruntimeobject.js");
|
||||
.SetGetter("getOpacity");
|
||||
GetAllConditionsForObject(
|
||||
"PanelSpriteObject::PanelSprite")["PanelSpriteObject::Opacity"]
|
||||
.SetFunctionName("getOpacity")
|
||||
.SetIncludeFile(
|
||||
"Extensions/TiledSpriteObject/panelspriteruntimeobject.js");
|
||||
.SetFunctionName("getOpacity");
|
||||
GetAllExpressionsForObject(
|
||||
"PanelSpriteObject::PanelSprite")["Opacity"]
|
||||
.SetFunctionName("getOpacity")
|
||||
.SetIncludeFile(
|
||||
"Extensions/TiledSpriteObject/panelspriteruntimeobject.js");
|
||||
.SetFunctionName("getOpacity");
|
||||
GetAllActionsForObject(
|
||||
"PanelSpriteObject::PanelSprite")["PanelSpriteObject::SetColor"]
|
||||
.SetFunctionName("setColor")
|
||||
.SetIncludeFile(
|
||||
"Extensions/TiledSpriteObject/panelspriteruntimeobject.js");
|
||||
.SetFunctionName("setColor");
|
||||
|
||||
GetAllActionsForObject(
|
||||
"PanelSpriteObject::PanelSprite")["PanelSpriteObject::Width"]
|
||||
|
@@ -19,9 +19,8 @@ This project is released under the MIT License.
|
||||
|
||||
using namespace std;
|
||||
|
||||
PanelSpriteObject::PanelSpriteObject(gd::String name_)
|
||||
: Object(name_),
|
||||
textureName(""),
|
||||
PanelSpriteObject::PanelSpriteObject()
|
||||
: textureName(""),
|
||||
width(32),
|
||||
height(32),
|
||||
leftMargin(0),
|
||||
|
@@ -10,7 +10,7 @@ This project is released under the MIT License.
|
||||
#include <memory>
|
||||
#include "GDCore/Project/Object.h"
|
||||
namespace gd {
|
||||
class Object;
|
||||
class ObjectConfiguration;
|
||||
class InitialInstance;
|
||||
class Project;
|
||||
}
|
||||
@@ -18,12 +18,12 @@ class Project;
|
||||
/**
|
||||
* PanelSprite Object
|
||||
*/
|
||||
class GD_EXTENSION_API PanelSpriteObject : public gd::Object {
|
||||
class GD_EXTENSION_API PanelSpriteObject : public gd::ObjectConfiguration {
|
||||
public:
|
||||
PanelSpriteObject(gd::String name_);
|
||||
PanelSpriteObject();
|
||||
virtual ~PanelSpriteObject();
|
||||
virtual std::unique_ptr<gd::Object> Clone() const {
|
||||
return std::unique_ptr<gd::Object>(new PanelSpriteObject(*this));
|
||||
virtual std::unique_ptr<gd::ObjectConfiguration> Clone() const {
|
||||
return std::unique_ptr<gd::ObjectConfiguration>(new PanelSpriteObject(*this));
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
|
@@ -55,8 +55,7 @@ ParticleEmitterBase::ParticleEmitterBase()
|
||||
maxParticleNb(300),
|
||||
destroyWhenNoParticles(true) {}
|
||||
|
||||
ParticleEmitterObject::ParticleEmitterObject(gd::String name_)
|
||||
: Object(name_) {}
|
||||
ParticleEmitterObject::ParticleEmitterObject() {}
|
||||
|
||||
void ParticleEmitterObject::DoUnserializeFrom(
|
||||
gd::Project& project, const gd::SerializerElement& element) {
|
||||
|
@@ -8,7 +8,7 @@ This project is released under the MIT License.
|
||||
#ifndef PARTICLEEMITTEROBJECT_H
|
||||
#define PARTICLEEMITTEROBJECT_H
|
||||
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
namespace gd {
|
||||
class InitialInstance;
|
||||
class Project;
|
||||
@@ -211,12 +211,12 @@ class GD_EXTENSION_API ParticleEmitterBase {
|
||||
/**
|
||||
* \brief Particle Emitter object used for storage and for the IDE.
|
||||
*/
|
||||
class GD_EXTENSION_API ParticleEmitterObject : public gd::Object,
|
||||
class GD_EXTENSION_API ParticleEmitterObject : public gd::ObjectConfiguration,
|
||||
public ParticleEmitterBase {
|
||||
public:
|
||||
ParticleEmitterObject(gd::String name_);
|
||||
ParticleEmitterObject();
|
||||
virtual ~ParticleEmitterObject(){};
|
||||
virtual std::unique_ptr<gd::Object> Clone() const {
|
||||
virtual std::unique_ptr<gd::ObjectConfiguration> Clone() const {
|
||||
return gd::make_unique<ParticleEmitterObject>(*this);
|
||||
}
|
||||
|
||||
|
@@ -33,7 +33,7 @@ ShapePainterObjectBase::ShapePainterObjectBase()
|
||||
clearBetweenFrames(true),
|
||||
absoluteCoordinates(false) {}
|
||||
|
||||
ShapePainterObject::ShapePainterObject(gd::String name_) : gd::Object(name_) {}
|
||||
ShapePainterObject::ShapePainterObject() {}
|
||||
|
||||
void ShapePainterObjectBase::DoUnserializeFrom(
|
||||
gd::Project& project, const gd::SerializerElement& element) {
|
||||
|
@@ -9,7 +9,7 @@ This project is released under the MIT License.
|
||||
#define SHAPEPAINTEROBJECT_H
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
namespace gd {
|
||||
class Object;
|
||||
class InitialInstance;
|
||||
@@ -88,12 +88,12 @@ class GD_EXTENSION_API ShapePainterObjectBase {
|
||||
/**
|
||||
* \brief The Shape Painter object used for storage and by the IDE.
|
||||
*/
|
||||
class GD_EXTENSION_API ShapePainterObject : public gd::Object,
|
||||
class GD_EXTENSION_API ShapePainterObject : public gd::ObjectConfiguration,
|
||||
public ShapePainterObjectBase {
|
||||
public:
|
||||
ShapePainterObject(gd::String name_);
|
||||
ShapePainterObject();
|
||||
virtual ~ShapePainterObject(){};
|
||||
virtual std::unique_ptr<gd::Object> Clone() const {
|
||||
virtual std::unique_ptr<gd::ObjectConfiguration> Clone() const {
|
||||
return gd::make_unique<ShapePainterObject>(*this);
|
||||
}
|
||||
|
||||
|
@@ -10,4 +10,4 @@ This project is released under the MIT License.
|
||||
|
||||
using namespace std;
|
||||
|
||||
TextEntryObject::TextEntryObject(gd::String name_) : Object(name_) {}
|
||||
TextEntryObject::TextEntryObject() {}
|
||||
|
@@ -7,16 +7,16 @@ This project is released under the MIT License.
|
||||
|
||||
#ifndef TEXTENTRYOBJECT_H
|
||||
#define TEXTENTRYOBJECT_H
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
|
||||
/**
|
||||
* \brief Simple object which stores user keyboard input.
|
||||
*/
|
||||
class GD_EXTENSION_API TextEntryObject : public gd::Object {
|
||||
class GD_EXTENSION_API TextEntryObject : public gd::ObjectConfiguration {
|
||||
public:
|
||||
TextEntryObject(gd::String name_);
|
||||
TextEntryObject();
|
||||
virtual ~TextEntryObject(){};
|
||||
virtual std::unique_ptr<gd::Object> Clone() const {
|
||||
virtual std::unique_ptr<gd::ObjectConfiguration> Clone() const {
|
||||
return gd::make_unique<TextEntryObject>(*this);
|
||||
}
|
||||
|
||||
|
@@ -582,7 +582,7 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
) {
|
||||
@@ -590,7 +590,7 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
);
|
||||
@@ -618,7 +618,8 @@ module.exports = {
|
||||
|
||||
update() {
|
||||
const instance = this._instance;
|
||||
const properties = this._associatedObject.getProperties();
|
||||
const properties = this._associatedObjectConfiguration
|
||||
.getProperties();
|
||||
|
||||
const placeholder =
|
||||
instance.getRawStringProperty('placeholder') ||
|
||||
|
@@ -19,9 +19,8 @@ This project is released under the MIT License.
|
||||
|
||||
using namespace std;
|
||||
|
||||
TextObject::TextObject(gd::String name_)
|
||||
: Object(name_),
|
||||
text("Text"),
|
||||
TextObject::TextObject()
|
||||
: text("Text"),
|
||||
characterSize(20),
|
||||
fontName(""),
|
||||
smoothed(true),
|
||||
|
@@ -7,7 +7,7 @@ This project is released under the MIT License.
|
||||
|
||||
#ifndef TEXTOBJECT_H
|
||||
#define TEXTOBJECT_H
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
namespace gd {
|
||||
class Project;
|
||||
class Object;
|
||||
@@ -17,11 +17,11 @@ class InitialInstance;
|
||||
/**
|
||||
* Text Object
|
||||
*/
|
||||
class GD_EXTENSION_API TextObject : public gd::Object {
|
||||
class GD_EXTENSION_API TextObject : public gd::ObjectConfiguration {
|
||||
public:
|
||||
TextObject(gd::String name_);
|
||||
TextObject();
|
||||
virtual ~TextObject();
|
||||
virtual std::unique_ptr<gd::Object> Clone() const {
|
||||
virtual std::unique_ptr<gd::ObjectConfiguration> Clone() const {
|
||||
return gd::make_unique<TextObject>(*this);
|
||||
}
|
||||
|
||||
|
@@ -940,26 +940,23 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader,
|
||||
pixiRenderer
|
||||
pixiResourcesLoader
|
||||
) {
|
||||
RenderedInstance.call(
|
||||
this,
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader,
|
||||
pixiRenderer
|
||||
pixiResourcesLoader
|
||||
);
|
||||
|
||||
// This setting allows tile maps with more than 16K tiles.
|
||||
Tilemap.settings.use32bitIndex = true;
|
||||
pixiRenderer.plugins.tilemap =
|
||||
pixiRenderer.plugins.tilemap || new Tilemap.TileRenderer();
|
||||
|
||||
this.tileMapPixiObject = new Tilemap.CompositeTilemap();
|
||||
this._pixiObject = this.tileMapPixiObject;
|
||||
|
||||
@@ -1020,26 +1017,26 @@ module.exports = {
|
||||
*/
|
||||
RenderedTileMapInstance.prototype.updateTileMap = function () {
|
||||
// Get the tileset resource to use
|
||||
const tilemapAtlasImage = this._associatedObject
|
||||
const tilemapAtlasImage = this._associatedObjectConfiguration
|
||||
.getProperties(this.project)
|
||||
.get('tilemapAtlasImage')
|
||||
.getValue();
|
||||
const tilemapJsonFile = this._associatedObject
|
||||
const tilemapJsonFile = this._associatedObjectConfiguration
|
||||
.getProperties(this.project)
|
||||
.get('tilemapJsonFile')
|
||||
.getValue();
|
||||
const tilesetJsonFile = this._associatedObject
|
||||
const tilesetJsonFile = this._associatedObjectConfiguration
|
||||
.getProperties(this.project)
|
||||
.get('tilesetJsonFile')
|
||||
.getValue();
|
||||
const layerIndex = parseInt(
|
||||
this._associatedObject
|
||||
this._associatedObjectConfiguration
|
||||
.getProperties(this.project)
|
||||
.get('layerIndex')
|
||||
.getValue(),
|
||||
10
|
||||
);
|
||||
const displayMode = this._associatedObject
|
||||
const displayMode = this._associatedObjectConfiguration
|
||||
.getProperties(this.project)
|
||||
.get('displayMode')
|
||||
.getValue();
|
||||
@@ -1187,7 +1184,7 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
) {
|
||||
@@ -1196,7 +1193,7 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
);
|
||||
@@ -1262,39 +1259,39 @@ module.exports = {
|
||||
*/
|
||||
RenderedCollisionMaskInstance.prototype.updateTileMap = function () {
|
||||
// Get the tileset resource to use
|
||||
const tilemapAtlasImage = this._associatedObject
|
||||
const tilemapAtlasImage = this._associatedObjectConfiguration
|
||||
.getProperties(this.project)
|
||||
.get('tilemapAtlasImage')
|
||||
.getValue();
|
||||
const tilemapJsonFile = this._associatedObject
|
||||
const tilemapJsonFile = this._associatedObjectConfiguration
|
||||
.getProperties(this.project)
|
||||
.get('tilemapJsonFile')
|
||||
.getValue();
|
||||
const tilesetJsonFile = this._associatedObject
|
||||
const tilesetJsonFile = this._associatedObjectConfiguration
|
||||
.getProperties(this.project)
|
||||
.get('tilesetJsonFile')
|
||||
.getValue();
|
||||
const collisionMaskTag = this._associatedObject
|
||||
const collisionMaskTag = this._associatedObjectConfiguration
|
||||
.getProperties(this.project)
|
||||
.get('collisionMaskTag')
|
||||
.getValue();
|
||||
const outlineColor = objectsRenderingService.rgbOrHexToHexNumber(
|
||||
this._associatedObject
|
||||
this._associatedObjectConfiguration
|
||||
.getProperties(this.project)
|
||||
.get('outlineColor')
|
||||
.getValue()
|
||||
);
|
||||
const fillColor = objectsRenderingService.rgbOrHexToHexNumber(
|
||||
this._associatedObject
|
||||
this._associatedObjectConfiguration
|
||||
.getProperties(this.project)
|
||||
.get('fillColor')
|
||||
.getValue()
|
||||
);
|
||||
const outlineOpacity = this._associatedObject
|
||||
const outlineOpacity = this._associatedObjectConfiguration
|
||||
.getProperties(this.project)
|
||||
.get('outlineOpacity')
|
||||
.getValue() / 255;
|
||||
const fillOpacity = this._associatedObject
|
||||
const fillOpacity = this._associatedObjectConfiguration
|
||||
.getProperties(this.project)
|
||||
.get('fillOpacity')
|
||||
.getValue() / 255;
|
||||
|
@@ -10,7 +10,6 @@ namespace gdjs {
|
||||
*/
|
||||
export class TileMapRuntimeObjectPixiRenderer {
|
||||
private _object: any;
|
||||
private _runtimeScene: gdjs.RuntimeScene;
|
||||
private _tileMap: TileMapHelper.EditableTileMap | null = null;
|
||||
|
||||
private _pixiObject: PIXI.tilemap.CompositeTilemap;
|
||||
@@ -24,20 +23,9 @@ namespace gdjs {
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
this._object = runtimeObject;
|
||||
this._runtimeScene = runtimeScene;
|
||||
|
||||
const pixiRenderer = runtimeScene
|
||||
.getGame()
|
||||
.getRenderer()
|
||||
.getPIXIRenderer();
|
||||
|
||||
// This setting allows tile maps with more than 16K tiles.
|
||||
PIXI.tilemap.settings.use32bitIndex = true;
|
||||
if (pixiRenderer) {
|
||||
pixiRenderer.plugins.tilemap =
|
||||
// @ts-ignore - pixi-tilemap types to be added.
|
||||
pixiRenderer.plugins.tilemap || new PIXI.tilemap.TileRenderer();
|
||||
}
|
||||
|
||||
// Load (or reset)
|
||||
this._pixiObject = new PIXI.tilemap.CompositeTilemap();
|
||||
|
@@ -20,8 +20,8 @@ This project is released under the MIT License.
|
||||
|
||||
using namespace std;
|
||||
|
||||
TiledSpriteObject::TiledSpriteObject(gd::String name_)
|
||||
: Object(name_), textureName(""), width(32), height(32) {}
|
||||
TiledSpriteObject::TiledSpriteObject()
|
||||
: textureName(""), width(32), height(32) {}
|
||||
|
||||
void TiledSpriteObject::DoUnserializeFrom(
|
||||
gd::Project& project, const gd::SerializerElement& element) {
|
||||
@@ -40,4 +40,4 @@ void TiledSpriteObject::DoSerializeTo(gd::SerializerElement& element) const {
|
||||
void TiledSpriteObject::ExposeResources(gd::ArbitraryResourceWorker& worker) {
|
||||
worker.ExposeImage(textureName);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@@ -8,7 +8,7 @@ This project is released under the MIT License.
|
||||
#ifndef TILEDSPRITEOBJECT_H
|
||||
#define TILEDSPRITEOBJECT_H
|
||||
#include <memory>
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
namespace gd {
|
||||
class InitialInstance;
|
||||
class Project;
|
||||
@@ -17,11 +17,11 @@ class Project;
|
||||
/**
|
||||
* TiledSprite Object
|
||||
*/
|
||||
class GD_EXTENSION_API TiledSpriteObject : public gd::Object {
|
||||
class GD_EXTENSION_API TiledSpriteObject : public gd::ObjectConfiguration {
|
||||
public:
|
||||
TiledSpriteObject(gd::String name_);
|
||||
TiledSpriteObject();
|
||||
virtual ~TiledSpriteObject(){};
|
||||
virtual std::unique_ptr<gd::Object> Clone() const {
|
||||
virtual std::unique_ptr<gd::ObjectConfiguration> Clone() const {
|
||||
return gd::make_unique<TiledSpriteObject>(*this);
|
||||
}
|
||||
|
||||
|
@@ -528,7 +528,7 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
) {
|
||||
@@ -537,7 +537,7 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
);
|
||||
@@ -568,7 +568,7 @@ module.exports = {
|
||||
|
||||
RenderedVideoObjectInstance.prototype._getVideoTexture = function () {
|
||||
// Get the video resource to use
|
||||
const videoResource = this._associatedObject
|
||||
const videoResource = this._associatedObjectConfiguration
|
||||
.getProperties()
|
||||
.get('videoResource')
|
||||
.getValue();
|
||||
@@ -585,7 +585,7 @@ module.exports = {
|
||||
*/
|
||||
RenderedVideoObjectInstance.prototype.update = function () {
|
||||
// Check if the video resource has changed
|
||||
const videoResource = this._associatedObject
|
||||
const videoResource = this._associatedObjectConfiguration
|
||||
.getProperties()
|
||||
.get('videoResource')
|
||||
.getValue();
|
||||
@@ -606,7 +606,7 @@ module.exports = {
|
||||
}
|
||||
|
||||
// Update opacity
|
||||
const opacity = this._associatedObject
|
||||
const opacity = this._associatedObjectConfiguration
|
||||
.getProperties()
|
||||
.get('Opacity')
|
||||
.getValue();
|
||||
|
@@ -6,6 +6,20 @@
|
||||
namespace gdjs {
|
||||
const logger = new gdjs.Logger('Font manager');
|
||||
|
||||
const checkIfCredentialsRequired = (url: string) => {
|
||||
// Any resource stored on the GDevelop Cloud buckets needs the "credentials" of the user,
|
||||
// i.e: its gdevelop.io cookie, to be passed.
|
||||
// Note that this is only useful during previews.
|
||||
if (
|
||||
url.startsWith('https://project-resources.gdevelop.io/') ||
|
||||
url.startsWith('https://project-resources-dev.gdevelop.io/')
|
||||
)
|
||||
return true;
|
||||
|
||||
// For other resources, use the default way of loading resources ("anonymous" or "same-site").
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* FontFaceObserverFontManager loads fonts (using `FontFace` or `fontfaceobserver` library)
|
||||
* from the game resources (see `loadFonts`), and allow to access to
|
||||
@@ -121,13 +135,40 @@ namespace gdjs {
|
||||
// @ts-ignore
|
||||
if (typeof FontFace !== 'undefined') {
|
||||
// Load the given font using CSS Font Loading API.
|
||||
// @ts-ignore
|
||||
const fontFace = new FontFace(fontFamily, srcWithUrl, descriptors);
|
||||
return fetch(src, {
|
||||
credentials: checkIfCredentialsRequired(src)
|
||||
? // Any resource stored on the GDevelop Cloud buckets needs the "credentials" of the user,
|
||||
// i.e: its gdevelop.io cookie, to be passed.
|
||||
'include'
|
||||
: // For other resources, use "same-origin" as done by default by fetch.
|
||||
'same-origin',
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
const errorMessage =
|
||||
'Unable to fetch ' +
|
||||
src +
|
||||
' to be loaded as a font. HTTP status is: ' +
|
||||
response.status +
|
||||
'.';
|
||||
logger.error(errorMessage);
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
document.fonts.add(fontFace);
|
||||
return fontFace.load();
|
||||
return response.arrayBuffer();
|
||||
})
|
||||
.then((arrayBuffer) => {
|
||||
// @ts-ignore
|
||||
const fontFace = new FontFace(fontFamily, arrayBuffer, descriptors);
|
||||
|
||||
// @ts-ignore
|
||||
document.fonts.add(fontFace);
|
||||
});
|
||||
} else {
|
||||
// TODO: this method of loading font should be removed as old and not allowing
|
||||
// to handle loading with credentials. All moderns and not-so-modern browsers
|
||||
// that we support also support FontFace API.
|
||||
|
||||
// Add @font-face and use FontFaceObserver to be notified when the
|
||||
// font is ready.
|
||||
const newStyle = document.createElement('style');
|
||||
|
@@ -15,6 +15,20 @@ namespace gdjs {
|
||||
logger.error('Error while loading an audio file: ' + error),
|
||||
};
|
||||
|
||||
const checkIfCredentialsRequired = (url: string) => {
|
||||
// Any resource stored on the GDevelop Cloud buckets needs the "credentials" of the user,
|
||||
// i.e: its gdevelop.io cookie, to be passed.
|
||||
// Note that this is only useful during previews.
|
||||
if (
|
||||
url.startsWith('https://project-resources.gdevelop.io/') ||
|
||||
url.startsWith('https://project-resources-dev.gdevelop.io/')
|
||||
)
|
||||
return true;
|
||||
|
||||
// For other resources, use the default way of loading resources ("anonymous" or "same-site").
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ensure the volume is between 0 and 1.
|
||||
*/
|
||||
@@ -517,6 +531,9 @@ namespace gdjs {
|
||||
{
|
||||
src: [soundFile],
|
||||
html5: isMusic,
|
||||
xhr: {
|
||||
withCredentials: checkIfCredentialsRequired(soundFile),
|
||||
},
|
||||
// Cache the sound with no volume. This avoids a bug where it plays at full volume
|
||||
// for a split second before setting its correct volume.
|
||||
volume: 0,
|
||||
@@ -551,6 +568,9 @@ namespace gdjs {
|
||||
{
|
||||
src: [soundFile],
|
||||
html5: isMusic,
|
||||
xhr: {
|
||||
withCredentials: checkIfCredentialsRequired(soundFile),
|
||||
},
|
||||
// Cache the sound with no volume. This avoids a bug where it plays at full volume
|
||||
// for a split second before setting its correct volume.
|
||||
volume: 0,
|
||||
@@ -791,6 +811,9 @@ namespace gdjs {
|
||||
onload: onLoadCallback,
|
||||
onloaderror: onLoadCallback,
|
||||
html5: isMusic,
|
||||
xhr: {
|
||||
withCredentials: checkIfCredentialsRequired(file),
|
||||
},
|
||||
// Cache the sound with no volume. This avoids a bug where it plays at full volume
|
||||
// for a split second before setting its correct volume.
|
||||
volume: 0,
|
||||
@@ -823,6 +846,7 @@ namespace gdjs {
|
||||
// preloading as sound already does a XHR request, hence "else if"
|
||||
loadCounter++;
|
||||
const sound = new XMLHttpRequest();
|
||||
sound.withCredentials = checkIfCredentialsRequired(file);
|
||||
sound.addEventListener('load', callback);
|
||||
sound.addEventListener('error', (_) =>
|
||||
callback(_, 'XHR error: ' + file)
|
||||
|
@@ -17,6 +17,20 @@ namespace gdjs {
|
||||
content: Object | null
|
||||
) => void;
|
||||
|
||||
const checkIfCredentialsRequired = (url: string) => {
|
||||
// Any resource stored on the GDevelop Cloud buckets needs the "credentials" of the user,
|
||||
// i.e: its gdevelop.io cookie, to be passed.
|
||||
// Note that this is only useful during previews.
|
||||
if (
|
||||
url.startsWith('https://project-resources.gdevelop.io/') ||
|
||||
url.startsWith('https://project-resources-dev.gdevelop.io/')
|
||||
)
|
||||
return true;
|
||||
|
||||
// For other resources, use the default way of loading resources ("anonymous" or "same-site").
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* JsonManager loads json files (using `XMLHttpRequest`), using the "json" resources
|
||||
* registered in the game resources.
|
||||
@@ -127,6 +141,7 @@ namespace gdjs {
|
||||
const that = this;
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.responseType = 'json';
|
||||
xhr.withCredentials = checkIfCredentialsRequired(resource.file);
|
||||
xhr.open('GET', resource.file);
|
||||
xhr.onload = function () {
|
||||
const callbacks = that._callbacks[resourceName];
|
||||
|
@@ -16,6 +16,20 @@ namespace gdjs {
|
||||
// Set this to 0 to unload from memory ("uninstall") as soon as a font is unused.
|
||||
const uninstallCacheSize = 5;
|
||||
|
||||
const checkIfCredentialsRequired = (url: string) => {
|
||||
// Any resource stored on the GDevelop Cloud buckets needs the "credentials" of the user,
|
||||
// i.e: its gdevelop.io cookie, to be passed.
|
||||
// Note that this is only useful during previews.
|
||||
if (
|
||||
url.startsWith('https://project-resources.gdevelop.io/') ||
|
||||
url.startsWith('https://project-resources-dev.gdevelop.io/')
|
||||
)
|
||||
return true;
|
||||
|
||||
// For other resources, use the default way of loading resources ("anonymous" or "same-site").
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* We patch the installed font to use a name that is unique for each font data and texture,
|
||||
* to avoid conflicts between different font files using the same font name (by default, the
|
||||
@@ -261,7 +275,14 @@ namespace gdjs {
|
||||
let loadedCount = 0;
|
||||
return Promise.all(
|
||||
bitmapFontResources.map((bitmapFontResource) => {
|
||||
return fetch(bitmapFontResource.file)
|
||||
return fetch(bitmapFontResource.file, {
|
||||
credentials: checkIfCredentialsRequired(bitmapFontResource.file)
|
||||
? // Any resource stored on the GDevelop Cloud buckets needs the "credentials" of the user,
|
||||
// i.e: its gdevelop.io cookie, to be passed.
|
||||
'include'
|
||||
: // For other resources, use "same-origin" as done by default by fetch.
|
||||
'same-origin',
|
||||
})
|
||||
.then((response) => response.text())
|
||||
.then((fontData) => {
|
||||
this._loadedFontsData[bitmapFontResource.name] = fontData;
|
||||
|
@@ -40,7 +40,7 @@ namespace gdjs {
|
||||
return null;
|
||||
};
|
||||
|
||||
const determineCrossOrigin = (url: string) => {
|
||||
const checkIfCredentialsRequired = (url: string) => {
|
||||
// Any resource stored on the GDevelop Cloud buckets needs the "credentials" of the user,
|
||||
// i.e: its gdevelop.io cookie, to be passed.
|
||||
// Note that this is only useful during previews.
|
||||
@@ -48,12 +48,10 @@ namespace gdjs {
|
||||
url.startsWith('https://project-resources.gdevelop.io/') ||
|
||||
url.startsWith('https://project-resources-dev.gdevelop.io/')
|
||||
)
|
||||
return 'use-credentials';
|
||||
return true;
|
||||
|
||||
// For other resources, use "anonymous" as done by default by PixiJS. Note that using `false`
|
||||
// to not having `crossorigin` at all would NOT work because the browser would taint the
|
||||
// loaded resource so that it can't be read/used in a canvas (it's only working for display `<img>` on screen).
|
||||
return 'anonymous';
|
||||
// For other resources, use the default way of loading resources ("anonymous" or "same-site").
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -134,7 +132,12 @@ namespace gdjs {
|
||||
const file = resource.file;
|
||||
const texture = PIXI.Texture.from(file, {
|
||||
resourceOptions: {
|
||||
crossorigin: determineCrossOrigin(file),
|
||||
// Note that using `false`
|
||||
// to not having `crossorigin` at all would NOT work because the browser would taint the
|
||||
// loaded resource so that it can't be read/used in a canvas (it's only working for display `<img>` on screen).
|
||||
crossorigin: checkIfCredentialsRequired(file)
|
||||
? 'use-credentials'
|
||||
: 'anonymous',
|
||||
},
|
||||
}).on('error', (error) => {
|
||||
logFileLoadingError(file, error);
|
||||
@@ -178,7 +181,12 @@ namespace gdjs {
|
||||
);
|
||||
const texture = PIXI.Texture.from(file, {
|
||||
resourceOptions: {
|
||||
crossorigin: determineCrossOrigin(file),
|
||||
// Note that using `false`
|
||||
// to not having `crossorigin` at all would NOT work because the browser would taint the
|
||||
// loaded resource so that it can't be read/used in a canvas (it's only working for display `<img>` on screen).
|
||||
crossorigin: checkIfCredentialsRequired(file)
|
||||
? 'use-credentials'
|
||||
: 'anonymous',
|
||||
},
|
||||
}).on('error', (error) => {
|
||||
logFileLoadingError(file, error);
|
||||
@@ -239,7 +247,9 @@ namespace gdjs {
|
||||
name: file,
|
||||
url: file,
|
||||
loadType: PIXI.LoaderResource.LOAD_TYPE.IMAGE,
|
||||
crossOrigin: determineCrossOrigin(file),
|
||||
crossOrigin: checkIfCredentialsRequired(file)
|
||||
? 'use-credentials'
|
||||
: 'anonymous',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -121,8 +121,8 @@ interface ProjectHelper {
|
||||
void STATIC_InitializePlatforms();
|
||||
[Const, Value] DOMString STATIC_SanityCheckBehaviorProperty(Behavior behavior, [Const] DOMString propertyName, [Const] DOMString newValue);
|
||||
[Const, Value] DOMString STATIC_SanityCheckBehaviorsSharedDataProperty(BehaviorsSharedData behavior, [Const] DOMString propertyName, [Const] DOMString newValue);
|
||||
[Const, Value] DOMString STATIC_SanityCheckObjectProperty(gdObject obj, [Const] DOMString propertyName, [Const] DOMString newValue);
|
||||
[Const, Value] DOMString STATIC_SanityCheckObjectInitialInstanceProperty(gdObject obj, [Const] DOMString propertyName, [Const] DOMString newValue);
|
||||
[Const, Value] DOMString STATIC_SanityCheckObjectProperty(ObjectConfiguration configuration, [Const] DOMString propertyName, [Const] DOMString newValue);
|
||||
[Const, Value] DOMString STATIC_SanityCheckObjectInitialInstanceProperty(ObjectConfiguration configuration, [Const] DOMString propertyName, [Const] DOMString newValue);
|
||||
};
|
||||
|
||||
interface EventsVariablesFinder {
|
||||
@@ -543,10 +543,33 @@ interface BehaviorSharedDataJsImplementation {
|
||||
void InitializeContent([Ref] SerializerElement behaviorSharedDataContent);
|
||||
};
|
||||
|
||||
interface ObjectConfiguration {
|
||||
void ObjectConfiguration();
|
||||
[Value] UniquePtrObjectConfiguration Clone();
|
||||
|
||||
[Const, Ref] DOMString GetType();
|
||||
|
||||
[Value] MapStringPropertyDescriptor GetProperties();
|
||||
boolean UpdateProperty([Const] DOMString name, [Const] DOMString value);
|
||||
|
||||
[Value] MapStringPropertyDescriptor GetInitialInstanceProperties([Const, Ref] InitialInstance instance, [Ref] Project project, [Ref] Layout scene);
|
||||
boolean UpdateInitialInstanceProperty([Ref] InitialInstance instance, [Const] DOMString name, [Const] DOMString value, [Ref] Project project, [Ref] Layout scene);
|
||||
|
||||
void ExposeResources([Ref] ArbitraryResourceWorker worker);
|
||||
|
||||
void SerializeTo([Ref] SerializerElement element);
|
||||
void UnserializeFrom([Ref] Project project, [Const, Ref] SerializerElement element);
|
||||
};
|
||||
|
||||
interface UniquePtrObjectConfiguration {
|
||||
ObjectConfiguration get();
|
||||
ObjectConfiguration release();
|
||||
};
|
||||
|
||||
interface gdObject {
|
||||
// /!\ We need to call it gdObject to avoid messing up with javascript Object
|
||||
// global in glue.js!
|
||||
void gdObject([Const] DOMString name);
|
||||
void gdObject([Const] DOMString name, [Const] DOMString type, ObjectConfiguration configuration);
|
||||
[Value] UniquePtrObject Clone();
|
||||
|
||||
void SetName([Const] DOMString name);
|
||||
@@ -558,13 +581,7 @@ interface gdObject {
|
||||
void SetTags([Const] DOMString tags);
|
||||
[Const, Ref] DOMString GetTags();
|
||||
|
||||
[Value] MapStringPropertyDescriptor GetProperties();
|
||||
boolean UpdateProperty([Const] DOMString name, [Const] DOMString value);
|
||||
|
||||
[Value] MapStringPropertyDescriptor GetInitialInstanceProperties([Const, Ref] InitialInstance instance, [Ref] Project project, [Ref] Layout scene);
|
||||
boolean UpdateInitialInstanceProperty([Ref] InitialInstance instance, [Const] DOMString name, [Const] DOMString value, [Ref] Project project, [Ref] Layout scene);
|
||||
|
||||
void ExposeResources([Ref] ArbitraryResourceWorker worker);
|
||||
[Ref] ObjectConfiguration GetConfiguration();
|
||||
|
||||
[Ref] VariablesContainer GetVariables();
|
||||
[Ref] EffectsContainer GetEffects();
|
||||
@@ -584,10 +601,10 @@ interface UniquePtrObject {
|
||||
gdObject release();
|
||||
};
|
||||
|
||||
[JSImplementation=gdObject]
|
||||
[JSImplementation=ObjectConfiguration]
|
||||
interface ObjectJsImplementation {
|
||||
void ObjectJsImplementation();
|
||||
[Value] UniquePtrObject Clone();
|
||||
[Value] UniquePtrObjectConfiguration Clone();
|
||||
|
||||
[Value] MapStringPropertyDescriptor GetProperties();
|
||||
boolean UpdateProperty([Const] DOMString name, [Const] DOMString value);
|
||||
@@ -606,6 +623,19 @@ interface ObjectJsImplementation {
|
||||
// void DoUnserializeFrom([Ref] Project project, [Const, Ref] SerializerElement element);
|
||||
};
|
||||
|
||||
interface CustomObjectConfiguration {
|
||||
[Value] UniquePtrObjectConfiguration Clone();
|
||||
|
||||
[Ref] ObjectConfiguration GetChildObjectConfiguration([Const] DOMString objectName);
|
||||
|
||||
[Value] MapStringPropertyDescriptor GetProperties();
|
||||
boolean UpdateProperty([Const] DOMString name, [Const] DOMString value);
|
||||
|
||||
[Value] MapStringPropertyDescriptor GetInitialInstanceProperties([Const, Ref] InitialInstance instance, [Ref] Project project, [Ref] Layout scene);
|
||||
boolean UpdateInitialInstanceProperty([Ref] InitialInstance instance, [Const] DOMString name, [Const] DOMString value, [Ref] Project project, [Ref] Layout scene);
|
||||
};
|
||||
CustomObjectConfiguration implements ObjectConfiguration;
|
||||
|
||||
interface Layout {
|
||||
void Layout();
|
||||
|
||||
@@ -1600,7 +1630,7 @@ interface PlatformExtension {
|
||||
[Const] DOMString fullname,
|
||||
[Const] DOMString description,
|
||||
[Const] DOMString icon24x24,
|
||||
gdObject instance);
|
||||
ObjectConfiguration instance);
|
||||
|
||||
[Ref] ObjectMetadata AddEventsBasedObject([Const] DOMString name,
|
||||
[Const] DOMString fullname,
|
||||
@@ -2047,7 +2077,7 @@ interface WholeProjectRefactorer {
|
||||
void STATIC_ObjectOrGroupRemovedInLayout([Ref] Project project, [Ref] Layout layout, [Const] DOMString objectName, boolean isObjectGroup, boolean removeEventsAndGroups);
|
||||
void STATIC_ObjectOrGroupRenamedInEventsFunction([Ref] Project project, [Ref] EventsFunction eventsFunction, [Ref] ObjectsContainer globalObjectsContainer, [Ref] ObjectsContainer objectsContainer, [Const] DOMString oldName, [Const] DOMString newName, boolean isObjectGroup);
|
||||
void STATIC_ObjectOrGroupRemovedInEventsFunction([Ref] Project project, [Ref] EventsFunction eventsFunction, [Ref] ObjectsContainer globalObjectsContainer, [Ref] ObjectsContainer objectsContainer, [Const] DOMString objectName, boolean isObjectGroup, boolean removeEventsAndGroups);
|
||||
void STATIC_ObjectOrGroupRenamedInEventsBasedObject([Ref] Project project, [Ref] EventsBasedObject eventsBasedObject, [Ref] ObjectsContainer globalObjectsContainer, [Ref] ObjectsContainer objectsContainer, [Const] DOMString oldName, [Const] DOMString newName, boolean isObjectGroup);
|
||||
void STATIC_ObjectOrGroupRenamedInEventsBasedObject([Ref] Project project, [Ref] ObjectsContainer globalObjectsContainer, [Ref] EventsBasedObject eventsBasedObject, [Const] DOMString oldName, [Const] DOMString newName, boolean isObjectGroup);
|
||||
void STATIC_ObjectOrGroupRemovedInEventsBasedObject([Ref] Project project, [Ref] EventsBasedObject eventsBasedObject, [Ref] ObjectsContainer globalObjectsContainer, [Ref] ObjectsContainer objectsContainer, [Const] DOMString objectName, boolean isObjectGroup, boolean removeEventsAndGroups);
|
||||
void STATIC_GlobalObjectOrGroupRenamed([Ref] Project project, [Const] DOMString oldName, [Const] DOMString newName, boolean isObjectGroup);
|
||||
void STATIC_GlobalObjectOrGroupRemoved([Ref] Project project, [Const] DOMString objectName, boolean isObjectGroup, boolean removeEventsAndGroups);
|
||||
@@ -2298,24 +2328,11 @@ interface EventsBasedObject {
|
||||
void SerializeTo([Ref] SerializerElement element);
|
||||
void UnserializeFrom([Ref] Project project, [Const, Ref] SerializerElement element);
|
||||
|
||||
//Inherited from gd::ObjectsContainer
|
||||
[Ref] gdObject InsertNewObject([Ref] Project project, [Const] DOMString type, [Const] DOMString name, unsigned long pos);
|
||||
[Ref] gdObject InsertObject([Const, Ref] gdObject obj, unsigned long pos);
|
||||
boolean HasObjectNamed([Const] DOMString name);
|
||||
[Ref] gdObject GetObject([Const] DOMString name);
|
||||
[Ref] gdObject GetObjectAt(unsigned long pos);
|
||||
unsigned long GetObjectPosition([Const] DOMString name);
|
||||
void RemoveObject([Const] DOMString name);
|
||||
void SwapObjects(unsigned long first, unsigned long second);
|
||||
void MoveObject(unsigned long oldIndex, unsigned long newIndex);
|
||||
void MoveObjectToAnotherContainer([Const] DOMString name, [Ref] ObjectsContainer newObjectsContainer, unsigned long newPosition);
|
||||
unsigned long GetObjectsCount();
|
||||
[Ref] ObjectGroupsContainer GetObjectGroups();
|
||||
|
||||
[Const, Value] DOMString STATIC_GetPropertyActionName([Const] DOMString propertyName);
|
||||
[Const, Value] DOMString STATIC_GetPropertyConditionName([Const] DOMString propertyName);
|
||||
[Const, Value] DOMString STATIC_GetPropertyExpressionName([Const] DOMString propertyName);
|
||||
};
|
||||
EventsBasedObject implements ObjectsContainer;
|
||||
|
||||
interface EventsBasedObjectsList {
|
||||
[Ref] EventsBasedObject InsertNew([Const] DOMString name, unsigned long pos);
|
||||
@@ -2659,7 +2676,7 @@ interface Animation {
|
||||
};
|
||||
|
||||
interface SpriteObject {
|
||||
void SpriteObject([Const] DOMString name);
|
||||
void SpriteObject();
|
||||
|
||||
void AddAnimation([Const, Ref] Animation animation);
|
||||
[Ref] Animation GetAnimation(unsigned long index);
|
||||
@@ -2673,7 +2690,7 @@ interface SpriteObject {
|
||||
void SetUpdateIfNotVisible(boolean updateIfNotVisible);
|
||||
boolean GetUpdateIfNotVisible();
|
||||
};
|
||||
SpriteObject implements gdObject;
|
||||
SpriteObject implements ObjectConfiguration;
|
||||
|
||||
interface Vector2f {
|
||||
void Vector2f();
|
||||
@@ -2697,7 +2714,7 @@ interface VectorVector2f {
|
||||
//Extensions bindings:
|
||||
|
||||
interface TextObject {
|
||||
void TextObject([Const] DOMString name);
|
||||
void TextObject();
|
||||
|
||||
void SetString([Const] DOMString string);
|
||||
[Const, Ref] DOMString GetString();
|
||||
@@ -2716,10 +2733,10 @@ interface TextObject {
|
||||
unsigned long GetColorG();
|
||||
unsigned long GetColorB();
|
||||
};
|
||||
TextObject implements gdObject;
|
||||
TextObject implements ObjectConfiguration;
|
||||
|
||||
interface TiledSpriteObject {
|
||||
void TiledSpriteObject([Const] DOMString name);
|
||||
void TiledSpriteObject();
|
||||
|
||||
void SetTexture([Const] DOMString texture);
|
||||
[Const, Ref] DOMString GetTexture();
|
||||
@@ -2728,10 +2745,10 @@ interface TiledSpriteObject {
|
||||
void SetHeight(float height);
|
||||
float GetHeight();
|
||||
};
|
||||
TiledSpriteObject implements gdObject;
|
||||
TiledSpriteObject implements ObjectConfiguration;
|
||||
|
||||
interface PanelSpriteObject {
|
||||
void PanelSpriteObject([Const] DOMString name);
|
||||
void PanelSpriteObject();
|
||||
|
||||
float GetLeftMargin();
|
||||
void SetLeftMargin(float newMargin);
|
||||
@@ -2756,10 +2773,10 @@ interface PanelSpriteObject {
|
||||
void SetHeight(float height);
|
||||
float GetHeight();
|
||||
};
|
||||
PanelSpriteObject implements gdObject;
|
||||
PanelSpriteObject implements ObjectConfiguration;
|
||||
|
||||
interface ShapePainterObject {
|
||||
void ShapePainterObject([Const] DOMString name);
|
||||
void ShapePainterObject();
|
||||
|
||||
void SetCoordinatesAbsolute();
|
||||
void SetCoordinatesRelative();
|
||||
@@ -2787,12 +2804,12 @@ interface ShapePainterObject {
|
||||
unsigned long GetFillColorG();
|
||||
unsigned long GetFillColorB();
|
||||
};
|
||||
ShapePainterObject implements gdObject;
|
||||
ShapePainterObject implements ObjectConfiguration;
|
||||
|
||||
interface TextEntryObject {
|
||||
void TextEntryObject([Const] DOMString name);
|
||||
void TextEntryObject();
|
||||
};
|
||||
TextEntryObject implements gdObject;
|
||||
TextEntryObject implements ObjectConfiguration;
|
||||
|
||||
enum ParticleEmitterObject_RendererType {
|
||||
"ParticleEmitterObject::Point",
|
||||
@@ -2801,7 +2818,7 @@ enum ParticleEmitterObject_RendererType {
|
||||
};
|
||||
|
||||
interface ParticleEmitterObject {
|
||||
void ParticleEmitterObject([Const] DOMString name);
|
||||
void ParticleEmitterObject();
|
||||
|
||||
void SetRendererType(ParticleEmitterObject_RendererType type);
|
||||
ParticleEmitterObject_RendererType GetRendererType();
|
||||
@@ -2889,7 +2906,7 @@ interface ParticleEmitterObject {
|
||||
float GetParticleAngleRandomness2();
|
||||
|
||||
};
|
||||
ParticleEmitterObject implements gdObject;
|
||||
ParticleEmitterObject implements ObjectConfiguration;
|
||||
|
||||
//GDJS bindings:
|
||||
[Prefix="gdjs::"]
|
||||
|
@@ -12,7 +12,7 @@
|
||||
|
||||
using namespace gd;
|
||||
|
||||
std::unique_ptr<gd::Object> ObjectJsImplementation::Clone() const {
|
||||
std::unique_ptr<gd::ObjectConfiguration> ObjectJsImplementation::Clone() const {
|
||||
ObjectJsImplementation* clone = new ObjectJsImplementation(*this);
|
||||
|
||||
// Copy the references to the JS implementations of the functions (because we
|
||||
@@ -31,7 +31,7 @@ std::unique_ptr<gd::Object> ObjectJsImplementation::Clone() const {
|
||||
(int)clone,
|
||||
(int)this);
|
||||
|
||||
return std::unique_ptr<gd::Object>(clone);
|
||||
return std::unique_ptr<gd::ObjectConfiguration>(clone);
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor>
|
||||
@@ -144,12 +144,12 @@ bool ObjectJsImplementation::UpdateInitialInstanceProperty(
|
||||
(int)&scene);
|
||||
}
|
||||
|
||||
void ObjectJsImplementation::DoSerializeTo(SerializerElement& arg0) const {
|
||||
arg0.AddChild("content") = gd::Serializer::FromJSON(jsonContent);
|
||||
void ObjectJsImplementation::DoSerializeTo(SerializerElement& element) const {
|
||||
element.AddChild("content") = gd::Serializer::FromJSON(jsonContent);
|
||||
}
|
||||
void ObjectJsImplementation::DoUnserializeFrom(Project& arg0,
|
||||
const SerializerElement& arg1) {
|
||||
jsonContent = gd::Serializer::ToJSON(arg1.GetChild("content"));
|
||||
void ObjectJsImplementation::DoUnserializeFrom(Project& project,
|
||||
const SerializerElement& element) {
|
||||
jsonContent = gd::Serializer::ToJSON(element.GetChild("content"));
|
||||
}
|
||||
|
||||
void ObjectJsImplementation::__destroy__() { // Useless?
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#include <GDCore/Project/Object.h>
|
||||
#include <GDCore/Project/ObjectConfiguration.h>
|
||||
#include <GDCore/Project/Project.h>
|
||||
#include <GDCore/Project/PropertyDescriptor.h>
|
||||
#include <GDCore/Serialization/Serializer.h>
|
||||
@@ -14,14 +15,10 @@ using namespace gd;
|
||||
* It also implements "ExposeResources" to expose the properties of type
|
||||
* "resource".
|
||||
*/
|
||||
class ObjectJsImplementation : public gd::Object {
|
||||
class ObjectJsImplementation : public gd::ObjectConfiguration {
|
||||
public:
|
||||
ObjectJsImplementation()
|
||||
: // Name is not important as this object is just a "blueprint"
|
||||
// that is copied (see calls to AddObject).
|
||||
Object("ObjectJsImplementation"),
|
||||
jsonContent("{}") {}
|
||||
std::unique_ptr<gd::Object> Clone() const override;
|
||||
ObjectJsImplementation() : jsonContent("{}") {}
|
||||
std::unique_ptr<gd::ObjectConfiguration> Clone() const override;
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetProperties() const override;
|
||||
bool UpdateProperty(const gd::String& name, const gd::String& value) override;
|
||||
|
@@ -103,25 +103,28 @@ class ProjectHelper {
|
||||
* \brief This check that the given gd::Object can be properly cloned
|
||||
* and have the given property updated.
|
||||
*/
|
||||
static gd::String SanityCheckObjectProperty(gd::Object* object,
|
||||
const gd::String& propertyName,
|
||||
const gd::String& newValue) {
|
||||
if (!object) return "FAIL: object passed is null";
|
||||
static gd::String SanityCheckObjectProperty(
|
||||
gd::ObjectConfiguration* objectConfiguration,
|
||||
const gd::String& propertyName,
|
||||
const gd::String& newValue) {
|
||||
if (!objectConfiguration) return "FAIL: object passed is null";
|
||||
gd::Project project;
|
||||
project.AddPlatform(JsPlatform::Get());
|
||||
|
||||
gd::String originalValue =
|
||||
object->GetProperties()[propertyName].GetValue();
|
||||
gd::Object object("MyObject", "", objectConfiguration->Clone());
|
||||
|
||||
std::unique_ptr<gd::Object> copiedObject = object->Clone();
|
||||
if (copiedObject->GetProperties()[propertyName].GetValue() !=
|
||||
gd::String originalValue =
|
||||
object.GetConfiguration().GetProperties()[propertyName].GetValue();
|
||||
|
||||
std::unique_ptr<gd::Object> copiedObject = object.Clone();
|
||||
if (copiedObject->GetConfiguration().GetProperties()[propertyName].GetValue() !=
|
||||
originalValue) {
|
||||
return "FAIL: Cloning the object does not copy properly the property";
|
||||
}
|
||||
|
||||
object->UpdateProperty(propertyName, newValue);
|
||||
object.GetConfiguration().UpdateProperty(propertyName, newValue);
|
||||
gd::String updatedValue =
|
||||
object->GetProperties()[propertyName].GetValue();
|
||||
object.GetConfiguration().GetProperties()[propertyName].GetValue();
|
||||
if (updatedValue != newValue) {
|
||||
return "FAIL: expected the newValue to be set for the property, but "
|
||||
"received:" +
|
||||
@@ -129,7 +132,7 @@ class ProjectHelper {
|
||||
}
|
||||
|
||||
gd::String copiedObjectValue =
|
||||
copiedObject->GetProperties()[propertyName].GetValue();
|
||||
copiedObject->GetConfiguration().GetProperties()[propertyName].GetValue();
|
||||
if (copiedObjectValue != originalValue) {
|
||||
return "FAIL: Updating the property of the object will change the "
|
||||
"property of the cloned object. Clone object property is "
|
||||
@@ -145,34 +148,39 @@ class ProjectHelper {
|
||||
* and return/set the properties of a gd::InitialInstance.
|
||||
*/
|
||||
static gd::String SanityCheckObjectInitialInstanceProperty(
|
||||
gd::Object* object,
|
||||
gd::ObjectConfiguration* objectConfiguration,
|
||||
const gd::String& propertyName,
|
||||
const gd::String& newValue) {
|
||||
if (!object) return "FAIL: object passed is null";
|
||||
if (!objectConfiguration) return "FAIL: object passed is null";
|
||||
|
||||
gd::Project project;
|
||||
project.AddPlatform(JsPlatform::Get());
|
||||
gd::Layout layout;
|
||||
gd::InitialInstance instance;
|
||||
|
||||
gd::Object object("MyObject", "", objectConfiguration->Clone());
|
||||
|
||||
gd::String originalValue = object
|
||||
->GetInitialInstanceProperties(
|
||||
.GetConfiguration()
|
||||
.GetInitialInstanceProperties(
|
||||
instance, project, layout)[propertyName]
|
||||
.GetValue();
|
||||
|
||||
std::unique_ptr<gd::Object> copiedObject = object->Clone();
|
||||
std::unique_ptr<gd::Object> copiedObject = object.Clone();
|
||||
if (copiedObject
|
||||
->GetInitialInstanceProperties(
|
||||
->GetConfiguration()
|
||||
.GetInitialInstanceProperties(
|
||||
instance, project, layout)[propertyName]
|
||||
.GetValue() != originalValue) {
|
||||
return "FAIL: Cloned object does not return the same initial value for "
|
||||
"the instance property";
|
||||
}
|
||||
|
||||
copiedObject->UpdateInitialInstanceProperty(
|
||||
copiedObject->GetConfiguration().UpdateInitialInstanceProperty(
|
||||
instance, propertyName, newValue, project, layout);
|
||||
gd::String updatedValue = copiedObject
|
||||
->GetInitialInstanceProperties(
|
||||
->GetConfiguration()
|
||||
.GetInitialInstanceProperties(
|
||||
instance, project, layout)[propertyName]
|
||||
.GetValue();
|
||||
if (updatedValue != newValue) {
|
||||
|
@@ -62,8 +62,8 @@
|
||||
#include <GDCore/Project/Layout.h>
|
||||
#include <GDCore/Project/NamedPropertyDescriptor.h>
|
||||
#include <GDCore/Project/Object.h>
|
||||
#include <GDCore/Project/CustomObject.h>
|
||||
#include <GDCore/Project/CustomBehavior.h>
|
||||
#include <GDCore/Project/ObjectConfiguration.h>
|
||||
#include <GDCore/Project/CustomObjectConfiguration.h>
|
||||
#include <GDCore/Project/Project.h>
|
||||
#include <GDCore/Project/PropertyDescriptor.h>
|
||||
#include <GDCore/Project/Variable.h>
|
||||
@@ -413,6 +413,7 @@ typedef gd::Object gdObject; // To avoid clashing javascript Object in glue.js
|
||||
typedef ParticleEmitterObject::RendererType ParticleEmitterObject_RendererType;
|
||||
typedef EventsFunction::FunctionType EventsFunction_FunctionType;
|
||||
typedef std::unique_ptr<gd::Object> UniquePtrObject;
|
||||
typedef std::unique_ptr<gd::ObjectConfiguration> UniquePtrObjectConfiguration;
|
||||
typedef std::unique_ptr<ExpressionNode> UniquePtrExpressionNode;
|
||||
typedef std::vector<gd::ExpressionParserDiagnostic *>
|
||||
VectorExpressionParserDiagnostic;
|
||||
@@ -491,7 +492,7 @@ typedef ExtensionAndMetadata<ExpressionMetadata> ExtensionAndExpressionMetadata;
|
||||
fullname, \
|
||||
description, \
|
||||
icon24x24, \
|
||||
std::shared_ptr<gd::Object>(instance))
|
||||
std::shared_ptr<gd::ObjectConfiguration>(instance))
|
||||
|
||||
#define WRAPPED_at(a) at(a).get()
|
||||
|
||||
|
@@ -117,33 +117,36 @@ var adaptNamingConventions = function (gd) {
|
||||
return gd.castObject(evt, gd.Platform);
|
||||
};
|
||||
|
||||
gd.asSpriteObject = function (evt) {
|
||||
gd.asSpriteConfiguration = function (evt) {
|
||||
return gd.castObject(evt, gd.SpriteObject);
|
||||
};
|
||||
gd.asTiledSpriteObject = function (evt) {
|
||||
gd.asTiledSpriteConfiguration = function (evt) {
|
||||
return gd.castObject(evt, gd.TiledSpriteObject);
|
||||
};
|
||||
gd.asPanelSpriteObject = function (evt) {
|
||||
gd.asPanelSpriteConfiguration = function (evt) {
|
||||
return gd.castObject(evt, gd.PanelSpriteObject);
|
||||
};
|
||||
gd.asTextObject = function (evt) {
|
||||
gd.asTextObjectConfiguration = function (evt) {
|
||||
return gd.castObject(evt, gd.TextObject);
|
||||
};
|
||||
gd.asShapePainterObject = function (evt) {
|
||||
gd.asShapePainterConfiguration = function (evt) {
|
||||
return gd.castObject(evt, gd.ShapePainterObject);
|
||||
};
|
||||
gd.asAdMobObject = function (evt) {
|
||||
gd.asAdMobConfiguration = function (evt) {
|
||||
return gd.castObject(evt, gd.AdMobObject);
|
||||
};
|
||||
gd.asTextEntryObject = function (evt) {
|
||||
return gd.castObject(evt, gd.TextEntryObject);
|
||||
};
|
||||
gd.asParticleEmitterObject = function (evt) {
|
||||
gd.asParticleEmitterConfiguration = function (evt) {
|
||||
return gd.castObject(evt, gd.ParticleEmitterObject);
|
||||
};
|
||||
gd.asObjectJsImplementation = function (evt) {
|
||||
return gd.castObject(evt, gd.ObjectJsImplementation);
|
||||
};
|
||||
gd.asCustomObjectConfiguration = function (evt) {
|
||||
return gd.castObject(evt, gd.CustomObjectConfiguration);
|
||||
};
|
||||
|
||||
gd.asImageResource = function (evt) {
|
||||
return gd.castObject(evt, gd.ImageResource);
|
||||
|
@@ -374,20 +374,14 @@ describe('libGD.js', function () {
|
||||
|
||||
describe('gd.ObjectsContainer', function () {
|
||||
it('can move objects between containers, without moving them in memory', function () {
|
||||
const project = new gd.ProjectHelper.createNewGDJSProject();
|
||||
|
||||
// Prepare two containers, one with 3 objects and one empty
|
||||
const objectsContainer1 = new gd.ObjectsContainer();
|
||||
const objectsContainer2 = new gd.ObjectsContainer();
|
||||
const mySpriteObject = new gd.SpriteObject('MySprite');
|
||||
const mySprite2Object = new gd.SpriteObject('MySprite2');
|
||||
const mySprite3Object = new gd.SpriteObject('MySprite3');
|
||||
objectsContainer1.insertObject(mySpriteObject, 0);
|
||||
objectsContainer1.insertObject(mySprite2Object, 1);
|
||||
objectsContainer1.insertObject(mySprite3Object, 2);
|
||||
|
||||
// Objects are copied when inserted in the container, so we delete them:
|
||||
mySpriteObject.delete();
|
||||
mySprite2Object.delete();
|
||||
mySprite3Object.delete();
|
||||
const mySpriteObject = objectsContainer1.insertNewObject(project, 'Sprite', 'MySprite', 0);
|
||||
const mySprite2Object = objectsContainer1.insertNewObject(project, 'Sprite', 'MySprite2', 1);
|
||||
const mySprite3Object = objectsContainer1.insertNewObject(project, 'Sprite', 'MySprite3', 2);
|
||||
|
||||
// Find the pointer to the objects in memory
|
||||
expect(objectsContainer1.getObjectsCount()).toBe(3);
|
||||
@@ -455,6 +449,7 @@ describe('libGD.js', function () {
|
||||
expect(gd.getPointer(objectsContainer2.getObjectAt(0))).toBe(
|
||||
mySprite3ObjectPtr
|
||||
);
|
||||
project.delete();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1200,7 +1195,7 @@ describe('libGD.js', function () {
|
||||
anim1.setDirectionsCount(1);
|
||||
anim1.getDirection(0).addSprite(sprite1);
|
||||
|
||||
gd.castObject(obj, gd.SpriteObject).addAnimation(anim1);
|
||||
gd.castObject(obj.getConfiguration(), gd.SpriteObject).addAnimation(anim1);
|
||||
|
||||
{
|
||||
let allResources = project.getResourcesManager().getAllResourceNames();
|
||||
@@ -1257,13 +1252,13 @@ describe('libGD.js', function () {
|
||||
it('should be called with resources of the project', function (done) {
|
||||
let project = gd.ProjectHelper.createNewGDJSProject();
|
||||
let obj = project.insertNewObject(project, 'Sprite', 'MyObject', 0);
|
||||
const spriteObject = gd.asSpriteObject(obj);
|
||||
const spriteConfiguration = gd.asSpriteConfiguration(obj.getConfiguration());
|
||||
let sprite1 = new gd.Sprite();
|
||||
sprite1.setImageName('Used');
|
||||
const animation = new gd.Animation();
|
||||
animation.setDirectionsCount(1);
|
||||
animation.getDirection(0).addSprite(sprite1);
|
||||
spriteObject.addAnimation(animation);
|
||||
spriteConfiguration.addAnimation(animation);
|
||||
|
||||
let worker = extend(new gd.ArbitraryResourceWorkerJS(), {
|
||||
exposeImage: function (image) {
|
||||
@@ -1288,7 +1283,7 @@ describe('libGD.js', function () {
|
||||
let sprite3 = new gd.Sprite();
|
||||
sprite3.setImageName('Image3');
|
||||
|
||||
const spriteObject = new gd.SpriteObject('My sprite object');
|
||||
const spriteObject = new gd.SpriteObject();
|
||||
const animation = new gd.Animation();
|
||||
animation.setDirectionsCount(1);
|
||||
animation.getDirection(0).addSprite(sprite1);
|
||||
@@ -1296,7 +1291,7 @@ describe('libGD.js', function () {
|
||||
animation.getDirection(0).addSprite(sprite1);
|
||||
spriteObject.addAnimation(animation);
|
||||
|
||||
const spriteObject2 = new gd.SpriteObject('My sprite object');
|
||||
const spriteObject2 = new gd.SpriteObject();
|
||||
const animation2 = new gd.Animation();
|
||||
animation2.setDirectionsCount(1);
|
||||
animation2.getDirection(0).addSprite(sprite1);
|
||||
@@ -1779,7 +1774,7 @@ describe('libGD.js', function () {
|
||||
// see ObjectJsImplementation C++ implementation). If called directly here from JS,
|
||||
// the arguments will be mismatched. To workaround this, always case the object to
|
||||
// a base gdObject to ensure C++ methods are called.
|
||||
return gd.castObject(myObject, gd.Object);
|
||||
return gd.castObject(myObject, gd.ObjectConfiguration);
|
||||
};
|
||||
|
||||
it('can create a gd.ObjectJsImplementation and pass sanity checks', function () {
|
||||
@@ -1824,7 +1819,6 @@ describe('libGD.js', function () {
|
||||
});
|
||||
|
||||
it('can clone a gd.ObjectJsImplementation', function () {
|
||||
const project = gd.ProjectHelper.createNewGDJSProject();
|
||||
const object1 = createSampleObjectJsImplementation();
|
||||
expect(
|
||||
object1.getProperties().get('My first property').getValue() ==
|
||||
@@ -1883,8 +1877,6 @@ describe('libGD.js', function () {
|
||||
propertiesObject3.get('My first property').getValue() == 'test1'
|
||||
);
|
||||
}
|
||||
|
||||
project.delete();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2640,17 +2632,19 @@ describe('libGD.js', function () {
|
||||
|
||||
describe('gd.SpriteObject', function () {
|
||||
it('is a gd.Object and can have tags', function () {
|
||||
let object = new gd.SpriteObject('MySpriteObject');
|
||||
const project = new gd.ProjectHelper.createNewGDJSProject();
|
||||
let object = project.insertNewObject(project, 'Sprite', 'MySpriteObject');
|
||||
|
||||
expect(object instanceof gd.Object).toBe(true);
|
||||
object.setTags('tag1, tag2, tag3');
|
||||
expect(object.getTags()).toBe('tag1, tag2, tag3');
|
||||
expect(object.getVariables()).toBeTruthy();
|
||||
object.delete();
|
||||
project.delete();
|
||||
});
|
||||
|
||||
it('can have animations', function () {
|
||||
let obj = new gd.SpriteObject('MySpriteObject');
|
||||
let obj = new gd.SpriteObject();
|
||||
obj.addAnimation(new gd.Animation());
|
||||
obj.addAnimation(new gd.Animation());
|
||||
expect(obj.getAnimationsCount()).toBe(2);
|
||||
@@ -2659,7 +2653,7 @@ describe('libGD.js', function () {
|
||||
});
|
||||
|
||||
it('can swap animations', function () {
|
||||
let obj = new gd.SpriteObject('MySpriteObject');
|
||||
let obj = new gd.SpriteObject();
|
||||
obj.removeAllAnimations();
|
||||
let anim1 = new gd.Animation();
|
||||
let anim2 = new gd.Animation();
|
||||
|
@@ -618,17 +618,9 @@ describe('libGD.js - GDJS related tests', function () {
|
||||
});
|
||||
});
|
||||
|
||||
const testObjectFeatures = (object) => {
|
||||
expect(object instanceof gd.Object).toBe(true);
|
||||
object.setTags('tag1, tag2, tag3');
|
||||
expect(object.getTags()).toBe('tag1, tag2, tag3');
|
||||
expect(object.getVariables()).toBeTruthy();
|
||||
};
|
||||
|
||||
describe('TextObject', function () {
|
||||
it('should expose TextObject specific methods', function () {
|
||||
var object = new gd.TextObject('MyTextObject');
|
||||
testObjectFeatures(object);
|
||||
object.setString('Hello');
|
||||
object.setFontName('Hello.ttf');
|
||||
object.setCharacterSize(10);
|
||||
@@ -647,7 +639,6 @@ describe('libGD.js - GDJS related tests', function () {
|
||||
describe('TiledSpriteObject', function () {
|
||||
it('should expose TiledSpriteObject specific methods', function () {
|
||||
var object = new gd.TiledSpriteObject('MyTiledSpriteObject');
|
||||
testObjectFeatures(object);
|
||||
object.setTexture('MyImageName');
|
||||
expect(object.getTexture()).toBe('MyImageName');
|
||||
});
|
||||
@@ -655,7 +646,6 @@ describe('libGD.js - GDJS related tests', function () {
|
||||
describe('PanelSpriteObject', function () {
|
||||
it('should expose PanelSpriteObject specific methods', function () {
|
||||
var object = new gd.PanelSpriteObject('MyPanelSpriteObject');
|
||||
testObjectFeatures(object);
|
||||
object.setTexture('MyImageName');
|
||||
expect(object.getTexture()).toBe('MyImageName');
|
||||
});
|
||||
@@ -663,7 +653,6 @@ describe('libGD.js - GDJS related tests', function () {
|
||||
describe('ShapePainterObject', function () {
|
||||
it('should expose ShapePainterObject specific methods', function () {
|
||||
var object = new gd.ShapePainterObject('MyShapePainterObject');
|
||||
testObjectFeatures(object);
|
||||
object.setCoordinatesAbsolute();
|
||||
expect(object.areCoordinatesAbsolute()).toBe(true);
|
||||
object.setCoordinatesRelative();
|
||||
@@ -673,7 +662,6 @@ describe('libGD.js - GDJS related tests', function () {
|
||||
describe('ShapePainterObject', function () {
|
||||
it('should expose ShapePainterObject specific methods', function () {
|
||||
var object = new gd.ShapePainterObject('MyShapePainterObject');
|
||||
testObjectFeatures(object);
|
||||
object.setClearBetweenFrames(true);
|
||||
expect(object.isClearedBetweenFrames()).toBe(true);
|
||||
object.setClearBetweenFrames(false);
|
||||
@@ -683,13 +671,11 @@ describe('libGD.js - GDJS related tests', function () {
|
||||
describe('TextEntryObject', function () {
|
||||
it('should expose TextEntryObject', function () {
|
||||
var object = new gd.TextEntryObject('MyTextEntryObject');
|
||||
testObjectFeatures(object);
|
||||
});
|
||||
});
|
||||
describe('ParticleEmitterObject', function () {
|
||||
it('should expose ParticleEmitterObject', function () {
|
||||
var object = new gd.ParticleEmitterObject('MyParticleEmitterObject');
|
||||
testObjectFeatures(object);
|
||||
});
|
||||
});
|
||||
describe('JsCodeEvent', function () {
|
||||
|
194
GDevelop.js/__tests__/GDJSProjectSerialization.js
Normal file
194
GDevelop.js/__tests__/GDJSProjectSerialization.js
Normal file
@@ -0,0 +1,194 @@
|
||||
const path = require('path');
|
||||
const {
|
||||
makeFakeAbstractFileSystem,
|
||||
} = require('../TestUtils/FakeAbstractFileSystem');
|
||||
const initializeGDevelopJs = require('../../Binaries/embuild/GDevelop.js/libGD.js');
|
||||
const { makeTestExtensions } = require('../TestUtils/TestExtensions');
|
||||
|
||||
describe('libGD.js - GDJS project serialization tests', function () {
|
||||
let gd = null;
|
||||
|
||||
beforeAll((done) => {
|
||||
initializeGDevelopJs().then((module) => {
|
||||
gd = module;
|
||||
makeTestExtensions(gd);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should keep TextObject configuration after after a save and reload', function () {
|
||||
const checkConfiguration = (project) => {
|
||||
const layout = project.getLayout('Scene');
|
||||
const object = layout.getObject('MyObject');
|
||||
const configuration = gd.asTextObjectConfiguration(
|
||||
object.getConfiguration()
|
||||
);
|
||||
expect(configuration.getString()).toBe('Hello');
|
||||
};
|
||||
|
||||
const serializerElement = new gd.SerializerElement();
|
||||
{
|
||||
const project = gd.ProjectHelper.createNewGDJSProject();
|
||||
const layout = project.insertNewLayout('Scene', 0);
|
||||
const object = layout.insertNewObject(
|
||||
project,
|
||||
'TextObject::Text',
|
||||
'MyObject',
|
||||
0
|
||||
);
|
||||
const configuration = gd.asTextObjectConfiguration(
|
||||
object.getConfiguration()
|
||||
);
|
||||
configuration.setString('Hello');
|
||||
|
||||
checkConfiguration(project);
|
||||
project.serializeTo(serializerElement);
|
||||
}
|
||||
{
|
||||
const project = gd.ProjectHelper.createNewGDJSProject();
|
||||
project.unserializeFrom(serializerElement);
|
||||
checkConfiguration(project);
|
||||
}
|
||||
});
|
||||
|
||||
it('should keep TiledSpriteObject configuration after a save and reload', function () {
|
||||
const checkConfiguration = (project) => {
|
||||
const layout = project.getLayout('Scene');
|
||||
const object = layout.getObject('MyObject');
|
||||
const configuration = gd.asTiledSpriteConfiguration(
|
||||
object.getConfiguration()
|
||||
);
|
||||
expect(configuration.getTexture()).toBe('MyImageName');
|
||||
};
|
||||
|
||||
const serializerElement = new gd.SerializerElement();
|
||||
{
|
||||
const project = gd.ProjectHelper.createNewGDJSProject();
|
||||
const layout = project.insertNewLayout('Scene', 0);
|
||||
const object = layout.insertNewObject(
|
||||
project,
|
||||
'TiledSpriteObject::TiledSprite',
|
||||
'MyObject',
|
||||
0
|
||||
);
|
||||
const configuration = gd.asTiledSpriteConfiguration(
|
||||
object.getConfiguration()
|
||||
);
|
||||
configuration.setTexture('MyImageName');
|
||||
|
||||
checkConfiguration(project);
|
||||
project.serializeTo(serializerElement);
|
||||
}
|
||||
{
|
||||
const project = gd.ProjectHelper.createNewGDJSProject();
|
||||
project.unserializeFrom(serializerElement);
|
||||
checkConfiguration(project);
|
||||
}
|
||||
});
|
||||
|
||||
it('should keep PanelSpriteObject configuration after a save and reload', function () {
|
||||
const checkConfiguration = (project) => {
|
||||
const layout = project.getLayout('Scene');
|
||||
const object = layout.getObject('MyObject');
|
||||
const configuration = gd.asPanelSpriteConfiguration(
|
||||
object.getConfiguration()
|
||||
);
|
||||
expect(configuration.getTexture()).toBe('MyImageName');
|
||||
};
|
||||
|
||||
const serializerElement = new gd.SerializerElement();
|
||||
{
|
||||
const project = gd.ProjectHelper.createNewGDJSProject();
|
||||
const layout = project.insertNewLayout('Scene', 0);
|
||||
const object = layout.insertNewObject(
|
||||
project,
|
||||
'PanelSpriteObject::PanelSprite',
|
||||
'MyObject',
|
||||
0
|
||||
);
|
||||
const configuration = gd.asPanelSpriteConfiguration(
|
||||
object.getConfiguration()
|
||||
);
|
||||
configuration.setTexture('MyImageName');
|
||||
|
||||
checkConfiguration(project);
|
||||
project.serializeTo(serializerElement);
|
||||
}
|
||||
{
|
||||
const project = gd.ProjectHelper.createNewGDJSProject();
|
||||
project.unserializeFrom(serializerElement);
|
||||
checkConfiguration(project);
|
||||
}
|
||||
});
|
||||
|
||||
it('should keep ShapePainterObject configuration after a save and reload', function () {
|
||||
const checkConfiguration = (project) => {
|
||||
const layout = project.getLayout('Scene');
|
||||
const object = layout.getObject('MyObject');
|
||||
const configuration = gd.asShapePainterConfiguration(
|
||||
object.getConfiguration()
|
||||
);
|
||||
expect(configuration.areCoordinatesAbsolute()).toBe(true);
|
||||
};
|
||||
|
||||
const serializerElement = new gd.SerializerElement();
|
||||
{
|
||||
const project = gd.ProjectHelper.createNewGDJSProject();
|
||||
const layout = project.insertNewLayout('Scene', 0);
|
||||
const object = layout.insertNewObject(
|
||||
project,
|
||||
'PrimitiveDrawing::Drawer',
|
||||
'MyObject',
|
||||
0
|
||||
);
|
||||
const configuration = gd.asShapePainterConfiguration(
|
||||
object.getConfiguration()
|
||||
);
|
||||
// It's relative by default.
|
||||
configuration.setCoordinatesAbsolute();
|
||||
|
||||
checkConfiguration(project);
|
||||
project.serializeTo(serializerElement);
|
||||
}
|
||||
{
|
||||
const project = gd.ProjectHelper.createNewGDJSProject();
|
||||
project.unserializeFrom(serializerElement);
|
||||
checkConfiguration(project);
|
||||
}
|
||||
});
|
||||
|
||||
it('should keep ParticleEmitterObject configuration after a save and reload', function () {
|
||||
const checkConfiguration = (project) => {
|
||||
const layout = project.getLayout('Scene');
|
||||
const object = layout.getObject('MyObject');
|
||||
const configuration = gd.asParticleEmitterConfiguration(
|
||||
object.getConfiguration()
|
||||
);
|
||||
expect(configuration.getParticleAngle1()).toBe(45);
|
||||
};
|
||||
|
||||
const serializerElement = new gd.SerializerElement();
|
||||
{
|
||||
const project = gd.ProjectHelper.createNewGDJSProject();
|
||||
const layout = project.insertNewLayout('Scene', 0);
|
||||
const object = layout.insertNewObject(
|
||||
project,
|
||||
'ParticleSystem::ParticleEmitter',
|
||||
'MyObject',
|
||||
0
|
||||
);
|
||||
const configuration = gd.asParticleEmitterConfiguration(
|
||||
object.getConfiguration()
|
||||
);
|
||||
configuration.setParticleAngle1(45);
|
||||
|
||||
checkConfiguration(project);
|
||||
project.serializeTo(serializerElement);
|
||||
}
|
||||
{
|
||||
const project = gd.ProjectHelper.createNewGDJSProject();
|
||||
project.unserializeFrom(serializerElement);
|
||||
checkConfiguration(project);
|
||||
}
|
||||
});
|
||||
});
|
@@ -56,11 +56,7 @@ describe('libGD.js object serialization', function() {
|
||||
describe('gd.Serializer', function() {
|
||||
it('should serialize a Text Object', function() {
|
||||
var obj = new gd.TextObject('testObject');
|
||||
obj.setType('TextObject::Text');
|
||||
obj.setName('testObject');
|
||||
obj.setString('Text of the object, with 官话 characters');
|
||||
obj.setTags('inventory, player');
|
||||
obj.setAssetStoreId('1234');
|
||||
|
||||
var serializedObject = new gd.SerializerElement();
|
||||
obj.serializeTo(serializedObject);
|
||||
@@ -69,7 +65,7 @@ describe('libGD.js object serialization', function() {
|
||||
obj.delete();
|
||||
|
||||
expect(jsonObject).toBe(
|
||||
'{"assetStoreId":"1234","bold":false,"italic":false,"name":"testObject","smoothed":true,"tags":"inventory, player","type":"TextObject::Text","underlined":false,"variables":[],"effects":[],"behaviors":[],"string":"Text of the object, with 官话 characters","font":"","characterSize":20.0,"color":{"b":0,"g":0,"r":0}}'
|
||||
'{"bold":false,"italic":false,"smoothed":true,"underlined":false,"string":"Text of the object, with 官话 characters","font":"","characterSize":20.0,"color":{"b":0,"g":0,"r":0}}'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@@ -177,15 +177,16 @@ type ParticleEmitterObject_RendererType = 0 | 1 | 2`
|
||||
` asJsCodeEvent(gdBaseEvent): gdJsCodeEvent;`,
|
||||
` asPlatform(gdPlatform): gdPlatform;`,
|
||||
'',
|
||||
` asSpriteObject(gdObject): gdSpriteObject;`,
|
||||
` asTiledSpriteObject(gdObject): gdTiledSpriteObject;`,
|
||||
` asPanelSpriteObject(gdObject): gdPanelSpriteObject;`,
|
||||
` asTextObject(gdObject): gdTextObject;`,
|
||||
` asShapePainterObject(gdObject): gdShapePainterObject;`,
|
||||
` asAdMobObject(gdObject): gdAdMobObject;`,
|
||||
` asTextEntryObject(gdObject): gdTextEntryObject;`,
|
||||
` asParticleEmitterObject(gdObject): gdParticleEmitterObject;`,
|
||||
` asObjectJsImplementation(gdObject): gdObjectJsImplementation;`,
|
||||
` asSpriteConfiguration(gdObjectConfiguration): gdSpriteObject;`,
|
||||
` asTiledSpriteConfiguration(gdObjectConfiguration): gdTiledSpriteObject;`,
|
||||
` asPanelSpriteConfiguration(gdObjectConfiguration): gdPanelSpriteObject;`,
|
||||
` asTextObjectConfiguration(gdObjectConfiguration): gdTextObject;`,
|
||||
` asShapePainterConfiguration(gdObjectConfiguration): gdShapePainterObject;`,
|
||||
` asAdMobConfiguration(gdObjectConfiguration): gdAdMobObject;`,
|
||||
` asTextEntryConfiguration(gdObjectConfiguration): gdTextEntryObject;`,
|
||||
` asParticleEmitterConfiguration(gdObjectConfiguration): gdParticleEmitterObject;`,
|
||||
` asObjectJsImplementation(gdObjectConfiguration): gdObjectJsImplementation;`,
|
||||
` asCustomObjectConfiguration(gdObjectConfiguration): gdCustomObjectConfiguration;`,
|
||||
'',
|
||||
` asImageResource(gdResource): gdImageResource;`,
|
||||
'',
|
||||
@@ -249,14 +250,14 @@ type ParticleEmitterObject_RendererType = 0 | 1 | 2`
|
||||
shell.sed(
|
||||
'-i',
|
||||
'declare class gdObjectJsImplementation {',
|
||||
'declare class gdObjectJsImplementation extends gdObject {',
|
||||
'declare class gdObjectJsImplementation extends gdObjectConfiguration {',
|
||||
'types/gdobjectjsimplementation.js'
|
||||
);
|
||||
shell.sed(
|
||||
'-i',
|
||||
'declare class gdCustomObject {',
|
||||
'declare class gdCustomObject extends gdObject {',
|
||||
'types/gdcustomobject.js'
|
||||
'declare class gdCustomObjectConfiguration {',
|
||||
'declare class gdCustomObjectConfiguration extends gdObjectConfiguration {',
|
||||
'types/gdcustomobjectconfiguration.js'
|
||||
);
|
||||
shell.sed(
|
||||
'-i',
|
||||
@@ -264,12 +265,6 @@ type ParticleEmitterObject_RendererType = 0 | 1 | 2`
|
||||
'declare class gdBehaviorJsImplementation extends gdBehavior {',
|
||||
'types/gdbehaviorjsimplementation.js'
|
||||
);
|
||||
shell.sed(
|
||||
'-i',
|
||||
'declare class gdCustomBehavior {',
|
||||
'declare class gdCustomBehavior extends gdBehavior {',
|
||||
'types/gdcustombehavior.js'
|
||||
);
|
||||
shell.sed(
|
||||
'-i',
|
||||
'declare class gdBehaviorSharedDataJsImplementation {',
|
||||
|
11
GDevelop.js/types/gdcustomobjectconfiguration.js
Normal file
11
GDevelop.js/types/gdcustomobjectconfiguration.js
Normal file
@@ -0,0 +1,11 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdCustomObjectConfiguration extends gdObjectConfiguration {
|
||||
clone(): gdUniquePtrObjectConfiguration;
|
||||
getChildObjectConfiguration(objectName: string): gdObjectConfiguration;
|
||||
getProperties(): gdMapStringPropertyDescriptor;
|
||||
updateProperty(name: string, value: string): boolean;
|
||||
getInitialInstanceProperties(instance: gdInitialInstance, project: gdProject, scene: gdLayout): gdMapStringPropertyDescriptor;
|
||||
updateInitialInstanceProperty(instance: gdInitialInstance, name: string, value: string, project: gdProject, scene: gdLayout): boolean;
|
||||
delete(): void;
|
||||
ptr: number;
|
||||
};
|
@@ -11,18 +11,6 @@ declare class gdEventsBasedObject extends gdObjectsContainer {
|
||||
getPropertyDescriptors(): gdNamedPropertyDescriptorsList;
|
||||
serializeTo(element: gdSerializerElement): void;
|
||||
unserializeFrom(project: gdProject, element: gdSerializerElement): void;
|
||||
insertNewObject(project: gdProject, type: string, name: string, pos: number): gdObject;
|
||||
insertObject(obj: gdObject, pos: number): gdObject;
|
||||
hasObjectNamed(name: string): boolean;
|
||||
getObject(name: string): gdObject;
|
||||
getObjectAt(pos: number): gdObject;
|
||||
getObjectPosition(name: string): number;
|
||||
removeObject(name: string): void;
|
||||
swapObjects(first: number, second: number): void;
|
||||
moveObject(oldIndex: number, newIndex: number): void;
|
||||
moveObjectToAnotherContainer(name: string, newObjectsContainer: gdObjectsContainer, newPosition: number): void;
|
||||
getObjectsCount(): number;
|
||||
getObjectGroups(): gdObjectGroupsContainer;
|
||||
static getPropertyActionName(propertyName: string): string;
|
||||
static getPropertyConditionName(propertyName: string): string;
|
||||
static getPropertyExpressionName(propertyName: string): string;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdObject {
|
||||
constructor(name: string): void;
|
||||
constructor(name: string, type: string, configuration: gdObjectConfiguration): void;
|
||||
clone(): gdUniquePtrObject;
|
||||
setName(name: string): void;
|
||||
getName(): string;
|
||||
@@ -10,11 +10,7 @@ declare class gdObject {
|
||||
getType(): string;
|
||||
setTags(tags: string): void;
|
||||
getTags(): string;
|
||||
getProperties(): gdMapStringPropertyDescriptor;
|
||||
updateProperty(name: string, value: string): boolean;
|
||||
getInitialInstanceProperties(instance: gdInitialInstance, project: gdProject, scene: gdLayout): gdMapStringPropertyDescriptor;
|
||||
updateInitialInstanceProperty(instance: gdInitialInstance, name: string, value: string, project: gdProject, scene: gdLayout): boolean;
|
||||
exposeResources(worker: gdArbitraryResourceWorker): void;
|
||||
getConfiguration(): gdObjectConfiguration;
|
||||
getVariables(): gdVariablesContainer;
|
||||
getEffects(): gdEffectsContainer;
|
||||
getAllBehaviorNames(): gdVectorString;
|
||||
|
15
GDevelop.js/types/gdobjectconfiguration.js
Normal file
15
GDevelop.js/types/gdobjectconfiguration.js
Normal file
@@ -0,0 +1,15 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdObjectConfiguration {
|
||||
constructor(): void;
|
||||
clone(): gdUniquePtrObjectConfiguration;
|
||||
getType(): string;
|
||||
getProperties(): gdMapStringPropertyDescriptor;
|
||||
updateProperty(name: string, value: string): boolean;
|
||||
getInitialInstanceProperties(instance: gdInitialInstance, project: gdProject, scene: gdLayout): gdMapStringPropertyDescriptor;
|
||||
updateInitialInstanceProperty(instance: gdInitialInstance, name: string, value: string, project: gdProject, scene: gdLayout): boolean;
|
||||
exposeResources(worker: gdArbitraryResourceWorker): void;
|
||||
serializeTo(element: gdSerializerElement): void;
|
||||
unserializeFrom(project: gdProject, element: gdSerializerElement): void;
|
||||
delete(): void;
|
||||
ptr: number;
|
||||
};
|
@@ -1,7 +1,7 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdObjectJsImplementation extends gdObject {
|
||||
declare class gdObjectJsImplementation extends gdObjectConfiguration {
|
||||
constructor(): void;
|
||||
clone(): gdUniquePtrObject;
|
||||
clone(): gdUniquePtrObjectConfiguration;
|
||||
getProperties(): gdMapStringPropertyDescriptor;
|
||||
updateProperty(name: string, value: string): boolean;
|
||||
getInitialInstanceProperties(instance: gdInitialInstance, project: gdProject, scene: gdLayout): gdMapStringPropertyDescriptor;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdPanelSpriteObject extends gdObject {
|
||||
constructor(name: string): void;
|
||||
declare class gdPanelSpriteObject extends gdObjectConfiguration {
|
||||
constructor(): void;
|
||||
getLeftMargin(): number;
|
||||
setLeftMargin(newMargin: number): void;
|
||||
getTopMargin(): number;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdParticleEmitterObject extends gdObject {
|
||||
constructor(name: string): void;
|
||||
declare class gdParticleEmitterObject extends gdObjectConfiguration {
|
||||
constructor(): void;
|
||||
setRendererType(type: ParticleEmitterObject_RendererType): void;
|
||||
getRendererType(): ParticleEmitterObject_RendererType;
|
||||
setParticleTexture(resourceName: string): void;
|
||||
|
@@ -16,7 +16,7 @@ declare class gdPlatformExtension {
|
||||
addDependency(): gdDependencyMetadata;
|
||||
addBehavior(name: string, fullname: string, defaultName: string, description: string, group: string, icon24x24: string, className: string, instance: gdBehavior, sharedDatasInstance: gdBehaviorsSharedData): gdBehaviorMetadata;
|
||||
addEventsBasedBehavior(name: string, fullname: string, description: string, group: string, icon24x24: string): gdBehaviorMetadata;
|
||||
addObject(name: string, fullname: string, description: string, icon24x24: string, instance: gdObject): gdObjectMetadata;
|
||||
addObject(name: string, fullname: string, description: string, icon24x24: string, instance: gdObjectConfiguration): gdObjectMetadata;
|
||||
addEventsBasedObject(name: string, fullname: string, description: string, icon24x24: string): gdObjectMetadata;
|
||||
addEffect(name: string): gdEffectMetadata;
|
||||
registerProperty(name: string): gdPropertyDescriptor;
|
||||
|
@@ -4,8 +4,8 @@ declare class gdProjectHelper {
|
||||
static initializePlatforms(): void;
|
||||
static sanityCheckBehaviorProperty(behavior: gdBehavior, propertyName: string, newValue: string): string;
|
||||
static sanityCheckBehaviorsSharedDataProperty(behavior: gdBehaviorsSharedData, propertyName: string, newValue: string): string;
|
||||
static sanityCheckObjectProperty(obj: gdObject, propertyName: string, newValue: string): string;
|
||||
static sanityCheckObjectInitialInstanceProperty(obj: gdObject, propertyName: string, newValue: string): string;
|
||||
static sanityCheckObjectProperty(configuration: gdObjectConfiguration, propertyName: string, newValue: string): string;
|
||||
static sanityCheckObjectInitialInstanceProperty(configuration: gdObjectConfiguration, propertyName: string, newValue: string): string;
|
||||
delete(): void;
|
||||
ptr: number;
|
||||
};
|
@@ -1,6 +1,6 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdShapePainterObject extends gdObject {
|
||||
constructor(name: string): void;
|
||||
declare class gdShapePainterObject extends gdObjectConfiguration {
|
||||
constructor(): void;
|
||||
setCoordinatesAbsolute(): void;
|
||||
setCoordinatesRelative(): void;
|
||||
areCoordinatesAbsolute(): boolean;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdSpriteObject extends gdObject {
|
||||
constructor(name: string): void;
|
||||
declare class gdSpriteObject extends gdObjectConfiguration {
|
||||
constructor(): void;
|
||||
addAnimation(animation: gdAnimation): void;
|
||||
getAnimation(index: number): gdAnimation;
|
||||
getAnimationsCount(): number;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdTextEntryObject extends gdObject {
|
||||
constructor(name: string): void;
|
||||
declare class gdTextEntryObject extends gdObjectConfiguration {
|
||||
constructor(): void;
|
||||
delete(): void;
|
||||
ptr: number;
|
||||
};
|
@@ -1,6 +1,6 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdTextObject extends gdObject {
|
||||
constructor(name: string): void;
|
||||
declare class gdTextObject extends gdObjectConfiguration {
|
||||
constructor(): void;
|
||||
setString(string: string): void;
|
||||
getString(): string;
|
||||
setCharacterSize(size: number): void;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdTiledSpriteObject extends gdObject {
|
||||
constructor(name: string): void;
|
||||
declare class gdTiledSpriteObject extends gdObjectConfiguration {
|
||||
constructor(): void;
|
||||
setTexture(texture: string): void;
|
||||
getTexture(): string;
|
||||
setWidth(width: number): void;
|
||||
|
7
GDevelop.js/types/gduniqueptrobjectconfiguration.js
Normal file
7
GDevelop.js/types/gduniqueptrobjectconfiguration.js
Normal file
@@ -0,0 +1,7 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdUniquePtrObjectConfiguration {
|
||||
get(): gdObjectConfiguration;
|
||||
release(): gdObjectConfiguration;
|
||||
delete(): void;
|
||||
ptr: number;
|
||||
};
|
@@ -16,7 +16,7 @@ declare class gdWholeProjectRefactorer {
|
||||
static objectOrGroupRemovedInLayout(project: gdProject, layout: gdLayout, objectName: string, isObjectGroup: boolean, removeEventsAndGroups: boolean): void;
|
||||
static objectOrGroupRenamedInEventsFunction(project: gdProject, eventsFunction: gdEventsFunction, globalObjectsContainer: gdObjectsContainer, objectsContainer: gdObjectsContainer, oldName: string, newName: string, isObjectGroup: boolean): void;
|
||||
static objectOrGroupRemovedInEventsFunction(project: gdProject, eventsFunction: gdEventsFunction, globalObjectsContainer: gdObjectsContainer, objectsContainer: gdObjectsContainer, objectName: string, isObjectGroup: boolean, removeEventsAndGroups: boolean): void;
|
||||
static objectOrGroupRenamedInEventsBasedObject(project: gdProject, eventsBasedObject: gdEventsBasedObject, globalObjectsContainer: gdObjectsContainer, objectsContainer: gdObjectsContainer, oldName: string, newName: string, isObjectGroup: boolean): void;
|
||||
static objectOrGroupRenamedInEventsBasedObject(project: gdProject, globalObjectsContainer: gdObjectsContainer, eventsBasedObject: gdEventsBasedObject, oldName: string, newName: string, isObjectGroup: boolean): void;
|
||||
static objectOrGroupRemovedInEventsBasedObject(project: gdProject, eventsBasedObject: gdEventsBasedObject, globalObjectsContainer: gdObjectsContainer, objectsContainer: gdObjectsContainer, objectName: string, isObjectGroup: boolean, removeEventsAndGroups: boolean): void;
|
||||
static globalObjectOrGroupRenamed(project: gdProject, oldName: string, newName: string, isObjectGroup: boolean): void;
|
||||
static globalObjectOrGroupRemoved(project: gdProject, objectName: string, isObjectGroup: boolean, removeEventsAndGroups: boolean): void;
|
||||
|
2728
GDevelop.js/types/libgdevelop.d.ts
vendored
Normal file
2728
GDevelop.js/types/libgdevelop.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -22,15 +22,16 @@ declare class libGDevelop {
|
||||
asJsCodeEvent(gdBaseEvent): gdJsCodeEvent;
|
||||
asPlatform(gdPlatform): gdPlatform;
|
||||
|
||||
asSpriteObject(gdObject): gdSpriteObject;
|
||||
asTiledSpriteObject(gdObject): gdTiledSpriteObject;
|
||||
asPanelSpriteObject(gdObject): gdPanelSpriteObject;
|
||||
asTextObject(gdObject): gdTextObject;
|
||||
asShapePainterObject(gdObject): gdShapePainterObject;
|
||||
asAdMobObject(gdObject): gdAdMobObject;
|
||||
asTextEntryObject(gdObject): gdTextEntryObject;
|
||||
asParticleEmitterObject(gdObject): gdParticleEmitterObject;
|
||||
asObjectJsImplementation(gdObject): gdObjectJsImplementation;
|
||||
asSpriteConfiguration(gdObjectConfiguration): gdSpriteObject;
|
||||
asTiledSpriteConfiguration(gdObjectConfiguration): gdTiledSpriteObject;
|
||||
asPanelSpriteConfiguration(gdObjectConfiguration): gdPanelSpriteObject;
|
||||
asTextObjectConfiguration(gdObjectConfiguration): gdTextObject;
|
||||
asShapePainterConfiguration(gdObjectConfiguration): gdShapePainterObject;
|
||||
asAdMobConfiguration(gdObjectConfiguration): gdAdMobObject;
|
||||
asTextEntryConfiguration(gdObjectConfiguration): gdTextEntryObject;
|
||||
asParticleEmitterConfiguration(gdObjectConfiguration): gdParticleEmitterObject;
|
||||
asObjectJsImplementation(gdObjectConfiguration): gdObjectJsImplementation;
|
||||
asCustomObjectConfiguration(gdObjectConfiguration): gdCustomObjectConfiguration;
|
||||
|
||||
asImageResource(gdResource): gdImageResource;
|
||||
|
||||
@@ -69,9 +70,12 @@ declare class libGDevelop {
|
||||
BehaviorJsImplementation: Class<gdBehaviorJsImplementation>;
|
||||
BehaviorsSharedData: Class<gdBehaviorsSharedData>;
|
||||
BehaviorSharedDataJsImplementation: Class<gdBehaviorSharedDataJsImplementation>;
|
||||
ObjectConfiguration: Class<gdObjectConfiguration>;
|
||||
UniquePtrObjectConfiguration: Class<gdUniquePtrObjectConfiguration>;
|
||||
gdObject: Class<gdObject>;
|
||||
UniquePtrObject: Class<gdUniquePtrObject>;
|
||||
ObjectJsImplementation: Class<gdObjectJsImplementation>;
|
||||
CustomObjectConfiguration: Class<gdCustomObjectConfiguration>;
|
||||
Layout: Class<gdLayout>;
|
||||
ExternalEvents: Class<gdExternalEvents>;
|
||||
ExternalLayout: Class<gdExternalLayout>;
|
||||
|
91
newIDE/app/src/AnnouncementsFeed/AnnouncementsFeedContext.js
Normal file
91
newIDE/app/src/AnnouncementsFeed/AnnouncementsFeedContext.js
Normal file
@@ -0,0 +1,91 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import {
|
||||
type Announcement,
|
||||
listAllAnnouncements,
|
||||
} from '../Utils/GDevelopServices/Announcement';
|
||||
|
||||
type AnnouncementsFeedState = {|
|
||||
announcements: ?(Announcement[]),
|
||||
error: ?Error,
|
||||
fetchAnnouncements: () => void,
|
||||
|};
|
||||
|
||||
export const AnnouncementsFeedContext = React.createContext<AnnouncementsFeedState>(
|
||||
{
|
||||
announcements: null,
|
||||
error: null,
|
||||
fetchAnnouncements: () => {},
|
||||
}
|
||||
);
|
||||
|
||||
type AnnouncementsFeedStateProviderProps = {|
|
||||
children: React.Node,
|
||||
|};
|
||||
|
||||
export const AnnouncementsFeedStateProvider = ({
|
||||
children,
|
||||
}: AnnouncementsFeedStateProviderProps) => {
|
||||
const [announcements, setAnnouncements] = React.useState<?(Announcement[])>(
|
||||
null
|
||||
);
|
||||
const [error, setError] = React.useState<?Error>(null);
|
||||
const isLoading = React.useRef<boolean>(false);
|
||||
|
||||
const fetchAnnouncements = React.useCallback(
|
||||
() => {
|
||||
if (isLoading.current) return;
|
||||
|
||||
(async () => {
|
||||
setError(null);
|
||||
isLoading.current = true;
|
||||
|
||||
try {
|
||||
const announcements = await listAllAnnouncements();
|
||||
|
||||
setAnnouncements(announcements);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
`Unable to load the announcements from the api:`,
|
||||
error
|
||||
);
|
||||
setError(error);
|
||||
}
|
||||
|
||||
isLoading.current = false;
|
||||
})();
|
||||
},
|
||||
[isLoading]
|
||||
);
|
||||
|
||||
// Preload the announcements when the app loads.
|
||||
React.useEffect(
|
||||
() => {
|
||||
// Don't attempt to load again announcements if they
|
||||
// were loaded already.
|
||||
if (announcements || isLoading.current) return;
|
||||
|
||||
const timeoutId = setTimeout(() => {
|
||||
console.info('Pre-fetching announcements from the api...');
|
||||
fetchAnnouncements();
|
||||
}, 1000);
|
||||
return () => clearTimeout(timeoutId);
|
||||
},
|
||||
[fetchAnnouncements, announcements, isLoading]
|
||||
);
|
||||
|
||||
const announcementsFeedState = React.useMemo(
|
||||
() => ({
|
||||
announcements,
|
||||
error,
|
||||
fetchAnnouncements,
|
||||
}),
|
||||
[announcements, error, fetchAnnouncements]
|
||||
);
|
||||
|
||||
return (
|
||||
<AnnouncementsFeedContext.Provider value={announcementsFeedState}>
|
||||
{children}
|
||||
</AnnouncementsFeedContext.Provider>
|
||||
);
|
||||
};
|
111
newIDE/app/src/AnnouncementsFeed/index.js
Normal file
111
newIDE/app/src/AnnouncementsFeed/index.js
Normal file
@@ -0,0 +1,111 @@
|
||||
// @flow
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { I18n } from '@lingui/react';
|
||||
import * as React from 'react';
|
||||
import AlertMessage from '../UI/AlertMessage';
|
||||
import { ColumnStackLayout } from '../UI/Layout';
|
||||
import PlaceholderError from '../UI/PlaceholderError';
|
||||
import PlaceholderLoader from '../UI/PlaceholderLoader';
|
||||
import RaisedButton from '../UI/RaisedButton';
|
||||
import { selectMessageByLocale } from '../Utils/i18n/MessageByLocale';
|
||||
import Window from '../Utils/Window';
|
||||
import { AnnouncementsFeedContext } from './AnnouncementsFeedContext';
|
||||
import Text from '../UI/Text';
|
||||
import { Line } from '../UI/Grid';
|
||||
import PreferencesContext from '../MainFrame/Preferences/PreferencesContext';
|
||||
import { MarkdownText } from '../UI/MarkdownText';
|
||||
|
||||
type AnnouncementsFeedProps = {|
|
||||
level?: 'urgent' | 'normal',
|
||||
canClose?: boolean,
|
||||
addMargins?: boolean,
|
||||
|};
|
||||
|
||||
export const AnnouncementsFeed = ({
|
||||
level,
|
||||
canClose,
|
||||
addMargins,
|
||||
}: AnnouncementsFeedProps) => {
|
||||
const { announcements, error, fetchAnnouncements } = React.useContext(
|
||||
AnnouncementsFeedContext
|
||||
);
|
||||
const { values, showAnnouncement } = React.useContext(PreferencesContext);
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<PlaceholderError onRetry={fetchAnnouncements}>
|
||||
<Trans>
|
||||
Can't load the announcements. Verify your internet connection or try
|
||||
again later.
|
||||
</Trans>
|
||||
</PlaceholderError>
|
||||
);
|
||||
} else if (!announcements) {
|
||||
return <PlaceholderLoader />;
|
||||
}
|
||||
|
||||
const properLevelAnnouncements = level
|
||||
? announcements.filter(announcement => announcement.level === level)
|
||||
: announcements;
|
||||
|
||||
const displayedAnnouncements = canClose
|
||||
? properLevelAnnouncements.filter(announcement => {
|
||||
return !values.hiddenAnnouncements[announcement.id];
|
||||
})
|
||||
: properLevelAnnouncements;
|
||||
|
||||
if (!displayedAnnouncements.length) return null;
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<Line noMargin={!addMargins}>
|
||||
<ColumnStackLayout noMargin={!addMargins} expand>
|
||||
{displayedAnnouncements.map(announcement => {
|
||||
const { buttonLabelByLocale, buttonUrl } = announcement;
|
||||
|
||||
return (
|
||||
<AlertMessage
|
||||
kind={announcement.type === 'warning' ? 'warning' : 'info'}
|
||||
renderRightButton={
|
||||
buttonLabelByLocale && buttonUrl
|
||||
? () => (
|
||||
<RaisedButton
|
||||
label={selectMessageByLocale(
|
||||
i18n,
|
||||
buttonLabelByLocale
|
||||
)}
|
||||
onClick={() => Window.openExternalURL(buttonUrl)}
|
||||
/>
|
||||
)
|
||||
: null
|
||||
}
|
||||
onHide={
|
||||
canClose
|
||||
? () => {
|
||||
showAnnouncement(announcement.id, false);
|
||||
}
|
||||
: null
|
||||
}
|
||||
>
|
||||
<Text size="block-title">
|
||||
<Trans>
|
||||
{selectMessageByLocale(i18n, announcement.titleByLocale)}
|
||||
</Trans>
|
||||
</Text>
|
||||
<MarkdownText
|
||||
source={selectMessageByLocale(
|
||||
i18n,
|
||||
announcement.markdownMessageByLocale
|
||||
)}
|
||||
allowParagraphs={false}
|
||||
/>
|
||||
</AlertMessage>
|
||||
);
|
||||
})}
|
||||
</ColumnStackLayout>
|
||||
</Line>
|
||||
)}
|
||||
</I18n>
|
||||
);
|
||||
};
|
@@ -183,7 +183,7 @@ export const addAssetToProject = async ({
|
||||
const renamedResourcesMap = toNewGdMapStringString(resourceNewNames);
|
||||
const resourcesRenamer = new gd.ResourcesRenamer(renamedResourcesMap);
|
||||
renamedResourcesMap.delete();
|
||||
object.exposeResources(resourcesRenamer);
|
||||
object.getConfiguration().exposeResources(resourcesRenamer);
|
||||
resourcesRenamer.delete();
|
||||
|
||||
objectAsset.customization.forEach(customization => {
|
||||
|
@@ -227,7 +227,7 @@ describe('InstallAsset', () => {
|
||||
const object = layout.getObject('PlayerSpaceship');
|
||||
|
||||
const resourcesInUse = new gd.ResourcesInUseHelper();
|
||||
object.exposeResources(resourcesInUse);
|
||||
object.getConfiguration().exposeResources(resourcesInUse);
|
||||
const objectResourceNames = resourcesInUse
|
||||
.getAllImages()
|
||||
.toNewVectorString()
|
||||
|
@@ -59,6 +59,7 @@ type ImageCardProps = {|
|
||||
size: number,
|
||||
resource: Resource,
|
||||
onChoose: () => void,
|
||||
removeThemeFilterAppliedOnBackground?: boolean,
|
||||
imageStyle?: {|
|
||||
width: number,
|
||||
height: number,
|
||||
@@ -70,12 +71,21 @@ const ImageCard = ({
|
||||
onChoose,
|
||||
size,
|
||||
imageStyle,
|
||||
removeThemeFilterAppliedOnBackground,
|
||||
}: ImageCardProps) => {
|
||||
return (
|
||||
<ButtonBase onClick={onChoose} focusRipple>
|
||||
<div style={{ ...styles.cardContainer, width: size, height: size }}>
|
||||
<div style={{ ...styles.previewContainer, width: size, height: size }}>
|
||||
<CheckeredBackground />
|
||||
<CheckeredBackground
|
||||
style={
|
||||
removeThemeFilterAppliedOnBackground
|
||||
? {
|
||||
filter: 'unset',
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
<CorsAwareImage
|
||||
key={resource.url}
|
||||
style={{
|
||||
@@ -148,6 +158,7 @@ export const ResourceCard = ({ resource, onChoose, size }: Props) => {
|
||||
onChoose={onChoose}
|
||||
size={size}
|
||||
imageStyle={styles.previewIcon}
|
||||
removeThemeFilterAppliedOnBackground // All svg are black and hard to see on background darken by the theme filter so we prefer using the raw checkered background that is quite light #nofilter
|
||||
/>
|
||||
);
|
||||
case 'audio':
|
||||
|
@@ -69,6 +69,7 @@ export const create = (authentication: Authentication) => {
|
||||
renderPreviewLauncher={(props, ref) => (
|
||||
<BrowserS3PreviewLauncher {...props} ref={ref} />
|
||||
)}
|
||||
initialDialog={appArguments['initial-dialog']}
|
||||
renderExportDialog={props => (
|
||||
<ExportDialog
|
||||
project={props.project}
|
||||
|
@@ -27,6 +27,7 @@ type Props = {|
|
||||
type State = {|
|
||||
editedObjectWithContext: ?ObjectWithContext,
|
||||
editedObjectInitialTab: ?ObjectEditorTab,
|
||||
selectedObjectNames: string[],
|
||||
|};
|
||||
|
||||
export default class EventBasedObjectChildrenEditor extends React.Component<
|
||||
@@ -38,6 +39,7 @@ export default class EventBasedObjectChildrenEditor extends React.Component<
|
||||
state = {
|
||||
editedObjectWithContext: null,
|
||||
editedObjectInitialTab: 'properties',
|
||||
selectedObjectNames: [],
|
||||
};
|
||||
|
||||
_onDeleteObject = (i18n: I18nType) => (
|
||||
@@ -131,7 +133,6 @@ export default class EventBasedObjectChildrenEditor extends React.Component<
|
||||
if (object.getName() !== newName) {
|
||||
gd.WholeProjectRefactorer.objectOrGroupRenamedInEventsBasedObject(
|
||||
project,
|
||||
eventsBasedObject,
|
||||
globalObjectsContainer,
|
||||
eventsBasedObject,
|
||||
object.getName(),
|
||||
@@ -161,6 +162,18 @@ export default class EventBasedObjectChildrenEditor extends React.Component<
|
||||
}
|
||||
};
|
||||
|
||||
_onObjectSelected = (selectedObjectName: string) => {
|
||||
if (!selectedObjectName) {
|
||||
this.setState({
|
||||
selectedObjectNames: [],
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
selectedObjectNames: [selectedObjectName],
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
updateBehaviorsSharedData = () => {
|
||||
// TODO EBO Decide how BehaviorsSharedData of child-objects should work.
|
||||
// - Use a shared data per object instance
|
||||
@@ -181,6 +194,11 @@ export default class EventBasedObjectChildrenEditor extends React.Component<
|
||||
render() {
|
||||
const { eventsBasedObject, project } = this.props;
|
||||
|
||||
// TODO EBO When adding an object, filter the object types to excludes
|
||||
// object that depend (transitively) on this object to avoid cycles.
|
||||
|
||||
// TODO EBO Add a button icon to mark some objects solid or not.
|
||||
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
@@ -197,7 +215,7 @@ export default class EventBasedObjectChildrenEditor extends React.Component<
|
||||
resourceSources={[]}
|
||||
resourceExternalEditors={[]}
|
||||
onChooseResource={() => Promise.resolve([])}
|
||||
selectedObjectNames={[]}
|
||||
selectedObjectNames={this.state.selectedObjectNames}
|
||||
onEditObject={this.editObject}
|
||||
onDeleteObject={this._onDeleteObject(i18n)}
|
||||
canRenameObject={newName =>
|
||||
@@ -205,8 +223,7 @@ export default class EventBasedObjectChildrenEditor extends React.Component<
|
||||
}
|
||||
// Nothing special to do.
|
||||
onObjectCreated={() => {}}
|
||||
// Object selection has no impact.
|
||||
onObjectSelected={() => {}}
|
||||
onObjectSelected={this._onObjectSelected}
|
||||
onRenameObject={(objectWithContext, newName, done) =>
|
||||
this._onRenameObject(objectWithContext, newName, done, i18n)
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@ import Text from '../../UI/Text';
|
||||
import { ExtensionOptionsEditor } from './ExtensionOptionsEditor';
|
||||
import { Tab, Tabs } from '../../UI/Tabs';
|
||||
import { ExtensionDependenciesEditor } from './ExtensionDependenciesEditor';
|
||||
import { LineStackLayout } from '../../UI/Layout';
|
||||
|
||||
const exportExtension = (
|
||||
eventsFunctionsExtensionsState: EventsFunctionsExtensionsState,
|
||||
@@ -36,31 +37,8 @@ const exportExtension = (
|
||||
};
|
||||
|
||||
const openGitHubIssue = () => {
|
||||
const body = `
|
||||
**⚠️ Please edit and complete this before submitting your extension:**
|
||||
|
||||
## Describe the extension
|
||||
A clear and concise description of what the extension is, how useful it is.
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Extension has a proper name and description.
|
||||
- [ ] Extension has tags (for example: "platform, brick, breakable").
|
||||
- [ ] All behaviors have a description.
|
||||
- [ ] All functions (actions, conditions, expressions) have descriptions.
|
||||
- [ ] I confirm that this extension can be intergrated to this GitHub repository, distributed and MIT licensed.
|
||||
|
||||
## Extension file
|
||||
|
||||
Finally, attach the .json file of your extension here.
|
||||
|
||||
You also may have to create an account on GitHub before posting.
|
||||
If your extension is high quality and useful, it will be added to the list of GDevelop community extensions.
|
||||
When you're ready, remove this last paragraph and click on "Submit new issue". Thanks 🙌`;
|
||||
Window.openExternalURL(
|
||||
`https://github.com/4ian/GDevelop-extensions/issues/new?body=${encodeURIComponent(
|
||||
body
|
||||
)}&title=New%20extension`
|
||||
'https://github.com/GDevelopApp/GDevelop-extensions/issues/new?assignees=&labels=%E2%9C%A8+New+extension&template=new-extension.yml&title=New+extension%3A+%3Ctitle%3E'
|
||||
);
|
||||
};
|
||||
|
||||
@@ -166,7 +144,7 @@ export default function OptionsEditorDialog({
|
||||
</Trans>
|
||||
</Text>
|
||||
</Line>
|
||||
<Line>
|
||||
<LineStackLayout>
|
||||
<RaisedButton
|
||||
icon={<CloudUpload />}
|
||||
primary
|
||||
@@ -182,7 +160,7 @@ export default function OptionsEditorDialog({
|
||||
label={<Trans>Submit extension to the community</Trans>}
|
||||
onClick={openGitHubIssue}
|
||||
/>
|
||||
</Line>
|
||||
</LineStackLayout>
|
||||
</Column>
|
||||
</Dialog>
|
||||
)}
|
||||
|
@@ -1410,15 +1410,21 @@ export default class EventsFunctionsExtensionEditor extends React.Component<
|
||||
)
|
||||
}
|
||||
initialNodes={
|
||||
isDev !==
|
||||
// "objects-list" must only appear in dev mode.
|
||||
isDev ===
|
||||
mosaicContainsNode(
|
||||
initialMosaicEditorNodes,
|
||||
getDefaultEditorMosaicNode(
|
||||
'events-functions-extension-editor'
|
||||
) || initialMosaicEditorNodes,
|
||||
'objects-list'
|
||||
)
|
||||
? getDefaultEditorMosaicNode(
|
||||
'events-functions-extension-editor'
|
||||
) || initialMosaicEditorNodes
|
||||
: initialMosaicEditorNodes
|
||||
: // Force the mosaic to reset to default.
|
||||
// It contains "objects-list" only
|
||||
// in dev mode.
|
||||
initialMosaicEditorNodes
|
||||
}
|
||||
/>
|
||||
)}
|
||||
|
@@ -47,10 +47,12 @@ export default class ObjectAnimationNameField extends Component<
|
||||
}
|
||||
|
||||
if (object.getType() === 'Sprite') {
|
||||
const spriteObject = gd.asSpriteObject(object);
|
||||
const spriteConfiguration = gd.asSpriteConfiguration(
|
||||
object.getConfiguration()
|
||||
);
|
||||
|
||||
return mapFor(0, spriteObject.getAnimationsCount(), index => {
|
||||
const animationName = spriteObject.getAnimation(index).getName();
|
||||
return mapFor(0, spriteConfiguration.getAnimationsCount(), index => {
|
||||
const animationName = spriteConfiguration.getAnimation(index).getName();
|
||||
return animationName.length > 0 ? animationName : null;
|
||||
})
|
||||
.filter(Boolean)
|
||||
|
@@ -47,9 +47,11 @@ export default class ObjectPointNameField extends Component<
|
||||
}
|
||||
|
||||
if (object.getType() === 'Sprite') {
|
||||
const spriteObject = gd.asSpriteObject(object);
|
||||
const spriteConfiguration = gd.asSpriteConfiguration(
|
||||
object.getConfiguration()
|
||||
);
|
||||
|
||||
return getAllPointNames(spriteObject)
|
||||
return getAllPointNames(spriteConfiguration)
|
||||
.map(spriteObjectName =>
|
||||
spriteObjectName.length > 0 ? spriteObjectName : null
|
||||
)
|
||||
|
@@ -163,7 +163,11 @@ export const browserOnlineCordovaExportPipeline: ExportPipeline<
|
||||
exportState: ExportState,
|
||||
authenticatedUser: AuthenticatedUser,
|
||||
uploadBucketKey: string,
|
||||
gameId: string
|
||||
gameId: string,
|
||||
options: {|
|
||||
gameName: string,
|
||||
gameVersion: string,
|
||||
|}
|
||||
): Promise<Build> => {
|
||||
const { getAuthorizationHeader, firebaseUser } = authenticatedUser;
|
||||
if (!firebaseUser)
|
||||
@@ -175,7 +179,8 @@ export const browserOnlineCordovaExportPipeline: ExportPipeline<
|
||||
uploadBucketKey,
|
||||
exportState.targets,
|
||||
exportState.keystore,
|
||||
gameId
|
||||
gameId,
|
||||
options
|
||||
);
|
||||
},
|
||||
};
|
||||
|
@@ -161,7 +161,11 @@ export const browserOnlineElectronExportPipeline: ExportPipeline<
|
||||
exportState: ExportState,
|
||||
authenticatedUser: AuthenticatedUser,
|
||||
uploadBucketKey: string,
|
||||
gameId: string
|
||||
gameId: string,
|
||||
options: {|
|
||||
gameName: string,
|
||||
gameVersion: string,
|
||||
|}
|
||||
): Promise<Build> => {
|
||||
const { getAuthorizationHeader, firebaseUser } = authenticatedUser;
|
||||
if (!firebaseUser)
|
||||
@@ -172,7 +176,8 @@ export const browserOnlineElectronExportPipeline: ExportPipeline<
|
||||
firebaseUser.uid,
|
||||
uploadBucketKey,
|
||||
exportState.targets,
|
||||
gameId
|
||||
gameId,
|
||||
options
|
||||
);
|
||||
},
|
||||
};
|
||||
|
@@ -172,7 +172,11 @@ export const browserOnlineWebExportPipeline: ExportPipeline<
|
||||
exportState: ExportState,
|
||||
authenticatedUser: AuthenticatedUser,
|
||||
uploadBucketKey: string,
|
||||
gameId: string
|
||||
gameId: string,
|
||||
options: {|
|
||||
gameName: string,
|
||||
gameVersion: string,
|
||||
|}
|
||||
): Promise<Build> => {
|
||||
const { getAuthorizationHeader, firebaseUser } = authenticatedUser;
|
||||
if (!firebaseUser)
|
||||
@@ -182,7 +186,8 @@ export const browserOnlineWebExportPipeline: ExportPipeline<
|
||||
getAuthorizationHeader,
|
||||
firebaseUser.uid,
|
||||
uploadBucketKey,
|
||||
gameId
|
||||
gameId,
|
||||
options
|
||||
);
|
||||
},
|
||||
};
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user