initial import of sharesystem (unfinished)
final revision of handle system (I hope!) initial import of plugin handles --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40234
This commit is contained in:
parent
5b331ca858
commit
f068587ecc
@ -7,6 +7,8 @@
|
||||
#define SMINTERFACE_HANDLESYSTEM_NAME "IHandleSys"
|
||||
#define SMINTERFACE_HANDLESYSTEM_VERSION 1
|
||||
|
||||
#define DEFAULT_IDENTITY NULL
|
||||
|
||||
namespace SourceMod
|
||||
{
|
||||
/**
|
||||
@ -37,6 +39,7 @@ namespace SourceMod
|
||||
HandleError_Index, /* generic internal indexing error */
|
||||
HandleError_Access, /* No access permitted to free this handle */
|
||||
HandleError_Limit, /* The limited number of handles has been reached */
|
||||
HandleError_Identity, /* The identity token was not usable */
|
||||
};
|
||||
|
||||
enum HandleAccessRight
|
||||
@ -54,14 +57,14 @@ namespace SourceMod
|
||||
{
|
||||
HandleSecurity()
|
||||
{
|
||||
owner = 0;
|
||||
owner = NULL;
|
||||
access[HandleAccess_Create] = true;
|
||||
access[HandleAccess_Read] = true;
|
||||
access[HandleAccess_Delete] = true;
|
||||
access[HandleAccess_Inherit] = true;
|
||||
access[HandleAccess_Clone] = true;
|
||||
}
|
||||
IdentityToken_t owner; /* Owner of the handle */
|
||||
IdentityToken_t *owner; /* Owner of the handle */
|
||||
bool access[HandleAccess_TOTAL]; /* World access rights */
|
||||
};
|
||||
|
||||
@ -112,12 +115,14 @@ namespace SourceMod
|
||||
* @param parent Parent handle to inherit from, 0 for none.
|
||||
* @param security Pointer to a temporary HandleSecurity object, NULL to use default
|
||||
* or inherited permissions.
|
||||
* @param ident Security token for any permissions.
|
||||
* @return A new HandleType_t unique ID.
|
||||
*/
|
||||
virtual HandleType_t CreateTypeEx(const char *name,
|
||||
IHandleTypeDispatch *dispatch,
|
||||
HandleType_t parent,
|
||||
const HandleSecurity *security) =0;
|
||||
const HandleSecurity *security,
|
||||
IdentityToken_t *ident) =0;
|
||||
|
||||
|
||||
/**
|
||||
@ -143,7 +148,7 @@ namespace SourceMod
|
||||
* @param type Type chain to remove.
|
||||
* @return True on success, false on failure.
|
||||
*/
|
||||
virtual bool RemoveType(HandleType_t type, IdentityToken_t ident) =0;
|
||||
virtual bool RemoveType(HandleType_t type, IdentityToken_t *ident) =0;
|
||||
|
||||
/**
|
||||
* @brief Finds a handle type by name.
|
||||
@ -159,14 +164,14 @@ namespace SourceMod
|
||||
*
|
||||
* @param type Type to use on the handle.
|
||||
* @param object Object to bind to the handle.
|
||||
* @param source Identity token for object using this handle (for example, a script).
|
||||
* @param owner Owner for the handle.
|
||||
* @param ident Identity token if any security rights are needed.
|
||||
* @return A new Handle_t, or 0 on failure.
|
||||
*/
|
||||
virtual Handle_t CreateHandle(HandleType_t type,
|
||||
void *object,
|
||||
IdentityToken_t source,
|
||||
IdentityToken_t ident) =0;
|
||||
IdentityToken_t *owner,
|
||||
IdentityToken_t *ident) =0;
|
||||
|
||||
/**
|
||||
* @brief Creates a new handle.
|
||||
@ -181,7 +186,7 @@ namespace SourceMod
|
||||
virtual Handle_t CreateScriptHandle(HandleType_t type,
|
||||
void *object,
|
||||
sp_context_t *ctx,
|
||||
IdentityToken_t ident) =0;
|
||||
IdentityToken_t *ident) =0;
|
||||
|
||||
/**
|
||||
* @brief Frees the memory associated with a handle and calls any destructors.
|
||||
@ -192,7 +197,7 @@ namespace SourceMod
|
||||
* @param ident Identity token, for destroying secure handles (0 for none).
|
||||
* @return A HandleError error code.
|
||||
*/
|
||||
virtual HandleError FreeHandle(Handle_t handle, IdentityToken_t ident) =0;
|
||||
virtual HandleError FreeHandle(Handle_t handle, IdentityToken_t *ident) =0;
|
||||
|
||||
/**
|
||||
* @brief Clones a handle by adding to its internal reference count. Its data,
|
||||
@ -200,11 +205,11 @@ namespace SourceMod
|
||||
*
|
||||
* @param handle Handle to duplicate. Any non-free handle target is valid.
|
||||
* @param newhandle If non-NULL, stores the duplicated handle in the pointer.
|
||||
* @param source New source of cloned handle.
|
||||
* @param owner New owner of cloned handle.
|
||||
* @param ident Security token, if needed.
|
||||
* @return A HandleError error code.
|
||||
*/
|
||||
virtual HandleError CloneHandle(Handle_t handle, Handle_t *newhandle, IdentityToken_t source, IdentityToken_t ident) =0;
|
||||
virtual HandleError CloneHandle(Handle_t handle, Handle_t *newhandle, IdentityToken_t *owner, IdentityToken_t *ident) =0;
|
||||
|
||||
/**
|
||||
* @brief Retrieves the contents of a handle.
|
||||
@ -215,7 +220,7 @@ namespace SourceMod
|
||||
* @param object Address to store object in.
|
||||
* @return HandleError error code.
|
||||
*/
|
||||
virtual HandleError ReadHandle(Handle_t handle, HandleType_t type, IdentityToken_t ident, void **object) =0;
|
||||
virtual HandleError ReadHandle(Handle_t handle, HandleType_t type, IdentityToken_t *ident, void **object) =0;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -147,7 +147,7 @@ namespace SourceMod
|
||||
/**
|
||||
* @brief Returns a plugin's identity token.
|
||||
*/
|
||||
virtual IdentityToken_t GetIdentity() =0;
|
||||
virtual IdentityToken_t *GetIdentity() =0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -3,11 +3,13 @@
|
||||
|
||||
#include <sp_vm_types.h>
|
||||
|
||||
#define DEFAULT_IDENTITY 0
|
||||
#define NO_IDENTITY 0
|
||||
|
||||
namespace SourceMod
|
||||
{
|
||||
typedef unsigned int IdentityToken_t;
|
||||
struct IdentityToken_t;
|
||||
typedef unsigned int HandleType_t;
|
||||
typedef HandleType_t IdentityType_t;
|
||||
/**
|
||||
* @brief Defines the base functionality required by a shared interface.
|
||||
*/
|
||||
@ -49,12 +51,13 @@ namespace SourceMod
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Adds an interface to the global interface system
|
||||
* @brief Adds an interface to the global interface system.
|
||||
*
|
||||
* @param iface Interface pointer (must be unique).
|
||||
* @param token Parent token of the module/interface.
|
||||
* @return True on success, false otherwise.
|
||||
*/
|
||||
virtual bool AddInterface(SMInterface *iface, IdentityToken_t token) =0;
|
||||
virtual bool AddInterface(SMInterface *iface, IdentityToken_t *token) =0;
|
||||
|
||||
/**
|
||||
* @brief Requests an interface from the global interface system.
|
||||
@ -67,8 +70,8 @@ namespace SourceMod
|
||||
*/
|
||||
virtual bool RequestInterface(const char *iface_name,
|
||||
unsigned int iface_vers,
|
||||
IdentityToken_t token,
|
||||
void **pIface) =0;
|
||||
IdentityToken_t *token,
|
||||
SMInterface **pIface) =0;
|
||||
|
||||
/**
|
||||
* @brief Adds a list of natives to the global native pool.
|
||||
@ -76,7 +79,54 @@ namespace SourceMod
|
||||
* @param token Identity token of parent object.
|
||||
* @param natives Array of natives to add, NULL terminated.
|
||||
*/
|
||||
virtual void AddNatives(IdentityToken_t token, const sp_nativeinfo_t *natives[]) =0;
|
||||
virtual void AddNatives(IdentityToken_t *token, const sp_nativeinfo_t *natives[]) =0;
|
||||
|
||||
/**
|
||||
* @brief Creates a new identity type.
|
||||
* NOTE: Module authors should never need to use this. Due to the current implementation,
|
||||
* there is a hardcoded limit of 15 types. Core uses up a few, so think carefully!
|
||||
*
|
||||
* @param name String containing type name. Must not be empty or NULL.
|
||||
* @return A new HandleType_t identifier, or 0 on failure.
|
||||
*/
|
||||
virtual IdentityType_t CreateIdentType(const char *name) =0;
|
||||
|
||||
/**
|
||||
* @brief Finds an identity type by name.
|
||||
* DEFAULT IDENTITY TYPES:
|
||||
* "PLUGIN" - An IPlugin object.
|
||||
* "MODULE" - An IModule object.
|
||||
* "CORE" - An SMGlobalClass or other singleton.
|
||||
*
|
||||
* @param name String containing type name to search for.
|
||||
* @return A HandleType_t identifier if found, 0 otherwise.
|
||||
*/
|
||||
virtual IdentityType_t FindIdentType(const char *name) =0;
|
||||
|
||||
/**
|
||||
* @brief Creates a new identity token. This token is guaranteed to be unique
|
||||
* amongst all other open identities.
|
||||
*
|
||||
* @param type Identity type.
|
||||
* @return A new IdentityToken_t identifier.
|
||||
*/
|
||||
virtual IdentityToken_t *CreateIdentity(IdentityType_t type) =0;
|
||||
|
||||
/**
|
||||
* @brief Destroys an identity type. Note that this will delete any identities
|
||||
* that are under this type.
|
||||
*
|
||||
* @param type Identity type.
|
||||
*/
|
||||
virtual void DestroyIdentType(IdentityType_t type) =0;
|
||||
|
||||
/**
|
||||
* @brief Destroys an identity token. Any handles being owned by this token, or
|
||||
* any handles being
|
||||
*
|
||||
* @param identity Identity to remove.
|
||||
*/
|
||||
virtual void DestroyIdentity(IdentityToken_t *identity) =0;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -13,6 +13,40 @@
|
||||
using namespace SourcePawn;
|
||||
using namespace SourceMod;
|
||||
|
||||
/**
|
||||
* @brief Any class deriving from this will be automatically initiated/shutdown by SourceMod
|
||||
*/
|
||||
class SMGlobalClass
|
||||
{
|
||||
friend class SourceModBase;
|
||||
public:
|
||||
SMGlobalClass();
|
||||
public:
|
||||
/**
|
||||
* @brief Called when SourceMod is initially loading
|
||||
*/
|
||||
virtual void OnSourceModStartup(bool late)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Called after all global classes have initialized
|
||||
*/
|
||||
virtual void OnSourceModAllInitialized()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Called when SourceMod is shutting down
|
||||
*/
|
||||
virtual void OnSourceModShutdown()
|
||||
{
|
||||
}
|
||||
private:
|
||||
SMGlobalClass *m_pGlobalClassNext;
|
||||
static SMGlobalClass *head;
|
||||
};
|
||||
|
||||
extern ISourcePawnEngine *g_pSourcePawn;
|
||||
extern IVirtualMachine *g_pVM;
|
||||
|
||||
|
@ -52,40 +52,6 @@ private:
|
||||
bool m_IsLateLoadInMap;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Any class deriving from this will be automatically initiated/shutdown by SourceMod
|
||||
*/
|
||||
class SMGlobalClass
|
||||
{
|
||||
friend class SourceModBase;
|
||||
public:
|
||||
SMGlobalClass();
|
||||
public:
|
||||
/**
|
||||
* @brief Called when SourceMod is initially loading
|
||||
*/
|
||||
virtual void OnSourceModStartup(bool late)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Called after all global classes have initialized
|
||||
*/
|
||||
virtual void OnSourceModAllInitialized()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Called when SourceMod is shutting down
|
||||
*/
|
||||
virtual void OnSourceModShutdown()
|
||||
{
|
||||
}
|
||||
private:
|
||||
SMGlobalClass *m_pGlobalClassNext;
|
||||
static SMGlobalClass *head;
|
||||
};
|
||||
|
||||
extern SourceModBase g_SourceMod;
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_GLOBALHEADER_H_
|
||||
|
@ -1,9 +1,22 @@
|
||||
#include "HandleSys.h"
|
||||
#include "ShareSys.h"
|
||||
#include "PluginSys.h"
|
||||
#include <assert.h>
|
||||
|
||||
HandleSystem g_HandleSys;
|
||||
|
||||
QHandle *ignore_handle;
|
||||
|
||||
inline HandleType_t TypeParent(HandleType_t type)
|
||||
{
|
||||
return (type & ~HANDLESYS_SUBTYPE_MASK);
|
||||
}
|
||||
|
||||
inline HandleError IdentityHandle(IdentityToken_t *token, unsigned int *index)
|
||||
{
|
||||
return g_HandleSys.GetHandle(token->ident, g_ShareSys.GetIdentRoot(), &ignore_handle, index, HandleAccess_Read);
|
||||
}
|
||||
|
||||
HandleSystem::HandleSystem()
|
||||
{
|
||||
m_Handles = new QHandle[HANDLESYS_MAX_HANDLES + 1];
|
||||
@ -28,18 +41,19 @@ HandleSystem::~HandleSystem()
|
||||
|
||||
HandleType_t HandleSystem::CreateType(const char *name, IHandleTypeDispatch *dispatch)
|
||||
{
|
||||
return CreateTypeEx(name, dispatch, 0, NULL);
|
||||
return CreateTypeEx(name, dispatch, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
HandleType_t HandleSystem::CreateChildType(const char *name, HandleType_t parent, IHandleTypeDispatch *dispatch)
|
||||
{
|
||||
return CreateTypeEx(name, dispatch, parent, NULL);
|
||||
return CreateTypeEx(name, dispatch, parent, NULL, NULL);
|
||||
}
|
||||
|
||||
HandleType_t HandleSystem::CreateTypeEx(const char *name,
|
||||
IHandleTypeDispatch *dispatch,
|
||||
HandleType_t parent,
|
||||
const HandleSecurity *security)
|
||||
const HandleSecurity *security,
|
||||
IdentityToken_t *ident)
|
||||
{
|
||||
if (!dispatch)
|
||||
{
|
||||
@ -56,8 +70,9 @@ HandleType_t HandleSystem::CreateTypeEx(const char *name,
|
||||
return 0;
|
||||
}
|
||||
if (parent >= HANDLESYS_TYPEARRAY_SIZE
|
||||
|| m_Types[parent].dispatch != NULL
|
||||
|| m_Types[parent].sec.access[HandleAccess_Inherit] == false)
|
||||
|| m_Types[parent].dispatch == NULL
|
||||
|| (m_Types[parent].sec.access[HandleAccess_Inherit] == false
|
||||
&& m_Types[parent].sec.owner != ident))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -163,8 +178,16 @@ bool HandleSystem::FindHandleType(const char *name, HandleType_t *type)
|
||||
HandleError HandleSystem::MakePrimHandle(HandleType_t type,
|
||||
QHandle **in_pHandle,
|
||||
unsigned int *in_index,
|
||||
Handle_t *in_handle)
|
||||
Handle_t *in_handle,
|
||||
IdentityToken_t *owner)
|
||||
{
|
||||
unsigned int owner_index = 0;
|
||||
|
||||
if (owner && (IdentityHandle(owner, &owner_index) != HandleError_None))
|
||||
{
|
||||
return HandleError_Identity;
|
||||
}
|
||||
|
||||
unsigned int handle;
|
||||
if (m_FreeHandles == 0)
|
||||
{
|
||||
@ -187,10 +210,12 @@ HandleError HandleSystem::MakePrimHandle(HandleType_t type,
|
||||
}
|
||||
|
||||
/* Set essential information */
|
||||
pHandle->set = true;
|
||||
pHandle->set = HandleSet_Used;;
|
||||
pHandle->refcount = 1;
|
||||
pHandle->type = type;
|
||||
pHandle->serial = m_HSerial;
|
||||
pHandle->owner = owner;
|
||||
pHandle->ch_next = 0;
|
||||
|
||||
/* Create the hash value */
|
||||
Handle_t hash = pHandle->serial;
|
||||
@ -205,10 +230,44 @@ HandleError HandleSystem::MakePrimHandle(HandleType_t type,
|
||||
*in_index = handle;
|
||||
*in_handle = hash;
|
||||
|
||||
/* Decode the identity token */
|
||||
if (owner)
|
||||
{
|
||||
QHandle *pIdentity = &m_Handles[owner_index];
|
||||
if (pIdentity->ch_prev == 0)
|
||||
{
|
||||
pIdentity->ch_prev = handle;
|
||||
pIdentity->ch_next = handle;
|
||||
pHandle->ch_prev = 0;
|
||||
} else {
|
||||
/* Link previous node to us (forward) */
|
||||
m_Handles[pIdentity->ch_next].ch_next = handle;
|
||||
/* Link us to previous node (backwards) */
|
||||
pHandle->ch_prev = pIdentity->ch_next;
|
||||
/* Set new tail */
|
||||
pIdentity->ch_next = handle;
|
||||
}
|
||||
pIdentity->refcount++;
|
||||
} else {
|
||||
pHandle->ch_prev = 0;
|
||||
}
|
||||
|
||||
return HandleError_None;
|
||||
}
|
||||
|
||||
Handle_t HandleSystem::CreateHandle(HandleType_t type, void *object, IdentityToken_t source, IdentityToken_t ident)
|
||||
void HandleSystem::SetTypeSecurityOwner(HandleType_t type, IdentityToken_t *pToken)
|
||||
{
|
||||
if (!type
|
||||
|| type >= HANDLESYS_TYPEARRAY_SIZE
|
||||
|| m_Types[type].dispatch == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_Types[type].sec.owner = pToken;
|
||||
}
|
||||
|
||||
Handle_t HandleSystem::CreateHandle(HandleType_t type, void *object, IdentityToken_t *source, IdentityToken_t *ident)
|
||||
{
|
||||
if (!type
|
||||
|| type >= HANDLESYS_TYPEARRAY_SIZE
|
||||
@ -230,12 +289,11 @@ Handle_t HandleSystem::CreateHandle(HandleType_t type, void *object, IdentityTok
|
||||
QHandle *pHandle;
|
||||
HandleError err;
|
||||
|
||||
if ((err=MakePrimHandle(type, &pHandle, &index, &handle)) != HandleError_None)
|
||||
if ((err=MakePrimHandle(type, &pHandle, &index, &handle, source)) != HandleError_None)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
pHandle->source = source;
|
||||
pHandle->object = object;
|
||||
pHandle->clone = 0;
|
||||
|
||||
@ -245,15 +303,35 @@ Handle_t HandleSystem::CreateHandle(HandleType_t type, void *object, IdentityTok
|
||||
Handle_t HandleSystem::CreateScriptHandle(HandleType_t type,
|
||||
void *object,
|
||||
sp_context_t *ctx,
|
||||
IdentityToken_t ident)
|
||||
IdentityToken_t *ident)
|
||||
{
|
||||
IPlugin *pPlugin = g_PluginSys.FindPluginByContext(ctx);
|
||||
|
||||
return CreateHandle(type, object, pPlugin->GetIdentity(), ident);
|
||||
}
|
||||
|
||||
bool HandleSystem::TypeCheck(HandleType_t intype, HandleType_t outtype)
|
||||
{
|
||||
/* Check the type inheritance */
|
||||
if (intype & HANDLESYS_SUBTYPE_MASK)
|
||||
{
|
||||
if (intype != outtype
|
||||
&& (TypeParent(intype) != TypeParent(outtype)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (intype != outtype)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
HandleError HandleSystem::GetHandle(Handle_t handle,
|
||||
IdentityToken_t ident,
|
||||
IdentityToken_t *ident,
|
||||
QHandle **in_pHandle,
|
||||
unsigned int *in_index,
|
||||
HandleAccessRight access)
|
||||
@ -277,6 +355,11 @@ HandleError HandleSystem::GetHandle(Handle_t handle,
|
||||
if (!pHandle->set)
|
||||
{
|
||||
return HandleError_Freed;
|
||||
} else if (pHandle->set == HandleSet_Identity
|
||||
&& ident != g_ShareSys.GetIdentRoot())
|
||||
{
|
||||
/* Only IdentityHandle() can read this! */
|
||||
return HandleError_Identity;
|
||||
}
|
||||
if (pHandle->serial != serial)
|
||||
{
|
||||
@ -289,7 +372,7 @@ HandleError HandleSystem::GetHandle(Handle_t handle,
|
||||
return HandleError_None;
|
||||
}
|
||||
|
||||
HandleError HandleSystem::CloneHandle(Handle_t handle, Handle_t *out_newhandle, IdentityToken_t source, IdentityToken_t ident)
|
||||
HandleError HandleSystem::CloneHandle(Handle_t handle, Handle_t *out_newhandle, IdentityToken_t *source, IdentityToken_t *ident)
|
||||
{
|
||||
HandleError err;
|
||||
QHandle *pHandle;
|
||||
@ -307,13 +390,12 @@ HandleError HandleSystem::CloneHandle(Handle_t handle, Handle_t *out_newhandle,
|
||||
QHandle *pNewHandle;
|
||||
Handle_t new_handle;
|
||||
|
||||
if ((err=MakePrimHandle(pHandle->type, &pNewHandle, &new_index, &new_handle)) != HandleError_None)
|
||||
if ((err=MakePrimHandle(pHandle->type, &pNewHandle, &new_index, &new_handle, source)) != HandleError_None)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
pNewHandle->clone = index;
|
||||
pNewHandle->source = source;
|
||||
|
||||
if (out_newhandle)
|
||||
{
|
||||
@ -323,7 +405,7 @@ HandleError HandleSystem::CloneHandle(Handle_t handle, Handle_t *out_newhandle,
|
||||
return HandleError_None;
|
||||
}
|
||||
|
||||
HandleError HandleSystem::FreeHandle(Handle_t handle, IdentityToken_t ident)
|
||||
HandleError HandleSystem::FreeHandle(Handle_t handle, IdentityToken_t *ident)
|
||||
{
|
||||
unsigned int index;
|
||||
QHandle *pHandle;
|
||||
@ -361,14 +443,9 @@ HandleError HandleSystem::FreeHandle(Handle_t handle, IdentityToken_t ident)
|
||||
return HandleError_None;
|
||||
}
|
||||
|
||||
inline HandleType_t TypeParent(HandleType_t type)
|
||||
{
|
||||
return (type & ~HANDLESYS_SUBTYPE_MASK);
|
||||
}
|
||||
|
||||
HandleError HandleSystem::ReadHandle(Handle_t handle,
|
||||
HandleType_t type,
|
||||
IdentityToken_t ident,
|
||||
IdentityToken_t *ident,
|
||||
void **object)
|
||||
{
|
||||
unsigned int index;
|
||||
@ -412,12 +489,59 @@ void HandleSystem::ReleasePrimHandle(unsigned int index)
|
||||
{
|
||||
QHandle *pHandle = &m_Handles[index];
|
||||
|
||||
pHandle->set = false;
|
||||
pHandle->set = HandleSet_None;
|
||||
m_Types[pHandle->type].opened--;
|
||||
m_Handles[++m_FreeHandles].freeID = index;
|
||||
|
||||
/* Unlink us if necessary */
|
||||
if (pHandle->owner)
|
||||
{
|
||||
unsigned int ident_index;
|
||||
if (IdentityHandle(pHandle->owner, &ident_index) != HandleError_None)
|
||||
{
|
||||
/* Uh-oh! */
|
||||
assert(pHandle->owner == 0);
|
||||
return;
|
||||
}
|
||||
/* Note that since 0 is an invalid handle, if any of these links are 0,
|
||||
* the data can still be set.
|
||||
*/
|
||||
QHandle *pIdentity = &m_Handles[ident_index];
|
||||
|
||||
/* Unlink case: We're the head AND tail node */
|
||||
if (index == pIdentity->ch_prev && index == pIdentity->ch_next)
|
||||
{
|
||||
pIdentity->ch_prev = 0;
|
||||
pIdentity->ch_next = 0;
|
||||
}
|
||||
/* Unlink case: We're the head node */
|
||||
else if (index == pIdentity->ch_prev) {
|
||||
/* Link us to the next in the chain */
|
||||
pIdentity->ch_prev = pHandle->ch_next;
|
||||
/* Patch up the previous link */
|
||||
m_Handles[pHandle->ch_next].ch_prev = 0;
|
||||
}
|
||||
/* Unlink case: We're the tail node */
|
||||
else if (index == pIdentity->ch_next) {
|
||||
/* Link us to the previous in the chain */
|
||||
pIdentity->ch_next = pHandle->ch_prev;
|
||||
/* Patch up the next link */
|
||||
m_Handles[pHandle->ch_prev].ch_next = 0;
|
||||
}
|
||||
/* Unlink case: We're in the middle! */
|
||||
else {
|
||||
/* Patch the forward reference */
|
||||
m_Handles[pHandle->ch_next].ch_prev = pHandle->ch_prev;
|
||||
/* Patch the backward reference */
|
||||
m_Handles[pHandle->ch_prev].ch_next = pHandle->ch_next;
|
||||
}
|
||||
|
||||
/* Lastly, decrease the reference count */
|
||||
pIdentity->refcount--;
|
||||
}
|
||||
}
|
||||
|
||||
bool HandleSystem::RemoveType(HandleType_t type, IdentityToken_t ident)
|
||||
bool HandleSystem::RemoveType(HandleType_t type, IdentityToken_t *ident)
|
||||
{
|
||||
if (type == 0 || type >= HANDLESYS_TYPEARRAY_SIZE)
|
||||
{
|
||||
@ -499,3 +623,16 @@ bool HandleSystem::RemoveType(HandleType_t type, IdentityToken_t ident)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleSystem::MarkHandleAsIdentity(Handle_t handle)
|
||||
{
|
||||
QHandle *pHandle;
|
||||
unsigned int index;
|
||||
|
||||
if (GetHandle(handle, g_ShareSys.GetIdentRoot(), &pHandle, &index, HandleAccess_Read) != HandleError_None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pHandle->set = HandleSet_Identity;
|
||||
}
|
||||
|
@ -16,16 +16,46 @@
|
||||
#define HANDLESYS_SERIAL_MASK 0xFFFF0000
|
||||
#define HANDLESYS_HANDLE_MASK 0x0000FFFF
|
||||
|
||||
/**
|
||||
* The QHandle is a nasty structure that compacts the handle system into a big vector.
|
||||
* The members of the vector each encapsulate one Handle, however, they also act as nodes
|
||||
* in an inlined linked list and an inlined vector.
|
||||
*
|
||||
* The first of these lists is the 'freeID' list. Each node from 1 to N (where N
|
||||
* is the number of free nodes) has a 'freeID' that specifies a free Handle ID. This
|
||||
* is a quick hack to get around allocating a second base vector.
|
||||
*
|
||||
* The second vector is the identity linked list. An identity has its own handle, so
|
||||
* these handles are used as sentinel nodes for index linking. They point to the first and last
|
||||
* index into the handle array. Each subsequent Handle who is owned by that indentity is mapped into
|
||||
* that list. This lets owning identities be unloaded in O(n) time.
|
||||
*
|
||||
* Eventually, there may be a third list for type chains.
|
||||
*/
|
||||
|
||||
enum HandleSet
|
||||
{
|
||||
HandleSet_None = 0,
|
||||
HandleSet_Used,
|
||||
HandleSet_Identity
|
||||
};
|
||||
|
||||
struct QHandle
|
||||
{
|
||||
HandleType_t type; /* Handle type */
|
||||
void *object; /* Unmaintained object pointer */
|
||||
unsigned int freeID; /* ID of a free handle in the free handle chain */
|
||||
IdentityToken_t source; /* Identity of object which owns this */
|
||||
IdentityToken_t *owner; /* Identity of object which owns this */
|
||||
unsigned int serial; /* Serial no. for sanity checking */
|
||||
unsigned int refcount; /* Reference count for safe destruction */
|
||||
Handle_t clone; /* If non-zero, this is our cloned parent */
|
||||
bool set; /* Whether or not this handle is set */
|
||||
HandleSet set; /* Information about the handle's state */
|
||||
/* The following variables are unrelated to the Handle array, and used
|
||||
* as an inlined chain of information */
|
||||
unsigned int freeID; /* ID of a free handle in the free handle chain */
|
||||
/* Indexes into the handle array for owner membership.
|
||||
* For identity roots, these are treated as the head/tail. */
|
||||
unsigned int ch_prev; /* chained previous handle or HEAD */
|
||||
unsigned int ch_next; /* chained next handle or TAIL */
|
||||
};
|
||||
|
||||
struct QHandleType
|
||||
@ -41,6 +71,8 @@ struct QHandleType
|
||||
class HandleSystem :
|
||||
public IHandleSys
|
||||
{
|
||||
friend HandleError IdentityHandle(IdentityToken_t *token, unsigned int *index);
|
||||
friend class ShareSystem;
|
||||
public:
|
||||
HandleSystem();
|
||||
~HandleSystem();
|
||||
@ -49,24 +81,26 @@ public: //IHandleSystem
|
||||
HandleType_t CreateTypeEx(const char *name,
|
||||
IHandleTypeDispatch *dispatch,
|
||||
HandleType_t parent,
|
||||
const HandleSecurity *security);
|
||||
const HandleSecurity *security,
|
||||
IdentityToken_t *ident);
|
||||
HandleType_t CreateChildType(const char *name, HandleType_t parent, IHandleTypeDispatch *dispatch);
|
||||
bool RemoveType(HandleType_t type, IdentityToken_t ident);
|
||||
bool RemoveType(HandleType_t type, IdentityToken_t *ident);
|
||||
bool FindHandleType(const char *name, HandleType_t *type);
|
||||
Handle_t CreateHandle(HandleType_t type,
|
||||
void *object,
|
||||
IdentityToken_t source,
|
||||
IdentityToken_t ident);
|
||||
Handle_t CreateScriptHandle(HandleType_t type, void *object, sp_context_t *ctx, IdentityToken_t ident);
|
||||
HandleError FreeHandle(Handle_t handle, IdentityToken_t ident);
|
||||
HandleError CloneHandle(Handle_t handle, Handle_t *newhandle, IdentityToken_t source, IdentityToken_t ident);
|
||||
HandleError ReadHandle(Handle_t handle, HandleType_t type, IdentityToken_t ident, void **object);
|
||||
private:
|
||||
IdentityToken_t *source,
|
||||
IdentityToken_t *ident);
|
||||
Handle_t CreateScriptHandle(HandleType_t type, void *object, sp_context_t *ctx, IdentityToken_t *ident);
|
||||
HandleError FreeHandle(Handle_t handle, IdentityToken_t *ident);
|
||||
HandleError CloneHandle(Handle_t handle, Handle_t *newhandle, IdentityToken_t *source, IdentityToken_t *ident);
|
||||
HandleError ReadHandle(Handle_t handle, HandleType_t type, IdentityToken_t *ident, void **object);
|
||||
bool TypeCheck(HandleType_t intype, HandleType_t outtype);
|
||||
protected:
|
||||
/**
|
||||
* Decodes a handle with sanity and security checking.
|
||||
*/
|
||||
HandleError GetHandle(Handle_t handle,
|
||||
IdentityToken_t ident,
|
||||
IdentityToken_t *ident,
|
||||
QHandle **pHandle,
|
||||
unsigned int *index,
|
||||
HandleAccessRight access);
|
||||
@ -75,12 +109,28 @@ private:
|
||||
* Creates a basic handle and sets its reference count to 1.
|
||||
* Does not do any type or security checking.
|
||||
*/
|
||||
HandleError MakePrimHandle(HandleType_t type, QHandle **pHandle, unsigned int *index, HandleType_t *handle);
|
||||
HandleError MakePrimHandle(HandleType_t type,
|
||||
QHandle **pHandle,
|
||||
unsigned int *index,
|
||||
HandleType_t *handle,
|
||||
IdentityToken_t *owner);
|
||||
|
||||
/**
|
||||
* Frees a primitive handle. Does no object freeing, only reference count and bookkeepping.
|
||||
* Frees a primitive handle. Does no object freeing, only reference count, bookkeepping,
|
||||
* and linked list maintenance.
|
||||
*/
|
||||
void ReleasePrimHandle(unsigned int index);
|
||||
|
||||
/**
|
||||
* Sets the security owner of a type
|
||||
*/
|
||||
void SetTypeSecurityOwner(HandleType_t type, IdentityToken_t *pToken);
|
||||
|
||||
/**
|
||||
* Marks a handle as an identity.
|
||||
* This prevents it from being tampered with by outside stuff
|
||||
*/
|
||||
void MarkHandleAsIdentity(Handle_t handle);
|
||||
private:
|
||||
QHandle *m_Handles;
|
||||
QHandleType *m_Types;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include "PluginSys.h"
|
||||
#include "ShareSys.h"
|
||||
#include "LibrarySys.h"
|
||||
#include "HandleSys.h"
|
||||
#include "sourcemm_api.h"
|
||||
@ -8,6 +9,7 @@
|
||||
|
||||
CPluginManager g_PluginSys;
|
||||
HandleType_t g_PluginType = 0;
|
||||
IdentityType_t g_PluginIdent = 0;
|
||||
|
||||
CPlugin::CPlugin(const char *file)
|
||||
{
|
||||
@ -22,8 +24,8 @@ CPlugin::CPlugin(const char *file)
|
||||
m_pub_funcs = NULL;
|
||||
m_errormsg[256] = '\0';
|
||||
snprintf(m_filename, sizeof(m_filename), "%s", file);
|
||||
/* :TODO: ShareSys token */
|
||||
m_handle = g_HandleSys.CreateHandle(g_PluginType, this, DEFAULT_IDENTITY, 1);
|
||||
m_handle = 0;
|
||||
m_ident = NULL;
|
||||
}
|
||||
|
||||
CPlugin::~CPlugin()
|
||||
@ -70,7 +72,20 @@ CPlugin::~CPlugin()
|
||||
m_plugin = NULL;
|
||||
}
|
||||
|
||||
g_HandleSys.FreeHandle(m_handle, g_PluginType);
|
||||
if (m_handle)
|
||||
{
|
||||
g_HandleSys.FreeHandle(m_handle, g_PluginSys.GetIdentity());
|
||||
g_ShareSys.DestroyIdentity(m_ident);
|
||||
}
|
||||
}
|
||||
|
||||
void CPlugin::InitIdentity()
|
||||
{
|
||||
if (!m_handle)
|
||||
{
|
||||
m_ident = g_ShareSys.CreateIdentity(g_PluginIdent);
|
||||
m_handle = g_HandleSys.CreateHandle(g_PluginType, this, g_PluginSys.GetIdentity(), g_PluginSys.GetIdentity());
|
||||
}
|
||||
}
|
||||
|
||||
CPlugin *CPlugin::CreatePlugin(const char *file, char *error, size_t maxlength)
|
||||
@ -447,9 +462,9 @@ bool CPlugin::SetPauseState(bool paused)
|
||||
return true;
|
||||
}
|
||||
|
||||
IdentityToken_t CPlugin::GetIdentity()
|
||||
IdentityToken_t *CPlugin::GetIdentity()
|
||||
{
|
||||
return 0;
|
||||
return m_ident;
|
||||
}
|
||||
|
||||
/*******************
|
||||
@ -499,6 +514,7 @@ CPluginManager::CPluginManager()
|
||||
{
|
||||
m_LoadLookup = sm_trie_create();
|
||||
m_AllPluginsLoaded = false;
|
||||
m_MyIdent = NULL;
|
||||
}
|
||||
|
||||
CPluginManager::~CPluginManager()
|
||||
@ -661,6 +677,7 @@ void CPluginManager::LoadAutoPlugin(const char *file)
|
||||
if (pPlugin->GetStatus() == Plugin_Created)
|
||||
{
|
||||
AddCoreNativesToPlugin(pPlugin);
|
||||
pPlugin->InitIdentity();
|
||||
pPlugin->Call_AskPluginLoad(NULL, 0);
|
||||
}
|
||||
|
||||
@ -712,6 +729,8 @@ IPlugin *CPluginManager::LoadPlugin(const char *path, bool debug, PluginType typ
|
||||
|
||||
AddCoreNativesToPlugin(pPlugin);
|
||||
|
||||
pPlugin->InitIdentity();
|
||||
|
||||
/* Finally, ask the plugin if it wants to be loaded */
|
||||
if (!pPlugin->Call_AskPluginLoad(error, err_max))
|
||||
{
|
||||
@ -1092,20 +1111,25 @@ bool CPluginManager::IsLateLoadTime()
|
||||
|
||||
void CPluginManager::OnSourceModAllInitialized()
|
||||
{
|
||||
m_MyIdent = g_ShareSys.CreateCoreIdentity();
|
||||
|
||||
HandleSecurity sec;
|
||||
|
||||
sec.owner = 1; /* :TODO: implement ShareSys */
|
||||
sec.owner = m_MyIdent; /* :TODO: implement ShareSys */
|
||||
sec.access[HandleAccess_Create] = false;
|
||||
sec.access[HandleAccess_Delete] = false;
|
||||
sec.access[HandleAccess_Inherit] = false;
|
||||
sec.access[HandleAccess_Clone] = false;
|
||||
|
||||
g_PluginType = g_HandleSys.CreateTypeEx("IPlugin", this, 0, &sec);
|
||||
g_PluginType = g_HandleSys.CreateTypeEx("IPlugin", this, 0, &sec, NULL);
|
||||
g_PluginIdent = g_ShareSys.CreateIdentType("PLUGIN");
|
||||
}
|
||||
|
||||
void CPluginManager::OnSourceModShutdown()
|
||||
{
|
||||
g_HandleSys.RemoveType(g_PluginType, 1);
|
||||
g_HandleSys.RemoveType(g_PluginType, m_MyIdent);
|
||||
g_ShareSys.DestroyIdentType(g_PluginIdent);
|
||||
g_ShareSys.DestroyIdentity(m_MyIdent);
|
||||
}
|
||||
|
||||
void CPluginManager::OnHandleDestroy(HandleType_t type, void *object)
|
||||
|
@ -93,7 +93,7 @@ public:
|
||||
virtual const sp_plugin_t *GetPluginStructure() const;
|
||||
virtual IPluginFunction *GetFunctionByName(const char *public_name);
|
||||
virtual IPluginFunction *GetFunctionById(funcid_t func_id);
|
||||
virtual IdentityToken_t GetIdentity();
|
||||
virtual IdentityToken_t *GetIdentity();
|
||||
public:
|
||||
/**
|
||||
* Creates a plugin object with default values.
|
||||
@ -114,11 +114,17 @@ public:
|
||||
*/
|
||||
bool FinishMyCompile(char *error, size_t maxlength);
|
||||
void CancelMyCompile();
|
||||
|
||||
/**
|
||||
* Sets an error state on the plugin
|
||||
*/
|
||||
void SetErrorState(PluginStatus status, const char *error_fmt, ...);
|
||||
|
||||
/**
|
||||
* Initializes the plugin's identity information
|
||||
*/
|
||||
void InitIdentity();
|
||||
|
||||
/**
|
||||
* Calls the OnPluginLoad function, and sets any failed states if necessary.
|
||||
* NOTE: Valid pre-states are: Plugin_Created
|
||||
@ -151,6 +157,7 @@ private:
|
||||
CFunction **m_pub_funcs;
|
||||
char m_errormsg[256];
|
||||
time_t m_LastAccess;
|
||||
IdentityToken_t *m_ident;
|
||||
Handle_t m_handle;
|
||||
};
|
||||
|
||||
@ -262,6 +269,10 @@ protected:
|
||||
void ReleaseIterator(CPluginIterator *iter);
|
||||
CFunction *GetFunctionFromPool(funcid_t f, CPlugin *plugin);
|
||||
void ReleaseFunctionToPool(CFunction *func);
|
||||
inline IdentityToken_t *GetIdentity()
|
||||
{
|
||||
return m_MyIdent;
|
||||
}
|
||||
private:
|
||||
List<IPluginsListener *> m_listeners;
|
||||
List<CPlugin *> m_plugins;
|
||||
@ -271,6 +282,7 @@ private:
|
||||
CPluginInfoDatabase m_PluginInfo;
|
||||
Trie *m_LoadLookup;
|
||||
bool m_AllPluginsLoaded;
|
||||
IdentityToken_t *m_MyIdent;
|
||||
};
|
||||
|
||||
extern CPluginManager g_PluginSys;
|
||||
|
195
core/systems/ShareSys.cpp
Normal file
195
core/systems/ShareSys.cpp
Normal file
@ -0,0 +1,195 @@
|
||||
#include "ShareSys.h"
|
||||
#include "HandleSys.h"
|
||||
|
||||
ShareSystem g_ShareSys;
|
||||
|
||||
ShareSystem::ShareSystem()
|
||||
{
|
||||
m_IdentRoot.ident = 0;
|
||||
m_TypeRoot = 0;
|
||||
m_IfaceType = 0;
|
||||
m_CoreType = 0;
|
||||
}
|
||||
|
||||
IdentityToken_t *ShareSystem::CreateCoreIdentity()
|
||||
{
|
||||
if (!m_CoreType)
|
||||
{
|
||||
m_CoreType = CreateIdentType("CORE");
|
||||
}
|
||||
|
||||
return CreateIdentity(m_CoreType);
|
||||
}
|
||||
|
||||
void ShareSystem::OnSourceModStartup(bool late)
|
||||
{
|
||||
HandleSecurity sec;
|
||||
|
||||
sec.owner = GetIdentRoot();
|
||||
sec.access[HandleAccess_Inherit] = false;
|
||||
sec.access[HandleAccess_Delete] = false;
|
||||
|
||||
m_TypeRoot = g_HandleSys.CreateTypeEx("Identity", this, 0, &sec, NULL);
|
||||
m_IfaceType = g_HandleSys.CreateTypeEx("Interface", this, 0, &sec, NULL);
|
||||
|
||||
/* Initialize our static identity handle */
|
||||
m_IdentRoot.ident = g_HandleSys.CreateHandle(m_TypeRoot, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void ShareSystem::OnSourceModShutdown()
|
||||
{
|
||||
if (m_CoreType)
|
||||
{
|
||||
g_HandleSys.RemoveType(m_CoreType, GetIdentRoot());
|
||||
}
|
||||
|
||||
g_HandleSys.RemoveType(m_IfaceType, GetIdentRoot());
|
||||
g_HandleSys.RemoveType(m_TypeRoot, GetIdentRoot());
|
||||
}
|
||||
|
||||
IdentityType_t ShareSystem::FindIdentType(const char *name)
|
||||
{
|
||||
HandleType_t type;
|
||||
|
||||
if (g_HandleSys.FindHandleType(name, &type))
|
||||
{
|
||||
if (g_HandleSys.TypeCheck(type, m_TypeRoot))
|
||||
{
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
IdentityType_t ShareSystem::CreateIdentType(const char *name)
|
||||
{
|
||||
if (!m_TypeRoot)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return g_HandleSys.CreateTypeEx(name, this, m_TypeRoot, NULL, GetIdentRoot());
|
||||
}
|
||||
|
||||
void ShareSystem::OnHandleDestroy(HandleType_t type, void *object)
|
||||
{
|
||||
/* We don't care here */
|
||||
}
|
||||
|
||||
IdentityToken_t *ShareSystem::CreateIdentity(IdentityType_t type)
|
||||
{
|
||||
if (!m_TypeRoot)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* :TODO: Cache? */
|
||||
IdentityToken_t *pToken = new IdentityToken_t;
|
||||
pToken->ident = g_HandleSys.CreateHandle(type, NULL, NULL, GetIdentRoot());
|
||||
|
||||
return pToken;
|
||||
}
|
||||
|
||||
bool ShareSystem::AddInterface(SMInterface *iface, IdentityToken_t *token)
|
||||
{
|
||||
if (!iface)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
IfaceInfo info;
|
||||
|
||||
info.iface = iface;
|
||||
info.token = token;
|
||||
|
||||
if (token)
|
||||
{
|
||||
/* If we're an external object, we have to do this */
|
||||
info.handle = g_HandleSys.CreateHandle(m_IfaceType, iface, token, GetIdentRoot());
|
||||
} else {
|
||||
info.handle = 0;
|
||||
}
|
||||
|
||||
m_Interfaces.push_back(info);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ShareSystem::RequestInterface(const char *iface_name,
|
||||
unsigned int iface_vers,
|
||||
IdentityToken_t *token,
|
||||
SMInterface **pIface)
|
||||
{
|
||||
/* If Some yahoo.... SOME HOOLIGAN... some NO GOOD DIRTY
|
||||
* HORRIBLE PERSON passed in a token that we don't recognize....
|
||||
* <b>Punish them.</b>
|
||||
*/
|
||||
if (!g_HandleSys.ReadHandle(token->ident, m_TypeRoot, GetIdentRoot(), NULL))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* See if the interface exists */
|
||||
List<IfaceInfo>::iterator iter;
|
||||
SMInterface *iface;
|
||||
IdentityToken_t *iface_owner;
|
||||
Handle_t iface_handle;
|
||||
bool found = false;
|
||||
for (iter=m_Interfaces.begin(); iter!=m_Interfaces.end(); iter++)
|
||||
{
|
||||
IfaceInfo &info = (*iter);
|
||||
iface = info.iface;
|
||||
if (strcmp(iface->GetInterfaceName(), iface_name) == 0)
|
||||
{
|
||||
if (iface->GetInterfaceVersion() == iface_vers
|
||||
|| iface->IsVersionCompatible(iface_vers))
|
||||
{
|
||||
iface_owner = info.token;
|
||||
iface_handle = info.handle;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If something external owns this, we need to track it. */
|
||||
if (iface_owner)
|
||||
{
|
||||
Handle_t newhandle;
|
||||
if (g_HandleSys.CloneHandle(iface_handle, &newhandle, token, GetIdentRoot())
|
||||
!= HandleError_None)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Now we can deny module loads based on dependencies.
|
||||
*/
|
||||
}
|
||||
|
||||
/* :TODO: finish */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ShareSystem::AddNatives(IdentityToken_t *token, const sp_nativeinfo_t *natives[])
|
||||
{
|
||||
/* :TODO: implement */
|
||||
}
|
||||
|
||||
void ShareSystem::DestroyIdentity(IdentityToken_t *identity)
|
||||
{
|
||||
g_HandleSys.FreeHandle(identity->ident, GetIdentRoot());
|
||||
delete identity;
|
||||
}
|
||||
|
||||
void ShareSystem::DestroyIdentType(IdentityType_t type)
|
||||
{
|
||||
g_HandleSys.RemoveType(type, GetIdentRoot());
|
||||
}
|
||||
|
69
core/systems/ShareSys.h
Normal file
69
core/systems/ShareSys.h
Normal file
@ -0,0 +1,69 @@
|
||||
#ifndef _INCLUDE_SOURCEMOD_SHARESYSTEM_H_
|
||||
#define _INCLUDE_SOURCEMOD_SHARESYSTEM_H_
|
||||
|
||||
#include <IShareSys.h>
|
||||
#include <IHandleSys.h>
|
||||
#include <sh_list.h>
|
||||
#include "sm_globals.h"
|
||||
#include "sourcemod.h"
|
||||
|
||||
using namespace SourceHook;
|
||||
|
||||
namespace SourceMod
|
||||
{
|
||||
struct IdentityToken_t
|
||||
{
|
||||
Handle_t ident;
|
||||
};
|
||||
};
|
||||
|
||||
struct IfaceInfo
|
||||
{
|
||||
SMInterface *iface;
|
||||
IdentityToken_t *token;
|
||||
Handle_t handle;
|
||||
};
|
||||
|
||||
class ShareSystem :
|
||||
public IShareSys,
|
||||
public SMGlobalClass,
|
||||
public IHandleTypeDispatch
|
||||
{
|
||||
public:
|
||||
ShareSystem();
|
||||
public: //IShareSys
|
||||
bool AddInterface(SMInterface *iface, IdentityToken_t *token);
|
||||
bool RequestInterface(const char *iface_name,
|
||||
unsigned int iface_vers,
|
||||
IdentityToken_t *token,
|
||||
SMInterface **pIface);
|
||||
void AddNatives(IdentityToken_t *token, const sp_nativeinfo_t *natives[]);
|
||||
IdentityType_t CreateIdentType(const char *name);
|
||||
IdentityType_t FindIdentType(const char *name);
|
||||
IdentityToken_t *CreateIdentity(IdentityType_t type);
|
||||
void DestroyIdentType(IdentityType_t type);
|
||||
void DestroyIdentity(IdentityToken_t *identity);
|
||||
public: //SMGlobalClass
|
||||
/* Pre-empt in case anything tries to register idents early */
|
||||
void OnSourceModStartup(bool late);
|
||||
void OnSourceModShutdown();
|
||||
public: //IHandleTypeDispatch
|
||||
void OnHandleDestroy(HandleType_t type, void *object);
|
||||
public:
|
||||
IdentityToken_t *CreateCoreIdentity();
|
||||
public:
|
||||
inline IdentityToken_t *GetIdentRoot()
|
||||
{
|
||||
return &m_IdentRoot;
|
||||
}
|
||||
private:
|
||||
List<IfaceInfo> m_Interfaces;
|
||||
HandleType_t m_TypeRoot;
|
||||
IdentityToken_t m_IdentRoot;
|
||||
HandleType_t m_IfaceType;
|
||||
IdentityType_t m_CoreType;
|
||||
};
|
||||
|
||||
extern ShareSystem g_ShareSys;
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_SHARESYSTEM_H_
|
Loading…
Reference in New Issue
Block a user