public/IExtensionSys.h

Go to the documentation of this file.
00001 /**
00002  * vim: set ts=4 :
00003  * =============================================================================
00004  * SourceMod
00005  * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
00006  * =============================================================================
00007  *
00008  * This program is free software; you can redistribute it and/or modify it under
00009  * the terms of the GNU General Public License, version 3.0, as published by the
00010  * Free Software Foundation.
00011  * 
00012  * This program is distributed in the hope that it will be useful, but WITHOUT
00013  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00014  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
00015  * details.
00016  *
00017  * You should have received a copy of the GNU General Public License along with
00018  * this program.  If not, see <http://www.gnu.org/licenses/>.
00019  *
00020  * As a special exception, AlliedModders LLC gives you permission to link the
00021  * code of this program (as well as its derivative works) to "Half-Life 2," the
00022  * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
00023  * by the Valve Corporation.  You must obey the GNU General Public License in
00024  * all respects for all other code used.  Additionally, AlliedModders LLC grants
00025  * this exception to all derivative works.  AlliedModders LLC defines further
00026  * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
00027  * or <http://www.sourcemod.net/license.php>.
00028  *
00029  * Version: $Id: IExtensionSys.h 2315 2008-07-01 06:12:16Z dvander $
00030  */
00031 
00032 #ifndef _INCLUDE_SOURCEMOD_MODULE_INTERFACE_H_
00033 #define _INCLUDE_SOURCEMOD_MODULE_INTERFACE_H_
00034 
00035 #include <IShareSys.h>
00036 #include <ILibrarySys.h>
00037 
00038 /**
00039  * @file IExtensionSys.h
00040  * @brief Defines the interface for loading/unloading/managing extensions.
00041  */
00042 
00043 struct edict_t;
00044 
00045 namespace SourceMod
00046 {
00047           class IExtensionInterface;
00048           typedef void *                ITERATOR;           /**< Generic pointer for dependency iterators */
00049 
00050           /** 
00051            * @brief Encapsulates an IExtensionInterface and its dependencies.
00052            */
00053           class IExtension
00054           {
00055           public:
00056                     /**
00057                      * @brief Returns whether or not the extension is properly loaded.
00058                      */
00059                     virtual bool IsLoaded() =0;
00060 
00061                     /**
00062                      * @brief Returns the extension's API interface
00063                      *
00064                      * @return                              An IExtensionInterface pointer.
00065                      */
00066                     virtual IExtensionInterface *GetAPI() =0;
00067 
00068                     /**
00069                      * @brief Returns the filename of the extension, relative to the
00070                      * extension folder.   If the extension is an "external" extension, 
00071                      * the file path is specified by the extension itself, and may be 
00072                      * arbitrary (not real).
00073                      *
00074                      * @return                              A string containing the extension file name.
00075                      */
00076                     virtual const char *GetFilename() =0;
00077 
00078                     /**
00079                      * @brief Returns the extension's identity token.
00080                      *
00081                      * @return                              An IdentityToken_t pointer.
00082                      */
00083                     virtual IdentityToken_t *GetIdentity() =0;
00084 
00085                     /**
00086                      * @brief Retrieves the extension dependency list for this extension.
00087                      *
00088                      * @param pOwner              Optional pointer to store the first interface's owner.
00089                      * @param pInterface          Optional pointer to store the first interface.
00090                      * @return                                        An ITERATOR pointer for the results, or NULL if no results at all.
00091                      */
00092                     virtual ITERATOR *FindFirstDependency(IExtension **pOwner, SMInterface **pInterface) =0;
00093 
00094                     /**
00095                      * @brief Finds the next dependency in the dependency list.
00096                      *
00097                      * @param iter                          Pointer to iterator from FindFirstDependency.
00098                      * @param pOwner              Optional pointer to store the interface's owner.
00099                      * @param pInterface          Optional pointer to store the interface.
00100                      * @return                                        True if there are more results after this, false otherwise.
00101                      */
00102                     virtual bool FindNextDependency(ITERATOR *iter, IExtension **pOwner, SMInterface **pInterface) =0;
00103 
00104                     /**
00105                      * @brief Frees an ITERATOR handle from FindFirstDependency.
00106                      *
00107                      * @param iter                          Pointer to iterator to free.
00108                      */
00109                     virtual void FreeDependencyIterator(ITERATOR *iter) =0;
00110 
00111                     /**
00112                      * @brief Queries the extension to see its run state.
00113                      *
00114                      * @param error                         Error buffer (may be NULL).
00115                      * @param maxlength           Maximum length of buffer.
00116                      * @return                                        True if extension is okay, false if not okay.
00117                      */
00118                     virtual bool IsRunning(char *error, size_t maxlength) =0;
00119 
00120                     /**
00121                      * @brief Returns whether the extension is local (from the extensions 
00122                      * folder), or is from an external source (such as Metamod:Source).
00123                      *
00124                      * @return                                        True if from an external source, 
00125                      *                                                          false if local to SourceMod.
00126                      */
00127                     virtual bool IsExternal() =0;
00128           };
00129 
00130           /**
00131            * @brief Version code of the IExtensionInterface API itself.
00132            *
00133            * Note: This is bumped when IShareSys is changed, because IShareSys 
00134            * itself is not versioned.
00135            */
00136           #define SMINTERFACE_EXTENSIONAPI_VERSION          4
00137 
00138           /**
00139            * @brief The interface an extension must expose.
00140            */
00141           class IExtensionInterface
00142           {
00143           public:
00144                     /** Returns the interface API version */
00145                     virtual unsigned int GetExtensionVersion()
00146                     {
00147                               return SMINTERFACE_EXTENSIONAPI_VERSION;
00148                     }
00149           public:
00150                     /**
00151                      * @brief Called when the extension is loaded.
00152                      * 
00153                      * @param me                  Pointer back to extension.
00154                      * @param sys                 Pointer to interface sharing system of SourceMod.
00155                      * @param error               Error buffer to print back to, if any.
00156                      * @param maxlength Maximum size of error buffer.
00157                      * @param late                If this extension was loaded "late" (i.e. manually).
00158                      * @return                              True if load should continue, false otherwise.
00159                      */
00160                     virtual bool OnExtensionLoad(IExtension *me,
00161                               IShareSys *sys, 
00162                               char *error, 
00163                               size_t maxlength, 
00164                               bool late) =0;
00165 
00166                     /**
00167                      * @brief Called when the extension is about to be unloaded.
00168                      */
00169                     virtual void OnExtensionUnload() =0;
00170 
00171                     /**
00172                      * @brief Called when all extensions are loaded (loading cycle is done).
00173                      * If loaded late, this will be called right after OnExtensionLoad().
00174                      */
00175                     virtual void OnExtensionsAllLoaded() =0;
00176 
00177                     /**
00178                      * @brief Called when your pause state is about to change.
00179                      * 
00180                      * @param pause               True if pausing, false if unpausing.
00181                      */
00182                     virtual void OnExtensionPauseChange(bool pause) =0;
00183 
00184                     /**
00185                      * @brief Asks the extension whether it's safe to remove an external 
00186                      * interface it's using.  If it's not safe, return false, and the 
00187                      * extension will be unloaded afterwards.
00188                      *
00189                      * NOTE: It is important to also hook NotifyInterfaceDrop() in order to clean 
00190                      * up resources.
00191                      *
00192                      * @param pInterface                    Pointer to interface being dropped.  This 
00193                      *                                                                    pointer may be opaque, and it should not 
00194                      *                                                                    be queried using SMInterface functions unless 
00195                      *                                                                    it can be verified to match an existing 
00196                      *                                                                    pointer of known type.
00197                      * @return                                                  True to continue, false to unload this 
00198                      *                                                                    extension afterwards.
00199                      */
00200                     virtual bool QueryInterfaceDrop(SMInterface *pInterface)
00201                     {
00202                               return false;
00203                     }
00204 
00205                     /**
00206                      * @brief Notifies the extension that an external interface it uses is being removed.
00207                      *
00208                      * @param pInterface                    Pointer to interface being dropped.  This
00209                      *                                                                    pointer may be opaque, and it should not 
00210                      *                                                                    be queried using SMInterface functions unless 
00211                      *                                                                    it can be verified to match an existing 
00212                      */
00213                     virtual void NotifyInterfaceDrop(SMInterface *pInterface)
00214                     {
00215                     }
00216 
00217                     /**
00218                      * @brief Return false to tell Core that your extension should be considered unusable.
00219                      *
00220                      * @param error                                   Error buffer.
00221                      * @param maxlength                     Size of error buffer.
00222                      * @return                                                  True on success, false otherwise.
00223                      */
00224                     virtual bool QueryRunning(char *error, size_t maxlength)
00225                     {
00226                               return true;
00227                     }
00228           public:
00229                     /**
00230                      * @brief For extensions loaded through SourceMod, this should return true 
00231                      * if the extension needs to attach to Metamod:Source.  If the extension 
00232                      * is loaded through Metamod:Source, and uses SourceMod optionally, it must 
00233                      * return false.
00234                      *
00235                      * @return                                                  True if Metamod:Source is needed.
00236                      */
00237                     virtual bool IsMetamodExtension() =0;
00238 
00239                     /**
00240                      * @brief Must return a string containing the extension's short name.
00241                      *
00242                      * @return                                                  String containing extension name.
00243                      */
00244                     virtual const char *GetExtensionName() =0;
00245 
00246                     /**
00247                      * @brief Must return a string containing the extension's URL.
00248                      *
00249                      * @return                                                  String containing extension URL.
00250                      */
00251                     virtual const char *GetExtensionURL() =0;
00252 
00253                     /**
00254                      * @brief Must return a string containing a short identifier tag.
00255                      *
00256                      * @return                                                  String containing extension tag.
00257                      */
00258                     virtual const char *GetExtensionTag() =0;
00259 
00260                     /**
00261                      * @brief Must return a string containing a short author identifier.
00262                      *
00263                      * @return                                                  String containing extension author.
00264                      */
00265                     virtual const char *GetExtensionAuthor() =0;
00266 
00267                     /**
00268                      * @brief Must return a string containing version information.
00269                      *
00270                      * Any version string format can be used, however, SourceMod 
00271                      * makes a special guarantee version numbers in the form of 
00272                      * A.B.C.D will always be fully displayed, where:
00273                      * 
00274                      * A is a major version number of at most one digit.
00275                      * B is a minor version number of at most two digits.
00276                      * C is a minor version number of at most two digits.
00277                      * D is a build number of at most 5 digits.
00278                      *
00279                      * Thus, thirteen characters of display is guaranteed.
00280                      *
00281                      * @return                                                  String containing extension version.
00282                      */
00283                     virtual const char *GetExtensionVerString() =0;
00284 
00285                     /**
00286                      * @brief Must return a string containing description text.
00287                      *
00288                      * The description text may be longer than the other identifiers, 
00289                      * as it is only displayed when viewing one extension at a time.
00290                      * However, it should not have newlines, or any other characters 
00291                      * which would otherwise disrupt the display pattern.
00292                      * 
00293                      * @return                                                  String containing extension description.
00294                      */
00295                     virtual const char *GetExtensionDescription() =0;
00296 
00297                     /**
00298                      * @brief Must return a string containing the compilation date.
00299                      *
00300                      * @return                                                  String containing the compilation date.
00301                      */
00302                     virtual const char *GetExtensionDateString() =0;
00303 
00304                     /**
00305                      * @brief Called on server activation before plugins receive the OnServerLoad forward.
00306                      * 
00307                      * @param pEdictList                    Edicts list.
00308                      * @param edictCount                    Number of edicts in the list.
00309                      * @param clientMax                     Maximum number of clients allowed in the server.
00310                      */
00311                     virtual void OnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax)
00312                     {
00313                     }
00314           };
00315 
00316           /**
00317            * @brief Returned via OnMetamodQuery() to get an IExtensionManager pointer.
00318            */
00319           #define SOURCEMOD_INTERFACE_EXTENSIONS                                "SM_ExtensionManager"
00320 
00321           /**
00322            * @brief Fired through OnMetamodQuery() to notify plugins that SourceMod is 
00323            * loaded.  
00324            *
00325            * Plugins should not return an interface pointer or IFACE_OK, instead, 
00326            * they should attach as needed by searching for SOURCEMOD_INTERFACE_EXTENSIONS.
00327            *
00328            * This may be fired more than once; if already attached, an extension should 
00329            * not attempt to re-attach.  The purpose of this is to notify Metamod:Source 
00330            * plugins which load after SourceMod loads.
00331            */
00332           #define SOURCEMOD_NOTICE_EXTENSIONS                                             "SM_ExtensionsAttachable"
00333 
00334           #define SMINTERFACE_EXTENSIONMANAGER_NAME                             "IExtensionManager"
00335           #define SMINTERFACE_EXTENSIONMANAGER_VERSION                2
00336 
00337           /**
00338            * @brief Manages the loading/unloading of extensions.
00339            */
00340           class IExtensionManager : public SMInterface
00341           {
00342           public:
00343                     virtual const char *GetInterfaceName()
00344                     {
00345                               return SMINTERFACE_EXTENSIONMANAGER_NAME;
00346                     }
00347                     virtual unsigned int GetInterfaceVersion()
00348                     {
00349                               return SMINTERFACE_EXTENSIONMANAGER_VERSION;
00350                     }
00351                     virtual bool IsVersionCompatible(unsigned int version)
00352                     {
00353                               if (version < 2)
00354                               {
00355                                         return false;
00356                               }
00357                               return SMInterface::IsVersionCompatible(version);
00358                     }
00359           public:
00360                     /**
00361                      * @brief Loads a extension into the extension system.
00362                      *
00363                      * @param path                          Path to extension file, relative to the 
00364                      *                                                          extensions folder.
00365                      * @param error                         Error buffer.
00366                      * @param maxlength           Maximum error buffer length.
00367                      * @return                                        New IExtension on success, NULL on failure.
00368                      *                                                          If        NULL is returned, the error buffer will be 
00369                      *                                                          filled with a null-terminated string.
00370                      */
00371                     virtual IExtension *LoadExtension(const char *path, 
00372                               char *error,
00373                               size_t maxlength) =0;
00374 
00375                     /**
00376                      * @brief Loads an extension into the extension system, directly, 
00377                      * as an external extension.  
00378                      *
00379                      * The extension receives all normal callbacks.  However, it is 
00380                      * never opened via LoadLibrary/dlopen or closed via FreeLibrary
00381                      * or dlclose.
00382                      *
00383                      * @param pInterface          Pointer to an IExtensionInterface instance.
00384                      * @param filepath            Relative path to the extension's file, from 
00385                      *                                                          mod folder.
00386                      * @param filename            Name to use to uniquely identify the extension. 
00387                      *                                                          The name should be generic, without any 
00388                      *                                                          platform-specific suffices.  For example, 
00389                      *                                                          sdktools.ext instead of sdktools.ext.so.
00390                      *                                                          This filename is used to detect if the 
00391                      *                                                          extension is already loaded, and to verify 
00392                      *                                                          plugins that require the same extension.
00393                      * @param error                         Buffer to store error message.
00394                      * @param maxlength           Maximum size of the error buffer.
00395                      * @return                                        IExtension pointer on success, NULL on failure.
00396                      *                                                          If NULL is returned, the error buffer will be 
00397                      *                                                          filled with a null-terminated string.
00398                      */
00399                     virtual IExtension *LoadExternal(IExtensionInterface *pInterface,
00400                               const char *filepath,
00401                               const char *filename,
00402                               char *error,
00403                               size_t maxlength) =0;
00404 
00405                     /**
00406                      * @brief Attempts to unload an extension.  External extensions must 
00407                      * call this before unloading.
00408                      *
00409                      * @param pExt                          IExtension pointer.
00410                      * @return                                        True if successful, false otherwise.
00411                      */
00412                     virtual bool UnloadExtension(IExtension *pExt) =0;
00413           };
00414 
00415           #define SM_IFACEPAIR(name) SMINTERFACE_##name##_NAME, SMINTERFACE_##name##_VERSION
00416 
00417           #define SM_FIND_IFACE_OR_FAIL(prefix, variable, errbuf, errsize) \
00418                     if (!sharesys->RequestInterface(SM_IFACEPAIR(prefix), myself, (SMInterface **)&variable)) \
00419                     { \
00420                               if (errbuf) \
00421                               { \
00422                                         size_t len = snprintf(errbuf, \
00423                                                   errsize, \
00424                                                   "Could not find interface: %s (version: %d)", \
00425                                                   SM_IFACEPAIR(prefix)); \
00426                                         if (len >= errsize) \
00427                                         { \
00428                                                   errbuf[errsize - 1] = '\0'; \
00429                                         } \
00430                               } \
00431                               return false; \
00432                     }
00433 
00434           #define SM_FIND_IFACE(prefix, variable) \
00435                     sharesys->RequestInterface(SM_IFACEPAIR(prefix), myself, (SMInterface **)&variable);
00436 }
00437 
00438 #endif //_INCLUDE_SOURCEMOD_MODULE_INTERFACE_H_
00439 

Generated on Fri Nov 21 01:10:02 2008 for SourceMod SDK by  doxygen 1.5.1