]> git.lizzy.rs Git - minetest.git/blobdiff - src/utility.h
bug-fixin'
[minetest.git] / src / utility.h
index 785ff167cb391c122e3e1d5d4679e04bc1113b68..7d8102b62cc709d68621d8d0a1547e56945851c7 100644 (file)
@@ -207,6 +207,10 @@ class SharedPtr
        {
                return ptr == t;
        }
+       T & operator[](unsigned int i)
+       {
+               return ptr[i];
+       }
 private:
        void drop()
        {
@@ -409,6 +413,8 @@ class TimeTaker
 
        u32 stop(bool quiet=false);
 
+       u32 getTime();
+
 private:
        const char *m_name;
        u32 m_time1;
@@ -536,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 (
@@ -553,13 +576,13 @@ inline bool isInArea(v2s16 p, s16 d)
        );
 }
 
-inline s16 rangelim(s16 i, s16 min, s16 max)
+inline bool isInArea(v3s16 p, v3s16 d)
 {
-       if(i < min)
-               return min;
-       if(i > max)
-               return max;
-       return i;
+       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 max)
@@ -571,6 +594,8 @@ inline s16 rangelim(s16 i, s16 max)
        return i;
 }
 
+#define rangelim(d, min, max) ((d) < (min) ? (min) : ((d)>(max)?(max):(d)))
+
 inline v3s16 arealim(v3s16 p, s16 d)
 {
        if(p.X < 0)
@@ -758,17 +783,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
@@ -788,14 +816,31 @@ class Settings
                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
 
@@ -1042,6 +1087,8 @@ class Settings
                        n = m_defaults.find(name);
                        if(n == NULL)
                        {
+                               dstream<<"INFO: Settings: Setting not found: \""
+                                               <<name<<"\""<<std::endl;
                                throw SettingNotFoundException("Setting not found");
                        }
                }
@@ -1087,10 +1134,7 @@ class Settings
 
        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)
@@ -1126,6 +1170,34 @@ class Settings
                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();
@@ -1395,188 +1467,22 @@ int myrand(void);
 void mysrand(unsigned seed);
 #define MYRAND_MAX 32767
 
-/*
-       Some kind of a thing that stores attributes related to
-       coordinate points
-*/
-
-struct Attribute
-{
-       Attribute()
-       {
-       }
-
-       Attribute(const std::string &value):
-               m_value(value)
-       {
-       }
-
-       Attribute(float value)
-       {
-               m_value = ftos(value);
-       }
-
-       void set(const std::string &value)
-       {
-               m_value = value;
-       }
-       
-       std::string get()
-       {
-               return m_value;
-       }
-       
-       bool getBool()
-       {
-               return is_yes(get());
-       }
-       
-       float getFloat()
-       {
-               float f;
-               std::istringstream vis(get());
-               vis>>f;
-               return f;
-       }
-
-       u16 getU16()
-       {
-               return stoi(get(), 0, 65535);
-       }
-
-       s16 getS16()
-       {
-               return stoi(get(), -32768, 32767);
-       }
-
-       s32 getS32()
-       {
-               return stoi(get());
-       }
-
-       std::string m_value;
-};
-
-class PointAttributeList
-{
-       struct PointWithAttr
-       {
-               v2s16 p;
-               Attribute attr;
-       };
-
-public:
-       ~PointAttributeList()
-       {
-       }
-
-       Attribute getNearAttr(v2s16 p)
-       {
-               core::list<PointWithAttr>::Iterator
-                               nearest_i = m_points.end();
-               s16 nearest_d = 32767;
-               for(core::list<PointWithAttr>::Iterator
-                               i = m_points.begin();
-                               i != m_points.end(); i++)
-               {
-                       PointWithAttr &pwa = *i;
-                       s16 d = pwa.p.getDistanceFrom(p);
-                       if(d < nearest_d)
-                       {
-                               nearest_i = i;
-                               nearest_d = d;
-                       }
-               }
-
-               if(nearest_i == m_points.end())
-                       Attribute();
-
-               return nearest_i->attr;
-       }
-       
-       Attribute getNearAttr(v3s16 p)
-       {
-               return getNearAttr(v2s16(p.X, p.Z));
-       }
-
-       bool empty()
-       {
-               return (m_points.size() == 0);
-       }
-       
-       /*
-               Take all points in range, or at least the nearest point,
-               and interpolate the values as floats
-       */
-       float getInterpolatedFloat(v2s16 p);
-       
-       float getInterpolatedFloat(v3s16 p)
-       {
-               return getInterpolatedFloat(v2s16(p.X, p.Z));
-       }
-       
-       void addPoint(v2s16 p, const Attribute &attr)
-       {
-               PointWithAttr pattr;
-               pattr.p = p;
-               pattr.attr = attr;
-               m_points.push_back(pattr);
-       }
-
-       void addPoint(v3s16 p, const Attribute &attr)
-       {
-               addPoint(v2s16(p.X, p.Z), attr);
-       }
-
-private:
-       core::list<PointWithAttr> m_points;
-};
-
-/*
-       Basically just a wrapper to core::map<PointAttributeList*>
-*/
-
-class PointAttributeDatabase
+inline int myrand_range(int min, int max)
 {
-public:
-       ~PointAttributeDatabase()
+       if(min > max)
        {
-               for(core::map<std::string, PointAttributeList*>::Iterator
-                               i = m_lists.getIterator();
-                               i.atEnd() == false; i++)
-               {
-                       delete i.getNode()->getValue();
-               }
-       }
-
-       PointAttributeList *getList(const std::string &name)
-       {
-               PointAttributeList *list = NULL;
-
-               core::map<std::string, PointAttributeList*>::Node *n;
-               n = m_lists.find(name);
-               
-               if(n == NULL)
-               {
-                       list = new PointAttributeList();
-                       m_lists.insert(name, list);
-               }
-               else
-               {
-                       list = n->getValue();
-               }
-
-               return list;
+               assert(0);
+               return max;
        }
-private:
-       core::map<std::string, PointAttributeList*> m_lists;
-};
+       return (myrand()%(max-min+1))+min;
+}
 
 /*
        Miscellaneous functions
 */
 
-bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 range);
+bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 range,
+               f32 *distance_ptr=NULL);
 
 /*
        Queue with unique values with fast checking of value existence
@@ -1626,5 +1532,127 @@ class UniqueQueue
        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;
+}
+
+/*
+       Some helper stuff
+*/
+#define MYMIN(a,b) ((a)<(b)?(a):(b))
+#define MYMAX(a,b) ((a)>(b)?(a):(b))
+
 #endif