some tweaking
[oweals/minetest.git] / src / utility.h
index fd2881cffd6ade359065e0f217fdb1af15be8f2f..cc69099b43abeee1f47bc78734a6d9b8391cabab 100644 (file)
@@ -36,6 +36,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 extern const v3s16 g_26dirs[26];
 
+// 26th is (0,0,0)
+extern const v3s16 g_27dirs[27];
+
 inline void writeU32(u8 *data, u32 i)
 {
        data[0] = ((i>>24)&0xff);
@@ -204,6 +207,10 @@ public:
        {
                return ptr == t;
        }
+       T & operator[](unsigned int i)
+       {
+               return ptr[i];
+       }
 private:
        void drop()
        {
@@ -406,6 +413,8 @@ public:
 
        u32 stop(bool quiet=false);
 
+       u32 getTime();
+
 private:
        const char *m_name;
        u32 m_time1;
@@ -533,6 +542,23 @@ inline v3s16 getContainerPos(v3s16 p, s16 d)
        );
 }
 
+inline v2s16 getContainerPos(v2s16 p, v2s16 d)
+{
+       return v2s16(
+               getContainerPos(p.X, d.X),
+               getContainerPos(p.Y, d.Y)
+       );
+}
+
+inline v3s16 getContainerPos(v3s16 p, v3s16 d)
+{
+       return v3s16(
+               getContainerPos(p.X, d.X),
+               getContainerPos(p.Y, d.Y),
+               getContainerPos(p.Z, d.Z)
+       );
+}
+
 inline bool isInArea(v3s16 p, s16 d)
 {
        return (
@@ -550,6 +576,15 @@ inline bool isInArea(v2s16 p, s16 d)
        );
 }
 
+inline bool isInArea(v3s16 p, v3s16 d)
+{
+       return (
+               p.X >= 0 && p.X < d.X &&
+               p.Y >= 0 && p.Y < d.Y &&
+               p.Z >= 0 && p.Z < d.Z
+       );
+}
+
 inline s16 rangelim(s16 i, s16 min, s16 max)
 {
        if(i < min)
@@ -666,6 +701,14 @@ inline s32 stoi(std::string s)
        return atoi(s.c_str());
 }
 
