2016-02-21 08:25:46 +01:00
|
|
|
#ifndef _ROUTINE_HPP_
|
|
|
|
#define _ROUTINE_HPP_
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
#include "Base/Shared.hpp"
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
2016-05-22 05:20:38 +02:00
|
|
|
#include <array>
|
|
|
|
#include <utility>
|
|
|
|
#include <unordered_map>
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
namespace SqMod {
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
|
|
* Execute callbacks after specific intervals of time.
|
|
|
|
*/
|
|
|
|
class Routine
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Simplify future changes to a single point of change.
|
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
typedef Int64 Time;
|
|
|
|
typedef SQInteger Interval;
|
|
|
|
typedef Uint32 Iterator;
|
|
|
|
typedef std::pair< Interval, Routine * > Element;
|
|
|
|
typedef std::array< Element, SQMOD_MAX_ROUTINES > Routines;
|
|
|
|
typedef std::unordered_map< Routine *, Object > Objects;
|
2016-02-21 08:25:46 +01:00
|
|
|
|
2016-02-23 04:23:56 +01:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Process all active routines and update elapsed time.
|
|
|
|
*/
|
|
|
|
static void Process();
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-05-22 05:20:38 +02:00
|
|
|
* Initialize all resources and prepare for startup.
|
2016-02-23 04:23:56 +01:00
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
static void Initialize();
|
2016-02-21 08:25:46 +01:00
|
|
|
|
2016-03-10 04:57:13 +01:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-05-22 05:20:38 +02:00
|
|
|
* Release all resources and prepare for shutdown.
|
2016-02-21 08:25:46 +01:00
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
static void Deinitialize();
|
2016-02-21 08:25:46 +01:00
|
|
|
|
2016-05-22 05:20:38 +02:00
|
|
|
protected:
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------------
|
2016-05-22 05:20:38 +02:00
|
|
|
static Time s_Last; // Last time point.
|
|
|
|
static Time s_Prev; // Previous time point.
|
|
|
|
static Routines s_Routines; // Buckets of routines grouped by similar intervals.
|
|
|
|
static Objects s_Objects; // List of existing routines and their associated object.
|
2016-03-10 04:57:13 +01:00
|
|
|
|
2016-05-22 05:20:38 +02:00
|
|
|
protected:
|
2016-03-10 04:57:13 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-03-12 07:47:50 +01:00
|
|
|
* Create or locate the object for the specified routine and keep a strong reference to it.
|
2016-03-10 04:57:13 +01:00
|
|
|
*/
|
2016-03-12 07:47:50 +01:00
|
|
|
static Object Associate(Routine * routine);
|
2016-02-23 04:23:56 +01:00
|
|
|
|
2016-02-21 08:25:46 +01:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-03-12 07:47:50 +01:00
|
|
|
* Release the strong reference associated with the specified routine so it can be destroyed.
|
2016-02-21 08:25:46 +01:00
|
|
|
*/
|
2016-03-12 07:47:50 +01:00
|
|
|
static void Dissociate(Routine * routine);
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-03-12 07:47:50 +01:00
|
|
|
* See whether the specified routine exists in the pool and references itself.
|
2016-02-21 08:25:46 +01:00
|
|
|
*/
|
2016-03-12 07:47:50 +01:00
|
|
|
static bool Associated(Routine * routine);
|
2016-02-21 08:25:46 +01:00
|
|
|
|
2016-03-12 07:47:50 +01:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Remove the specified routine from the pool and any associated reference, if any.
|
|
|
|
*/
|
|
|
|
static void Forget(Routine * routine);
|
2016-02-23 04:23:56 +01:00
|
|
|
|
2016-03-12 07:47:50 +01:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-05-22 05:20:38 +02:00
|
|
|
* Insert a routine instance into the pool to be processed.
|
|
|
|
*/
|
|
|
|
static void Insert(Routine * routine, bool associate = true);
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Insert a routine instance from the pool to not be processed.
|
|
|
|
*/
|
|
|
|
static void Remove(Routine * routine);
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Release routine resources.
|
|
|
|
*/
|
|
|
|
void Release();
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Execute the binded callback.
|
2016-03-12 07:47:50 +01:00
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
void Execute();
|
2016-02-23 04:23:56 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-03-12 07:47:50 +01:00
|
|
|
* See whether this routine is valid otherwise throw an exception.
|
2016-02-23 04:23:56 +01:00
|
|
|
*/
|
2016-03-12 07:47:50 +01:00
|
|
|
void Validate() const
|
|
|
|
{
|
|
|
|
if (m_Terminated)
|
|
|
|
{
|
2016-03-21 21:37:58 +01:00
|
|
|
STHROWF("Routine was terminated [%s]", m_Tag.c_str());
|
2016-03-12 07:47:50 +01:00
|
|
|
}
|
|
|
|
}
|
2016-02-23 04:23:56 +01:00
|
|
|
|
2016-03-12 07:47:50 +01:00
|
|
|
private:
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Constructor with just an interval.
|
|
|
|
*/
|
|
|
|
Routine(Object & env, Function & func, Interval interval);
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Constructor with just an interval and explicit iterations.
|
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
Routine(Object & env, Function & func, Interval interval, Iterator iterations);
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Constructor with just an interval, explicit iterations and arguments.
|
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
Routine(Object & env, Function & func, Interval interval, Iterator iterations
|
2016-02-21 08:25:46 +01:00
|
|
|
, Object & a1);
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Constructor with just an interval, explicit iterations and arguments.
|
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
Routine(Object & env, Function & func, Interval interval, Iterator iterations
|
2016-02-21 08:25:46 +01:00
|
|
|
, Object & a1, Object & a2);
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Constructor with just an interval, explicit iterations and arguments.
|
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
Routine(Object & env, Function & func, Interval interval, Iterator iterations
|
2016-02-21 08:25:46 +01:00
|
|
|
, Object & a1, Object & a2, Object & a3);
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Constructor with just an interval, explicit iterations and arguments.
|
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
Routine(Object & env, Function & func, Interval interval, Iterator iterations
|
2016-02-21 08:25:46 +01:00
|
|
|
, Object & a1, Object & a2, Object & a3, Object & a4);
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Constructor with just an interval, explicit iterations and arguments.
|
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
Routine(Object & env, Function & func, Interval interval, Iterator iterations
|
2016-02-21 08:25:46 +01:00
|
|
|
, Object & a1, Object & a2, Object & a3, Object & a4, Object & a5);
|
|
|
|
|
2016-03-12 07:47:50 +01:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Copy constructor. (disabled)
|
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
Routine(const Routine & o) = delete;
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Move constructor. (disabled)
|
|
|
|
*/
|
|
|
|
Routine(Routine && o) = delete;
|
2016-03-12 07:47:50 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Copy assignment operator. (disabled)
|
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
Routine & operator = (const Routine & o) = delete;
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Move assignment operator. (disabled)
|
|
|
|
*/
|
|
|
|
Routine & operator = (Routine && o) = delete;
|
2016-03-12 07:47:50 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Number of iterations before self destruct.
|
2016-05-22 05:20:38 +02:00
|
|
|
*/
|
|
|
|
Iterator m_Iterations;
|
2016-03-12 07:47:50 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Interval between calls.
|
2016-05-22 05:20:38 +02:00
|
|
|
*/
|
2016-03-12 07:47:50 +01:00
|
|
|
Interval m_Interval;
|
|
|
|
|
2016-05-22 05:20:38 +02:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* The index of the slot in the pool.
|
|
|
|
*/
|
|
|
|
Uint16 m_Slot;
|
|
|
|
|
2016-03-12 07:47:50 +01:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Number of arguments to forward.
|
2016-05-22 05:20:38 +02:00
|
|
|
*/
|
|
|
|
Uint16 m_Arguments;
|
2016-03-12 07:47:50 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Whether calls should be ignored.
|
2016-05-22 05:20:38 +02:00
|
|
|
*/
|
2016-03-12 07:47:50 +01:00
|
|
|
bool m_Suspended;
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Whether the routine was terminated.
|
2016-05-22 05:20:38 +02:00
|
|
|
*/
|
2016-03-12 07:47:50 +01:00
|
|
|
bool m_Terminated;
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* The callback to be executed when triggered.
|
|
|
|
*/
|
|
|
|
Function m_Callback;
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* User tag associated with this instance.
|
|
|
|
*/
|
|
|
|
String m_Tag;
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* User data associated with this instance.
|
|
|
|
*/
|
|
|
|
Object m_Data;
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Arguments to be forwarded to the callback.
|
|
|
|
*/
|
|
|
|
Object m_Arg1, m_Arg2, m_Arg3, m_Arg4, m_Arg5, m_Arg6, m_Arg7,
|
|
|
|
m_Arg8, m_Arg9, m_Arg10, m_Arg11, m_Arg12, m_Arg13, m_Arg14;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
2016-02-21 08:25:46 +01:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Destructor.
|
|
|
|
*/
|
|
|
|
~Routine();
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Used by the script engine to compare two instances of this type.
|
|
|
|
*/
|
|
|
|
Int32 Cmp(const Routine & o) const;
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Used by the script engine to convert an instance of this type to a string.
|
|
|
|
*/
|
|
|
|
CSStr ToString() const;
|
|
|
|
|
2016-03-12 07:47:50 +01:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Used by the script engine to retrieve the name from instances of this type.
|
|
|
|
*/
|
|
|
|
static SQInteger Typename(HSQUIRRELVM vm);
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Retrieve the associated user tag.
|
|
|
|
*/
|
|
|
|
const String & GetTag() const;
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Modify the associated user tag.
|
|
|
|
*/
|
|
|
|
void SetTag(CSStr tag);
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Retrieve the associated user data.
|
|
|
|
*/
|
|
|
|
Object & GetData();
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Modify the associated user data.
|
|
|
|
*/
|
|
|
|
void SetData(Object & data);
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Modify the associated user tag and allow chaining of operations.
|
|
|
|
*/
|
|
|
|
Routine & ApplyTag(CSStr tag);
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Modify the associated user data and allow chaining of operations.
|
|
|
|
*/
|
|
|
|
Routine & ApplyData(Object & data);
|
|
|
|
|
2016-02-21 08:25:46 +01:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
2016-05-22 05:20:38 +02:00
|
|
|
* Activate the routine instance.
|
|
|
|
*/
|
|
|
|
Routine & Activate();
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Deactivate the routine instance.
|
|
|
|
*/
|
|
|
|
Routine & Deactivate();
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Terminate this routine by deactivating and releasing all resources.
|
|
|
|
*/
|
|
|
|
Routine & Terminate();
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Unmark this routine as terminated and allow to be activated.
|
2016-02-21 08:25:46 +01:00
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
Routine & Reanimate();
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Modify an explicit value to be passed as the specified argument.
|
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
Routine & SetArg(Uint16 num, Object & val);
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Retrieve the value that is passed as the specified argument.
|
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
Object & GetArg(Uint16 num);
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Retrieve the amount of time required to wait between calls to the routine.
|
|
|
|
*/
|
|
|
|
Interval GetInterval() const;
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Modify the amount of time required to wait between calls to the routine.
|
|
|
|
*/
|
|
|
|
void SetInterval(Interval interval);
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Retrieve the number of times that the routine can be called before terminating itself.
|
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
Iterator GetIterations() const;
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Modify the number of times that the routine can be called before terminating itself.
|
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
void SetIterations(Iterator iterations);
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Retrieve the number of arguments that are forwarded when executing the callback.
|
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
Uint16 GetArguments() const;
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Modify the number of arguments that are forwarded when executing the callback.
|
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
void SetArguments(Uint16 num);
|
2016-02-21 08:25:46 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* See whether the routine is suspended from further calls.
|
|
|
|
*/
|
|
|
|
bool GetSuspended() const;
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Set whether the routine is suspended from further calls.
|
|
|
|
*/
|
|
|
|
void SetSuspended(bool toggle);
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* See whether the routine was terminated or not.
|
|
|
|
*/
|
|
|
|
bool GetTerminated() const;
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Retrieve the currently binded callback.
|
|
|
|
*/
|
|
|
|
Function & GetCallback();
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Bind a certain function to be executed when this routine is triggered.
|
|
|
|
*/
|
|
|
|
void SetCallback(Object & env, Function & func);
|
|
|
|
|
2016-03-12 07:47:50 +01:00
|
|
|
public:
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Create a routine with just an interval.
|
|
|
|
*/
|
|
|
|
static Object Create(Object & env, Function & func, Interval interval);
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Create a routine with just an interval and explicit iterations.
|
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
static Object Create(Object & env, Function & func, Interval interval, Iterator iterations);
|
2016-03-12 07:47:50 +01:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Create a routine with just an interval, explicit iterations and arguments.
|
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
static Object Create(Object & env, Function & func, Interval interval, Iterator iterations
|
2016-03-12 07:47:50 +01:00
|
|
|
, Object & a1);
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Create a routine with just an interval, explicit iterations and arguments.
|
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
static Object Create(Object & env, Function & func, Interval interval, Iterator iterations
|
2016-03-12 07:47:50 +01:00
|
|
|
, Object & a1, Object & a2);
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Create a routine with just an interval, explicit iterations and arguments.
|
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
static Object Create(Object & env, Function & func, Interval interval, Iterator iterations
|
2016-03-12 07:47:50 +01:00
|
|
|
, Object & a1, Object & a2, Object & a3);
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Create a routine with just an interval, explicit iterations and arguments.
|
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
static Object Create(Object & env, Function & func, Interval interval, Iterator iterations
|
2016-03-12 07:47:50 +01:00
|
|
|
, Object & a1, Object & a2, Object & a3, Object & a4);
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Create a routine with just an interval, explicit iterations and arguments.
|
|
|
|
*/
|
2016-05-22 05:20:38 +02:00
|
|
|
static Object Create(Object & env, Function & func, Interval interval, Iterator iterations
|
2016-03-12 07:47:50 +01:00
|
|
|
, Object & a1, Object & a2, Object & a3, Object & a4, Object & a5);
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Attempt to find a certain routine by its associated tag.
|
|
|
|
*/
|
|
|
|
static Object FindByTag(CSStr tag);
|
2016-02-21 08:25:46 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
} // Namespace:: SqMod
|
|
|
|
|
|
|
|
#endif // _ROUTINE_HPP_
|