sourcemod/core/systems/HandleSys.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

226 lines
7.9 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_HANDLESYSTEM_H_
#define _INCLUDE_SOURCEMOD_HANDLESYSTEM_H_
#include <IHandleSys.h>
#include <stdio.h>
#include "sm_globals.h"
#include "sm_trie.h"
#include "sourcemod.h"
#include "sm_memtable.h"
#define HANDLESYS_MAX_HANDLES (1<<14)
#define HANDLESYS_MAX_TYPES (1<<9)
#define HANDLESYS_MAX_SUBTYPES 0xF
#define HANDLESYS_SUBTYPE_MASK 0xF
#define HANDLESYS_TYPEARRAY_SIZE (HANDLESYS_MAX_TYPES * (HANDLESYS_MAX_SUBTYPES + 1))
#define HANDLESYS_MAX_SERIALS 0xFFFF
#define HANDLESYS_SERIAL_MASK 0xFFFF0000
#define HANDLESYS_HANDLE_MASK 0x0000FFFF
#define HANDLESYS_MEMUSAGE_MIN_VERSION 3
/**
* 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 identity 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, /* The Handle is in use */
HandleSet_Freed, /* The "master" Handle of a clone chain is freed */
HandleSet_Identity, /* The Handle is a special identity */
};
struct QHandle
{
HandleType_t type; /* Handle type */
void *object; /* Unmaintained object pointer */
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 */
unsigned int clone; /* If non-zero, this is our cloned parent index */
HandleSet set; /* Information about the handle's state */
bool access_special; /* Whether or not access rules are special or type-derived */
bool is_destroying; /* Whether or not the handle is being destroyed */
HandleAccess sec; /* Security rules */
/* 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 */
unsigned int ch_next; /* chained next handle */
};
struct QHandleType
{
IHandleTypeDispatch *dispatch;
unsigned int freeID;
unsigned int children;
TypeAccess typeSec;
HandleAccess hndlSec;
unsigned int opened;
int nameIdx;
};
typedef void (HANDLE_REPORTER)(const char *str, ...);
class HandleSystem :
public IHandleSys
{
friend HandleError IdentityHandle(IdentityToken_t *token, unsigned int *index);
friend class ShareSystem;
public:
HandleSystem();
~HandleSystem();
public: //IHandleSystem
HandleType_t CreateType(const char *name,
IHandleTypeDispatch *dispatch,
HandleType_t parent,
const TypeAccess *typeAccess,
const HandleAccess *hndlAccess,
IdentityToken_t *ident,
HandleError *err);
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 *owner,
IdentityToken_t *ident,
HandleError *err);
HandleError FreeHandle(Handle_t handle, const HandleSecurity *pSecurity);
HandleError CloneHandle(Handle_t handle,
Handle_t *newhandle,
IdentityToken_t *newOwner,
const HandleSecurity *pSecurity);
HandleError ReadHandle(Handle_t handle,
HandleType_t type,
const HandleSecurity *pSecurity,
void **object);
bool InitAccessDefaults(TypeAccess *pTypeAccess, HandleAccess *pHandleAccess);
bool TypeCheck(HandleType_t intype, HandleType_t outtype);
virtual Handle_t CreateHandleEx(HandleType_t type,
void *object,
const HandleSecurity *pSec,
const HandleAccess *pAccess,
HandleError *err);
void Dump(HANDLE_REPORTER rep);
protected:
/**
* Decodes a handle with sanity and security checking.
*/
HandleError GetHandle(Handle_t handle,
IdentityToken_t *ident,
QHandle **pHandle,
unsigned int *index,
bool ignoreFree=false);
/**
* 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,
IdentityToken_t *owner,
bool identity=false);
/**
* Frees a primitive handle. Does no object freeing, only reference count, bookkeeping,
* and linked list maintenance.
* If used on an Identity handle, destroys all Handles under that identity.
*/
void ReleasePrimHandle(unsigned int index);
/**
* Sets the security owner of a type.
*/
void SetTypeSecurityOwner(HandleType_t type, IdentityToken_t *pToken);
/**
* Helper function to check access rights.
*/
bool CheckAccess(QHandle *pHandle, HandleAccessRight right, const HandleSecurity *pSecurity);
/**
* Some wrappers for internal functions, so we can pass indexes instead of encoded handles.
*/
HandleError FreeHandle(QHandle *pHandle, unsigned int index);
void UnlinkHandleFromOwner(QHandle *pHandle, unsigned int index);
HandleError CloneHandle(QHandle *pHandle, unsigned int index, Handle_t *newhandle, IdentityToken_t *newOwner);
Handle_t CreateHandleInt(HandleType_t type, void *object, const HandleSecurity *pSec, HandleError *err, const HandleAccess *pAccess, bool identity);
bool TryAndFreeSomeHandles();
HandleError TryAllocHandle(unsigned int *handle);
private:
QHandle *m_Handles;
QHandleType *m_Types;
Trie *m_TypeLookup;
unsigned int m_TypeTail;
unsigned int m_FreeTypes;
unsigned int m_HandleTail;
unsigned int m_FreeHandles;
unsigned int m_HSerial;
BaseStringTable *m_strtab;
};
extern HandleSystem g_HandleSys;
#endif //_INCLUDE_SOURCEMOD_HANDLESYSTEM_H_