// vi: set ts=4 sw=4 : // vim: set tw=75 : // linkent.h - export entities from mod "games" back to the HL engine /* * Copyright (c) 2001-2003 Will Day * * This file is part of Metamod. * * Metamod 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 2 of the License, or (at * your option) any later version. * * Metamod 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 GNU General Public License * along with Metamod; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * In addition, as a special exception, the author gives permission to * link the code of this program with the Half-Life Game Engine ("HL * Engine") and Modified Game Libraries ("MODs") developed by Valve, * L.L.C ("Valve"). You must obey the GNU General Public License in all * respects for all of the code used other than the HL Engine and MODs * from Valve. If you modify this file, you may extend this exception * to your version of the file, but you are not obligated to do so. If * you do not wish to do so, delete this exception statement from your * version. * */ #ifndef LINK_ENT_H #define LINK_ENT_H #include // always #include "osdep.h" // DLLEXPORT, etc #include "metamod.h" // GameDLL, etc #include "mlist.h" // MPluginList::find_match, etc #include "mplugin.h" // MPlugin::info, etc #include "log_meta.h" // META_DEBUG, etc // Comments from SDK dlls/util.h: //! This is the glue that hooks .MAP entity class names to our CPP classes. //! The _declspec forces them to be exported by name so we can do a lookup with GetProcAddress(). //! The function is used to intialize / allocate the object for the entity. // Adapted from LINK_ENTITY_TO_FUNC in adminmod linkfunc.cpp. typedef void (*ENTITY_FN) (entvars_t *); // Function to perform common code of LINK_ENTITY_TO_GAME. void do_link_ent(ENTITY_FN *pfnEntity, int *missing, char *entStr, entvars_t *pev); #define LINK_ENTITY_TO_GAME(entityName) \ C_DLLEXPORT void entityName(entvars_t *pev); \ void entityName(entvars_t *pev) { \ static ENTITY_FN pfnEntity = NULL; \ static int missing=0; \ char *entStr; \ entStr = STRINGIZE(entityName, 0); \ do_link_ent(&pfnEntity, &missing, entStr, pev); \ } // For now, we have to explicitly export functions for plugin entities, // just as for gamedll entities. Ideally, this could be generalized in // some manner, so that plugins can declare and use their own entities // without having them explicitly supported by metamod, but I don't know // yet if that is actually possible. // // LINK_ENTITY_TO_PLUGIN // - if plugin not loaded & running, return // - plugin has to be set loadable=startup only, else log error, return // - (plugin loaded) if func missing, return // - (plugin loaded) if func not found, dlsym // - (plugin loaded) if func still not found, set missing, return // - (plugin loaded, func found) call func #define LINK_ENTITY_TO_PLUGIN(entityName, pluginName) \ C_DLLEXPORT void entityName(entvars_t *pev); \ void entityName(entvars_t *pev) { \ static ENTITY_FN pfnEntity = NULL; \ static int missing=0; \ char *entStr; \ MPlugin *findp; \ entStr = STRINGIZE(entityName, 0); \ if(missing) \ return; \ if(!pfnEntity) { \ if(!(findp=Plugins->find_match(pluginName))) { \ META_ERROR("Couldn't find loaded plugin '%s' for plugin entity '%s'", pluginName, entStr); \ missing=1; \ return; \ } \ if(findp->info && findp->info->loadable != PT_STARTUP) { \ META_ERROR("Can't link entity '%s' for plugin '%s'; loadable != startup: %s", entStr, pluginName, findp->str_loadable()); \ missing=1; \ return; \ } \ META_DEBUG(9, ("Looking up plugin entity '%s'", entStr)); \ pfnEntity = (ENTITY_FN) DLSYM(findp->handle, entStr); \ } \ if(!pfnEntity) { \ META_ERROR("Couldn't find plugin entity '%s' in plugin DLL '%s'", entStr, findp->file); \ missing=1; \ return; \ } \ META_DEBUG(8, ("Linking plugin entity '%s'", entStr)); \ (*pfnEntity)(pev); \ } #endif /* LINK_ENT_H */