mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
32 Commits
move-insta
...
experiment
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c8477629d0 | ||
![]() |
08b0a9ff37 | ||
![]() |
8be099d50a | ||
![]() |
713698d3d6 | ||
![]() |
8b36908fd8 | ||
![]() |
c0722dc441 | ||
![]() |
9c6a1bed2c | ||
![]() |
a8a4d14ee1 | ||
![]() |
b27abfbe5d | ||
![]() |
28b585aefa | ||
![]() |
0623b6acd9 | ||
![]() |
1a833bc388 | ||
![]() |
827f187e10 | ||
![]() |
0f25b80a66 | ||
![]() |
fbf9710cc5 | ||
![]() |
3d80709029 | ||
![]() |
5ab9c565b0 | ||
![]() |
e237fc4b21 | ||
![]() |
18892f97f3 | ||
![]() |
0ec0654032 | ||
![]() |
8e29c723e8 | ||
![]() |
6acde2865a | ||
![]() |
49e176a98f | ||
![]() |
71c2a0be01 | ||
![]() |
4ad1a0dd68 | ||
![]() |
a556690307 | ||
![]() |
6950f323b3 | ||
![]() |
de129f6cc4 | ||
![]() |
b3b88a0445 | ||
![]() |
8e8f3a7d55 | ||
![]() |
cc6b4a283a | ||
![]() |
f393f36bad |
@@ -18,8 +18,6 @@ namespace gd {
|
||||
|
||||
EventsList BaseEvent::badSubEvents;
|
||||
VariablesContainer BaseEvent::badLocalVariables;
|
||||
std::vector<gd::String> BaseEvent::emptyDependencies;
|
||||
gd::String BaseEvent::emptySourceFile;
|
||||
|
||||
BaseEvent::BaseEvent()
|
||||
: totalTimeDuringLastSession(0),
|
||||
|
@@ -175,26 +175,6 @@ class GD_CORE_API BaseEvent {
|
||||
noExpr;
|
||||
return noExpr;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Returns the dependencies on source files of the project.
|
||||
* \note Default implementation returns an empty list of dependencies. This is
|
||||
* fine for most events that are not related to adding custom user source
|
||||
* code.
|
||||
*/
|
||||
virtual const std::vector<gd::String>& GetSourceFileDependencies() const {
|
||||
return emptyDependencies;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Returns the name of the source file associated with the event
|
||||
* \note Default implementation returns an empty string. This is fine for most
|
||||
* events that are not related to adding custom user source code.
|
||||
*/
|
||||
virtual const gd::String& GetAssociatedGDManagedSourceFile(
|
||||
gd::Project& project) const {
|
||||
return emptySourceFile;
|
||||
};
|
||||
///@}
|
||||
|
||||
/** \name Code generation
|
||||
@@ -327,8 +307,6 @@ class GD_CORE_API BaseEvent {
|
||||
|
||||
static gd::EventsList badSubEvents;
|
||||
static gd::VariablesContainer badLocalVariables;
|
||||
static std::vector<gd::String> emptyDependencies;
|
||||
static gd::String emptySourceFile;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -272,7 +272,7 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
|
||||
* Check if the behavior is private - it can't be used outside of its
|
||||
* extension.
|
||||
*/
|
||||
bool IsPrivate() const { return isPrivate; }
|
||||
bool IsPrivate() const override { return isPrivate; }
|
||||
|
||||
/**
|
||||
* Set that the behavior is private - it can't be used outside of its
|
||||
|
@@ -174,6 +174,7 @@ public:
|
||||
virtual const gd::String &GetFullName() const = 0;
|
||||
virtual const gd::String &GetDescription() const = 0;
|
||||
virtual const gd::String &GetIconFilename() const = 0;
|
||||
virtual bool IsPrivate() const = 0;
|
||||
|
||||
/**
|
||||
* \brief Return a reference to a map containing the names of the actions
|
||||
|
@@ -300,6 +300,22 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
|
||||
*/
|
||||
std::map<gd::String, gd::ExpressionMetadata>& GetAllStrExpressions() override { return strExpressionsInfos; };
|
||||
|
||||
|
||||
/**
|
||||
* Check if the behavior is private - it can't be used outside of its
|
||||
* extension.
|
||||
*/
|
||||
bool IsPrivate() const override { return isPrivate; }
|
||||
|
||||
/**
|
||||
* Set that the behavior is private - it can't be used outside of its
|
||||
* extension.
|
||||
*/
|
||||
ObjectMetadata &SetPrivate() {
|
||||
isPrivate = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the object to be hidden in the IDE.
|
||||
*
|
||||
@@ -356,6 +372,7 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
|
||||
gd::String iconFilename;
|
||||
gd::String categoryFullName;
|
||||
std::set<gd::String> defaultBehaviorTypes;
|
||||
bool isPrivate = false;
|
||||
bool hidden = false;
|
||||
bool isRenderedIn3D = false;
|
||||
gd::String openFullEditorLabel;
|
||||
|
56
Core/GDCore/Extensions/Metadata/SourceFileMetadata.h
Normal file
56
Core/GDCore/Extensions/Metadata/SourceFileMetadata.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#pragma once
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
||||
namespace gd {
|
||||
/**
|
||||
* \brief Contains information about a source file that must be included
|
||||
* when an extension is used.
|
||||
*/
|
||||
class GD_CORE_API SourceFileMetadata {
|
||||
public:
|
||||
/**
|
||||
* Construct a new dependency metadata, though you probably want to call
|
||||
* `AddSourceFile` on gd::PlatformExtension.
|
||||
*
|
||||
* \see gd::PlatformExtension
|
||||
*/
|
||||
SourceFileMetadata() {};
|
||||
|
||||
SourceFileMetadata& SetResourceName(const gd::String& resourceName_) {
|
||||
resourceName = resourceName_;
|
||||
return *this;
|
||||
};
|
||||
|
||||
SourceFileMetadata& SetIncludePosition(const gd::String& includePosition_) {
|
||||
includePosition = includePosition_;
|
||||
return *this;
|
||||
};
|
||||
|
||||
const gd::String& GetResourceName() const { return resourceName; };
|
||||
|
||||
gd::String& GetResourceName() { return resourceName; };
|
||||
|
||||
const gd::String& GetIncludePosition() const { return includePosition; };
|
||||
|
||||
void SerializeTo(SerializerElement& element) const {
|
||||
element.AddChild("resourceName").SetStringValue(resourceName);
|
||||
element.AddChild("includePosition").SetStringValue(includePosition);
|
||||
}
|
||||
|
||||
void UnserializeFrom(const SerializerElement& element) {
|
||||
resourceName = element.GetStringAttribute("resourceName");
|
||||
includePosition = element.GetStringAttribute("includePosition", "last");
|
||||
}
|
||||
|
||||
private:
|
||||
gd::String resourceName; ///< The name of the resource in the project.
|
||||
gd::String includePosition = "last"; ///< "first" or "last".
|
||||
};
|
||||
|
||||
} // namespace gd
|
@@ -215,6 +215,11 @@ gd::DependencyMetadata& PlatformExtension::AddDependency() {
|
||||
return extensionDependenciesMetadata.back();
|
||||
}
|
||||
|
||||
gd::SourceFileMetadata& PlatformExtension::AddSourceFile() {
|
||||
extensionSourceFilesMetadata.push_back(SourceFileMetadata());
|
||||
return extensionSourceFilesMetadata.back();
|
||||
}
|
||||
|
||||
gd::ObjectMetadata& PlatformExtension::AddObject(
|
||||
const gd::String& name,
|
||||
const gd::String& fullname,
|
||||
@@ -463,10 +468,22 @@ PlatformExtension::GetAllStrExpressions() {
|
||||
return strExpressionsInfos;
|
||||
}
|
||||
|
||||
const std::vector<gd::DependencyMetadata>& PlatformExtension::GetAllDependencies() const {
|
||||
return extensionDependenciesMetadata;
|
||||
}
|
||||
|
||||
std::vector<gd::DependencyMetadata>& PlatformExtension::GetAllDependencies() {
|
||||
return extensionDependenciesMetadata;
|
||||
}
|
||||
|
||||
const std::vector<gd::SourceFileMetadata>& PlatformExtension::GetAllSourceFiles() const {
|
||||
return extensionSourceFilesMetadata;
|
||||
}
|
||||
|
||||
std::vector<gd::SourceFileMetadata>& PlatformExtension::GetAllSourceFiles() {
|
||||
return extensionSourceFilesMetadata;
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::EventMetadata>& PlatformExtension::GetAllEvents() {
|
||||
return eventsInfos;
|
||||
}
|
||||
|
@@ -13,6 +13,7 @@
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Extensions/Metadata/BehaviorMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/DependencyMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/SourceFileMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/EffectMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/EventMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/InstructionOrExpressionGroupMetadata.h"
|
||||
@@ -214,6 +215,7 @@ class GD_CORE_API PlatformExtension {
|
||||
const gd::String& icon);
|
||||
|
||||
gd::DependencyMetadata& AddDependency();
|
||||
gd::SourceFileMetadata& AddSourceFile();
|
||||
|
||||
/**
|
||||
* \brief Declare a new object as being part of the extension.
|
||||
@@ -552,6 +554,24 @@ class GD_CORE_API PlatformExtension {
|
||||
*/
|
||||
std::vector<gd::DependencyMetadata>& GetAllDependencies();
|
||||
|
||||
/**
|
||||
* \brief Return a reference to a vector containing the metadata of all the
|
||||
* dependencies of the extension.
|
||||
*/
|
||||
const std::vector<gd::DependencyMetadata>& GetAllDependencies() const;
|
||||
|
||||
/**
|
||||
* \brief Return a reference to a vector containing the metadata of all the
|
||||
* dependencies of the extension.
|
||||
*/
|
||||
std::vector<gd::SourceFileMetadata>& GetAllSourceFiles();
|
||||
|
||||
/**
|
||||
* \brief Return a reference to a vector containing the metadata of all the
|
||||
* dependencies of the extension.
|
||||
*/
|
||||
const std::vector<gd::SourceFileMetadata>& GetAllSourceFiles() const;
|
||||
|
||||
/**
|
||||
* \brief Return a reference to a map containing the names of the actions,
|
||||
* related to the object type, and the metadata associated with.
|
||||
@@ -687,6 +707,7 @@ class GD_CORE_API PlatformExtension {
|
||||
std::map<gd::String, gd::ExpressionMetadata> expressionsInfos;
|
||||
std::map<gd::String, gd::ExpressionMetadata> strExpressionsInfos;
|
||||
std::vector<gd::DependencyMetadata> extensionDependenciesMetadata;
|
||||
std::vector<gd::SourceFileMetadata> extensionSourceFilesMetadata;
|
||||
std::map<gd::String, gd::EventMetadata> eventsInfos;
|
||||
std::map<gd::String, gd::PropertyDescriptor> extensionPropertiesMetadata;
|
||||
std::map<gd::String, InstructionOrExpressionGroupMetadata>
|
||||
|
@@ -12,7 +12,6 @@
|
||||
#include "GDCore/Project/ExternalEvents.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/SourceFile.h"
|
||||
|
||||
DependenciesAnalyzer::DependenciesAnalyzer(const gd::Project& project_,
|
||||
const gd::Layout& layout_)
|
||||
@@ -74,16 +73,6 @@ bool DependenciesAnalyzer::Analyze(const gd::EventsList& events) {
|
||||
}
|
||||
}
|
||||
|
||||
// Search for source files dependencies
|
||||
std::vector<gd::String> dependencies =
|
||||
events[i].GetSourceFileDependencies();
|
||||
sourceFilesDependencies.insert(dependencies.begin(), dependencies.end());
|
||||
|
||||
const gd::String& associatedSourceFile =
|
||||
events[i].GetAssociatedGDManagedSourceFile(const_cast<gd::Project&>(project));
|
||||
if (!associatedSourceFile.empty())
|
||||
sourceFilesDependencies.insert(associatedSourceFile);
|
||||
|
||||
// Analyze sub events dependencies
|
||||
if (events[i].CanHaveSubEvents()) {
|
||||
if (!Analyze(events[i].GetSubEvents())) return false;
|
||||
|
@@ -71,14 +71,6 @@ class GD_CORE_API DependenciesAnalyzer {
|
||||
return externalEventsDependencies;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Return the source files being dependencies of the scene or external
|
||||
* events passed in the constructor.
|
||||
*/
|
||||
const std::set<gd::String>& GetSourceFilesDependencies() const {
|
||||
return sourceFilesDependencies;
|
||||
};
|
||||
|
||||
private:
|
||||
/**
|
||||
* \brief Analyze the dependencies of the events.
|
||||
@@ -92,7 +84,6 @@ class GD_CORE_API DependenciesAnalyzer {
|
||||
|
||||
std::set<gd::String> scenesDependencies;
|
||||
std::set<gd::String> externalEventsDependencies;
|
||||
std::set<gd::String> sourceFilesDependencies;
|
||||
std::vector<gd::String>
|
||||
parentScenes; ///< Used to check for circular dependencies.
|
||||
std::vector<gd::String>
|
||||
|
@@ -13,6 +13,18 @@
|
||||
|
||||
namespace gd {
|
||||
|
||||
void UsedExtensionsResult::AddUsedExtension(const gd::PlatformExtension& extension) {
|
||||
usedExtensions.insert(extension.GetName());
|
||||
|
||||
usedSourceFiles.insert(usedSourceFiles.end(),
|
||||
extension.GetAllSourceFiles().begin(),
|
||||
extension.GetAllSourceFiles().end());
|
||||
}
|
||||
|
||||
void UsedExtensionsResult::AddUsedBuiltinExtension(const gd::String& extensionName) {
|
||||
usedExtensions.insert(extensionName);
|
||||
}
|
||||
|
||||
const UsedExtensionsResult UsedExtensionsFinder::ScanProject(gd::Project& project) {
|
||||
UsedExtensionsFinder worker(project);
|
||||
gd::ProjectBrowserHelper::ExposeProjectObjects(project, worker);
|
||||
@@ -28,9 +40,9 @@ void UsedExtensionsFinder::DoVisitObject(gd::Object &object) {
|
||||
if (metadata.GetMetadata().IsRenderedIn3D()) {
|
||||
result.MarkAsHaving3DObjects();
|
||||
}
|
||||
result.GetUsedExtensions().insert(metadata.GetExtension().GetName());
|
||||
result.AddUsedExtension(metadata.GetExtension());
|
||||
for (auto &&includeFile : metadata.GetMetadata().includeFiles) {
|
||||
result.GetUsedIncludeFiles().insert(includeFile);
|
||||
result.AddUsedIncludeFiles(includeFile);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -39,12 +51,12 @@ void UsedExtensionsFinder::DoVisitObject(gd::Object &object) {
|
||||
void UsedExtensionsFinder::DoVisitBehavior(gd::Behavior &behavior) {
|
||||
auto metadata = gd::MetadataProvider::GetExtensionAndBehaviorMetadata(
|
||||
project.GetCurrentPlatform(), behavior.GetTypeName());
|
||||
result.GetUsedExtensions().insert(metadata.GetExtension().GetName());
|
||||
result.AddUsedExtension(metadata.GetExtension());
|
||||
for (auto &&includeFile : metadata.GetMetadata().includeFiles) {
|
||||
result.GetUsedIncludeFiles().insert(includeFile);
|
||||
result.AddUsedIncludeFiles(includeFile);
|
||||
}
|
||||
for (auto &&includeFile : metadata.GetMetadata().requiredFiles) {
|
||||
result.GetUsedRequiredFiles().insert(includeFile);
|
||||
result.AddUsedRequiredFiles(includeFile);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -57,9 +69,9 @@ bool UsedExtensionsFinder::DoVisitInstruction(gd::Instruction& instruction,
|
||||
project.GetCurrentPlatform(), instruction.GetType())
|
||||
: gd::MetadataProvider::GetExtensionAndActionMetadata(
|
||||
project.GetCurrentPlatform(), instruction.GetType());
|
||||
result.GetUsedExtensions().insert(metadata.GetExtension().GetName());
|
||||
result.AddUsedExtension(metadata.GetExtension());
|
||||
for (auto&& includeFile : metadata.GetMetadata().GetIncludeFiles()) {
|
||||
result.GetUsedIncludeFiles().insert(includeFile);
|
||||
result.AddUsedIncludeFiles(includeFile);
|
||||
}
|
||||
|
||||
gd::ParameterMetadataTools::IterateOverParameters(
|
||||
@@ -77,7 +89,7 @@ bool UsedExtensionsFinder::DoVisitInstruction(gd::Instruction& instruction,
|
||||
rootType = "number";
|
||||
parameterValue.GetRootNode()->Visit(*this);
|
||||
} else if (gd::ParameterMetadata::IsExpression("variable", parameterType))
|
||||
result.GetUsedExtensions().insert("BuiltinVariables");
|
||||
result.AddUsedBuiltinExtension("BuiltinVariables");
|
||||
});
|
||||
|
||||
return false;
|
||||
@@ -110,7 +122,7 @@ void UsedExtensionsFinder::OnVisitUnaryOperatorNode(UnaryOperatorNode& node) {
|
||||
|
||||
// Add variable extension and visit sub-expressions on variable nodes
|
||||
void UsedExtensionsFinder::OnVisitVariableNode(VariableNode& node) {
|
||||
result.GetUsedExtensions().insert("BuiltinVariables");
|
||||
result.AddUsedBuiltinExtension("BuiltinVariables");
|
||||
|
||||
auto type = gd::ExpressionTypeFinder::GetType(
|
||||
project.GetCurrentPlatform(), GetProjectScopedContainers(), rootType, node);
|
||||
@@ -123,9 +135,9 @@ void UsedExtensionsFinder::OnVisitVariableNode(VariableNode& node) {
|
||||
// This represents an object.
|
||||
auto metadata = gd::MetadataProvider::GetExtensionAndObjectMetadata(
|
||||
project.GetCurrentPlatform(), node.name);
|
||||
result.GetUsedExtensions().insert(metadata.GetExtension().GetName());
|
||||
result.AddUsedExtension(metadata.GetExtension());
|
||||
for (auto &&includeFile : metadata.GetMetadata().includeFiles) {
|
||||
result.GetUsedIncludeFiles().insert(includeFile);
|
||||
result.AddUsedIncludeFiles(includeFile);
|
||||
}
|
||||
}, [&]() {
|
||||
// This is a variable.
|
||||
@@ -143,13 +155,13 @@ void UsedExtensionsFinder::OnVisitVariableNode(VariableNode& node) {
|
||||
|
||||
void UsedExtensionsFinder::OnVisitVariableAccessorNode(
|
||||
VariableAccessorNode& node) {
|
||||
result.GetUsedExtensions().insert("BuiltinVariables");
|
||||
result.AddUsedBuiltinExtension("BuiltinVariables");
|
||||
if (node.child) node.child->Visit(*this);
|
||||
};
|
||||
|
||||
void UsedExtensionsFinder::OnVisitVariableBracketAccessorNode(
|
||||
VariableBracketAccessorNode& node) {
|
||||
result.GetUsedExtensions().insert("BuiltinVariables");
|
||||
result.AddUsedBuiltinExtension("BuiltinVariables");
|
||||
node.expression->Visit(*this);
|
||||
if (node.child) node.child->Visit(*this);
|
||||
};
|
||||
@@ -163,9 +175,9 @@ void UsedExtensionsFinder::OnVisitIdentifierNode(IdentifierNode &node) {
|
||||
// An object or object variable is used.
|
||||
auto metadata = gd::MetadataProvider::GetExtensionAndObjectMetadata(
|
||||
project.GetCurrentPlatform(), node.identifierName);
|
||||
result.GetUsedExtensions().insert(metadata.GetExtension().GetName());
|
||||
result.AddUsedExtension(metadata.GetExtension());
|
||||
for (auto &&includeFile : metadata.GetMetadata().includeFiles) {
|
||||
result.GetUsedIncludeFiles().insert(includeFile);
|
||||
result.AddUsedIncludeFiles(includeFile);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -187,9 +199,9 @@ void UsedExtensionsFinder::OnVisitFunctionCallNode(FunctionCallNode& node) {
|
||||
return;
|
||||
}
|
||||
|
||||
result.GetUsedExtensions().insert(metadata.GetExtension().GetName());
|
||||
result.AddUsedExtension(metadata.GetExtension());
|
||||
for (auto&& includeFile : metadata.GetMetadata().GetIncludeFiles()) {
|
||||
result.GetUsedIncludeFiles().insert(includeFile);
|
||||
result.AddUsedIncludeFiles(includeFile);
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -9,6 +9,8 @@
|
||||
#include <set>
|
||||
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
|
||||
#include "GDCore/Extensions/Metadata/SourceFileMetadata.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
@@ -44,6 +46,10 @@ public:
|
||||
return usedRequiredFiles;
|
||||
}
|
||||
|
||||
const std::vector<gd::SourceFileMetadata>& GetUsedSourceFiles() const {
|
||||
return usedSourceFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return true when at least 1 object uses the 3D renderer.
|
||||
*/
|
||||
@@ -51,20 +57,10 @@ public:
|
||||
return has3DObjects;
|
||||
}
|
||||
|
||||
/**
|
||||
* The extensions used by the project (or part of it).
|
||||
*/
|
||||
std::set<gd::String> &GetUsedExtensions() { return usedExtensions; }
|
||||
|
||||
/**
|
||||
* The include files used at runtime by the project (or part of it).
|
||||
*/
|
||||
std::set<gd::String> &GetUsedIncludeFiles() { return usedIncludeFiles; }
|
||||
|
||||
/**
|
||||
* The additional files required at runtime by the project (or part of it).
|
||||
*/
|
||||
std::set<gd::String> &GetUsedRequiredFiles() { return usedRequiredFiles; }
|
||||
void AddUsedExtension(const gd::PlatformExtension& extension);
|
||||
void AddUsedBuiltinExtension(const gd::String& extensionName);
|
||||
void AddUsedIncludeFiles(const gd::String& includeFile) { usedIncludeFiles.insert(includeFile); }
|
||||
void AddUsedRequiredFiles(const gd::String& requiredFile) { usedRequiredFiles.insert(requiredFile); }
|
||||
|
||||
void MarkAsHaving3DObjects() {
|
||||
has3DObjects = true;
|
||||
@@ -74,6 +70,7 @@ private:
|
||||
std::set<gd::String> usedExtensions;
|
||||
std::set<gd::String> usedIncludeFiles;
|
||||
std::set<gd::String> usedRequiredFiles;
|
||||
std::vector<gd::SourceFileMetadata> usedSourceFiles;
|
||||
bool has3DObjects = false;
|
||||
};
|
||||
|
||||
|
@@ -62,6 +62,11 @@ void ArbitraryResourceWorker::ExposeSpine(gd::String& resourceName){
|
||||
// do.
|
||||
};
|
||||
|
||||
void ArbitraryResourceWorker::ExposeJavaScript(gd::String& resourceName){
|
||||
// Nothing to do by default - each child class can define here the action to
|
||||
// do.
|
||||
};
|
||||
|
||||
void ArbitraryResourceWorker::ExposeVideo(gd::String& videoName){
|
||||
// Nothing to do by default - each child class can define here the action to
|
||||
// do.
|
||||
@@ -195,6 +200,10 @@ void ArbitraryResourceWorker::ExposeResourceWithType(
|
||||
ExposeSpine(resourceName);
|
||||
return;
|
||||
}
|
||||
if (resourceType == "javascript") {
|
||||
ExposeJavaScript(resourceName);
|
||||
return;
|
||||
}
|
||||
gd::LogError("Unexpected resource type: " + resourceType + " for: " + resourceName);
|
||||
return;
|
||||
}
|
||||
|
@@ -96,7 +96,7 @@ public:
|
||||
* \brief Expose a 3D model, which is always a reference to a "model3D" resource.
|
||||
*/
|
||||
virtual void ExposeModel3D(gd::String &resourceName);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Expose an atlas, which is always a reference to a "atlas" resource.
|
||||
*/
|
||||
@@ -112,6 +112,11 @@ public:
|
||||
*/
|
||||
virtual void ExposeVideo(gd::String &videoName);
|
||||
|
||||
/**
|
||||
* \brief Expose a JavaScript file, which is always a reference to a "javascript" resource.
|
||||
*/
|
||||
virtual void ExposeJavaScript(gd::String &javaScriptName);
|
||||
|
||||
/**
|
||||
* \brief Expose a bitmap font, which is always a reference to a "bitmapFont" resource.
|
||||
*/
|
||||
|
@@ -38,6 +38,10 @@ void AssetResourcePathCleaner::ExposeVideo(gd::String &videoName) {
|
||||
ExposeResourceAsFile(videoName);
|
||||
}
|
||||
|
||||
void AssetResourcePathCleaner::ExposeJavaScript(gd::String &javaScriptResourceName) {
|
||||
ExposeResourceAsFile(javaScriptResourceName);
|
||||
}
|
||||
|
||||
void AssetResourcePathCleaner::ExposeBitmapFont(gd::String &bitmapFontName) {
|
||||
ExposeResourceAsFile(bitmapFontName);
|
||||
}
|
||||
|
@@ -46,6 +46,7 @@ public:
|
||||
void ExposeTileset(gd::String &tilesetName) override;
|
||||
void ExposeVideo(gd::String &videoName) override;
|
||||
void ExposeBitmapFont(gd::String &bitmapFontName) override;
|
||||
void ExposeJavaScript(gd::String &javaScriptResourceName) override;
|
||||
void ExposeFile(gd::String &resource) override;
|
||||
|
||||
protected:
|
||||
|
@@ -73,6 +73,9 @@ public:
|
||||
virtual void ExposeVideo(gd::String& otherResourceName) override {
|
||||
MatchResourceName(otherResourceName);
|
||||
};
|
||||
virtual void ExposeJavaScript(gd::String& otherResourceName) override {
|
||||
MatchResourceName(otherResourceName);
|
||||
};
|
||||
virtual void ExposeBitmapFont(gd::String& otherResourceName) override {
|
||||
MatchResourceName(otherResourceName);
|
||||
};
|
||||
|
@@ -60,6 +60,7 @@ public:
|
||||
if (resourceType == "model3D") return allModel3Ds;
|
||||
if (resourceType == "atlas") return allAtlases;
|
||||
if (resourceType == "spine") return allSpines;
|
||||
if (resourceType == "javascript") return allJavaScripts;
|
||||
|
||||
return emptyResources;
|
||||
};
|
||||
@@ -88,6 +89,9 @@ public:
|
||||
virtual void ExposeVideo(gd::String& resourceName) override {
|
||||
allVideos.insert(resourceName);
|
||||
};
|
||||
virtual void ExposeJavaScript(gd::String& resourceName) override {
|
||||
allJavaScripts.insert(resourceName);
|
||||
};
|
||||
virtual void ExposeBitmapFont(gd::String& resourceName) override {
|
||||
allBitmapFonts.insert(resourceName);
|
||||
};
|
||||
@@ -114,6 +118,7 @@ public:
|
||||
std::set<gd::String> allModel3Ds;
|
||||
std::set<gd::String> allAtlases;
|
||||
std::set<gd::String> allSpines;
|
||||
std::set<gd::String> allJavaScripts;
|
||||
std::set<gd::String> emptyResources;
|
||||
|
||||
static const std::vector<gd::String> resourceTypes;
|
||||
|
@@ -59,6 +59,9 @@ class ResourcesRenamer : public gd::ArbitraryResourceWorker {
|
||||
virtual void ExposeVideo(gd::String& videoResourceName) override {
|
||||
RenameIfNeeded(videoResourceName);
|
||||
};
|
||||
virtual void ExposeJavaScript(gd::String& javaScriptResourceName) override {
|
||||
RenameIfNeeded(javaScriptResourceName);
|
||||
};
|
||||
virtual void ExposeBitmapFont(gd::String& bitmapFontName) override {
|
||||
RenameIfNeeded(bitmapFontName);
|
||||
};
|
||||
|
@@ -74,6 +74,9 @@ private:
|
||||
void ExposeVideo(gd::String &videoResourceName) override {
|
||||
AddUsedResource(videoResourceName);
|
||||
};
|
||||
void ExposeJavaScript(gd::String &javaScriptResourceName) override {
|
||||
AddUsedResource(javaScriptResourceName);
|
||||
};
|
||||
void ExposeBitmapFont(gd::String &bitmapFontName) override {
|
||||
AddUsedResource(bitmapFontName);
|
||||
};
|
||||
|
@@ -26,8 +26,8 @@ namespace gd {
|
||||
|
||||
void ProjectBrowserHelper::ExposeProjectEvents(
|
||||
gd::Project &project, gd::ArbitraryEventsWorker &worker) {
|
||||
// See also gd::Project::ExposeResources for a method that traverses the whole
|
||||
// project (this time for resources).
|
||||
// See also gd::ResourceExposer::ExposeWholeProjectResources
|
||||
// for a method that traverses the whole project (this time for resources).
|
||||
|
||||
ExposeProjectEventsWithoutExtensions(project, worker);
|
||||
|
||||
@@ -106,16 +106,16 @@ void ProjectBrowserHelper::ExposeLayoutEventsAndDependencies(
|
||||
}
|
||||
for (const gd::String& sceneName : dependenciesAnalyzer.GetScenesDependencies()) {
|
||||
gd::Layout& dependencyLayout = project.GetLayout(sceneName);
|
||||
|
||||
|
||||
worker.Launch(dependencyLayout.GetEvents());
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectBrowserHelper::ExposeProjectEvents(
|
||||
gd::Project &project, gd::ArbitraryEventsWorkerWithContext &worker) {
|
||||
// See also gd::Project::ExposeResources for a method that traverse the whole
|
||||
// project (this time for resources) and ExposeProjectEffects (this time for
|
||||
// effects).
|
||||
// See also gd::ResourceExposer::ExposeWholeProjectResources
|
||||
// for a method that traverses the whole project (this time for resources)
|
||||
// and ExposeProjectEffects (this time for effects).
|
||||
|
||||
// Add layouts events
|
||||
for (std::size_t s = 0; s < project.GetLayoutsCount(); s++) {
|
||||
|
@@ -5,21 +5,22 @@
|
||||
*/
|
||||
#include "ResourceExposer.h"
|
||||
|
||||
#include "GDCore/Extensions/Metadata/EffectMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#include "GDCore/IDE/ProjectBrowserHelper.h"
|
||||
#include "GDCore/Project/Effect.h"
|
||||
#include "GDCore/Project/EventsFunctionsExtension.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/Effect.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Metadata/EffectMetadata.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
void ResourceExposer::ExposeWholeProjectResources(gd::Project& project, gd::ArbitraryResourceWorker& worker) {
|
||||
void ResourceExposer::ExposeWholeProjectResources(
|
||||
gd::Project &project, gd::ArbitraryResourceWorker &worker) {
|
||||
// See also gd::ProjectBrowserHelper::ExposeProjectEvents for a method that
|
||||
// traverse the whole project (this time for events) and ExposeProjectEffects
|
||||
// (this time for effects).
|
||||
@@ -31,13 +32,11 @@ void ResourceExposer::ExposeWholeProjectResources(gd::Project& project, gd::Arbi
|
||||
|
||||
// Expose event resources
|
||||
auto eventWorker = gd::GetResourceWorkerOnEvents(project, worker);
|
||||
gd::ProjectBrowserHelper::ExposeProjectEvents(
|
||||
project, eventWorker);
|
||||
gd::ProjectBrowserHelper::ExposeProjectEvents(project, eventWorker);
|
||||
|
||||
// Expose object configuration resources
|
||||
auto objectWorker = gd::GetResourceWorkerOnObjects(project, worker);
|
||||
gd::ProjectBrowserHelper::ExposeProjectObjects(
|
||||
project, objectWorker);
|
||||
gd::ProjectBrowserHelper::ExposeProjectObjects(project, objectWorker);
|
||||
|
||||
// Expose layer effect resources
|
||||
for (std::size_t layoutIndex = 0; layoutIndex < project.GetLayoutsCount();
|
||||
@@ -52,28 +51,36 @@ void ResourceExposer::ExposeWholeProjectResources(gd::Project& project, gd::Arbi
|
||||
for (size_t effectIndex = 0; effectIndex < effects.GetEffectsCount();
|
||||
effectIndex++) {
|
||||
auto &effect = effects.GetEffect(effectIndex);
|
||||
gd::ResourceExposer::ExposeEffectResources(project.GetCurrentPlatform(),
|
||||
effect, worker);
|
||||
gd::ResourceExposer::ExposeEffectResources(
|
||||
project.GetCurrentPlatform(), effect, worker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Expose loading screen background image if present
|
||||
auto& loadingScreen = project.GetLoadingScreen();
|
||||
auto &loadingScreen = project.GetLoadingScreen();
|
||||
if (loadingScreen.GetBackgroundImageResourceName() != "")
|
||||
worker.ExposeImage(loadingScreen.GetBackgroundImageResourceName());
|
||||
|
||||
// Expose extension source files
|
||||
for (std::size_t e = 0; e < project.GetEventsFunctionsExtensionsCount();
|
||||
e++) {
|
||||
auto &eventsFunctionsExtension = project.GetEventsFunctionsExtension(e);
|
||||
ExposeExtensionResources(eventsFunctionsExtension, worker);
|
||||
}
|
||||
}
|
||||
|
||||
void ResourceExposer::ExposeProjectResources(gd::Project& project, gd::ArbitraryResourceWorker& worker) {
|
||||
void ResourceExposer::ExposeProjectResources(
|
||||
gd::Project &project, gd::ArbitraryResourceWorker &worker) {
|
||||
// Expose global objects configuration resources
|
||||
auto objectWorker = gd::GetResourceWorkerOnObjects(project, worker);
|
||||
objectWorker.Launch(project.GetObjects());
|
||||
}
|
||||
|
||||
void ResourceExposer::ExposeLayoutResources(
|
||||
gd::Project &project, gd::Layout &layout,
|
||||
gd::Project &project,
|
||||
gd::Layout &layout,
|
||||
gd::ArbitraryResourceWorker &worker) {
|
||||
|
||||
// Expose object configuration resources
|
||||
auto objectWorker = gd::GetResourceWorkerOnObjects(project, worker);
|
||||
gd::ProjectBrowserHelper::ExposeLayoutObjects(layout, objectWorker);
|
||||
@@ -87,15 +94,15 @@ void ResourceExposer::ExposeLayoutResources(
|
||||
for (size_t effectIndex = 0; effectIndex < effects.GetEffectsCount();
|
||||
effectIndex++) {
|
||||
auto &effect = effects.GetEffect(effectIndex);
|
||||
gd::ResourceExposer::ExposeEffectResources(project.GetCurrentPlatform(),
|
||||
effect, worker);
|
||||
gd::ResourceExposer::ExposeEffectResources(
|
||||
project.GetCurrentPlatform(), effect, worker);
|
||||
}
|
||||
}
|
||||
|
||||
// Expose event resources
|
||||
auto eventWorker = gd::GetResourceWorkerOnEvents(project, worker);
|
||||
gd::ProjectBrowserHelper::ExposeLayoutEventsAndDependencies(project, layout,
|
||||
eventWorker);
|
||||
gd::ProjectBrowserHelper::ExposeLayoutEventsAndDependencies(
|
||||
project, layout, eventWorker);
|
||||
|
||||
// Exposed extension event resources
|
||||
// Note that using resources in extensions is very unlikely and probably not
|
||||
@@ -103,12 +110,14 @@ void ResourceExposer::ExposeLayoutResources(
|
||||
for (std::size_t e = 0; e < project.GetEventsFunctionsExtensionsCount();
|
||||
e++) {
|
||||
auto &eventsFunctionsExtension = project.GetEventsFunctionsExtension(e);
|
||||
gd::ProjectBrowserHelper::ExposeEventsFunctionsExtensionEvents(project, eventsFunctionsExtension, eventWorker);
|
||||
gd::ProjectBrowserHelper::ExposeEventsFunctionsExtensionEvents(
|
||||
project, eventsFunctionsExtension, eventWorker);
|
||||
}
|
||||
}
|
||||
|
||||
void ResourceExposer::ExposeEffectResources(
|
||||
gd::Platform &platform, gd::Effect &effect,
|
||||
gd::Platform &platform,
|
||||
gd::Effect &effect,
|
||||
gd::ArbitraryResourceWorker &worker) {
|
||||
auto &effectMetadata =
|
||||
MetadataProvider::GetEffectMetadata(platform, effect.GetEffectType());
|
||||
@@ -127,11 +136,20 @@ void ResourceExposer::ExposeEffectResources(
|
||||
worker.ExposeResourceWithType(resourceType,
|
||||
potentiallyUpdatedResourceName);
|
||||
if (potentiallyUpdatedResourceName != resourceName) {
|
||||
effect.SetStringParameter(propertyName, potentiallyUpdatedResourceName);
|
||||
effect.SetStringParameter(propertyName,
|
||||
potentiallyUpdatedResourceName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
void ResourceExposer::ExposeExtensionResources(
|
||||
gd::EventsFunctionsExtension &extension,
|
||||
gd::ArbitraryResourceWorker &worker) {
|
||||
for (auto &sourceFile : extension.GetAllSourceFiles()) {
|
||||
worker.ExposeJavaScript(sourceFile.GetResourceName());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -9,9 +9,10 @@ namespace gd {
|
||||
class Platform;
|
||||
class Project;
|
||||
class ArbitraryResourceWorker;
|
||||
class EventsFunctionsExtension;
|
||||
class Effect;
|
||||
class Layout;
|
||||
} // namespace gd
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
@@ -19,7 +20,7 @@ namespace gd {
|
||||
* \brief
|
||||
*/
|
||||
class GD_CORE_API ResourceExposer {
|
||||
public:
|
||||
public:
|
||||
/**
|
||||
* \brief Called ( e.g. during compilation ) so as to inventory internal
|
||||
* resources, sometimes update their filename or any other work or resources.
|
||||
@@ -34,7 +35,7 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Expose only the resources used globally on a project.
|
||||
*
|
||||
*
|
||||
* It doesn't include resources used in layouts.
|
||||
*/
|
||||
static void ExposeProjectResources(gd::Project &project,
|
||||
@@ -42,17 +43,25 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Expose the resources used in a given layout.
|
||||
*
|
||||
*
|
||||
* It doesn't include resources used globally.
|
||||
*/
|
||||
static void ExposeLayoutResources(gd::Project &project, gd::Layout &layout,
|
||||
gd::ArbitraryResourceWorker &worker);
|
||||
static void ExposeLayoutResources(gd::Project &project,
|
||||
gd::Layout &layout,
|
||||
gd::ArbitraryResourceWorker &worker);
|
||||
|
||||
/**
|
||||
* @brief Expose the resources used in a given effect.
|
||||
*/
|
||||
static void ExposeEffectResources(gd::Platform &platform, gd::Effect &effect,
|
||||
static void ExposeEffectResources(gd::Platform &platform,
|
||||
gd::Effect &effect,
|
||||
gd::ArbitraryResourceWorker &worker);
|
||||
|
||||
/**
|
||||
* @brief Expose the resources used in an extension.
|
||||
*/
|
||||
static void ExposeExtensionResources(gd::EventsFunctionsExtension &extension,
|
||||
gd::ArbitraryResourceWorker &worker);
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
} // namespace gd
|
||||
|
@@ -23,6 +23,9 @@ void AbstractEventsBasedEntity::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("description", description);
|
||||
element.SetAttribute("name", name);
|
||||
element.SetAttribute("fullName", fullName);
|
||||
if (isPrivate) {
|
||||
element.SetBoolAttribute("private", isPrivate);
|
||||
}
|
||||
|
||||
gd::SerializerElement& eventsFunctionsElement =
|
||||
element.AddChild("eventsFunctions");
|
||||
@@ -36,6 +39,7 @@ void AbstractEventsBasedEntity::UnserializeFrom(
|
||||
description = element.GetStringAttribute("description");
|
||||
name = element.GetStringAttribute("name");
|
||||
fullName = element.GetStringAttribute("fullName");
|
||||
isPrivate = element.GetBoolAttribute("private");
|
||||
|
||||
const gd::SerializerElement& eventsFunctionsElement =
|
||||
element.GetChild("eventsFunctions");
|
||||
|
@@ -3,8 +3,7 @@
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef GDCORE_ABSTRACTEVENTSBASEDENTITY_H
|
||||
#define GDCORE_ABSTRACTEVENTSBASEDENTITY_H
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "GDCore/Project/NamedPropertyDescriptor.h"
|
||||
@@ -40,6 +39,21 @@ class GD_CORE_API AbstractEventsBasedEntity {
|
||||
*/
|
||||
AbstractEventsBasedEntity* Clone() const { return new AbstractEventsBasedEntity(*this); };
|
||||
|
||||
/**
|
||||
* \brief Check if the behavior or object is private - it can't be used outside of its
|
||||
* extension.
|
||||
*/
|
||||
bool IsPrivate() const { return isPrivate; }
|
||||
|
||||
/**
|
||||
* \brief Set that the behavior or object is private - it can't be used outside of its
|
||||
* extension.
|
||||
*/
|
||||
AbstractEventsBasedEntity& SetPrivate(bool isPrivate_) {
|
||||
isPrivate = isPrivate_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the description of the behavior or object, that is displayed in the
|
||||
* editor.
|
||||
@@ -151,8 +165,7 @@ class GD_CORE_API AbstractEventsBasedEntity {
|
||||
gd::EventsFunctionsContainer eventsFunctionsContainer;
|
||||
gd::PropertiesContainer propertyDescriptors;
|
||||
gd::String extensionName;
|
||||
bool isPrivate = false;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_ABSTRACTEVENTSBASEDENTITY_H
|
||||
|
@@ -53,7 +53,8 @@ std::map<gd::String, gd::PropertyDescriptor> CustomConfigurationHelper::GetPrope
|
||||
if (configurationContent.HasChild(propertyName)) {
|
||||
if (propertyType == "String" || propertyType == "Choice" ||
|
||||
propertyType == "Color" || propertyType == "Behavior" ||
|
||||
propertyType == "Resource" || propertyType == "LeaderboardId") {
|
||||
propertyType == "Resource" || propertyType == "LeaderboardId" ||
|
||||
propertyType == "AnimationName") {
|
||||
newProperty.SetValue(
|
||||
configurationContent.GetChild(propertyName).GetStringValue());
|
||||
} else if (propertyType == "Number") {
|
||||
@@ -89,7 +90,8 @@ bool CustomConfigurationHelper::UpdateProperty(
|
||||
|
||||
if (propertyType == "String" || propertyType == "Choice" ||
|
||||
propertyType == "Color" || propertyType == "Behavior" ||
|
||||
propertyType == "Resource" || propertyType == "LeaderboardId") {
|
||||
propertyType == "Resource" || propertyType == "LeaderboardId" ||
|
||||
propertyType == "AnimationName") {
|
||||
element.SetStringValue(newValue);
|
||||
} else if (propertyType == "Number") {
|
||||
element.SetDoubleValue(newValue.To<double>());
|
||||
|
@@ -21,9 +21,6 @@ EventsBasedBehavior::EventsBasedBehavior()
|
||||
void EventsBasedBehavior::SerializeTo(SerializerElement& element) const {
|
||||
AbstractEventsBasedEntity::SerializeTo(element);
|
||||
element.SetAttribute("objectType", objectType);
|
||||
if (isPrivate) {
|
||||
element.SetBoolAttribute("private", isPrivate);
|
||||
}
|
||||
sharedPropertyDescriptors.SerializeElementsTo(
|
||||
"propertyDescriptor", element.AddChild("sharedPropertyDescriptors"));
|
||||
if (quickCustomizationVisibility != QuickCustomization::Visibility::Default) {
|
||||
@@ -39,7 +36,6 @@ void EventsBasedBehavior::UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element) {
|
||||
AbstractEventsBasedEntity::UnserializeFrom(project, element);
|
||||
objectType = element.GetStringAttribute("objectType");
|
||||
isPrivate = element.GetBoolAttribute("private");
|
||||
sharedPropertyDescriptors.UnserializeElementsFrom(
|
||||
"propertyDescriptor", element.GetChild("sharedPropertyDescriptors"));
|
||||
if (element.HasChild("quickCustomizationVisibility")) {
|
||||
|
@@ -3,8 +3,7 @@
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef GDCORE_EVENTSBASEDBEHAVIOR_H
|
||||
#define GDCORE_EVENTSBASEDBEHAVIOR_H
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "GDCore/Project/AbstractEventsBasedEntity.h"
|
||||
@@ -75,17 +74,11 @@ class GD_CORE_API EventsBasedBehavior: public AbstractEventsBasedEntity {
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check if the behavior is private - it can't be used outside of its
|
||||
* \brief Set that the behavior or object is private - it can't be used outside of its
|
||||
* extension.
|
||||
*/
|
||||
bool IsPrivate() const { return isPrivate; }
|
||||
|
||||
/**
|
||||
* \brief Set that the behavior is private - it can't be used outside of its
|
||||
* extension.
|
||||
*/
|
||||
EventsBasedBehavior& SetPrivate(bool _isPrivate) {
|
||||
isPrivate = _isPrivate;
|
||||
EventsBasedBehavior& SetPrivate(bool isPrivate) {
|
||||
AbstractEventsBasedEntity::SetPrivate(isPrivate);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -149,11 +142,8 @@ class GD_CORE_API EventsBasedBehavior: public AbstractEventsBasedEntity {
|
||||
|
||||
private:
|
||||
gd::String objectType;
|
||||
bool isPrivate = false;
|
||||
gd::PropertiesContainer sharedPropertyDescriptors;
|
||||
QuickCustomization::Visibility quickCustomizationVisibility;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_EVENTSBASEDBEHAVIOR_H
|
||||
|
@@ -72,6 +72,15 @@ class GD_CORE_API EventsBasedObject: public AbstractEventsBasedEntity {
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set that the object is private - it can't be used outside of its
|
||||
* extension.
|
||||
*/
|
||||
EventsBasedObject& SetPrivate(bool isPrivate) {
|
||||
AbstractEventsBasedEntity::SetPrivate(isPrivate);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Declare a usage of the 3D renderer.
|
||||
*/
|
||||
|
@@ -87,6 +87,13 @@ void EventsFunctionsExtension::SerializeTo(SerializerElement& element) const {
|
||||
for (auto& dependency : dependencies)
|
||||
SerializeDependencyTo(dependency, dependenciesElement.AddChild(""));
|
||||
|
||||
if (!sourceFiles.empty()) {
|
||||
auto& sourceFilesElement = element.AddChild("sourceFiles");
|
||||
sourceFilesElement.ConsiderAsArray();
|
||||
for (auto& sourceFile : sourceFiles)
|
||||
sourceFile.SerializeTo(sourceFilesElement.AddChild(""));
|
||||
}
|
||||
|
||||
GetGlobalVariables().SerializeTo(element.AddChild("globalVariables"));
|
||||
GetSceneVariables().SerializeTo(element.AddChild("sceneVariables"));
|
||||
|
||||
@@ -159,6 +166,17 @@ void EventsFunctionsExtension::UnserializeExtensionDeclarationFrom(
|
||||
dependencies.push_back(
|
||||
UnserializeDependencyFrom(dependenciesElement.GetChild(i)));
|
||||
|
||||
sourceFiles.clear();
|
||||
if (element.HasChild("sourceFiles")) {
|
||||
const auto& sourceFilesElement = element.GetChild("sourceFiles");
|
||||
sourceFilesElement.ConsiderAsArray();
|
||||
for (size_t i = 0; i < sourceFilesElement.GetChildrenCount(); ++i) {
|
||||
SourceFileMetadata sourceFile;
|
||||
sourceFile.UnserializeFrom(sourceFilesElement.GetChild(i));
|
||||
sourceFiles.push_back(sourceFile);
|
||||
}
|
||||
}
|
||||
|
||||
globalVariables.UnserializeFrom(element.GetChild("globalVariables"));
|
||||
sceneVariables.UnserializeFrom(element.GetChild("sceneVariables"));
|
||||
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Extensions/Metadata/DependencyMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/SourceFileMetadata.h"
|
||||
#include "GDCore/Project/EventsBasedBehavior.h"
|
||||
#include "GDCore/Project/EventsBasedObject.h"
|
||||
#include "GDCore/Project/EventsFunctionsContainer.h"
|
||||
@@ -289,6 +290,42 @@ class GD_CORE_API EventsFunctionsExtension : public EventsFunctionsContainer {
|
||||
const gd::String& eventsFunctionName);
|
||||
///@}
|
||||
|
||||
/** \name Source files
|
||||
*/
|
||||
///@{
|
||||
|
||||
/**
|
||||
* \brief Adds a new source file.
|
||||
*/
|
||||
gd::SourceFileMetadata& AddSourceFile() {
|
||||
gd::SourceFileMetadata sourceFile;
|
||||
sourceFiles.push_back(sourceFile);
|
||||
return sourceFiles.back();
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Removes a source file.
|
||||
*/
|
||||
void RemoveSourceFileAt(size_t index) {
|
||||
sourceFiles.erase(sourceFiles.begin() + index);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Returns the list of source files.
|
||||
*/
|
||||
std::vector<gd::SourceFileMetadata>& GetAllSourceFiles() {
|
||||
return sourceFiles;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Returns the list of source files.
|
||||
*/
|
||||
const std::vector<gd::SourceFileMetadata>& GetAllSourceFiles() const {
|
||||
return sourceFiles;
|
||||
};
|
||||
|
||||
///@}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Initialize object using another object. Used by copy-ctor and assign-op.
|
||||
@@ -336,7 +373,8 @@ class GD_CORE_API EventsFunctionsExtension : public EventsFunctionsContainer {
|
||||
gd::SerializableWithNameList<EventsBasedBehavior> eventsBasedBehaviors;
|
||||
gd::SerializableWithNameList<EventsBasedObject> eventsBasedObjects;
|
||||
std::vector<gd::DependencyMetadata> dependencies;
|
||||
|
||||
std::vector<gd::SourceFileMetadata> sourceFiles;
|
||||
|
||||
gd::VariablesContainer globalVariables;
|
||||
gd::VariablesContainer sceneVariables;
|
||||
};
|
||||
|
@@ -30,7 +30,6 @@
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
#include "GDCore/Project/ObjectGroupsContainer.h"
|
||||
#include "GDCore/Project/ResourcesManager.h"
|
||||
#include "GDCore/Project/SourceFile.h"
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/String.h"
|
||||
@@ -67,7 +66,6 @@ Project::Project()
|
||||
isAntialisingEnabledOnMobile(false),
|
||||
projectUuid(""),
|
||||
useDeprecatedZeroAsDefaultZOrder(false),
|
||||
useExternalSourceFiles(false),
|
||||
isPlayableWithKeyboard(false),
|
||||
isPlayableWithGamepad(false),
|
||||
isPlayableWithMobile(false),
|
||||
@@ -742,9 +740,6 @@ void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
loadingScreen.UnserializeFrom(propElement.GetChild("loadingScreen"));
|
||||
watermark.UnserializeFrom(propElement.GetChild("watermark"));
|
||||
|
||||
useExternalSourceFiles =
|
||||
propElement.GetBoolAttribute("useExternalSourceFiles");
|
||||
|
||||
authorIds.clear();
|
||||
auto& authorIdsElement = propElement.GetChild("authorIds");
|
||||
authorIdsElement.ConsiderAsArray();
|
||||
@@ -917,19 +912,6 @@ void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
InsertNewExternalLayout("", GetExternalLayoutsCount());
|
||||
newExternalLayout.UnserializeFrom(externalLayoutElement);
|
||||
}
|
||||
|
||||
externalSourceFiles.clear();
|
||||
const SerializerElement& externalSourceFilesElement =
|
||||
element.GetChild("externalSourceFiles", 0, "ExternalSourceFiles");
|
||||
externalSourceFilesElement.ConsiderAsArrayOf("sourceFile", "SourceFile");
|
||||
for (std::size_t i = 0; i < externalSourceFilesElement.GetChildrenCount();
|
||||
++i) {
|
||||
const SerializerElement& sourceFileElement =
|
||||
externalSourceFilesElement.GetChild(i);
|
||||
|
||||
gd::SourceFile& newSourceFile = InsertNewSourceFile("", "");
|
||||
newSourceFile.UnserializeFrom(sourceFileElement);
|
||||
}
|
||||
}
|
||||
|
||||
void Project::UnserializeAndInsertExtensionsFrom(
|
||||
@@ -1109,7 +1091,6 @@ void Project::SerializeTo(SerializerElement& element) const {
|
||||
propElement.AddChild("platformSpecificAssets"));
|
||||
loadingScreen.SerializeTo(propElement.AddChild("loadingScreen"));
|
||||
watermark.SerializeTo(propElement.AddChild("watermark"));
|
||||
propElement.SetAttribute("useExternalSourceFiles", useExternalSourceFiles);
|
||||
|
||||
auto& authorIdsElement = propElement.AddChild("authorIds");
|
||||
authorIdsElement.ConsiderAsArray();
|
||||
@@ -1197,13 +1178,6 @@ void Project::SerializeTo(SerializerElement& element) const {
|
||||
for (std::size_t i = 0; i < externalLayouts.size(); ++i)
|
||||
externalLayouts[i]->SerializeTo(
|
||||
externalLayoutsElement.AddChild("externalLayout"));
|
||||
|
||||
SerializerElement& externalSourceFilesElement =
|
||||
element.AddChild("externalSourceFiles");
|
||||
externalSourceFilesElement.ConsiderAsArrayOf("sourceFile");
|
||||
for (std::size_t i = 0; i < externalSourceFiles.size(); ++i)
|
||||
externalSourceFiles[i]->SerializeTo(
|
||||
externalSourceFilesElement.AddChild("sourceFile"));
|
||||
}
|
||||
|
||||
bool Project::IsNameSafe(const gd::String& name) {
|
||||
@@ -1244,63 +1218,6 @@ gd::String Project::GetSafeName(const gd::String& name) {
|
||||
return newName;
|
||||
}
|
||||
|
||||
bool Project::HasSourceFile(gd::String name, gd::String language) const {
|
||||
vector<std::unique_ptr<SourceFile> >::const_iterator sourceFile =
|
||||
find_if(externalSourceFiles.begin(),
|
||||
externalSourceFiles.end(),
|
||||
[&name](const std::unique_ptr<SourceFile>& sourceFile) {
|
||||
return sourceFile->GetFileName() == name;
|
||||
});
|
||||
|
||||
if (sourceFile == externalSourceFiles.end()) return false;
|
||||
|
||||
return language.empty() || (*sourceFile)->GetLanguage() == language;
|
||||
}
|
||||
|
||||
gd::SourceFile& Project::GetSourceFile(const gd::String& name) {
|
||||
return *(*find_if(externalSourceFiles.begin(),
|
||||
externalSourceFiles.end(),
|
||||
[&name](const std::unique_ptr<SourceFile>& sourceFile) {
|
||||
return sourceFile->GetFileName() == name;
|
||||
}));
|
||||
}
|
||||
|
||||
const gd::SourceFile& Project::GetSourceFile(const gd::String& name) const {
|
||||
return *(*find_if(externalSourceFiles.begin(),
|
||||
externalSourceFiles.end(),
|
||||
[&name](const std::unique_ptr<SourceFile>& sourceFile) {
|
||||
return sourceFile->GetFileName() == name;
|
||||
}));
|
||||
}
|
||||
|
||||
void Project::RemoveSourceFile(const gd::String& name) {
|
||||
std::vector<std::unique_ptr<gd::SourceFile> >::iterator sourceFile =
|
||||
find_if(externalSourceFiles.begin(),
|
||||
externalSourceFiles.end(),
|
||||
[&name](const std::unique_ptr<SourceFile>& sourceFile) {
|
||||
return sourceFile->GetFileName() == name;
|
||||
});
|
||||
if (sourceFile == externalSourceFiles.end()) return;
|
||||
|
||||
externalSourceFiles.erase(sourceFile);
|
||||
}
|
||||
|
||||
gd::SourceFile& Project::InsertNewSourceFile(const gd::String& name,
|
||||
const gd::String& language,
|
||||
std::size_t position) {
|
||||
if (HasSourceFile(name, language)) return GetSourceFile(name);
|
||||
|
||||
gd::SourceFile& newlyInsertedSourceFile = *(
|
||||
*(externalSourceFiles.emplace(position < externalSourceFiles.size()
|
||||
? externalSourceFiles.begin() + position
|
||||
: externalSourceFiles.end(),
|
||||
new SourceFile())));
|
||||
newlyInsertedSourceFile.SetLanguage(language);
|
||||
newlyInsertedSourceFile.SetFileName(name);
|
||||
|
||||
return newlyInsertedSourceFile;
|
||||
}
|
||||
|
||||
Project::Project(const Project &other)
|
||||
: objectsContainer(gd::ObjectsContainer::SourceType::Global) {
|
||||
Init(other);
|
||||
@@ -1367,10 +1284,6 @@ void Project::Init(const gd::Project& game) {
|
||||
externalLayouts = gd::Clone(game.externalLayouts);
|
||||
eventsFunctionsExtensions = gd::Clone(game.eventsFunctionsExtensions);
|
||||
|
||||
useExternalSourceFiles = game.useExternalSourceFiles;
|
||||
|
||||
externalSourceFiles = gd::Clone(game.externalSourceFiles);
|
||||
|
||||
variables = game.GetVariables();
|
||||
|
||||
projectFile = game.GetProjectFile();
|
||||
|
@@ -32,7 +32,6 @@ class Object;
|
||||
class ObjectConfiguration;
|
||||
class VariablesContainer;
|
||||
class ArbitraryResourceWorker;
|
||||
class SourceFile;
|
||||
class Behavior;
|
||||
class BehaviorsSharedData;
|
||||
class BaseEvent;
|
||||
@@ -1019,56 +1018,6 @@ class GD_CORE_API Project {
|
||||
static gd::String GetSafeName(const gd::String& name);
|
||||
///@}
|
||||
|
||||
/** \name External source files
|
||||
* To manage external C++ or Javascript source files used by the game
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Return true if the game activated the use of external source files.
|
||||
*/
|
||||
bool UseExternalSourceFiles() const { return useExternalSourceFiles; }
|
||||
|
||||
/**
|
||||
* \brief Return a const reference to the vector containing all the source
|
||||
* files used by the game.
|
||||
*/
|
||||
const std::vector<std::unique_ptr<gd::SourceFile> >& GetAllSourceFiles()
|
||||
const {
|
||||
return externalSourceFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return true if the source file with the specified name is used by
|
||||
* the game. \param name The filename of the source file. \param language
|
||||
* Optional. If specified, check that the source file that exists is in this
|
||||
* language.
|
||||
*/
|
||||
bool HasSourceFile(gd::String name, gd::String language = "") const;
|
||||
|
||||
/**
|
||||
* Return a reference to the external source file with the given name.
|
||||
*/
|
||||
SourceFile& GetSourceFile(const gd::String& name);
|
||||
|
||||
/**
|
||||
* Return a reference to the external source file with the given name.
|
||||
*/
|
||||
const SourceFile& GetSourceFile(const gd::String& name) const;
|
||||
|
||||
/**
|
||||
* Remove the specified source file.
|
||||
*/
|
||||
void RemoveSourceFile(const gd::String& name);
|
||||
|
||||
/**
|
||||
* Add a new source file the specified position in the external source files
|
||||
* list.
|
||||
*/
|
||||
gd::SourceFile& InsertNewSourceFile(const gd::String& name,
|
||||
const gd::String& language,
|
||||
std::size_t position = -1);
|
||||
///@}
|
||||
|
||||
gd::WholeProjectDiagnosticReport& GetWholeProjectDiagnosticReport() {
|
||||
return wholeProjectDiagnosticReport;
|
||||
}
|
||||
@@ -1141,10 +1090,6 @@ class GD_CORE_API Project {
|
||||
std::vector<gd::Platform*>
|
||||
platforms; ///< Pointers to the platforms this project supports.
|
||||
gd::String firstLayout;
|
||||
bool useExternalSourceFiles =
|
||||
false; ///< True if game used external source files.
|
||||
std::vector<std::unique_ptr<gd::SourceFile> >
|
||||
externalSourceFiles; ///< List of external source files used.
|
||||
gd::String author; ///< Game author name, for publishing purpose.
|
||||
std::vector<gd::String>
|
||||
authorIds; ///< Game author ids, from GDevelop users DB.
|
||||
|
@@ -97,6 +97,8 @@ std::shared_ptr<Resource> ResourcesManager::CreateResource(
|
||||
return std::make_shared<AtlasResource>();
|
||||
else if (kind == "spine")
|
||||
return std::make_shared<SpineResource>();
|
||||
else if (kind == "javascript")
|
||||
return std::make_shared<JavaScriptResource>();
|
||||
|
||||
std::cout << "Bad resource created (type: " << kind << ")" << std::endl;
|
||||
return std::make_shared<Resource>();
|
||||
@@ -767,6 +769,20 @@ void AtlasResource::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("file", GetFile());
|
||||
}
|
||||
|
||||
void JavaScriptResource::SetFile(const gd::String& newFile) {
|
||||
file = NormalizePathSeparator(newFile);
|
||||
}
|
||||
|
||||
void JavaScriptResource::UnserializeFrom(const SerializerElement& element) {
|
||||
SetUserAdded(element.GetBoolAttribute("userAdded"));
|
||||
SetFile(element.GetStringAttribute("file"));
|
||||
}
|
||||
|
||||
void JavaScriptResource::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("userAdded", IsUserAdded());
|
||||
element.SetAttribute("file", GetFile());
|
||||
}
|
||||
|
||||
ResourceFolder::ResourceFolder(const ResourceFolder& other) { Init(other); }
|
||||
|
||||
ResourceFolder& ResourceFolder::operator=(const ResourceFolder& other) {
|
||||
|
@@ -547,6 +547,32 @@ class GD_CORE_API AtlasResource : public Resource {
|
||||
gd::String file;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Describe a video file used by a project.
|
||||
*
|
||||
* \see Resource
|
||||
* \ingroup ResourcesManagement
|
||||
*/
|
||||
class GD_CORE_API JavaScriptResource : public Resource {
|
||||
public:
|
||||
JavaScriptResource() : Resource() { SetKind("javascript"); };
|
||||
virtual ~JavaScriptResource(){};
|
||||
virtual JavaScriptResource* Clone() const override {
|
||||
return new JavaScriptResource(*this);
|
||||
}
|
||||
|
||||
virtual const gd::String& GetFile() const override { return file; };
|
||||
virtual void SetFile(const gd::String& newFile) override;
|
||||
|
||||
virtual bool UseFile() const override { return true; }
|
||||
void SerializeTo(SerializerElement& element) const override;
|
||||
|
||||
void UnserializeFrom(const SerializerElement& element) override;
|
||||
|
||||
private:
|
||||
gd::String file;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Inventory all resources used by a project
|
||||
*
|
||||
|
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "GDCore/Project/SourceFile.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
SourceFile::SourceFile() : gdManaged(false) {
|
||||
// ctor
|
||||
}
|
||||
|
||||
SourceFile::~SourceFile() {
|
||||
// dtor
|
||||
}
|
||||
|
||||
void SourceFile::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("filename", filename);
|
||||
element.SetAttribute("language", language);
|
||||
element.SetAttribute("gdManaged", gdManaged);
|
||||
}
|
||||
|
||||
void SourceFile::UnserializeFrom(const SerializerElement& element) {
|
||||
filename = element.GetStringAttribute("filename");
|
||||
language = element.GetStringAttribute("language", "C++");
|
||||
gdManaged = element.GetBoolAttribute("gdManaged");
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif
|
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef SOURCEFILE_H
|
||||
#define SOURCEFILE_H
|
||||
#include <ctime>
|
||||
#include <memory>
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
}
|
||||
class BaseEvent;
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Represents a "physical" source file.
|
||||
*
|
||||
* Source file can be compiled (or just integrated to the exported project)
|
||||
* by platforms. Most of the time, special events are provided to use functions
|
||||
* created in such files.
|
||||
*/
|
||||
class GD_CORE_API SourceFile {
|
||||
public:
|
||||
SourceFile();
|
||||
virtual ~SourceFile();
|
||||
|
||||
/**
|
||||
* \brief Return a pointer to a new SourceFile constructed from this one.
|
||||
*/
|
||||
SourceFile* Clone() const { return new SourceFile(*this); };
|
||||
|
||||
/**
|
||||
* \brief Get the filename
|
||||
*/
|
||||
gd::String GetFileName() const { return filename; };
|
||||
|
||||
/**
|
||||
* \brief Change the filename
|
||||
*/
|
||||
void SetFileName(gd::String filename_) { filename = filename_; };
|
||||
|
||||
/**
|
||||
* \brief Serialize the source file.
|
||||
*/
|
||||
void SerializeTo(SerializerElement& element) const;
|
||||
|
||||
/**
|
||||
* \brief Unserialize the source file.
|
||||
*/
|
||||
void UnserializeFrom(const SerializerElement& element);
|
||||
|
||||
/**
|
||||
* \brief Set if the file is hidden from the user point of view and is only
|
||||
* managed by GDevelop
|
||||
*/
|
||||
void SetGDManaged(bool gdManaged_) { gdManaged = gdManaged_; };
|
||||
|
||||
/**
|
||||
* \brief Return true if the file is hidden from the user point of view and is
|
||||
* only managed by GDevelop
|
||||
*/
|
||||
bool IsGDManaged() const { return gdManaged; };
|
||||
|
||||
/**
|
||||
* \brief Change the language of the source file
|
||||
*/
|
||||
void SetLanguage(gd::String lang) { language = lang; }
|
||||
|
||||
/**
|
||||
* \brief Get the language of the source file
|
||||
*/
|
||||
const gd::String& GetLanguage() const { return language; }
|
||||
|
||||
private:
|
||||
gd::String filename; ///< Filename
|
||||
bool gdManaged; ///< True if the source file is hidden from the user point of
|
||||
///< view and is managed only by GDevelop.
|
||||
gd::String language; ///< String identifying the language of this source file
|
||||
///< (typically "C++ or "Javascript").
|
||||
std::weak_ptr<BaseEvent>
|
||||
associatedGdEvent; ///< When a source file is GD-managed, it is usually
|
||||
///< created for a specific event. This member is not
|
||||
///< saved: It is the event responsibility to call
|
||||
///< SetAssociatedEvent.
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // SOURCEFILE_H
|
@@ -32,7 +32,6 @@ TEST_CASE("DependenciesAnalyzer", "[common]") {
|
||||
REQUIRE(analyzer.GetScenesDependencies().find("Layout2") !=
|
||||
analyzer.GetScenesDependencies().end());
|
||||
REQUIRE(analyzer.GetExternalEventsDependencies().size() == 0);
|
||||
REQUIRE(analyzer.GetSourceFilesDependencies().size() == 0);
|
||||
}
|
||||
|
||||
SECTION("Can detect a simple external events dependency") {
|
||||
@@ -55,7 +54,6 @@ TEST_CASE("DependenciesAnalyzer", "[common]") {
|
||||
REQUIRE(analyzer.GetExternalEventsDependencies().size() == 1);
|
||||
REQUIRE(analyzer.GetExternalEventsDependencies().find("ExternalEvents1") !=
|
||||
analyzer.GetExternalEventsDependencies().end());
|
||||
REQUIRE(analyzer.GetSourceFilesDependencies().size() == 0);
|
||||
}
|
||||
|
||||
SECTION("Can detect a transitive scene and external events dependency") {
|
||||
@@ -87,7 +85,6 @@ TEST_CASE("DependenciesAnalyzer", "[common]") {
|
||||
REQUIRE(analyzer.GetExternalEventsDependencies().size() == 1);
|
||||
REQUIRE(analyzer.GetExternalEventsDependencies().find("ExternalEvents1") !=
|
||||
analyzer.GetExternalEventsDependencies().end());
|
||||
REQUIRE(analyzer.GetSourceFilesDependencies().size() == 0);
|
||||
}
|
||||
|
||||
SECTION("Can detect a (nested) circular dependency with scenes") {
|
||||
|
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
/**
|
||||
* @file Tests covering common features of GDevelop Core.
|
||||
*/
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/SourceFile.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
TEST_CASE("SourceFile", "[common]") {
|
||||
SECTION("Basics") {
|
||||
gd::Project project;
|
||||
project.InsertNewSourceFile("test.cpp", "C++");
|
||||
project.InsertNewSourceFile("test.js", "Javascript");
|
||||
REQUIRE(project.HasSourceFile("test.cpp", "C++") == true);
|
||||
REQUIRE(project.HasSourceFile("test.cpp", "JS") == false);
|
||||
REQUIRE(project.HasSourceFile("test.cpp") == true);
|
||||
gd::SourceFile& cppSourceFile = project.GetSourceFile("test.cpp");
|
||||
REQUIRE(cppSourceFile.GetFileName() == "test.cpp");
|
||||
REQUIRE(cppSourceFile.GetLanguage() == "C++");
|
||||
|
||||
project.RemoveSourceFile("test.cpp");
|
||||
REQUIRE(project.HasSourceFile("test.cpp") == false);
|
||||
REQUIRE(project.HasSourceFile("test.js") == true);
|
||||
}
|
||||
}
|
39
Extensions/DialogueTree/bondage.js/dist/bondage.d.ts
vendored
Normal file
39
Extensions/DialogueTree/bondage.js/dist/bondage.d.ts
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
declare namespace bondage {
|
||||
export class Runner {
|
||||
yarnNodes: any;
|
||||
variables: any;
|
||||
functions: any;
|
||||
visited: any;
|
||||
load(data: any[]): void;
|
||||
setVariableStorage(storage: any): void;
|
||||
registerFunction(name: string, func): void;
|
||||
run(startNode: string): any;
|
||||
evalNodes(nodes: any[], yarnNodeData: any): any;
|
||||
handleSelections(selections: any[]): any;
|
||||
evaluateAssignment(node: any): any;
|
||||
evaluateConditional(node: any): any;
|
||||
evaluateExpressionOrLiteral(node): any;
|
||||
}
|
||||
|
||||
export class Result {}
|
||||
|
||||
export class TextResult extends Result {
|
||||
text: string;
|
||||
data: any;
|
||||
lineNum: number;
|
||||
}
|
||||
|
||||
export class CommandResult extends Result {
|
||||
text: string;
|
||||
data: any;
|
||||
lineNum: number;
|
||||
}
|
||||
|
||||
export class OptionsResult extends Result {
|
||||
options: string[];
|
||||
lineNum: number[];
|
||||
selected: number;
|
||||
|
||||
select(index: number): void;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -340,7 +340,8 @@ module.exports = {
|
||||
_(
|
||||
'The friction applied when touching other objects. The higher the value, the more friction.'
|
||||
)
|
||||
);
|
||||
)
|
||||
.setGroup(_('Movement'));
|
||||
behaviorProperties
|
||||
.getOrCreate('restitution')
|
||||
.setValue(
|
||||
@@ -352,7 +353,8 @@ module.exports = {
|
||||
_(
|
||||
'The "bounciness" of the object. The higher the value, the more other objects will bounce against it.'
|
||||
)
|
||||
);
|
||||
)
|
||||
.setGroup(_('Movement'));
|
||||
behaviorProperties
|
||||
.getOrCreate('linearDamping')
|
||||
.setValue(
|
||||
|
@@ -964,7 +964,7 @@ namespace gdjs {
|
||||
// It would be useless to try to recreate it as updateBodyFromObject already does it.
|
||||
// If the body is null, we just don't do anything
|
||||
// (but still run the physics simulation - this is independent).
|
||||
if (this._body !== null) {
|
||||
if (this._body !== null && !this.isStatic() && this._body.IsAwake()) {
|
||||
this.owner.setX(
|
||||
this._body.GetPosition().get_x() * this._sharedData.worldScale -
|
||||
this.owner.getWidth() / 2 +
|
||||
|
@@ -300,7 +300,8 @@ module.exports = {
|
||||
_(
|
||||
'The friction applied when touching other objects. The higher the value, the more friction.'
|
||||
)
|
||||
);
|
||||
)
|
||||
.setGroup(_('Movement'));
|
||||
behaviorProperties
|
||||
.getOrCreate('restitution')
|
||||
.setValue(
|
||||
@@ -315,7 +316,8 @@ module.exports = {
|
||||
_(
|
||||
'The "bounciness" of the object. The higher the value, the more other objects will bounce against it.'
|
||||
)
|
||||
);
|
||||
)
|
||||
.setGroup(_('Movement'));
|
||||
behaviorProperties
|
||||
.getOrCreate('linearDamping')
|
||||
.setValue(
|
||||
@@ -1533,6 +1535,15 @@ module.exports = {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'stairHeightMax') {
|
||||
const newValueAsNumber = parseFloat(newValue);
|
||||
if (newValueAsNumber !== newValueAsNumber) return false;
|
||||
behaviorContent
|
||||
.getChild('stairHeightMax')
|
||||
.setDoubleValue(newValueAsNumber);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'shouldBindObjectAndForwardAngle') {
|
||||
behaviorContent
|
||||
.getChild('shouldBindObjectAndForwardAngle')
|
||||
@@ -1701,6 +1712,24 @@ module.exports = {
|
||||
.setAdvanced(true)
|
||||
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden);
|
||||
|
||||
if (!behaviorContent.hasChild('stairHeightMax')) {
|
||||
behaviorContent.addChild('stairHeightMax').setDoubleValue(20);
|
||||
}
|
||||
behaviorProperties
|
||||
.getOrCreate('stairHeightMax')
|
||||
.setLabel('Max. stair height')
|
||||
.setGroup(_('Walk'))
|
||||
.setType('Number')
|
||||
.setMeasurementUnit(gd.MeasurementUnit.getPixel())
|
||||
.setValue(
|
||||
behaviorContent
|
||||
.getChild('stairHeightMax')
|
||||
.getDoubleValue()
|
||||
.toString(10)
|
||||
)
|
||||
.setAdvanced(true)
|
||||
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden);
|
||||
|
||||
behaviorProperties
|
||||
.getOrCreate('shouldBindObjectAndForwardAngle')
|
||||
.setLabel('Keep object angle and forward direction the same')
|
||||
@@ -1732,6 +1761,7 @@ module.exports = {
|
||||
behaviorContent.addChild('sidewaysDeceleration').setDoubleValue(800);
|
||||
behaviorContent.addChild('sidewaysSpeedMax').setDoubleValue(400);
|
||||
behaviorContent.addChild('slopeMaxAngle').setDoubleValue(50);
|
||||
behaviorContent.addChild('stairHeightMax').setDoubleValue(20);
|
||||
behaviorContent
|
||||
.addChild('shouldBindObjectAndForwardAngle')
|
||||
.setBoolValue(true);
|
||||
|
@@ -296,6 +296,7 @@ namespace gdjs {
|
||||
|
||||
export class Physics3DRuntimeBehavior extends gdjs.RuntimeBehavior {
|
||||
bodyUpdater: gdjs.Physics3DRuntimeBehavior.BodyUpdater;
|
||||
collisionChecker: gdjs.Physics3DRuntimeBehavior.CollisionChecker;
|
||||
owner3D: gdjs.RuntimeObject3D;
|
||||
|
||||
bodyType: string;
|
||||
@@ -338,7 +339,7 @@ namespace gdjs {
|
||||
* each time the methods onContactBegin and onContactEnd are called by the contact
|
||||
* listener.
|
||||
*/
|
||||
private _currentContacts: Array<Physics3DRuntimeBehavior> = [];
|
||||
_currentContacts: Array<Physics3DRuntimeBehavior> = [];
|
||||
|
||||
private _destroyedDuringFrameLogic: boolean;
|
||||
_body: Jolt.Body | null = null;
|
||||
@@ -381,6 +382,9 @@ namespace gdjs {
|
||||
this.bodyUpdater = new gdjs.Physics3DRuntimeBehavior.DefaultBodyUpdater(
|
||||
this
|
||||
);
|
||||
this.collisionChecker = new gdjs.Physics3DRuntimeBehavior.DefaultCollisionChecker(
|
||||
this
|
||||
);
|
||||
this.owner3D = owner;
|
||||
this.bodyType = behaviorData.bodyType;
|
||||
this.bullet = behaviorData.bullet;
|
||||
@@ -540,7 +544,7 @@ namespace gdjs {
|
||||
if (this._body) {
|
||||
this._sharedData.bodyInterface.SetPosition(
|
||||
this._body.GetID(),
|
||||
this.getVec3(
|
||||
this.getRVec3(
|
||||
behaviorSpecificProps.px,
|
||||
behaviorSpecificProps.py,
|
||||
behaviorSpecificProps.pz
|
||||
@@ -804,13 +808,11 @@ namespace gdjs {
|
||||
getBodyLayer(): number {
|
||||
return Jolt.ObjectLayerPairFilterMask.prototype.sGetObjectLayer(
|
||||
// Make sure objects don't register in the wrong layer group.
|
||||
this.bodyType === 'Static'
|
||||
this.isStatic()
|
||||
? this.layers & gdjs.Physics3DSharedData.staticLayersMask
|
||||
: this.layers & gdjs.Physics3DSharedData.dynamicLayersMask,
|
||||
// Static objects accept all collisions as it's the mask of dynamic objects that matters.
|
||||
this.bodyType === 'Static'
|
||||
? gdjs.Physics3DSharedData.allLayersMask
|
||||
: this.masks
|
||||
this.isStatic() ? gdjs.Physics3DSharedData.allLayersMask : this.masks
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1696,27 +1698,7 @@ namespace gdjs {
|
||||
behaviorName
|
||||
) as Physics3DRuntimeBehavior | null;
|
||||
if (!behavior1) return false;
|
||||
|
||||
if (
|
||||
behavior1._currentContacts.some(
|
||||
(behavior) => behavior.owner === object2
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
// If a contact has started at this frame and ended right away, it
|
||||
// won't appear in current contacts but the condition should return
|
||||
// true anyway.
|
||||
if (
|
||||
behavior1._contactsStartedThisFrame.some(
|
||||
(behavior) => behavior.owner === object2
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// No contact found
|
||||
return false;
|
||||
return behavior1.collisionChecker.isColliding(object2);
|
||||
}
|
||||
|
||||
static hasCollisionStartedBetween(
|
||||
@@ -1728,10 +1710,7 @@ namespace gdjs {
|
||||
behaviorName
|
||||
) as Physics3DRuntimeBehavior | null;
|
||||
if (!behavior1) return false;
|
||||
|
||||
return behavior1._contactsStartedThisFrame.some(
|
||||
(behavior) => behavior.owner === object2
|
||||
);
|
||||
return behavior1.collisionChecker.hasCollisionStartedWith(object2);
|
||||
}
|
||||
|
||||
static hasCollisionStoppedBetween(
|
||||
@@ -1743,10 +1722,7 @@ namespace gdjs {
|
||||
behaviorName
|
||||
) as Physics3DRuntimeBehavior | null;
|
||||
if (!behavior1) return false;
|
||||
|
||||
return behavior1._contactsEndedThisFrame.some(
|
||||
(behavior) => behavior.owner === object2
|
||||
);
|
||||
return behavior1.collisionChecker.hasCollisionStoppedWith(object2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1827,7 +1803,7 @@ namespace gdjs {
|
||||
// It would be useless to try to recreate it as updateBodyFromObject already does it.
|
||||
// If the body is null, we just don't do anything
|
||||
// (but still run the physics simulation - this is independent).
|
||||
if (_body !== null) {
|
||||
if (_body !== null && _body.IsActive()) {
|
||||
behavior.moveObjectToPhysicsPosition(_body.GetPosition());
|
||||
behavior.moveObjectToPhysicsRotation(_body.GetRotation());
|
||||
}
|
||||
@@ -1841,8 +1817,6 @@ namespace gdjs {
|
||||
}
|
||||
const body = behavior._body!;
|
||||
|
||||
// TODO the `if` is probably unnecessary because `SetPositionAndRotationWhenChanged` already check this.
|
||||
// The object object transform has changed, update body transform:
|
||||
if (
|
||||
this.behavior._objectOldX !== owner3D.getX() ||
|
||||
this.behavior._objectOldY !== owner3D.getY() ||
|
||||
@@ -1877,5 +1851,49 @@ namespace gdjs {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export interface CollisionChecker {
|
||||
isColliding(object: gdjs.RuntimeObject): boolean;
|
||||
hasCollisionStartedWith(object: gdjs.RuntimeObject): boolean;
|
||||
hasCollisionStoppedWith(object: gdjs.RuntimeObject): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* The default collision checker uses the contacts found while
|
||||
* stepping the physics simulation. For characters, another one is used
|
||||
* as characters are simulated before the rest of the physics simulation.
|
||||
*/
|
||||
export class DefaultCollisionChecker implements CollisionChecker {
|
||||
behavior: gdjs.Physics3DRuntimeBehavior;
|
||||
|
||||
constructor(behavior: gdjs.Physics3DRuntimeBehavior) {
|
||||
this.behavior = behavior;
|
||||
}
|
||||
|
||||
isColliding(object: gdjs.RuntimeObject): boolean {
|
||||
if (
|
||||
this.behavior._currentContacts.some(
|
||||
(behavior) => behavior.owner === object
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return this.behavior._contactsStartedThisFrame.some(
|
||||
(behavior) => behavior.owner === object
|
||||
);
|
||||
}
|
||||
|
||||
hasCollisionStartedWith(object: gdjs.RuntimeObject): boolean {
|
||||
return this.behavior._contactsStartedThisFrame.some(
|
||||
(behavior) => behavior.owner === object
|
||||
);
|
||||
}
|
||||
|
||||
hasCollisionStoppedWith(object: gdjs.RuntimeObject): boolean {
|
||||
return this.behavior._contactsEndedThisFrame.some(
|
||||
(behavior) => behavior.owner === object
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -53,6 +53,7 @@ namespace gdjs {
|
||||
* before stepping the world.
|
||||
*/
|
||||
_sharedData: gdjs.Physics3DSharedData;
|
||||
collisionChecker: gdjs.PhysicsCharacter3DRuntimeBehavior.CharacterCollisionChecker;
|
||||
|
||||
// TODO Should there be angle were the character can climb but will slip?
|
||||
_slopeMaxAngle: float;
|
||||
@@ -70,6 +71,7 @@ namespace gdjs {
|
||||
private _maxFallingSpeed: float;
|
||||
private _jumpSpeed: float;
|
||||
private _jumpSustainTime: float;
|
||||
private _stairHeightMax: float;
|
||||
|
||||
private _hasPressedForwardKey: boolean = false;
|
||||
private _hasPressedBackwardKey: boolean = false;
|
||||
@@ -121,6 +123,9 @@ namespace gdjs {
|
||||
instanceContainer.getScene(),
|
||||
behaviorData.Physics3D
|
||||
);
|
||||
this.collisionChecker = new gdjs.PhysicsCharacter3DRuntimeBehavior.CharacterCollisionChecker(
|
||||
this
|
||||
);
|
||||
|
||||
this._slopeMaxAngle = 0;
|
||||
this.setSlopeMaxAngle(behaviorData.slopeMaxAngle);
|
||||
@@ -136,6 +141,10 @@ namespace gdjs {
|
||||
this._jumpSpeed = this.getJumpSpeedToReach(behaviorData.jumpHeight);
|
||||
this._shouldBindObjectAndForwardAngle =
|
||||
behaviorData.shouldBindObjectAndForwardAngle;
|
||||
this._stairHeightMax =
|
||||
behaviorData.stairHeightMax === undefined
|
||||
? 20
|
||||
: behaviorData.stairHeightMax;
|
||||
}
|
||||
|
||||
private getVec3(x: float, y: float, z: float): Jolt.Vec3 {
|
||||
@@ -155,7 +164,6 @@ namespace gdjs {
|
||||
const sharedData = behavior._sharedData;
|
||||
const jolt = sharedData.jolt;
|
||||
const extendedUpdateSettings = new Jolt.ExtendedUpdateSettings();
|
||||
extendedUpdateSettings.mWalkStairsStepUp = this.getVec3(0, 0, 0.4);
|
||||
const broadPhaseLayerFilter = new Jolt.DefaultBroadPhaseLayerFilter(
|
||||
jolt.GetObjectVsBroadPhaseLayerFilter(),
|
||||
gdjs.Physics3DSharedData.dynamicBroadPhaseLayerIndex
|
||||
@@ -175,11 +183,13 @@ namespace gdjs {
|
||||
bodyFilter,
|
||||
shapeFilter,
|
||||
};
|
||||
this.setStairHeightMax(this._stairHeightMax);
|
||||
sharedData.registerHook(this);
|
||||
|
||||
behavior.bodyUpdater = new gdjs.PhysicsCharacter3DRuntimeBehavior.CharacterBodyUpdater(
|
||||
this
|
||||
);
|
||||
behavior.collisionChecker = this.collisionChecker;
|
||||
behavior.recreateBody();
|
||||
|
||||
// Always begin in the direction of the object.
|
||||
@@ -241,6 +251,9 @@ namespace gdjs {
|
||||
newBehaviorData.shouldBindObjectAndForwardAngle
|
||||
);
|
||||
}
|
||||
if (oldBehaviorData.stairHeightMax !== newBehaviorData.stairHeightMax) {
|
||||
this.setStairHeightMax(newBehaviorData.stairHeightMax);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -328,7 +341,9 @@ namespace gdjs {
|
||||
);
|
||||
}
|
||||
|
||||
onDeActivate() {}
|
||||
onDeActivate() {
|
||||
this.collisionChecker.clearContacts();
|
||||
}
|
||||
|
||||
onActivate() {}
|
||||
|
||||
@@ -498,6 +513,7 @@ namespace gdjs {
|
||||
shapeFilter,
|
||||
this._sharedData.jolt.GetTempAllocator()
|
||||
);
|
||||
this.collisionChecker.updateContacts();
|
||||
|
||||
if (this.isOnFloor()) {
|
||||
this._canJump = true;
|
||||
@@ -775,6 +791,27 @@ namespace gdjs {
|
||||
);
|
||||
}
|
||||
|
||||
getStairHeightMax(): float {
|
||||
return this._stairHeightMax;
|
||||
}
|
||||
|
||||
setStairHeightMax(stairHeightMax: float): void {
|
||||
const { extendedUpdateSettings } = this.getPhysics3D();
|
||||
this._stairHeightMax = stairHeightMax;
|
||||
const walkStairsStepUp = stairHeightMax * this._sharedData.worldInvScale;
|
||||
extendedUpdateSettings.mWalkStairsStepUp = this.getVec3(
|
||||
0,
|
||||
0,
|
||||
walkStairsStepUp
|
||||
);
|
||||
// Use default values proportionally;
|
||||
// "The factors are arbitrary but works well when tested in a game."
|
||||
extendedUpdateSettings.mWalkStairsMinStepForward =
|
||||
(0.02 / 0.4) * walkStairsStepUp;
|
||||
extendedUpdateSettings.mWalkStairsStepForwardTest =
|
||||
(0.15 / 0.4) * walkStairsStepUp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the gravity of the Character.
|
||||
* @returns The current gravity.
|
||||
@@ -1187,7 +1224,7 @@ namespace gdjs {
|
||||
* @returns Returns true if it is falling and false if not.
|
||||
*/
|
||||
isFallingWithoutJumping(): boolean {
|
||||
return !this.isOnFloor() && this._currentJumpSpeed === 0;
|
||||
return !this.isOnFloor() && !this.isJumping();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1204,7 +1241,8 @@ namespace gdjs {
|
||||
*/
|
||||
isFalling(): boolean {
|
||||
return (
|
||||
!this.isOnFloor() && this._currentJumpSpeed < this._currentFallSpeed
|
||||
!this.isOnFloor() ||
|
||||
(this.isJumping() && this._currentFallSpeed > this._currentJumpSpeed)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1426,5 +1464,87 @@ namespace gdjs {
|
||||
this.updateCharacterPosition();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A character is simulated by Jolt before the rest of the physics simulation
|
||||
* (see `doBeforePhysicsStep`).
|
||||
* This means that contacts with the character would only rarely be recognized by
|
||||
* the physics engine if using the default contact listeners.
|
||||
* Instead, this class allows to properly track contacts of the character
|
||||
* using Jolt `CharacterVirtual::GetActiveContacts`.
|
||||
*/
|
||||
export class CharacterCollisionChecker
|
||||
implements gdjs.Physics3DRuntimeBehavior.CollisionChecker {
|
||||
characterBehavior: gdjs.PhysicsCharacter3DRuntimeBehavior;
|
||||
|
||||
_currentContacts: Array<Physics3DRuntimeBehavior> = [];
|
||||
_previousContacts: Array<Physics3DRuntimeBehavior> = [];
|
||||
|
||||
constructor(characterBehavior: gdjs.PhysicsCharacter3DRuntimeBehavior) {
|
||||
this.characterBehavior = characterBehavior;
|
||||
}
|
||||
|
||||
clearContacts(): void {
|
||||
this._previousContacts.length = 0;
|
||||
this._currentContacts.length = 0;
|
||||
}
|
||||
|
||||
updateContacts(): void {
|
||||
const swap = this._previousContacts;
|
||||
this._previousContacts = this._currentContacts;
|
||||
this._currentContacts = swap;
|
||||
this._currentContacts.length = 0;
|
||||
|
||||
const { character, _sharedData } = this.characterBehavior;
|
||||
if (!character) {
|
||||
return;
|
||||
}
|
||||
const contacts = character.GetActiveContacts();
|
||||
for (let index = 0; index < contacts.size(); index++) {
|
||||
const contact = contacts.at(index);
|
||||
|
||||
const bodyLockInterface = _sharedData.physicsSystem.GetBodyLockInterface();
|
||||
const body = bodyLockInterface.TryGetBody(contact.mBodyB);
|
||||
const behavior = body.gdjsAssociatedBehavior;
|
||||
if (behavior) {
|
||||
this._currentContacts.push(behavior);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
isColliding(object: gdjs.RuntimeObject): boolean {
|
||||
const { character } = this.characterBehavior;
|
||||
if (!character) {
|
||||
return false;
|
||||
}
|
||||
return this._currentContacts.some(
|
||||
(behavior) => behavior.owner === object
|
||||
);
|
||||
}
|
||||
|
||||
hasCollisionStartedWith(object: gdjs.RuntimeObject): boolean {
|
||||
const { character } = this.characterBehavior;
|
||||
if (!character) {
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
this._currentContacts.some((behavior) => behavior.owner === object) &&
|
||||
!this._previousContacts.some((behavior) => behavior.owner === object)
|
||||
);
|
||||
}
|
||||
|
||||
hasCollisionStoppedWith(object: gdjs.RuntimeObject): boolean {
|
||||
const { character } = this.characterBehavior;
|
||||
if (!character) {
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
!this._currentContacts.some(
|
||||
(behavior) => behavior.owner === object
|
||||
) &&
|
||||
this._previousContacts.some((behavior) => behavior.owner === object)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
288
Extensions/Physics3DBehavior/jolt-physics.d.ts
vendored
288
Extensions/Physics3DBehavior/jolt-physics.d.ts
vendored
@@ -55,6 +55,26 @@ declare namespace Jolt {
|
||||
clear(): void;
|
||||
data(): Mat44MemRef;
|
||||
}
|
||||
class ArrayBodyID {
|
||||
empty(): boolean;
|
||||
size(): number;
|
||||
at(inIndex: number): BodyID;
|
||||
push_back(inValue: BodyID): void;
|
||||
reserve(inSize: number): void;
|
||||
resize(inSize: number): void;
|
||||
clear(): void;
|
||||
data(): BodyIDMemRef;
|
||||
}
|
||||
class ArrayBodyPtr {
|
||||
empty(): boolean;
|
||||
size(): number;
|
||||
at(inIndex: number): Body;
|
||||
push_back(inValue: Body): void;
|
||||
reserve(inSize: number): void;
|
||||
resize(inSize: number): void;
|
||||
clear(): void;
|
||||
data(): BodyPtrMemRef;
|
||||
}
|
||||
const EBodyType_RigidBody: number;
|
||||
const EBodyType_SoftBody: number;
|
||||
type EBodyType = typeof EBodyType_RigidBody | typeof EBodyType_SoftBody;
|
||||
@@ -414,6 +434,8 @@ declare namespace Jolt {
|
||||
class Vec3MemRef {}
|
||||
class QuatMemRef {}
|
||||
class Mat44MemRef {}
|
||||
class BodyIDMemRef {}
|
||||
class BodyPtrMemRef {}
|
||||
class FloatMemRef {}
|
||||
class Uint8MemRef {}
|
||||
class UintMemRef {}
|
||||
@@ -429,6 +451,10 @@ declare namespace Jolt {
|
||||
sMin(inLHS: Vec3, inRHS: Vec3): Vec3;
|
||||
sMax(inLHS: Vec3, inRHS: Vec3): Vec3;
|
||||
sClamp(inValue: Vec3, inMin: Vec3, inMax: Vec3): Vec3;
|
||||
sFusedMultiplyAdd(inMul1: Vec3, inMul2: Vec3, inAdd: Vec3): Vec3;
|
||||
sOr(inV1: Vec3, inV2: Vec3): Vec3;
|
||||
sXor(inV1: Vec3, inV2: Vec3): Vec3;
|
||||
sAnd(inV1: Vec3, inV2: Vec3): Vec3;
|
||||
sUnitSpherical(inTheta: number, inPhi: number): Vec3;
|
||||
GetComponent(inCoordinate: number): number;
|
||||
Equals(inV: Vec3): boolean;
|
||||
@@ -455,10 +481,21 @@ declare namespace Jolt {
|
||||
Reciprocal(): Vec3;
|
||||
Cross(inRHS: Vec3): Vec3;
|
||||
Dot(inRHS: Vec3): number;
|
||||
DotV(inRHS: Vec3): Vec3;
|
||||
DotV4(inRHS: Vec3): Vec4;
|
||||
Add(inV: Vec3): Vec3;
|
||||
Sub(inV: Vec3): Vec3;
|
||||
Mul(inV: number): Vec3;
|
||||
Div(inV: number): Vec3;
|
||||
MulVec3(inV: Vec3): Vec3;
|
||||
MulFloat(inV: number): Vec3;
|
||||
DivVec3(inV: Vec3): Vec3;
|
||||
DivFloat(inV: number): Vec3;
|
||||
AddVec3(inV: Vec3): Vec3;
|
||||
SubVec3(inV: Vec3): Vec3;
|
||||
SplatX(): Vec4;
|
||||
SplatY(): Vec4;
|
||||
SplatZ(): Vec4;
|
||||
ReduceMin(): number;
|
||||
ReduceMax(): number;
|
||||
Sqrt(): Vec3;
|
||||
@@ -500,6 +537,12 @@ declare namespace Jolt {
|
||||
Sub(inV: Vec3): RVec3;
|
||||
Mul(inV: number): RVec3;
|
||||
Div(inV: number): RVec3;
|
||||
MulRVec3(inV: RVec3): RVec3;
|
||||
MulFloat(inV: number): RVec3;
|
||||
DivRVec3(inV: RVec3): RVec3;
|
||||
DivFloat(inV: number): RVec3;
|
||||
AddRVec3(inV: RVec3): RVec3;
|
||||
SubRVec3(inV: RVec3): RVec3;
|
||||
Sqrt(): RVec3;
|
||||
GetSign(): RVec3;
|
||||
}
|
||||
@@ -508,6 +551,14 @@ declare namespace Jolt {
|
||||
constructor(inV: Vec4);
|
||||
constructor(inV: Vec3, inW: number);
|
||||
constructor(inX: number, inY: number, inZ: number, inW: number);
|
||||
sZero(): Vec4;
|
||||
sReplicate(inV: number): Vec4;
|
||||
sMin(inLHS: Vec4, inRHS: Vec4): Vec4;
|
||||
sMax(inLHS: Vec4, inRHS: Vec4): Vec4;
|
||||
sFusedMultiplyAdd(inMul1: Vec4, inMul2: Vec4, inAdd: Vec4): Vec4;
|
||||
sOr(inV1: Vec4, inV2: Vec4): Vec4;
|
||||
sXor(inV1: Vec4, inV2: Vec4): Vec4;
|
||||
sAnd(inV1: Vec4, inV2: Vec4): Vec4;
|
||||
GetX(): number;
|
||||
GetY(): number;
|
||||
GetZ(): number;
|
||||
@@ -518,6 +569,18 @@ declare namespace Jolt {
|
||||
SetW(inW: number): void;
|
||||
Set(inX: number, inY: number, inZ: number, inW: number): void;
|
||||
GetComponent(inCoordinate: number): number;
|
||||
IsClose(inV: Vec4, inMaxDistSq?: number): boolean;
|
||||
IsNormalized(inTolerance?: number): boolean;
|
||||
Add(inV: Vec4): Vec4;
|
||||
Sub(inV: Vec4): Vec4;
|
||||
Mul(inV: number): Vec4;
|
||||
Div(inV: number): Vec4;
|
||||
MulVec4(inV: Vec4): Vec4;
|
||||
MulFloat(inV: number): Vec4;
|
||||
DivVec4(inV: Vec4): Vec4;
|
||||
DivFloat(inV: number): Vec4;
|
||||
AddVec4(inV: Vec4): Vec4;
|
||||
SubVec4(inV: Vec4): Vec4;
|
||||
}
|
||||
class Vector2 {
|
||||
constructor();
|
||||
@@ -531,6 +594,10 @@ declare namespace Jolt {
|
||||
Sub(inV: Vector2): Vector2;
|
||||
Mul(inV: number): Vector2;
|
||||
Div(inV: number): Vector2;
|
||||
MulFloat(inV: number): Vector2;
|
||||
DivFloat(inV: number): Vector2;
|
||||
AddVector2(inV: Vector2): Vector2;
|
||||
SubVector2(inV: Vector2): Vector2;
|
||||
Dot(inRHS: Vector2): number;
|
||||
}
|
||||
class Quat {
|
||||
@@ -599,10 +666,17 @@ declare namespace Jolt {
|
||||
sRotationY(inY: number): Mat44;
|
||||
sRotationZ(inZ: number): Mat44;
|
||||
sRotation(inQ: Quat): Mat44;
|
||||
sRotationAxisAngle(inAxis: Vec3, inAngle: number): Mat44;
|
||||
sTranslation(inTranslation: Vec3): Mat44;
|
||||
sRotationTranslation(inRotation: Quat, inTranslation: Vec3): Mat44;
|
||||
sInverseRotationTranslation(inRotation: Quat, inTranslation: Vec3): Mat44;
|
||||
sScale(inScale: number): Mat44;
|
||||
sScaleVec3(inScale: Vec3): Mat44;
|
||||
sOuterProduct(inV1: Vec3, inV2: Vec3): Mat44;
|
||||
sCrossProduct(inV: Vec3): Mat44;
|
||||
sQuatLeftMultiply(inQ: Quat): Mat44;
|
||||
sQuatRightMultiply(inQ: Quat): Mat44;
|
||||
sLookAt(inPos: Vec3, inTarget: Vec3, inUp: Vec3): Mat44;
|
||||
sPerspective(
|
||||
inFovY: number,
|
||||
inAspect: number,
|
||||
@@ -612,16 +686,32 @@ declare namespace Jolt {
|
||||
GetAxisX(): Vec3;
|
||||
GetAxisY(): Vec3;
|
||||
GetAxisZ(): Vec3;
|
||||
GetDiagonal3(): Vec3;
|
||||
GetDiagonal4(): Vec4;
|
||||
GetRotation(): Mat44;
|
||||
GetRotationSafe(): Mat44;
|
||||
GetQuaternion(): Quat;
|
||||
GetTranslation(): Vec3;
|
||||
Equals(inV: Mat44): boolean;
|
||||
NotEquals(inV: Mat44): boolean;
|
||||
IsClose(inM: Mat44, inMaxDistSq?: number): boolean;
|
||||
Add(inM: Mat44): Mat44;
|
||||
MulFloat(inV: number): Mat44;
|
||||
MulMat44(inM: Mat44): Mat44;
|
||||
MulVec3(inV: Vec3): Vec3;
|
||||
MulVec4(inV: Vec4): Vec4;
|
||||
AddMat44(inM: Mat44): Mat44;
|
||||
SubMat44(inM: Mat44): Mat44;
|
||||
Multiply3x3(inV: Vec3): Vec3;
|
||||
Multiply3x3Transposed(inV: Vec3): Vec3;
|
||||
Multiply3x3LeftTransposed(inM: Mat44): Mat44;
|
||||
Multiply3x3RightTransposed(inM: Mat44): Mat44;
|
||||
Transposed(): Mat44;
|
||||
Transposed3x3(): Mat44;
|
||||
Inversed(): Mat44;
|
||||
InversedRotationTranslation(): Mat44;
|
||||
Adjointed3x3(): Mat44;
|
||||
SetInversed3x3(inM: Mat44): boolean;
|
||||
GetDeterminant3x3(): number;
|
||||
Inversed3x3(): Mat44;
|
||||
GetDirectionPreservingMatrix(): Mat44;
|
||||
@@ -629,12 +719,16 @@ declare namespace Jolt {
|
||||
PostTranslated(inTranslation: Vec3): Mat44;
|
||||
PreScaled(inScale: Vec3): Mat44;
|
||||
PostScaled(inScale: Vec3): Mat44;
|
||||
Decompose(outScale: Vec3): Mat44;
|
||||
SetColumn3(inCol: number, inV: Vec3): void;
|
||||
SetColumn4(inCol: number, inV: Vec4): void;
|
||||
SetAxisX(inV: Vec3): void;
|
||||
SetAxisY(inV: Vec3): void;
|
||||
SetAxisZ(inV: Vec3): void;
|
||||
SetDiagonal3(inV: Vec3): void;
|
||||
SetDiagonal4(inV: Vec4): void;
|
||||
SetTranslation(inV: Vec3): void;
|
||||
SetColumn4(inCol: number, inV: Vec4): void;
|
||||
GetColumn3(inCol: number): Vec3;
|
||||
GetColumn4(inCol: number): Vec4;
|
||||
}
|
||||
class RMat44 {
|
||||
@@ -645,10 +739,18 @@ declare namespace Jolt {
|
||||
sTranslation(inTranslation: RVec3): RMat44;
|
||||
sRotationTranslation(inRotation: Quat, inTranslation: RVec3): RMat44;
|
||||
sInverseRotationTranslation(inRotation: Quat, inTranslation: RVec3): RMat44;
|
||||
ToMat44(): Mat44;
|
||||
Equals(inV: RMat44): boolean;
|
||||
NotEquals(inV: RMat44): boolean;
|
||||
MulVec3(inV: Vec3): RVec3;
|
||||
MulRVec3(inV: RVec3): RVec3;
|
||||
MulMat44(inM: Mat44): RMat44;
|
||||
MulRMat44(inM: RMat44): RMat44;
|
||||
GetAxisX(): Vec3;
|
||||
GetAxisY(): Vec3;
|
||||
GetAxisZ(): Vec3;
|
||||
GetRotation(): Mat44;
|
||||
SetRotation(inRotation: Mat44): void;
|
||||
GetQuaternion(): Quat;
|
||||
GetTranslation(): RVec3;
|
||||
IsClose(inM: RMat44, inMaxDistSq?: number): boolean;
|
||||
@@ -661,25 +763,59 @@ declare namespace Jolt {
|
||||
PostTranslated(inTranslation: Vec3): RMat44;
|
||||
PreScaled(inScale: Vec3): RMat44;
|
||||
PostScaled(inScale: Vec3): RMat44;
|
||||
GetDirectionPreservingMatrix(): Mat44;
|
||||
SetColumn3(inCol: number, inV: Vec3): void;
|
||||
GetColumn3(inCol: number): Vec3;
|
||||
SetAxisX(inV: Vec3): void;
|
||||
SetAxisY(inV: Vec3): void;
|
||||
SetAxisZ(inV: Vec3): void;
|
||||
SetTranslation(inV: RVec3): void;
|
||||
SetColumn4(inCol: number, inV: Vec4): void;
|
||||
GetColumn4(inCol: number): Vec4;
|
||||
Decompose(outScale: Vec3): RMat44;
|
||||
}
|
||||
class AABox {
|
||||
constructor();
|
||||
constructor(inMin: Vec3, inMax: Vec3);
|
||||
sBiggest(): AABox;
|
||||
sFromTwoPoints(inP1: Vec3, inP2: Vec3): AABox;
|
||||
sFromTriangle(inVertices: VertexList, inTriangle: IndexedTriangle): AABox;
|
||||
Equals(inB: AABox): boolean;
|
||||
NotEquals(inB: AABox): boolean;
|
||||
SetEmpty(): void;
|
||||
IsValid(): boolean;
|
||||
EncapsulateVec3(inV: Vec3): void;
|
||||
EncapsulateAABox(inBox: AABox): void;
|
||||
EncapsulateTriangle(inTriangle: Triangle): void;
|
||||
EncapsulateIndexedTriangle(
|
||||
inVertices: VertexList,
|
||||
inTriangle: IndexedTriangle
|
||||
): void;
|
||||
Intersect(inOther: AABox): AABox;
|
||||
EnsureMinimalEdgeLength(inMinEdgeLength: number): void;
|
||||
ExpandBy(inV: Vec3): void;
|
||||
GetCenter(): Vec3;
|
||||
GetExtent(): Vec3;
|
||||
GetSize(): Vec3;
|
||||
GetSurfaceArea(): number;
|
||||
GetVolume(): number;
|
||||
ContainsVec3(inOther: Vec3): boolean;
|
||||
ContainsRVec3(inOther: RVec3): boolean;
|
||||
OverlapsAABox(inOther: AABox): boolean;
|
||||
OverlapsPlane(inOther: AABox): boolean;
|
||||
TranslateVec3(inOther: Vec3): void;
|
||||
TranslateRVec3(inOther: RVec3): void;
|
||||
TransformedMat44(inOther: Mat44): AABox;
|
||||
TransformedRMat44(inOther: RMat44): AABox;
|
||||
Scaled(inScale: Vec3): AABox;
|
||||
GetClosestPoint(inV: Vec3): Vec3;
|
||||
GetSqDistanceTo(inV: Vec3): number;
|
||||
get_mMin(): Vec3;
|
||||
set_mMin(mMin: Vec3): void;
|
||||
mMin: Vec3;
|
||||
get_mMax(): Vec3;
|
||||
set_mMax(mMax: Vec3): void;
|
||||
mMax: Vec3;
|
||||
Overlaps(inOther: AABox): boolean;
|
||||
}
|
||||
class OrientedBox {
|
||||
constructor();
|
||||
@@ -1019,6 +1155,7 @@ declare namespace Jolt {
|
||||
mDensity: number;
|
||||
}
|
||||
class ConvexShape extends Shape {
|
||||
SetMaterial(inMaterial: PhysicsMaterial): void;
|
||||
GetDensity(): number;
|
||||
SetDensity(inDensity: number): void;
|
||||
}
|
||||
@@ -1203,7 +1340,8 @@ declare namespace Jolt {
|
||||
inPosition: Vec3,
|
||||
inRotation: Quat,
|
||||
inShape: Shape,
|
||||
inUserData: number
|
||||
inUserData: number,
|
||||
inIndex?: number
|
||||
): number;
|
||||
RemoveShape(inIndex: number): void;
|
||||
ModifyShape(inIndex: number, inPosition: Vec3, inRotation: Quat): void;
|
||||
@@ -1405,6 +1543,7 @@ declare namespace Jolt {
|
||||
inMaterial?: PhysicsMaterial,
|
||||
inHalfExtent?: number
|
||||
);
|
||||
SetMaterial(inMaterial: PhysicsMaterial): void;
|
||||
GetPlane(): Plane;
|
||||
GetHalfExtent(): number;
|
||||
}
|
||||
@@ -1449,6 +1588,8 @@ declare namespace Jolt {
|
||||
GetUserData(): number;
|
||||
SetUserData(inUserData: number): void;
|
||||
ResetWarmStart(): void;
|
||||
SaveState(inStream: StateRecorder): void;
|
||||
RestoreState(inStream: StateRecorder): void;
|
||||
}
|
||||
class TwoBodyConstraintSettings extends ConstraintSettings {
|
||||
Create(inBody1: Body, inBody2: Body): Constraint;
|
||||
@@ -1936,6 +2077,9 @@ declare namespace Jolt {
|
||||
AddRef(): void;
|
||||
Release(): void;
|
||||
}
|
||||
class PathConstraintPathHermite extends PathConstraintPath {
|
||||
AddPoint(inPosition: Vec3, inTangent: Vec3, inNormal: Vec3): void;
|
||||
}
|
||||
class PathConstraintPathEm extends PathConstraintPath {}
|
||||
class PathConstraintPathJS extends PathConstraintPathEm {
|
||||
constructor();
|
||||
@@ -2088,6 +2232,7 @@ declare namespace Jolt {
|
||||
GetInverseInertiaDiagonal(): Vec3;
|
||||
GetInertiaRotation(): Quat;
|
||||
SetInverseInertia(inInvI: Vec3, inRotation: Quat): void;
|
||||
ScaleToMass(inMass: number): void;
|
||||
GetLocalSpaceInverseInertia(): Mat44;
|
||||
GetInverseInertiaForRotation(inRotation: Mat44): Mat44;
|
||||
MultiplyWorldSpaceInverseInertiaByVector(inRotation: Quat, inV: Vec3): Vec3;
|
||||
@@ -2211,22 +2356,31 @@ declare namespace Jolt {
|
||||
): Vec3;
|
||||
GetUserData(): number;
|
||||
SetUserData(inUserData: number): void;
|
||||
SaveState(inStream: StateRecorder): void;
|
||||
RestoreState(inStream: StateRecorder): void;
|
||||
}
|
||||
class BodyInterface_AddState {}
|
||||
class BodyInterface {
|
||||
CreateBody(inSettings: BodyCreationSettings): Body;
|
||||
CreateSoftBody(inSettings: SoftBodyCreationSettings): Body;
|
||||
CreateBodyWithID(inBodyID: BodyID, inSettings: BodyCreationSettings): void;
|
||||
CreateBodyWithID(inBodyID: BodyID, inSettings: BodyCreationSettings): Body;
|
||||
CreateSoftBodyWithID(
|
||||
inBodyID: BodyID,
|
||||
inSettings: SoftBodyCreationSettings
|
||||
): void;
|
||||
): Body;
|
||||
CreateBodyWithoutID(inSettings: BodyCreationSettings): Body;
|
||||
CreateSoftBodyWithoutID(inSettings: SoftBodyCreationSettings): Body;
|
||||
DestroyBodyWithoutID(inBody: Body): void;
|
||||
AssignBodyID(ioBody: Body): boolean;
|
||||
AssignBodyID(ioBody: Body, inBodyID: BodyID): boolean;
|
||||
UnassignBodyID(inBodyID: BodyID): Body;
|
||||
UnassignBodyIDs(
|
||||
inBodyIDs: BodyIDMemRef,
|
||||
inNumber: number,
|
||||
outBodies: BodyPtrMemRef
|
||||
): void;
|
||||
DestroyBody(inBodyID: BodyID): void;
|
||||
DestroyBodies(inBodyIDs: BodyIDMemRef, inNumber: number): void;
|
||||
AddBody(inBodyID: BodyID, inActivationMode: EActivation): void;
|
||||
RemoveBody(inBodyID: BodyID): void;
|
||||
IsAdded(inBodyID: BodyID): boolean;
|
||||
@@ -2238,6 +2392,22 @@ declare namespace Jolt {
|
||||
inSettings: SoftBodyCreationSettings,
|
||||
inActivationMode: EActivation
|
||||
): BodyID;
|
||||
AddBodiesPrepare(
|
||||
ioBodies: BodyIDMemRef,
|
||||
inNumber: number
|
||||
): BodyInterface_AddState;
|
||||
AddBodiesFinalize(
|
||||
ioBodies: BodyIDMemRef,
|
||||
inNumber: number,
|
||||
inAddState: BodyInterface_AddState,
|
||||
inActivationMode: EActivation
|
||||
): void;
|
||||
AddBodiesAbort(
|
||||
ioBodies: BodyIDMemRef,
|
||||
inNumber: number,
|
||||
inAddState: BodyInterface_AddState
|
||||
): void;
|
||||
RemoveBodies(ioBodies: BodyIDMemRef, inNumber: number): void;
|
||||
CreateConstraint(
|
||||
inSettings: TwoBodyConstraintSettings,
|
||||
inBodyID1: BodyID,
|
||||
@@ -2290,6 +2460,16 @@ declare namespace Jolt {
|
||||
GetRotation(inBodyID: BodyID): Quat;
|
||||
GetWorldTransform(inBodyID: BodyID): RMat44;
|
||||
GetCenterOfMassTransform(inBodyID: BodyID): RMat44;
|
||||
SetLinearAndAngularVelocity(
|
||||
inBodyID: BodyID,
|
||||
inLinearVelocity: Vec3,
|
||||
inAngularVelocity: Vec3
|
||||
): void;
|
||||
GetLinearAndAngularVelocity(
|
||||
inBodyID: BodyID,
|
||||
outLinearVelocity: Vec3,
|
||||
outAngularVelocity: Vec3
|
||||
): void;
|
||||
SetLinearVelocity(inBodyID: BodyID, inLinearVelocity: Vec3): void;
|
||||
GetLinearVelocity(inBodyID: BodyID): Vec3;
|
||||
AddLinearVelocity(inBodyID: BodyID, inLinearVelocity: Vec3): void;
|
||||
@@ -2315,12 +2495,14 @@ declare namespace Jolt {
|
||||
inDeltaTime: number
|
||||
): void;
|
||||
ActivateBody(inBodyID: BodyID): void;
|
||||
ActivateBodies(inBodyIDs: BodyIDMemRef, inNumber: number): void;
|
||||
ActivateBodiesInAABox(
|
||||
inBox: AABox,
|
||||
inBroadPhaseLayerFilter: BroadPhaseLayerFilter,
|
||||
inObjectLayerFilter: ObjectLayerFilter
|
||||
): void;
|
||||
DeactivateBody(inBodyID: BodyID): void;
|
||||
DeactivateBodies(inBodyIDs: BodyIDMemRef, inNumber: number): void;
|
||||
IsActive(inBodyID: BodyID): boolean;
|
||||
ResetSleepTimer(inBodyID: BodyID): void;
|
||||
GetBodyType(inBodyID: BodyID): EBodyType;
|
||||
@@ -3083,6 +3265,18 @@ declare namespace Jolt {
|
||||
inBodyFilter: BodyFilter,
|
||||
inShapeFilter: ShapeFilter
|
||||
): void;
|
||||
CollideShapeWithInternalEdgeRemoval(
|
||||
inShape: Shape,
|
||||
inShapeScale: Vec3,
|
||||
inCenterOfMassTransform: RMat44,
|
||||
inCollideShapeSettings: CollideShapeSettings,
|
||||
inBaseOffset: RVec3,
|
||||
ioCollector: CollideShapeCollector,
|
||||
inBroadPhaseLayerFilter: BroadPhaseLayerFilter,
|
||||
inObjectLayerFilter: ObjectLayerFilter,
|
||||
inBodyFilter: BodyFilter,
|
||||
inShapeFilter: ShapeFilter
|
||||
): void;
|
||||
CastShape(
|
||||
inShapeCast: RShapeCast,
|
||||
inShapeCastSettings: ShapeCastSettings,
|
||||
@@ -3176,6 +3370,8 @@ declare namespace Jolt {
|
||||
SetBodyActivationListener(inListener: BodyActivationListener): void;
|
||||
GetBodyActivationListener(): BodyActivationListener;
|
||||
WereBodiesInContact(inBodyID1: BodyID, inBodyID2: BodyID): boolean;
|
||||
SetSimShapeFilter(inShapeFilter: SimShapeFilter): void;
|
||||
GetSimShapeFilter(): SimShapeFilter;
|
||||
}
|
||||
class MassProperties {
|
||||
constructor();
|
||||
@@ -3845,6 +4041,7 @@ declare namespace Jolt {
|
||||
}
|
||||
class CharacterVsCharacterCollision {}
|
||||
class CharacterVsCharacterCollisionSimple extends CharacterVsCharacterCollision {
|
||||
constructor();
|
||||
Add(inCharacter: CharacterVirtual): void;
|
||||
Remove(inCharacter: CharacterVirtual): void;
|
||||
}
|
||||
@@ -3871,6 +4068,62 @@ declare namespace Jolt {
|
||||
set_mWalkStairsStepDownExtra(mWalkStairsStepDownExtra: Vec3): void;
|
||||
mWalkStairsStepDownExtra: Vec3;
|
||||
}
|
||||
class CharacterVirtualContact {
|
||||
IsSameBody(inOther: CharacterVirtualContact): boolean;
|
||||
get_mPosition(): RVec3;
|
||||
set_mPosition(mPosition: RVec3): void;
|
||||
mPosition: RVec3;
|
||||
get_mLinearVelocity(): Vec3;
|
||||
set_mLinearVelocity(mLinearVelocity: Vec3): void;
|
||||
mLinearVelocity: Vec3;
|
||||
get_mContactNormal(): Vec3;
|
||||
set_mContactNormal(mContactNormal: Vec3): void;
|
||||
mContactNormal: Vec3;
|
||||
get_mSurfaceNormal(): Vec3;
|
||||
set_mSurfaceNormal(mSurfaceNormal: Vec3): void;
|
||||
mSurfaceNormal: Vec3;
|
||||
get_mDistance(): number;
|
||||
set_mDistance(mDistance: number): void;
|
||||
mDistance: number;
|
||||
get_mFraction(): number;
|
||||
set_mFraction(mFraction: number): void;
|
||||
mFraction: number;
|
||||
get_mBodyB(): BodyID;
|
||||
set_mBodyB(mBodyB: BodyID): void;
|
||||
mBodyB: BodyID;
|
||||
get_mCharacterB(): CharacterVirtual;
|
||||
set_mCharacterB(mCharacterB: CharacterVirtual): void;
|
||||
mCharacterB: CharacterVirtual;
|
||||
get_mSubShapeIDB(): SubShapeID;
|
||||
set_mSubShapeIDB(mSubShapeIDB: SubShapeID): void;
|
||||
mSubShapeIDB: SubShapeID;
|
||||
get_mMotionTypeB(): EMotionType;
|
||||
set_mMotionTypeB(mMotionTypeB: EMotionType): void;
|
||||
mMotionTypeB: EMotionType;
|
||||
get_mIsSensorB(): boolean;
|
||||
set_mIsSensorB(mIsSensorB: boolean): void;
|
||||
mIsSensorB: boolean;
|
||||
get_mUserData(): number;
|
||||
set_mUserData(mUserData: number): void;
|
||||
mUserData: number;
|
||||
get_mMaterial(): PhysicsMaterial;
|
||||
set_mMaterial(mMaterial: PhysicsMaterial): void;
|
||||
mMaterial: PhysicsMaterial;
|
||||
get_mHadCollision(): boolean;
|
||||
set_mHadCollision(mHadCollision: boolean): void;
|
||||
mHadCollision: boolean;
|
||||
get_mWasDiscarded(): boolean;
|
||||
set_mWasDiscarded(mWasDiscarded: boolean): void;
|
||||
mWasDiscarded: boolean;
|
||||
get_mCanPushCharacter(): boolean;
|
||||
set_mCanPushCharacter(mCanPushCharacter: boolean): void;
|
||||
mCanPushCharacter: boolean;
|
||||
}
|
||||
class ArrayCharacterVirtualContact {
|
||||
empty(): boolean;
|
||||
size(): number;
|
||||
at(inIndex: number): CharacterVirtualContact;
|
||||
}
|
||||
class TempAllocator {}
|
||||
class BroadPhaseLayerFilter {
|
||||
constructor();
|
||||
@@ -3940,6 +4193,20 @@ declare namespace Jolt {
|
||||
inSubShapeIDOfShape2: number
|
||||
): boolean;
|
||||
}
|
||||
class SimShapeFilter {
|
||||
constructor();
|
||||
}
|
||||
class SimShapeFilterJS extends SimShapeFilter {
|
||||
constructor();
|
||||
ShouldCollide(
|
||||
inBody1: number,
|
||||
inShape1: number,
|
||||
inSubShapeIDOfShape1: number,
|
||||
inBody2: number,
|
||||
inShape2: number,
|
||||
inSubShapeIDOfShape2: number
|
||||
): boolean;
|
||||
}
|
||||
class CharacterBase {
|
||||
GetRefCount(): number;
|
||||
AddRef(): void;
|
||||
@@ -3957,6 +4224,8 @@ declare namespace Jolt {
|
||||
GetGroundVelocity(): Vec3;
|
||||
GetGroundMaterial(): PhysicsMaterial;
|
||||
GetGroundBodyID(): BodyID;
|
||||
SaveState(inStream: StateRecorder): void;
|
||||
RestoreState(inStream: StateRecorder): void;
|
||||
}
|
||||
class CharacterVirtual extends CharacterBase {
|
||||
constructor(
|
||||
@@ -4056,6 +4325,9 @@ declare namespace Jolt {
|
||||
): boolean;
|
||||
SetInnerBodyShape(inShape: Shape): void;
|
||||
GetTransformedShape(): TransformedShape;
|
||||
HasCollidedWith(inBodyID: BodyID): boolean;
|
||||
HasCollidedWithCharacter(inCharacter: CharacterVirtual): boolean;
|
||||
GetActiveContacts(): ArrayCharacterVirtualContact;
|
||||
}
|
||||
class LinearCurve {
|
||||
constructor();
|
||||
@@ -4550,6 +4822,7 @@ declare namespace Jolt {
|
||||
GetRefCount(): number;
|
||||
AddRef(): void;
|
||||
Release(): void;
|
||||
GetConstraint(): VehicleConstraint;
|
||||
}
|
||||
class WheeledVehicleController extends VehicleController {
|
||||
constructor(
|
||||
@@ -4665,6 +4938,8 @@ declare namespace Jolt {
|
||||
}
|
||||
class SkeletalAnimation {
|
||||
constructor();
|
||||
SetIsLooping(inLooping: boolean): void;
|
||||
IsLooping(): boolean;
|
||||
GetDuration(): number;
|
||||
ScaleJoints(inScale: number): void;
|
||||
Sample(inTime: number, ioPose: SkeletonPose): void;
|
||||
@@ -4845,6 +5120,9 @@ declare namespace Jolt {
|
||||
get_mMaxContactConstraints(): number;
|
||||
set_mMaxContactConstraints(mMaxContactConstraints: number): void;
|
||||
mMaxContactConstraints: number;
|
||||
get_mMaxWorkerThreads(): number;
|
||||
set_mMaxWorkerThreads(mMaxWorkerThreads: number): void;
|
||||
mMaxWorkerThreads: number;
|
||||
get_mBroadPhaseLayerInterface(): BroadPhaseLayerInterface;
|
||||
set_mBroadPhaseLayerInterface(
|
||||
mBroadPhaseLayerInterface: BroadPhaseLayerInterface
|
||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -175,7 +175,8 @@ std::map<gd::String, gd::PropertyDescriptor> TextObject::GetProperties() const {
|
||||
.AddExtraInfo("center")
|
||||
.AddExtraInfo("bottom")
|
||||
.SetLabel(_("Vertical alignment"))
|
||||
.SetGroup(_("Font"));
|
||||
.SetGroup(_("Font"))
|
||||
.SetQuickCustomizationVisibility(gd::QuickCustomization::Hidden);
|
||||
|
||||
objectProperties["isOutlineEnabled"]
|
||||
.SetValue(isOutlineEnabled ? "true" : "false")
|
||||
|
@@ -10,7 +10,6 @@
|
||||
#include "GDCore/Events/Tools/EventsCodeNameMangler.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/SourceFile.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
|
@@ -53,6 +53,10 @@ void MetadataDeclarationHelper::DeclareExtension(
|
||||
extension.SetCategory(eventsFunctionsExtension.GetCategory());
|
||||
|
||||
DeclareExtensionDependencies(extension, eventsFunctionsExtension);
|
||||
|
||||
for (const auto &sourceFile : eventsFunctionsExtension.GetAllSourceFiles()) {
|
||||
extension.AddSourceFile() = sourceFile;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -154,6 +158,9 @@ gd::ObjectMetadata &MetadataDeclarationHelper::DeclareObjectMetadata(
|
||||
.AddDefaultBehavior("TextContainerCapability::TextContainerBehavior");
|
||||
}
|
||||
|
||||
if (eventsBasedObject.IsPrivate())
|
||||
objectMetadata.SetPrivate();
|
||||
|
||||
// TODO EBO Use full type to identify object to avoid collision.
|
||||
// Objects are identified by their name alone.
|
||||
const gd::String &objectType = eventsBasedObject.GetName();
|
||||
|
@@ -22,7 +22,6 @@
|
||||
#include "GDCore/Project/ExternalLayout.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/SourceFile.h"
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
@@ -130,15 +129,6 @@ bool Exporter::ExportWholePixiProject(const ExportOptions &options) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Export source files
|
||||
if (!helper.ExportExternalSourceFiles(
|
||||
exportedProject, codeOutputDir, includesFiles)) {
|
||||
gd::LogError(
|
||||
_("Error during exporting! Unable to export source files:\n") +
|
||||
lastError);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto projectUsedResources =
|
||||
gd::SceneResourcesFinder::FindProjectResources(exportedProject);
|
||||
std::unordered_map<gd::String, std::set<gd::String>> scenesUsedResources;
|
||||
@@ -173,10 +163,11 @@ bool Exporter::ExportWholePixiProject(const ExportOptions &options) {
|
||||
else if (options.target == "facebookInstantGames")
|
||||
source = gdjsRoot + "/Runtime/FacebookInstantGames/index.html";
|
||||
|
||||
if (!helper.ExportPixiIndexFile(exportedProject,
|
||||
if (!helper.ExportIndexFile(exportedProject,
|
||||
source,
|
||||
exportDir,
|
||||
includesFiles,
|
||||
usedExtensionsResult.GetUsedSourceFiles(),
|
||||
/*nonRuntimeScriptsCacheBurst=*/0,
|
||||
"")) {
|
||||
gd::LogError(_("Error during export:\n") + lastError);
|
||||
@@ -204,11 +195,8 @@ bool Exporter::ExportWholePixiProject(const ExportOptions &options) {
|
||||
exportedProject, options.exportPath, usedExtensions))
|
||||
return false;
|
||||
|
||||
if (!helper.ExportBuildResourcesElectronFiles(
|
||||
// It's important to use the original project here, as the exported
|
||||
// project can have its resources modified.
|
||||
options.project,
|
||||
options.exportPath))
|
||||
if (!helper.ExportBuildResourcesElectronFiles(exportedProject,
|
||||
options.exportPath))
|
||||
return false;
|
||||
} else if (options.target == "facebookInstantGames") {
|
||||
if (!exportProject(options.exportPath)) return false;
|
||||
|
@@ -38,7 +38,6 @@
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/Project/SourceFile.h"
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
@@ -71,6 +70,11 @@ static void InsertUnique(std::vector<gd::String> &container, gd::String str) {
|
||||
container.push_back(str);
|
||||
}
|
||||
|
||||
static void InsertUniqueFirst(std::vector<gd::String> &container, gd::String str) {
|
||||
if (std::find(container.begin(), container.end(), str) == container.end())
|
||||
container.insert(container.begin(), str);
|
||||
}
|
||||
|
||||
static gd::String CleanProjectName(gd::String projectName) {
|
||||
gd::String partiallyCleanedProjectName = projectName;
|
||||
|
||||
@@ -190,15 +194,6 @@ bool ExporterHelper::ExportProjectForPixiPreview(
|
||||
return false;
|
||||
}
|
||||
|
||||
// Export source files
|
||||
if (!ExportExternalSourceFiles(
|
||||
immutableProject, codeOutputDir, includesFiles)) {
|
||||
gd::LogError(
|
||||
_("Error during exporting! Unable to export source files:\n") +
|
||||
lastError);
|
||||
return false;
|
||||
}
|
||||
|
||||
previousTime = LogTimeSpent("Events code export", previousTime);
|
||||
}
|
||||
|
||||
@@ -318,10 +313,11 @@ bool ExporterHelper::ExportProjectForPixiPreview(
|
||||
ExportIncludesAndLibs(resourcesFiles, options.exportPath, true);
|
||||
|
||||
// Create the index file
|
||||
if (!ExportPixiIndexFile(exportedProject,
|
||||
if (!ExportIndexFile(exportedProject,
|
||||
gdjsRoot + "/Runtime/index.html",
|
||||
options.exportPath,
|
||||
includesFiles,
|
||||
usedExtensionsResult.GetUsedSourceFiles(),
|
||||
options.nonRuntimeScriptsCacheBurst,
|
||||
"gdjs.runtimeGameOptions"))
|
||||
return false;
|
||||
@@ -383,19 +379,40 @@ void ExporterHelper::SerializeUsedResources(
|
||||
}
|
||||
}
|
||||
|
||||
bool ExporterHelper::ExportPixiIndexFile(
|
||||
bool ExporterHelper::ExportIndexFile(
|
||||
const gd::Project &project,
|
||||
gd::String source,
|
||||
gd::String exportDir,
|
||||
const std::vector<gd::String> &includesFiles,
|
||||
const std::vector<gd::SourceFileMetadata> &sourceFiles,
|
||||
unsigned int nonRuntimeScriptsCacheBurst,
|
||||
gd::String additionalSpec) {
|
||||
gd::String str = fs.ReadFile(source);
|
||||
|
||||
// Add a reference to all files to include, as weel as the source files
|
||||
// required by the project.
|
||||
std::vector<gd::String> finalIncludesFiles = includesFiles;
|
||||
auto addSourceFileToIncludeFiles = [&](const gd::SourceFileMetadata& sourceFile) {
|
||||
const auto& resourcesManager = project.GetResourcesManager();
|
||||
if (!resourcesManager.HasResource(sourceFile.GetResourceName()))
|
||||
return;
|
||||
|
||||
const gd::String& sourceFileFilename = resourcesManager.GetResource(sourceFile.GetResourceName()).GetFile();
|
||||
|
||||
if (sourceFile.GetIncludePosition() == "first") {
|
||||
InsertUniqueFirst(finalIncludesFiles, sourceFileFilename);
|
||||
} else if (sourceFile.GetIncludePosition() == "last") {
|
||||
InsertUnique(finalIncludesFiles, sourceFileFilename);
|
||||
}
|
||||
};
|
||||
for (const auto& sourceFile : sourceFiles) {
|
||||
addSourceFileToIncludeFiles(sourceFile);
|
||||
}
|
||||
|
||||
// Generate the file
|
||||
if (!CompleteIndexFile(str,
|
||||
exportDir,
|
||||
includesFiles,
|
||||
finalIncludesFiles,
|
||||
nonRuntimeScriptsCacheBurst,
|
||||
additionalSpec))
|
||||
return false;
|
||||
@@ -730,9 +747,7 @@ bool ExporterHelper::ExportBuildResourcesElectronFiles(
|
||||
.GetResource(platformSpecificAssets.Get("desktop", "icon-512"))
|
||||
.GetFile();
|
||||
|
||||
auto projectDirectory = gd::AbstractFileSystem::NormalizeSeparator(
|
||||
fs.DirNameFrom(project.GetProjectFile()));
|
||||
fs.MakeAbsolute(iconFilename, projectDirectory);
|
||||
fs.MakeAbsolute(iconFilename, exportDir + "/app");
|
||||
fs.MkDir(exportDir + "/buildResources");
|
||||
if (fs.FileExists(iconFilename)) {
|
||||
fs.CopyFile(iconFilename, exportDir + "/buildResources/icon.png");
|
||||
@@ -964,29 +979,6 @@ bool ExporterHelper::ExportEventsCode(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExporterHelper::ExportExternalSourceFiles(
|
||||
const gd::Project &project,
|
||||
gd::String outputDir,
|
||||
std::vector<gd::String> &includesFiles) {
|
||||
const auto &allFiles = project.GetAllSourceFiles();
|
||||
for (std::size_t i = 0; i < allFiles.size(); ++i) {
|
||||
if (!allFiles[i]) continue;
|
||||
if (allFiles[i]->GetLanguage() != "Javascript") continue;
|
||||
|
||||
gd::SourceFile &file = *allFiles[i];
|
||||
|
||||
gd::String filename = file.GetFileName();
|
||||
fs.MakeAbsolute(filename, fs.DirNameFrom(project.GetProjectFile()));
|
||||
gd::String outFilename = "ext-code" + gd::String::From(i) + ".js";
|
||||
if (!fs.CopyFile(filename, outputDir + outFilename))
|
||||
gd::LogWarning(_("Could not copy external file") + filename);
|
||||
|
||||
InsertUnique(includesFiles, outputDir + outFilename);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
gd::String ExporterHelper::GetExportedIncludeFilename(
|
||||
const gd::String &include, unsigned int nonRuntimeScriptsCacheBurst) {
|
||||
auto addSearchParameterToUrl = [](const gd::String &url,
|
||||
|
@@ -20,11 +20,11 @@ class ExternalLayout;
|
||||
class SerializerElement;
|
||||
class AbstractFileSystem;
|
||||
class ResourcesManager;
|
||||
class SourceFileMetadata;
|
||||
class WholeProjectDiagnosticReport;
|
||||
class CaptureOptions;
|
||||
class Screenshot;
|
||||
} // namespace gd
|
||||
class wxProgressDialog;
|
||||
|
||||
namespace gdjs {
|
||||
|
||||
@@ -450,21 +450,6 @@ class ExporterHelper {
|
||||
bool ExportEffectIncludes(gd::Project &project,
|
||||
std::vector<gd::String> &includesFiles);
|
||||
|
||||
/**
|
||||
* \brief Copy the external source files used by the game into the export
|
||||
* directory, and add them into files to be included.
|
||||
*
|
||||
* Files are named "ext-codeX.js", X being the index of the external source
|
||||
* file in the project. \param project The project with resources to be
|
||||
* exported. \param outputDir The directory where the events code must be
|
||||
* generated. \param includesFiles A reference to a vector that will be filled
|
||||
* with JS files to be exported along with the project. (including
|
||||
* "ext-codeX.js" files).
|
||||
*/
|
||||
bool ExportExternalSourceFiles(const gd::Project &project,
|
||||
gd::String outputDir,
|
||||
std::vector<gd::String> &includesFiles);
|
||||
|
||||
/**
|
||||
* \brief Generate the standard index file and save it to the export
|
||||
* directory.
|
||||
@@ -482,10 +467,11 @@ class ExporterHelper {
|
||||
* \param additionalSpec JSON string that will be passed to the
|
||||
* gdjs.RuntimeGame object.
|
||||
*/
|
||||
bool ExportPixiIndexFile(const gd::Project &project,
|
||||
bool ExportIndexFile(const gd::Project &project,
|
||||
gd::String source,
|
||||
gd::String exportDir,
|
||||
const std::vector<gd::String> &includesFiles,
|
||||
const std::vector<gd::SourceFileMetadata> &sourceFiles,
|
||||
unsigned int nonRuntimeScriptsCacheBurst,
|
||||
gd::String additionalSpec = "");
|
||||
|
||||
|
1
GDJS/Runtime/types/project-data.d.ts
vendored
1
GDJS/Runtime/types/project-data.d.ts
vendored
@@ -340,7 +340,6 @@ declare interface ProjectPropertiesData {
|
||||
antialiasingMode: 'none' | 'MSAA';
|
||||
antialisingEnabledOnMobile: boolean;
|
||||
sizeOnStartupMode: string;
|
||||
useExternalSourceFiles: boolean;
|
||||
version: string;
|
||||
name: string;
|
||||
author: string;
|
||||
|
@@ -20,7 +20,6 @@ gdjs.createProjectData = (settings) => {
|
||||
sizeOnStartupMode: '',
|
||||
antialiasingMode: 'MSAA',
|
||||
antialisingEnabledOnMobile: false,
|
||||
useExternalSourceFiles: true,
|
||||
version: '1.0.0',
|
||||
name: 'Test game',
|
||||
author: '',
|
||||
|
@@ -24,7 +24,6 @@ gdjs.getPixiRuntimeGameWithAssets = () => {
|
||||
sizeOnStartupMode: 'adaptWidth',
|
||||
antialiasingMode: 'MSAA',
|
||||
antialisingEnabledOnMobile: false,
|
||||
useExternalSourceFiles: true,
|
||||
version: '1.0.0',
|
||||
name: 'Test game with real assets',
|
||||
author: '',
|
||||
|
@@ -39,6 +39,11 @@ interface VectorDependencyMetadata {
|
||||
[Const, Ref] DependencyMetadata at(unsigned long index);
|
||||
};
|
||||
|
||||
interface VectorSourceFileMetadata {
|
||||
unsigned long size();
|
||||
[Const, Ref] SourceFileMetadata at(unsigned long index);
|
||||
};
|
||||
|
||||
interface VectorInt {
|
||||
unsigned long size();
|
||||
long at(unsigned long index);
|
||||
@@ -833,6 +838,7 @@ interface ObjectConfiguration {
|
||||
void UnserializeFrom([Ref] Project project, [Const, Ref] SerializerElement element);
|
||||
|
||||
unsigned long GetAnimationsCount();
|
||||
[Const, Ref] DOMString GetAnimationName(unsigned long index);
|
||||
};
|
||||
|
||||
interface UniquePtrObjectConfiguration {
|
||||
@@ -1322,6 +1328,11 @@ interface AtlasResource {
|
||||
};
|
||||
AtlasResource implements Resource;
|
||||
|
||||
interface JavaScriptResource {
|
||||
void JavaScriptResource();
|
||||
};
|
||||
JavaScriptResource implements Resource;
|
||||
|
||||
interface InitialInstance {
|
||||
void InitialInstance();
|
||||
|
||||
@@ -1759,6 +1770,15 @@ interface DependencyMetadata {
|
||||
void CopyFrom([Const, Ref] DependencyMetadata dependencyMetadata);
|
||||
};
|
||||
|
||||
interface SourceFileMetadata {
|
||||
void SourceFileMetadata();
|
||||
|
||||
[Const, Ref] DOMString GetResourceName();
|
||||
[Ref] SourceFileMetadata SetResourceName([Const] DOMString resourceName_);
|
||||
[Const, Ref] DOMString GetIncludePosition();
|
||||
[Ref] SourceFileMetadata SetIncludePosition([Const] DOMString includePosition_);
|
||||
};
|
||||
|
||||
interface ParameterMetadata {
|
||||
void ParameterMetadata();
|
||||
|
||||
@@ -1928,6 +1948,9 @@ interface ObjectMetadata {
|
||||
boolean HasDefaultBehavior([Const] DOMString behaviorType);
|
||||
[Ref] ObjectMetadata AddDefaultBehavior([Const] DOMString behaviorType);
|
||||
|
||||
boolean IsPrivate();
|
||||
[Ref] ObjectMetadata SetPrivate();
|
||||
|
||||
[Ref] ObjectMetadata SetHidden();
|
||||
boolean IsHidden();
|
||||
|
||||
@@ -2245,6 +2268,7 @@ interface PlatformExtension {
|
||||
|
||||
[Ref] MapStringPropertyDescriptor GetAllProperties();
|
||||
[Ref] VectorDependencyMetadata GetAllDependencies();
|
||||
[Ref] VectorSourceFileMetadata GetAllSourceFiles();
|
||||
|
||||
[Const, Value] DOMString STATIC_GetNamespaceSeparator();
|
||||
[Const, Value] DOMString STATIC_GetBehaviorFullType(
|
||||
@@ -3006,6 +3030,11 @@ interface AbstractEventsBasedEntity {
|
||||
[Ref] EventsFunctionsContainer GetEventsFunctions();
|
||||
[Ref] PropertiesContainer GetPropertyDescriptors();
|
||||
|
||||
[Const, Ref] DOMString GetName();
|
||||
[Const, Ref] DOMString GetFullName();
|
||||
[Const, Ref] DOMString GetDescription();
|
||||
boolean IsPrivate();
|
||||
|
||||
void SerializeTo([Ref] SerializerElement element);
|
||||
void UnserializeFrom([Ref] Project project, [Const, Ref] SerializerElement element);
|
||||
};
|
||||
@@ -3013,16 +3042,13 @@ interface AbstractEventsBasedEntity {
|
||||
interface EventsBasedBehavior {
|
||||
void EventsBasedBehavior();
|
||||
|
||||
[Ref] EventsBasedBehavior SetDescription([Const] DOMString description);
|
||||
[Const, Ref] DOMString GetDescription();
|
||||
[Ref] EventsBasedBehavior SetName([Const] DOMString name);
|
||||
[Const, Ref] DOMString GetName();
|
||||
[Ref] EventsBasedBehavior SetFullName([Const] DOMString fullName);
|
||||
[Const, Ref] DOMString GetFullName();
|
||||
[Ref] EventsBasedBehavior SetDescription([Const] DOMString description);
|
||||
[Ref] EventsBasedBehavior SetPrivate(boolean isPrivate);
|
||||
|
||||
[Ref] EventsBasedBehavior SetObjectType([Const] DOMString fullName);
|
||||
[Const, Ref] DOMString GetObjectType();
|
||||
[Ref] EventsBasedBehavior SetPrivate(boolean isPrivate);
|
||||
boolean IsPrivate();
|
||||
[Ref] EventsBasedBehavior SetQuickCustomizationVisibility(QuickCustomization_Visibility visibility);
|
||||
QuickCustomization_Visibility GetQuickCustomizationVisibility();
|
||||
|
||||
@@ -3057,15 +3083,13 @@ interface EventsBasedBehaviorsList {
|
||||
interface EventsBasedObject {
|
||||
void EventsBasedObject();
|
||||
|
||||
[Ref] EventsBasedObject SetDescription([Const] DOMString description);
|
||||
[Const, Ref] DOMString GetDescription();
|
||||
[Ref] EventsBasedObject SetName([Const] DOMString name);
|
||||
[Const, Ref] DOMString GetName();
|
||||
[Ref] EventsBasedObject SetFullName([Const] DOMString fullName);
|
||||
[Const, Ref] DOMString GetFullName();
|
||||
[Ref] EventsBasedObject SetDescription([Const] DOMString description);
|
||||
[Ref] EventsBasedObject SetPrivate(boolean isPrivate);
|
||||
|
||||
[Ref] EventsBasedObject SetDefaultName([Const] DOMString defaultName);
|
||||
[Const, Ref] DOMString GetDefaultName();
|
||||
|
||||
[Ref] EventsBasedObject MarkAsRenderedIn3D(boolean isRenderedIn3D);
|
||||
boolean IsRenderedIn3D();
|
||||
[Ref] EventsBasedObject MarkAsAnimatable(boolean isAnimatable);
|
||||
@@ -3168,6 +3192,10 @@ interface EventsFunctionsExtension {
|
||||
void RemoveDependencyAt(unsigned long index);
|
||||
[Ref] VectorDependencyMetadata GetAllDependencies();
|
||||
|
||||
[Ref] SourceFileMetadata AddSourceFile();
|
||||
void RemoveSourceFileAt(unsigned long index);
|
||||
[Ref] VectorSourceFileMetadata GetAllSourceFiles();
|
||||
|
||||
[Ref] VariablesContainer GetGlobalVariables();
|
||||
[Ref] VariablesContainer GetSceneVariables();
|
||||
|
||||
|
@@ -424,6 +424,7 @@ typedef std::vector<Polygon2d> VectorPolygon2d;
|
||||
typedef std::vector<gd::Vector2f> VectorVector2f;
|
||||
typedef std::vector<EventsSearchResult> VectorEventsSearchResult;
|
||||
typedef std::vector<gd::DependencyMetadata> VectorDependencyMetadata;
|
||||
typedef std::vector<gd::SourceFileMetadata> VectorSourceFileMetadata;
|
||||
typedef std::vector<gd::EventsFunction> VectorEventsFunction;
|
||||
typedef gd::Object gdObject; // To avoid clashing javascript Object in glue.js
|
||||
typedef ParticleEmitterObject::RendererType ParticleEmitterObject_RendererType;
|
||||
|
@@ -1368,6 +1368,24 @@ describe('libGD.js', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('gd.JavaScriptResource', function () {
|
||||
it('should have name and file', function () {
|
||||
const resource = new gd.JavaScriptResource();
|
||||
resource.setName('MyJavaScriptResource');
|
||||
resource.setFile('MyJavaScriptFile');
|
||||
expect(resource.getName()).toBe('MyJavaScriptResource');
|
||||
expect(resource.getFile()).toBe('MyJavaScriptFile');
|
||||
resource.delete();
|
||||
});
|
||||
it('can have metadata', function () {
|
||||
const resource = new gd.JavaScriptResource();
|
||||
expect(resource.getMetadata()).toBe('');
|
||||
resource.setMetadata(JSON.stringify({ hello: 'world' }));
|
||||
expect(resource.getMetadata()).toBe('{"hello":"world"}');
|
||||
resource.delete();
|
||||
});
|
||||
});
|
||||
|
||||
describe('gd.JsonResource', function () {
|
||||
it('should have name and file', function () {
|
||||
const resource = new gd.JsonResource();
|
||||
|
42
GDevelop.js/types.d.ts
vendored
42
GDevelop.js/types.d.ts
vendored
@@ -125,6 +125,11 @@ export class VectorDependencyMetadata extends EmscriptenObject {
|
||||
at(index: number): DependencyMetadata;
|
||||
}
|
||||
|
||||
export class VectorSourceFileMetadata extends EmscriptenObject {
|
||||
size(): number;
|
||||
at(index: number): SourceFileMetadata;
|
||||
}
|
||||
|
||||
export class VectorInt extends EmscriptenObject {
|
||||
size(): number;
|
||||
at(index: number): number;
|
||||
@@ -708,6 +713,7 @@ export class ObjectConfiguration extends EmscriptenObject {
|
||||
serializeTo(element: SerializerElement): void;
|
||||
unserializeFrom(project: Project, element: SerializerElement): void;
|
||||
getAnimationsCount(): number;
|
||||
getAnimationName(index: number): string;
|
||||
}
|
||||
|
||||
export class UniquePtrObjectConfiguration extends EmscriptenObject {
|
||||
@@ -1100,6 +1106,10 @@ export class AtlasResource extends Resource {
|
||||
constructor();
|
||||
}
|
||||
|
||||
export class JavaScriptResource extends Resource {
|
||||
constructor();
|
||||
}
|
||||
|
||||
export class InitialInstance extends EmscriptenObject {
|
||||
constructor();
|
||||
setObjectName(name: string): void;
|
||||
@@ -1448,6 +1458,14 @@ export class DependencyMetadata extends EmscriptenObject {
|
||||
copyFrom(dependencyMetadata: DependencyMetadata): void;
|
||||
}
|
||||
|
||||
export class SourceFileMetadata extends EmscriptenObject {
|
||||
constructor();
|
||||
getResourceName(): string;
|
||||
setResourceName(resourceName_: string): SourceFileMetadata;
|
||||
getIncludePosition(): string;
|
||||
setIncludePosition(includePosition_: string): SourceFileMetadata;
|
||||
}
|
||||
|
||||
export class ParameterMetadata extends EmscriptenObject {
|
||||
constructor();
|
||||
getType(): string;
|
||||
@@ -1543,6 +1561,8 @@ export class ObjectMetadata extends EmscriptenObject {
|
||||
getDefaultBehaviors(): SetString;
|
||||
hasDefaultBehavior(behaviorType: string): boolean;
|
||||
addDefaultBehavior(behaviorType: string): ObjectMetadata;
|
||||
isPrivate(): boolean;
|
||||
setPrivate(): ObjectMetadata;
|
||||
setHidden(): ObjectMetadata;
|
||||
isHidden(): boolean;
|
||||
markAsRenderedIn3D(): ObjectMetadata;
|
||||
@@ -1704,6 +1724,7 @@ export class PlatformExtension extends EmscriptenObject {
|
||||
getAllStrExpressionsForBehavior(autoType: string): MapStringExpressionMetadata;
|
||||
getAllProperties(): MapStringPropertyDescriptor;
|
||||
getAllDependencies(): VectorDependencyMetadata;
|
||||
getAllSourceFiles(): VectorSourceFileMetadata;
|
||||
static getNamespaceSeparator(): string;
|
||||
static getBehaviorFullType(extensionName: string, behaviorName: string): string;
|
||||
static getObjectFullType(extensionName: string, objectName: string): string;
|
||||
@@ -2172,22 +2193,22 @@ export class EventsFunctionsContainer extends EmscriptenObject {
|
||||
export class AbstractEventsBasedEntity extends EmscriptenObject {
|
||||
getEventsFunctions(): EventsFunctionsContainer;
|
||||
getPropertyDescriptors(): PropertiesContainer;
|
||||
getName(): string;
|
||||
getFullName(): string;
|
||||
getDescription(): string;
|
||||
isPrivate(): boolean;
|
||||
serializeTo(element: SerializerElement): void;
|
||||
unserializeFrom(project: Project, element: SerializerElement): void;
|
||||
}
|
||||
|
||||
export class EventsBasedBehavior extends AbstractEventsBasedEntity {
|
||||
constructor();
|
||||
setDescription(description: string): EventsBasedBehavior;
|
||||
getDescription(): string;
|
||||
setName(name: string): EventsBasedBehavior;
|
||||
getName(): string;
|
||||
setFullName(fullName: string): EventsBasedBehavior;
|
||||
getFullName(): string;
|
||||
setDescription(description: string): EventsBasedBehavior;
|
||||
setPrivate(isPrivate: boolean): EventsBasedBehavior;
|
||||
setObjectType(fullName: string): EventsBasedBehavior;
|
||||
getObjectType(): string;
|
||||
setPrivate(isPrivate: boolean): EventsBasedBehavior;
|
||||
isPrivate(): boolean;
|
||||
setQuickCustomizationVisibility(visibility: QuickCustomization_Visibility): EventsBasedBehavior;
|
||||
getQuickCustomizationVisibility(): QuickCustomization_Visibility;
|
||||
getSharedPropertyDescriptors(): PropertiesContainer;
|
||||
@@ -2217,12 +2238,10 @@ export class EventsBasedBehaviorsList extends EmscriptenObject {
|
||||
|
||||
export class EventsBasedObject extends AbstractEventsBasedEntity {
|
||||
constructor();
|
||||
setDescription(description: string): EventsBasedObject;
|
||||
getDescription(): string;
|
||||
setName(name: string): EventsBasedObject;
|
||||
getName(): string;
|
||||
setFullName(fullName: string): EventsBasedObject;
|
||||
getFullName(): string;
|
||||
setDescription(description: string): EventsBasedObject;
|
||||
setPrivate(isPrivate: boolean): EventsBasedObject;
|
||||
setDefaultName(defaultName: string): EventsBasedObject;
|
||||
getDefaultName(): string;
|
||||
markAsRenderedIn3D(isRenderedIn3D: boolean): EventsBasedObject;
|
||||
@@ -2317,6 +2336,9 @@ export class EventsFunctionsExtension extends EmscriptenObject {
|
||||
addDependency(): DependencyMetadata;
|
||||
removeDependencyAt(index: number): void;
|
||||
getAllDependencies(): VectorDependencyMetadata;
|
||||
addSourceFile(): SourceFileMetadata;
|
||||
removeSourceFileAt(index: number): void;
|
||||
getAllSourceFiles(): VectorSourceFileMetadata;
|
||||
getGlobalVariables(): VariablesContainer;
|
||||
getSceneVariables(): VariablesContainer;
|
||||
getEventsBasedBehaviors(): EventsBasedBehaviorsList;
|
||||
|
@@ -2,6 +2,10 @@
|
||||
declare class gdAbstractEventsBasedEntity {
|
||||
getEventsFunctions(): gdEventsFunctionsContainer;
|
||||
getPropertyDescriptors(): gdPropertiesContainer;
|
||||
getName(): string;
|
||||
getFullName(): string;
|
||||
getDescription(): string;
|
||||
isPrivate(): boolean;
|
||||
serializeTo(element: gdSerializerElement): void;
|
||||
unserializeFrom(project: gdProject, element: gdSerializerElement): void;
|
||||
delete(): void;
|
||||
|
@@ -1,16 +1,12 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdEventsBasedBehavior extends gdAbstractEventsBasedEntity {
|
||||
constructor(): void;
|
||||
setDescription(description: string): gdEventsBasedBehavior;
|
||||
getDescription(): string;
|
||||
setName(name: string): gdEventsBasedBehavior;
|
||||
getName(): string;
|
||||
setFullName(fullName: string): gdEventsBasedBehavior;
|
||||
getFullName(): string;
|
||||
setDescription(description: string): gdEventsBasedBehavior;
|
||||
setPrivate(isPrivate: boolean): gdEventsBasedBehavior;
|
||||
setObjectType(fullName: string): gdEventsBasedBehavior;
|
||||
getObjectType(): string;
|
||||
setPrivate(isPrivate: boolean): gdEventsBasedBehavior;
|
||||
isPrivate(): boolean;
|
||||
setQuickCustomizationVisibility(visibility: QuickCustomization_Visibility): gdEventsBasedBehavior;
|
||||
getQuickCustomizationVisibility(): QuickCustomization_Visibility;
|
||||
getSharedPropertyDescriptors(): gdPropertiesContainer;
|
||||
|
@@ -1,12 +1,10 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdEventsBasedObject extends gdAbstractEventsBasedEntity {
|
||||
constructor(): void;
|
||||
setDescription(description: string): gdEventsBasedObject;
|
||||
getDescription(): string;
|
||||
setName(name: string): gdEventsBasedObject;
|
||||
getName(): string;
|
||||
setFullName(fullName: string): gdEventsBasedObject;
|
||||
getFullName(): string;
|
||||
setDescription(description: string): gdEventsBasedObject;
|
||||
setPrivate(isPrivate: boolean): gdEventsBasedObject;
|
||||
setDefaultName(defaultName: string): gdEventsBasedObject;
|
||||
getDefaultName(): string;
|
||||
markAsRenderedIn3D(isRenderedIn3D: boolean): gdEventsBasedObject;
|
||||
|
@@ -31,6 +31,9 @@ declare class gdEventsFunctionsExtension extends gdEventsFunctionsContainer {
|
||||
addDependency(): gdDependencyMetadata;
|
||||
removeDependencyAt(index: number): void;
|
||||
getAllDependencies(): gdVectorDependencyMetadata;
|
||||
addSourceFile(): gdSourceFileMetadata;
|
||||
removeSourceFileAt(index: number): void;
|
||||
getAllSourceFiles(): gdVectorSourceFileMetadata;
|
||||
getGlobalVariables(): gdVariablesContainer;
|
||||
getSceneVariables(): gdVariablesContainer;
|
||||
getEventsBasedBehaviors(): gdEventsBasedBehaviorsList;
|
||||
|
6
GDevelop.js/types/gdjavascriptresource.js
Normal file
6
GDevelop.js/types/gdjavascriptresource.js
Normal file
@@ -0,0 +1,6 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdJavaScriptResource extends gdResource {
|
||||
constructor(): void;
|
||||
delete(): void;
|
||||
ptr: number;
|
||||
};
|
@@ -12,6 +12,7 @@ declare class gdObjectConfiguration {
|
||||
serializeTo(element: gdSerializerElement): void;
|
||||
unserializeFrom(project: gdProject, element: gdSerializerElement): void;
|
||||
getAnimationsCount(): number;
|
||||
getAnimationName(index: number): string;
|
||||
delete(): void;
|
||||
ptr: number;
|
||||
};
|
@@ -24,6 +24,8 @@ declare class gdObjectMetadata {
|
||||
getDefaultBehaviors(): gdSetString;
|
||||
hasDefaultBehavior(behaviorType: string): boolean;
|
||||
addDefaultBehavior(behaviorType: string): gdObjectMetadata;
|
||||
isPrivate(): boolean;
|
||||
setPrivate(): gdObjectMetadata;
|
||||
setHidden(): gdObjectMetadata;
|
||||
isHidden(): boolean;
|
||||
markAsRenderedIn3D(): gdObjectMetadata;
|
||||
|
@@ -55,6 +55,7 @@ declare class gdPlatformExtension {
|
||||
getAllStrExpressionsForBehavior(autoType: string): gdMapStringExpressionMetadata;
|
||||
getAllProperties(): gdMapStringPropertyDescriptor;
|
||||
getAllDependencies(): gdVectorDependencyMetadata;
|
||||
getAllSourceFiles(): gdVectorSourceFileMetadata;
|
||||
static getNamespaceSeparator(): string;
|
||||
static getBehaviorFullType(extensionName: string, behaviorName: string): string;
|
||||
static getObjectFullType(extensionName: string, objectName: string): string;
|
||||
|
10
GDevelop.js/types/gdsourcefilemetadata.js
Normal file
10
GDevelop.js/types/gdsourcefilemetadata.js
Normal file
@@ -0,0 +1,10 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdSourceFileMetadata {
|
||||
constructor(): void;
|
||||
getResourceName(): string;
|
||||
setResourceName(resourceName_: string): gdSourceFileMetadata;
|
||||
getIncludePosition(): string;
|
||||
setIncludePosition(includePosition_: string): gdSourceFileMetadata;
|
||||
delete(): void;
|
||||
ptr: number;
|
||||
};
|
7
GDevelop.js/types/gdvectorsourcefilemetadata.js
Normal file
7
GDevelop.js/types/gdvectorsourcefilemetadata.js
Normal file
@@ -0,0 +1,7 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdVectorSourceFileMetadata {
|
||||
size(): number;
|
||||
at(index: number): gdSourceFileMetadata;
|
||||
delete(): void;
|
||||
ptr: number;
|
||||
};
|
@@ -43,6 +43,7 @@ declare class libGDevelop {
|
||||
VectorString: Class<gdVectorString>;
|
||||
VectorPlatformExtension: Class<gdVectorPlatformExtension>;
|
||||
VectorDependencyMetadata: Class<gdVectorDependencyMetadata>;
|
||||
VectorSourceFileMetadata: Class<gdVectorSourceFileMetadata>;
|
||||
VectorInt: Class<gdVectorInt>;
|
||||
VectorVariable: Class<gdVectorVariable>;
|
||||
VectorObjectFolderOrObject: Class<gdVectorObjectFolderOrObject>;
|
||||
@@ -123,6 +124,7 @@ declare class libGDevelop {
|
||||
TilesetResource: Class<gdTilesetResource>;
|
||||
Model3DResource: Class<gdModel3DResource>;
|
||||
AtlasResource: Class<gdAtlasResource>;
|
||||
JavaScriptResource: Class<gdJavaScriptResource>;
|
||||
InitialInstance: Class<gdInitialInstance>;
|
||||
InitialInstancesContainer: Class<gdInitialInstancesContainer>;
|
||||
HighestZOrderFinder: Class<gdHighestZOrderFinder>;
|
||||
@@ -146,6 +148,7 @@ declare class libGDevelop {
|
||||
ExpressionMetadata: Class<gdExpressionMetadata>;
|
||||
MultipleInstructionMetadata: Class<gdMultipleInstructionMetadata>;
|
||||
DependencyMetadata: Class<gdDependencyMetadata>;
|
||||
SourceFileMetadata: Class<gdSourceFileMetadata>;
|
||||
ParameterMetadata: Class<gdParameterMetadata>;
|
||||
ValueTypeMetadata: Class<gdValueTypeMetadata>;
|
||||
ParameterMetadataContainer: Class<gdParameterMetadataContainer>;
|
||||
|
@@ -1,2 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m7 0-6 3.5v7l6 3.5 6-3.5v-7l-6-3.5z" fill="#2e388a"/><g transform="translate(-.0405 .026)" fill="none" stroke="#53a6da" stroke-width=".7"><path d="m8.294 9.112c-1.291 0.7556-2.601 1.165-3.664 1.229-1.085 0.0656-1.803-0.2277-2.095-0.7272-0.2924-0.4996-0.1966-1.269 0.3921-2.183 0.5768-0.8956 1.575-1.837 2.866-2.593 1.291-0.7556 2.601-1.165 3.664-1.229 1.085-0.06552 1.803 0.2277 2.095 0.7272s0.1964 1.269-0.3862 2.174-1.581 1.846-2.872 2.602z"/><path d="m5.787 9.112c1.291 0.7556 2.601 1.165 3.664 1.229 1.085 0.0656 1.803-0.2277 2.095-0.7272 0.2924-0.4996 0.1966-1.269-0.3921-2.183-0.5768-0.8956-1.575-1.837-2.866-2.593-1.291-0.7556-2.601-1.165-3.664-1.229-1.085-0.06552-1.803 0.2277-2.095 0.7272s-0.1964 1.269 0.3862 2.174 1.581 1.846 2.872 2.602z"/><path d="m7.038 1.75c-0.5788 0-1.194 0.4711-1.686 1.441-0.4817 0.9502-0.7898 2.287-0.7898 3.783s0.3081 2.833 0.7898 3.783c0.4916 0.9697 1.107 1.441 1.686 1.441s1.194-0.4712 1.686-1.441c0.4817-0.9502 0.7898-2.287 0.7898-3.783s-0.3081-2.833-0.7898-3.783c-0.4916-0.9698-1.107-1.441-1.686-1.441z"/></g><path d="m7 8c0.5524 0 1-0.4478 1-1 0-0.5524-0.4478-1-1-1s-1 0.4478-1 1c0 0.5524 0.4478 1 1 1z" fill="#fff" stroke-width=".6439"/></svg>
|
||||
<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m7 0-6 3.5v7l6 3.5 6-3.5v-7z" fill="#55b1e0" style="paint-order:normal"/><path transform="translate(-5.299 -.3008)" d="m12.3 0.5898 5.75 3.355v6.711l-5.75 3.355-5.75-3.355v-6.711z" fill="#2e388a" style="paint-order:normal"/><g transform="translate(-.0405 .026)" fill="none" stroke="#55b1e0" stroke-width=".7"><path d="m8.294 9.112c-1.291 0.7556-2.601 1.165-3.664 1.229-1.085 0.0656-1.803-0.2277-2.095-0.7272-0.2924-0.4996-0.1966-1.269 0.3921-2.183 0.5768-0.8956 1.575-1.837 2.866-2.593 1.291-0.7556 2.601-1.165 3.664-1.229 1.085-0.06552 1.803 0.2277 2.095 0.7272s0.1964 1.269-0.3862 2.174-1.581 1.846-2.872 2.602z"/><path d="m5.787 9.112c1.291 0.7556 2.601 1.165 3.664 1.229 1.085 0.0656 1.803-0.2277 2.095-0.7272 0.2924-0.4996 0.1966-1.269-0.3921-2.183-0.5768-0.8956-1.575-1.837-2.866-2.593-1.291-0.7556-2.601-1.165-3.664-1.229-1.085-0.06552-1.803 0.2277-2.095 0.7272s-0.1964 1.269 0.3862 2.174 1.581 1.846 2.872 2.602z"/><path d="m7.038 1.75c-0.5788 0-1.194 0.4711-1.686 1.441-0.4817 0.9502-0.7898 2.287-0.7898 3.783s0.3081 2.833 0.7898 3.783c0.4916 0.9697 1.107 1.441 1.686 1.441s1.194-0.4712 1.686-1.441c0.4817-0.9502 0.7898-2.287 0.7898-3.783s-0.3081-2.833-0.7898-3.783c-0.4916-0.9698-1.107-1.441-1.686-1.441z"/></g><path d="m7 8c0.5524 0 1-0.4478 1-1 0-0.5524-0.4478-1-1-1s-1 0.4478-1 1c0 0.5524 0.4478 1 1 1z" fill="#fff" stroke-width=".6439"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.5 KiB |
@@ -1,2 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><path d="m7 0-6 3.5v7l6 3.5 6-3.5v-7l-6-3.5z" fill="#2e388a"/><g fill="#27aae1" stroke-width=".7"><path d="m9.1 3.801v1.398h-0.6992-2.801-2.1v1.4 1.4h1.4v-1.4h0.6992v2.801h-2.1v1.4h2.1 1.4v-1.4h1.4 0.6992v1.4h1.4v-1.4-1.4h-2.1v-1.4h2.1v-1.4-1.398h-1.4z"/><path d="m7 5.2c0.7732 0 1.4-0.6268 1.4-1.4s-0.6268-1.4-1.4-1.4-1.4 0.6268-1.4 1.4 0.6268 1.4 1.4 1.4z"/></g></svg>
|
||||
<svg width="14" height="14" version="1.1" viewBox="0 0 14 14" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><g><path d="m7 0-6 3.5v7l6 3.5 6-3.5v-7l-6-3.5z" fill="#55b1e0" style="paint-order:normal"/><path transform="translate(-5.299 -.3008)" d="m12.3 0.5898 5.75 3.355v6.711l-5.75 3.355-5.75-3.355v-6.711z" fill="#2e388a" style="paint-order:normal"/><g fill="#55b1e0" stroke-width=".7"><path d="m9.1 3.801v1.398h-5.6v2.8h1.4v-1.4h0.6992v2.801h-2.1v1.4h3.5v-1.4h2.099v1.4h1.4v-2.8h-2.1v-1.4h2.1v-2.798h-1.4z"/><path d="m7 5.2c0.7732 0 1.4-0.6268 1.4-1.4s-0.6268-1.4-1.4-1.4-1.4 0.6268-1.4 1.4 0.6268 1.4 1.4 1.4z"/></g></g></svg>
|
||||
|
Before Width: | Height: | Size: 528 B After Width: | Height: | Size: 679 B |
@@ -7,6 +7,7 @@ const shell = require('shelljs');
|
||||
const path = require('path');
|
||||
const copy = require('recursive-copy');
|
||||
const args = require('minimist')(process.argv.slice(2));
|
||||
const fs = require('fs');
|
||||
|
||||
const gdevelopRootPath = path.join(__dirname, '..', '..', '..');
|
||||
const destinationPaths = [
|
||||
@@ -53,6 +54,8 @@ if (!args['skip-sources']) {
|
||||
|
||||
const startTime = Date.now();
|
||||
|
||||
const typesDestinationPath = path.join(destinationPath, 'Runtime-sources', 'types');
|
||||
const pixiDestinationPath = path.join(typesDestinationPath, 'pixi');
|
||||
// TODO: Investigate the use of a smart & faster sync
|
||||
// that only copy files with changed content.
|
||||
return Promise.all([
|
||||
@@ -66,8 +69,71 @@ if (!args['skip-sources']) {
|
||||
path.join(destinationPath, 'Runtime-sources', 'Extensions'),
|
||||
{ ...copyOptions, filter: ['**/*.js', '**/*.ts'] }
|
||||
),
|
||||
copy(
|
||||
path.join(gdevelopRootPath, 'GDJS', 'node_modules', '@types', 'three'),
|
||||
path.join(typesDestinationPath, 'three'),
|
||||
{ ...copyOptions, filter: ['*.d.ts'] }
|
||||
),
|
||||
copy(
|
||||
path.join(gdevelopRootPath, 'GDJS', 'node_modules', '@types', 'three', 'src'),
|
||||
path.join(typesDestinationPath, 'three', 'src'),
|
||||
{ ...copyOptions, filter: ['**/*.d.ts'] }
|
||||
),
|
||||
copy(
|
||||
path.join(gdevelopRootPath, 'GDJS', 'node_modules', '@pixi'),
|
||||
pixiDestinationPath,
|
||||
{ ...copyOptions, filter: ['**/*.d.ts'] }
|
||||
),
|
||||
])
|
||||
.then(function([unbundledResults, unbundledExtensionsResults]) {
|
||||
// Replace import of packages by import of relative folders.
|
||||
shell.sed(
|
||||
'-i',
|
||||
'from \'@pixi((/\\w+)+)',
|
||||
'from \'../..$1/lib',
|
||||
pixiDestinationPath + '/*/lib/*.d.ts'
|
||||
);
|
||||
fs.writeFileSync(path.join(pixiDestinationPath, 'index.d.ts'), `
|
||||
import './mixin-cache-as-bitmap/lib';
|
||||
import './mixin-get-child-by-name/lib';
|
||||
import './mixin-get-global-position/lib';
|
||||
export * from './accessibility/lib';
|
||||
export * from './app/lib';
|
||||
export * from './assets/lib';
|
||||
export * from './color/lib';
|
||||
export * from './compressed-textures/lib';
|
||||
export * from './constant/lib';
|
||||
export * from './core';
|
||||
export * from './display/lib';
|
||||
export * from './events/lib';
|
||||
export * from './extensions/lib';
|
||||
export * from './extract/lib';
|
||||
export * from './filter-alpha/lib';
|
||||
export * from './filter-blur/lib';
|
||||
export * from './filter-color-matrix/lib';
|
||||
export * from './filter-displacement/lib';
|
||||
export * from './filter-fxaa/lib';
|
||||
export * from './filter-noise/lib';
|
||||
export * from './graphics/lib';
|
||||
export * from './math/lib';
|
||||
export * from './mesh/lib';
|
||||
export * from './mesh-extras/lib';
|
||||
export * from './particle-container/lib';
|
||||
export * from './prepare/lib';
|
||||
export * from './runner/lib';
|
||||
export * from './settings/lib';
|
||||
export * from './sprite/lib';
|
||||
export * from './sprite-animated/lib';
|
||||
export * from './sprite-tiling/lib';
|
||||
export * from './spritesheet/lib';
|
||||
export * from './text/lib';
|
||||
export * from './text-bitmap/lib';
|
||||
export * from './text-html/lib';
|
||||
export * from './ticker/lib';
|
||||
export * from './utils/lib';
|
||||
|
||||
export as namespace PIXI;
|
||||
`);
|
||||
const totalFilesCount =
|
||||
unbundledResults.length + unbundledExtensionsResults.length;
|
||||
const duration = Date.now() - startTime;
|
||||
|
@@ -403,6 +403,9 @@ const generateExtensionReference = extension => {
|
||||
/** @type {Array<ObjectReference>} */
|
||||
let objectReferences = objectTypes.map(objectType => {
|
||||
const objectMetadata = extension.getObjectMetadata(objectType);
|
||||
if (objectMetadata.isPrivate()) {
|
||||
return null;
|
||||
}
|
||||
const actionsReferenceTexts = generateInstructionsReferenceRowsTexts({
|
||||
areConditions: false,
|
||||
instructionsMetadata: extension.getAllActionsForObject(objectType),
|
||||
@@ -433,7 +436,7 @@ const generateExtensionReference = extension => {
|
||||
conditionsReferenceTexts,
|
||||
expressionsReferenceTexts,
|
||||
};
|
||||
});
|
||||
}).filter(Boolean);
|
||||
|
||||
// Behavior expressions
|
||||
/** @type {Array<BehaviorReference>} */
|
||||
|
@@ -201,11 +201,11 @@ export const AssetDetails = React.forwardRef<Props, AssetDetailsInterface>(
|
||||
|
||||
React.useEffect(
|
||||
() => {
|
||||
if (!asset) {
|
||||
if (!asset || asset.id !== assetShortHeader.id) {
|
||||
loadAsset();
|
||||
}
|
||||
},
|
||||
[asset, loadAsset]
|
||||
[asset, loadAsset, assetShortHeader]
|
||||
);
|
||||
|
||||
const loadAuthorPublicProfiles = React.useCallback(
|
||||
|
@@ -29,9 +29,9 @@ import {
|
||||
AssetSwappingAssetStoreSearchFilter,
|
||||
} from './AssetStoreSearchFilter';
|
||||
import {
|
||||
type NavigationState,
|
||||
type AssetStorePageState,
|
||||
assetStoreHomePageState,
|
||||
AssetStoreNavigatorContext,
|
||||
} from './AssetStoreNavigator';
|
||||
import { type ChosenCategory } from '../UI/Search/FiltersChooser';
|
||||
import AuthenticatedUserContext from '../Profile/AuthenticatedUserContext';
|
||||
@@ -41,8 +41,6 @@ import {
|
||||
} from './AssetStoreUtils';
|
||||
import useAlertDialog from '../UI/Alert/useAlertDialog';
|
||||
|
||||
const defaultSearchText = '';
|
||||
|
||||
export type AssetFiltersState = {|
|
||||
animatedFilter: AnimatedAssetStoreSearchFilter,
|
||||
setAnimatedFilter: AnimatedAssetStoreSearchFilter => void,
|
||||
@@ -78,12 +76,9 @@ type AssetStoreState = {|
|
||||
privateAssetPackListingDatasSearchResults: ?Array<PrivateAssetPackListingData>,
|
||||
fetchAssetsAndFilters: () => void,
|
||||
error: ?Error,
|
||||
searchText: string,
|
||||
setSearchText: string => void,
|
||||
assetFiltersState: AssetFiltersState,
|
||||
assetPackFiltersState: AssetPackFiltersState,
|
||||
clearAllFilters: () => void,
|
||||
shopNavigationState: NavigationState,
|
||||
currentPage: AssetStorePageState,
|
||||
useSearchItem: (
|
||||
searchText: string,
|
||||
@@ -108,8 +103,6 @@ export const initialAssetStoreState: AssetStoreState = {
|
||||
privateAssetPackListingDatasSearchResults: null,
|
||||
fetchAssetsAndFilters: () => {},
|
||||
error: null,
|
||||
searchText: '',
|
||||
setSearchText: () => {},
|
||||
assetFiltersState: {
|
||||
animatedFilter: new AnimatedAssetStoreSearchFilter(),
|
||||
setAnimatedFilter: filter => {},
|
||||
@@ -131,30 +124,6 @@ export const initialAssetStoreState: AssetStoreState = {
|
||||
setTypeFilter: filter => {},
|
||||
},
|
||||
clearAllFilters: () => {},
|
||||
shopNavigationState: {
|
||||
getCurrentPage: () => assetStoreHomePageState,
|
||||
isRootPage: true,
|
||||
backToPreviousPage: () => assetStoreHomePageState,
|
||||
openHome: () => assetStoreHomePageState,
|
||||
openAssetSwapping: () => assetStoreHomePageState,
|
||||
clearHistory: () => {},
|
||||
clearPreviousPageFromHistory: () => {},
|
||||
openSearchResultPage: () => {},
|
||||
openTagPage: tag => {},
|
||||
openShopCategoryPage: category => {},
|
||||
openPackPage: ({ assetPack, previousSearchText }) => {},
|
||||
openAssetDetailPage: ({ assetShortHeader, previousSearchText }) => {},
|
||||
openPrivateAssetPackInformationPage: ({
|
||||
privateAssetPackListingData,
|
||||
previousSearchText,
|
||||
}) => {},
|
||||
openPrivateGameTemplateInformationPage: ({
|
||||
privateGameTemplateListingData,
|
||||
previousSearchText,
|
||||
}) => {},
|
||||
navigateInsideFolder: folder => {},
|
||||
goBackToFolderIndex: index => {},
|
||||
},
|
||||
currentPage: assetStoreHomePageState,
|
||||
useSearchItem: (searchText, chosenCategory, chosenFilters, searchFilters) =>
|
||||
null,
|
||||
@@ -167,7 +136,6 @@ export const AssetStoreContext = React.createContext<AssetStoreState>(
|
||||
);
|
||||
|
||||
type AssetStoreStateProviderProps = {|
|
||||
shopNavigationState: NavigationState,
|
||||
children: React.Node,
|
||||
|};
|
||||
|
||||
@@ -189,9 +157,11 @@ const getPrivateAssetPackListingDataSearchTerms = (
|
||||
) => privateAssetPack.name + '\n' + privateAssetPack.description;
|
||||
|
||||
export const AssetStoreStateProvider = ({
|
||||
shopNavigationState,
|
||||
children,
|
||||
}: AssetStoreStateProviderProps) => {
|
||||
const shopNavigationState = React.useContext(AssetStoreNavigatorContext);
|
||||
const { searchText } = shopNavigationState;
|
||||
|
||||
const [assetShortHeadersById, setAssetShortHeadersById] = React.useState<?{
|
||||
[string]: AssetShortHeader,
|
||||
}>(null);
|
||||
@@ -229,8 +199,6 @@ export const AssetStoreStateProvider = ({
|
||||
const initialPackOpened = React.useRef<boolean>(false);
|
||||
const { showAlert } = useAlertDialog();
|
||||
|
||||
const [searchText, setSearchText] = React.useState(defaultSearchText);
|
||||
|
||||
const [
|
||||
animatedFilter,
|
||||
setAnimatedFilter,
|
||||
@@ -403,7 +371,8 @@ export const AssetStoreStateProvider = ({
|
||||
if (assetPack) {
|
||||
shopNavigationState.openPackPage({
|
||||
assetPack,
|
||||
previousSearchText: searchText,
|
||||
storeSearchText: true,
|
||||
clearSearchText: false,
|
||||
});
|
||||
initialPackOpened.current = false; // Allow to open the pack again if the effect run again.
|
||||
setInitialPackUserFriendlySlug(null);
|
||||
@@ -421,7 +390,8 @@ export const AssetStoreStateProvider = ({
|
||||
if (privateAssetPackListingData) {
|
||||
shopNavigationState.openPrivateAssetPackInformationPage({
|
||||
privateAssetPackListingData,
|
||||
previousSearchText: searchText,
|
||||
storeSearchText: true,
|
||||
clearSearchText: false,
|
||||
});
|
||||
initialPackOpened.current = false; // Allow to open the pack again if the effect run again.
|
||||
setInitialPackUserFriendlySlug(null);
|
||||
@@ -441,7 +411,6 @@ export const AssetStoreStateProvider = ({
|
||||
shopNavigationState,
|
||||
showAlert,
|
||||
initialPackUserFriendlySlug,
|
||||
searchText,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -606,10 +575,7 @@ export const AssetStoreStateProvider = ({
|
||||
environment,
|
||||
setEnvironment,
|
||||
error,
|
||||
shopNavigationState,
|
||||
currentPage,
|
||||
searchText,
|
||||
setSearchText,
|
||||
assetFiltersState,
|
||||
assetPackFiltersState,
|
||||
clearAllFilters,
|
||||
@@ -643,9 +609,7 @@ export const AssetStoreStateProvider = ({
|
||||
licenses,
|
||||
environment,
|
||||
error,
|
||||
shopNavigationState,
|
||||
currentPage,
|
||||
searchText,
|
||||
assetFiltersState,
|
||||
assetPackFiltersState,
|
||||
clearAllFilters,
|
||||
|
@@ -22,6 +22,7 @@ import { type RGBColor } from '../Utils/ColorTransformer';
|
||||
import { HexColorField } from './HexColorField';
|
||||
import Slider from '../UI/Slider';
|
||||
import AuthenticatedUserContext from '../Profile/AuthenticatedUserContext';
|
||||
import { AssetStoreNavigatorContext } from './AssetStoreNavigator';
|
||||
|
||||
type Choice = {|
|
||||
label: React.Node,
|
||||
@@ -229,8 +230,9 @@ export const AssetStoreFilterPanel = ({
|
||||
assetFiltersState,
|
||||
assetPackFiltersState,
|
||||
clearAllFilters,
|
||||
shopNavigationState,
|
||||
} = React.useContext(AssetStoreContext);
|
||||
const shopNavigationState = React.useContext(AssetStoreNavigatorContext);
|
||||
|
||||
const { receivedAssetPacks } = React.useContext(AuthenticatedUserContext);
|
||||
const onChoiceChange = React.useCallback(
|
||||
() => {
|
||||
|
@@ -26,6 +26,8 @@ export type AssetStorePageState = {|
|
||||
|};
|
||||
|
||||
export type NavigationState = {|
|
||||
searchText: string,
|
||||
setSearchText: string => void,
|
||||
getCurrentPage: () => AssetStorePageState,
|
||||
isRootPage: boolean,
|
||||
backToPreviousPage: () => AssetStorePageState,
|
||||
@@ -38,19 +40,23 @@ export type NavigationState = {|
|
||||
openShopCategoryPage: string => void,
|
||||
openPackPage: ({|
|
||||
assetPack: PublicAssetPack | PrivateAssetPack,
|
||||
previousSearchText: string,
|
||||
storeSearchText: boolean,
|
||||
clearSearchText: boolean,
|
||||
|}) => void,
|
||||
openPrivateAssetPackInformationPage: ({|
|
||||
privateAssetPackListingData: PrivateAssetPackListingData,
|
||||
previousSearchText: string,
|
||||
storeSearchText: boolean,
|
||||
clearSearchText: boolean,
|
||||
|}) => void,
|
||||
openPrivateGameTemplateInformationPage: ({|
|
||||
privateGameTemplateListingData: PrivateGameTemplateListingData,
|
||||
previousSearchText: string,
|
||||
storeSearchText: boolean,
|
||||
clearSearchText: boolean,
|
||||
|}) => void,
|
||||
openAssetDetailPage: ({|
|
||||
assetShortHeader: AssetShortHeader,
|
||||
previousSearchText: string,
|
||||
storeSearchText: boolean,
|
||||
clearSearchText: boolean,
|
||||
|}) => void,
|
||||
navigateInsideFolder: string => void,
|
||||
goBackToFolderIndex: number => void,
|
||||
@@ -111,14 +117,44 @@ type AssetStorePageHistory = {|
|
||||
previousPages: Array<AssetStorePageState>,
|
||||
|};
|
||||
|
||||
export const useShopNavigation = (): NavigationState => {
|
||||
export const AssetStoreNavigatorContext = React.createContext<NavigationState>({
|
||||
searchText: '',
|
||||
setSearchText: () => {},
|
||||
getCurrentPage: () => assetStoreHomePageState,
|
||||
isRootPage: true,
|
||||
backToPreviousPage: () => assetStoreHomePageState,
|
||||
openHome: () => assetStoreHomePageState,
|
||||
openAssetSwapping: () => assetStoreHomePageState,
|
||||
clearHistory: () => {},
|
||||
clearPreviousPageFromHistory: () => {},
|
||||
openSearchResultPage: () => {},
|
||||
openTagPage: string => {},
|
||||
openShopCategoryPage: string => {},
|
||||
openPackPage: () => {},
|
||||
openPrivateAssetPackInformationPage: () => {},
|
||||
openPrivateGameTemplateInformationPage: () => {},
|
||||
openAssetDetailPage: () => {},
|
||||
navigateInsideFolder: string => {},
|
||||
goBackToFolderIndex: number => {},
|
||||
});
|
||||
|
||||
type AssetStoreNavigatorStateProviderProps = {|
|
||||
children: React.Node,
|
||||
|};
|
||||
|
||||
export const AssetStoreNavigatorStateProvider = (
|
||||
props: AssetStoreNavigatorStateProviderProps
|
||||
) => {
|
||||
const [searchText, setSearchText] = React.useState<string>('');
|
||||
const [history, setHistory] = React.useState<AssetStorePageHistory>({
|
||||
previousPages: [assetStoreHomePageState],
|
||||
});
|
||||
const previousPages = history.previousPages;
|
||||
|
||||
return React.useMemo(
|
||||
const state = React.useMemo(
|
||||
() => ({
|
||||
searchText,
|
||||
setSearchText,
|
||||
getCurrentPage: () => previousPages[previousPages.length - 1],
|
||||
isRootPage: previousPages.length <= 1,
|
||||
backToPreviousPage: () => {
|
||||
@@ -244,10 +280,12 @@ export const useShopNavigation = (): NavigationState => {
|
||||
},
|
||||
openPackPage: ({
|
||||
assetPack,
|
||||
previousSearchText,
|
||||
storeSearchText,
|
||||
clearSearchText,
|
||||
}: {|
|
||||
assetPack: PublicAssetPack | PrivateAssetPack,
|
||||
previousSearchText: string,
|
||||
storeSearchText: boolean,
|
||||
clearSearchText: boolean,
|
||||
|}) => {
|
||||
setHistory(previousHistory => {
|
||||
const currentPage =
|
||||
@@ -256,7 +294,7 @@ export const useShopNavigation = (): NavigationState => {
|
||||
];
|
||||
const currentPageWithSearchText = {
|
||||
...currentPage,
|
||||
searchText: previousSearchText,
|
||||
searchText: storeSearchText ? searchText : '',
|
||||
};
|
||||
const previousPagesWithoutCurrentPage = previousHistory.previousPages.slice(
|
||||
0,
|
||||
@@ -297,13 +335,16 @@ export const useShopNavigation = (): NavigationState => {
|
||||
],
|
||||
};
|
||||
});
|
||||
if (clearSearchText) setSearchText('');
|
||||
},
|
||||
openPrivateAssetPackInformationPage: ({
|
||||
privateAssetPackListingData,
|
||||
previousSearchText,
|
||||
storeSearchText,
|
||||
clearSearchText,
|
||||
}: {|
|
||||
privateAssetPackListingData: PrivateAssetPackListingData,
|
||||
previousSearchText: string,
|
||||
storeSearchText: boolean,
|
||||
clearSearchText: boolean,
|
||||
|}) => {
|
||||
setHistory(previousHistory => {
|
||||
const currentPage =
|
||||
@@ -312,7 +353,7 @@ export const useShopNavigation = (): NavigationState => {
|
||||
];
|
||||
const currentPageWithSearchText = {
|
||||
...currentPage,
|
||||
searchText: previousSearchText,
|
||||
searchText: storeSearchText ? searchText : '',
|
||||
};
|
||||
const previousPagesWithoutCurrentPage = previousHistory.previousPages.slice(
|
||||
0,
|
||||
@@ -339,13 +380,16 @@ export const useShopNavigation = (): NavigationState => {
|
||||
],
|
||||
};
|
||||
});
|
||||
if (clearSearchText) setSearchText('');
|
||||
},
|
||||
openAssetDetailPage: ({
|
||||
assetShortHeader,
|
||||
previousSearchText,
|
||||
storeSearchText,
|
||||
clearSearchText,
|
||||
}: {|
|
||||
assetShortHeader: AssetShortHeader,
|
||||
previousSearchText: string,
|
||||
storeSearchText: boolean,
|
||||
clearSearchText: boolean,
|
||||
|}) => {
|
||||
setHistory(previousHistory => {
|
||||
const currentPage =
|
||||
@@ -354,7 +398,7 @@ export const useShopNavigation = (): NavigationState => {
|
||||
];
|
||||
const currentPageWithSearchText = {
|
||||
...currentPage,
|
||||
searchText: previousSearchText,
|
||||
searchText: storeSearchText ? searchText : '',
|
||||
};
|
||||
const previousPagesWithoutCurrentPage = previousHistory.previousPages.slice(
|
||||
0,
|
||||
@@ -381,13 +425,16 @@ export const useShopNavigation = (): NavigationState => {
|
||||
],
|
||||
};
|
||||
});
|
||||
if (clearSearchText) setSearchText('');
|
||||
},
|
||||
openPrivateGameTemplateInformationPage: ({
|
||||
privateGameTemplateListingData,
|
||||
previousSearchText,
|
||||
storeSearchText,
|
||||
clearSearchText,
|
||||
}: {|
|
||||
privateGameTemplateListingData: PrivateGameTemplateListingData,
|
||||
previousSearchText: string,
|
||||
storeSearchText: boolean,
|
||||
clearSearchText: boolean,
|
||||
|}) => {
|
||||
setHistory(previousHistory => {
|
||||
const currentPage =
|
||||
@@ -396,7 +443,7 @@ export const useShopNavigation = (): NavigationState => {
|
||||
];
|
||||
const currentPageWithSearchText = {
|
||||
...currentPage,
|
||||
searchText: previousSearchText,
|
||||
searchText: storeSearchText ? searchText : '',
|
||||
};
|
||||
const previousPagesWithoutCurrentPage = previousHistory.previousPages.slice(
|
||||
0,
|
||||
@@ -423,6 +470,7 @@ export const useShopNavigation = (): NavigationState => {
|
||||
],
|
||||
};
|
||||
});
|
||||
if (clearSearchText) setSearchText('');
|
||||
},
|
||||
navigateInsideFolder: (folderTag: string) => {
|
||||
setHistory(previousHistory => {
|
||||
@@ -476,6 +524,12 @@ export const useShopNavigation = (): NavigationState => {
|
||||
});
|
||||
},
|
||||
}),
|
||||
[previousPages]
|
||||
[searchText, previousPages]
|
||||
);
|
||||
|
||||
return (
|
||||
<AssetStoreNavigatorContext.Provider value={state}>
|
||||
{props.children}
|
||||
</AssetStoreNavigatorContext.Provider>
|
||||
);
|
||||
};
|
||||
|
@@ -6,7 +6,6 @@ import Dialog from '../UI/Dialog';
|
||||
import FlatButton from '../UI/FlatButton';
|
||||
import { AssetStore, type AssetStoreInterface } from '.';
|
||||
import { type ResourceManagementProps } from '../ResourcesList/ResourceSource';
|
||||
import { AssetStoreContext } from './AssetStoreContext';
|
||||
import ErrorBoundary from '../UI/ErrorBoundary';
|
||||
import LoaderModal from '../UI/LoaderModal';
|
||||
import { useInstallAsset } from './NewObjectDialog';
|
||||
@@ -14,6 +13,7 @@ import { swapAsset } from './AssetSwapper';
|
||||
import PixiResourcesLoader from '../ObjectsRendering/PixiResourcesLoader';
|
||||
import useAlertDialog from '../UI/Alert/useAlertDialog';
|
||||
import RaisedButton from '../UI/RaisedButton';
|
||||
import { AssetStoreNavigatorContext } from './AssetStoreNavigator';
|
||||
|
||||
type Props = {|
|
||||
project: gdProject,
|
||||
@@ -37,7 +37,7 @@ function AssetSwappingDialog({
|
||||
onClose,
|
||||
minimalUI,
|
||||
}: Props) {
|
||||
const { shopNavigationState } = React.useContext(AssetStoreContext);
|
||||
const shopNavigationState = React.useContext(AssetStoreNavigatorContext);
|
||||
const { openedAssetShortHeader } = shopNavigationState.getCurrentPage();
|
||||
|
||||
const [
|
||||
|
@@ -42,6 +42,7 @@ import { getAssetShortHeadersToDisplay } from './AssetsList';
|
||||
import ErrorBoundary from '../UI/ErrorBoundary';
|
||||
import type { ObjectFolderOrObjectWithContext } from '../ObjectsList/EnumerateObjectFolderOrObject';
|
||||
import LoaderModal from '../UI/LoaderModal';
|
||||
import { AssetStoreNavigatorContext } from './AssetStoreNavigator';
|
||||
|
||||
const isDev = Window.isDev();
|
||||
|
||||
@@ -130,7 +131,7 @@ export const useInstallAsset = ({
|
||||
targetObjectFolderOrObjectWithContext?: ?ObjectFolderOrObjectWithContext,
|
||||
resourceManagementProps: ResourceManagementProps,
|
||||
|}) => {
|
||||
const { shopNavigationState } = React.useContext(AssetStoreContext);
|
||||
const shopNavigationState = React.useContext(AssetStoreNavigatorContext);
|
||||
const { openedAssetPack } = shopNavigationState.getCurrentPage();
|
||||
const eventsFunctionsExtensionsState = React.useContext(
|
||||
EventsFunctionsExtensionsContext
|
||||
@@ -261,10 +262,10 @@ function NewObjectDialog({
|
||||
|
||||
const {
|
||||
assetShortHeadersSearchResults,
|
||||
shopNavigationState,
|
||||
environment,
|
||||
setEnvironment,
|
||||
} = React.useContext(AssetStoreContext);
|
||||
const shopNavigationState = React.useContext(AssetStoreNavigatorContext);
|
||||
const {
|
||||
openedAssetPack,
|
||||
openedAssetShortHeader,
|
||||
|
@@ -12,7 +12,7 @@ import {
|
||||
type PrivateGameTemplateListingData,
|
||||
} from '../../Utils/GDevelopServices/Shop';
|
||||
import { capitalize } from 'lodash';
|
||||
import { type NavigationState } from '../AssetStoreNavigator';
|
||||
import { AssetStoreNavigatorContext } from '../AssetStoreNavigator';
|
||||
import { getPrivateGameTemplateListingDataFromUserFriendlySlug } from '../AssetStoreUtils';
|
||||
import useAlertDialog from '../../UI/Alert/useAlertDialog';
|
||||
import { t } from '@lingui/macro';
|
||||
@@ -40,8 +40,6 @@ type PrivateGameTemplateStoreState = {|
|
||||
error: ?Error,
|
||||
shop: {
|
||||
privateGameTemplateListingDatasSearchResults: ?Array<PrivateGameTemplateListingData>,
|
||||
searchText: string,
|
||||
setSearchText: string => void,
|
||||
filtersState: FiltersState,
|
||||
setInitialGameTemplateUserFriendlySlug: string => void,
|
||||
},
|
||||
@@ -63,8 +61,6 @@ export const initialPrivateGameTemplateStoreState: PrivateGameTemplateStoreState
|
||||
error: null,
|
||||
shop: {
|
||||
privateGameTemplateListingDatasSearchResults: null,
|
||||
searchText: '',
|
||||
setSearchText: () => {},
|
||||
filtersState: {
|
||||
chosenFilters: new Set(),
|
||||
addFilter: () => {},
|
||||
@@ -95,14 +91,17 @@ export const PrivateGameTemplateStoreContext = React.createContext<PrivateGameTe
|
||||
);
|
||||
|
||||
type PrivateGameTemplateStoreStateProviderProps = {|
|
||||
shopNavigationState: NavigationState,
|
||||
children: React.Node,
|
||||
|};
|
||||
|
||||
export const PrivateGameTemplateStoreStateProvider = ({
|
||||
shopNavigationState,
|
||||
children,
|
||||
}: PrivateGameTemplateStoreStateProviderProps) => {
|
||||
const shopNavigationState = React.useContext(AssetStoreNavigatorContext);
|
||||
const {
|
||||
searchText: shopSearchText,
|
||||
setSearchText: setShopSearchText,
|
||||
} = shopNavigationState;
|
||||
const { limits } = React.useContext(AuthenticatedUserContext);
|
||||
|
||||
const [
|
||||
@@ -123,7 +122,6 @@ export const PrivateGameTemplateStoreStateProvider = ({
|
||||
const isLoading = React.useRef<boolean>(false);
|
||||
const { showAlert } = useAlertDialog();
|
||||
|
||||
const [shopSearchText, setShopSearchText] = React.useState(defaultSearchText);
|
||||
const [exampleStoreSearchText, setExampleStoreSearchText] = React.useState(
|
||||
defaultSearchText
|
||||
);
|
||||
@@ -224,7 +222,8 @@ export const PrivateGameTemplateStoreStateProvider = ({
|
||||
});
|
||||
shopNavigationState.openPrivateGameTemplateInformationPage({
|
||||
privateGameTemplateListingData,
|
||||
previousSearchText: shopSearchText,
|
||||
storeSearchText: true,
|
||||
clearSearchText: false,
|
||||
});
|
||||
initialGameTemplateOpened.current = false; // Allow to open the game template again if the effect run again.
|
||||
setInitialGameTemplateUserFriendlySlug(null);
|
||||
@@ -242,7 +241,6 @@ export const PrivateGameTemplateStoreStateProvider = ({
|
||||
shopNavigationState,
|
||||
showAlert,
|
||||
initialGameTemplateUserFriendlySlug,
|
||||
shopSearchText,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -341,6 +339,7 @@ export const PrivateGameTemplateStoreStateProvider = ({
|
||||
privateGameTemplateListingDatasSearchResultsForExampleStore,
|
||||
privateGameTemplateListingDatasSearchResultsForShop,
|
||||
shopSearchText,
|
||||
setShopSearchText,
|
||||
exampleStoreSearchText,
|
||||
currentPage.filtersState,
|
||||
filtersStateForExampleStore,
|
||||
|
@@ -47,6 +47,7 @@ import AlertMessage from '../UI/AlertMessage';
|
||||
import AuthenticatedUserContext from '../Profile/AuthenticatedUserContext';
|
||||
import { LineStackLayout } from '../UI/Layout';
|
||||
import {
|
||||
AssetStoreNavigatorContext,
|
||||
isHomePage,
|
||||
isSearchResultPage,
|
||||
type AssetStorePageState,
|
||||
@@ -121,14 +122,17 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
|
||||
privateAssetPackListingDatas,
|
||||
error: assetStoreError,
|
||||
fetchAssetsAndFilters,
|
||||
shopNavigationState,
|
||||
searchText,
|
||||
setSearchText: setAssetStoreSearchText,
|
||||
clearAllFilters: clearAllAssetStoreFilters,
|
||||
assetFiltersState,
|
||||
getAssetShortHeaderFromId,
|
||||
} = React.useContext(AssetStoreContext);
|
||||
|
||||
const shopNavigationState = React.useContext(AssetStoreNavigatorContext);
|
||||
const {
|
||||
searchText,
|
||||
setSearchText: setAssetStoreSearchText,
|
||||
} = shopNavigationState;
|
||||
|
||||
const assetSwappedObjectPtr = React.useRef<number | null>(null);
|
||||
React.useEffect(
|
||||
() => {
|
||||
@@ -169,10 +173,7 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
|
||||
privateGameTemplateListingDatas,
|
||||
error: privateGameTemplateStoreError,
|
||||
fetchGameTemplates,
|
||||
shop: {
|
||||
privateGameTemplateListingDatasSearchResults,
|
||||
setSearchText: setPrivateGameTemplateSearchText,
|
||||
},
|
||||
shop: { privateGameTemplateListingDatasSearchResults },
|
||||
} = React.useContext(PrivateGameTemplateStoreContext);
|
||||
const currentPage = shopNavigationState.getCurrentPage();
|
||||
const {
|
||||
@@ -226,9 +227,8 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
|
||||
const setSearchText = React.useCallback(
|
||||
(newSearchText: string) => {
|
||||
setAssetStoreSearchText(newSearchText);
|
||||
setPrivateGameTemplateSearchText(newSearchText);
|
||||
},
|
||||
[setAssetStoreSearchText, setPrivateGameTemplateSearchText]
|
||||
[setAssetStoreSearchText]
|
||||
);
|
||||
|
||||
const fetchAssetsAndGameTemplates = React.useCallback(
|
||||
@@ -344,12 +344,10 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
|
||||
assetPackKind,
|
||||
});
|
||||
saveScrollPosition();
|
||||
const previousSearchText = searchText;
|
||||
// Don't reset search text when opening an asset as the search bar is not active.
|
||||
// This helps speeding up the navigation when going back to the results page.
|
||||
shopNavigationState.openAssetDetailPage({
|
||||
assetShortHeader,
|
||||
previousSearchText,
|
||||
storeSearchText: true,
|
||||
clearSearchText: false,
|
||||
});
|
||||
},
|
||||
[
|
||||
@@ -358,7 +356,6 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
|
||||
privateAssetPackListingDatas,
|
||||
saveScrollPosition,
|
||||
shopNavigationState,
|
||||
searchText,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -378,19 +375,15 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
|
||||
Window.openExternalURL(assetPack.externalWebLink);
|
||||
} else {
|
||||
saveScrollPosition();
|
||||
const previousSearchText = searchText;
|
||||
setSearchText(''); // Reset search text when opening a pack.
|
||||
shopNavigationState.openPackPage({ assetPack, previousSearchText });
|
||||
shopNavigationState.openPackPage({
|
||||
assetPack,
|
||||
storeSearchText: true,
|
||||
clearSearchText: true,
|
||||
});
|
||||
openFiltersPanelIfAppropriate();
|
||||
}
|
||||
},
|
||||
[
|
||||
shopNavigationState,
|
||||
searchText,
|
||||
saveScrollPosition,
|
||||
setSearchText,
|
||||
openFiltersPanelIfAppropriate,
|
||||
]
|
||||
[shopNavigationState, saveScrollPosition, openFiltersPanelIfAppropriate]
|
||||
);
|
||||
|
||||
// When a private pack is selected from the home page,
|
||||
@@ -417,11 +410,10 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
|
||||
assetPackKind: 'private',
|
||||
});
|
||||
saveScrollPosition();
|
||||
const previousSearchText = searchText;
|
||||
setSearchText(''); // Reset search text when opening a pack.
|
||||
shopNavigationState.openPrivateAssetPackInformationPage({
|
||||
privateAssetPackListingData,
|
||||
previousSearchText,
|
||||
storeSearchText: true,
|
||||
clearSearchText: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -435,11 +427,10 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
|
||||
source: 'store-home',
|
||||
});
|
||||
saveScrollPosition();
|
||||
const previousSearchText = searchText;
|
||||
setSearchText(''); // Reset search text when opening a pack.
|
||||
shopNavigationState.openPackPage({
|
||||
assetPack: receivedAssetPack,
|
||||
previousSearchText,
|
||||
storeSearchText: true,
|
||||
clearSearchText: true,
|
||||
});
|
||||
openFiltersPanelIfAppropriate();
|
||||
},
|
||||
@@ -447,9 +438,7 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
|
||||
receivedAssetPacks,
|
||||
saveScrollPosition,
|
||||
shopNavigationState,
|
||||
setSearchText,
|
||||
openFiltersPanelIfAppropriate,
|
||||
searchText,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -475,14 +464,13 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
|
||||
source: 'store',
|
||||
});
|
||||
saveScrollPosition();
|
||||
const previousSearchText = searchText;
|
||||
setSearchText(''); // Reset search text when opening a template.
|
||||
shopNavigationState.openPrivateGameTemplateInformationPage({
|
||||
privateGameTemplateListingData,
|
||||
previousSearchText,
|
||||
storeSearchText: true,
|
||||
clearSearchText: true,
|
||||
});
|
||||
},
|
||||
[saveScrollPosition, setSearchText, searchText, shopNavigationState]
|
||||
[saveScrollPosition, shopNavigationState]
|
||||
);
|
||||
|
||||
const selectShopCategory = React.useCallback(
|
||||
@@ -505,16 +493,17 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
|
||||
publicAssetPacks &&
|
||||
publicAssetPacks.starterPacks.find(pack => pack.tag === tag);
|
||||
saveScrollPosition();
|
||||
setSearchText('');
|
||||
if (privateAssetPack) {
|
||||
shopNavigationState.openPackPage({
|
||||
assetPack: privateAssetPack,
|
||||
previousSearchText: '', // We were on an asset page.
|
||||
storeSearchText: false,
|
||||
clearSearchText: true,
|
||||
});
|
||||
} else if (publicAssetPack) {
|
||||
shopNavigationState.openPackPage({
|
||||
assetPack: publicAssetPack,
|
||||
previousSearchText: '', // We were on an asset page.
|
||||
storeSearchText: false,
|
||||
clearSearchText: true,
|
||||
});
|
||||
} else {
|
||||
shopNavigationState.openTagPage(tag);
|
||||
@@ -523,7 +512,6 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
|
||||
openFiltersPanelIfAppropriate();
|
||||
},
|
||||
[
|
||||
setSearchText,
|
||||
receivedAssetPacks,
|
||||
publicAssetPacks,
|
||||
saveScrollPosition,
|
||||
|
@@ -27,10 +27,11 @@ import Button from '@material-ui/core/Button';
|
||||
import ButtonGroup from '@material-ui/core/ButtonGroup';
|
||||
import InputAdornment from '@material-ui/core/InputAdornment';
|
||||
import Tooltip from '@material-ui/core/Tooltip';
|
||||
import CircledInfo from '../../../UI/CustomSvgIcons/SmallCircledInfo';
|
||||
|
||||
type Props = BehaviorEditorProps;
|
||||
|
||||
const NumericProperty = (props: {|
|
||||
export const NumericProperty = (props: {|
|
||||
id?: string,
|
||||
properties: gdMapStringPropertyDescriptor,
|
||||
propertyName: string,
|
||||
@@ -55,9 +56,24 @@ const NumericProperty = (props: {|
|
||||
);
|
||||
};
|
||||
|
||||
const UnitAdornment = (props: {| property: gdPropertyDescriptor |}) => {
|
||||
export const UnitAdornment = (props: {| property: gdPropertyDescriptor |}) => {
|
||||
const { property } = props;
|
||||
const measurementUnit = property.getMeasurementUnit();
|
||||
if (measurementUnit.isUndefined() && property.getDescription()) {
|
||||
return (
|
||||
<Tooltip
|
||||
title={
|
||||
<MeasurementUnitDocumentation
|
||||
label={property.getLabel()}
|
||||
description={property.getDescription()}
|
||||
elementsWithWords={''}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<InputAdornment position="end">{<CircledInfo />}</InputAdornment>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Tooltip
|
||||
title={
|
||||
@@ -220,11 +236,13 @@ const Physics2Editor = (props: Props) => {
|
||||
value={properties.get('shapeDimensionA').getValue()}
|
||||
key={'shapeDimensionA'}
|
||||
floatingLabelText={
|
||||
shape === 'Circle'
|
||||
? 'Radius'
|
||||
: shape === 'Edge'
|
||||
? 'Length'
|
||||
: 'Width'
|
||||
shape === 'Circle' ? (
|
||||
<Trans>Radius</Trans>
|
||||
) : shape === 'Edge' ? (
|
||||
<Trans>Length</Trans>
|
||||
) : (
|
||||
<Trans>Width</Trans>
|
||||
)
|
||||
}
|
||||
min={0}
|
||||
onChange={newValue =>
|
||||
@@ -241,7 +259,9 @@ const Physics2Editor = (props: Props) => {
|
||||
fullWidth
|
||||
value={properties.get('shapeDimensionB').getValue()}
|
||||
key={'shapeDimensionB'}
|
||||
floatingLabelText={shape === 'Edge' ? 'Angle' : 'Height'}
|
||||
floatingLabelText={
|
||||
shape === 'Edge' ? <Trans>Angle</Trans> : <Trans>Height</Trans>
|
||||
}
|
||||
min={shape === 'Edge' ? undefined : 0}
|
||||
onChange={newValue =>
|
||||
updateBehaviorProperty('shapeDimensionB', newValue)
|
||||
|
@@ -8,8 +8,6 @@ import Checkbox from '../../../UI/Checkbox';
|
||||
import SelectField from '../../../UI/SelectField';
|
||||
import SelectOption from '../../../UI/SelectOption';
|
||||
import SemiControlledTextField from '../../../UI/SemiControlledTextField';
|
||||
import { getMeasurementUnitShortLabel } from '../../../PropertiesEditor/PropertiesMapToSchema';
|
||||
import MeasurementUnitDocumentation from '../../../PropertiesEditor/MeasurementUnitDocumentation';
|
||||
import { type BehaviorEditorProps } from '../BehaviorEditorProps.flow';
|
||||
import Text from '../../../UI/Text';
|
||||
import DismissableAlertMessage from '../../../UI/DismissableAlertMessage';
|
||||
@@ -17,56 +15,10 @@ import { ResponsiveLineStackLayout } from '../../../UI/Layout';
|
||||
import useForceUpdate from '../../../Utils/UseForceUpdate';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import ButtonGroup from '@material-ui/core/ButtonGroup';
|
||||
import InputAdornment from '@material-ui/core/InputAdornment';
|
||||
import Tooltip from '@material-ui/core/Tooltip';
|
||||
import { NumericProperty, UnitAdornment } from '../Physics2Editor';
|
||||
|
||||
type Props = BehaviorEditorProps;
|
||||
|
||||
const NumericProperty = (props: {|
|
||||
id?: string,
|
||||
properties: gdMapStringPropertyDescriptor,
|
||||
propertyName: string,
|
||||
step: number,
|
||||
onUpdate: (newValue: string) => void,
|
||||
|}) => {
|
||||
const { properties, propertyName, step, onUpdate, id } = props;
|
||||
const property = properties.get(propertyName);
|
||||
|
||||
return (
|
||||
<SemiControlledTextField
|
||||
id={id}
|
||||
fullWidth
|
||||
value={property.getValue()}
|
||||
key={propertyName}
|
||||
floatingLabelText={property.getLabel()}
|
||||
step={step}
|
||||
onChange={onUpdate}
|
||||
type="number"
|
||||
endAdornment={<UnitAdornment property={property} />}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const UnitAdornment = (props: {| property: gdPropertyDescriptor |}) => {
|
||||
const { property } = props;
|
||||
const measurementUnit = property.getMeasurementUnit();
|
||||
return (
|
||||
<Tooltip
|
||||
title={
|
||||
<MeasurementUnitDocumentation
|
||||
label={measurementUnit.getLabel()}
|
||||
description={measurementUnit.getDescription()}
|
||||
elementsWithWords={measurementUnit.getElementsWithWords()}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<InputAdornment position="end">
|
||||
{getMeasurementUnitShortLabel(measurementUnit)}
|
||||
</InputAdornment>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
const BitGroupEditor = (props: {|
|
||||
bits: Array<boolean>,
|
||||
onChange: (index: number, value: boolean) => void,
|
||||
@@ -227,7 +179,9 @@ const Physics3DEditor = (props: Props) => {
|
||||
fullWidth
|
||||
value={properties.get('shapeDimensionA').getValue()}
|
||||
key={'shapeDimensionA'}
|
||||
floatingLabelText={shape === 'Box' ? 'Width' : 'Radius'}
|
||||
floatingLabelText={
|
||||
shape === 'Box' ? <Trans>Width</Trans> : <Trans>Radius</Trans>
|
||||
}
|
||||
min={0}
|
||||
onChange={newValue =>
|
||||
updateBehaviorProperty('shapeDimensionA', newValue)
|
||||
@@ -242,7 +196,9 @@ const Physics3DEditor = (props: Props) => {
|
||||
fullWidth
|
||||
value={properties.get('shapeDimensionB').getValue()}
|
||||
key={'shapeDimensionB'}
|
||||
floatingLabelText={shape === 'Box' ? 'Width' : 'Depth'}
|
||||
floatingLabelText={
|
||||
shape === 'Box' ? <Trans>Height</Trans> : <Trans>Depth</Trans>
|
||||
}
|
||||
min={0}
|
||||
onChange={newValue =>
|
||||
updateBehaviorProperty('shapeDimensionB', newValue)
|
||||
@@ -258,7 +214,7 @@ const Physics3DEditor = (props: Props) => {
|
||||
fullWidth
|
||||
value={properties.get('shapeDimensionC').getValue()}
|
||||
key={'shapeDimensionC'}
|
||||
floatingLabelText={'Depth'}
|
||||
floatingLabelText={<Trans>Depth</Trans>}
|
||||
min={0}
|
||||
onChange={newValue =>
|
||||
updateBehaviorProperty('shapeDimensionC', newValue)
|
||||
|
@@ -4,6 +4,16 @@ import optionalRequire from '../Utils/OptionalRequire';
|
||||
const fs = optionalRequire('fs');
|
||||
const path = optionalRequire('path');
|
||||
|
||||
// Avoid conflicts in declaration of PIXI and THREE namespaces.
|
||||
const excludedFiles = [
|
||||
'global-three.d.ts',
|
||||
'global-pixi.d.ts',
|
||||
'pixi-particles-pixi-renderer.d.ts',
|
||||
'pixi-tilemap.d.ts',
|
||||
'pixi.js',
|
||||
'three.js',
|
||||
];
|
||||
|
||||
export const setupAutocompletions = (monaco: any) => {
|
||||
const importAllJsFilesFromFolder = (folderPath: string) =>
|
||||
fs.readdir(folderPath, (error: ?Error, filenames: Array<string>) => {
|
||||
@@ -21,6 +31,7 @@ export const setupAutocompletions = (monaco: any) => {
|
||||
.isDirectory();
|
||||
if (
|
||||
(filename.endsWith('.ts') || filename.endsWith('.js')) &&
|
||||
!excludedFiles.includes(filename) &&
|
||||
// Dialogue tree uses a folder called `bondage.js` that should not be read as a file.
|
||||
!isDirectory
|
||||
) {
|
||||
@@ -43,6 +54,40 @@ export const setupAutocompletions = (monaco: any) => {
|
||||
});
|
||||
});
|
||||
|
||||
const importAllJsFilesFromFolderRecursively = (folderPath: string) =>
|
||||
fs.readdir(folderPath, (error: ?Error, filenames: Array<string>) => {
|
||||
if (error) {
|
||||
console.error(
|
||||
'Unable to read GDJS files for setting up autocompletions:',
|
||||
error
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
filenames.forEach(filename => {
|
||||
const fullPath = path.join(folderPath, filename);
|
||||
const isDirectory = fs.lstatSync(fullPath).isDirectory();
|
||||
if (isDirectory) {
|
||||
importAllJsFilesFromFolderRecursively(fullPath);
|
||||
} else if (filename.endsWith('.ts') || filename.endsWith('.js')) {
|
||||
fs.readFile(fullPath, 'utf8', (fileError, content) => {
|
||||
if (fileError) {
|
||||
console.error(
|
||||
`Unable to read ${fullPath} for setting up autocompletions:`,
|
||||
fileError
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
monaco.languages.typescript.javascriptDefaults.addExtraLib(
|
||||
content,
|
||||
fullPath
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
findGDJS().then(({ gdjsRoot }) => {
|
||||
// Autocompletions are generated by reading the sources of the game engine
|
||||
// (much like how autocompletions work in Visual Studio Code) - *not* the built files.
|
||||
@@ -66,6 +111,8 @@ export const setupAutocompletions = (monaco: any) => {
|
||||
);
|
||||
const extensionsPath = path.join(runtimePath, 'Extensions');
|
||||
const eventToolsPath = path.join(runtimePath, 'events-tools');
|
||||
const threeTypesPath = path.join(runtimeTypesPath, 'three');
|
||||
const pixiTypesPath = path.join(runtimeTypesPath, 'pixi');
|
||||
|
||||
importAllJsFilesFromFolder(runtimePath);
|
||||
importAllJsFilesFromFolder(runtimeTypesPath);
|
||||
@@ -74,6 +121,9 @@ export const setupAutocompletions = (monaco: any) => {
|
||||
importAllJsFilesFromFolder(runtimeHowlerSoundManagerPath);
|
||||
importAllJsFilesFromFolder(runtimeFontfaceobserverFontManagerPath);
|
||||
importAllJsFilesFromFolder(eventToolsPath);
|
||||
importAllJsFilesFromFolderRecursively(threeTypesPath);
|
||||
importAllJsFilesFromFolderRecursively(pixiTypesPath);
|
||||
|
||||
fs.readdir(extensionsPath, (error: ?Error, folderNames: Array<string>) => {
|
||||
if (error) {
|
||||
console.error(
|
||||
|
@@ -72,7 +72,8 @@ export class CodeEditor extends React.Component<Props, State> {
|
||||
|
||||
// Enable type checking of JavaScript files
|
||||
monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
|
||||
...monaco.languages.typescript.javascriptDefaults.getCompilerOptions(),
|
||||
// TODO: Uncomment to activate type checking of JS files, once autocompletions are all handled properly.
|
||||
// ...monaco.languages.typescript.javascriptDefaults.getCompilerOptions()
|
||||
target: monaco.languages.typescript.ScriptTarget.ES6,
|
||||
allowNonTsExtensions: true,
|
||||
allowJs: true,
|
||||
@@ -82,12 +83,15 @@ export class CodeEditor extends React.Component<Props, State> {
|
||||
// Activate checks - though this won't work for .d.ts classes/funcions for
|
||||
// some reason. See:
|
||||
// https://microsoft.github.io/monaco-editor/playground.html?source=v0.52.0#XQAAAALxBQAAAAAAAABBqQkHQ5NjdMjwa-jY7SIQ9S7DNlzs5W-mwj0fe1ZCDRFc9ws9XQE0SJE1jc2VKxhaLFIw9vEWSxW3yscw90T9lfa8wm3bKzPN7npWhYaA4x4rxLXXBbB2_OnRSToJ21hOUR_hS9pG2m6stSYmFVtipRHVTrIB91DOr8dFz_2f6wKJhg_ghHcsBt-hKnlu-qt2H4NuwdaqfbMd6vqkrLY5fzdHCB8FZIGGUDanilP6QXPTpV0rme8fvINUj2BklEotLylw-HHch53nHQMCabAMh3iNqg8S_rHB5OZg2IxLB-8POziUzSwFrTcfwxftX7gi3ZIWNPyf4vJOFtRKVr3hJLIKUGJew4RN0hYb1SnPUm1x6B8hb8I5-9WqAgbYz6E0ntlpOU4jvw6zty4iIJ4GQFuyQ1ys6LtVNKef1bnBs7fDr3xFb3LOW7E4RMonCTxapW3_DQvpQ_x4psM1GYFKMZZXr0lCRvrFs4PBf0uXMwEeTfC1PurLOeoNNEEZFLutUE1ojQVjkTgxZC_HCheas9sKTtZRsJ0i6qDWJh3PbNocPFIbvPQ5la2NXuQIph1oaGrDjqgoirRoexyKumFnXVLkvKVoTdglfgXLwEaoheNdItwJfWKdPqmHh18GTsk8Df_mr8zt3r-pLUtNvB6220ZAKaswAMPR0yDrfHfz_7vWaBfDy6yykp-ROV0Ckt2qV83DVNrHW9HNm4e0WC1ByFoDOB8AdJzjQye8YD3aCwy8ft4sSOGvSeNo2FOPoqd2TU-Sr58fhP09rWes4Vgrv1MhMlUtZ5zBNSL_Mpb1R32H8hrNShgxxaT0r048_u6-nFbkNKq-VCjTlFuUoTW-3y8b1UrYxSmTkjmp-KCc9ObqKgzbRV5tPIX_sqYqVCJFOZN0Nndp4s6xm7qmVPi8SMcDfCD4zfPWBpanAohwTcIIbXPJqggntHxMUFvH7h85mh3AZoJ5FPz2v387LTrxdqOZZW7kTGqSl-Y8NHsa_znjlaNDOU-qywr5DypPbH3_wOm2XMeQNg0jX1bBtIoh_PG5BWMQNlJmQRlDnmDtueZf_nTzQw
|
||||
monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
|
||||
...monaco.languages.typescript.javascriptDefaults.getDiagnosticsOptions(),
|
||||
noSemanticValidation: false,
|
||||
noSuggestionDiagnostics: false,
|
||||
noSyntaxValidation: false,
|
||||
});
|
||||
//
|
||||
// TODO: Uncomment to activate type checking of JS files, once autocompletions are all handled properly.
|
||||
//
|
||||
// monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
|
||||
// ...monaco.languages.typescript.javascriptDefaults.getDiagnosticsOptions(),
|
||||
// noSemanticValidation: false,
|
||||
// noSuggestionDiagnostics: false,
|
||||
// noSyntaxValidation: false,
|
||||
// });
|
||||
|
||||
setupAutocompletions(monaco);
|
||||
}
|
||||
|
@@ -234,6 +234,42 @@ const createField = (
|
||||
getDescription,
|
||||
hasImpactOnAllOtherFields: property.hasImpactOnOtherProperties(),
|
||||
};
|
||||
} else if (valueType === 'animationname') {
|
||||
return {
|
||||
getChoices: () => {
|
||||
if (!object) {
|
||||
return [];
|
||||
}
|
||||
const animationArray = mapFor(
|
||||
0,
|
||||
object.getConfiguration().getAnimationsCount(),
|
||||
i => {
|
||||
const animationName = object.getConfiguration().getAnimationName(i);
|
||||
if (animationName === '') {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
value: animationName,
|
||||
label: animationName,
|
||||
};
|
||||
}
|
||||
).filter(Boolean);
|
||||
animationArray.push({ value: '', label: '(no animation)' });
|
||||
return animationArray;
|
||||
},
|
||||
name,
|
||||
valueType: 'string',
|
||||
getValue: (instance: Instance): string => {
|
||||
return getProperties(instance)
|
||||
.get(name)
|
||||
.getValue();
|
||||
},
|
||||
setValue: (instance: Instance, newValue: string) => {
|
||||
onUpdateProperty(instance, name, newValue);
|
||||
},
|
||||
getLabel,
|
||||
getDescription,
|
||||
};
|
||||
} else {
|
||||
console.error(
|
||||
`A property with type=${valueType} could not be mapped to a field. Ensure that this type is correct and understood by the IDE.`
|
||||
|
@@ -729,6 +729,11 @@ export default function EventsBasedBehaviorPropertiesEditor({
|
||||
value="Boolean"
|
||||
label={t`Boolean (checkbox)`}
|
||||
/>
|
||||
<SelectOption
|
||||
key="property-type-animationname"
|
||||
value="AnimationName"
|
||||
label={t`Animation name (text)`}
|
||||
/>
|
||||
<SelectOption
|
||||
key="property-type-choice"
|
||||
value="Choice"
|
||||
@@ -802,7 +807,9 @@ export default function EventsBasedBehaviorPropertiesEditor({
|
||||
</SelectField>
|
||||
)}
|
||||
{(property.getType() === 'String' ||
|
||||
property.getType() === 'Number') && (
|
||||
property.getType() === 'Number' ||
|
||||
property.getType() ===
|
||||
'AnimationName') && (
|
||||
<SemiControlledTextField
|
||||
commitOnBlur
|
||||
floatingLabelText={
|
||||
|
@@ -178,6 +178,18 @@ export default function EventsBasedBehaviorEditor({
|
||||
if (onConfigurationUpdated) onConfigurationUpdated('isPrivate');
|
||||
onChange();
|
||||
}}
|
||||
tooltipOrHelperText={
|
||||
eventsBasedBehavior.isPrivate() ? (
|
||||
<Trans>
|
||||
This behavior won't be visible in the scene and events
|
||||
editors.
|
||||
</Trans>
|
||||
) : (
|
||||
<Trans>
|
||||
This behavior will be visible in the scene and events editors.
|
||||
</Trans>
|
||||
)
|
||||
}
|
||||
/>
|
||||
{eventsBasedBehavior
|
||||
.getEventsFunctions()
|
||||
|
@@ -141,6 +141,26 @@ export default function EventsBasedObjectEditor({
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Checkbox
|
||||
label={<Trans>Private</Trans>}
|
||||
checked={eventsBasedObject.isPrivate()}
|
||||
onCheck={(e, checked) => {
|
||||
eventsBasedObject.setPrivate(checked);
|
||||
onChange();
|
||||
onEventsBasedObjectChildrenEdited();
|
||||
}}
|
||||
tooltipOrHelperText={
|
||||
eventsBasedObject.isPrivate() ? (
|
||||
<Trans>
|
||||
This object won't be visible in the scene and events editors.
|
||||
</Trans>
|
||||
) : (
|
||||
<Trans>
|
||||
This object will be visible in the scene and events editors.
|
||||
</Trans>
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Line noMargin justifyContent="center">
|
||||
<RaisedButton
|
||||
label={<Trans>Open visual editor for the object</Trans>}
|
||||
|
@@ -529,6 +529,17 @@ export const EventsFunctionPropertiesEditor = ({
|
||||
onConfigurationUpdated('isPrivate');
|
||||
forceUpdate();
|
||||
}}
|
||||
tooltipOrHelperText={
|
||||
eventsFunction.isPrivate() ? (
|
||||
<Trans>
|
||||
This function won't be visible in the events editor.
|
||||
</Trans>
|
||||
) : (
|
||||
<Trans>
|
||||
This function will be visible in the events editor.
|
||||
</Trans>
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Checkbox
|
||||
label={<Trans>Asynchronous</Trans>}
|
||||
|
@@ -12,8 +12,7 @@ import {
|
||||
} from '../../UI/Table';
|
||||
import RaisedButton from '../../UI/RaisedButton';
|
||||
import IconButton from '../../UI/IconButton';
|
||||
import SemiControlledTextField from '../../UI/SemiControlledTextField';
|
||||
import SelectField from '../../UI/SelectField';
|
||||
import CompactSemiControlledTextField from '../../UI/CompactSemiControlledTextField';
|
||||
import SelectOption from '../../UI/SelectOption';
|
||||
import { Line, Column } from '../../UI/Grid';
|
||||
|
||||
@@ -25,6 +24,11 @@ import { showWarningBox } from '../../UI/Messages/MessageBox';
|
||||
import Paper from '../../UI/Paper';
|
||||
import Trash from '../../UI/CustomSvgIcons/Trash';
|
||||
import Add from '../../UI/CustomSvgIcons/Add';
|
||||
import { ColumnStackLayout } from '../../UI/Layout';
|
||||
import Text from '../../UI/Text';
|
||||
import { CompactResourceSelectorWithThumbnail } from '../../ResourcesList/CompactResourceSelectorWithThumbnail';
|
||||
import { type ResourceManagementProps } from '../../ResourcesList/ResourceSource';
|
||||
import CompactSelectField from '../../UI/CompactSelectField';
|
||||
|
||||
const styles = {
|
||||
paper: { minWidth: '100%' },
|
||||
@@ -39,10 +43,18 @@ const checkNameExists = (
|
||||
return false;
|
||||
};
|
||||
|
||||
type Props = {| eventsFunctionsExtension: gdEventsFunctionsExtension |};
|
||||
type Props = {|
|
||||
eventsFunctionsExtension: gdEventsFunctionsExtension,
|
||||
|
||||
// For source files:
|
||||
project: gdProject,
|
||||
resourceManagementProps: ResourceManagementProps,
|
||||
|};
|
||||
|
||||
export const ExtensionDependenciesEditor = ({
|
||||
eventsFunctionsExtension,
|
||||
project,
|
||||
resourceManagementProps,
|
||||
}: Props) => {
|
||||
const deps = eventsFunctionsExtension.getAllDependencies();
|
||||
const forceUpdate = useForceUpdate();
|
||||
@@ -62,146 +74,242 @@ export const ExtensionDependenciesEditor = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<Column noMargin>
|
||||
<Line expand>
|
||||
<TableContainer
|
||||
component={({ children }) => (
|
||||
<Paper style={styles.paper} background="medium">
|
||||
{children}
|
||||
</Paper>
|
||||
)}
|
||||
>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHeaderColumn>
|
||||
<Trans>Name</Trans>
|
||||
</TableHeaderColumn>
|
||||
<TableHeaderColumn>
|
||||
<Trans>Export name</Trans>
|
||||
</TableHeaderColumn>
|
||||
<TableHeaderColumn>
|
||||
<Trans>Version</Trans>
|
||||
</TableHeaderColumn>
|
||||
<TableHeaderColumn>
|
||||
<Trans>Dependency type</Trans>
|
||||
</TableHeaderColumn>
|
||||
<TableHeaderColumn>
|
||||
<Trans>Action</Trans>
|
||||
</TableHeaderColumn>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{// $FlowFixMe - unsure why Flow complains about TableRow.
|
||||
mapVector<gdDependencyMetadata, TableRow>(
|
||||
eventsFunctionsExtension.getAllDependencies(),
|
||||
(dependency, index) => (
|
||||
// $FlowFixMe - unsure why Flow complains about TableRow.
|
||||
<TableRow key={dependency.getName()}>
|
||||
<TableRowColumn>
|
||||
<SemiControlledTextField
|
||||
commitOnBlur
|
||||
value={dependency.getName()}
|
||||
onChange={newName => {
|
||||
if (newName === dependency.getName()) return;
|
||||
<ColumnStackLayout noMargin noOverflowParent>
|
||||
<Text size="block-title">
|
||||
<Trans>Dependencies</Trans>
|
||||
</Text>
|
||||
<TableContainer
|
||||
component={({ children }) => (
|
||||
<Paper style={styles.paper} background="medium">
|
||||
{children}
|
||||
</Paper>
|
||||
)}
|
||||
>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHeaderColumn>
|
||||
<Trans>Name</Trans>
|
||||
</TableHeaderColumn>
|
||||
<TableHeaderColumn>
|
||||
<Trans>Export name</Trans>
|
||||
</TableHeaderColumn>
|
||||
<TableHeaderColumn>
|
||||
<Trans>Version</Trans>
|
||||
</TableHeaderColumn>
|
||||
<TableHeaderColumn>
|
||||
<Trans>Dependency type</Trans>
|
||||
</TableHeaderColumn>
|
||||
<TableHeaderColumn>
|
||||
<Trans>Action</Trans>
|
||||
</TableHeaderColumn>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{// $FlowFixMe - unsure why Flow complains about TableRow.
|
||||
mapVector<gdDependencyMetadata, TableRow>(
|
||||
eventsFunctionsExtension.getAllDependencies(),
|
||||
(dependency, index) => (
|
||||
// $FlowFixMe - unsure why Flow complains about TableRow.
|
||||
<TableRow key={dependency.getName()}>
|
||||
<TableRowColumn>
|
||||
<CompactSemiControlledTextField
|
||||
commitOnBlur
|
||||
value={dependency.getName()}
|
||||
onChange={newName => {
|
||||
if (newName === dependency.getName()) return;
|
||||
|
||||
if (checkNameExists(newName, deps)) {
|
||||
showWarningBox(
|
||||
`This name is already in use! Please use a unique name.`,
|
||||
{ delayToNextTick: true }
|
||||
);
|
||||
} else {
|
||||
dependency.setName(newName);
|
||||
forceUpdate();
|
||||
}
|
||||
}}
|
||||
margin="none"
|
||||
if (checkNameExists(newName, deps)) {
|
||||
showWarningBox(
|
||||
`This name is already in use! Please use a unique name.`,
|
||||
{ delayToNextTick: true }
|
||||
);
|
||||
} else {
|
||||
dependency.setName(newName);
|
||||
forceUpdate();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</TableRowColumn>
|
||||
<TableRowColumn>
|
||||
<CompactSemiControlledTextField
|
||||
commitOnBlur
|
||||
value={dependency.getExportName()}
|
||||
onChange={newExportName => {
|
||||
if (newExportName === dependency.getExportName())
|
||||
return;
|
||||
|
||||
dependency.setExportName(newExportName);
|
||||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
</TableRowColumn>
|
||||
<TableRowColumn>
|
||||
<CompactSemiControlledTextField
|
||||
commitOnBlur
|
||||
value={dependency.getVersion()}
|
||||
onChange={newVersion => {
|
||||
if (newVersion === dependency.getVersion()) return;
|
||||
|
||||
dependency.setVersion(newVersion);
|
||||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
</TableRowColumn>
|
||||
<TableRowColumn>
|
||||
<CompactSelectField
|
||||
value={dependency.getDependencyType()}
|
||||
onChange={newType => {
|
||||
if (newType === dependency.getDependencyType()) return;
|
||||
|
||||
dependency.setDependencyType(newType);
|
||||
forceUpdate();
|
||||
}}
|
||||
>
|
||||
<SelectOption value="npm" label={t`NPM`} />
|
||||
<SelectOption value="cordova" label={t`Cordova`} />
|
||||
</CompactSelectField>
|
||||
</TableRowColumn>
|
||||
<TableRowColumn>
|
||||
<IconButton
|
||||
tooltip={t`Delete`}
|
||||
onClick={() => {
|
||||
eventsFunctionsExtension.removeDependencyAt(index);
|
||||
forceUpdate();
|
||||
}}
|
||||
size="small"
|
||||
>
|
||||
<Trash />
|
||||
</IconButton>
|
||||
</TableRowColumn>
|
||||
</TableRow>
|
||||
)
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
<Column expand>
|
||||
<Line justifyContent="flex-end">
|
||||
<RaisedButton
|
||||
primary
|
||||
icon={<Add />}
|
||||
label={<Trans>Add</Trans>}
|
||||
onClick={addDependency}
|
||||
/>
|
||||
</Line>
|
||||
</Column>
|
||||
</TableContainer>
|
||||
<BackgroundText>
|
||||
<Trans>
|
||||
Dependencies allow to add additional libraries in the exported games.
|
||||
NPM dependencies will be included for Electron builds (Windows, macOS,
|
||||
Linux) and Cordova dependencies will be included for Cordova builds
|
||||
(Android, iOS). Note that this is intended for usage in JavaScript
|
||||
events only. If you are only using standard events, you should not
|
||||
worry about this.
|
||||
</Trans>
|
||||
</BackgroundText>
|
||||
<Text size="block-title">
|
||||
<Trans>Extra source files (experimental)</Trans>
|
||||
</Text>
|
||||
<TableContainer
|
||||
component={({ children }) => (
|
||||
<Paper style={styles.paper} background="medium">
|
||||
{children}
|
||||
</Paper>
|
||||
)}
|
||||
>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHeaderColumn>
|
||||
<Trans>Source file</Trans>
|
||||
</TableHeaderColumn>
|
||||
<TableHeaderColumn>
|
||||
<Trans>Loading Position</Trans>
|
||||
</TableHeaderColumn>
|
||||
<TableHeaderColumn>
|
||||
<Trans>Action</Trans>
|
||||
</TableHeaderColumn>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{// $FlowFixMe - unsure why Flow complains about TableRow.
|
||||
mapVector<gdSourceFileMetadata, TableRow>(
|
||||
eventsFunctionsExtension.getAllSourceFiles(),
|
||||
(sourceFile, index) => (
|
||||
// $FlowFixMe - unsure why Flow complains about TableRow.
|
||||
<TableRow key={sourceFile.getResourceName()}>
|
||||
<TableRowColumn>
|
||||
<CompactResourceSelectorWithThumbnail
|
||||
project={project}
|
||||
resourceManagementProps={resourceManagementProps}
|
||||
resourceKind="javascript"
|
||||
resourceName={sourceFile.getResourceName()}
|
||||
onChange={newResourceName => {
|
||||
sourceFile.setResourceName(newResourceName);
|
||||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
</TableRowColumn>
|
||||
<TableRowColumn>
|
||||
<CompactSelectField
|
||||
value={sourceFile.getIncludePosition()}
|
||||
onChange={newType => {
|
||||
if (newType === sourceFile.getIncludePosition()) return;
|
||||
|
||||
sourceFile.setIncludePosition(newType);
|
||||
forceUpdate();
|
||||
}}
|
||||
>
|
||||
<SelectOption
|
||||
value="first"
|
||||
label={t`First (before other files)`}
|
||||
/>
|
||||
</TableRowColumn>
|
||||
<TableRowColumn>
|
||||
<SemiControlledTextField
|
||||
commitOnBlur
|
||||
value={dependency.getExportName()}
|
||||
onChange={newExportName => {
|
||||
if (newExportName === dependency.getExportName())
|
||||
return;
|
||||
|
||||
dependency.setExportName(newExportName);
|
||||
forceUpdate();
|
||||
}}
|
||||
margin="none"
|
||||
<SelectOption
|
||||
value="last"
|
||||
label={t`Last (after other files)`}
|
||||
/>
|
||||
</TableRowColumn>
|
||||
<TableRowColumn>
|
||||
<SemiControlledTextField
|
||||
commitOnBlur
|
||||
value={dependency.getVersion()}
|
||||
onChange={newVersion => {
|
||||
if (newVersion === dependency.getVersion()) return;
|
||||
|
||||
dependency.setVersion(newVersion);
|
||||
forceUpdate();
|
||||
}}
|
||||
margin="none"
|
||||
/>
|
||||
</TableRowColumn>
|
||||
<TableRowColumn>
|
||||
<SelectField
|
||||
value={dependency.getDependencyType()}
|
||||
onChange={(_, __, newType) => {
|
||||
if (newType === dependency.getDependencyType())
|
||||
return;
|
||||
|
||||
dependency.setDependencyType(newType);
|
||||
forceUpdate();
|
||||
}}
|
||||
margin="none"
|
||||
>
|
||||
<SelectOption value="npm" label={t`NPM`} />
|
||||
<SelectOption value="cordova" label={t`Cordova`} />
|
||||
</SelectField>
|
||||
</TableRowColumn>
|
||||
<TableRowColumn>
|
||||
<IconButton
|
||||
tooltip={t`Delete`}
|
||||
onClick={() => {
|
||||
eventsFunctionsExtension.removeDependencyAt(index);
|
||||
forceUpdate();
|
||||
}}
|
||||
size="small"
|
||||
>
|
||||
<Trash />
|
||||
</IconButton>
|
||||
</TableRowColumn>
|
||||
</TableRow>
|
||||
)
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
<Column expand>
|
||||
<Line justifyContent="flex-end">
|
||||
<RaisedButton
|
||||
primary
|
||||
icon={<Add />}
|
||||
label={<Trans>Add</Trans>}
|
||||
onClick={addDependency}
|
||||
/>
|
||||
</Line>
|
||||
</Column>
|
||||
</TableContainer>
|
||||
</Line>
|
||||
<Line>
|
||||
<BackgroundText>
|
||||
<Trans>
|
||||
Dependencies allow to add additional libraries in the exported
|
||||
games. NPM dependencies will be included for Electron builds
|
||||
(Windows, macOS, Linux) and Cordova dependencies will be included
|
||||
for Cordova builds (Android, iOS). Note that this is intended for
|
||||
usage in JavaScript events only. If you are only using standard
|
||||
events, you should not worry about this.
|
||||
</Trans>
|
||||
</BackgroundText>
|
||||
</Line>
|
||||
</Column>
|
||||
</CompactSelectField>
|
||||
</TableRowColumn>
|
||||
<TableRowColumn>
|
||||
<IconButton
|
||||
tooltip={t`Delete`}
|
||||
onClick={() => {
|
||||
eventsFunctionsExtension.removeSourceFileAt(index);
|
||||
forceUpdate();
|
||||
}}
|
||||
size="small"
|
||||
>
|
||||
<Trash />
|
||||
</IconButton>
|
||||
</TableRowColumn>
|
||||
</TableRow>
|
||||
)
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
<Column expand>
|
||||
<Line justifyContent="flex-end">
|
||||
<RaisedButton
|
||||
primary
|
||||
icon={<Add />}
|
||||
label={<Trans>Add</Trans>}
|
||||
onClick={() => {
|
||||
eventsFunctionsExtension.addSourceFile();
|
||||
forceUpdate();
|
||||
}}
|
||||
/>
|
||||
</Line>
|
||||
</Column>
|
||||
</TableContainer>
|
||||
<BackgroundText>
|
||||
<Trans>
|
||||
JavaScript files are imported as is (no compilation and not available
|
||||
in JavaScript code block autocompletions). Make sure your extension is
|
||||
used by the game (at least one action/condition used in a scene),
|
||||
otherwise the files won't be imported.
|
||||
</Trans>
|
||||
</BackgroundText>
|
||||
</ColumnStackLayout>
|
||||
);
|
||||
};
|
||||
|
@@ -11,6 +11,7 @@ import { ExtensionDependenciesEditor } from './ExtensionDependenciesEditor';
|
||||
import ExtensionExporterDialog from './ExtensionExporterDialog';
|
||||
import { Line } from '../../UI/Grid';
|
||||
import Upload from '../../UI/CustomSvgIcons/Upload';
|
||||
import { type ResourceManagementProps } from '../../ResourcesList/ResourceSource';
|
||||
|
||||
type TabName = 'options' | 'dependencies';
|
||||
|
||||
@@ -19,10 +20,14 @@ type Props = {|
|
||||
eventsFunctionsExtension: gdEventsFunctionsExtension,
|
||||
onClose: () => void,
|
||||
open: boolean,
|
||||
|
||||
// For source files:
|
||||
resourceManagementProps: ResourceManagementProps,
|
||||
|};
|
||||
|
||||
export default function OptionsEditorDialog({
|
||||
project,
|
||||
resourceManagementProps,
|
||||
eventsFunctionsExtension,
|
||||
onClose,
|
||||
open,
|
||||
@@ -95,6 +100,8 @@ export default function OptionsEditorDialog({
|
||||
{currentTab === 'dependencies' && (
|
||||
<Line>
|
||||
<ExtensionDependenciesEditor
|
||||
project={project}
|
||||
resourceManagementProps={resourceManagementProps}
|
||||
eventsFunctionsExtension={eventsFunctionsExtension}
|
||||
/>
|
||||
</Line>
|
||||
|
@@ -1630,6 +1630,7 @@ export default class EventsFunctionsExtensionEditor extends React.Component<
|
||||
{editOptionsDialogOpen && (
|
||||
<OptionsEditorDialog
|
||||
project={project}
|
||||
resourceManagementProps={this.props.resourceManagementProps}
|
||||
eventsFunctionsExtension={eventsFunctionsExtension}
|
||||
open
|
||||
onClose={() => this._editOptions(false)}
|
||||
|
@@ -198,7 +198,9 @@ export class EventsBasedBehaviorTreeViewItemContent
|
||||
return this.eventsBasedBehavior.isPrivate() ? (
|
||||
<Tooltip
|
||||
title={
|
||||
<Trans>This behavior won't be visible in the events editor.</Trans>
|
||||
<Trans>
|
||||
This behavior won't be visible in the scene and events editors.
|
||||
</Trans>
|
||||
}
|
||||
>
|
||||
<VisibilityOff
|
||||
|
@@ -1,6 +1,7 @@
|
||||
// @flow
|
||||
import { type I18n as I18nType } from '@lingui/core';
|
||||
import { t } from '@lingui/macro';
|
||||
import { Trans } from '@lingui/macro';
|
||||
|
||||
import * as React from 'react';
|
||||
import newNameGenerator from '../Utils/NewNameGenerator';
|
||||
@@ -15,10 +16,16 @@ import {
|
||||
type TreeItemProps,
|
||||
extensionObjectsRootFolderId,
|
||||
} from '.';
|
||||
import Tooltip from '@material-ui/core/Tooltip';
|
||||
import VisibilityOff from '../UI/CustomSvgIcons/VisibilityOff';
|
||||
import Add from '../UI/CustomSvgIcons/Add';
|
||||
|
||||
const EVENTS_BASED_OBJECT_CLIPBOARD_KIND = 'Events Based Object';
|
||||
|
||||
const styles = {
|
||||
tooltip: { marginRight: 5, verticalAlign: 'bottom' },
|
||||
};
|
||||
|
||||
export type EventsBasedObjectCreationParameters = {|
|
||||
isRenderedIn3D: boolean,
|
||||
|};
|
||||
@@ -170,6 +177,12 @@ export class EventsBasedObjectTreeViewItemContent
|
||||
click: () => this.delete(),
|
||||
accelerator: 'Backspace',
|
||||
},
|
||||
{
|
||||
label: this.eventsBasedObject.isPrivate()
|
||||
? i18n._(t`Make public`)
|
||||
: i18n._(t`Make private`),
|
||||
click: () => this._togglePrivate(),
|
||||
},
|
||||
{
|
||||
type: 'separator',
|
||||
},
|
||||
@@ -193,7 +206,23 @@ export class EventsBasedObjectTreeViewItemContent
|
||||
}
|
||||
|
||||
renderRightComponent(i18n: I18nType): ?React.Node {
|
||||
return null;
|
||||
return this.eventsBasedObject.isPrivate() ? (
|
||||
<Tooltip
|
||||
title={
|
||||
<Trans>
|
||||
This object won't be visible in the scene and events editors.
|
||||
</Trans>
|
||||
}
|
||||
>
|
||||
<VisibilityOff
|
||||
fontSize="small"
|
||||
style={{
|
||||
...styles.tooltip,
|
||||
color: this.props.gdevelopTheme.text.color.disabled,
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
) : null;
|
||||
}
|
||||
|
||||
delete(): void {
|
||||
@@ -225,6 +254,11 @@ export class EventsBasedObjectTreeViewItemContent
|
||||
});
|
||||
}
|
||||
|
||||
_togglePrivate(): void {
|
||||
this.eventsBasedObject.setPrivate(!this.eventsBasedObject.isPrivate());
|
||||
this.props.forceUpdateEditor();
|
||||
}
|
||||
|
||||
getIndex(): number {
|
||||
return this.props.eventsBasedObjectsList.getPosition(
|
||||
this.eventsBasedObject
|
||||
|
@@ -50,6 +50,25 @@ type Props = {|
|
||||
|}) => React.Node,
|
||||
|};
|
||||
|
||||
const deduplicateEventSearchResults = (
|
||||
eventsSearchResults: gdVectorEventsSearchResult
|
||||
) => {
|
||||
const resultEventsWithDuplicates = mapFor(
|
||||
0,
|
||||
eventsSearchResults.size(),
|
||||
eventIndex => {
|
||||
const eventsSearchResult = eventsSearchResults.at(eventIndex);
|
||||
return eventsSearchResult.isEventValid()
|
||||
? eventsSearchResult.getEvent()
|
||||
: null;
|
||||
}
|
||||
).filter(Boolean);
|
||||
|
||||
// Store a list of unique events, because browsing for results in the events
|
||||
// tree is made event by event.
|
||||
return uniqBy<gdBaseEvent>(resultEventsWithDuplicates, event => event.ptr);
|
||||
};
|
||||
|
||||
/**
|
||||
* Computes the positions of the first selected event and the search results
|
||||
* in the flatten event tree and looks for the search result just after the
|
||||
@@ -116,25 +135,6 @@ export default class EventsSearcher extends React.Component<Props, State> {
|
||||
});
|
||||
};
|
||||
|
||||
_deduplicateEventSearchResults = (
|
||||
eventsSearchResults: gdVectorEventsSearchResult
|
||||
) => {
|
||||
const resultEventsWithDuplicates = mapFor(
|
||||
0,
|
||||
eventsSearchResults.size(),
|
||||
eventIndex => {
|
||||
const eventsSearchResult = eventsSearchResults.at(eventIndex);
|
||||
return eventsSearchResult.isEventValid()
|
||||
? eventsSearchResult.getEvent()
|
||||
: null;
|
||||
}
|
||||
).filter(Boolean);
|
||||
|
||||
// Store a list of unique events, because browsing for results in the events
|
||||
// tree is made event by event.
|
||||
return uniqBy<gdBaseEvent>(resultEventsWithDuplicates, event => event.ptr);
|
||||
};
|
||||
|
||||
_doReplaceInEvents = (
|
||||
{
|
||||
searchInSelection,
|
||||
@@ -181,7 +181,7 @@ export default class EventsSearcher extends React.Component<Props, State> {
|
||||
cb();
|
||||
}
|
||||
);
|
||||
return this._deduplicateEventSearchResults(modifiedEvents);
|
||||
return deduplicateEventSearchResults(modifiedEvents);
|
||||
};
|
||||
|
||||
_doSearchInEvents = (
|
||||
@@ -238,9 +238,7 @@ export default class EventsSearcher extends React.Component<Props, State> {
|
||||
return;
|
||||
}
|
||||
|
||||
this._resultEvents = this._deduplicateEventSearchResults(
|
||||
eventsSearchResults
|
||||
);
|
||||
this._resultEvents = deduplicateEventSearchResults(eventsSearchResults);
|
||||
};
|
||||
|
||||
_goToSearchResults = (step: number): ?gdBaseEvent => {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user