]> git.lizzy.rs Git - minetest.git/blobdiff - src/util/container.h
Fixes for Android build errors. Enable sensor landscape rotation.
[minetest.git] / src / util / container.h
index 15c877fde549dd8a3368fbbd261ca413b9f06fe8..6d836a4d55d20f5fc7751b8938d01041f5397959 100644 (file)
@@ -1,6 +1,6 @@
 /*
 Minetest
-Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as published by
@@ -21,9 +21,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define UTIL_CONTAINER_HEADER
 
 #include "../irrlichttypes.h"
-#include <jmutex.h>
-#include <jmutexautolock.h>
-#include "../porting.h" // For sleep_ms
+#include "../exceptions.h"
+#include "../jthread/jmutex.h"
+#include "../jthread/jmutexautolock.h"
+#include "../jthread/jsemaphore.h"
+#include <list>
+#include <vector>
+#include <map>
 
 /*
        Queue with unique values with fast checking of value existence
@@ -43,11 +47,11 @@ class UniqueQueue
        bool push_back(Value value)
        {
                // Check if already exists
-               if(m_map.find(value) != NULL)
+               if(m_map.find(value) != m_map.end())
                        return false;
 
                // Add
-               m_map.insert(value, 0);
+               m_map[value] = 0;
                m_list.push_back(value);
                
                return true;
@@ -55,22 +59,21 @@ class UniqueQueue
 
        Value pop_front()
        {
-               typename core::list<Value>::Iterator i = m_list.begin();
+               typename std::list<Value>::iterator i = m_list.begin();
                Value value = *i;
-               m_map.remove(value);
+               m_map.erase(value);
                m_list.erase(i);
                return value;
        }
 
        u32 size()
        {
-               assert(m_list.size() == m_map.size());
-               return m_list.size();
+               return m_map.size();
        }
 
 private:
-       core::map<Value, u8> m_map;
-       core::list<Value> m_list;
+       std::map<Value, u8> m_map;
+       std::list<Value> m_list;
 };
 
 #if 1
@@ -80,8 +83,6 @@ class MutexedMap
 public:
        MutexedMap()
        {
-               m_mutex.Init();
-               assert(m_mutex.IsInitialized());
        }
        
        void set(const Key &name, const Value &value)
@@ -95,31 +96,36 @@ class MutexedMap
        {
                JMutexAutoLock lock(m_mutex);
 
-               typename core::map<Key, Value>::Node *n;
+               typename std::map<Key, Value>::iterator n;
                n = m_values.find(name);
 
-               if(n == NULL)
+               if(n == m_values.end())
                        return false;
                
                if(result != NULL)
-                       *result = n->getValue();
+                       *result = n->second;
                        
                return true;
        }
 
-       core::list<Value> getValues()
+       std::list<Value> getValues()
        {
-               core::list<Value> result;
-               for(typename core::map<Key, Value>::Iterator
-                               i = m_values.getIterator();
-                               i.atEnd() == false; i++){
-                       result.push_back(i.getNode()->getValue());
+               std::list<Value> result;
+               for(typename std::map<Key, Value>::iterator
+                               i = m_values.begin();
+                               i != m_values.end(); ++i){
+                       result.push_back(i->second);
                }
                return result;
        }
+       
+       void clear ()
+       {
+               m_values.clear();
+       }
 
 private:
-       core::map<Key, Value> m_values;
+       std::map<Key, Value> m_values;
        JMutex m_mutex;
 };
 #endif
@@ -142,8 +148,6 @@ class MutexedIdGenerator
 public:
        MutexedIdGenerator()
        {
-               m_mutex.Init();
-               assert(m_mutex.IsInitialized());
        }
        
        // Returns true if found
@@ -163,10 +167,10 @@ class MutexedIdGenerator
        u32 getId(const T &value)
        {
                JMutexAutoLock lock(m_mutex);
-               typename core::map<T, u32>::Node *n;
+               typename std::map<T, u32>::iterator n;
                n = m_value_to_id.find(value);
-               if(n != NULL)
-                       return n->getValue();
+               if(n != m_value_to_id.end())
+                       return n->second;
                m_id_to_value.push_back(value);
                u32 new_id = m_id_to_value.size();
                m_value_to_id.insert(value, new_id);
@@ -176,8 +180,8 @@ class MutexedIdGenerator
 private:
        JMutex m_mutex;
        // Values are stored here at id-1 position (id 1 = [0])
-       core::array<T> m_id_to_value;
-       core::map<T, u32> m_value_to_id;
+       std::vector<T> m_id_to_value;
+       std::map<T, u32> m_value_to_id;
 };
 
 /*
@@ -187,39 +191,58 @@ template<typename T>
 class Queue
 {
 public:
+       Queue():
+               m_list_size(0)
+       {}
+
        void push_back(T t)
        {
                m_list.push_back(t);
+               ++m_list_size;
        }
        
+       void push_front(T t)
+       {
+               m_list.push_front(t);
+               ++m_list_size;
+       }
+
        T pop_front()
        {
-               if(m_list.size() == 0)
+               if(m_list.empty())
                        throw ItemNotFoundException("Queue: queue is empty");
 
-               typename core::list<T>::Iterator begin = m_list.begin();
+               typename std::list<T>::iterator begin = m_list.begin();
                T t = *begin;
                m_list.erase(begin);
+               --m_list_size;
                return t;
        }
        T pop_back()
        {
-               if(m_list.size() == 0)
+               if(m_list.empty())
                        throw ItemNotFoundException("Queue: queue is empty");
 
-               typename core::list<T>::Iterator last = m_list.getLast();
+               typename std::list<T>::iterator last = m_list.back();
                T t = *last;
                m_list.erase(last);
+               --m_list_size;
                return t;
        }
 
        u32 size()
        {
-               return m_list.size();
+               return m_list_size;
+       }
+
+       bool empty()
+       {
+               return m_list.empty();
        }
 
 protected:
-       core::list<T> m_list;
+       std::list<T> m_list;
+       u32 m_list_size;
 };
 
 /*
@@ -230,86 +253,141 @@ template<typename T>
 class MutexedQueue
 {
 public:
+       template<typename Key, typename U, typename Caller, typename CallerData>
+       friend class RequestQueue;
+
        MutexedQueue()
        {
-               m_mutex.Init();
        }
-       u32 size()
+       bool empty()
        {
                JMutexAutoLock lock(m_mutex);
-               return m_list.size();
+               return (m_size.GetValue() == 0);
        }
        void push_back(T t)
        {
                JMutexAutoLock lock(m_mutex);
                m_list.push_back(t);
+               m_size.Post();
        }
-       T pop_front(u32 wait_time_max_ms=0)
+
+       /* this version of pop_front returns a empty element of T on timeout.
+        * Make sure default constructor of T creates a recognizable "empty" element
+        */
+       T pop_frontNoEx(u32 wait_time_max_ms)
        {
-               u32 wait_time_ms = 0;
+               if (m_size.Wait(wait_time_max_ms))
+               {
+                       JMutexAutoLock lock(m_mutex);
 
-               for(;;)
+                       typename std::list<T>::iterator begin = m_list.begin();
+                       T t = *begin;
+                       m_list.erase(begin);
+                       return t;
+               }
+               else
                {
-                       {
-                               JMutexAutoLock lock(m_mutex);
-
-                               if(m_list.size() > 0)
-                               {
-                                       typename core::list<T>::Iterator begin = m_list.begin();
-                                       T t = *begin;
-                                       m_list.erase(begin);
-                                       return t;
-                               }
-
-                               if(wait_time_ms >= wait_time_max_ms)
-                                       throw ItemNotFoundException("MutexedQueue: queue is empty");
-                       }
-
-                       // Wait a while before trying again
-                       sleep_ms(10);
-                       wait_time_ms += 10;
+                       return T();
+               }
+       }
+
+       T pop_front(u32 wait_time_max_ms)
+       {
+               if (m_size.Wait(wait_time_max_ms))
+               {
+                       JMutexAutoLock lock(m_mutex);
+
+                       typename std::list<T>::iterator begin = m_list.begin();
+                       T t = *begin;
+                       m_list.erase(begin);
+                       return t;
                }
+               else
+               {
+                       throw ItemNotFoundException("MutexedQueue: queue is empty");
+               }
+       }
+
+       T pop_frontNoEx()
+       {
+               m_size.Wait();
+
+               JMutexAutoLock lock(m_mutex);
+
+               typename std::list<T>::iterator begin = m_list.begin();
+               T t = *begin;
+               m_list.erase(begin);
+               return t;
        }
