public/IExtensionSys.h
changeset 1952 b7aa2b626807
child 1993 8c08aaff4d39
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/public/IExtensionSys.h	Sun Mar 30 07:00:22 2008 +0000
     1.3 @@ -0,0 +1,417 @@
     1.4 +/**
     1.5 + * vim: set ts=4 :
     1.6 + * =============================================================================
     1.7 + * SourceMod
     1.8 + * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
     1.9 + * =============================================================================
    1.10 + *
    1.11 + * This program is free software; you can redistribute it and/or modify it under
    1.12 + * the terms of the GNU General Public License, version 3.0, as published by the
    1.13 + * Free Software Foundation.
    1.14 + * 
    1.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
    1.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    1.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    1.18 + * details.
    1.19 + *
    1.20 + * You should have received a copy of the GNU General Public License along with
    1.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
    1.22 + *
    1.23 + * As a special exception, AlliedModders LLC gives you permission to link the
    1.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
    1.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    1.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
    1.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
    1.28 + * this exception to all derivative works.  AlliedModders LLC defines further
    1.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    1.30 + * or <http://www.sourcemod.net/license.php>.
    1.31 + *
    1.32 + * Version: $Id$
    1.33 + */
    1.34 +
    1.35 +#ifndef _INCLUDE_SOURCEMOD_MODULE_INTERFACE_H_
    1.36 +#define _INCLUDE_SOURCEMOD_MODULE_INTERFACE_H_
    1.37 +
    1.38 +#include <IShareSys.h>
    1.39 +#include <ILibrarySys.h>
    1.40 +
    1.41 +/**
    1.42 + * @file IExtensionSys.h
    1.43 + * @brief Defines the interface for loading/unloading/managing extensions.
    1.44 + */
    1.45 +
    1.46 +namespace SourceMod
    1.47 +{
    1.48 +	class IExtensionInterface;
    1.49 +	typedef void *		ITERATOR;		/**< Generic pointer for dependency iterators */
    1.50 +
    1.51 +	/** 
    1.52 +	 * @brief Encapsulates an IExtensionInterface and its dependencies.
    1.53 +	 */
    1.54 +	class IExtension
    1.55 +	{
    1.56 +	public:
    1.57 +		/**
    1.58 +		 * @brief Returns whether or not the extension is properly loaded.
    1.59 +		 */
    1.60 +		virtual bool IsLoaded() =0;
    1.61 +
    1.62 +		/**
    1.63 +		 * @brief Returns the extension's API interface
    1.64 +		 *
    1.65 +		 * @return			An IExtensionInterface pointer.
    1.66 +		 */
    1.67 +		virtual IExtensionInterface *GetAPI() =0;
    1.68 +
    1.69 +		/**
    1.70 +		 * @brief Returns the filename of the extension, relative to the
    1.71 +		 * extension folder.   If the extension is an "external" extension, 
    1.72 +		 * the file path is specified by the extension itself, and may be 
    1.73 +		 * arbitrary (not real).
    1.74 +		 *
    1.75 +		 * @return			A string containing the extension file name.
    1.76 +		 */
    1.77 +		virtual const char *GetFilename() =0;
    1.78 +
    1.79 +		/**
    1.80 +		 * @brief Returns the extension's identity token.
    1.81 +		 *
    1.82 +		 * @return			An IdentityToken_t pointer.
    1.83 +		 */
    1.84 +		virtual IdentityToken_t *GetIdentity() =0;
    1.85 +
    1.86 +		/**
    1.87 +		 * @brief Retrieves the extension dependency list for this extension.
    1.88 +		 *
    1.89 +		 * @param pOwner		Optional pointer to store the first interface's owner.
    1.90 +		 * @param pInterface	Optional pointer to store the first interface.
    1.91 +		 * @return				An ITERATOR pointer for the results, or NULL if no results at all.
    1.92 +		 */
    1.93 +		virtual ITERATOR *FindFirstDependency(IExtension **pOwner, SMInterface **pInterface) =0;
    1.94 +
    1.95 +		/**
    1.96 +		 * @brief Finds the next dependency in the dependency list.
    1.97 +		 *
    1.98 +		 * @param iter			Pointer to iterator from FindFirstDependency.
    1.99 +		 * @param pOwner		Optional pointer to store the interface's owner.
   1.100 +		 * @param pInterface	Optional pointer to store the interface.
   1.101 +		 * @return				True if there are more results after this, false otherwise.
   1.102 +		 */
   1.103 +		virtual bool FindNextDependency(ITERATOR *iter, IExtension **pOwner, SMInterface **pInterface) =0;
   1.104 +
   1.105 +		/**
   1.106 +		 * @brief Frees an ITERATOR handle from FindFirstDependency.
   1.107 +		 *
   1.108 +		 * @param iter			Pointer to iterator to free.
   1.109 +		 */
   1.110 +		virtual void FreeDependencyIterator(ITERATOR *iter) =0;
   1.111 +
   1.112 +		/**
   1.113 +		 * @brief Queries the extension to see its run state.
   1.114 +		 *
   1.115 +		 * @param error			Error buffer (may be NULL).
   1.116 +		 * @param maxlength		Maximum length of buffer.
   1.117 +		 * @return				True if extension is okay, false if not okay.
   1.118 +		 */
   1.119 +		virtual bool IsRunning(char *error, size_t maxlength) =0;
   1.120 +
   1.121 +		/**
   1.122 +		 * @brief Returns whether the extension is local (from the extensions 
   1.123 +		 * folder), or is from an external source (such as Metamod:Source).
   1.124 +		 *
   1.125 +		 * @return				True if from an external source, 
   1.126 +		 *						false if local to SourceMod.
   1.127 +		 */
   1.128 +		virtual bool IsExternal() =0;
   1.129 +	};
   1.130 +
   1.131 +	/**
   1.132 +	 * @brief Version code of the IExtensionInterface API itself.
   1.133 +	 *
   1.134 +	 * Note: This is bumped when IShareSys is changed, because IShareSys 
   1.135 +	 * itself is not versioned.
   1.136 +	 */
   1.137 +	#define SMINTERFACE_EXTENSIONAPI_VERSION	3
   1.138 +
   1.139 +	/**
   1.140 +	 * @brief The interface an extension must expose.
   1.141 +	 */
   1.142 +	class IExtensionInterface
   1.143 +	{
   1.144 +	public:
   1.145 +		/** Returns the interface API version */
   1.146 +		virtual unsigned int GetExtensionVersion()
   1.147 +		{
   1.148 +			return SMINTERFACE_EXTENSIONAPI_VERSION;
   1.149 +		}
   1.150 +	public:
   1.151 +		/**
   1.152 +		 * @brief Called when the extension is loaded.
   1.153 +		 * 
   1.154 +		 * @param me		Pointer back to extension.
   1.155 +		 * @param sys		Pointer to interface sharing system of SourceMod.
   1.156 +		 * @param error		Error buffer to print back to, if any.
   1.157 +		 * @param maxlength	Maximum size of error buffer.
   1.158 +		 * @param late		If this extension was loaded "late" (i.e. manually).
   1.159 +		 * @return			True if load should continue, false otherwise.
   1.160 +		 */
   1.161 +		virtual bool OnExtensionLoad(IExtension *me,
   1.162 +			IShareSys *sys, 
   1.163 +			char *error, 
   1.164 +			size_t maxlength, 
   1.165 +			bool late) =0;
   1.166 +
   1.167 +		/**
   1.168 +		 * @brief Called when the extension is about to be unloaded.
   1.169 +		 */
   1.170 +		virtual void OnExtensionUnload() =0;
   1.171 +
   1.172 +		/**
   1.173 +		 * @brief Called when all extensions are loaded (loading cycle is done).
   1.174 +		 * If loaded late, this will be called right after OnExtensionLoad().
   1.175 +		 */
   1.176 +		virtual void OnExtensionsAllLoaded() =0;
   1.177 +
   1.178 +		/**
   1.179 +		 * @brief Called when your pause state is about to change.
   1.180 +		 * 
   1.181 +		 * @param pause		True if pausing, false if unpausing.
   1.182 +		 */
   1.183 +		virtual void OnExtensionPauseChange(bool pause) =0;
   1.184 +
   1.185 +		/**
   1.186 +		 * @brief Asks the extension whether it's safe to remove an external 
   1.187 +		 * interface it's using.  If it's not safe, return false, and the 
   1.188 +		 * extension will be unloaded afterwards.
   1.189 +		 *
   1.190 +		 * NOTE: It is important to also hook NotifyInterfaceDrop() in order to clean up resources.
   1.191 +		 *
   1.192 +		 * @param pInterface		Pointer to interface being dropped.
   1.193 +		 * @return					True to continue, false to unload this extension afterwards.
   1.194 +		 */
   1.195 +		virtual bool QueryInterfaceDrop(SMInterface *pInterface)
   1.196 +		{
   1.197 +			return false;
   1.198 +		}
   1.199 +
   1.200 +		/**
   1.201 +		 * @brief Notifies the extension that an external interface it uses is being removed.
   1.202 +		 *
   1.203 +		 * @param pInterface		Pointer to interface being dropped.
   1.204 +		 */
   1.205 +		virtual void NotifyInterfaceDrop(SMInterface *pInterface)
   1.206 +		{
   1.207 +		}
   1.208 +
   1.209 +		/**
   1.210 +		 * @brief Return false to tell Core that your extension should be considered unusable.
   1.211 +		 *
   1.212 +		 * @param error				Error buffer.
   1.213 +		 * @param maxlength			Size of error buffer.
   1.214 +		 * @return					True on success, false otherwise.
   1.215 +		 */
   1.216 +		virtual bool QueryRunning(char *error, size_t maxlength)
   1.217 +		{
   1.218 +			return true;
   1.219 +		}
   1.220 +	public:
   1.221 +		/**
   1.222 +		 * @brief For extensions loaded through SourceMod, this should return true 
   1.223 +		 * if the extension needs to attach to Metamod:Source.  If the extension 
   1.224 +		 * is loaded through Metamod:Source, and uses SourceMod optionally, it must 
   1.225 +		 * return false.
   1.226 +		 *
   1.227 +		 * @return					True if Metamod:Source is needed.
   1.228 +		 */
   1.229 +		virtual bool IsMetamodExtension() =0;
   1.230 +
   1.231 +		/**
   1.232 +		 * @brief Must return a string containing the extension's short name.
   1.233 +		 *
   1.234 +		 * @return					String containing extension name.
   1.235 +		 */
   1.236 +		virtual const char *GetExtensionName() =0;
   1.237 +
   1.238 +		/**
   1.239 +		 * @brief Must return a string containing the extension's URL.
   1.240 +		 *
   1.241 +		 * @return					String containing extension URL.
   1.242 +		 */
   1.243 +		virtual const char *GetExtensionURL() =0;
   1.244 +
   1.245 +		/**
   1.246 +		 * @brief Must return a string containing a short identifier tag.
   1.247 +		 *
   1.248 +		 * @return					String containing extension tag.
   1.249 +		 */
   1.250 +		virtual const char *GetExtensionTag() =0;
   1.251 +
   1.252 +		/**
   1.253 +		 * @brief Must return a string containing a short author identifier.
   1.254 +		 *
   1.255 +		 * @return					String containing extension author.
   1.256 +		 */
   1.257 +		virtual const char *GetExtensionAuthor() =0;
   1.258 +
   1.259 +		/**
   1.260 +		 * @brief Must return a string containing version information.
   1.261 +		 *
   1.262 +		 * Any version string format can be used, however, SourceMod 
   1.263 +		 * makes a special guarantee version numbers in the form of 
   1.264 +		 * A.B.C.D will always be fully displayed, where:
   1.265 +		 * 
   1.266 +		 * A is a major version number of at most one digit.
   1.267 +		 * B is a minor version number of at most two digits.
   1.268 +		 * C is a minor version number of at most two digits.
   1.269 +		 * D is a build number of at most 5 digits.
   1.270 +		 *
   1.271 +		 * Thus, thirteen characters of display is guaranteed.
   1.272 +		 *
   1.273 +		 * @return					String containing extension version.
   1.274 +		 */
   1.275 +		virtual const char *GetExtensionVerString() =0;
   1.276 +
   1.277 +		/**
   1.278 +		 * @brief Must return a string containing description text.
   1.279 +		 *
   1.280 +		 * The description text may be longer than the other identifiers, 
   1.281 +		 * as it is only displayed when viewing one extension at a time.
   1.282 +		 * However, it should not have newlines, or any other characters 
   1.283 +		 * which would otherwise disrupt the display pattern.
   1.284 +		 * 
   1.285 +		 * @return					String containing extension description.
   1.286 +		 */
   1.287 +		virtual const char *GetExtensionDescription() =0;
   1.288 +
   1.289 +		/**
   1.290 +		 * @brief Must return a string containing the compilation date.
   1.291 +		 *
   1.292 +		 * @return					String containing the compilation date.
   1.293 +		 */
   1.294 +		virtual const char *GetExtensionDateString() =0;
   1.295 +	};
   1.296 +
   1.297 +	/**
   1.298 +	 * @brief Returned via OnMetamodQuery() to get an IExtensionManager pointer.
   1.299 +	 */
   1.300 +	#define SOURCEMOD_INTERFACE_EXTENSIONS				"SM_ExtensionManager"
   1.301 +
   1.302 +	/**
   1.303 +	 * @brief Fired through OnMetamodQuery() to notify plugins that SourceMod is 
   1.304 +	 * loaded.  
   1.305 +	 *
   1.306 +	 * Plugins should not return an interface pointer or IFACE_OK, instead, 
   1.307 +	 * they should attach as needed by searching for SOURCEMOD_INTERFACE_EXTENSIONS.
   1.308 +	 *
   1.309 +	 * This may be fired more than once; if already attached, an extension should 
   1.310 +	 * not attempt to re-attach.  The purpose of this is to notify Metamod:Source 
   1.311 +	 * plugins which load after SourceMod loads.
   1.312 +	 */
   1.313 +	#define SOURCEMOD_NOTICE_EXTENSIONS					"SM_ExtensionsAttachable"
   1.314 +
   1.315 +	#define SMINTERFACE_EXTENSIONMANAGER_NAME			"IExtensionManager"
   1.316 +	#define SMINTERFACE_EXTENSIONMANAGER_VERSION		2
   1.317 +
   1.318 +	/**
   1.319 +	 * @brief Manages the loading/unloading of extensions.
   1.320 +	 */
   1.321 +	class IExtensionManager : public SMInterface
   1.322 +	{
   1.323 +	public:
   1.324 +		virtual const char *GetInterfaceName()
   1.325 +		{
   1.326 +			return SMINTERFACE_EXTENSIONMANAGER_NAME;
   1.327 +		}
   1.328 +		virtual unsigned int GetInterfaceVersion()
   1.329 +		{
   1.330 +			return SMINTERFACE_EXTENSIONMANAGER_VERSION;
   1.331 +		}
   1.332 +		virtual bool IsVersionCompatible(unsigned int version)
   1.333 +		{
   1.334 +			if (version < 2)
   1.335 +			{
   1.336 +				return false;
   1.337 +			}
   1.338 +			return SMInterface::IsVersionCompatible(version);
   1.339 +		}
   1.340 +	public:
   1.341 +		/**
   1.342 +		 * @brief Loads a extension into the extension system.
   1.343 +		 *
   1.344 +		 * @param path			Path to extension file, relative to the 
   1.345 +		 *						extensions folder.
   1.346 +		 * @param error			Error buffer.
   1.347 +		 * @param maxlength		Maximum error buffer length.
   1.348 +		 * @return				New IExtension on success, NULL on failure.
   1.349 +		 *						If	NULL is returned, the error buffer will be 
   1.350 +		 *						filled with a null-terminated string.
   1.351 +		 */
   1.352 +		virtual IExtension *LoadExtension(const char *path, 
   1.353 +			char *error,
   1.354 +			size_t maxlength) =0;
   1.355 +
   1.356 +		/**
   1.357 +		 * @brief Loads an extension into the extension system, directly, 
   1.358 +		 * as an external extension.  
   1.359 +		 *
   1.360 +		 * The extension receives all normal callbacks.  However, it is 
   1.361 +		 * never opened via LoadLibrary/dlopen or closed via FreeLibrary
   1.362 +		 * or dlclose.
   1.363 +		 *
   1.364 +		 * @param pInterface	Pointer to an IExtensionInterface instance.
   1.365 +		 * @param filepath		Relative path to the extension's file, from 
   1.366 +		 * 						mod folder.
   1.367 +		 * @param filename		Name to use to uniquely identify the extension. 
   1.368 +		 *						The name should be generic, without any 
   1.369 +		 *						platform-specific suffices.  For example, 
   1.370 +		 *						sdktools.ext instead of sdktools.ext.so.
   1.371 +		 *						This filename is used to detect if the 
   1.372 +		 *						extension is already loaded, and to verify 
   1.373 +		 *						plugins that require the same extension.
   1.374 +		 * @param error			Buffer to store error message.
   1.375 +		 * @param maxlength		Maximum size of the error buffer.
   1.376 +		 * @return				IExtension pointer on success, NULL on failure.
   1.377 +		 *						If NULL is returned, the error buffer will be 
   1.378 +		 *						filled with a null-terminated string.
   1.379 +		 */
   1.380 +		virtual IExtension *LoadExternal(IExtensionInterface *pInterface,
   1.381 +			const char *filepath,
   1.382 +			const char *filename,
   1.383 +			char *error,
   1.384 +			size_t maxlength) =0;
   1.385 +
   1.386 +		/**
   1.387 +		 * @brief Attempts to unload an extension.  External extensions must 
   1.388 +		 * call this before unloading.
   1.389 +		 *
   1.390 +		 * @param pExt			IExtension pointer.
   1.391 +		 * @return				True if successful, false otherwise.
   1.392 +		 */
   1.393 +		virtual bool UnloadExtension(IExtension *pExt) =0;
   1.394 +	};
   1.395 +
   1.396 +	#define SM_IFACEPAIR(name) SMINTERFACE_##name##_NAME, SMINTERFACE_##name##_VERSION
   1.397 +
   1.398 +	#define SM_FIND_IFACE_OR_FAIL(prefix, variable, errbuf, errsize) \
   1.399 +		if (!sharesys->RequestInterface(SM_IFACEPAIR(prefix), myself, (SMInterface **)&variable)) \
   1.400 +		{ \
   1.401 +			if (errbuf) \
   1.402 +			{ \
   1.403 +				size_t len = snprintf(errbuf, \
   1.404 +					errsize, \
   1.405 +					"Could not find interface: %s (version: %d)", \
   1.406 +					SM_IFACEPAIR(prefix)); \
   1.407 +				if (len >= errsize) \
   1.408 +				{ \
   1.409 +					errbuf[errsize - 1] = '\0'; \
   1.410 +				} \
   1.411 +			} \
   1.412 +			return false; \
   1.413 +		}
   1.414 +
   1.415 +	#define SM_FIND_IFACE(prefix, variable) \
   1.416 +		sharesys->RequestInterface(SM_IFACEPAIR(prefix), myself, (SMInterface **)&variable);
   1.417 +}
   1.418 +
   1.419 +#endif //_INCLUDE_SOURCEMOD_MODULE_INTERFACE_H_
   1.420 +