/** 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(new TimedEvent)) .SetCodeGenerator([](gd::BaseEvent & event_, gd::EventsCodeGenerator & codeGenerator, gd::EventsCodeGenerationContext & context) { TimedEvent & event = dynamic_cast(event_); codeGenerator.AddIncludeFile("TimedEvent/TimedEventTools.h"); //Notify parent timed event that they have a child for (unsigned int i = 0;icodeGenerationChildren.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(GDpriv::TimedEvents::UpdateAndGetTimeOf(*runtimeContext->scene, \""+codeName+"\"))/1000000.0 > "+timeOutCode+")"; outputCode += "{"; outputCode += codeGenerator.GenerateConditionsListCode(event.GetConditions(), context); gd::String ifPredicat; for (unsigned int i = 0;iscene, \""+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;iGetName() == 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;jGetName().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(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; }