+
        T pop_back(u32 wait_time_max_ms=0)
        {
-               u32 wait_time_ms = 0;
+               if (m_size.Wait(wait_time_max_ms))
+               {
+                       JMutexAutoLock lock(m_mutex);
 
-               for(;;)
+                       typename std::list<T>::iterator last = m_list.end();
+                       last--;
+                       T t = *last;
+                       m_list.erase(last);
+                       return t;
+               }
+               else
                {
-                       {
-                               JMutexAutoLock lock(m_mutex);
-
-                               if(m_list.size() > 0)
-                               {
-                                       typename core::list<T>::Iterator last = m_list.getLast();
-                                       T t = *last;
-                                       m_list.erase(last);
-                                       return t;
-                               }
-
-                               if(wait_time_ms >= wait_time_max_ms)
-                                       throw ItemNotFoundException("MutexedQueue: queue is empty");
-                       }
-
-                       // Wait a while before trying again
-                       sleep_ms(10);
-                       wait_time_ms += 10;
+                       throw ItemNotFoundException("MutexedQueue: queue is empty");
                }
        }
 
+       /* this version of pop_back returns a empty element of T on timeout.
+        * Make sure default constructor of T creates a recognizable "empty" element
+        */
+       T pop_backNoEx(u32 wait_time_max_ms=0)
+       {
+               if (m_size.Wait(wait_time_max_ms))
+               {
+                       JMutexAutoLock lock(m_mutex);
+
+                       typename std::list<T>::iterator last = m_list.end();
+                       last--;
+                       T t = *last;
+                       m_list.erase(last);
+                       return t;
+               }
+               else
+               {
+                       return T();
+               }
+       }
+
+       T pop_backNoEx()
+       {
+               m_size.Wait();
+
+               JMutexAutoLock lock(m_mutex);
+
+               typename std::list<T>::iterator last = m_list.end();
+               last--;
+               T t = *last;
+               m_list.erase(last);
+               return t;
+       }
+
+protected:
        JMutex & getMutex()
        {
                return m_mutex;
        }
 
-       core::list<T> & getList()
+       // NEVER EVER modify the >>list<< you got by using this function!
+       // You may only modify it's content
+       std::list<T> & getList()
        {
                return m_list;
        }
 
-protected:
        JMutex m_mutex;
-       core::list<T> m_list;
+       std::list<T> m_list;
+       JSemaphore m_size;
 };
 
 #endif