mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Add animation autocompletion for object groups (#6817)
This commit is contained in:
@@ -116,6 +116,13 @@ void SpriteAnimationList::ExposeResources(gd::ArbitraryResourceWorker& worker) {
|
||||
}
|
||||
}
|
||||
|
||||
bool SpriteAnimationList::HasAnimationNamed(const gd::String &name) const {
|
||||
return !name.empty() && (find_if(animations.begin(), animations.end(),
|
||||
[&name](const Animation &animation) {
|
||||
return animation.GetName() == name;
|
||||
}) != animations.end());
|
||||
}
|
||||
|
||||
const Animation& SpriteAnimationList::GetAnimation(std::size_t nb) const {
|
||||
if (nb >= animations.size()) return badAnimation;
|
||||
|
||||
|
@@ -51,6 +51,11 @@ class GD_CORE_API SpriteAnimationList {
|
||||
*/
|
||||
std::size_t GetAnimationsCount() const { return animations.size(); };
|
||||
|
||||
/**
|
||||
* \brief Return true if an animation exists for a given name.
|
||||
*/
|
||||
bool HasAnimationNamed(const gd::String &name) const;
|
||||
|
||||
/**
|
||||
* \brief Add an animation at the end of the existing ones.
|
||||
*/
|
||||
|
@@ -87,6 +87,19 @@ bool SpriteObject::UpdateInitialInstanceProperty(
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t SpriteObject::GetAnimationsCount() const {
|
||||
return animations.GetAnimationsCount();
|
||||
}
|
||||
|
||||
const gd::String &SpriteObject::GetAnimationName(size_t index) const {
|
||||
return animations.GetAnimation(index).GetName();
|
||||
}
|
||||
|
||||
bool SpriteObject::HasAnimationNamed(
|
||||
const gd::String &name) const {
|
||||
return animations.HasAnimationNamed(name);
|
||||
}
|
||||
|
||||
const SpriteAnimationList& SpriteObject::GetAnimations() const {
|
||||
return animations;
|
||||
}
|
||||
|
@@ -52,6 +52,12 @@ class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
|
||||
const gd::String& name,
|
||||
const gd::String& value) override;
|
||||
|
||||
size_t GetAnimationsCount() const override;
|
||||
|
||||
const gd::String &GetAnimationName(size_t index) const override;
|
||||
|
||||
bool HasAnimationNamed(const gd::String &animationName) const override;
|
||||
|
||||
/**
|
||||
* \brief Return the animation configuration.
|
||||
*/
|
||||
|
@@ -224,6 +224,20 @@ void CustomObjectConfiguration::ExposeResources(gd::ArbitraryResourceWorker& wor
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t CustomObjectConfiguration::GetAnimationsCount() const {
|
||||
return animations.GetAnimationsCount();
|
||||
}
|
||||
|
||||
const gd::String &
|
||||
CustomObjectConfiguration::GetAnimationName(size_t index) const {
|
||||
return animations.GetAnimation(index).GetName();
|
||||
}
|
||||
|
||||
bool CustomObjectConfiguration::HasAnimationNamed(
|
||||
const gd::String &name) const {
|
||||
return animations.HasAnimationNamed(name);
|
||||
}
|
||||
|
||||
const SpriteAnimationList& CustomObjectConfiguration::GetAnimations() const {
|
||||
return animations;
|
||||
}
|
||||
|
@@ -67,6 +67,12 @@ class CustomObjectConfiguration : public gd::ObjectConfiguration {
|
||||
|
||||
gd::ObjectConfiguration &GetChildObjectConfiguration(const gd::String& objectName);
|
||||
|
||||
std::size_t GetAnimationsCount() const override;
|
||||
|
||||
const gd::String &GetAnimationName(size_t index) const override;
|
||||
|
||||
bool HasAnimationNamed(const gd::String &animationName) const override;
|
||||
|
||||
/**
|
||||
* \brief Return the animation configuration for Animatable custom objects.
|
||||
*/
|
||||
|
@@ -14,6 +14,7 @@
|
||||
#include "GDCore/Tools/Log.h"
|
||||
|
||||
namespace gd {
|
||||
gd::String ObjectConfiguration::badAnimationName;
|
||||
|
||||
ObjectConfiguration::~ObjectConfiguration() {}
|
||||
|
||||
|
@@ -165,7 +165,36 @@ class GD_CORE_API ObjectConfiguration {
|
||||
void UnserializeFrom(gd::Project& project, const SerializerElement& element);
|
||||
///@}
|
||||
|
||||
protected:
|
||||
/** \name Animations
|
||||
* Members functions related to object animations
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Return the number of animations declared in this object
|
||||
* configuration.
|
||||
*/
|
||||
virtual size_t GetAnimationsCount() const {
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Return the name of an animation declared in this object
|
||||
* configuration.
|
||||
*/
|
||||
virtual const gd::String &GetAnimationName(size_t index) const {
|
||||
return badAnimationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return true if an animation is declared in this object
|
||||
* configuration for a given name.
|
||||
*/
|
||||
virtual bool HasAnimationNamed(const gd::String &animationName) const {
|
||||
return false;
|
||||
}
|
||||
///@}
|
||||
|
||||
protected:
|
||||
gd::String type; ///< Which type of object is represented by this
|
||||
///< configuration.
|
||||
|
||||
@@ -181,6 +210,9 @@ class GD_CORE_API ObjectConfiguration {
|
||||
* custom attributes.
|
||||
*/
|
||||
virtual void DoSerializeTo(SerializerElement& element) const {};
|
||||
|
||||
private:
|
||||
static gd::String badAnimationName;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -73,6 +73,15 @@ bool ObjectsContainersList::HasObjectNamed(const gd::String& name) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
const gd::Object* ObjectsContainersList::GetObject(const gd::String& name) const {
|
||||
for (auto it = objectsContainers.rbegin(); it != objectsContainers.rend();
|
||||
++it) {
|
||||
if ((*it)->HasObjectNamed(name)) return &(*it)->GetObject(name);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ObjectsContainersList::VariableExistence
|
||||
ObjectsContainersList::HasObjectOrGroupWithVariableNamed(
|
||||
const gd::String& objectOrGroupName, const gd::String& variableName) const {
|
||||
@@ -368,7 +377,7 @@ std::vector<gd::String> ObjectsContainersList::ExpandObjectName(
|
||||
}
|
||||
|
||||
// Ensure that all returned objects actually exists (i.e: if some groups have
|
||||
// names refering to non existing objects, don't return them).
|
||||
// names referring to non existing objects, don't return them).
|
||||
for (std::size_t i = 0; i < realObjects.size();) {
|
||||
if (!HasObjectNamed(realObjects[i]))
|
||||
realObjects.erase(realObjects.begin() + i);
|
||||
@@ -521,4 +530,63 @@ std::vector<gd::String> ObjectsContainersList::GetBehaviorsOfObject(
|
||||
*objectsContainers[0], *objectsContainers[1], objectName, searchInGroups);
|
||||
}
|
||||
|
||||
std::vector<gd::String> ObjectsContainersList::GetAnimationNamesOfObject(
|
||||
const gd::String &objectOrGroupName) const {
|
||||
std::vector<gd::String> animationNames;
|
||||
|
||||
for (auto it = objectsContainers.rbegin(); it != objectsContainers.rend();
|
||||
++it) {
|
||||
if ((*it)->HasObjectNamed(objectOrGroupName)) {
|
||||
const auto &objectConfiguration =
|
||||
(*it)->GetObject(objectOrGroupName).GetConfiguration();
|
||||
|
||||
for (size_t index = 0; index < objectConfiguration.GetAnimationsCount();
|
||||
index++) {
|
||||
animationNames.push_back(objectConfiguration.GetAnimationName(index));
|
||||
}
|
||||
return animationNames;
|
||||
}
|
||||
if ((*it)->GetObjectGroups().Has(objectOrGroupName)) {
|
||||
const auto &objectGroup = (*it)->GetObjectGroups().Get(objectOrGroupName);
|
||||
const auto &objectNames = objectGroup.GetAllObjectsNames();
|
||||
|
||||
std::size_t objectIndex = 0;
|
||||
bool isFirstObjectFound = false;
|
||||
for (; objectIndex < objectNames.size() && !isFirstObjectFound;
|
||||
objectIndex++) {
|
||||
const gd::String &objectName = objectNames[objectIndex];
|
||||
if (!HasObjectNamed(objectName)) {
|
||||
continue;
|
||||
}
|
||||
isFirstObjectFound = true;
|
||||
const auto &objectConfiguration =
|
||||
GetObject(objectName)->GetConfiguration();
|
||||
for (size_t index = 0; index < objectConfiguration.GetAnimationsCount();
|
||||
index++) {
|
||||
animationNames.push_back(objectConfiguration.GetAnimationName(index));
|
||||
}
|
||||
}
|
||||
for (; objectIndex < objectNames.size(); objectIndex++) {
|
||||
const gd::String &objectName = objectNames[objectIndex];
|
||||
if (!HasObjectNamed(objectName)) {
|
||||
continue;
|
||||
}
|
||||
const auto &objectConfiguration =
|
||||
GetObject(objectName)->GetConfiguration();
|
||||
|
||||
for (size_t animationIndex = 0; animationIndex < animationNames.size();
|
||||
animationIndex++) {
|
||||
if (!objectConfiguration.HasAnimationNamed(
|
||||
animationNames[animationIndex])) {
|
||||
animationNames.erase(animationNames.begin() + animationIndex);
|
||||
animationIndex--;
|
||||
}
|
||||
}
|
||||
}
|
||||
return animationNames;
|
||||
}
|
||||
}
|
||||
return animationNames;
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -129,7 +129,17 @@ class GD_CORE_API ObjectsContainersList {
|
||||
const gd::String& objectName, bool searchInGroups = true) const;
|
||||
|
||||
/**
|
||||
* \brief Return a list containing all objects refered to by the group.
|
||||
* \brief Get the animation names of an object/group.
|
||||
* \note The animation names of a group are the animation names common to
|
||||
* every object of the group.
|
||||
*
|
||||
* @return The names of animations
|
||||
*/
|
||||
std::vector<gd::String>
|
||||
GetAnimationNamesOfObject(const gd::String &objectOrGroupName) const;
|
||||
|
||||
/**
|
||||
* \brief Return a list containing all objects referred to by the group.
|
||||
* If an object name is passed, then only this object name is returned.
|
||||
*
|
||||
* If \a onlyObjectToSelectIfPresent is set and present in the group(s),
|
||||
@@ -170,6 +180,8 @@ class GD_CORE_API ObjectsContainersList {
|
||||
private:
|
||||
bool HasObjectNamed(const gd::String& name) const;
|
||||
|
||||
const gd::Object* GetObject(const gd::String& name) const;
|
||||
|
||||
bool HasObjectWithVariableNamed(const gd::String& objectName,
|
||||
const gd::String& variableName) const;
|
||||
|
||||
|
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2023 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
/**
|
||||
* @file Tests covering layout content helper methods.
|
||||
*/
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "DummyPlatform.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
using namespace gd;
|
||||
|
||||
TEST_CASE("Layout", "[common]") {
|
||||
|
||||
SECTION("Find the type of a behavior in a object") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject", 0);
|
||||
object.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
|
||||
REQUIRE(GetTypeOfBehaviorInObjectOrGroup(
|
||||
project.GetObjects(), layout.GetObjects(),
|
||||
"MyObject", "MyBehavior", true) == "MyExtension::MyBehavior");
|
||||
}
|
||||
|
||||
SECTION("Give an empty type for an object that doesn't have the behavior") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject", 0);
|
||||
|
||||
REQUIRE(GetTypeOfBehaviorInObjectOrGroup(
|
||||
project.GetObjects(), layout.GetObjects(),
|
||||
"MyObject", "MyBehavior", true) == "");
|
||||
}
|
||||
|
||||
SECTION("Find the type of a behavior in a group") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object1 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject1", 0);
|
||||
object1.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
gd::Object &object2 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject2", 0);
|
||||
object2.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
|
||||
auto &group =
|
||||
layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
REQUIRE(GetTypeOfBehaviorInObjectOrGroup(
|
||||
project.GetObjects(), layout.GetObjects(),
|
||||
"MyGroup", "MyBehavior", true) == "MyExtension::MyBehavior");
|
||||
}
|
||||
|
||||
SECTION(
|
||||
"Give an empty type for a group with an object missing the behavior") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object1 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject1", 0);
|
||||
object1.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
gd::Object &object2 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject2", 0);
|
||||
// object2 doesn't have the behavior.
|
||||
|
||||
auto &group =
|
||||
layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
REQUIRE(GetTypeOfBehaviorInObjectOrGroup(
|
||||
project.GetObjects(), layout.GetObjects(),
|
||||
"MyGroup", "MyBehavior", true) == "");
|
||||
}
|
||||
|
||||
SECTION("Give an empty type for a group with behaviors of same name but "
|
||||
"different types") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object1 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject1", 0);
|
||||
object1.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
gd::Object &object2 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject2", 0);
|
||||
object2.AddNewBehavior(project, "MyExtension::MyOtherBehavior",
|
||||
"MyBehavior");
|
||||
|
||||
auto &group =
|
||||
layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
REQUIRE(GetTypeOfBehaviorInObjectOrGroup(
|
||||
project.GetObjects(), layout.GetObjects(),
|
||||
"MyGroup", "MyBehavior", true) == "");
|
||||
}
|
||||
|
||||
SECTION("Give an empty type for an empty group") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
auto &group =
|
||||
layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
|
||||
REQUIRE(GetTypeOfBehaviorInObjectOrGroup(
|
||||
project.GetObjects(), layout.GetObjects(),
|
||||
"MyGroup", "MyBehavior", true) == "");
|
||||
}
|
||||
}
|
488
Core/tests/ObjectsContainersList.cpp
Normal file
488
Core/tests/ObjectsContainersList.cpp
Normal file
@@ -0,0 +1,488 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2023 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
/**
|
||||
* @file Tests covering layout content helper methods.
|
||||
*/
|
||||
#include "GDCore/Project/ObjectsContainersList.h"
|
||||
#include "DummyPlatform.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Tools/MakeUnique.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
using namespace gd;
|
||||
|
||||
TEST_CASE("ObjectContainersList (HasObjectOrGroupNamed)", "[common]") {
|
||||
|
||||
SECTION("Can check an object exists") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject", 0);
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.HasObjectOrGroupNamed("MyObject"));
|
||||
REQUIRE(!objectsContainersList.HasObjectOrGroupNamed("MyWrongObject"));
|
||||
}
|
||||
|
||||
SECTION("Can check a group exists") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.HasObjectOrGroupNamed("MyGroup"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ObjectContainersList (HasObjectOrGroupWithVariableNamed)", "[common]") {
|
||||
|
||||
SECTION("Can check a variable exists in an object") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject", 0);
|
||||
object.GetVariables().InsertNew("MyVariable", 0);
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.HasObjectOrGroupWithVariableNamed("MyObject", "MyVariable"));
|
||||
REQUIRE(!objectsContainersList.HasObjectOrGroupWithVariableNamed("MyObject", "MyWrongVariable"));
|
||||
}
|
||||
|
||||
SECTION("Can check a variable exists in a group") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object1 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject1", 0);
|
||||
object1.GetVariables().InsertNew("MyVariable", 0);
|
||||
// This variable is only in one of the 2 objects.
|
||||
object1.GetVariables().InsertNew("MyOtherVariable", 0);
|
||||
gd::Object &object2 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject2", 0);
|
||||
object1.GetVariables().InsertNew("MyVariable", 0);
|
||||
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.HasObjectOrGroupWithVariableNamed("MyGroup", "MyVariable"));
|
||||
REQUIRE(!objectsContainersList.HasObjectOrGroupWithVariableNamed("MyGroup", "MyWrongVariable"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ObjectContainersList (GetTypeOfObject)", "[common]") {
|
||||
|
||||
SECTION("Find the type of an object") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject", 0);
|
||||
object.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.GetTypeOfObject("MyObject") == "MyExtension::Sprite");
|
||||
}
|
||||
|
||||
SECTION("Find the object type of a group") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object1 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject1", 0);
|
||||
gd::Object &object2 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject2", 0);
|
||||
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.GetTypeOfObject("MyGroup") == "MyExtension::Sprite");
|
||||
}
|
||||
|
||||
SECTION("Give an empty type for groups with mixed object types") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object1 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject1", 0);
|
||||
gd::Object &object2 = layout.GetObjects().InsertNewObject(
|
||||
project, "FakeObjectWithDefaultBehavior", "MyObject2", 0);
|
||||
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.GetTypeOfObject("MyGroup") == "");
|
||||
}
|
||||
|
||||
SECTION("Give an empty type for an empty group") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.GetTypeOfObject(
|
||||
"MyGroup") == "");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ObjectContainersList (GetTypeOfBehaviorInObjectOrGroup)",
|
||||
"[common]") {
|
||||
|
||||
SECTION("Find the type of a behavior in an object") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject", 0);
|
||||
object.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.GetTypeOfBehaviorInObjectOrGroup(
|
||||
"MyObject", "MyBehavior", true) == "MyExtension::MyBehavior");
|
||||
}
|
||||
|
||||
SECTION("Give an empty type for an object that doesn't have the behavior") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject", 0);
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.GetTypeOfBehaviorInObjectOrGroup(
|
||||
"MyObject", "MyBehavior", true) == "");
|
||||
}
|
||||
|
||||
SECTION("Find the type of a behavior in a group") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object1 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject1", 0);
|
||||
object1.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
gd::Object &object2 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject2", 0);
|
||||
object2.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.GetTypeOfBehaviorInObjectOrGroup(
|
||||
"MyGroup", "MyBehavior", true) == "MyExtension::MyBehavior");
|
||||
}
|
||||
|
||||
SECTION(
|
||||
"Give an empty type for a group with an object missing the behavior") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object1 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject1", 0);
|
||||
object1.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
gd::Object &object2 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject2", 0);
|
||||
// object2 doesn't have the behavior.
|
||||
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.GetTypeOfBehaviorInObjectOrGroup(
|
||||
"MyGroup", "MyBehavior", true) == "");
|
||||
}
|
||||
|
||||
SECTION("Give an empty type for a group with behaviors of same name but different types") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object1 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject1", 0);
|
||||
object1.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
gd::Object &object2 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject2", 0);
|
||||
object2.AddNewBehavior(project, "MyExtension::MyOtherBehavior",
|
||||
"MyBehavior");
|
||||
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.GetTypeOfBehaviorInObjectOrGroup(
|
||||
"MyGroup", "MyBehavior", true) == "");
|
||||
}
|
||||
|
||||
SECTION("Give an empty type for an empty group") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.GetTypeOfBehaviorInObjectOrGroup(
|
||||
"MyGroup", "MyBehavior", true) == "");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ObjectContainersList (HasBehaviorInObjectOrGroup)", "[common]") {
|
||||
|
||||
SECTION("Can check a behavior exists in an object") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject", 0);
|
||||
object.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.HasBehaviorInObjectOrGroup("MyObject", "MyBehavior"));
|
||||
REQUIRE(!objectsContainersList.HasBehaviorInObjectOrGroup("MyObject", "MyWrongBehavior"));
|
||||
}
|
||||
|
||||
SECTION("Can check a behavior exists in a group") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object1 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject1", 0);
|
||||
object1.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
// This behavior is only in one of the 2 objects.
|
||||
object1.AddNewBehavior(project, "MyExtension::MyOtherBehavior",
|
||||
"MyOtherBehavior");
|
||||
gd::Object &object2 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject2", 0);
|
||||
object2.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.HasBehaviorInObjectOrGroup("MyGroup", "MyBehavior"));
|
||||
REQUIRE(!objectsContainersList.HasBehaviorInObjectOrGroup("MyGroup", "MyOtherBehavior"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ObjectContainersList (GetBehaviorsOfObject)", "[common]") {
|
||||
|
||||
SECTION("Find the behaviors in an object") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject", 0);
|
||||
object.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
const auto behaviors =
|
||||
objectsContainersList.GetBehaviorsOfObject("MyObject", true);
|
||||
REQUIRE(behaviors.size() == 1);
|
||||
REQUIRE(behaviors[0] == "MyBehavior");
|
||||
}
|
||||
|
||||
SECTION("Find the behaviors in a group") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object1 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject1", 0);
|
||||
object1.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
// This behavior is only in one of the 2 objects.
|
||||
object1.AddNewBehavior(project, "MyExtension::MyOtherBehavior",
|
||||
"MyOtherBehavior");
|
||||
gd::Object &object2 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject2", 0);
|
||||
object2.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
const auto behaviors =
|
||||
objectsContainersList.GetBehaviorsOfObject("MyGroup", true);
|
||||
REQUIRE(behaviors.size() == 1);
|
||||
REQUIRE(behaviors[0] == "MyBehavior");
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
gd::SpriteObject BuildSpriteWithAnimations(gd::String animationName1 = "!",
|
||||
gd::String animationName2 = "!",
|
||||
gd::String animationName3 = "!") {
|
||||
gd::SpriteObject configuration;
|
||||
gd::SpriteAnimationList &animations = configuration.GetAnimations();
|
||||
if (animationName1 != "!") {
|
||||
gd::Animation animation;
|
||||
animation.SetName(animationName1);
|
||||
animations.AddAnimation(animation);
|
||||
if (animationName2 != "!") {
|
||||
gd::Animation animation;
|
||||
animation.SetName(animationName2);
|
||||
animations.AddAnimation(animation);
|
||||
}
|
||||
if (animationName3 != "!") {
|
||||
gd::Animation animation;
|
||||
animation.SetName(animationName3);
|
||||
animations.AddAnimation(animation);
|
||||
}
|
||||
}
|
||||
return configuration;
|
||||
}
|
||||
|
||||
bool Contains(const std::vector<gd::String> &vector, const gd::String &value) {
|
||||
return std::find(vector.begin(), vector.end(), value) !=
|
||||
vector.end();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("ObjectContainersList (GetAnimationNamesOfObject)", "[common]") {
|
||||
|
||||
SECTION("Find the animation names in a sprite") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object object("MyObject", "Sprite",
|
||||
gd::make_unique<gd::SpriteObject>(
|
||||
BuildSpriteWithAnimations("Idle", "Run")));
|
||||
layout.GetObjects().InsertObject(object, 0);
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
const auto animationNames =
|
||||
objectsContainersList.GetAnimationNamesOfObject("MyObject");
|
||||
REQUIRE(Contains(animationNames, "Idle"));
|
||||
REQUIRE(Contains(animationNames, "Run"));
|
||||
REQUIRE(animationNames.size() == 2);
|
||||
}
|
||||
|
||||
SECTION("Find the animation names in a group of sprite") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object object1("MyObject1", "Sprite",
|
||||
gd::make_unique<gd::SpriteObject>(
|
||||
BuildSpriteWithAnimations("Idle", "Jump", "Run")));
|
||||
layout.GetObjects().InsertObject(object1, 0);
|
||||
gd::Object object2("MyObject2", "Sprite",
|
||||
gd::make_unique<gd::SpriteObject>(
|
||||
BuildSpriteWithAnimations("Run", "Idle", "Climb")));
|
||||
layout.GetObjects().InsertObject(object2, 0);
|
||||
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
const auto animationNames =
|
||||
objectsContainersList.GetAnimationNamesOfObject("MyGroup");
|
||||
REQUIRE(Contains(animationNames, "Idle"));
|
||||
REQUIRE(Contains(animationNames, "Run"));
|
||||
REQUIRE(animationNames.size() == 2);
|
||||
}
|
||||
}
|
@@ -235,6 +235,19 @@ void Model3DObjectConfiguration::ExposeResources(
|
||||
worker.ExposeModel3D(modelResourceName);
|
||||
}
|
||||
|
||||
const gd::String &
|
||||
Model3DObjectConfiguration::GetAnimationName(size_t index) const {
|
||||
return GetAnimation(index).GetName();
|
||||
}
|
||||
|
||||
bool Model3DObjectConfiguration::HasAnimationNamed(
|
||||
const gd::String &name) const {
|
||||
return !name.empty() && (find_if(animations.begin(), animations.end(),
|
||||
[&name](const Model3DAnimation &animation) {
|
||||
return animation.GetName() == name;
|
||||
}) != animations.end());
|
||||
}
|
||||
|
||||
Model3DAnimation Model3DObjectConfiguration::badAnimation;
|
||||
|
||||
const Model3DAnimation &
|
||||
@@ -252,14 +265,6 @@ Model3DAnimation &Model3DObjectConfiguration::GetAnimation(std::size_t nb) {
|
||||
return animations[nb];
|
||||
}
|
||||
|
||||
bool Model3DObjectConfiguration::HasAnimationNamed(
|
||||
const gd::String &name) const {
|
||||
return !name.empty() && (find_if(animations.begin(), animations.end(),
|
||||
[&name](const Model3DAnimation &animation) {
|
||||
return animation.GetName() == name;
|
||||
}) != animations.end());
|
||||
}
|
||||
|
||||
void Model3DObjectConfiguration::AddAnimation(
|
||||
const Model3DAnimation &animation) {
|
||||
animations.push_back(animation);
|
||||
|
@@ -85,6 +85,12 @@ public:
|
||||
* Methods related to animations management
|
||||
*/
|
||||
///@{
|
||||
std::size_t GetAnimationsCount() const override { return animations.size(); };
|
||||
|
||||
const gd::String &GetAnimationName(size_t index) const override;
|
||||
|
||||
bool HasAnimationNamed(const gd::String &animationName) const override;
|
||||
|
||||
/**
|
||||
* \brief Return the animation at the specified index.
|
||||
* If the index is out of bound, a "bad animation" object is returned.
|
||||
@@ -97,16 +103,6 @@ public:
|
||||
*/
|
||||
Model3DAnimation &GetAnimation(std::size_t nb);
|
||||
|
||||
/**
|
||||
* \brief Return the number of animations this object has.
|
||||
*/
|
||||
std::size_t GetAnimationsCount() const { return animations.size(); };
|
||||
|
||||
/**
|
||||
* \brief Return true if the animation called "name" exists.
|
||||
*/
|
||||
bool HasAnimationNamed(const gd::String& name) const;
|
||||
|
||||
/**
|
||||
* \brief Add an animation at the end of the existing ones.
|
||||
*/
|
||||
|
@@ -116,6 +116,18 @@ void SpineObjectConfiguration::ExposeResources(gd::ArbitraryResourceWorker &work
|
||||
worker.ExposeEmbeddeds(spineResourceName);
|
||||
}
|
||||
|
||||
const gd::String &
|
||||
SpineObjectConfiguration::GetAnimationName(size_t index) const {
|
||||
return GetAnimation(index).GetName();
|
||||
}
|
||||
|
||||
bool SpineObjectConfiguration::HasAnimationNamed(const gd::String &name) const {
|
||||
return !name.empty() && (find_if(animations.begin(), animations.end(),
|
||||
[&name](const SpineAnimation &animation) {
|
||||
return animation.GetName() == name;
|
||||
}) != animations.end());
|
||||
}
|
||||
|
||||
const SpineAnimation &
|
||||
SpineObjectConfiguration::GetAnimation(std::size_t nb) const {
|
||||
if (nb >= animations.size()) return badAnimation;
|
||||
@@ -129,13 +141,6 @@ SpineAnimation &SpineObjectConfiguration::GetAnimation(std::size_t nb) {
|
||||
return animations[nb];
|
||||
}
|
||||
|
||||
bool SpineObjectConfiguration::HasAnimationNamed(const gd::String &name) const {
|
||||
return !name.empty() && (find_if(animations.begin(), animations.end(),
|
||||
[&name](const SpineAnimation &animation) {
|
||||
return animation.GetName() == name;
|
||||
}) != animations.end());
|
||||
}
|
||||
|
||||
void SpineObjectConfiguration::AddAnimation(const SpineAnimation &animation) {
|
||||
animations.push_back(animation);
|
||||
}
|
||||
|
@@ -93,15 +93,11 @@ public:
|
||||
*/
|
||||
SpineAnimation &GetAnimation(std::size_t nb);
|
||||
|
||||
/**
|
||||
* \brief Return the number of animations this object has.
|
||||
*/
|
||||
std::size_t GetAnimationsCount() const { return animations.size(); };
|
||||
std::size_t GetAnimationsCount() const override { return animations.size(); };
|
||||
|
||||
/**
|
||||
* \brief Return true if the animation called "name" exists.
|
||||
*/
|
||||
bool HasAnimationNamed(const gd::String& name) const;
|
||||
const gd::String &GetAnimationName(size_t index) const override;
|
||||
|
||||
bool HasAnimationNamed(const gd::String &animationName) const override;
|
||||
|
||||
/**
|
||||
* \brief Add an animation at the end of the existing ones.
|
||||
|
@@ -659,6 +659,7 @@ interface ObjectsContainersList {
|
||||
[Const, Value] DOMString GetTypeOfObject([Const] DOMString objectName);
|
||||
[Const, Value] DOMString GetTypeOfBehavior([Const] DOMString name, boolean searchInGroups);
|
||||
[Value] VectorString GetBehaviorsOfObject([Const] DOMString name, boolean searchInGroups);
|
||||
[Value] VectorString GetAnimationNamesOfObject([Const] DOMString name);
|
||||
[Const, Value] DOMString GetTypeOfBehaviorInObjectOrGroup([Const] DOMString objectOrGroupName, [Const] DOMString behaviorName, boolean searchInGroups);
|
||||
boolean HasObjectOrGroupNamed([Const] DOMString name);
|
||||
|
||||
|
1
GDevelop.js/types.d.ts
vendored
1
GDevelop.js/types.d.ts
vendored
@@ -590,6 +590,7 @@ export class ObjectsContainersList extends EmscriptenObject {
|
||||
getTypeOfObject(objectName: string): string;
|
||||
getTypeOfBehavior(name: string, searchInGroups: boolean): string;
|
||||
getBehaviorsOfObject(name: string, searchInGroups: boolean): VectorString;
|
||||
getAnimationNamesOfObject(name: string): VectorString;
|
||||
getTypeOfBehaviorInObjectOrGroup(objectOrGroupName: string, behaviorName: string, searchInGroups: boolean): string;
|
||||
hasObjectOrGroupNamed(name: string): boolean;
|
||||
hasObjectOrGroupWithVariableNamed(objectName: string, variableName: string): ObjectsContainersList_VariableExistence;
|
||||
|
@@ -10,6 +10,7 @@ declare class gdObjectsContainersList {
|
||||
getTypeOfObject(objectName: string): string;
|
||||
getTypeOfBehavior(name: string, searchInGroups: boolean): string;
|
||||
getBehaviorsOfObject(name: string, searchInGroups: boolean): gdVectorString;
|
||||
getAnimationNamesOfObject(name: string): gdVectorString;
|
||||
getTypeOfBehaviorInObjectOrGroup(objectOrGroupName: string, behaviorName: string, searchInGroups: boolean): string;
|
||||
hasObjectOrGroupNamed(name: string): boolean;
|
||||
hasObjectOrGroupWithVariableNamed(objectName: string, variableName: string): ObjectsContainersList_VariableExistence;
|
||||
|
@@ -34,7 +34,7 @@ export default React.forwardRef<ParameterFieldProps, ParameterFieldInterface>(
|
||||
}));
|
||||
|
||||
const {
|
||||
project,
|
||||
projectScopedContainersAccessor,
|
||||
scope,
|
||||
instructionMetadata,
|
||||
instruction,
|
||||
@@ -43,7 +43,7 @@ export default React.forwardRef<ParameterFieldProps, ParameterFieldInterface>(
|
||||
parameterIndex,
|
||||
} = props;
|
||||
|
||||
const { layout, eventsFunctionsExtension, eventsBasedObject } = scope;
|
||||
const { eventsFunctionsExtension, eventsBasedObject } = scope;
|
||||
|
||||
// We don't memo/callback this, as we want to recompute it every time something changes.
|
||||
// Because of the function getLastObjectParameterValue.
|
||||
@@ -55,84 +55,21 @@ export default React.forwardRef<ParameterFieldProps, ParameterFieldInterface>(
|
||||
expression,
|
||||
parameterIndex,
|
||||
});
|
||||
|
||||
if (!objectName || !project) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const object = getObjectByName(
|
||||
project.getObjects(),
|
||||
layout ? layout.getObjects() : null,
|
||||
objectName
|
||||
);
|
||||
if (!object) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (object.getType() === 'Sprite') {
|
||||
const spriteConfiguration = gd.asSpriteConfiguration(
|
||||
object.getConfiguration()
|
||||
);
|
||||
const animations = spriteConfiguration.getAnimations();
|
||||
|
||||
return mapFor(0, animations.getAnimationsCount(), index => {
|
||||
const animationName = animations.getAnimation(index).getName();
|
||||
return animationName.length > 0 ? animationName : null;
|
||||
}).filter(Boolean);
|
||||
} else if (object.getType() === 'Scene3D::Model3DObject') {
|
||||
const model3DConfiguration = gd.asModel3DConfiguration(
|
||||
object.getConfiguration()
|
||||
);
|
||||
|
||||
return mapFor(0, model3DConfiguration.getAnimationsCount(), index => {
|
||||
const animationName = model3DConfiguration
|
||||
.getAnimation(index)
|
||||
.getName();
|
||||
return animationName.length > 0 ? animationName : null;
|
||||
})
|
||||
.filter(Boolean)
|
||||
.sort();
|
||||
} else if (object.getType() === 'SpineObject::SpineObject') {
|
||||
const spineConfiguration = gd.asSpineConfiguration(
|
||||
object.getConfiguration()
|
||||
);
|
||||
|
||||
return mapFor(0, spineConfiguration.getAnimationsCount(), index => {
|
||||
const animationName = spineConfiguration
|
||||
.getAnimation(index)
|
||||
.getName();
|
||||
return animationName.length > 0 ? animationName : null;
|
||||
})
|
||||
.filter(Boolean)
|
||||
.sort();
|
||||
} else if (project.hasEventsBasedObject(object.getType())) {
|
||||
const eventsBasedObject = project.getEventsBasedObject(
|
||||
object.getType()
|
||||
);
|
||||
if (eventsBasedObject.isAnimatable()) {
|
||||
const customObjectConfiguration = gd.asCustomObjectConfiguration(
|
||||
object.getConfiguration()
|
||||
);
|
||||
const animations = customObjectConfiguration.getAnimations();
|
||||
|
||||
return mapFor(0, animations.getAnimationsCount(), index => {
|
||||
const animationName = animations.getAnimation(index).getName();
|
||||
return animationName.length > 0 ? animationName : null;
|
||||
}).filter(Boolean);
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
return objectName
|
||||
? projectScopedContainersAccessor
|
||||
.get()
|
||||
.getObjectsContainersList()
|
||||
.getAnimationNamesOfObject(objectName)
|
||||
.toJSArray()
|
||||
: [];
|
||||
};
|
||||
|
||||
const animationNames = getAnimationNames();
|
||||
const canAutocomplete = !eventsFunctionsExtension || eventsBasedObject;
|
||||
const animationNames = canAutocomplete ? getAnimationNames() : [];
|
||||
|
||||
const isCurrentValueInAnimationNamesList = !!animationNames.find(
|
||||
animationName => `"${animationName}"` === props.value
|
||||
);
|
||||
|
||||
const canAutocomplete = !eventsFunctionsExtension || eventsBasedObject;
|
||||
|
||||
// If the current value is not in the list of animation names, display an expression field.
|
||||
const [isExpressionField, setIsExpressionField] = React.useState(
|
||||
(!!props.value && !isCurrentValueInAnimationNamesList) || !canAutocomplete
|
||||
|
Reference in New Issue
Block a user