--- deliantra/server/include/util.h 2011/04/23 04:56:51 1.114 +++ deliantra/server/include/util.h 2012/11/12 02:39:51 1.122 @@ -1,22 +1,22 @@ /* * This file is part of Deliantra, the Roguelike Realtime MMORPG. - * - * Copyright (©) 2005,2006,2007,2008,2009,2010,2011 Marc Alexander Lehmann / Robin Redeker / the Deliantra team - * + * + * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann / Robin Redeker / the Deliantra team + * * Deliantra is free software: you can redistribute it and/or modify it under * the terms of the Affero GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the Affero GNU General Public License * and the GNU General Public License along with this program. If not, see * . - * + * * The authors can be reached via e-mail to */ @@ -88,8 +88,8 @@ // rationale for using (U) not (T) is to reduce signed/unsigned issues, // as a is often a constant while b is the variable. it is still a bug, though. -template static inline T min (T a, U b) { return (U)a < b ? (U)a : b; } -template static inline T max (T a, U b) { return (U)a > b ? (U)a : b; } +template static inline T min (T a, U b) { return a < (T)b ? a : (T)b; } +template static inline T max (T a, U b) { return a > (T)b ? a : (T)b; } template static inline T clamp (T v, U a, V b) { return v < (T)a ? (T)a : v >(T)b ? (T)b : v; } template static inline void min_it (T &v, U m) { v = min (v, (T)m); } @@ -239,9 +239,9 @@ #else // and has a max. error of 9 in the range -100..+100. #endif -inline int +inline int idistance (int dx, int dy) -{ +{ unsigned int dx_ = abs (dx); unsigned int dy_ = abs (dy); @@ -254,6 +254,26 @@ #endif } +// can be substantially faster than floor, if your value range allows for it +template +inline T +fastfloor (T x) +{ + return std::floor (x); +} + +inline float +fastfloor (float x) +{ + return sint32(x) - (x < 0); +} + +inline double +fastfloor (double x) +{ + return sint64(x) - (x < 0); +} + /* * absdir(int): Returns a number between 1 and 8, which represent * the "absolute" direction of a number (it actually takes care of @@ -306,7 +326,6 @@ slice_alloc -= n * sizeof (T); if (DEBUG_POISON) memset (ptr, DEBUG_POISON, n * sizeof (T)); g_slice_free1 (n * sizeof (T), (void *)ptr); - assert (slice_alloc >= 0);//D } } @@ -390,7 +409,7 @@ typedef const Tp &const_reference; typedef Tp value_type; - template + template struct rebind { typedef slice_allocator other; @@ -432,6 +451,70 @@ } }; +// basically a memory area, but refcounted +struct refcnt_buf +{ + char *data; + + refcnt_buf (size_t size = 0); + refcnt_buf (void *data, size_t size); + + refcnt_buf (const refcnt_buf &src) + { + data = src.data; + inc (); + } + + ~refcnt_buf (); + + refcnt_buf &operator =(const refcnt_buf &src); + + operator char *() + { + return data; + } + + size_t size () const + { + return _size (); + } + +protected: + enum { + overhead = sizeof (uint32_t) * 2 + }; + + uint32_t &_size () const + { + return ((unsigned int *)data)[-2]; + } + + uint32_t &_refcnt () const + { + return ((unsigned int *)data)[-1]; + } + + void _alloc (uint32_t size) + { + data = ((char *)salloc (size + overhead)) + overhead; + _size () = size; + _refcnt () = 1; + } + + void _dealloc (); + + void inc () + { + ++_refcnt (); + } + + void dec () + { + if (!--_refcnt ()) + _dealloc (); + } +}; + INTERFACE_CLASS (attachable) struct refcnt_base { @@ -516,7 +599,7 @@ // runs concurrently with the looping logic. // we modify the hash a bit to improve its distribution uint32_t hash = STRHSH_NULL; - + while (*s) hash = (hash ^ *s++) * 16777619U; @@ -527,7 +610,7 @@ memhsh (const char *s, size_t len) { uint32_t hash = STRHSH_NULL; - + while (len--) hash = (hash ^ *s++) * 16777619U; @@ -580,7 +663,7 @@ // This container blends advantages of linked lists // (efficiency) with vectors (random access) by -// by using an unordered vector and storing the vector +// using an unordered vector and storing the vector // index inside the object. // // + memory-efficient on most 64 bit archs @@ -627,7 +710,7 @@ void erase (T *obj) { - unsigned int pos = obj->*indexmember; + object_vector_index pos = obj->*indexmember; obj->*indexmember = 0; if (pos < this->size ())