From 123e8fdf53ffb40c7464d0559a49e048fed79d7d Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Mon, 20 Dec 2010 22:03:49 +0200 Subject: framework for modifying textures --- src/utility.h | 301 +++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 215 insertions(+), 86 deletions(-) (limited to 'src/utility.h') diff --git a/src/utility.h b/src/utility.h index e4494948c..cde555760 100644 --- a/src/utility.h +++ b/src/utility.h @@ -17,10 +17,6 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -/* -(c) 2010 Perttu Ahola -*/ - #ifndef UTILITY_HEADER #define UTILITY_HEADER @@ -403,56 +399,23 @@ private: TimeTaker */ +class IrrlichtWrapper; + class TimeTaker { public: - TimeTaker(const char *name, IrrlichtDevice *dev, u32 *result=NULL) - { - m_name = name; - m_dev = dev; - m_result = result; - m_running = true; - if(dev == NULL) - { - m_time1 = 0; - return; - } - m_time1 = m_dev->getTimer()->getRealTime(); - } + TimeTaker(const char *name, IrrlichtWrapper *irrlicht, u32 *result=NULL); + ~TimeTaker() { stop(); } - u32 stop(bool quiet=false) - { - if(m_running) - { - if(m_dev == NULL) - { - /*if(quiet == false) - std::cout<<"Couldn't measure time for "<getTimer()->getRealTime(); - u32 dtime = time2 - m_time1; - if(m_result != NULL) - { - (*m_result) += dtime; - } - else - { - if(quiet == false) - std::cout< +class MutexedQueue { public: - TextureCache() + MutexedQueue() { m_mutex.Init(); - assert(m_mutex.IsInitialized()); + m_is_empty_mutex.Init(); } - - void set(std::string name, video::ITexture *texture) + u32 size() { - JMutexAutoLock lock(m_mutex); - - m_textures[name] = texture; + return m_list.size(); } - - video::ITexture* get(std::string name) + void push_back(T t) { JMutexAutoLock lock(m_mutex); + m_list.push_back(t); + + if(m_list.size() == 1) + m_is_empty_mutex.Unlock(); + } + T pop_front(bool wait_if_empty=false) + { + for(;;) + { + { + JMutexAutoLock lock(m_mutex); - core::map::Node *n; - n = m_textures.find(name); + if(m_list.size() > 0) + { + if(m_list.size() == 1) + m_is_empty_mutex.Lock(); + + typename core::list::Iterator begin = m_list.begin(); + T t = *begin; + m_list.erase(begin); + return t; + } - if(n != NULL) - return n->getValue(); + if(wait_if_empty == false) + throw ItemNotFoundException("MutexedQueue: item not found"); + } + + // To wait for an empty list, we're gonna hang on this mutex + m_is_empty_mutex.Lock(); + m_is_empty_mutex.Unlock(); - return NULL; + // Then loop to the beginning and hopefully return something + } } -private: - core::map m_textures; + JMutex & getMutex() + { + return m_mutex; + } + + JMutex & getIsEmptyMutex() + { + return m_is_empty_mutex; + } + + core::list & getList() + { + return m_list; + } + +protected: JMutex m_mutex; + // This is locked always when the list is empty + JMutex m_is_empty_mutex; + core::list m_list; }; -class SimpleThread : public JThread +template +class CallerInfo { - bool run; - JMutex run_mutex; +public: + Caller caller; + Data data; +}; +template +class GetResult +{ public: + Key key; + T item; + core::list > callers; +}; - SimpleThread(): - JThread(), - run(true) +template +class ResultQueue: public MutexedQueue< GetResult > +{ +}; + +template +class GetRequest +{ +public: + GetRequest() { - run_mutex.Init(); + dest = NULL; } + GetRequest(ResultQueue *a_dest) + { + dest = a_dest; + } + GetRequest(ResultQueue *a_dest, + Key a_key) + { + dest = a_dest; + key = a_key; + } + ~GetRequest() + { + } + + Key key; + ResultQueue *dest; + core::list > callers; +}; - virtual ~SimpleThread() - {} - - virtual void * Thread() = 0; +/* + Quickhands for typical request-result queues. + Used for distributing work between threads. +*/ - bool getRun() +template +class RequestQueue +{ +public: + u32 size() { - JMutexAutoLock lock(run_mutex); - return run; + return m_queue.size(); } - void setRun(bool a_run) + + void add(Key key, Caller caller, CallerData callerdata, + ResultQueue *dest) { - JMutexAutoLock lock(run_mutex); - run = a_run; + JMutexAutoLock lock(m_queue.getMutex()); + + /* + If the caller is already on the list, only update CallerData + */ + for(typename core::list< GetRequest >::Iterator + i = m_queue.getList().begin(); + i != m_queue.getList().end(); i++) + { + GetRequest &request = *i; + + if(request.key == key) + { + for(typename core::list< CallerInfo >::Iterator + i = request.callers.begin(); + i != request.callers.end(); i++) + { + CallerInfo &ca = *i; + if(ca.caller == caller) + { + ca.data = callerdata; + return; + } + } + CallerInfo ca; + ca.caller = caller; + ca.data = callerdata; + request.callers.push_back(ca); + return; + } + } + + /* + Else add a new request to the queue + */ + + GetRequest request; + request.key = key; + CallerInfo ca; + ca.caller = caller; + ca.data = callerdata; + request.callers.push_back(ca); + request.dest = dest; + + m_queue.getList().push_back(request); + + if(m_queue.getList().size() == 1) + m_queue.getIsEmptyMutex().Unlock(); } - void stop() + GetRequest pop(bool wait_if_empty=false) { - setRun(false); - while(IsRunning()) - sleep_ms(100); + return m_queue.pop_front(wait_if_empty); } + +private: + MutexedQueue< GetRequest > m_queue; }; #endif -- cgit v1.2.3