mirror of
https://github.com/Heretek-AI/GDevelop.git
synced 2026-07-21 17:45:25 -04:00
e5631383dd
* Declare objects lists used by actions only when actions are launched for standard events (both GDCpp and GDJS) * Enable the object list reuse optimisation in GDCpp as done in GDJS.
165 lines
7.1 KiB
C++
165 lines
7.1 KiB
C++
/*
|
|
* GDevelop Core
|
|
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights reserved.
|
|
* This project is released under the MIT License.
|
|
*/
|
|
/**
|
|
* @file Tests covering events of GDevelop Core.
|
|
*/
|
|
#include "catch.hpp"
|
|
#include "GDCore/CommonTools.h"
|
|
#include "GDCore/Tools/VersionWrapper.h"
|
|
#include "GDCore/Project/Project.h"
|
|
#include "GDCore/Project/Layout.h"
|
|
#include "GDCore/Extensions/Platform.h"
|
|
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
|
#include <memory>
|
|
|
|
TEST_CASE( "EventsCodeGenerationContext", "[common][events]" ) {
|
|
/**
|
|
* Generate a tree of contexts with declared objects as below:
|
|
* c1 -> c1.object1, c1.object2, c1.empty1 (empty list request)
|
|
* / \
|
|
* c2.object1 <- c2 c3 -> c3.object1, c1.object2
|
|
* / \
|
|
* c4 c5 -> c5.object1, c5.empty1 (empty list request), c1.object2
|
|
*/
|
|
|
|
unsigned int maxDepth = 0;
|
|
gd::EventsCodeGenerationContext c1(&maxDepth);
|
|
c1.ObjectsListNeeded("c1.object1");
|
|
c1.ObjectsListNeeded("c1.object2");
|
|
c1.EmptyObjectsListNeeded("c1.empty1");
|
|
|
|
gd::EventsCodeGenerationContext c2;
|
|
c2.InheritsFrom(c1);
|
|
c2.ObjectsListNeeded("c2.object1");
|
|
|
|
gd::EventsCodeGenerationContext c3;
|
|
c3.InheritsFrom(c1);
|
|
c3.ObjectsListNeeded("c3.object1");
|
|
c3.ObjectsListNeeded("c1.object2");
|
|
|
|
gd::EventsCodeGenerationContext c4;
|
|
c4.InheritsFrom(c2);
|
|
|
|
gd::EventsCodeGenerationContext c5;
|
|
c5.InheritsFrom(c2);
|
|
c5.EmptyObjectsListNeeded("c5.empty1");
|
|
c5.ObjectsListNeeded("c5.object1");
|
|
c5.ObjectsListNeeded("c1.object2");
|
|
|
|
SECTION("Parenting") {
|
|
REQUIRE( c2.GetParentContext() == &c1 );
|
|
REQUIRE( c3.GetParentContext() == &c1 );
|
|
REQUIRE( c4.GetParentContext() == &c2 );
|
|
REQUIRE( c5.GetParentContext() == &c2 );
|
|
}
|
|
|
|
SECTION("Depth") {
|
|
REQUIRE( maxDepth == 2 );
|
|
|
|
REQUIRE( c1.GetContextDepth() == 0 );
|
|
REQUIRE( c2.GetContextDepth() == 1 );
|
|
REQUIRE( c3.GetContextDepth() == 1 );
|
|
REQUIRE( c4.GetContextDepth() == 2 );
|
|
REQUIRE( c5.GetContextDepth() == 2 );
|
|
}
|
|
|
|
SECTION("Object list needed") {
|
|
REQUIRE( c1.GetObjectsListsAlreadyDeclared() == std::set<gd::String>() );
|
|
REQUIRE( c1.GetObjectsListsToBeDeclared() == std::set<gd::String>({"c1.object1", "c1.object2"}) );
|
|
REQUIRE( c1.GetObjectsListsToBeDeclaredEmpty() == std::set<gd::String>({"c1.empty1"}) );
|
|
REQUIRE( c1.GetAllObjectsToBeDeclared() == std::set<gd::String>({"c1.object1", "c1.object2", "c1.empty1"}) );
|
|
|
|
REQUIRE( c2.GetObjectsListsAlreadyDeclared() == std::set<gd::String>({"c1.object1", "c1.object2", "c1.empty1"}) );
|
|
REQUIRE( c2.GetObjectsListsToBeDeclared() == std::set<gd::String>({"c2.object1"}) );
|
|
REQUIRE( c2.GetObjectsListsToBeDeclaredEmpty() == std::set<gd::String>() );
|
|
REQUIRE( c2.GetAllObjectsToBeDeclared() == std::set<gd::String>({"c2.object1"}) );
|
|
|
|
REQUIRE( c3.GetObjectsListsAlreadyDeclared() == std::set<gd::String>({"c1.object1", "c1.object2", "c1.empty1"}) );
|
|
REQUIRE( c3.GetObjectsListsToBeDeclared() == std::set<gd::String>({"c3.object1", "c1.object2"}) );
|
|
REQUIRE( c3.GetObjectsListsToBeDeclaredEmpty() == std::set<gd::String>() );
|
|
REQUIRE( c3.GetAllObjectsToBeDeclared() == std::set<gd::String>({"c3.object1", "c1.object2"}) );
|
|
|
|
REQUIRE( c5.GetObjectsListsAlreadyDeclared() == std::set<gd::String>({"c1.object1", "c1.object2", "c1.empty1", "c2.object1"}) );
|
|
REQUIRE( c5.GetObjectsListsToBeDeclared() == std::set<gd::String>({"c5.object1", "c1.object2"}) );
|
|
REQUIRE( c5.GetObjectsListsToBeDeclaredEmpty() == std::set<gd::String>({"c5.empty1"}) );
|
|
REQUIRE( c5.GetAllObjectsToBeDeclared() == std::set<gd::String>({"c5.object1", "c5.empty1", "c1.object2"}) );
|
|
}
|
|
|
|
SECTION("ObjectAlreadyDeclared") {
|
|
REQUIRE( c1.ObjectAlreadyDeclared("c1.object1") == false );
|
|
REQUIRE( c2.ObjectAlreadyDeclared("c1.object1") == true );
|
|
REQUIRE( c3.ObjectAlreadyDeclared("c1.object1") == true );
|
|
REQUIRE( c4.ObjectAlreadyDeclared("c1.object1") == true );
|
|
REQUIRE( c5.ObjectAlreadyDeclared("c1.object1") == true );
|
|
|
|
REQUIRE( c2.ObjectAlreadyDeclared("c2.object1") == false );
|
|
REQUIRE( c1.ObjectAlreadyDeclared("c2.object1") == false );
|
|
REQUIRE( c3.ObjectAlreadyDeclared("c2.object1") == false );
|
|
REQUIRE( c4.ObjectAlreadyDeclared("c2.object1") == true );
|
|
REQUIRE( c5.ObjectAlreadyDeclared("c2.object1") == true );
|
|
|
|
REQUIRE( c3.ObjectAlreadyDeclared("some object") == false );
|
|
c3.SetObjectDeclared("some object");
|
|
REQUIRE( c3.ObjectAlreadyDeclared("some object") == true );
|
|
}
|
|
|
|
SECTION("Object list last depth") {
|
|
REQUIRE( c1.GetLastDepthObjectListWasNeeded("c1.object1") == 0 );
|
|
REQUIRE( c2.GetLastDepthObjectListWasNeeded("c2.object1") == 1 );
|
|
REQUIRE( c3.GetLastDepthObjectListWasNeeded("c3.object1") == 1 );
|
|
REQUIRE( c4.GetLastDepthObjectListWasNeeded("c2.object1") == 1 );
|
|
REQUIRE( c5.GetLastDepthObjectListWasNeeded("c1.object2") == 2 );
|
|
REQUIRE( c5.GetLastDepthObjectListWasNeeded("c2.object1") == 1 );
|
|
REQUIRE( c5.GetLastDepthObjectListWasNeeded("c5.object1") == 2 );
|
|
}
|
|
|
|
SECTION("SetCurrentObject") {
|
|
REQUIRE( c3.GetCurrentObject() == "" );
|
|
c3.SetCurrentObject("current object");
|
|
REQUIRE( c3.GetCurrentObject() == "current object" );
|
|
c3.SetNoCurrentObject();
|
|
REQUIRE( c3.GetCurrentObject() == "" );
|
|
}
|
|
|
|
SECTION("Reuse") {
|
|
/**
|
|
* Generate a tree of contexts with declared objects as below:
|
|
* ...
|
|
* \
|
|
* c5 -> c5.object1, c5.empty1 (empty list request), c1.object2
|
|
* /
|
|
* c6 (reuse c5) -> c5.object1, c6.object3
|
|
* /
|
|
* c7 -> c5.object1
|
|
*/
|
|
gd::EventsCodeGenerationContext c6;
|
|
c6.Reuse(c5);
|
|
c6.ObjectsListNeeded("c5.object1");
|
|
c6.ObjectsListNeeded("c6.object3");
|
|
|
|
gd::EventsCodeGenerationContext c7;
|
|
c7.InheritsFrom(c6);
|
|
c7.ObjectsListNeeded("c5.object1");
|
|
c7.ObjectsListNeeded("c6.object3");
|
|
|
|
//c6 is reusing c5 context so it has the same depth:
|
|
REQUIRE( c6.GetParentContext() == &c5 );
|
|
REQUIRE( c6.GetContextDepth() == c5.GetContextDepth() );
|
|
REQUIRE( c6.GetLastDepthObjectListWasNeeded("c6.object3") == 2 );
|
|
|
|
//c6 reuse the objects lists from c5:
|
|
REQUIRE( c6.IsSameObjectsList("c5.object1", c5) == true );
|
|
REQUIRE( c6.IsSameObjectsList("c5.empty1", c5) == true );
|
|
REQUIRE( c6.GetLastDepthObjectListWasNeeded("c5.object1") == c5.GetLastDepthObjectListWasNeeded("c5.object1") );
|
|
REQUIRE( c6.GetLastDepthObjectListWasNeeded("c5.empty1") == c5.GetLastDepthObjectListWasNeeded("c5.empty1") );
|
|
|
|
REQUIRE( c7.GetParentContext() == &c6 );
|
|
REQUIRE( c7.GetContextDepth() == 3 );
|
|
REQUIRE( c7.IsSameObjectsList("c5.object1", c6) == false );
|
|
REQUIRE( c7.IsSameObjectsList("c6.object3", c6) == false );
|
|
}
|
|
}
|