Atrinik Server 2.5
server/links.c
Go to the documentation of this file.
00001 /************************************************************************
00002 *            Atrinik, a Multiplayer Online Role Playing Game            *
00003 *                                                                       *
00004 *    Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team    *
00005 *                                                                       *
00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game)     *
00007 * and Crossfire (Multiplayer game for X-windows).                       *
00008 *                                                                       *
00009 * This program is free software; you can redistribute it and/or modify  *
00010 * it under the terms of the GNU General Public License as published by  *
00011 * the Free Software Foundation; either version 2 of the License, or     *
00012 * (at your option) any later version.                                   *
00013 *                                                                       *
00014 * This program is distributed in the hope that it will be useful,       *
00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00017 * GNU General Public License for more details.                          *
00018 *                                                                       *
00019 * You should have received a copy of the GNU General Public License     *
00020 * along with this program; if not, write to the Free Software           *
00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.             *
00022 *                                                                       *
00023 * The author can be reached at admin@atrinik.org                        *
00024 ************************************************************************/
00025 
00030 #include <global.h>
00031 
00035 objectlink *get_objectlink()
00036 {
00037     objectlink *ol = (objectlink *) get_poolchunk(pool_objectlink);
00038 
00039     memset(ol, 0, sizeof(objectlink));
00040     return ol;
00041 }
00042 
00046 void free_objectlink(objectlink *ol)
00047 {
00048     if (OBJECT_VALID(ol->objlink.ob, ol->id))
00049     {
00050         CLEAR_FLAG(ol->objlink.ob, FLAG_IS_LINKED);
00051     }
00052 
00053     free_objectlink_simple(ol);
00054 }
00055 
00059 static void free_objectlink_recursive(objectlink *ol)
00060 {
00061     if (ol->next)
00062     {
00063         free_objectlink_recursive(ol->next);
00064     }
00065 
00066     if (OBJECT_VALID(ol->objlink.ob, ol->id))
00067     {
00068         CLEAR_FLAG(ol->objlink.ob, FLAG_IS_LINKED);
00069     }
00070 
00071     free_objectlink_simple(ol);
00072 }
00073 
00079 void free_objectlinkpt(objectlink *obp)
00080 {
00081     if (obp->next)
00082     {
00083         free_objectlinkpt(obp->next);
00084     }
00085 
00086     if (obp->objlink.link)
00087     {
00088         free_objectlink_recursive(obp->objlink.link);
00089     }
00090 
00091     free_objectlink_simple(obp);
00092 }
00093 
00096 objectlink *objectlink_link(objectlink **startptr, objectlink **endptr, objectlink *afterptr, objectlink *beforeptr, objectlink *objptr)
00097 {
00098     /* Link it behind afterptr */
00099     if (!beforeptr)
00100     {
00101         /* If not, we just have to update startptr and endptr */
00102         if (afterptr)
00103         {
00104             /* Link between something? */
00105             if (afterptr->next)
00106             {
00107                 objptr->next = afterptr->next;
00108                 afterptr->next->prev = objptr;
00109             }
00110 
00111             afterptr->next = objptr;
00112             objptr->prev = afterptr;
00113         }
00114 
00115         if (startptr && !*startptr)
00116         {
00117             *startptr = objptr;
00118         }
00119 
00120         if (endptr && (!*endptr || *endptr == afterptr))
00121         {
00122             *endptr = objptr;
00123         }
00124     }
00125     /* Link it before beforeptr */
00126     else if (!afterptr)
00127     {
00128         if (beforeptr->prev)
00129         {
00130             objptr->prev = beforeptr->prev;
00131             beforeptr->prev->next = objptr;
00132         }
00133 
00134         beforeptr->prev = objptr;
00135         objptr->next = beforeptr;
00136 
00137         /* We can't be endptr but perhaps start */
00138         if (startptr && (!*startptr || *startptr == beforeptr))
00139         {
00140             *startptr = objptr;
00141         }
00142     }
00143     /* Special: link together two lists/objects */
00144     else
00145     {
00146         beforeptr->prev = objptr;
00147         afterptr->next = objptr;
00148         objptr->next = beforeptr;
00149         objptr->prev = afterptr;
00150     }
00151 
00152     return objptr;
00153 }
00154 
00157 objectlink *objectlink_unlink(objectlink **startptr, objectlink **endptr, objectlink *objptr)
00158 {
00159     if (startptr && *startptr == objptr)
00160     {
00161         *startptr = objptr->next;
00162     }
00163 
00164     if (endptr && *endptr == objptr)
00165     {
00166         *endptr = objptr->prev;
00167     }
00168 
00169     if (objptr->prev)
00170     {
00171         objptr->prev->next = objptr->next;
00172     }
00173 
00174     if (objptr->next)
00175     {
00176         objptr->next->prev = objptr->prev;
00177     }
00178 
00179     return objptr;
00180 }