22 #include "MAValueGenerators.hpp" 24 #include <boost/math/constants/constants.hpp> 27 #include <MCThreadLocalData.hpp> 28 #include <MCTimer.hpp> 30 #include "MADevice.hpp" 31 #include "MARandomness.hpp" 34 Duration(0), Timer(new
MCTimer), Function(Linear)
39 MAGeneratorBase::~MAGeneratorBase()
47 (
int)MAGeneratorBase::FunctionTypeMax);
61 return Timer->GetStartTime();
67 return Timer->GetElapsedTime();
79 if (scale <= 0 || scale == 1.0 ||
Duration < 0)
124 return Timer->IsStarted();
132 MC_WARNING(
"The minimum (start) value of the value generator has not been initialized yet.");
137 MC_WARNING(
"The maximum (target) value of the value generator has not been initialized yet.");
151 MC_WARNING(
"The minimum (start) value of the value generator has not been initialized yet.");
156 MC_WARNING(
"The maximum (target) value of the value generator has not been initialized yet.");
169 Timer->Start(StartTime);
177 MC_WARNING(
"The minimum (start) value of the value generator has not been initialized yet.");
182 MC_WARNING(
"The maximum (target) value of the value generator has not been initialized yet.");
186 Timer->StartFromTime(start_time);
202 float NormalizedValue = (value-
GetMinValue())*(boost::math::constants::pi<float>() / 2) /
211 return MinValue+(1.0-sinf(boost::math::constants::pi<float>() / 2+NormalizedValue))*
222 MC_WARNING(
"The value is out of the generator range %1.2f ∉ [%1.2f, %1.2f]",
267 Timer->StartFromTime(start_time);
284 int ElapsedTime = (int)
Timer->GetElapsedTime();
314 int ElapsedTime =
Timer->GetElapsedTime();
333 int ElapsedTime = (int)
Timer->GetElapsedTime();
344 int dur4,
int dur5,
bool loop) :
364 int dur5,
bool loop) :
387 MC_WARNING(
"The minimum (start) value of the value generator has not been initialized yet.");
392 MC_WARNING(
"The maximum (target) value of the value generator has not been initialized yet.");
412 if (scale <= 0 || scale == 1.0 ||
Duration < 0)
429 int ElapsedTime =
Timer->GetElapsedTime();
437 CurrentPeriod = ElapsedTime;
470 int ElapsedTime = (int)
Timer->GetElapsedTime();
486 void CheckStaticGeneratorContainerVariables()
488 if (unlikely(!Containers.get()))
490 Containers.reset(
new MA::GeneratorContainerList);
491 Verbose.reset(
new bool);
499 AlreadyExpired(false), ExpiredSignalBlockRefCount(0)
501 CheckStaticGeneratorContainerVariables();
502 Containers->push_back(
this);
506 MC_LOG(std::string(
"Create container: "+
MCToStr(
this)).c_str());
517 MC_LOG(std::string(
"Delete container ("+
MCToStr(
this)+
", transition: "+
525 (*ExpiredSignal).Emit(*
this);
529 Containers->erase(std::find(Containers->begin(), Containers->end(),
this));
531 for (
unsigned int i = 0; i <
Generators.size(); ++i)
541 MC_LOG(
"----- Generatorcontainer list BEGIN -----");
542 MA::GeneratorContainerList& ContainerList = *Containers.get();
544 for (
auto& container : ContainerList)
546 MC_LOG(std::string(
"Container:"+
MCToStr(container)).c_str());
548 for (
auto& container : ContainerList)
551 container->BlockExpiredSignal();
553 container->UnblockExpiredSignal();
555 MC_LOG(
"----- Generatorcontainer list END -----");
561 CheckStaticGeneratorContainerVariables();
562 *Verbose = new_state;
573 MC_LOG(std::string(
"New owner for the container ("+
MCToStr(
this)+
", transition: "+
576 MC_LOG(std::string(
"New owner for the container ("+
MCToStr(
this)+
", transition: "+
620 if (!dynamic_cast<MADelayGenerator*>(generator))
621 return generator->IsAbsolute();
634 if (generator->GetDuration() < 0)
638 Duration += generator->GetDuration();
646 if (scale <= 0 || scale == 1.0)
651 if (generator->GetDuration() > 0)
653 generator->ScaleDuration(scale);
693 MC_LOG(std::string(
"Container expired ("+
MCToStr(
this)+
", transition: "+
699 (*ExpiredSignal).Emit(*
this);
716 if (!dynamic_cast<MADelayGenerator*>(generator))
727 MC_WARNING(
"It is not allowed to add new generators to a permanent container.");
739 MC_WARNING(
"It is not allowed to add an absolute generator to a relative container.");
744 MC_WARNING(
"It is not allowed to add a relative generator to an absolute container.");
760 float NewMinValue =
MCScaleValue(generator->GetMinValue(), min, max, new_max);
761 float NewMaxValue =
MCScaleValue(generator->GetMaxValue(), min, max, new_max);
763 generator->SetMinValue(NewMinValue);
764 generator->SetMaxValue(NewMaxValue);
800 MC_LOG(std::string(
"Container started ("+
MCToStr(
this)+
", transition: "+
889 if (dynamic_cast<MASimpleGenerator*>(Generator))
906 std::string LogMessage;
921 LogMessage +=
"min - "+
MCToStr((*iter)->GetMinValue())+
", ";
922 LogMessage +=
"max - "+
MCToStr((*iter)->GetMaxValue())+
", ";
923 LogMessage +=
"duration - "+
MCToStr((*iter)->GetDuration())+
", ";
924 LogMessage +=
"elapsed - "+
MCToStr((*iter)->GetElapsedTime())+
", ";
925 LogMessage +=
"started/expired - "+
MCToStr((*iter)->IsStarted())+
'/'+
MCToStr((*iter)->IsExpired());
927 LogMessage +=
" || ";
930 MC_LOG(
"%s", LogMessage.c_str());
float GetMinValue() const
Get the starting value of the generator.
void UnblockExpiredSignal()
Unblock the expiration signal of the container.
bool IsAbsolute() const
Check if the container is absolute.
bool IsExpired()
Check if the container has been expired.
virtual int GetDuration() const
Get the duration of the generator.
int Duration1
First segment duration (when it keeps the minimum value)
#define MA_RANDOM_POINT_1(_variable_name, _min, _max)
Set a random point with one value.
void AddGenerator(MAGeneratorBase &generator, bool in_front=false)
Add a new generator after the last internal generator.
void Dump()
Dump the internal generators in the container.
float GetDesiredStartingValue() const
Get the desired starting value of the container.
void SetTransferFunction(FunctionType function)
Set the transfer function.
virtual void SetMaxValue(float max_value) override
Set the target value of the generator.
float GetTargetValue() const
Get the final target value of the container.
int GetDuration() const
Get the container duration.
bool MCRangeCheck(const T &value, const T &min, const T &max)
Range check of a value.
int Duration3
Third segment duration (when it keeps the maximum value)
MADevice * Device
Owner device.
MAGeneratorContainer(MAGeneratorBase &generator)
Create a generator container with a generator.
MASimpleGenerator(float min, float max, int duration)
Creates a simple generator.
bool AlreadyExpired
Whenever it is expired already.
bool IsExpiredSignalBlocked() const
Check if the expiration signal of the container is blocked.
float MaxValue
Maximum value.
void CalculateCurrentValue(float device_value)
Calculate the current value based on a device value.
virtual void StartFromTime(int start_time) override
Start the generator from a certain time.
virtual void SetMaxValue(float max_value)
Set the target value of the generator.
bool IsPermanent() const
Check if the container is permanent.
std::string TransitionName
Transition name.
void MakePermanent()
Make the generator container infinite long (permanent)
float GetMaxValue() const
Get the target value of the generator.
float StartingValue
Starting value.
#define MC_WARNING(...)
Warning macro.
std::string MCToStr(const T value, bool hex_manipulator=false)
Convert an other type to string with std::stringstream.
int Duration5
Fifth segment duration (when it keeps the minimum value)
bool HasRealGenerator() const
Check if the container has any real generator other than delay generators.
virtual void ScaleDuration(float scale)
Scale the generator duration.
int Duration4
Fourth segment duration (when it interpolates back to the minimum value)
bool Loop
Whether the generator is looped.
void SetTransitionName(const std::string &name)
Set a transition name for the container.
boost::scoped_ptr< MCTimer > Timer
Timer.
MADelayGenerator(int duration)
Creates a delay generator.
virtual float GetCurrentValue() override
Get the current value.
FunctionType Function
Transfer function.
void Start(float device_value)
Start the first generator in the container based on a device value.
float MinValue
Minimum value.
float GetTransformedValue(float value) const
Get the transformed value for a derived generator.
static FunctionType GetRandomFunction()
Get a random generator function type.
bool IsStarted() const
Check if the container has been started.
bool MCIsFloatInfinity(const float value)
Check a value for float infinity.
#define MC_UNUSED(a)
Helper macro to avoid compiler warning about unused function parameters.
int GetStartTime() const
Get the start time of the generator.
bool IsAbsolute() const
Check if the generator is absolute.
void ScaleDuration(float scale)
Scale the generator durations in the container.
MASignal< MAGeneratorContainer & > ExpiredSignalType
Generator just expired signal type.
virtual void SetMinValue(float min_value) override
Set the starting value of the generator.
float GetCurrentValue()
Get the current value.
bool CheckValueRange(float value, bool verbose=true)
Check if a value falls into the valid generator value range.
virtual int GetOverTime() const override
Get the overtime after the generator has been expired.
int GetElapsedTime() const
Get the elapsed time of the generator.
virtual void Start() override
Start the generator.
float CurrentValue
Current value.
std::string GetTransitionName() const
Get the transition name where the container belongs to.
MAGeneratorBase(float min=MCFloatInfinity(), float max=MCFloatInfinity())
Create a base generator.
void SetOwnerDevice(MADevice &owner)
Set the owner device.
Base class for generators.
virtual void Start()
Start the generator.
bool IsFinite() const
Check if the container is finite.
Simple timer class with microsecond precision.
float MCFloatInfinity()
Get float infinity.
bool IsExpired() const
Check if the generator has been expired.
virtual int GetOverTime() const override
Get the overtime after the generator has been expired.
A wrapper class to cover boost::thread_specific_ptr/folly::ThreadLocal API on certain targets...
void ScaleGenerators(float min, float max, float new_max)
Scale the internal generators into a new value range.
MAPeriodicGenerator(float min, float max, int dur1, int dur2, int dur3, int dur4, int dur5, bool loop=false)
Creates a periodic generator.
static void DumpAllContainers()
Dump all containers in the current run (the list is tls based thus per thread)
float GetStartingValue() const
Get the starting value of the container.
float MCScaleValue(float value, float min, float max, float new_max)
Scale a value to a new range.
~MAGeneratorContainer()
Destroy the generator container.
virtual void ScaleDuration(float scale) override
Scale the generator duration.
bool HasOneGenerator() const
Check if the container has only one generator internally.
#define MC_LOG(...)
Debug macro.
virtual void SetMinValue(float min_value)
Set the starting value of the generator.
int ExpiredSignalBlockRefCount
Whenever the signal of the "just expiration" is blocked.
virtual float GetCurrentValue() override
Get the current value.
static void SetVerbose(bool new_state)
Set the verbosity of the generator containers.
int Duration2
Second segment duration (when it interpolates to the maximum value)
virtual void StartFromTime(int start_time)
Start the generator from a certain time.
MA::GeneratorList Generators
Value generators.
void BlockExpiredSignal()
Block the expiration signal of the container.
virtual int GetOverTime() const override
Get the overtime after the generator has been expired.
virtual int GetOverTime() const =0
Get the overtime after the generator has been expired.
bool IsStarted() const
Check if the generator has been started.
virtual float GetCurrentValue() override
Get the current value.