+inline float stof(std::string s)
+{
+       float f;
+       std::istringstream ss(s);
+       ss>>f;
+       return f;
+}
+
 inline std::string itos(s32 i)
 {
        std::ostringstream o;
@@ -747,17 +790,20 @@ class Settings
 {
 public:
 
-       // Returns false on EOF
-       bool parseConfigObject(std::istream &is)
+       void writeLines(std::ostream &os)
        {
-               if(is.eof())
-                       return false;
-               
-               // NOTE: This function will be expanded to allow multi-line settings
-               std::string line;
-               std::getline(is, line);
-               //dstream<<"got line: \""<<line<<"\""<<std::endl;
+               for(core::map<std::string, std::string>::Iterator
+                               i = m_settings.getIterator();
+                               i.atEnd() == false; i++)
+               {
+                       std::string name = i.getNode()->getKey();
+                       std::string value = i.getNode()->getValue();
+                       os<<name<<" = "<<value<<"\n";
+               }
+       }
 
+       bool parseConfigLine(const std::string &line)
+       {
                std::string trimmedline = trim(line);
                
                // Ignore comments
@@ -777,14 +823,31 @@ public:
                std::string value = sf.next("\n");
                value = trim(value);
 
-               dstream<<"Config name=\""<<name<<"\" value=\""
-                               <<value<<"\""<<std::endl;
+               /*dstream<<"Config name=\""<<name<<"\" value=\""
+                               <<value<<"\""<<std::endl;*/
                
                m_settings[name] = value;
                
                return true;
        }
 
+       // Returns false on EOF
+       bool parseConfigObject(std::istream &is)
+       {
+               if(is.eof())
+                       return false;
+               
+               /*
+                       NOTE: This function might be expanded to allow multi-line
+                             settings.
+               */
+               std::string line;
+               std::getline(is, line);
+               //dstream<<"got line: \""<<line<<"\""<<std::endl;
+
+               return parseConfigLine(line);
+       }
+
        /*
                Read configuration file
 
@@ -1076,10 +1139,7 @@ public:
 
        float getFloat(std::string name)
        {
-               float f;
-               std::istringstream vis(get(name));
-               vis>>f;
-               return f;
+               return stof(get(name));
        }
 
        u16 getU16(std::string name)
@@ -1115,6 +1175,34 @@ public:
                return stoi(get(name));
        }
 
+       v3f getV3F(std::string name)
+       {
+               v3f value;
+               Strfnd f(get(name));
+               f.next("(");
+               value.X = stof(f.next(","));
+               value.Y = stof(f.next(","));
+               value.Z = stof(f.next(")"));
+               return value;
+       }
+
+       void setS32(std::string name, s32 value)
+       {
+               set(name, itos(value));
+       }
+
+       void setFloat(std::string name, float value)
+       {
+               set(name, ftos(value));
+       }
+
+       void setV3F(std::string name, v3f value)
+       {
+               std::ostringstream os;
+               os<<"("<<value.X<<","<<value.Y<<","<<value.Z<<")";
+               set(name, os.str());
+       }
+
        void clear()
        {
                m_settings.clear();
@@ -1384,6 +1472,16 @@ int myrand(void);
 void mysrand(unsigned seed);
 #define MYRAND_MAX 32767
 
+inline int myrand_range(int min, int max)
+{
+       if(min > max)
+       {
+               assert(0);
+               return max;
+       }
+       return (myrand()%(max-min+1))+min;
+}
+
 /*
        Some kind of a thing that stores attributes related to
        coordinate points
@@ -1615,5 +1713,121 @@ private:
        core::list<Value> m_list;
 };
 
+#if 0
+template<typename Key, typename Value>
+class MutexedCache
+{
+public:
+       MutexedCache()
+       {
+               m_mutex.Init();
+               assert(m_mutex.IsInitialized());
+       }
+       
+       void set(const Key &name, const Value &value)
+       {
+               JMutexAutoLock lock(m_mutex);
+
+               m_values[name] = value;
+       }
+       
+       bool get(const Key &name, Value *result)
+       {
+               JMutexAutoLock lock(m_mutex);
+
+               typename core::map<Key, Value>::Node *n;
+               n = m_values.find(name);
+
+               if(n == NULL)
+                       return false;
+
+               *result = n->getValue();
+               return true;
+       }
+
+private:
+       core::map<Key, Value> m_values;
+       JMutex m_mutex;
+};
+#endif
+
+/*
+       Generates ids for comparable values.
+       Id=0 is reserved for "no value".
+
+       Is fast at:
+       - Returning value by id (very fast)
+       - Returning id by value
+       - Generating a new id for a value
+
+       Is not able to:
+       - Remove an id/value pair (is possible to implement but slow)
+*/
+template<typename T>
+class MutexedIdGenerator
+{
+public:
+       MutexedIdGenerator()
+       {
+               m_mutex.Init();
+               assert(m_mutex.IsInitialized());
+       }
+       
+       // Returns true if found
+       bool getValue(u32 id, T &value)
+       {
+               if(id == 0)
+                       return false;
+               JMutexAutoLock lock(m_mutex);
+               if(m_id_to_value.size() < id)
+                       return false;
+               value = m_id_to_value[id-1];
+               return true;
+       }
+       
+       // If id exists for value, returns the id.
+       // Otherwise generates an id for the value.
+       u32 getId(const T &value)
+       {
+               JMutexAutoLock lock(m_mutex);
+               typename core::map<T, u32>::Node *n;
+               n = m_value_to_id.find(value);
+               if(n != NULL)
+                       return n->getValue();
+               m_id_to_value.push_back(value);
+               u32 new_id = m_id_to_value.size();
+               m_value_to_id.insert(value, new_id);
+               return new_id;
+       }
+
+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;
+};
+
+/*
+       Checks if a string contains only supplied characters
+*/
+inline bool string_allowed(const std::string &s, const std::string &allowed_chars)
+{
+       for(u32 i=0; i<s.size(); i++)
+       {
+               bool confirmed = false;
+               for(u32 j=0; j<allowed_chars.size(); j++)
+               {
+                       if(s[i] == allowed_chars[j])
+                       {
+                               confirmed = true;
+                               break;
+                       }
+               }
+               if(confirmed == false)
+                       return false;
+       }
+       return true;
+}
+
 #endif