Allow live-reload of particle emitter parameters file.
Allow also specifying emission rate instead of emission interval. Allow emitting multiple particles per frame if necessary. Restored the "effect" component category in the editor. ParticleEmitter & DecalSet belong to it now.
This commit is contained in:
Родитель
7397399c7c
Коммит
3c244f9755
|
@ -5,7 +5,7 @@
|
|||
<numparticles value="10" />
|
||||
<activetime value="2" />
|
||||
<inactivetime value="0" />
|
||||
<interval value="0.075" />
|
||||
<emissionrate value="13.333" />
|
||||
<sorting enable="true" />
|
||||
<rotationspeed min="-60" max="60" />
|
||||
<direction min="-0.15 1 -0.15" max="0.15 1 0.15" />
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<numparticles value="10" />
|
||||
<activetime value="0.1" />
|
||||
<inactivetime value="0" />
|
||||
<interval value="0.02" />
|
||||
<emissionrate value="50" />
|
||||
<sorting enable="true" />
|
||||
<direction min="-1 0 -1" max="1 1 1" />
|
||||
<velocity min="0.5" max="1" />
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<emittersize value="0.3 0.3 0.3" />
|
||||
<activetime value="0.2" />
|
||||
<inactivetime value="0" />
|
||||
<interval value="0.02" />
|
||||
<emissionrate value="50" />
|
||||
<sorting enable="true" />
|
||||
<direction min="-1 0.5 -1" max="1 1 1" />
|
||||
<velocity min="2" max="3" />
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<numparticles value="5" />
|
||||
<activetime value="0.1" />
|
||||
<inactivetime value="0" />
|
||||
<interval value="0.02" />
|
||||
<emissionrate value="50" />
|
||||
<sorting enable="true" />
|
||||
<direction min="-1 0 -1" max="1 1 1" />
|
||||
<velocity min="0.5" max="1" />
|
||||
|
|
|
@ -1035,6 +1035,7 @@ Most of the parameters can take either a single value, or minimum and maximum va
|
|||
<activetime value="t" />
|
||||
<inactivetime value="t" />
|
||||
<interval min="t1" max="t2" />
|
||||
<emissionrate min="t1" max="t2" />
|
||||
<particlesize min="x1 y1" max="x2 y2" />
|
||||
<timetolive min="t1" max="t2" />
|
||||
<velocity min="x1" max="x2" />
|
||||
|
@ -1046,7 +1047,11 @@ Most of the parameters can take either a single value, or minimum and maximum va
|
|||
</particleemitter>
|
||||
\endcode
|
||||
|
||||
Note: zero active or inactive time period means infinite. Instead of defining a single color element, several colorfade elements can be defined in time order to describe how the particles change color over time.
|
||||
Notes:
|
||||
|
||||
- Zero active or inactive time period means infinite.
|
||||
- Interval is the reciprocal of emission rate. Either can be used to define the rate at which new particles are emitted.
|
||||
- Instead of defining a single color element, several colorfade elements can be defined in time order to describe how the particles change color over time.
|
||||
|
||||
|
||||
\page Zones Zones
|
||||
|
|
|
@ -886,7 +886,7 @@ static void RegisterParticleEmitter(asIScriptEngine* engine)
|
|||
{
|
||||
RegisterDrawable<ParticleEmitter>(engine, "ParticleEmitter");
|
||||
engine->RegisterObjectMethod("ParticleEmitter", "void SetEmitting(bool, bool)", asMETHOD(ParticleEmitter, SetEmitting), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("ParticleEmitter", "bool set_parameters(XMLFile@+ file)", asMETHOD(ParticleEmitter, SetParameters), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("ParticleEmitter", "void set_parameters(XMLFile@+ file)", asMETHOD(ParticleEmitter, SetParameters), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("ParticleEmitter", "XMLFile@+ get_parameters() const", asMETHOD(ParticleEmitter, GetParameters), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("ParticleEmitter", "void set_material(Material@+)", asMETHOD(ParticleEmitter, SetMaterial), asCALL_THISCALL);
|
||||
engine->RegisterObjectMethod("ParticleEmitter", "Material@+ get_material() const", asMETHOD(ParticleEmitter, GetMaterial), asCALL_THISCALL);
|
||||
|
|
|
@ -55,7 +55,7 @@ static const unsigned STATIC_ELEMENT_MASK = MASK_POSITION | MASK_NORMAL | MASK_T
|
|||
static const unsigned SKINNED_ELEMENT_MASK = MASK_POSITION | MASK_NORMAL | MASK_TEXCOORD1 | MASK_TANGENT | MASK_BLENDWEIGHTS |
|
||||
MASK_BLENDINDICES;
|
||||
|
||||
extern const char* GEOMETRY_CATEGORY;
|
||||
extern const char* EFFECT_CATEGORY;
|
||||
|
||||
static DecalVertex ClipEdge(const DecalVertex& v0, const DecalVertex& v1, float d0, float d1, bool skinned)
|
||||
{
|
||||
|
@ -180,7 +180,7 @@ DecalSet::~DecalSet()
|
|||
|
||||
void DecalSet::RegisterObject(Context* context)
|
||||
{
|
||||
context->RegisterFactory<DecalSet>(GEOMETRY_CATEGORY);
|
||||
context->RegisterFactory<DecalSet>(EFFECT_CATEGORY);
|
||||
|
||||
ACCESSOR_ATTRIBUTE(DecalSet, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
|
||||
ACCESSOR_ATTRIBUTE(DecalSet, VAR_RESOURCEREF, "Material", GetMaterialAttr, SetMaterialAttr, ResourceRef, ResourceRef(Material::GetTypeStatic()), AM_DEFAULT);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "ParticleEmitter.h"
|
||||
#include "Profiler.h"
|
||||
#include "ResourceCache.h"
|
||||
#include "ResourceEvents.h"
|
||||
#include "Scene.h"
|
||||
#include "SceneEvents.h"
|
||||
#include "XMLFile.h"
|
||||
|
@ -36,7 +37,9 @@
|
|||
namespace Urho3D
|
||||
{
|
||||
|
||||
extern const char* GEOMETRY_CATEGORY;
|
||||
const char* EFFECT_CATEGORY = "Effect";
|
||||
|
||||
static const unsigned MAX_PARTICLES_IN_FRAME = 100;
|
||||
|
||||
OBJECTTYPESTATIC(ParticleEmitter);
|
||||
|
||||
|
@ -81,7 +84,7 @@ ParticleEmitter::~ParticleEmitter()
|
|||
|
||||
void ParticleEmitter::RegisterObject(Context* context)
|
||||
{
|
||||
context->RegisterFactory<ParticleEmitter>(GEOMETRY_CATEGORY);
|
||||
context->RegisterFactory<ParticleEmitter>(EFFECT_CATEGORY);
|
||||
|
||||
ACCESSOR_ATTRIBUTE(ParticleEmitter, VAR_BOOL, "Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
|
||||
ACCESSOR_ATTRIBUTE(ParticleEmitter, VAR_RESOURCEREF, "Parameter Source", GetParameterSourceAttr, SetParameterSourceAttr, ResourceRef, ResourceRef(XMLFile::GetTypeStatic()), AM_DEFAULT);
|
||||
|
@ -136,18 +139,27 @@ void ParticleEmitter::Update(const FrameInfo& frame)
|
|||
emitting_ = true;
|
||||
periodTimer_ -= inactiveTime_;
|
||||
}
|
||||
// If emitter has an indefinite stop interval, keep period timer reset to allow restarting emission in the editor
|
||||
if (inactiveTime_ == 0.0f)
|
||||
periodTimer_ = 0.0f;
|
||||
}
|
||||
|
||||
// Check for emitting a new particle
|
||||
// Check for emitting new particles
|
||||
if (emitting_)
|
||||
{
|
||||
emissionTimer_ += lastTimeStep_;
|
||||
if (emissionTimer_ > 0.0f)
|
||||
unsigned counter = MAX_PARTICLES_IN_FRAME;
|
||||
while (emissionTimer_ > 0.0f && counter)
|
||||
{
|
||||
emissionTimer_ -= Lerp(intervalMin_, intervalMax_, Random(1.0f));
|
||||
if (EmitNewParticle())
|
||||
{
|
||||
--counter;
|
||||
needCommit = true;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Update existing particles
|
||||
|
@ -233,137 +245,27 @@ void ParticleEmitter::Update(const FrameInfo& frame)
|
|||
Commit();
|
||||
}
|
||||
|
||||
bool ParticleEmitter::SetParameters(XMLFile* file)
|
||||
void ParticleEmitter::SetParameters(XMLFile* file)
|
||||
{
|
||||
ResourceCache* cache = GetSubsystem<ResourceCache>();
|
||||
if (!file || !cache)
|
||||
return false;
|
||||
if (file == parameterSource_)
|
||||
return;
|
||||
|
||||
XMLElement rootElem = file->GetRoot();
|
||||
if (!rootElem)
|
||||
return false;
|
||||
if (parameterSource_)
|
||||
UnsubscribeFromEvent(parameterSource_, E_RELOADFINISHED);
|
||||
|
||||
if (file && !file->GetRoot())
|
||||
{
|
||||
LOGERROR("Particle emitter parameter file does not have a valid root element");
|
||||
return;
|
||||
}
|
||||
|
||||
parameterSource_ = file;
|
||||
|
||||
if (rootElem.HasChild("material"))
|
||||
SetMaterial(cache->GetResource<Material>(rootElem.GetChild("material").GetAttribute("name")));
|
||||
|
||||
if (rootElem.HasChild("numparticles"))
|
||||
SetNumParticles(rootElem.GetChild("numparticles").GetInt("value"));
|
||||
|
||||
if (rootElem.HasChild("updateinvisible"))
|
||||
updateInvisible_ = rootElem.GetChild("updateinvisible").GetBool("enable");
|
||||
|
||||
if (rootElem.HasChild("relative"))
|
||||
relative_ = rootElem.GetChild("relative").GetBool("enable");
|
||||
|
||||
if (rootElem.HasChild("scaled"))
|
||||
scaled_ = rootElem.GetChild("scaled").GetBool("enable");
|
||||
|
||||
if (rootElem.HasChild("sorted"))
|
||||
sorted_ = rootElem.GetChild("sorted").GetBool("enable");
|
||||
|
||||
if (rootElem.HasChild("animlodbias"))
|
||||
SetAnimationLodBias(rootElem.GetChild("relative").GetFloat("value"));
|
||||
|
||||
if (rootElem.HasChild("emittertype"))
|
||||
{
|
||||
String type = rootElem.GetChild("emittertype").GetAttributeLower("value");
|
||||
if (type == "point")
|
||||
emitterType_ = EMITTER_POINT;
|
||||
else if (type == "box")
|
||||
emitterType_ = EMITTER_BOX;
|
||||
else if (type == "sphere")
|
||||
emitterType_ = EMITTER_SPHERE;
|
||||
else
|
||||
LOGERROR("Unknown particle emitter type " + type);
|
||||
}
|
||||
|
||||
if (rootElem.HasChild("emittersize"))
|
||||
emitterSize_ = rootElem.GetChild("emittersize").GetVector3("value");
|
||||
|
||||
if (rootElem.HasChild("emitterradius"))
|
||||
emitterSize_.x_ = rootElem.GetChild("emitterradius").GetFloat("value");
|
||||
|
||||
if (rootElem.HasChild("direction"))
|
||||
GetVector3MinMax(rootElem.GetChild("direction"), directionMin_, directionMax_);
|
||||
|
||||
if (rootElem.HasChild("constantforce"))
|
||||
constanceForce_ = rootElem.GetChild("constantforce").GetVector3("value");
|
||||
|
||||
if (rootElem.HasChild("dampingforce"))
|
||||
dampingForce_ = rootElem.GetChild("dampingforce").GetFloat("value");
|
||||
|
||||
if (rootElem.HasChild("activetime"))
|
||||
activeTime_ = rootElem.GetChild("activetime").GetFloat("value");
|
||||
if (activeTime_ < 0.0f)
|
||||
activeTime_ = M_INFINITY;
|
||||
|
||||
if (rootElem.HasChild("inactivetime"))
|
||||
inactiveTime_ = rootElem.GetChild("inactivetime").GetFloat("value");
|
||||
if (inactiveTime_ < 0.0f)
|
||||
inactiveTime_ = M_INFINITY;
|
||||
|
||||
if (rootElem.HasChild("interval"))
|
||||
GetFloatMinMax(rootElem.GetChild("interval"), intervalMin_, intervalMax_);
|
||||
|
||||
if (rootElem.HasChild("particlesize"))
|
||||
GetVector2MinMax(rootElem.GetChild("particlesize"), sizeMin_, sizeMax_);
|
||||
|
||||
if (rootElem.HasChild("timetolive"))
|
||||
GetFloatMinMax(rootElem.GetChild("timetolive"), timeToLiveMin_, timeToLiveMax_);
|
||||
|
||||
if (rootElem.HasChild("velocity"))
|
||||
GetFloatMinMax(rootElem.GetChild("velocity"), velocityMin_, velocityMax_);
|
||||
|
||||
if (rootElem.HasChild("rotation"))
|
||||
GetFloatMinMax(rootElem.GetChild("rotation"), rotationMin_, rotationMax_);
|
||||
|
||||
if (rootElem.HasChild("rotationspeed"))
|
||||
GetFloatMinMax(rootElem.GetChild("rotationspeed"), rotationSpeedMin_, rotationSpeedMax_);
|
||||
|
||||
if (rootElem.HasChild("sizedelta"))
|
||||
{
|
||||
XMLElement deltaElem = rootElem.GetChild("sizedelta");
|
||||
if (deltaElem.HasAttribute("add"))
|
||||
sizeAdd_ = deltaElem.GetFloat("add");
|
||||
if (deltaElem.HasAttribute("mul"))
|
||||
sizeMul_ = deltaElem.GetFloat("mul");
|
||||
}
|
||||
|
||||
if (rootElem.HasChild("color"))
|
||||
SetParticleColor(rootElem.GetChild("color").GetColor("value"));
|
||||
|
||||
if (rootElem.HasChild("colorfade"))
|
||||
{
|
||||
Vector<ColorFade> fades;
|
||||
XMLElement colorFadeElem = rootElem.GetChild("colorfade");
|
||||
while (colorFadeElem)
|
||||
{
|
||||
fades.Push(ColorFade(colorFadeElem.GetColor("color"), colorFadeElem.GetFloat("time")));
|
||||
|
||||
colorFadeElem = colorFadeElem.GetNext("colorfade");
|
||||
}
|
||||
SetParticleColors(fades);
|
||||
}
|
||||
|
||||
if (rootElem.HasChild("texanim"))
|
||||
{
|
||||
Vector<TextureAnimation> animations;
|
||||
XMLElement animElem = rootElem.GetChild("texanim");
|
||||
while (animElem)
|
||||
{
|
||||
TextureAnimation animation;
|
||||
animation.uv_ = animElem.GetRect("uv");
|
||||
animation.time_ = animElem.GetFloat("time");
|
||||
animations.Push(animation);
|
||||
animElem = animElem.GetNext("texanim");
|
||||
}
|
||||
textureAnimation_ = animations;
|
||||
}
|
||||
if (parameterSource_)
|
||||
SubscribeToEvent(parameterSource_, E_RELOADFINISHED, HANDLER(ParticleEmitter, HandleParametersReloadFinished));
|
||||
|
||||
ApplyParameters();
|
||||
MarkNetworkUpdate();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ParticleEmitter::SetEmitting(bool enable, bool resetPeriod)
|
||||
|
@ -435,6 +337,140 @@ void ParticleEmitter::OnNodeSet(Node* node)
|
|||
}
|
||||
}
|
||||
|
||||
void ParticleEmitter::ApplyParameters()
|
||||
{
|
||||
if (!parameterSource_)
|
||||
return;
|
||||
|
||||
XMLElement rootElem = parameterSource_->GetRoot();
|
||||
|
||||
if (rootElem.HasChild("material"))
|
||||
SetMaterial(GetSubsystem<ResourceCache>()->GetResource<Material>(rootElem.GetChild("material").GetAttribute("name")));
|
||||
|
||||
if (rootElem.HasChild("numparticles"))
|
||||
SetNumParticles(rootElem.GetChild("numparticles").GetInt("value"));
|
||||
|
||||
if (rootElem.HasChild("updateinvisible"))
|
||||
updateInvisible_ = rootElem.GetChild("updateinvisible").GetBool("enable");
|
||||
|
||||
if (rootElem.HasChild("relative"))
|
||||
relative_ = rootElem.GetChild("relative").GetBool("enable");
|
||||
|
||||
if (rootElem.HasChild("scaled"))
|
||||
scaled_ = rootElem.GetChild("scaled").GetBool("enable");
|
||||
|
||||
if (rootElem.HasChild("sorted"))
|
||||
sorted_ = rootElem.GetChild("sorted").GetBool("enable");
|
||||
|
||||
if (rootElem.HasChild("animlodbias"))
|
||||
SetAnimationLodBias(rootElem.GetChild("relative").GetFloat("value"));
|
||||
|
||||
if (rootElem.HasChild("emittertype"))
|
||||
{
|
||||
String type = rootElem.GetChild("emittertype").GetAttributeLower("value");
|
||||
if (type == "point")
|
||||
emitterType_ = EMITTER_POINT;
|
||||
else if (type == "box")
|
||||
emitterType_ = EMITTER_BOX;
|
||||
else if (type == "sphere")
|
||||
emitterType_ = EMITTER_SPHERE;
|
||||
else
|
||||
LOGERROR("Unknown particle emitter type " + type);
|
||||
}
|
||||
|
||||
if (rootElem.HasChild("emittersize"))
|
||||
emitterSize_ = rootElem.GetChild("emittersize").GetVector3("value");
|
||||
|
||||
if (rootElem.HasChild("emitterradius"))
|
||||
emitterSize_.x_ = rootElem.GetChild("emitterradius").GetFloat("value");
|
||||
|
||||
if (rootElem.HasChild("direction"))
|
||||
GetVector3MinMax(rootElem.GetChild("direction"), directionMin_, directionMax_);
|
||||
|
||||
if (rootElem.HasChild("constantforce"))
|
||||
constanceForce_ = rootElem.GetChild("constantforce").GetVector3("value");
|
||||
|
||||
if (rootElem.HasChild("dampingforce"))
|
||||
dampingForce_ = rootElem.GetChild("dampingforce").GetFloat("value");
|
||||
|
||||
if (rootElem.HasChild("activetime"))
|
||||
activeTime_ = rootElem.GetChild("activetime").GetFloat("value");
|
||||
if (activeTime_ < 0.0f)
|
||||
activeTime_ = M_INFINITY;
|
||||
|
||||
if (rootElem.HasChild("inactivetime"))
|
||||
inactiveTime_ = rootElem.GetChild("inactivetime").GetFloat("value");
|
||||
if (inactiveTime_ < 0.0f)
|
||||
inactiveTime_ = M_INFINITY;
|
||||
|
||||
if (rootElem.HasChild("interval"))
|
||||
GetFloatMinMax(rootElem.GetChild("interval"), intervalMin_, intervalMax_);
|
||||
|
||||
if (rootElem.HasChild("emissionrate"))
|
||||
{
|
||||
float emissionRateMin = 0.0f;
|
||||
float emissionRateMax = 0.0f;
|
||||
GetFloatMinMax(rootElem.GetChild("emissionrate"), emissionRateMin, emissionRateMax);
|
||||
intervalMax_ = 1.0f / emissionRateMin;
|
||||
intervalMin_ = 1.0f / emissionRateMax;
|
||||
}
|
||||
|
||||
if (rootElem.HasChild("particlesize"))
|
||||
GetVector2MinMax(rootElem.GetChild("particlesize"), sizeMin_, sizeMax_);
|
||||
|
||||
if (rootElem.HasChild("timetolive"))
|
||||
GetFloatMinMax(rootElem.GetChild("timetolive"), timeToLiveMin_, timeToLiveMax_);
|
||||
|
||||
if (rootElem.HasChild("velocity"))
|
||||
GetFloatMinMax(rootElem.GetChild("velocity"), velocityMin_, velocityMax_);
|
||||
|
||||
if (rootElem.HasChild("rotation"))
|
||||
GetFloatMinMax(rootElem.GetChild("rotation"), rotationMin_, rotationMax_);
|
||||
|
||||
if (rootElem.HasChild("rotationspeed"))
|
||||
GetFloatMinMax(rootElem.GetChild("rotationspeed"), rotationSpeedMin_, rotationSpeedMax_);
|
||||
|
||||
if (rootElem.HasChild("sizedelta"))
|
||||
{
|
||||
XMLElement deltaElem = rootElem.GetChild("sizedelta");
|
||||
if (deltaElem.HasAttribute("add"))
|
||||
sizeAdd_ = deltaElem.GetFloat("add");
|
||||
if (deltaElem.HasAttribute("mul"))
|
||||
sizeMul_ = deltaElem.GetFloat("mul");
|
||||
}
|
||||
|
||||
if (rootElem.HasChild("color"))
|
||||
SetParticleColor(rootElem.GetChild("color").GetColor("value"));
|
||||
|
||||
if (rootElem.HasChild("colorfade"))
|
||||
{
|
||||
Vector<ColorFade> fades;
|
||||
XMLElement colorFadeElem = rootElem.GetChild("colorfade");
|
||||
while (colorFadeElem)
|
||||
{
|
||||
fades.Push(ColorFade(colorFadeElem.GetColor("color"), colorFadeElem.GetFloat("time")));
|
||||
|
||||
colorFadeElem = colorFadeElem.GetNext("colorfade");
|
||||
}
|
||||
SetParticleColors(fades);
|
||||
}
|
||||
|
||||
if (rootElem.HasChild("texanim"))
|
||||
{
|
||||
Vector<TextureAnimation> animations;
|
||||
XMLElement animElem = rootElem.GetChild("texanim");
|
||||
while (animElem)
|
||||
{
|
||||
TextureAnimation animation;
|
||||
animation.uv_ = animElem.GetRect("uv");
|
||||
animation.time_ = animElem.GetFloat("time");
|
||||
animations.Push(animation);
|
||||
animElem = animElem.GetNext("texanim");
|
||||
}
|
||||
textureAnimation_ = animations;
|
||||
}
|
||||
}
|
||||
|
||||
void ParticleEmitter::SetNumParticles(int num)
|
||||
{
|
||||
num = Max(num, 0);
|
||||
|
@ -598,4 +634,9 @@ void ParticleEmitter::HandleScenePostUpdate(StringHash eventType, VariantMap& ev
|
|||
}
|
||||
}
|
||||
|
||||
void ParticleEmitter::HandleParametersReloadFinished(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
ApplyParameters();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -86,8 +86,8 @@ public:
|
|||
/// Update before octree reinsertion. Is called from a worker thread. Needs to be requested with MarkForUpdate().
|
||||
virtual void Update(const FrameInfo& frame);
|
||||
|
||||
/// Set emitter parameters from an XML file. Return true if successful.
|
||||
bool SetParameters(XMLFile* file);
|
||||
/// Set emitter parameters from an XML file.
|
||||
void SetParameters(XMLFile* file);
|
||||
/// Set whether should be emitting and optionally reset emission period.
|
||||
void SetEmitting(bool enable, bool resetPeriod = false);
|
||||
|
||||
|
@ -111,6 +111,8 @@ protected:
|
|||
/// Handle node being assigned.
|
||||
virtual void OnNodeSet(Node* node);
|
||||
|
||||
/// Apply parameter file.
|
||||
void ApplyParameters();
|
||||
/// Set number of particles.
|
||||
void SetNumParticles(int num);
|
||||
/// Set color of particles.
|
||||
|
@ -131,6 +133,8 @@ protected:
|
|||
private:
|
||||
/// Handle scene post-update event.
|
||||
void HandleScenePostUpdate(StringHash eventType, VariantMap& eventData);
|
||||
/// Handle parameter file reload finished.
|
||||
void HandleParametersReloadFinished(StringHash eventType, VariantMap& eventData);
|
||||
|
||||
/// Parameter XML file.
|
||||
SharedPtr<XMLFile> parameterSource_;
|
||||
|
|
Загрузка…
Ссылка в новой задаче