--- deliantra/server/include/util.h 2007/07/13 15:54:40 1.53 +++ deliantra/server/include/util.h 2007/12/16 02:50:33 1.59 @@ -1,9 +1,9 @@ /* - * This file is part of Crossfire TRT, the Roguelike Realtime MORPG. + * This file is part of Deliantra, the Roguelike Realtime MMORPG. * - * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team + * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Deliantra team * - * Crossfire TRT is free software: you can redistribute it and/or modify + * Deliantra is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . * - * The authors can be reached via e-mail to + * The authors can be reached via e-mail to */ #ifndef UTIL_H__ @@ -174,6 +174,8 @@ return ((d - 1) & 7) + 1; } +extern size_t slice_alloc; // statistics + // makes dynamically allocated objects zero-initialised struct zero_initialised { @@ -185,21 +187,25 @@ void *operator new (size_t s) { + slice_alloc += s; return g_slice_alloc0 (s); } void *operator new[] (size_t s) { + slice_alloc += s; return g_slice_alloc0 (s); } void operator delete (void *p, size_t s) { + slice_alloc -= s; g_slice_free1 (s, p); } void operator delete[] (void *p, size_t s) { + slice_alloc -= s; g_slice_free1 (s, p); } }; @@ -227,6 +233,7 @@ #ifdef PREFER_MALLOC free (ptr); #else + slice_alloc -= n * sizeof (T); g_slice_free1 (n * sizeof (T), (void *)ptr); #endif } @@ -335,33 +342,67 @@ extern rand_gen rndm; +INTERFACE_CLASS (attachable) +struct refcnt_base +{ + typedef int refcnt_t; + mutable refcnt_t ACC (RW, refcnt); + + MTH void refcnt_inc () const { ++refcnt; } + MTH void refcnt_dec () const { --refcnt; } + + refcnt_base () : refcnt (0) { } +}; + +// to avoid branches with more advanced compilers +extern refcnt_base::refcnt_t refcnt_dummy; + template struct refptr { + // p if not null + refcnt_base::refcnt_t *refcnt_ref () { return p ? &p->refcnt : &refcnt_dummy; } + + void refcnt_dec () + { + if (!is_constant (p)) + --*refcnt_ref (); + else if (p) + --p->refcnt; + } + + void refcnt_inc () + { + if (!is_constant (p)) + ++*refcnt_ref (); + else if (p) + ++p->refcnt; + } + T *p; refptr () : p(0) { } - refptr (const refptr &p) : p(p.p) { if (p) p->refcnt_inc (); } - refptr (T *p) : p(p) { if (p) p->refcnt_inc (); } - ~refptr () { if (p) p->refcnt_dec (); } + refptr (const refptr &p) : p(p.p) { refcnt_inc (); } + refptr (T *p) : p(p) { refcnt_inc (); } + ~refptr () { refcnt_dec (); } const refptr &operator =(T *o) { - if (p) p->refcnt_dec (); + // if decrementing ever destroys we need to reverse the order here + refcnt_dec (); p = o; - if (p) p->refcnt_inc (); - + refcnt_inc (); return *this; } - const refptr &operator =(const refptr o) + const refptr &operator =(const refptr &o) { *this = o.p; return *this; } T &operator * () const { return *p; } - T *operator ->() const { return p; } + T *operator ->() const { return p; } operator T *() const { return p; } }; @@ -508,13 +549,13 @@ typedef double tstamp; -// return current time as timestampe +// return current time as timestamp tstamp now (); int similar_direction (int a, int b); -// like printf, but returns a std::string -const std::string format (const char *format, ...); +// like sprintf, but returns a "static" buffer +const char *format (const char *format, ...); #endif