Atrinik Server 2.5
plugins/plugin_python/atrinik_archetype.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 <plugin_python.h>
00031 
00034 /* @cparser
00035  * @page plugin_python_archetype_fields Python archetype fields
00036  * <h2>Python archetype fields</h2>
00037  * List of the archetype fields and their meaning. */
00038 static fields_struct fields[] =
00039 {
00040     {"name", FIELDTYPE_SHSTR, offsetof(archetype, name), 0, 0},
00041     {"next", FIELDTYPE_ARCH, offsetof(archetype, next), 0, 0},
00042     {"head", FIELDTYPE_ARCH, offsetof(archetype, head), 0, 0},
00043     {"more", FIELDTYPE_ARCH, offsetof(archetype, more), 0, 0},
00044     {"clone", FIELDTYPE_OBJECT2, offsetof(archetype, clone), 0, 0}
00045 };
00046 /* @endcparser */
00047 
00053 static PyObject *get_attribute(Atrinik_Archetype *at, void *context)
00054 {
00055     return generic_field_getter((fields_struct *) context, at->at);
00056 }
00057 
00064 static PyObject *Atrinik_Archetype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
00065 {
00066     Atrinik_Archetype *at;
00067 
00068     (void) args;
00069     (void) kwds;
00070 
00071     at = (Atrinik_Archetype *) type->tp_alloc(type, 0);
00072 
00073     if (at)
00074     {
00075         at->at = NULL;
00076     }
00077 
00078     return (PyObject *) at;
00079 }
00080 
00084 static void Atrinik_Archetype_dealloc(Atrinik_Archetype *at)
00085 {
00086     at->at = NULL;
00087 #ifndef IS_PY_LEGACY
00088     Py_TYPE(at)->tp_free((PyObject *) at);
00089 #else
00090     at->ob_type->tp_free((PyObject *) at);
00091 #endif
00092 }
00093 
00098 static PyObject *Atrinik_Archetype_str(Atrinik_Archetype *at)
00099 {
00100     return Py_BuildValue("s", at->at->name);
00101 }
00102 
00103 static int Atrinik_Archetype_InternalCompare(Atrinik_Archetype *left, Atrinik_Archetype *right)
00104 {
00105     return (left->at < right->at ? -1 : (left->at == right->at ? 0 : 1));
00106 }
00107 
00108 static PyObject *Atrinik_Archetype_RichCompare(Atrinik_Archetype *left, Atrinik_Archetype *right, int op)
00109 {
00110     if (!left || !right || !PyObject_TypeCheck((PyObject *) left, &Atrinik_ArchetypeType) || !PyObject_TypeCheck((PyObject *) right, &Atrinik_ArchetypeType))
00111     {
00112         Py_INCREF(Py_NotImplemented);
00113         return Py_NotImplemented;
00114     }
00115 
00116     return generic_rich_compare(op, Atrinik_Archetype_InternalCompare(left, right));
00117 }
00118 
00121 static PyGetSetDef getseters[NUM_FIELDS + 1];
00122 
00124 PyTypeObject Atrinik_ArchetypeType =
00125 {
00126 #ifdef IS_PY3K
00127     PyVarObject_HEAD_INIT(NULL, 0)
00128 #else
00129     PyObject_HEAD_INIT(NULL)
00130     0,
00131 #endif
00132     "Atrinik.Archetype",
00133     sizeof(Atrinik_Archetype),
00134     0,
00135     (destructor) Atrinik_Archetype_dealloc,
00136     NULL, NULL, NULL,
00137 #ifdef IS_PY3K
00138     NULL,
00139 #else
00140     (cmpfunc) Atrinik_Archetype_InternalCompare,
00141 #endif
00142     0, 0, 0, 0, 0, 0,
00143     (reprfunc) Atrinik_Archetype_str,
00144     0, 0, 0,
00145     Py_TPFLAGS_DEFAULT,
00146     "Atrinik archetypes",
00147     NULL, NULL,
00148     (richcmpfunc) Atrinik_Archetype_RichCompare,
00149     0, 0, 0,
00150     NULL,
00151     0,
00152     getseters,
00153     0, 0, 0, 0, 0, 0, 0,
00154     Atrinik_Archetype_new,
00155     0, 0, 0, 0, 0, 0, 0, 0
00156 #ifndef IS_PY_LEGACY
00157     , 0
00158 #endif
00159 };
00160 
00165 int Atrinik_Archetype_init(PyObject *module)
00166 {
00167     size_t i;
00168 
00169     /* Field getters */
00170     for (i = 0; i < NUM_FIELDS; i++)
00171     {
00172         PyGetSetDef *def = &getseters[i];
00173 
00174         def->name = fields[i].name;
00175         def->get = (getter) get_attribute;
00176         def->set = NULL;
00177         def->doc = NULL;
00178         def->closure = (void *) &fields[i];
00179     }
00180 
00181     getseters[i].name = NULL;
00182 
00183     Atrinik_ArchetypeType.tp_new = PyType_GenericNew;
00184 
00185     if (PyType_Ready(&Atrinik_ArchetypeType) < 0)
00186     {
00187         return 0;
00188     }
00189 
00190     Py_INCREF(&Atrinik_ArchetypeType);
00191     PyModule_AddObject(module, "Archetype", (PyObject *) &Atrinik_ArchetypeType);
00192 
00193     return 1;
00194 }
00195 
00200 PyObject *wrap_archetype(archetype *at)
00201 {
00202     Atrinik_Archetype *wrapper;
00203 
00204     /* Return None if no archetype was to be wrapped. */
00205     if (!at)
00206     {
00207         Py_INCREF(Py_None);
00208         return Py_None;
00209     }
00210 
00211     wrapper = PyObject_NEW(Atrinik_Archetype, &Atrinik_ArchetypeType);
00212 
00213     if (wrapper)
00214     {
00215         wrapper->at = at;
00216     }
00217 
00218     return (PyObject *) wrapper;
00219 }
00220