mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
160 lines
6.0 KiB
C++
160 lines
6.0 KiB
C++
/*
|
|
* GDevelop Core
|
|
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
|
* reserved. This project is released under the MIT License.
|
|
*/
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include "GDCore/CommonTools.h"
|
|
#include "GDCore/Events/Builtin/GroupEvent.h"
|
|
#include "GDCore/Events/Builtin/LinkEvent.h"
|
|
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
|
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
|
#include "GDCore/Events/Tools/EventsCodeNameMangler.h"
|
|
#include "GDCore/Project/ExternalEvents.h"
|
|
#include "GDCore/Project/Layout.h"
|
|
#include "GDCore/Project/Object.h"
|
|
#include "GDCore/Project/Project.h"
|
|
#include "GDCore/Serialization/SerializerElement.h"
|
|
|
|
using namespace std;
|
|
|
|
namespace gd {
|
|
|
|
const EventsList* LinkEvent::GetLinkedEvents(const gd::Project& project) const {
|
|
const EventsList* events = nullptr;
|
|
if (project.HasExternalEventsNamed(GetTarget())) {
|
|
const gd::ExternalEvents& linkedExternalEvents = project.GetExternalEvents(GetTarget());
|
|
events = &linkedExternalEvents.GetEvents();
|
|
} else if (project.HasLayoutNamed(GetTarget())) {
|
|
const gd::Layout& linkedLayout = project.GetLayout(GetTarget());
|
|
events = &linkedLayout.GetEvents();
|
|
}
|
|
|
|
// If the link only includes an events group, search it inside the
|
|
// layout/external events
|
|
if (events != nullptr && includeConfig == INCLUDE_EVENTS_GROUP) {
|
|
std::size_t i = 0;
|
|
std::size_t eventsCount = events->GetEventsCount();
|
|
for (; i < eventsCount; ++i) {
|
|
std::shared_ptr<const GroupEvent> groupEvent =
|
|
std::dynamic_pointer_cast<const GroupEvent>(
|
|
events->GetEventSmartPtr(i));
|
|
if (groupEvent && groupEvent->GetName() == eventsGroupName) {
|
|
// Get its sub-events
|
|
events = &groupEvent->GetSubEvents();
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i >= eventsCount) // We didn't find the events group, return nullptr
|
|
events = nullptr;
|
|
}
|
|
|
|
return events;
|
|
}
|
|
|
|
void LinkEvent::ReplaceLinkByLinkedEvents(
|
|
const gd::Project& project,
|
|
EventsList& eventList,
|
|
std::size_t indexOfTheEventInThisList) {
|
|
linkWasInvalid = false;
|
|
// Finding what to link to.
|
|
const EventsList* eventsToInclude = GetLinkedEvents(project);
|
|
if (eventsToInclude != NULL) {
|
|
std::size_t firstEvent =
|
|
includeConfig == INCLUDE_BY_INDEX ? GetIncludeStart() : 0;
|
|
std::size_t lastEvent = includeConfig == INCLUDE_BY_INDEX
|
|
? GetIncludeEnd()
|
|
: eventsToInclude->size() - 1;
|
|
|
|
// Check bounds
|
|
if (firstEvent >= eventsToInclude->size()) {
|
|
std::cout << "Unable to get events from a link ( Invalid start )"
|
|
<< std::endl;
|
|
linkWasInvalid = true;
|
|
return;
|
|
}
|
|
if (lastEvent >= eventsToInclude->size()) {
|
|
std::cout << "Unable to get events from a link ( Invalid end )"
|
|
<< std::endl;
|
|
linkWasInvalid = true;
|
|
return;
|
|
}
|
|
if (firstEvent > lastEvent) {
|
|
std::cout << "Unable to get events from a link ( End is before start )"
|
|
<< std::endl;
|
|
linkWasInvalid = true;
|
|
return;
|
|
}
|
|
|
|
// Insert an empty event to replace the link event ( we'll delete the link
|
|
// event at the end ) ( If we just erase the link event without adding a
|
|
// blank event to replace it, the first event inserted by the link will not
|
|
// be preprocessed ( and it can be annoying if it require preprocessing,
|
|
// such as another link event ). )
|
|
gd::EmptyEvent emptyEvent;
|
|
eventList.InsertEvent(emptyEvent, indexOfTheEventInThisList);
|
|
eventList.InsertEvents(
|
|
*eventsToInclude, firstEvent, lastEvent, indexOfTheEventInThisList + 1);
|
|
|
|
// Delete the link event ( which is now at the end of the list of events
|
|
// we've just inserted )
|
|
eventList.RemoveEvent(indexOfTheEventInThisList + 1 +
|
|
static_cast<unsigned>(lastEvent - firstEvent) + 1);
|
|
} else {
|
|
std::cout << "Unable to get events from a link." << std::endl;
|
|
linkWasInvalid = true;
|
|
|
|
// Delete the link event
|
|
eventList.RemoveEvent(indexOfTheEventInThisList);
|
|
return;
|
|
}
|
|
}
|
|
|
|
LinkEvent::~LinkEvent() {}
|
|
|
|
void LinkEvent::SerializeTo(SerializerElement& element) const {
|
|
SerializerElement& includeElement = element.AddChild("include").SetAttribute(
|
|
"includeConfig", static_cast<int>(GetIncludeConfig()));
|
|
|
|
if (GetIncludeConfig() == INCLUDE_EVENTS_GROUP) {
|
|
includeElement.SetAttribute("eventsGroup", GetEventsGroupName());
|
|
} else if (GetIncludeConfig() == INCLUDE_BY_INDEX) {
|
|
includeElement.SetAttribute("start", static_cast<int>(GetIncludeStart()));
|
|
includeElement.SetAttribute("end", static_cast<int>(GetIncludeEnd()));
|
|
}
|
|
|
|
element.AddChild("target").SetValue(GetTarget());
|
|
}
|
|
|
|
void LinkEvent::UnserializeFrom(gd::Project& project,
|
|
const SerializerElement& element) {
|
|
SerializerElement& includeElement = element.GetChild("include", 0, "Limites");
|
|
|
|
SetTarget(element.GetChild("target", 0, "Scene").GetValue().GetString());
|
|
|
|
if (includeElement.HasAttribute("includeAll")) {
|
|
// Compatibility with GDevelop <= 4.0.92
|
|
if (includeElement.GetBoolAttribute("includeAll", true)) {
|
|
SetIncludeAllEvents();
|
|
} else {
|
|
SetIncludeStartAndEnd(includeElement.GetIntAttribute("start"),
|
|
includeElement.GetIntAttribute("end"));
|
|
}
|
|
} else {
|
|
// GDevelop > 4.0.92
|
|
IncludeConfig config = static_cast<IncludeConfig>(
|
|
includeElement.GetIntAttribute("includeConfig", 0));
|
|
if (config == INCLUDE_ALL)
|
|
SetIncludeAllEvents();
|
|
else if (config == INCLUDE_EVENTS_GROUP)
|
|
SetIncludeEventsGroup(includeElement.GetStringAttribute("eventsGroup"));
|
|
else if (config == INCLUDE_BY_INDEX)
|
|
SetIncludeStartAndEnd(includeElement.GetIntAttribute("start"),
|
|
includeElement.GetIntAttribute("end"));
|
|
}
|
|
}
|
|
|
|
} // namespace gd
|