/*
===========================================================================
Copyright (C) 2000 - 2013, Raven Software, Inc.
Copyright (C) 2001 - 2013, Activision, Inc.
Copyright (C) 2013 - 2015, OpenJK contributors
This file is part of the OpenJK source code.
OpenJK is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see .
===========================================================================
*/
////////////////////////////////////////////////////////////////////////////////////////
// RAVEN STANDARD TEMPLATE LIBRARY
// (c) 2002 Activision
//
//
// Scheduler
// ---------
// The scheduler is a common piece of game functionality. To use it, simply add events
// at the given time, and call update() with the current time as frequently as you wish.
//
// Your event class MUST define a Fire() function which accepts a TCALLBACKPARAMS
// parameter.
//
// NOTES:
//
//
//
////////////////////////////////////////////////////////////////////////////////////////
#if !defined(RATL_SCHEDULER_VS_INC)
#define RATL_SCHEDULER_VS_INC
////////////////////////////////////////////////////////////////////////////////////////
// Includes
////////////////////////////////////////////////////////////////////////////////////////
#if !defined(RATL_COMMON_INC)
#include "ratl_common.h"
#endif
#if !defined(RATL_POOL_VS_INC)
#include "pool_vs.h"
#endif
#if !defined(RATL_HEAP_VS_INC)
#include "heap_vs.h"
#endif
namespace ratl
{
////////////////////////////////////////////////////////////////////////////////////////
// The Scheduler Class
////////////////////////////////////////////////////////////////////////////////////////
template
class scheduler_base : public ratl_base
{
public:
typedef typename T TStorageTraits;
typedef typename T::TValue TTValue;
////////////////////////////////////////////////////////////////////////////////////
// Capacity Enum
////////////////////////////////////////////////////////////////////////////////////
static const int CAPACITY = T::CAPACITY;
private:
////////////////////////////////////////////////////////////////////////////////////
// The Timed Event Class
//
// This class stores two numbers, a timer and an iterator to the events list. We
// don't store the event directly in the heap to make the swap operation in the
// heap faster. We define a less than operator so we can sort in the heap.
//
////////////////////////////////////////////////////////////////////////////////////
struct timed_event
{
float mTime;
int mEvent;
timed_event() {}
timed_event(float time, int event) : mTime(time), mEvent(event) {}
bool operator< (const timed_event& t) const
{
return (mTime > t.mTime);
}
};
pool_base mEvents;
heap_vs mHeap;
public:
////////////////////////////////////////////////////////////////////////////////////
// How Many Objects Are In This List
////////////////////////////////////////////////////////////////////////////////////
int size() const
{
// warning during a fire call, there will be one extra event
return mEvents.size();
}
////////////////////////////////////////////////////////////////////////////////////
// Are There Any Objects In This List?
////////////////////////////////////////////////////////////////////////////////////
bool empty() const
{
return !size();
}
////////////////////////////////////////////////////////////////////////////////////
// Is This List Filled?
////////////////////////////////////////////////////////////////////////////////////
bool full() const
{
return mEvents.full();
}
////////////////////////////////////////////////////////////////////////////////////
// Clear All Elements
////////////////////////////////////////////////////////////////////////////////////
void clear()
{
mEvents.clear();
mHeap.clear();
}
////////////////////////////////////////////////////////////////////////////////////
// Add An Event
////////////////////////////////////////////////////////////////////////////////////
void add(float time, const TTValue& e)
{
int nLoc = mEvents.alloc(e);
mHeap.push(timed_event(time, nLoc));
}
////////////////////////////////////////////////////////////////////////////////////
// Add An Event
////////////////////////////////////////////////////////////////////////////////////
TTValue & add(float time)
{
int nLoc = mEvents.alloc();
mHeap.push(timed_event(time, nLoc));
return mEvents[nLoc];
}
////////////////////////////////////////////////////////////////////////////////////
// Add A Raw Event for placement new
////////////////////////////////////////////////////////////////////////////////////
TRatlNew * add_raw(float time)
{
TRatlNew *ret = mEvents.alloc_raw();
mHeap.push(timed_event(time, mEvents.pointer_to_index(ret)));
return ret;
}
template
void update(float time, TCALLBACKPARAMS& Params)
{
while (!mHeap.empty())
{
timed_event Next = mHeap.top();
if (Next.mTime>=time)
{
break;
}
mHeap.pop();
mEvents[Next.mEvent].Fire(Params);
mEvents.free(Next.mEvent);
}
}
void update(float time)
{
while (!mHeap.empty())
{
timed_event Next = mHeap.top();
if (Next.mTime>=time)
{
break;
}
mHeap.pop();
mEvents[Next.mEvent].Fire();
mEvents.free(Next.mEvent);
}
}
};
template
class scheduler_vs : public scheduler_base >
{
public:
typedef typename storage::value_semantics TStorageTraits;
typedef typename TStorageTraits::TValue TTValue;
static const int CAPACITY = ARG_CAPACITY;
scheduler_vs() {}
};
template
class scheduler_os : public scheduler_base >
{
public:
typedef typename storage::object_semantics TStorageTraits;
typedef typename TStorageTraits::TValue TTValue;
static const int CAPACITY = ARG_CAPACITY;
scheduler_os() {}
};
template
class scheduler_is : public scheduler_base >
{
public:
typedef typename storage::virtual_semantics TStorageTraits;
typedef typename TStorageTraits::TValue TTValue;
static const int CAPACITY = ARG_CAPACITY;
static const int MAX_CLASS_SIZE = ARG_MAX_CLASS_SIZE;
scheduler_is() {}
};
}
#endif