--- deliantra/server/include/util.h 2011/04/23 04:56:51 1.114 +++ deliantra/server/include/util.h 2012/10/29 23:55:54 1.120 @@ -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); } @@ -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 } } @@ -432,6 +451,63 @@ } }; +// 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; + ++_refcnt (); + } + + ~refcnt_buf (); + + refcnt_buf &operator =(const refcnt_buf &src); + + operator char *() + { + return data; + } + + size_t size () const + { + return _size (); + } + +protected: + enum { + overhead = sizeof (unsigned int) * 2 + }; + + unsigned int &_size () const + { + return ((unsigned int *)data)[-2]; + } + + unsigned int &_refcnt () const + { + return ((unsigned int *)data)[-1]; + } + + void _alloc (unsigned int size) + { + data = ((char *)salloc (size + overhead)) + overhead; + _size () = size; + _refcnt () = 1; + } + + void dec () + { + if (!--_refcnt ()) + sfree (data - overhead, size () + overhead); + } +}; + INTERFACE_CLASS (attachable) struct refcnt_base { @@ -580,7 +656,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 +703,7 @@ void erase (T *obj) { - unsigned int pos = obj->*indexmember; + object_vector_index pos = obj->*indexmember; obj->*indexmember = 0; if (pos < this->size ())