3 Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #ifndef UTILITY_HEADER
21 #define UTILITY_HEADER
30 #include <jmutexautolock.h>
33 #include "common_irrlicht.h"
35 #include "exceptions.h"
37 #include "strfnd.h" // For trim()
39 extern const v3s16 g_6dirs[6];
41 extern const v3s16 g_26dirs[26];
44 extern const v3s16 g_27dirs[27];
46 inline void writeU64(u8 *data, u64 i)
48 data[0] = ((i>>56)&0xff);
49 data[1] = ((i>>48)&0xff);
50 data[2] = ((i>>40)&0xff);
51 data[3] = ((i>>32)&0xff);
52 data[4] = ((i>>24)&0xff);
53 data[5] = ((i>>16)&0xff);
54 data[6] = ((i>> 8)&0xff);
55 data[7] = ((i>> 0)&0xff);
58 inline void writeU32(u8 *data, u32 i)
60 data[0] = ((i>>24)&0xff);
61 data[1] = ((i>>16)&0xff);
62 data[2] = ((i>> 8)&0xff);
63 data[3] = ((i>> 0)&0xff);
66 inline void writeU16(u8 *data, u16 i)
68 data[0] = ((i>> 8)&0xff);
69 data[1] = ((i>> 0)&0xff);
72 inline void writeU8(u8 *data, u8 i)
74 data[0] = ((i>> 0)&0xff);
77 inline u64 readU64(u8 *data)
79 return ((u64)data[0]<<56) | ((u64)data[1]<<48)
80 | ((u64)data[2]<<40) | ((u64)data[3]<<32)
81 | ((u64)data[4]<<24) | ((u64)data[5]<<16)
82 | ((u64)data[6]<<8) | ((u64)data[7]<<0);
85 inline u32 readU32(u8 *data)
87 return (data[0]<<24) | (data[1]<<16) | (data[2]<<8) | (data[3]<<0);
90 inline u16 readU16(u8 *data)
92 return (data[0]<<8) | (data[1]<<0);
95 inline u8 readU8(u8 *data)
100 inline void writeS32(u8 *data, s32 i){
101 writeU32(data, (u32)i);
103 inline s32 readS32(u8 *data){
104 return (s32)readU32(data);
107 inline void writeF1000(u8 *data, f32 i){
108 writeS32(data, i*1000);
110 inline f32 readF1000(u8 *data){
111 return (f32)readS32(data)/1000.;
114 inline void writeS16(u8 *data, s16 i){
115 writeU16(data, (u16)i);
117 inline s16 readS16(u8 *data){
118 return (s16)readU16(data);
121 inline void writeV3S32(u8 *data, v3s32 p)
123 writeS32(&data[0], p.X);
124 writeS32(&data[4], p.Y);
125 writeS32(&data[8], p.Z);
127 inline v3s32 readV3S32(u8 *data)
130 p.X = readS32(&data[0]);
131 p.Y = readS32(&data[4]);
132 p.Z = readS32(&data[8]);
136 inline void writeV3F1000(u8 *data, v3f p)
138 writeF1000(&data[0], p.X);
139 writeF1000(&data[4], p.Y);
140 writeF1000(&data[8], p.Z);
142 inline v3f readV3F1000(u8 *data)
145 p.X = (float)readF1000(&data[0]);
146 p.Y = (float)readF1000(&data[4]);
147 p.Z = (float)readF1000(&data[8]);
151 inline void writeV2F1000(u8 *data, v2f p)
153 writeF1000(&data[0], p.X);
154 writeF1000(&data[4], p.Y);
156 inline v2f readV2F1000(u8 *data)
159 p.X = (float)readF1000(&data[0]);
160 p.Y = (float)readF1000(&data[4]);
164 inline void writeV2S16(u8 *data, v2s16 p)
166 writeS16(&data[0], p.X);
167 writeS16(&data[2], p.Y);
170 inline v2s16 readV2S16(u8 *data)
173 p.X = readS16(&data[0]);
174 p.Y = readS16(&data[2]);
178 inline void writeV2S32(u8 *data, v2s32 p)
180 writeS32(&data[0], p.X);
181 writeS32(&data[2], p.Y);
184 inline v2s32 readV2S32(u8 *data)
187 p.X = readS32(&data[0]);
188 p.Y = readS32(&data[2]);
192 inline void writeV3S16(u8 *data, v3s16 p)
194 writeS16(&data[0], p.X);
195 writeS16(&data[2], p.Y);
196 writeS16(&data[4], p.Z);
199 inline v3s16 readV3S16(u8 *data)
202 p.X = readS16(&data[0]);
203 p.Y = readS16(&data[2]);
204 p.Z = readS16(&data[4]);
209 The above stuff directly interfaced to iostream
212 inline void writeU8(std::ostream &os, u8 p)
215 writeU8((u8*)buf, p);
218 inline u8 readU8(std::istream &is)
222 return readU8((u8*)buf);
225 inline void writeU16(std::ostream &os, u16 p)
228 writeU16((u8*)buf, p);
231 inline u16 readU16(std::istream &is)
235 return readU16((u8*)buf);
238 inline void writeU32(std::ostream &os, u32 p)
241 writeU32((u8*)buf, p);
244 inline u32 readU32(std::istream &is)
248 return readU32((u8*)buf);
251 inline void writeS32(std::ostream &os, u32 p)
254 writeS32((u8*)buf, p);
257 inline u32 readS32(std::istream &is)
261 return readS32((u8*)buf);
264 inline void writeF1000(std::ostream &os, f32 p)
267 writeF1000((u8*)buf, p);
270 inline f32 readF1000(std::istream &is)
274 return readF1000((u8*)buf);
277 inline void writeV3F1000(std::ostream &os, v3f p)
280 writeV3F1000((u8*)buf, p);
283 inline v3f readV3F1000(std::istream &is)
287 return readV3F1000((u8*)buf);
290 inline void writeV2F1000(std::ostream &os, v2f p)
293 writeV2F1000((u8*)buf, p);
296 inline v2f readV2F1000(std::istream &is)
300 return readV2F1000((u8*)buf);
303 inline void writeV2S16(std::ostream &os, v2s16 p)
306 writeV2S16((u8*)buf, p);
309 inline v2s16 readV2S16(std::istream &is)
313 return readV2S16((u8*)buf);
316 inline void writeV3S16(std::ostream &os, v3s16 p)
319 writeV3S16((u8*)buf, p);
322 inline v3s16 readV3S16(std::istream &is)
326 return readV3S16((u8*)buf);
330 None of these are used at the moment
333 template <typename T>
343 SharedPtr(SharedPtr<T> &t)
347 refcount = t.refcount;
355 SharedPtr<T> & operator=(T *t)
363 SharedPtr<T> & operator=(SharedPtr<T> &t)
366 refcount = t.refcount;
379 bool operator!=(T *t)
383 bool operator==(T *t)
387 T & operator[](unsigned int i)
394 assert((*refcount) > 0);
407 template <typename T>
416 Buffer(unsigned int size)
424 Buffer(const Buffer &buffer)
426 m_size = buffer.m_size;
429 data = new T[buffer.m_size];
430 memcpy(data, buffer.data, buffer.m_size);
435 Buffer(const T *t, unsigned int size)
441 memcpy(data, t, size);
450 Buffer& operator=(const Buffer &buffer)
455 m_size = buffer.m_size;
458 data = new T[buffer.m_size];
459 memcpy(data, buffer.data, buffer.m_size);
465 T & operator[](unsigned int i) const
469 T * operator*() const
473 unsigned int getSize() const
487 template <typename T>
495 refcount = new unsigned int;
498 SharedBuffer(unsigned int size)
502 data = new T[m_size];
505 refcount = new unsigned int;
508 SharedBuffer(const SharedBuffer &buffer)
510 //std::cout<<"SharedBuffer(const SharedBuffer &buffer)"<<std::endl;
511 m_size = buffer.m_size;
513 refcount = buffer.refcount;
516 SharedBuffer & operator=(const SharedBuffer & buffer)
518 //std::cout<<"SharedBuffer & operator=(const SharedBuffer & buffer)"<<std::endl;
522 m_size = buffer.m_size;
524 refcount = buffer.refcount;
531 SharedBuffer(T *t, unsigned int size)
536 data = new T[m_size];
537 memcpy(data, t, m_size);
541 refcount = new unsigned int;
547 SharedBuffer(const Buffer<T> &buffer)
549 m_size = buffer.getSize();
552 data = new T[m_size];
553 memcpy(data, *buffer, buffer.getSize());
557 refcount = new unsigned int;
564 T & operator[](unsigned int i) const
569 T * operator*() const
573 unsigned int getSize() const
577 operator Buffer<T>() const
579 return Buffer<T>(data, m_size);
584 assert((*refcount) > 0);
595 unsigned int *refcount;
598 inline SharedBuffer<u8> SharedBufferFromString(const char *string)
600 SharedBuffer<u8> b((u8*)string, strlen(string)+1);
605 class MutexedVariable
608 MutexedVariable(T value):
616 JMutexAutoLock lock(m_mutex);
622 JMutexAutoLock lock(m_mutex);
626 // You'll want to grab this in a SharedPtr
627 JMutexAutoLock * getLock()
629 return new JMutexAutoLock(m_mutex);
632 // You pretty surely want to grab the lock when accessing this
646 TimeTaker(const char *name, u32 *result=NULL);
653 u32 stop(bool quiet=false);
665 // Sets the color of all vertices in the mesh
666 void setMeshVerticesColor(scene::IMesh* mesh, video::SColor& color);
669 // Calculates the borders of a "d-radius" cube
670 inline void getFacePositions(core::list<v3s16> &list, u16 d)
674 list.push_back(v3s16(0,0,0));
680 This is an optimized sequence of coordinates.
682 list.push_back(v3s16( 0, 1, 0)); // top
683 list.push_back(v3s16( 0, 0, 1)); // back
684 list.push_back(v3s16(-1, 0, 0)); // left
685 list.push_back(v3s16( 1, 0, 0)); // right
686 list.push_back(v3s16( 0, 0,-1)); // front
687 list.push_back(v3s16( 0,-1, 0)); // bottom
689 list.push_back(v3s16(-1, 0, 1)); // back left
690 list.push_back(v3s16( 1, 0, 1)); // back right
691 list.push_back(v3s16(-1, 0,-1)); // front left
692 list.push_back(v3s16( 1, 0,-1)); // front right
693 list.push_back(v3s16(-1,-1, 0)); // bottom left
694 list.push_back(v3s16( 1,-1, 0)); // bottom right
695 list.push_back(v3s16( 0,-1, 1)); // bottom back
696 list.push_back(v3s16( 0,-1,-1)); // bottom front
697 list.push_back(v3s16(-1, 1, 0)); // top left
698 list.push_back(v3s16( 1, 1, 0)); // top right
699 list.push_back(v3s16( 0, 1, 1)); // top back
700 list.push_back(v3s16( 0, 1,-1)); // top front
702 list.push_back(v3s16(-1, 1, 1)); // top back-left
703 list.push_back(v3s16( 1, 1, 1)); // top back-right
704 list.push_back(v3s16(-1, 1,-1)); // top front-left
705 list.push_back(v3s16( 1, 1,-1)); // top front-right
706 list.push_back(v3s16(-1,-1, 1)); // bottom back-left
707 list.push_back(v3s16( 1,-1, 1)); // bottom back-right
708 list.push_back(v3s16(-1,-1,-1)); // bottom front-left
709 list.push_back(v3s16( 1,-1,-1)); // bottom front-right
714 // Take blocks in all sides, starting from y=0 and going +-y
715 for(s16 y=0; y<=d-1; y++)
717 // Left and right side, including borders
718 for(s16 z=-d; z<=d; z++)
720 list.push_back(v3s16(d,y,z));
721 list.push_back(v3s16(-d,y,z));
724 list.push_back(v3s16(d,-y,z));
725 list.push_back(v3s16(-d,-y,z));
728 // Back and front side, excluding borders
729 for(s16 x=-d+1; x<=d-1; x++)
731 list.push_back(v3s16(x,y,d));
732 list.push_back(v3s16(x,y,-d));
735 list.push_back(v3s16(x,-y,d));
736 list.push_back(v3s16(x,-y,-d));
741 // Take the bottom and top face with borders
742 // -d<x<d, y=+-d, -d<z<d
743 for(s16 x=-d; x<=d; x++)
744 for(s16 z=-d; z<=d; z++)
746 list.push_back(v3s16(x,-d,z));
747 list.push_back(v3s16(x,d,z));
751 class IndentationRaiser
754 IndentationRaiser(u16 *indentation)
756 m_indentation = indentation;
767 inline s16 getContainerPos(s16 p, s16 d)
769 return (p>=0 ? p : p-d+1) / d;
772 inline v2s16 getContainerPos(v2s16 p, s16 d)
775 getContainerPos(p.X, d),
776 getContainerPos(p.Y, d)
780 inline v3s16 getContainerPos(v3s16 p, s16 d)
783 getContainerPos(p.X, d),
784 getContainerPos(p.Y, d),
785 getContainerPos(p.Z, d)
789 inline v2s16 getContainerPos(v2s16 p, v2s16 d)
792 getContainerPos(p.X, d.X),
793 getContainerPos(p.Y, d.Y)
797 inline v3s16 getContainerPos(v3s16 p, v3s16 d)
800 getContainerPos(p.X, d.X),
801 getContainerPos(p.Y, d.Y),
802 getContainerPos(p.Z, d.Z)
806 inline bool isInArea(v3s16 p, s16 d)
809 p.X >= 0 && p.X < d &&
810 p.Y >= 0 && p.Y < d &&
815 inline bool isInArea(v2s16 p, s16 d)
818 p.X >= 0 && p.X < d &&
823 inline bool isInArea(v3s16 p, v3s16 d)
826 p.X >= 0 && p.X < d.X &&
827 p.Y >= 0 && p.Y < d.Y &&
828 p.Z >= 0 && p.Z < d.Z
832 inline s16 rangelim(s16 i, s16 max)
841 #define rangelim(d, min, max) ((d) < (min) ? (min) : ((d)>(max)?(max):(d)))
843 inline v3s16 arealim(v3s16 p, s16 d)
860 inline std::wstring narrow_to_wide(const std::string& mbs)
862 size_t wcl = mbs.size();
863 Buffer<wchar_t> wcs(wcl+1);
864 size_t l = mbstowcs(*wcs, mbs.c_str(), wcl);
865 if(l == (size_t)(-1))
866 return L"<invalid multibyte string>";
871 inline std::string wide_to_narrow(const std::wstring& wcs)
873 size_t mbl = wcs.size()*4;
874 SharedBuffer<char> mbs(mbl+1);
875 size_t l = wcstombs(*mbs, wcs.c_str(), mbl);
876 if(l == (size_t)(-1))
883 // Split a string using the given delimiter. Returns a vector containing
884 // the component parts.
885 inline std::vector<std::wstring> str_split(const std::wstring &str, wchar_t delimiter)
887 std::vector<std::wstring> parts;
888 std::wstringstream sstr(str);
890 while(std::getline(sstr, part, delimiter))
891 parts.push_back(part);
897 See test.cpp for example cases.
898 wraps degrees to the range of -360...360
899 NOTE: Wrapping to 0...360 is not used because pitch needs negative values.
901 inline float wrapDegrees(float f)
903 // Take examples of f=10, f=720.5, f=-0.5, f=-360.5
909 // NOTE: This would be used for wrapping to 0...360
915 // 10, 0.5, -0.5, -0.5
920 /* Wrap to 0...360 */
921 inline float wrapDegrees_0_360(float f)
923 // Take examples of f=10, f=720.5, f=-0.5, f=-360.5
935 // 10, 0.5, -0.5, -0.5
940 /* Wrap to -180...180 */
941 inline float wrapDegrees_180(float f)
944 f = wrapDegrees_0_360(f);
949 inline std::string lowercase(const std::string &s)
952 for(size_t i=0; i<s.size(); i++)
955 if(c >= 'A' && c <= 'Z')
962 inline bool is_yes(const std::string &s)
964 std::string s2 = lowercase(trim(s));
965 if(s2 == "y" || s2 == "yes" || s2 == "true" || s2 == "1")
970 inline s32 stoi(const std::string &s, s32 min, s32 max)
972 s32 i = atoi(s.c_str());
981 // MSVC2010 includes it's own versions of these
982 #if !defined(_MSC_VER) || _MSC_VER < 1600
984 inline s32 stoi(std::string s)
986 return atoi(s.c_str());
989 inline s32 stoi(std::wstring s)
991 return atoi(wide_to_narrow(s).c_str());
994 inline float stof(std::string s)
997 std::istringstream ss(s);
1004 inline std::string itos(s32 i)
1006 std::ostringstream o;
1011 inline std::string ftos(float f)
1013 std::ostringstream o;
1018 inline void str_replace(std::string & str, std::string const & pattern,
1019 std::string const & replacement)
1021 std::string::size_type start = str.find(pattern, 0);
1022 while(start != str.npos)
1024 str.replace(start, pattern.size(), replacement);
1025 start = str.find(pattern, start+replacement.size());
1029 inline void str_replace_char(std::string & str, char from, char to)
1031 for(unsigned int i=0; i<str.size(); i++)
1039 A base class for simple background thread implementation
1042 class SimpleThread : public JThread
1056 virtual ~SimpleThread()
1059 virtual void * Thread() = 0;
1063 JMutexAutoLock lock(run_mutex);
1066 void setRun(bool a_run)
1068 JMutexAutoLock lock(run_mutex);
1081 FIFO queue (well, actually a FILO also)
1083 template<typename T>
1089 m_list.push_back(t);
1094 if(m_list.size() == 0)
1095 throw ItemNotFoundException("Queue: queue is empty");
1097 typename core::list<T>::Iterator begin = m_list.begin();
1099 m_list.erase(begin);
1104 if(m_list.size() == 0)
1105 throw ItemNotFoundException("Queue: queue is empty");
1107 typename core::list<T>::Iterator last = m_list.getLast();
1115 return m_list.size();
1119 core::list<T> m_list;
1123 Thread-safe FIFO queue (well, actually a FILO also)
1126 template<typename T>
1136 JMutexAutoLock lock(m_mutex);
1137 return m_list.size();
1141 JMutexAutoLock lock(m_mutex);
1142 m_list.push_back(t);
1144 T pop_front(u32 wait_time_max_ms=0)
1146 u32 wait_time_ms = 0;
1151 JMutexAutoLock lock(m_mutex);
1153 if(m_list.size() > 0)
1155 typename core::list<T>::Iterator begin = m_list.begin();
1157 m_list.erase(begin);
1161 if(wait_time_ms >= wait_time_max_ms)
1162 throw ItemNotFoundException("MutexedQueue: queue is empty");
1165 // Wait a while before trying again
1170 T pop_back(u32 wait_time_max_ms=0)
1172 u32 wait_time_ms = 0;
1177 JMutexAutoLock lock(m_mutex);
1179 if(m_list.size() > 0)
1181 typename core::list<T>::Iterator last = m_list.getLast();
1187 if(wait_time_ms >= wait_time_max_ms)
1188 throw ItemNotFoundException("MutexedQueue: queue is empty");
1191 // Wait a while before trying again
1202 core::list<T> & getList()
1209 core::list<T> m_list;
1213 A single worker thread - multiple client threads queue framework.
1216 template<typename Caller, typename Data>
1224 template<typename Key, typename T, typename Caller, typename CallerData>
1230 core::list<CallerInfo<Caller, CallerData> > callers;
1233 template<typename Key, typename T, typename Caller, typename CallerData>
1234 class ResultQueue: public MutexedQueue< GetResult<Key, T, Caller, CallerData> >
1238 template<typename Key, typename T, typename Caller, typename CallerData>
1246 GetRequest(ResultQueue<Key,T, Caller, CallerData> *a_dest)
1250 GetRequest(ResultQueue<Key,T, Caller, CallerData> *a_dest,
1261 ResultQueue<Key, T, Caller, CallerData> *dest;
1262 core::list<CallerInfo<Caller, CallerData> > callers;
1265 template<typename Key, typename T, typename Caller, typename CallerData>
1271 return m_queue.size();
1274 void add(Key key, Caller caller, CallerData callerdata,
1275 ResultQueue<Key, T, Caller, CallerData> *dest)
1277 JMutexAutoLock lock(m_queue.getMutex());
1280 If the caller is already on the list, only update CallerData
1282 for(typename core::list< GetRequest<Key, T, Caller, CallerData> >::Iterator
1283 i = m_queue.getList().begin();
1284 i != m_queue.getList().end(); i++)
1286 GetRequest<Key, T, Caller, CallerData> &request = *i;
1288 if(request.key == key)
1290 for(typename core::list< CallerInfo<Caller, CallerData> >::Iterator
1291 i = request.callers.begin();
1292 i != request.callers.end(); i++)
1294 CallerInfo<Caller, CallerData> &ca = *i;
1295 if(ca.caller == caller)
1297 ca.data = callerdata;
1301 CallerInfo<Caller, CallerData> ca;
1303 ca.data = callerdata;
1304 request.callers.push_back(ca);
1310 Else add a new request to the queue
1313 GetRequest<Key, T, Caller, CallerData> request;
1315 CallerInfo<Caller, CallerData> ca;
1317 ca.data = callerdata;
1318 request.callers.push_back(ca);
1319 request.dest = dest;
1321 m_queue.getList().push_back(request);
1324 GetRequest<Key, T, Caller, CallerData> pop(bool wait_if_empty=false)
1326 return m_queue.pop_front(wait_if_empty);
1330 MutexedQueue< GetRequest<Key, T, Caller, CallerData> > m_queue;
1334 Pseudo-random (VC++ rand() sucks)
1337 void mysrand(unsigned seed);
1338 #define MYRAND_MAX 32767
1340 int myrand_range(int min, int max);
1343 Miscellaneous functions
1346 bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
1347 f32 camera_fov, f32 range, f32 *distance_ptr=NULL);
1350 Queue with unique values with fast checking of value existence
1353 template<typename Value>
1359 Does nothing if value is already queued.
1362 false: value already exists
1364 bool push_back(Value value)
1366 // Check if already exists
1367 if(m_map.find(value) != NULL)
1371 m_map.insert(value, 0);
1372 m_list.push_back(value);
1379 typename core::list<Value>::Iterator i = m_list.begin();
1381 m_map.remove(value);
1388 assert(m_list.size() == m_map.size());
1389 return m_list.size();
1393 core::map<Value, u8> m_map;
1394 core::list<Value> m_list;
1398 template<typename Key, typename Value>
1405 assert(m_mutex.IsInitialized());
1408 void set(const Key &name, const Value &value)
1410 JMutexAutoLock lock(m_mutex);
1412 m_values[name] = value;
1415 bool get(const Key &name, Value *result)
1417 JMutexAutoLock lock(m_mutex);
1419 typename core::map<Key, Value>::Node *n;
1420 n = m_values.find(name);
1426 *result = n->getValue();
1432 core::map<Key, Value> m_values;
1438 Generates ids for comparable values.
1439 Id=0 is reserved for "no value".
1442 - Returning value by id (very fast)
1443 - Returning id by value
1444 - Generating a new id for a value
1447 - Remove an id/value pair (is possible to implement but slow)
1449 template<typename T>
1450 class MutexedIdGenerator
1453 MutexedIdGenerator()
1456 assert(m_mutex.IsInitialized());
1459 // Returns true if found
1460 bool getValue(u32 id, T &value)
1464 JMutexAutoLock lock(m_mutex);
1465 if(m_id_to_value.size() < id)
1467 value = m_id_to_value[id-1];
1471 // If id exists for value, returns the id.
1472 // Otherwise generates an id for the value.
1473 u32 getId(const T &value)
1475 JMutexAutoLock lock(m_mutex);
1476 typename core::map<T, u32>::Node *n;
1477 n = m_value_to_id.find(value);
1479 return n->getValue();
1480 m_id_to_value.push_back(value);
1481 u32 new_id = m_id_to_value.size();
1482 m_value_to_id.insert(value, new_id);
1488 // Values are stored here at id-1 position (id 1 = [0])
1489 core::array<T> m_id_to_value;
1490 core::map<T, u32> m_value_to_id;
1494 Checks if a string contains only supplied characters
1496 inline bool string_allowed(const std::string &s, const std::string &allowed_chars)
1498 for(u32 i=0; i<s.size(); i++)
1500 bool confirmed = false;
1501 for(u32 j=0; j<allowed_chars.size(); j++)
1503 if(s[i] == allowed_chars[j])
1509 if(confirmed == false)
1516 Forcefully wraps string into rows using \n
1517 (no word wrap, used for showing paths in gui)
1519 inline std::string wrap_rows(const std::string &from, u32 rowlen)
1522 for(u32 i=0; i<from.size(); i++)
1524 if(i != 0 && i%rowlen == 0)
1534 #define MYMIN(a,b) ((a)<(b)?(a):(b))
1535 #define MYMAX(a,b) ((a)>(b)?(a):(b))
1538 Returns integer position of node in given floating point position
1540 inline v3s16 floatToInt(v3f p, f32 d)
1543 (p.X + (p.X>0 ? d/2 : -d/2))/d,
1544 (p.Y + (p.Y>0 ? d/2 : -d/2))/d,
1545 (p.Z + (p.Z>0 ? d/2 : -d/2))/d);
1550 Returns floating point position of node in given integer position
1552 inline v3f intToFloat(v3s16 p, f32 d)
1563 More serialization stuff
1566 // Creates a string with the length as the first two bytes
1567 inline std::string serializeString(const std::string &plain)
1569 //assert(plain.size() <= 65535);
1570 if(plain.size() > 65535)
1571 throw SerializationError("String too long for serializeString");
1573 writeU16((u8*)&buf[0], plain.size());
1580 // Creates a string with the length as the first two bytes from wide string
1581 inline std::string serializeWideString(const std::wstring &plain)
1583 //assert(plain.size() <= 65535);
1584 if(plain.size() > 65535)
1585 throw SerializationError("String too long for serializeString");
1587 writeU16((u8*)buf, plain.size());
1590 for(u32 i=0; i<plain.size(); i++)
1592 writeU16((u8*)buf, plain[i]);
1598 // Reads a string with the length as the first two bytes
1599 inline std::string deSerializeString(std::istream &is)
1603 if(is.gcount() != 2)
1604 throw SerializationError("deSerializeString: size not read");
1605 u16 s_size = readU16((u8*)buf);
1608 Buffer<char> buf2(s_size);
1609 is.read(&buf2[0], s_size);
1612 s.append(&buf2[0], s_size);
1616 // Reads a wide string with the length as the first two bytes
1617 inline std::wstring deSerializeWideString(std::istream &is)
1621 if(is.gcount() != 2)
1622 throw SerializationError("deSerializeString: size not read");
1623 u16 s_size = readU16((u8*)buf);
1628 for(u32 i=0; i<s_size; i++)
1630 is.read(&buf[0], 2);
1631 wchar_t c16 = readU16((u8*)buf);
1637 // Creates a string with the length as the first four bytes
1638 inline std::string serializeLongString(const std::string &plain)
1641 writeU32((u8*)&buf[0], plain.size());
1648 // Reads a string with the length as the first four bytes
1649 inline std::string deSerializeLongString(std::istream &is)
1653 if(is.gcount() != 4)
1654 throw SerializationError("deSerializeLongString: size not read");
1655 u32 s_size = readU32((u8*)buf);
1658 Buffer<char> buf2(s_size);
1659 is.read(&buf2[0], s_size);
1662 s.append(&buf2[0], s_size);
1668 inline u32 time_to_daynight_ratio(u32 time_of_day)
1670 const s32 daylength = 16;
1671 const s32 nightlength = 6;
1672 const s32 daytimelength = 8;
1674 s32 t = (((time_of_day)%24000)/(24000/d));
1675 if(t < nightlength/2 || t >= d - nightlength/2)
1678 else if(t >= d/2 - daytimelength/2 && t < d/2 + daytimelength/2)
1684 // Random helper. Usually d=BS
1685 inline core::aabbox3d<f32> getNodeBox(v3s16 p, float d)
1687 return core::aabbox3d<f32>(
1688 (float)p.X * d - 0.5*d,
1689 (float)p.Y * d - 0.5*d,
1690 (float)p.Z * d - 0.5*d,
1691 (float)p.X * d + 0.5*d,
1692 (float)p.Y * d + 0.5*d,
1693 (float)p.Z * d + 0.5*d
1697 class IntervalLimiter
1705 dtime: time from last call to this method
1706 wanted_interval: interval wanted
1708 true: action should be skipped
1709 false: action should be done
1711 bool step(float dtime, float wanted_interval)
1713 m_accumulator += dtime;
1714 if(m_accumulator < wanted_interval)
1716 m_accumulator -= wanted_interval;
1720 float m_accumulator;
1723 std::string translatePassword(std::string playername, std::wstring password);