mirror of
https://github.com/Heretek-AI/GDevelop.git
synced 2026-07-23 18:45:48 -04:00
235 lines
10 KiB
C++
235 lines
10 KiB
C++
/**
|
|
|
|
GDevelop - Timed Event Extension
|
|
Copyright (c) 2011-2015 Florian Rival (Florian.Rival@gmail.com)
|
|
This project is released under the MIT License.
|
|
*/
|
|
|
|
#include "GDCpp/ExtensionBase.h"
|
|
#include "GDCore/Tools/Version.h"
|
|
|
|
#include "TimedEvent.h"
|
|
#include "TimedEventsManager.h"
|
|
#include "GDCpp/CommonTools.h"
|
|
#include "GDCore/Events/EventsCodeGenerator.h"
|
|
#include "GDCore/Events/ExpressionsCodeGeneration.h"
|
|
#include "GDCore/Events/EventsCodeGenerationContext.h"
|
|
#include "GDCore/Events/EventsCodeNameMangler.h"
|
|
#include "GDCpp/RuntimeScene.h"
|
|
#include "GDCore/Events/EventsCodeGenerationContext.h"
|
|
|
|
/**
|
|
* \brief This class declares information about the extension.
|
|
*/
|
|
class Extension : public ExtensionBase
|
|
{
|
|
public:
|
|
|
|
/**
|
|
* Constructor of an extension declares everything the extension contains: objects, actions, conditions and expressions.
|
|
*/
|
|
Extension()
|
|
{
|
|
SetExtensionInformation("TimedEvent",
|
|
_("Timed events"),
|
|
_("Event which launch its conditions and actions only after a amount of time is reached."),
|
|
"Florian Rival",
|
|
"Open source (MIT License)");
|
|
|
|
#if defined(GD_IDE_ONLY)
|
|
|
|
|
|
AddEvent("TimedEvent",
|
|
_("Timed event"),
|
|
_("Event which launch its conditions and actions only after a amount of time is reached."),
|
|
"",
|
|
"CppPlatform/Extensions/timedevent16.png",
|
|
std::shared_ptr<gd::BaseEvent>(new TimedEvent))
|
|
.SetCodeGenerator([](gd::BaseEvent & event_, gd::EventsCodeGenerator & codeGenerator, gd::EventsCodeGenerationContext & context) {
|
|
TimedEvent & event = dynamic_cast<TimedEvent&>(event_);
|
|
|
|
codeGenerator.AddIncludeFile("TimedEvent/TimedEventTools.h");
|
|
|
|
//Notify parent timed event that they have a child
|
|
for (unsigned int i = 0;i<TimedEvent::codeGenerationCurrentParents.size();++i)
|
|
TimedEvent::codeGenerationCurrentParents[i]->codeGenerationChildren.push_back(&event);
|
|
|
|
//And register this event as potential parent
|
|
TimedEvent::codeGenerationCurrentParents.push_back(&event);
|
|
event.codeGenerationChildren.clear();
|
|
|
|
//Prepare code for computing timeout
|
|
gd::String timeOutCode;
|
|
gd::CallbacksForGeneratingExpressionCode callbacks(timeOutCode, codeGenerator, context);
|
|
gd::ExpressionParser parser(event.GetTimeoutExpression());
|
|
if (!parser.ParseMathExpression(codeGenerator.GetPlatform(), codeGenerator.GetProject(), codeGenerator.GetLayout(), callbacks) || timeOutCode.empty()) timeOutCode = "0";
|
|
|
|
//Prepare name
|
|
gd::String codeName = !event.GetName().empty() ? "GDNamedTimedEvent_"+codeGenerator.ConvertToString(event.GetName()) : "GDTimedEvent_"+ToString(&event);
|
|
|
|
gd::String outputCode;
|
|
|
|
outputCode += "if ( static_cast<double>(GDpriv::TimedEvents::UpdateAndGetTimeOf(*runtimeContext->scene, \""+codeName+"\"))/1000000.0 > "+timeOutCode+")";
|
|
outputCode += "{";
|
|
|
|
outputCode += codeGenerator.GenerateConditionsListCode(event.GetConditions(), context);
|
|
|
|
gd::String ifPredicat;
|
|
for (unsigned int i = 0;i<event.GetConditions().size();++i)
|
|
{
|
|
if (i!=0) ifPredicat += " && ";
|
|
ifPredicat += "condition"+ToString(i)+"IsTrue";
|
|
}
|
|
|
|
if ( !ifPredicat.empty() ) outputCode += "if (" +ifPredicat+ ")\n";
|
|
outputCode += "{\n";
|
|
outputCode += codeGenerator.GenerateActionsListCode(event.GetActions(), context);
|
|
if ( event.HasSubEvents() ) //Sub events
|
|
{
|
|
outputCode += "\n{\n";
|
|
outputCode += codeGenerator.GenerateEventsListCode(event.GetSubEvents(), context);
|
|
outputCode += "}\n";
|
|
}
|
|
|
|
outputCode += "}\n";
|
|
|
|
outputCode += "}";
|
|
|
|
//This event cannot be a parent of other TimedEvent anymore
|
|
if (!TimedEvent::codeGenerationCurrentParents.empty())
|
|
TimedEvent::codeGenerationCurrentParents.pop_back();
|
|
else
|
|
std::cout << "Error! CodeGenerationCurrentParents cannot be empty!";
|
|
|
|
return outputCode;
|
|
});
|
|
|
|
AddAction("ResetTimedEvent",
|
|
_("Reset a timed event"),
|
|
_("Reset a timed event"),
|
|
_("Reset the timed event(s) called _PARAM1_"),
|
|
_("Timed events"),
|
|
"CppPlatform/Extensions/timedevent24.png",
|
|
"CppPlatform/Extensions/timedevent16.png")
|
|
.AddCodeOnlyParameter("currentScene", "")
|
|
.AddParameter("", _("Name"))
|
|
.codeExtraInformation.SetCustomCodeGenerator([](gd::Instruction & instruction, gd::EventsCodeGenerator & codeGenerator, gd::EventsCodeGenerationContext & context) {
|
|
codeGenerator.AddIncludeFile("TimedEvent/TimedEventTools.h");
|
|
|
|
gd::String codeName = "GDNamedTimedEvent_"+codeGenerator.ConvertToString(instruction.GetParameter(1).GetPlainString());
|
|
return "GDpriv::TimedEvents::Reset(*runtimeContext->scene, \""+codeName+"\");\n";
|
|
|
|
return gd::String("");
|
|
});
|
|
|
|
AddAction("ResetTimedEventAndSubs",
|
|
_("Reset a timed event and sub events"),
|
|
_("Reset a timed events, as well as all of its sub events."),
|
|
_("Reset timed events called _PARAM1_ and their sub events"),
|
|
_("Timed events"),
|
|
"CppPlatform/Extensions/timedevent24.png",
|
|
"CppPlatform/Extensions/timedevent16.png")
|
|
.AddParameter("", _("Name"))
|
|
.codeExtraInformation.SetCustomCodeGenerator([](gd::Instruction & instruction, gd::EventsCodeGenerator & codeGenerator, gd::EventsCodeGenerationContext & context) {
|
|
codeGenerator.AddIncludeFile("TimedEvent/TimedEventTools.h");
|
|
|
|
for (unsigned int i = 0;i<TimedEvent::codeGenerationCurrentParents.size();++i)
|
|
{
|
|
if ( TimedEvent::codeGenerationCurrentParents[i] == NULL )
|
|
{
|
|
std::cout << "WARNING : NULL timed event in codeGenerationCurrentParents";
|
|
continue;
|
|
}
|
|
|
|
if (TimedEvent::codeGenerationCurrentParents[i]->GetName() == instruction.GetParameter(0).GetPlainString())
|
|
{
|
|
TimedEvent & timedEvent = *TimedEvent::codeGenerationCurrentParents[i];
|
|
|
|
gd::String code;
|
|
{
|
|
gd::String codeName = !timedEvent.GetName().empty() ? "GDNamedTimedEvent_"+codeGenerator.ConvertToString(timedEvent.GetName()) : "GDTimedEvent_"+ToString(&timedEvent);
|
|
code += "GDpriv::TimedEvents::Reset(*runtimeContext->scene, \""+codeName+"\");\n";
|
|
}
|
|
for (unsigned int j = 0;j<timedEvent.codeGenerationChildren.size();++j)
|
|
{
|
|
gd::String codeName = !timedEvent.codeGenerationChildren[j]->GetName().empty() ? "GDNamedTimedEvent_"+codeGenerator.ConvertToString(timedEvent.codeGenerationChildren[j]->GetName()) : "GDTimedEvent_"+ToString(timedEvent.codeGenerationChildren[j]);
|
|
code += "GDpriv::TimedEvents::Reset(*runtimeContext->scene, \""+codeName+"\");\n";
|
|
}
|
|
return code;
|
|
}
|
|
}
|
|
|
|
return gd::String("");
|
|
})
|
|
.SetIncludeFile("TimedEvent/TimedEventTools.h");
|
|
#endif
|
|
|
|
GD_COMPLETE_EXTENSION_COMPILATION_INFORMATION();
|
|
};
|
|
|
|
#if defined(GD_IDE_ONLY)
|
|
bool HasDebuggingProperties() const { return true; };
|
|
|
|
void GetPropertyForDebugger(RuntimeScene & scene, unsigned int propertyNb, gd::String & name, gd::String & value) const
|
|
{
|
|
unsigned int i = 0;
|
|
std::map < gd::String, ManualTimer >::const_iterator end = TimedEventsManager::managers[&scene].timedEvents.end();
|
|
for (std::map < gd::String, ManualTimer >::iterator iter = TimedEventsManager::managers[&scene].timedEvents.begin();iter != end;++iter)
|
|
{
|
|
if ( propertyNb == i )
|
|
{
|
|
name = iter->first;
|
|
//Unmangle name
|
|
if ( name.find("GDNamedTimedEvent_") == 0 && name.length() > 18 )
|
|
name = name.substr(18, name.length());
|
|
else
|
|
name = _("No name");
|
|
|
|
value = ToString(static_cast<double>(iter->second.GetTime())/1000000.0)+"s";
|
|
|
|
return;
|
|
}
|
|
|
|
++i;
|
|
}
|
|
}
|
|
|
|
bool ChangeProperty(RuntimeScene & scene, unsigned int propertyNb, gd::String newValue)
|
|
{
|
|
unsigned int i = 0;
|
|
std::map < gd::String, ManualTimer >::const_iterator end = TimedEventsManager::managers[&scene].timedEvents.end();
|
|
for (std::map < gd::String, ManualTimer >::iterator iter = TimedEventsManager::managers[&scene].timedEvents.begin();iter != end;++iter)
|
|
{
|
|
if ( propertyNb == i )
|
|
{
|
|
iter->second.SetTime(ToDouble(newValue)*1000000.0);
|
|
|
|
return true;
|
|
}
|
|
|
|
++i;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
unsigned int GetNumberOfProperties(RuntimeScene & scene) const
|
|
{
|
|
return TimedEventsManager::managers[&scene].timedEvents.size();
|
|
}
|
|
#endif
|
|
|
|
void SceneLoaded(RuntimeScene & scene)
|
|
{
|
|
TimedEventsManager::managers[&scene].timedEvents.clear();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Used by GDevelop to create the extension class
|
|
* -- Do not need to be modified. --
|
|
*/
|
|
extern "C" ExtensionBase * GD_EXTENSION_API CreateGDExtension() {
|
|
return new Extension;
|
|
}
|