sourcemod/public/IExtensionSys.h
Scott Ehlert 251cced1f8 Spring Cleaning, Part Ichi (1)
Various minor things done to project files
Updated sample extension project file and updated makefile to the new unified version (more changes likely on the way)
Updated regex project file and makefile

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401971
2008-03-30 07:00:22 +00:00

418 lines
14 KiB
C++

/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program 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
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#ifndef _INCLUDE_SOURCEMOD_MODULE_INTERFACE_H_
#define _INCLUDE_SOURCEMOD_MODULE_INTERFACE_H_
#include <IShareSys.h>
#include <ILibrarySys.h>
/**
* @file IExtensionSys.h
* @brief Defines the interface for loading/unloading/managing extensions.
*/
namespace SourceMod
{
class IExtensionInterface;
typedef void * ITERATOR; /**< Generic pointer for dependency iterators */
/**
* @brief Encapsulates an IExtensionInterface and its dependencies.
*/
class IExtension
{
public:
/**
* @brief Returns whether or not the extension is properly loaded.
*/
virtual bool IsLoaded() =0;
/**
* @brief Returns the extension's API interface
*
* @return An IExtensionInterface pointer.
*/
virtual IExtensionInterface *GetAPI() =0;
/**
* @brief Returns the filename of the extension, relative to the
* extension folder. If the extension is an "external" extension,
* the file path is specified by the extension itself, and may be
* arbitrary (not real).
*
* @return A string containing the extension file name.
*/
virtual const char *GetFilename() =0;
/**
* @brief Returns the extension's identity token.
*
* @return An IdentityToken_t pointer.
*/
virtual IdentityToken_t *GetIdentity() =0;
/**
* @brief Retrieves the extension dependency list for this extension.
*
* @param pOwner Optional pointer to store the first interface's owner.
* @param pInterface Optional pointer to store the first interface.
* @return An ITERATOR pointer for the results, or NULL if no results at all.
*/
virtual ITERATOR *FindFirstDependency(IExtension **pOwner, SMInterface **pInterface) =0;
/**
* @brief Finds the next dependency in the dependency list.
*
* @param iter Pointer to iterator from FindFirstDependency.
* @param pOwner Optional pointer to store the interface's owner.
* @param pInterface Optional pointer to store the interface.
* @return True if there are more results after this, false otherwise.
*/
virtual bool FindNextDependency(ITERATOR *iter, IExtension **pOwner, SMInterface **pInterface) =0;
/**
* @brief Frees an ITERATOR handle from FindFirstDependency.
*
* @param iter Pointer to iterator to free.
*/
virtual void FreeDependencyIterator(ITERATOR *iter) =0;
/**
* @brief Queries the extension to see its run state.
*
* @param error Error buffer (may be NULL).
* @param maxlength Maximum length of buffer.
* @return True if extension is okay, false if not okay.
*/
virtual bool IsRunning(char *error, size_t maxlength) =0;
/**
* @brief Returns whether the extension is local (from the extensions
* folder), or is from an external source (such as Metamod:Source).
*
* @return True if from an external source,
* false if local to SourceMod.
*/
virtual bool IsExternal() =0;
};
/**
* @brief Version code of the IExtensionInterface API itself.
*
* Note: This is bumped when IShareSys is changed, because IShareSys
* itself is not versioned.
*/
#define SMINTERFACE_EXTENSIONAPI_VERSION 3
/**
* @brief The interface an extension must expose.
*/
class IExtensionInterface
{
public:
/** Returns the interface API version */
virtual unsigned int GetExtensionVersion()
{
return SMINTERFACE_EXTENSIONAPI_VERSION;
}
public:
/**
* @brief Called when the extension is loaded.
*
* @param me Pointer back to extension.
* @param sys Pointer to interface sharing system of SourceMod.
* @param error Error buffer to print back to, if any.
* @param maxlength Maximum size of error buffer.
* @param late If this extension was loaded "late" (i.e. manually).
* @return True if load should continue, false otherwise.
*/
virtual bool OnExtensionLoad(IExtension *me,
IShareSys *sys,
char *error,
size_t maxlength,
bool late) =0;
/**
* @brief Called when the extension is about to be unloaded.
*/
virtual void OnExtensionUnload() =0;
/**
* @brief Called when all extensions are loaded (loading cycle is done).
* If loaded late, this will be called right after OnExtensionLoad().
*/
virtual void OnExtensionsAllLoaded() =0;
/**
* @brief Called when your pause state is about to change.
*
* @param pause True if pausing, false if unpausing.
*/
virtual void OnExtensionPauseChange(bool pause) =0;
/**
* @brief Asks the extension whether it's safe to remove an external
* interface it's using. If it's not safe, return false, and the
* extension will be unloaded afterwards.
*
* NOTE: It is important to also hook NotifyInterfaceDrop() in order to clean up resources.
*
* @param pInterface Pointer to interface being dropped.
* @return True to continue, false to unload this extension afterwards.
*/
virtual bool QueryInterfaceDrop(SMInterface *pInterface)
{
return false;
}
/**
* @brief Notifies the extension that an external interface it uses is being removed.
*
* @param pInterface Pointer to interface being dropped.
*/
virtual void NotifyInterfaceDrop(SMInterface *pInterface)
{
}
/**
* @brief Return false to tell Core that your extension should be considered unusable.
*
* @param error Error buffer.
* @param maxlength Size of error buffer.
* @return True on success, false otherwise.
*/
virtual bool QueryRunning(char *error, size_t maxlength)
{
return true;
}
public:
/**
* @brief For extensions loaded through SourceMod, this should return true
* if the extension needs to attach to Metamod:Source. If the extension
* is loaded through Metamod:Source, and uses SourceMod optionally, it must
* return false.
*
* @return True if Metamod:Source is needed.
*/
virtual bool IsMetamodExtension() =0;
/**
* @brief Must return a string containing the extension's short name.
*
* @return String containing extension name.
*/
virtual const char *GetExtensionName() =0;
/**
* @brief Must return a string containing the extension's URL.
*
* @return String containing extension URL.
*/
virtual const char *GetExtensionURL() =0;
/**
* @brief Must return a string containing a short identifier tag.
*
* @return String containing extension tag.
*/
virtual const char *GetExtensionTag() =0;
/**
* @brief Must return a string containing a short author identifier.
*
* @return String containing extension author.
*/
virtual const char *GetExtensionAuthor() =0;
/**
* @brief Must return a string containing version information.
*
* Any version string format can be used, however, SourceMod
* makes a special guarantee version numbers in the form of
* A.B.C.D will always be fully displayed, where:
*
* A is a major version number of at most one digit.
* B is a minor version number of at most two digits.
* C is a minor version number of at most two digits.
* D is a build number of at most 5 digits.
*
* Thus, thirteen characters of display is guaranteed.
*
* @return String containing extension version.
*/
virtual const char *GetExtensionVerString() =0;
/**
* @brief Must return a string containing description text.
*
* The description text may be longer than the other identifiers,
* as it is only displayed when viewing one extension at a time.
* However, it should not have newlines, or any other characters
* which would otherwise disrupt the display pattern.
*
* @return String containing extension description.
*/
virtual const char *GetExtensionDescription() =0;
/**
* @brief Must return a string containing the compilation date.
*
* @return String containing the compilation date.
*/
virtual const char *GetExtensionDateString() =0;
};
/**
* @brief Returned via OnMetamodQuery() to get an IExtensionManager pointer.
*/
#define SOURCEMOD_INTERFACE_EXTENSIONS "SM_ExtensionManager"
/**
* @brief Fired through OnMetamodQuery() to notify plugins that SourceMod is
* loaded.
*
* Plugins should not return an interface pointer or IFACE_OK, instead,
* they should attach as needed by searching for SOURCEMOD_INTERFACE_EXTENSIONS.
*
* This may be fired more than once; if already attached, an extension should
* not attempt to re-attach. The purpose of this is to notify Metamod:Source
* plugins which load after SourceMod loads.
*/
#define SOURCEMOD_NOTICE_EXTENSIONS "SM_ExtensionsAttachable"
#define SMINTERFACE_EXTENSIONMANAGER_NAME "IExtensionManager"
#define SMINTERFACE_EXTENSIONMANAGER_VERSION 2
/**
* @brief Manages the loading/unloading of extensions.
*/
class IExtensionManager : public SMInterface
{
public:
virtual const char *GetInterfaceName()
{
return SMINTERFACE_EXTENSIONMANAGER_NAME;
}
virtual unsigned int GetInterfaceVersion()
{
return SMINTERFACE_EXTENSIONMANAGER_VERSION;
}
virtual bool IsVersionCompatible(unsigned int version)
{
if (version < 2)
{
return false;
}
return SMInterface::IsVersionCompatible(version);
}
public:
/**
* @brief Loads a extension into the extension system.
*
* @param path Path to extension file, relative to the
* extensions folder.
* @param error Error buffer.
* @param maxlength Maximum error buffer length.
* @return New IExtension on success, NULL on failure.
* If NULL is returned, the error buffer will be
* filled with a null-terminated string.
*/
virtual IExtension *LoadExtension(const char *path,
char *error,
size_t maxlength) =0;
/**
* @brief Loads an extension into the extension system, directly,
* as an external extension.
*
* The extension receives all normal callbacks. However, it is
* never opened via LoadLibrary/dlopen or closed via FreeLibrary
* or dlclose.
*
* @param pInterface Pointer to an IExtensionInterface instance.
* @param filepath Relative path to the extension's file, from
* mod folder.
* @param filename Name to use to uniquely identify the extension.
* The name should be generic, without any
* platform-specific suffices. For example,
* sdktools.ext instead of sdktools.ext.so.
* This filename is used to detect if the
* extension is already loaded, and to verify
* plugins that require the same extension.
* @param error Buffer to store error message.
* @param maxlength Maximum size of the error buffer.
* @return IExtension pointer on success, NULL on failure.
* If NULL is returned, the error buffer will be
* filled with a null-terminated string.
*/
virtual IExtension *LoadExternal(IExtensionInterface *pInterface,
const char *filepath,
const char *filename,
char *error,
size_t maxlength) =0;
/**
* @brief Attempts to unload an extension. External extensions must
* call this before unloading.
*
* @param pExt IExtension pointer.
* @return True if successful, false otherwise.
*/
virtual bool UnloadExtension(IExtension *pExt) =0;
};
#define SM_IFACEPAIR(name) SMINTERFACE_##name##_NAME, SMINTERFACE_##name##_VERSION
#define SM_FIND_IFACE_OR_FAIL(prefix, variable, errbuf, errsize) \
if (!sharesys->RequestInterface(SM_IFACEPAIR(prefix), myself, (SMInterface **)&variable)) \
{ \
if (errbuf) \
{ \
size_t len = snprintf(errbuf, \
errsize, \
"Could not find interface: %s (version: %d)", \
SM_IFACEPAIR(prefix)); \
if (len >= errsize) \
{ \
errbuf[errsize - 1] = '\0'; \
} \
} \
return false; \
}
#define SM_FIND_IFACE(prefix, variable) \
sharesys->RequestInterface(SM_IFACEPAIR(prefix), myself, (SMInterface **)&variable);
}
#endif //_INCLUDE_SOURCEMOD_MODULE_INTERFACE_H_