]> git.lizzy.rs Git - minetest.git/blob - src/utility.h
Reduced the CPU usage of the sent block selector algorithm
[minetest.git] / src / utility.h
1 /*
2 Minetest-c55
3 Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
4
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.
9
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.
14
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.
18 */
19
20 #ifndef UTILITY_HEADER
21 #define UTILITY_HEADER
22
23 #include <iostream>
24 #include <fstream>
25 #include <string>
26 #include <sstream>
27 #include <vector>
28 #include <jthread.h>
29 #include <jmutex.h>
30 #include <jmutexautolock.h>
31
32 #include "common_irrlicht.h"
33 #include "debug.h"
34 #include "strfnd.h"
35 #include "exceptions.h"
36 #include "porting.h"
37
38 extern const v3s16 g_6dirs[6];
39
40 extern const v3s16 g_26dirs[26];
41
42 // 26th is (0,0,0)
43 extern const v3s16 g_27dirs[27];
44
45 inline void writeU64(u8 *data, u64 i)
46 {
47         data[0] = ((i>>56)&0xff);
48         data[1] = ((i>>48)&0xff);
49         data[2] = ((i>>40)&0xff);
50         data[3] = ((i>>32)&0xff);
51         data[4] = ((i>>24)&0xff);
52         data[5] = ((i>>16)&0xff);
53         data[6] = ((i>> 8)&0xff);
54         data[7] = ((i>> 0)&0xff);
55 }
56
57 inline void writeU32(u8 *data, u32 i)
58 {
59         data[0] = ((i>>24)&0xff);
60         data[1] = ((i>>16)&0xff);
61         data[2] = ((i>> 8)&0xff);
62         data[3] = ((i>> 0)&0xff);
63 }
64
65 inline void writeU16(u8 *data, u16 i)
66 {
67         data[0] = ((i>> 8)&0xff);
68         data[1] = ((i>> 0)&0xff);
69 }
70
71 inline void writeU8(u8 *data, u8 i)
72 {
73         data[0] = ((i>> 0)&0xff);
74 }
75
76 inline u64 readU64(u8 *data)
77 {
78         return ((u64)data[0]<<56) | ((u64)data[1]<<48)
79                 | ((u64)data[2]<<40) | ((u64)data[3]<<32)
80                 | ((u64)data[4]<<24) | ((u64)data[5]<<16)
81                 | ((u64)data[6]<<8) | ((u64)data[7]<<0);
82 }
83
84 inline u32 readU32(u8 *data)
85 {
86         return (data[0]<<24) | (data[1]<<16) | (data[2]<<8) | (data[3]<<0);
87 }
88
89 inline u16 readU16(u8 *data)
90 {
91         return (data[0]<<8) | (data[1]<<0);
92 }
93
94 inline u8 readU8(u8 *data)
95 {
96         return (data[0]<<0);
97 }
98
99 inline void writeS32(u8 *data, s32 i){
100         writeU32(data, (u32)i);
101 }
102 inline s32 readS32(u8 *data){
103         return (s32)readU32(data);
104 }
105
106 inline void writeF1000(u8 *data, f32 i){
107         writeS32(data, i*1000);
108 }
109 inline f32 readF1000(u8 *data){
110         return (f32)readS32(data)/1000.;
111 }
112
113 inline void writeS16(u8 *data, s16 i){
114         writeU16(data, (u16)i);
115 }
116 inline s16 readS16(u8 *data){
117         return (s16)readU16(data);
118 }
119
120 inline void writeV3S32(u8 *data, v3s32 p)
121 {
122         writeS32(&data[0], p.X);
123         writeS32(&data[4], p.Y);
124         writeS32(&data[8], p.Z);
125 }
126 inline v3s32 readV3S32(u8 *data)
127 {
128         v3s32 p;
129         p.X = readS32(&data[0]);
130         p.Y = readS32(&data[4]);
131         p.Z = readS32(&data[8]);
132         return p;
133 }
134
135 inline void writeV3F1000(u8 *data, v3f p)
136 {
137         writeF1000(&data[0], p.X);
138         writeF1000(&data[4], p.Y);
139         writeF1000(&data[8], p.Z);
140 }
141 inline v3f readV3F1000(u8 *data)
142 {
143         v3f p;
144         p.X = (float)readF1000(&data[0]);
145         p.Y = (float)readF1000(&data[4]);
146         p.Z = (float)readF1000(&data[8]);
147         return p;
148 }
149
150 inline void writeV2S16(u8 *data, v2s16 p)
151 {
152         writeS16(&data[0], p.X);
153         writeS16(&data[2], p.Y);
154 }
155
156 inline v2s16 readV2S16(u8 *data)
157 {
158         v2s16 p;
159         p.X = readS16(&data[0]);
160         p.Y = readS16(&data[2]);
161         return p;
162 }
163
164 inline void writeV2S32(u8 *data, v2s32 p)
165 {
166         writeS32(&data[0], p.X);
167         writeS32(&data[2], p.Y);
168 }
169
170 inline v2s32 readV2S32(u8 *data)
171 {
172         v2s32 p;
173         p.X = readS32(&data[0]);
174         p.Y = readS32(&data[2]);
175         return p;
176 }
177
178 inline void writeV3S16(u8 *data, v3s16 p)
179 {
180         writeS16(&data[0], p.X);
181         writeS16(&data[2], p.Y);
182         writeS16(&data[4], p.Z);
183 }
184
185 inline v3s16 readV3S16(u8 *data)
186 {
187         v3s16 p;
188         p.X = readS16(&data[0]);
189         p.Y = readS16(&data[2]);
190         p.Z = readS16(&data[4]);
191         return p;
192 }
193
194 /*
195         The above stuff directly interfaced to iostream
196 */
197
198 inline void writeU8(std::ostream &os, u8 p)
199 {
200         char buf[1];
201         writeU8((u8*)buf, p);
202         os.write(buf, 1);
203 }
204 inline u8 readU8(std::istream &is)
205 {
206         char buf[1];
207         is.read(buf, 1);
208         return readU8((u8*)buf);
209 }
210
211 inline void writeU16(std::ostream &os, u16 p)
212 {
213         char buf[2];
214         writeU16((u8*)buf, p);
215         os.write(buf, 2);
216 }
217 inline u16 readU16(std::istream &is)
218 {
219         char buf[2];
220         is.read(buf, 2);
221         return readU16((u8*)buf);
222 }
223
224 inline void writeU32(std::ostream &os, u16 p)
225 {
226         char buf[4];
227         writeU16((u8*)buf, p);
228         os.write(buf, 4);
229 }
230 inline u16 readU32(std::istream &is)
231 {
232         char buf[4];
233         is.read(buf, 4);
234         return readU32((u8*)buf);
235 }
236
237 inline void writeF1000(std::ostream &os, f32 p)
238 {
239         char buf[2];
240         writeF1000((u8*)buf, p);
241         os.write(buf, 2);
242 }
243 inline f32 readF1000(std::istream &is)
244 {
245         char buf[2];
246         is.read(buf, 2);
247         // TODO: verify if this gets rid of the valgrind warning
248         //if(is.gcount() != 2)
249         //      return 0;
250         return readF1000((u8*)buf);
251 }
252
253 inline void writeV3F1000(std::ostream &os, v3f p)
254 {
255         char buf[12];
256         writeV3F1000((u8*)buf, p);
257         os.write(buf, 12);
258 }
259 inline v3f readV3F1000(std::istream &is)
260 {
261         char buf[12];
262         is.read(buf, 12);
263         return readV3F1000((u8*)buf);
264 }
265
266 /*
267         None of these are used at the moment
268 */
269
270 template <typename T>
271 class SharedPtr
272 {
273 public:
274         SharedPtr(T *t=NULL)
275         {
276                 refcount = new int;
277                 *refcount = 1;
278                 ptr = t;
279         }
280         SharedPtr(SharedPtr<T> &t)
281         {
282                 //*this = t;
283                 drop();
284                 refcount = t.refcount;
285                 (*refcount)++;
286                 ptr = t.ptr;
287         }
288         ~SharedPtr()
289         {
290                 drop();
291         }
292         SharedPtr<T> & operator=(T *t)
293         {
294                 drop();
295                 refcount = new int;
296                 *refcount = 1;
297                 ptr = t;
298                 return *this;
299         }
300         SharedPtr<T> & operator=(SharedPtr<T> &t)
301         {
302                 drop();
303                 refcount = t.refcount;
304                 (*refcount)++;
305                 ptr = t.ptr;
306                 return *this;
307         }
308         T* operator->()
309         {
310                 return ptr;
311         }
312         T & operator*()
313         {
314                 return *ptr;
315         }
316         bool operator!=(T *t)
317         {
318                 return ptr != t;
319         }
320         bool operator==(T *t)
321         {
322                 return ptr == t;
323         }
324         T & operator[](unsigned int i)
325         {
326                 return ptr[i];
327         }
328 private:
329         void drop()
330         {
331                 assert((*refcount) > 0);
332                 (*refcount)--;
333                 if(*refcount == 0)
334                 {
335                         delete refcount;
336                         if(ptr != NULL)
337                                 delete ptr;
338                 }
339         }
340         T *ptr;
341         int *refcount;
342 };
343
344 template <typename T>
345 class Buffer
346 {
347 public:
348         Buffer(unsigned int size)
349         {
350                 m_size = size;
351                 data = new T[size];
352         }
353         Buffer(const Buffer &buffer)
354         {
355                 m_size = buffer.m_size;
356                 data = new T[buffer.m_size];
357                 memcpy(data, buffer.data, buffer.m_size);
358         }
359         Buffer(T *t, unsigned int size)
360         {
361                 m_size = size;
362                 data = new T[size];
363                 memcpy(data, t, size);
364         }
365         ~Buffer()
366         {
367                 delete[] data;
368         }
369         T & operator[](unsigned int i) const
370         {
371                 return data[i];
372         }
373         T * operator*() const
374         {
375                 return data;
376         }
377         unsigned int getSize() const
378         {
379                 return m_size;
380         }
381 private:
382         T *data;
383         unsigned int m_size;
384 };
385
386 template <typename T>
387 class SharedBuffer
388 {
389 public:
390         SharedBuffer()
391         {
392                 m_size = 0;
393                 data = NULL;
394                 refcount = new unsigned int;
395                 (*refcount) = 1;
396         }
397         SharedBuffer(unsigned int size)
398         {
399                 m_size = size;
400                 if(m_size != 0)
401                         data = new T[m_size];
402                 else
403                         data = NULL;
404                 refcount = new unsigned int;
405                 (*refcount) = 1;
406         }
407         SharedBuffer(const SharedBuffer &buffer)
408         {
409                 //std::cout<<"SharedBuffer(const SharedBuffer &buffer)"<<std::endl;
410                 m_size = buffer.m_size;
411                 data = buffer.data;
412                 refcount = buffer.refcount;
413                 (*refcount)++;
414         }
415         SharedBuffer & operator=(const SharedBuffer & buffer)
416         {
417                 //std::cout<<"SharedBuffer & operator=(const SharedBuffer & buffer)"<<std::endl;
418                 if(this == &buffer)
419                         return *this;
420                 drop();
421                 m_size = buffer.m_size;
422                 data = buffer.data;
423                 refcount = buffer.refcount;
424                 (*refcount)++;
425                 return *this;
426         }
427         /*
428                 Copies whole buffer
429         */
430         SharedBuffer(T *t, unsigned int size)
431         {
432                 m_size = size;
433                 if(m_size != 0)
434                 {
435                         data = new T[m_size];
436                         memcpy(data, t, m_size);
437                 }
438                 else
439                         data = NULL;
440                 refcount = new unsigned int;
441                 (*refcount) = 1;
442         }
443         /*
444                 Copies whole buffer
445         */
446         SharedBuffer(const Buffer<T> &buffer)
447         {
448                 m_size = buffer.getSize();
449                 if(m_size != 0)
450                 {
451                         data = new T[m_size];
452                         memcpy(data, *buffer, buffer.getSize());
453                 }
454                 else
455                         data = NULL;
456                 refcount = new unsigned int;
457                 (*refcount) = 1;
458         }
459         ~SharedBuffer()
460         {
461                 drop();
462         }
463         T & operator[](unsigned int i) const
464         {
465                 //assert(i < m_size)
466                 return data[i];
467         }
468         T * operator*() const
469         {
470                 return data;
471         }
472         unsigned int getSize() const
473         {
474                 return m_size;
475         }
476 private:
477         void drop()
478         {
479                 assert((*refcount) > 0);
480                 (*refcount)--;
481                 if(*refcount == 0)
482                 {
483                         if(data)
484                                 delete[] data;
485                         delete refcount;
486                 }
487         }
488         T *data;
489         unsigned int m_size;
490         unsigned int *refcount;
491 };
492
493 inline SharedBuffer<u8> SharedBufferFromString(const char *string)
494 {
495         SharedBuffer<u8> b((u8*)string, strlen(string)+1);
496         return b;
497 }
498
499 template<typename T>
500 class MutexedVariable
501 {
502 public:
503         MutexedVariable(T value):
504                 m_value(value)
505         {
506                 m_mutex.Init();
507         }
508
509         T get()
510         {
511                 JMutexAutoLock lock(m_mutex);
512                 return m_value;
513         }
514
515         void set(T value)
516         {
517                 JMutexAutoLock lock(m_mutex);
518                 m_value = value;
519         }
520         
521         // You'll want to grab this in a SharedPtr
522         JMutexAutoLock * getLock()
523         {
524                 return new JMutexAutoLock(m_mutex);
525         }
526         
527         // You pretty surely want to grab the lock when accessing this
528         T m_value;
529
530 private:
531         JMutex m_mutex;
532 };
533
534 /*
535         TimeTaker
536 */
537
538 class TimeTaker
539 {
540 public:
541         TimeTaker(const char *name, u32 *result=NULL);
542
543         ~TimeTaker()
544         {
545                 stop();
546         }
547
548         u32 stop(bool quiet=false);
549
550         u32 getTime();
551
552 private:
553         const char *m_name;
554         u32 m_time1;
555         bool m_running;
556         u32 *m_result;
557 };
558
559 // Calculates the borders of a "d-radius" cube
560 inline void getFacePositions(core::list<v3s16> &list, u16 d)
561 {
562         if(d == 0)
563         {
564                 list.push_back(v3s16(0,0,0));
565                 return;
566         }
567         if(d == 1)
568         {
569                 /*
570                         This is an optimized sequence of coordinates.
571                 */
572                 list.push_back(v3s16( 0, 1, 0)); // top
573                 list.push_back(v3s16( 0, 0, 1)); // back
574                 list.push_back(v3s16(-1, 0, 0)); // left
575                 list.push_back(v3s16( 1, 0, 0)); // right
576                 list.push_back(v3s16( 0, 0,-1)); // front
577                 list.push_back(v3s16( 0,-1, 0)); // bottom
578                 // 6
579                 list.push_back(v3s16(-1, 0, 1)); // back left
580                 list.push_back(v3s16( 1, 0, 1)); // back right
581                 list.push_back(v3s16(-1, 0,-1)); // front left
582                 list.push_back(v3s16( 1, 0,-1)); // front right
583                 list.push_back(v3s16(-1,-1, 0)); // bottom left
584                 list.push_back(v3s16( 1,-1, 0)); // bottom right
585                 list.push_back(v3s16( 0,-1, 1)); // bottom back
586                 list.push_back(v3s16( 0,-1,-1)); // bottom front
587                 list.push_back(v3s16(-1, 1, 0)); // top left
588                 list.push_back(v3s16( 1, 1, 0)); // top right
589                 list.push_back(v3s16( 0, 1, 1)); // top back
590                 list.push_back(v3s16( 0, 1,-1)); // top front
591                 // 18
592                 list.push_back(v3s16(-1, 1, 1)); // top back-left
593                 list.push_back(v3s16( 1, 1, 1)); // top back-right
594                 list.push_back(v3s16(-1, 1,-1)); // top front-left
595                 list.push_back(v3s16( 1, 1,-1)); // top front-right
596                 list.push_back(v3s16(-1,-1, 1)); // bottom back-left
597                 list.push_back(v3s16( 1,-1, 1)); // bottom back-right
598                 list.push_back(v3s16(-1,-1,-1)); // bottom front-left
599                 list.push_back(v3s16( 1,-1,-1)); // bottom front-right
600                 // 26
601                 return;
602         }
603
604         // Take blocks in all sides, starting from y=0 and going +-y
605         for(s16 y=0; y<=d-1; y++)
606         {
607                 // Left and right side, including borders
608                 for(s16 z=-d; z<=d; z++)
609                 {
610                         list.push_back(v3s16(d,y,z));
611                         list.push_back(v3s16(-d,y,z));
612                         if(y != 0)
613                         {
614                                 list.push_back(v3s16(d,-y,z));
615                                 list.push_back(v3s16(-d,-y,z));
616                         }
617                 }
618                 // Back and front side, excluding borders
619                 for(s16 x=-d+1; x<=d-1; x++)
620                 {
621                         list.push_back(v3s16(x,y,d));
622                         list.push_back(v3s16(x,y,-d));
623                         if(y != 0)
624                         {
625                                 list.push_back(v3s16(x,-y,d));
626                                 list.push_back(v3s16(x,-y,-d));
627                         }
628                 }
629         }
630
631         // Take the bottom and top face with borders
632         // -d<x<d, y=+-d, -d<z<d
633         for(s16 x=-d; x<=d; x++)
634         for(s16 z=-d; z<=d; z++)
635         {
636                 list.push_back(v3s16(x,-d,z));
637                 list.push_back(v3s16(x,d,z));
638         }
639 }
640
641 class IndentationRaiser
642 {
643 public:
644         IndentationRaiser(u16 *indentation)
645         {
646                 m_indentation = indentation;
647                 (*m_indentation)++;
648         }
649         ~IndentationRaiser()
650         {
651                 (*m_indentation)--;
652         }
653 private:
654         u16 *m_indentation;
655 };
656
657 inline s16 getContainerPos(s16 p, s16 d)
658 {
659         return (p>=0 ? p : p-d+1) / d;
660 }
661
662 inline v2s16 getContainerPos(v2s16 p, s16 d)
663 {
664         return v2s16(
665                 getContainerPos(p.X, d),
666                 getContainerPos(p.Y, d)
667         );
668 }
669
670 inline v3s16 getContainerPos(v3s16 p, s16 d)
671 {
672         return v3s16(
673                 getContainerPos(p.X, d),
674                 getContainerPos(p.Y, d),
675                 getContainerPos(p.Z, d)
676         );
677 }
678
679 inline v2s16 getContainerPos(v2s16 p, v2s16 d)
680 {
681         return v2s16(
682                 getContainerPos(p.X, d.X),
683                 getContainerPos(p.Y, d.Y)
684         );
685 }
686
687 inline v3s16 getContainerPos(v3s16 p, v3s16 d)
688 {
689         return v3s16(
690                 getContainerPos(p.X, d.X),
691                 getContainerPos(p.Y, d.Y),
692                 getContainerPos(p.Z, d.Z)
693         );
694 }
695
696 inline bool isInArea(v3s16 p, s16 d)
697 {
698         return (
699                 p.X >= 0 && p.X < d &&
700                 p.Y >= 0 && p.Y < d &&
701                 p.Z >= 0 && p.Z < d
702         );
703 }
704
705 inline bool isInArea(v2s16 p, s16 d)
706 {
707         return (
708                 p.X >= 0 && p.X < d &&
709                 p.Y >= 0 && p.Y < d
710         );
711 }
712
713 inline bool isInArea(v3s16 p, v3s16 d)
714 {
715         return (
716                 p.X >= 0 && p.X < d.X &&
717                 p.Y >= 0 && p.Y < d.Y &&
718                 p.Z >= 0 && p.Z < d.Z
719         );
720 }
721
722 inline s16 rangelim(s16 i, s16 max)
723 {
724         if(i < 0)
725                 return 0;
726         if(i > max)
727                 return max;
728         return i;
729 }
730
731 #define rangelim(d, min, max) ((d) < (min) ? (min) : ((d)>(max)?(max):(d)))
732
733 inline v3s16 arealim(v3s16 p, s16 d)
734 {
735         if(p.X < 0)
736                 p.X = 0;
737         if(p.Y < 0)
738                 p.Y = 0;
739         if(p.Z < 0)
740                 p.Z = 0;
741         if(p.X > d-1)
742                 p.X = d-1;
743         if(p.Y > d-1)
744                 p.Y = d-1;
745         if(p.Z > d-1)
746                 p.Z = d-1;
747         return p;
748 }
749
750 inline std::wstring narrow_to_wide(const std::string& mbs)
751 {
752         size_t wcl = mbs.size();
753         Buffer<wchar_t> wcs(wcl+1);
754         size_t l = mbstowcs(*wcs, mbs.c_str(), wcl);
755         if(l == (size_t)(-1))
756                 return L"<invalid multibyte string>";
757         wcs[l] = 0;
758         return *wcs;
759 }
760
761 inline std::string wide_to_narrow(const std::wstring& wcs)
762 {
763         size_t mbl = wcs.size()*4;
764         SharedBuffer<char> mbs(mbl+1);
765         size_t l = wcstombs(*mbs, wcs.c_str(), mbl);
766         if(l == (size_t)(-1))
767                 mbs[0] = 0;
768         else
769                 mbs[l] = 0;
770         return *mbs;
771 }
772
773 // Split a string using the given delimiter. Returns a vector containing
774 // the component parts.
775 inline std::vector<std::wstring> str_split(const std::wstring &str, wchar_t delimiter)
776 {
777         std::vector<std::wstring> parts;
778         std::wstringstream sstr(str);
779         std::wstring part;
780         while(std::getline(sstr, part, delimiter))
781                 parts.push_back(part);
782         return parts;
783 }
784
785
786 /*
787         See test.cpp for example cases.
788         wraps degrees to the range of -360...360
789         NOTE: Wrapping to 0...360 is not used because pitch needs negative values.
790 */
791 inline float wrapDegrees(float f)
792 {
793         // Take examples of f=10, f=720.5, f=-0.5, f=-360.5
794         // This results in
795         // 10, 720, -1, -361
796         int i = floor(f);
797         // 0, 2, 0, -1
798         int l = i / 360;
799         // NOTE: This would be used for wrapping to 0...360
800         // 0, 2, -1, -2
801         /*if(i < 0)
802                 l -= 1;*/
803         // 0, 720, 0, -360
804         int k = l * 360;
805         // 10, 0.5, -0.5, -0.5
806         f -= float(k);
807         return f;
808 }
809
810 inline std::string lowercase(const std::string &s)
811 {
812         std::string s2;
813         for(size_t i=0; i<s.size(); i++)
814         {
815                 char c = s[i];
816                 if(c >= 'A' && c <= 'Z')
817                         c -= 'A' - 'a';
818                 s2 += c;
819         }
820         return s2;
821 }
822
823 inline bool is_yes(const std::string &s)
824 {
825         std::string s2 = lowercase(trim(s));
826         if(s2 == "y" || s2 == "yes" || s2 == "true" || s2 == "1")
827                 return true;
828         return false;
829 }
830
831 inline s32 stoi(const std::string &s, s32 min, s32 max)
832 {
833         s32 i = atoi(s.c_str());
834         if(i < min)
835                 i = min;
836         if(i > max)
837                 i = max;
838         return i;
839 }
840
841
842 // MSVC2010 includes it's own versions of these
843 #if !defined(_MSC_VER) || _MSC_VER < 1600
844
845 inline s32 stoi(std::string s)
846 {
847         return atoi(s.c_str());
848 }
849
850 inline s32 stoi(std::wstring s)
851 {
852         return atoi(wide_to_narrow(s).c_str());
853 }
854
855 inline float stof(std::string s)
856 {
857         float f;
858         std::istringstream ss(s);
859         ss>>f;
860         return f;
861 }
862
863 #endif
864
865 inline std::string itos(s32 i)
866 {
867         std::ostringstream o;
868         o<<i;
869         return o.str();
870 }
871
872 inline std::string ftos(float f)
873 {
874         std::ostringstream o;
875         o<<f;
876         return o.str();
877 }
878
879 inline void str_replace(std::string & str, std::string const & pattern,
880                 std::string const & replacement)
881 {
882         std::string::size_type start = str.find(pattern, 0);
883         while(start != str.npos)
884         {
885                 str.replace(start, pattern.size(), replacement);
886                 start = str.find(pattern, start+replacement.size());
887         }
888 }
889
890 inline void str_replace_char(std::string & str, char from, char to)
891 {
892         for(unsigned int i=0; i<str.size(); i++)
893         {
894                 if(str[i] == from)
895                         str[i] = to;
896         }
897 }
898
899 /*
900         A base class for simple background thread implementation
901 */
902
903 class SimpleThread : public JThread
904 {
905         bool run;
906         JMutex run_mutex;
907
908 public:
909
910         SimpleThread():
911                 JThread(),
912                 run(true)
913         {
914                 run_mutex.Init();
915         }
916
917         virtual ~SimpleThread()
918         {}
919
920         virtual void * Thread() = 0;
921
922         bool getRun()
923         {
924                 JMutexAutoLock lock(run_mutex);
925                 return run;
926         }
927         void setRun(bool a_run)
928         {
929                 JMutexAutoLock lock(run_mutex);
930                 run = a_run;
931         }
932
933         void stop()
934         {
935                 setRun(false);
936                 while(IsRunning())
937                         sleep_ms(100);
938         }
939 };
940
941 /*
942         Config stuff
943 */
944
945 enum ValueType
946 {
947         VALUETYPE_STRING,
948         VALUETYPE_FLAG // Doesn't take any arguments
949 };
950
951 struct ValueSpec
952 {
953         ValueSpec(ValueType a_type, const char *a_help=NULL)
954         {
955                 type = a_type;
956                 help = a_help;
957         }
958         ValueType type;
959         const char *help;
960 };
961
962 class Settings
963 {
964 public:
965         Settings()
966         {
967                 m_mutex.Init();
968         }
969
970         void writeLines(std::ostream &os)
971         {
972                 JMutexAutoLock lock(m_mutex);
973                 
974                 for(core::map<std::string, std::string>::Iterator
975                                 i = m_settings.getIterator();
976                                 i.atEnd() == false; i++)
977                 {
978                         std::string name = i.getNode()->getKey();
979                         std::string value = i.getNode()->getValue();
980                         os<<name<<" = "<<value<<"\n";
981                 }
982         }
983
984         bool parseConfigLine(const std::string &line)
985         {
986                 JMutexAutoLock lock(m_mutex);
987                 
988                 std::string trimmedline = trim(line);
989                 
990                 // Ignore comments
991                 if(trimmedline[0] == '#')
992                         return true;
993
994                 //dstream<<"trimmedline=\""<<trimmedline<<"\""<<std::endl;
995
996                 Strfnd sf(trim(line));
997
998                 std::string name = sf.next("=");
999                 name = trim(name);
1000
1001                 if(name == "")
1002                         return true;
1003                 
1004                 std::string value = sf.next("\n");
1005                 value = trim(value);
1006
1007                 /*dstream<<"Config name=\""<<name<<"\" value=\""
1008                                 <<value<<"\""<<std::endl;*/
1009                 
1010                 m_settings[name] = value;
1011                 
1012                 return true;
1013         }
1014
1015         // Returns false on EOF
1016         bool parseConfigObject(std::istream &is)
1017         {
1018                 if(is.eof())
1019                         return false;
1020                 
1021                 /*
1022                         NOTE: This function might be expanded to allow multi-line
1023                               settings.
1024                 */
1025                 std::string line;
1026                 std::getline(is, line);
1027                 //dstream<<"got line: \""<<line<<"\""<<std::endl;
1028
1029                 return parseConfigLine(line);
1030         }
1031
1032         /*
1033                 Read configuration file
1034
1035                 Returns true on success
1036         */
1037         bool readConfigFile(const char *filename)
1038         {
1039                 std::ifstream is(filename);
1040                 if(is.good() == false)
1041                 {
1042                         dstream<<"Error opening configuration file \""
1043                                         <<filename<<"\""<<std::endl;
1044                         return false;
1045                 }
1046
1047                 dstream<<"Parsing configuration file: \""
1048                                 <<filename<<"\""<<std::endl;
1049                                 
1050                 while(parseConfigObject(is));
1051                 
1052                 return true;
1053         }
1054
1055         /*
1056                 Reads a configuration object from stream (usually a single line)
1057                 and adds it to dst.
1058                 
1059                 Preserves comments and empty lines.
1060
1061                 Settings that were added to dst are also added to updated.
1062                 key of updated is setting name, value of updated is dummy.
1063
1064                 Returns false on EOF
1065         */
1066         bool getUpdatedConfigObject(std::istream &is,
1067                         core::list<std::string> &dst,
1068                         core::map<std::string, bool> &updated)
1069         {
1070                 JMutexAutoLock lock(m_mutex);
1071                 
1072                 if(is.eof())
1073                         return false;
1074                 
1075                 // NOTE: This function will be expanded to allow multi-line settings
1076                 std::string line;
1077                 std::getline(is, line);
1078
1079                 std::string trimmedline = trim(line);
1080
1081                 std::string line_end = "";
1082                 if(is.eof() == false)
1083                         line_end = "\n";
1084                 
1085                 // Ignore comments
1086                 if(trimmedline[0] == '#')
1087                 {
1088                         dst.push_back(line+line_end);
1089                         return true;
1090                 }
1091
1092                 Strfnd sf(trim(line));
1093
1094                 std::string name = sf.next("=");
1095                 name = trim(name);
1096
1097                 if(name == "")
1098                 {
1099                         dst.push_back(line+line_end);
1100                         return true;
1101                 }
1102                 
1103                 std::string value = sf.next("\n");
1104                 value = trim(value);
1105                 
1106                 if(m_settings.find(name))
1107                 {
1108                         std::string newvalue = m_settings[name];
1109                         
1110                         if(newvalue != value)
1111                         {
1112                                 dstream<<"Changing value of \""<<name<<"\" = \""
1113                                                 <<value<<"\" -> \""<<newvalue<<"\""
1114                                                 <<std::endl;
1115                         }
1116
1117                         dst.push_back(name + " = " + newvalue + line_end);
1118
1119                         updated[name] = true;
1120                 }
1121                 
1122                 return true;
1123         }
1124
1125         /*
1126                 Updates configuration file
1127
1128                 Returns true on success
1129         */
1130         bool updateConfigFile(const char *filename)
1131         {
1132                 dstream<<"Updating configuration file: \""
1133                                 <<filename<<"\""<<std::endl;
1134                 
1135                 core::list<std::string> objects;
1136                 core::map<std::string, bool> updated;
1137                 
1138                 // Read and modify stuff
1139                 {
1140                         std::ifstream is(filename);
1141                         if(is.good() == false)
1142                         {
1143                                 dstream<<"INFO: updateConfigFile():"
1144                                                 " Error opening configuration file"
1145                                                 " for reading: \""
1146                                                 <<filename<<"\""<<std::endl;
1147                         }
1148                         else
1149                         {
1150                                 while(getUpdatedConfigObject(is, objects, updated));
1151                         }
1152                 }
1153                 
1154                 JMutexAutoLock lock(m_mutex);
1155                 
1156                 // Write stuff back
1157                 {
1158                         std::ofstream os(filename);
1159                         if(os.good() == false)
1160                         {
1161                                 dstream<<"Error opening configuration file"
1162                                                 " for writing: \""
1163                                                 <<filename<<"\""<<std::endl;
1164                                 return false;
1165                         }
1166                         
1167                         /*
1168                                 Write updated stuff
1169                         */
1170                         for(core::list<std::string>::Iterator
1171                                         i = objects.begin();
1172                                         i != objects.end(); i++)
1173                         {
1174                                 os<<(*i);
1175                         }
1176
1177                         /*
1178                                 Write stuff that was not already in the file
1179                         */
1180                         for(core::map<std::string, std::string>::Iterator
1181                                         i = m_settings.getIterator();
1182                                         i.atEnd() == false; i++)
1183                         {
1184                                 if(updated.find(i.getNode()->getKey()))
1185                                         continue;
1186                                 std::string name = i.getNode()->getKey();
1187                                 std::string value = i.getNode()->getValue();
1188                                 dstream<<"Adding \""<<name<<"\" = \""<<value<<"\""
1189                                                 <<std::endl;
1190                                 os<<name<<" = "<<value<<"\n";
1191                         }
1192                 }
1193                 
1194                 return true;
1195         }
1196
1197         /*
1198                 NOTE: Types of allowed_options are ignored
1199
1200                 returns true on success
1201         */
1202         bool parseCommandLine(int argc, char *argv[],
1203                         core::map<std::string, ValueSpec> &allowed_options)
1204         {
1205                 int i=1;
1206                 for(;;)
1207                 {
1208                         if(i >= argc)
1209                                 break;
1210                         std::string argname = argv[i];
1211                         if(argname.substr(0, 2) != "--")
1212                         {
1213                                 dstream<<"Invalid command-line parameter \""
1214                                                 <<argname<<"\": --<option> expected."<<std::endl;
1215                                 return false;
1216                         }
1217                         i++;
1218
1219                         std::string name = argname.substr(2);
1220
1221                         core::map<std::string, ValueSpec>::Node *n;
1222                         n = allowed_options.find(name);
1223                         if(n == NULL)
1224                         {
1225                                 dstream<<"Unknown command-line parameter \""
1226                                                 <<argname<<"\""<<std::endl;
1227                                 return false;
1228                         }
1229
1230                         ValueType type = n->getValue().type;
1231
1232                         std::string value = "";
1233                         
1234                         if(type == VALUETYPE_FLAG)
1235                         {
1236                                 value = "true";
1237                         }
1238                         else
1239                         {
1240                                 if(i >= argc)
1241                                 {
1242                                         dstream<<"Invalid command-line parameter \""
1243                                                         <<name<<"\": missing value"<<std::endl;
1244                                         return false;
1245                                 }
1246                                 value = argv[i];
1247                                 i++;
1248                         }
1249                         
1250
1251                         dstream<<"Valid command-line parameter: \""
1252                                         <<name<<"\" = \""<<value<<"\""
1253                                         <<std::endl;
1254                         set(name, value);
1255                 }
1256
1257                 return true;
1258         }
1259
1260         void set(std::string name, std::string value)
1261         {
1262                 JMutexAutoLock lock(m_mutex);
1263                 
1264                 m_settings[name] = value;
1265         }
1266
1267         void setDefault(std::string name, std::string value)
1268         {
1269                 JMutexAutoLock lock(m_mutex);
1270                 
1271                 m_defaults[name] = value;
1272         }
1273
1274         bool exists(std::string name)
1275         {
1276                 JMutexAutoLock lock(m_mutex);
1277                 
1278                 return (m_settings.find(name) || m_defaults.find(name));
1279         }
1280
1281         std::string get(std::string name)
1282         {
1283                 JMutexAutoLock lock(m_mutex);
1284                 
1285                 core::map<std::string, std::string>::Node *n;
1286                 n = m_settings.find(name);
1287                 if(n == NULL)
1288                 {
1289                         n = m_defaults.find(name);
1290                         if(n == NULL)
1291                         {
1292                                 dstream<<"INFO: Settings: Setting not found: \""
1293                                                 <<name<<"\""<<std::endl;
1294                                 throw SettingNotFoundException("Setting not found");
1295                         }
1296                 }
1297
1298                 return n->getValue();
1299         }
1300
1301         bool getBool(std::string name)
1302         {
1303                 return is_yes(get(name));
1304         }
1305         
1306         bool getFlag(std::string name)
1307         {
1308                 try
1309                 {
1310                         return getBool(name);
1311                 }
1312                 catch(SettingNotFoundException &e)
1313                 {
1314                         return false;
1315                 }
1316         }
1317
1318         // Asks if empty
1319         bool getBoolAsk(std::string name, std::string question, bool def)
1320         {
1321                 // If it is in settings
1322                 if(exists(name))
1323                         return getBool(name);
1324                 
1325                 std::string s;
1326                 char templine[10];
1327                 std::cout<<question<<" [y/N]: ";
1328                 std::cin.getline(templine, 10);
1329                 s = templine;
1330
1331                 if(s == "")
1332                         return def;
1333
1334                 return is_yes(s);
1335         }
1336
1337         float getFloat(std::string name)
1338         {
1339                 return stof(get(name));
1340         }
1341
1342         u16 getU16(std::string name)
1343         {
1344                 return stoi(get(name), 0, 65535);
1345         }
1346
1347         u16 getU16Ask(std::string name, std::string question, u16 def)
1348         {
1349                 // If it is in settings
1350                 if(exists(name))
1351                         return getU16(name);
1352                 
1353                 std::string s;
1354                 char templine[10];
1355                 std::cout<<question<<" ["<<def<<"]: ";
1356                 std::cin.getline(templine, 10);
1357                 s = templine;
1358
1359                 if(s == "")
1360                         return def;
1361
1362                 return stoi(s, 0, 65535);
1363         }
1364
1365         s16 getS16(std::string name)
1366         {
1367                 return stoi(get(name), -32768, 32767);
1368         }
1369
1370         s32 getS32(std::string name)
1371         {
1372                 return stoi(get(name));
1373         }
1374
1375         v3f getV3F(std::string name)
1376         {
1377                 v3f value;
1378                 Strfnd f(get(name));
1379                 f.next("(");
1380                 value.X = stof(f.next(","));
1381                 value.Y = stof(f.next(","));
1382                 value.Z = stof(f.next(")"));
1383                 return value;
1384         }
1385
1386         u64 getU64(std::string name)
1387         {
1388                 u64 value = 0;
1389                 std::string s = get(name);
1390                 std::istringstream ss(s);
1391                 ss>>value;
1392                 return value;
1393         }
1394
1395         void setBool(std::string name, bool value)
1396         {
1397                 if(value)
1398                         set(name, "true");
1399                 else
1400                         set(name, "false");
1401         }
1402
1403         void setS32(std::string name, s32 value)
1404         {
1405                 set(name, itos(value));
1406         }
1407
1408         void setFloat(std::string name, float value)
1409         {
1410                 set(name, ftos(value));
1411         }
1412
1413         void setV3F(std::string name, v3f value)
1414         {
1415                 std::ostringstream os;
1416                 os<<"("<<value.X<<","<<value.Y<<","<<value.Z<<")";
1417                 set(name, os.str());
1418         }
1419
1420         void setU64(std::string name, u64 value)
1421         {
1422                 std::ostringstream os;
1423                 os<<value;
1424                 set(name, os.str());
1425         }
1426
1427         void clear()
1428         {
1429                 JMutexAutoLock lock(m_mutex);
1430                 
1431                 m_settings.clear();
1432                 m_defaults.clear();
1433         }
1434
1435         Settings & operator+=(Settings &other)
1436         {
1437                 JMutexAutoLock lock(m_mutex);
1438                 JMutexAutoLock lock2(other.m_mutex);
1439                 
1440                 if(&other == this)
1441                         return *this;
1442
1443                 for(core::map<std::string, std::string>::Iterator
1444                                 i = other.m_settings.getIterator();
1445                                 i.atEnd() == false; i++)
1446                 {
1447                         m_settings.insert(i.getNode()->getKey(),
1448                                         i.getNode()->getValue());
1449                 }
1450                 
1451                 for(core::map<std::string, std::string>::Iterator
1452                                 i = other.m_defaults.getIterator();
1453                                 i.atEnd() == false; i++)
1454                 {
1455                         m_defaults.insert(i.getNode()->getKey(),
1456                                         i.getNode()->getValue());
1457                 }
1458
1459         }
1460
1461         Settings & operator=(Settings &other)
1462         {
1463                 JMutexAutoLock lock(m_mutex);
1464                 JMutexAutoLock lock2(other.m_mutex);
1465                 
1466                 if(&other == this)
1467                         return *this;
1468
1469                 clear();
1470                 (*this) += other;
1471                 
1472                 return *this;
1473         }
1474
1475 private:
1476         core::map<std::string, std::string> m_settings;
1477         core::map<std::string, std::string> m_defaults;
1478         // All methods that access m_settings/m_defaults directly should lock this.
1479         JMutex m_mutex;
1480 };
1481
1482 /*
1483         FIFO queue (well, actually a FILO also)
1484 */
1485 template<typename T>
1486 class Queue
1487 {
1488 public:
1489         void push_back(T t)
1490         {
1491                 m_list.push_back(t);
1492         }
1493         
1494         T pop_front()
1495         {
1496                 if(m_list.size() == 0)
1497                         throw ItemNotFoundException("Queue: queue is empty");
1498
1499                 typename core::list<T>::Iterator begin = m_list.begin();
1500                 T t = *begin;
1501                 m_list.erase(begin);
1502                 return t;
1503         }
1504         T pop_back()
1505         {
1506                 if(m_list.size() == 0)
1507                         throw ItemNotFoundException("Queue: queue is empty");
1508
1509                 typename core::list<T>::Iterator last = m_list.getLast();
1510                 T t = *last;
1511                 m_list.erase(last);
1512                 return t;
1513         }
1514
1515         u32 size()
1516         {
1517                 return m_list.size();
1518         }
1519
1520 protected:
1521         core::list<T> m_list;
1522 };
1523
1524 /*
1525         Thread-safe FIFO queue (well, actually a FILO also)
1526 */
1527
1528 template<typename T>
1529 class MutexedQueue
1530 {
1531 public:
1532         MutexedQueue()
1533         {
1534                 m_mutex.Init();
1535         }
1536         u32 size()
1537         {
1538                 JMutexAutoLock lock(m_mutex);
1539                 return m_list.size();
1540         }
1541         void push_back(T t)
1542         {
1543                 JMutexAutoLock lock(m_mutex);
1544                 m_list.push_back(t);
1545         }
1546         T pop_front(u32 wait_time_max_ms=0)
1547         {
1548                 u32 wait_time_ms = 0;
1549
1550                 for(;;)
1551                 {
1552                         {
1553                                 JMutexAutoLock lock(m_mutex);
1554
1555                                 if(m_list.size() > 0)
1556                                 {
1557                                         typename core::list<T>::Iterator begin = m_list.begin();
1558                                         T t = *begin;
1559                                         m_list.erase(begin);
1560                                         return t;
1561                                 }
1562
1563                                 if(wait_time_ms >= wait_time_max_ms)
1564                                         throw ItemNotFoundException("MutexedQueue: queue is empty");
1565                         }
1566
1567                         // Wait a while before trying again
1568                         sleep_ms(10);
1569                         wait_time_ms += 10;
1570                 }
1571         }
1572         T pop_back(u32 wait_time_max_ms=0)
1573         {
1574                 u32 wait_time_ms = 0;
1575
1576                 for(;;)
1577                 {
1578                         {
1579                                 JMutexAutoLock lock(m_mutex);
1580
1581                                 if(m_list.size() > 0)
1582                                 {
1583                                         typename core::list<T>::Iterator last = m_list.getLast();
1584                                         T t = *last;
1585                                         m_list.erase(last);
1586                                         return t;
1587                                 }
1588
1589                                 if(wait_time_ms >= wait_time_max_ms)
1590                                         throw ItemNotFoundException("MutexedQueue: queue is empty");
1591                         }
1592
1593                         // Wait a while before trying again
1594                         sleep_ms(10);
1595                         wait_time_ms += 10;
1596                 }
1597         }
1598
1599         JMutex & getMutex()
1600         {
1601                 return m_mutex;
1602         }
1603
1604         core::list<T> & getList()
1605         {
1606                 return m_list;
1607         }
1608
1609 protected:
1610         JMutex m_mutex;
1611         core::list<T> m_list;
1612 };
1613
1614 /*
1615         A single worker thread - multiple client threads queue framework.
1616 */
1617
1618 template<typename Caller, typename Data>
1619 class CallerInfo
1620 {
1621 public:
1622         Caller caller;
1623         Data data;
1624 };
1625
1626 template<typename Key, typename T, typename Caller, typename CallerData>
1627 class GetResult
1628 {
1629 public:
1630         Key key;
1631         T item;
1632         core::list<CallerInfo<Caller, CallerData> > callers;
1633 };
1634
1635 template<typename Key, typename T, typename Caller, typename CallerData>
1636 class ResultQueue: public MutexedQueue< GetResult<Key, T, Caller, CallerData> >
1637 {
1638 };
1639
1640 template<typename Key, typename T, typename Caller, typename CallerData>
1641 class GetRequest
1642 {
1643 public:
1644         GetRequest()
1645         {
1646                 dest = NULL;
1647         }
1648         GetRequest(ResultQueue<Key,T, Caller, CallerData> *a_dest)
1649         {
1650                 dest = a_dest;
1651         }
1652         GetRequest(ResultQueue<Key,T, Caller, CallerData> *a_dest,
1653                         Key a_key)
1654         {
1655                 dest = a_dest;
1656                 key = a_key;
1657         }
1658         ~GetRequest()
1659         {
1660         }
1661         
1662         Key key;
1663         ResultQueue<Key, T, Caller, CallerData> *dest;
1664         core::list<CallerInfo<Caller, CallerData> > callers;
1665 };
1666
1667 template<typename Key, typename T, typename Caller, typename CallerData>
1668 class RequestQueue
1669 {
1670 public:
1671         u32 size()
1672         {
1673                 return m_queue.size();
1674         }
1675
1676         void add(Key key, Caller caller, CallerData callerdata,
1677                         ResultQueue<Key, T, Caller, CallerData> *dest)
1678         {
1679                 JMutexAutoLock lock(m_queue.getMutex());
1680                 
1681                 /*
1682                         If the caller is already on the list, only update CallerData
1683                 */
1684                 for(typename core::list< GetRequest<Key, T, Caller, CallerData> >::Iterator
1685                                 i = m_queue.getList().begin();
1686                                 i != m_queue.getList().end(); i++)
1687                 {
1688                         GetRequest<Key, T, Caller, CallerData> &request = *i;
1689
1690                         if(request.key == key)
1691                         {
1692                                 for(typename core::list< CallerInfo<Caller, CallerData> >::Iterator
1693                                                 i = request.callers.begin();
1694                                                 i != request.callers.end(); i++)
1695                                 {
1696                                         CallerInfo<Caller, CallerData> &ca = *i;
1697                                         if(ca.caller == caller)
1698                                         {
1699                                                 ca.data = callerdata;
1700                                                 return;
1701                                         }
1702                                 }
1703                                 CallerInfo<Caller, CallerData> ca;
1704                                 ca.caller = caller;
1705                                 ca.data = callerdata;
1706                                 request.callers.push_back(ca);
1707                                 return;
1708                         }
1709                 }
1710
1711                 /*
1712                         Else add a new request to the queue
1713                 */
1714
1715                 GetRequest<Key, T, Caller, CallerData> request;
1716                 request.key = key;
1717                 CallerInfo<Caller, CallerData> ca;
1718                 ca.caller = caller;
1719                 ca.data = callerdata;
1720                 request.callers.push_back(ca);
1721                 request.dest = dest;
1722                 
1723                 m_queue.getList().push_back(request);
1724         }
1725
1726         GetRequest<Key, T, Caller, CallerData> pop(bool wait_if_empty=false)
1727         {
1728                 return m_queue.pop_front(wait_if_empty);
1729         }
1730
1731 private:
1732         MutexedQueue< GetRequest<Key, T, Caller, CallerData> > m_queue;
1733 };
1734
1735 /*
1736         Pseudo-random (VC++ rand() sucks)
1737 */
1738 int myrand(void);
1739 void mysrand(unsigned seed);
1740 #define MYRAND_MAX 32767
1741
1742 inline int myrand_range(int min, int max)
1743 {
1744         if(min > max)
1745         {
1746                 assert(0);
1747                 return max;
1748         }
1749         return (myrand()%(max-min+1))+min;
1750 }
1751
1752 /*
1753         Miscellaneous functions
1754 */
1755
1756 bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 range,
1757                 f32 *distance_ptr=NULL);
1758
1759 /*
1760         Queue with unique values with fast checking of value existence
1761 */
1762
1763 template<typename Value>
1764 class UniqueQueue
1765 {
1766 public:
1767         
1768         /*
1769                 Does nothing if value is already queued.
1770                 Return value:
1771                         true: value added
1772                         false: value already exists
1773         */
1774         bool push_back(Value value)
1775         {
1776                 // Check if already exists
1777                 if(m_map.find(value) != NULL)
1778                         return false;
1779
1780                 // Add
1781                 m_map.insert(value, 0);
1782                 m_list.push_back(value);
1783                 
1784                 return true;
1785         }
1786
1787         Value pop_front()
1788         {
1789                 typename core::list<Value>::Iterator i = m_list.begin();
1790                 Value value = *i;
1791                 m_map.remove(value);
1792                 m_list.erase(i);
1793                 return value;
1794         }
1795
1796         u32 size()
1797         {
1798                 assert(m_list.size() == m_map.size());
1799                 return m_list.size();
1800         }
1801
1802 private:
1803         core::map<Value, u8> m_map;
1804         core::list<Value> m_list;
1805 };
1806
1807 #if 1
1808 template<typename Key, typename Value>
1809 class MutexedMap
1810 {
1811 public:
1812         MutexedMap()
1813         {
1814                 m_mutex.Init();
1815                 assert(m_mutex.IsInitialized());
1816         }
1817         
1818         void set(const Key &name, const Value &value)
1819         {
1820                 JMutexAutoLock lock(m_mutex);
1821
1822                 m_values[name] = value;
1823         }
1824         
1825         bool get(const Key &name, Value *result)
1826         {
1827                 JMutexAutoLock lock(m_mutex);
1828
1829                 typename core::map<Key, Value>::Node *n;
1830                 n = m_values.find(name);
1831
1832                 if(n == NULL)
1833                         return false;
1834                 
1835                 if(result != NULL)
1836                         *result = n->getValue();
1837                         
1838                 return true;
1839         }
1840
1841 private:
1842         core::map<Key, Value> m_values;
1843         JMutex m_mutex;
1844 };
1845 #endif
1846
1847 /*
1848         Generates ids for comparable values.
1849         Id=0 is reserved for "no value".
1850
1851         Is fast at:
1852         - Returning value by id (very fast)
1853         - Returning id by value
1854         - Generating a new id for a value
1855
1856         Is not able to:
1857         - Remove an id/value pair (is possible to implement but slow)
1858 */
1859 template<typename T>
1860 class MutexedIdGenerator
1861 {
1862 public:
1863         MutexedIdGenerator()
1864         {
1865                 m_mutex.Init();
1866                 assert(m_mutex.IsInitialized());
1867         }
1868         
1869         // Returns true if found
1870         bool getValue(u32 id, T &value)
1871         {
1872                 if(id == 0)
1873                         return false;
1874                 JMutexAutoLock lock(m_mutex);
1875                 if(m_id_to_value.size() < id)
1876                         return false;
1877                 value = m_id_to_value[id-1];
1878                 return true;
1879         }
1880         
1881         // If id exists for value, returns the id.
1882         // Otherwise generates an id for the value.
1883         u32 getId(const T &value)
1884         {
1885                 JMutexAutoLock lock(m_mutex);
1886                 typename core::map<T, u32>::Node *n;
1887                 n = m_value_to_id.find(value);
1888                 if(n != NULL)
1889                         return n->getValue();
1890                 m_id_to_value.push_back(value);
1891                 u32 new_id = m_id_to_value.size();
1892                 m_value_to_id.insert(value, new_id);
1893                 return new_id;
1894         }
1895
1896 private:
1897         JMutex m_mutex;
1898         // Values are stored here at id-1 position (id 1 = [0])
1899         core::array<T> m_id_to_value;
1900         core::map<T, u32> m_value_to_id;
1901 };
1902
1903 /*
1904         Checks if a string contains only supplied characters
1905 */
1906 inline bool string_allowed(const std::string &s, const std::string &allowed_chars)
1907 {
1908         for(u32 i=0; i<s.size(); i++)
1909         {
1910                 bool confirmed = false;
1911                 for(u32 j=0; j<allowed_chars.size(); j++)
1912                 {
1913                         if(s[i] == allowed_chars[j])
1914                         {
1915                                 confirmed = true;
1916                                 break;
1917                         }
1918                 }
1919                 if(confirmed == false)
1920                         return false;
1921         }
1922         return true;
1923 }
1924
1925 /*
1926         Forcefully wraps string into rows using \n
1927         (no word wrap, used for showing paths in gui)
1928 */
1929 inline std::string wrap_rows(const std::string &from, u32 rowlen)
1930 {
1931         std::string to;
1932         for(u32 i=0; i<from.size(); i++)
1933         {
1934                 if(i != 0 && i%rowlen == 0)
1935                         to += '\n';
1936                 to += from[i];
1937         }
1938         return to;
1939 }
1940
1941 /*
1942         Some helper stuff
1943 */
1944 #define MYMIN(a,b) ((a)<(b)?(a):(b))
1945 #define MYMAX(a,b) ((a)>(b)?(a):(b))
1946
1947 /*
1948         Returns integer position of node in given floating point position
1949 */
1950 inline v3s16 floatToInt(v3f p, f32 d)
1951 {
1952         v3s16 p2(
1953                 (p.X + (p.X>0 ? d/2 : -d/2))/d,
1954                 (p.Y + (p.Y>0 ? d/2 : -d/2))/d,
1955                 (p.Z + (p.Z>0 ? d/2 : -d/2))/d);
1956         return p2;
1957 }
1958
1959 /*
1960         Returns floating point position of node in given integer position
1961 */
1962 inline v3f intToFloat(v3s16 p, f32 d)
1963 {
1964         v3f p2(
1965                 (f32)p.X * d,
1966                 (f32)p.Y * d,
1967                 (f32)p.Z * d
1968         );
1969         return p2;
1970 }
1971
1972 /*
1973         More serialization stuff
1974 */
1975
1976 // Creates a string with the length as the first two bytes
1977 inline std::string serializeString(const std::string &plain)
1978 {
1979         //assert(plain.size() <= 65535);
1980         if(plain.size() > 65535)
1981                 throw SerializationError("String too long for serializeString");
1982         char buf[2];
1983         writeU16((u8*)&buf[0], plain.size());
1984         std::string s;
1985         s.append(buf, 2);
1986         s.append(plain);
1987         return s;
1988 }
1989
1990 // Creates a string with the length as the first two bytes from wide string
1991 inline std::string serializeWideString(const std::wstring &plain)
1992 {
1993         //assert(plain.size() <= 65535);
1994         if(plain.size() > 65535)
1995                 throw SerializationError("String too long for serializeString");
1996         char buf[2];
1997         writeU16((u8*)buf, plain.size());
1998         std::string s;
1999         s.append(buf, 2);
2000         for(u32 i=0; i<plain.size(); i++)
2001         {
2002                 writeU16((u8*)buf, plain[i]);
2003                 s.append(buf, 2);
2004         }
2005         return s;
2006 }
2007
2008 // Reads a string with the length as the first two bytes
2009 inline std::string deSerializeString(std::istream &is)
2010 {
2011         char buf[2];
2012         is.read(buf, 2);
2013         if(is.gcount() != 2)
2014                 throw SerializationError("deSerializeString: size not read");
2015         u16 s_size = readU16((u8*)buf);
2016         if(s_size == 0)
2017                 return "";
2018         Buffer<char> buf2(s_size);
2019         is.read(&buf2[0], s_size);
2020         std::string s;
2021         s.reserve(s_size);
2022         s.append(&buf2[0], s_size);
2023         return s;
2024 }
2025
2026 // Reads a wide string with the length as the first two bytes
2027 inline std::wstring deSerializeWideString(std::istream &is)
2028 {
2029         char buf[2];
2030         is.read(buf, 2);
2031         if(is.gcount() != 2)
2032                 throw SerializationError("deSerializeString: size not read");
2033         u16 s_size = readU16((u8*)buf);
2034         if(s_size == 0)
2035                 return L"";
2036         std::wstring s;
2037         s.reserve(s_size);
2038         for(u32 i=0; i<s_size; i++)
2039         {
2040                 is.read(&buf[0], 2);
2041                 wchar_t c16 = readU16((u8*)buf);
2042                 s.append(&c16, 1);
2043         }
2044         return s;
2045 }
2046
2047 // Creates a string with the length as the first four bytes
2048 inline std::string serializeLongString(const std::string &plain)
2049 {
2050         char buf[4];
2051         writeU32((u8*)&buf[0], plain.size());
2052         std::string s;
2053         s.append(buf, 4);
2054         s.append(plain);
2055         return s;
2056 }
2057
2058 // Reads a string with the length as the first four bytes
2059 inline std::string deSerializeLongString(std::istream &is)
2060 {
2061         char buf[4];
2062         is.read(buf, 4);
2063         if(is.gcount() != 4)
2064                 throw SerializationError("deSerializeLongString: size not read");
2065         u32 s_size = readU32((u8*)buf);
2066         if(s_size == 0)
2067                 return "";
2068         Buffer<char> buf2(s_size);
2069         is.read(&buf2[0], s_size);
2070         std::string s;
2071         s.reserve(s_size);
2072         s.append(&buf2[0], s_size);
2073         return s;
2074 }
2075
2076 //
2077
2078 inline u32 time_to_daynight_ratio(u32 time_of_day)
2079 {
2080         const s32 daylength = 16;
2081         const s32 nightlength = 6;
2082         const s32 daytimelength = 8;
2083         s32 d = daylength;
2084         s32 t = (((time_of_day)%24000)/(24000/d));
2085         if(t < nightlength/2 || t >= d - nightlength/2)
2086                 //return 300;
2087                 return 350;
2088         else if(t >= d/2 - daytimelength/2 && t < d/2 + daytimelength/2)
2089                 return 1000;
2090         else
2091                 return 750;
2092 }
2093
2094 // Random helper. Usually d=BS
2095 inline core::aabbox3d<f32> getNodeBox(v3s16 p, float d)
2096 {
2097         return core::aabbox3d<f32>(
2098                 (float)p.X * d - 0.5*d,
2099                 (float)p.Y * d - 0.5*d,
2100                 (float)p.Z * d - 0.5*d,
2101                 (float)p.X * d + 0.5*d,
2102                 (float)p.Y * d + 0.5*d,
2103                 (float)p.Z * d + 0.5*d
2104         );
2105 }
2106         
2107 class IntervalLimiter
2108 {
2109 public:
2110         IntervalLimiter():
2111                 m_accumulator(0)
2112         {
2113         }
2114         /*
2115                 dtime: time from last call to this method
2116                 wanted_interval: interval wanted
2117                 return value:
2118                         true: action should be skipped
2119                         false: action should be done
2120         */
2121         bool step(float dtime, float wanted_interval)
2122         {
2123                 m_accumulator += dtime;
2124                 if(m_accumulator < wanted_interval)
2125                         return false;
2126                 m_accumulator -= wanted_interval;
2127                 return true;
2128         }
2129 protected:
2130         float m_accumulator;
2131 };
2132
2133 std::string translatePassword(std::string playername, std::wstring password);
2134
2135 #endif
2136