diff -r e28a9247061f -r 9ac720a36ce4 core/systems/ShareSys.cpp
--- a/core/systems/ShareSys.cpp Wed Nov 19 02:14:43 2008 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,529 +0,0 @@
-/**
- * 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 .
- *
- * 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 .
- *
- * Version: $Id$
- */
-
-#include "ShareSys.h"
-#include "HandleSys.h"
-#include "ExtensionSys.h"
-#include "LibrarySys.h"
-#include "PluginSys.h"
-#include "sm_stringutil.h"
-
-ShareSystem g_ShareSys;
-static unsigned int g_mark_serial = 0;
-
-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, this);
-}
-
-void ShareSystem::Initialize()
-{
- TypeAccess sec;
-
- g_HandleSys.InitAccessDefaults(&sec, NULL);
- sec.ident = GetIdentRoot();
-
- m_TypeRoot = g_HandleSys.CreateType("Identity", this, 0, &sec, NULL, NULL, NULL);
- m_IfaceType = g_HandleSys.CreateType("Interface", this, 0, NULL, NULL, GetIdentRoot(), NULL);
-
- /* Initialize our static identity handle */
- m_IdentRoot.ident = g_HandleSys.CreateHandle(m_TypeRoot, NULL, NULL, GetIdentRoot(), NULL);
-
- /* Add the Handle System and others... they are too innocent and pure to do it themselves */
- AddInterface(NULL, &g_HandleSys);
- AddInterface(NULL, &g_LibSys);
-}
-
-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.CreateType(name, this, m_TypeRoot, NULL, NULL, GetIdentRoot(), NULL);
-}
-
-void ShareSystem::OnHandleDestroy(HandleType_t type, void *object)
-{
- /* THIS WILL NEVER BE CALLED FOR ANYTHING WITH THE IDENTITY TYPE */
-}
-
-IdentityToken_t *ShareSystem::CreateIdentity(IdentityType_t type, void *ptr)
-{
- if (!m_TypeRoot)
- {
- return 0;
- }
-
- /* :TODO: Cache? */
- IdentityToken_t *pToken = new IdentityToken_t;
-
- HandleSecurity sec;
- sec.pOwner = sec.pIdentity = GetIdentRoot();
-
- pToken->ident = g_HandleSys.CreateHandleInt(type, NULL, &sec, NULL, NULL, true);
- pToken->ptr = ptr;
- pToken->type = type;
-
- return pToken;
-}
-
-bool ShareSystem::AddInterface(IExtension *myself, SMInterface *iface)
-{
- if (!iface)
- {
- return false;
- }
-
- IfaceInfo info;
-
- info.owner = myself;
- info.iface = iface;
-
- m_Interfaces.push_back(info);
-
- return true;
-}
-
-bool ShareSystem::RequestInterface(const char *iface_name,
- unsigned int iface_vers,
- IExtension *myself,
- SMInterface **pIface)
-{
- /* See if the interface exists */
- List::iterator iter;
- SMInterface *iface;
- IExtension *iface_owner;
- 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.owner;
- found = true;
- break;
- }
- }
- }
-
- if (!found)
- {
- return false;
- }
-
- /* Add a dependency node */
- if (iface_owner)
- {
- IfaceInfo info;
- info.iface = iface;
- info.owner = iface_owner;
- g_Extensions.BindDependency(myself, &info);
- }
-
- if (pIface)
- {
- *pIface = iface;
- }
-
- return true;
-}
-
-void ShareSystem::AddNatives(IExtension *myself, const sp_nativeinfo_t *natives)
-{
- CNativeOwner *pOwner;
-
- pOwner = g_Extensions.GetNativeOwner(myself);
-
- pOwner->AddNatives(natives);
-}
-
-void ShareSystem::DestroyIdentity(IdentityToken_t *identity)
-{
- HandleSecurity sec;
-
- sec.pOwner = GetIdentRoot();
- sec.pIdentity = GetIdentRoot();
-
- g_HandleSys.FreeHandle(identity->ident, &sec);
- delete identity;
-}
-
-void ShareSystem::DestroyIdentType(IdentityType_t type)
-{
- g_HandleSys.RemoveType(type, GetIdentRoot());
-}
-
-void ShareSystem::RemoveInterfaces(IExtension *pExtension)
-{
- List::iterator iter = m_Interfaces.begin();
-
- while (iter != m_Interfaces.end())
- {
- if ((*iter).owner == pExtension)
- {
- iter = m_Interfaces.erase(iter);
- }
- else
- {
- iter++;
- }
- }
-}
-
-void ShareSystem::AddDependency(IExtension *myself, const char *filename, bool require, bool autoload)
-{
- g_Extensions.AddDependency(myself, filename, require, autoload);
-}
-
-void ShareSystem::RegisterLibrary(IExtension *myself, const char *name)
-{
- g_Extensions.AddLibrary(myself, name);
-}
-
-void ShareSystem::OverrideNatives(IExtension *myself, const sp_nativeinfo_t *natives)
-{
- unsigned int i;
- NativeEntry *pEntry;
- CNativeOwner *pOwner;
-
- pOwner = g_Extensions.GetNativeOwner(myself);
-
- for (i = 0; natives[i].func != NULL && natives[i].name != NULL; i++)
- {
- if ((pEntry = FindNative(natives[i].name)) == NULL)
- {
- continue;
- }
-
- if (pEntry->owner != g_pCoreNatives)
- {
- continue;
- }
-
- if (pEntry->replacement.owner != NULL)
- {
- continue;
- }
-
- /* Now it's safe to add the override */
- pEntry->replacement.func = natives[i].func;
- pEntry->replacement.owner = pOwner;
- pOwner->AddReplacedNative(pEntry);
- }
-}
-
-NativeEntry *ShareSystem::FindNative(const char *name)
-{
- NativeEntry **ppEntry;
-
- if ((ppEntry = m_NtvCache.retrieve(name)) == NULL)
- {
- return NULL;
- }
-
- return *ppEntry;
-}
-
-void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly)
-{
- NativeEntry *pEntry;
- sp_native_t *native;
- uint32_t i, native_count;
- IPluginContext *pContext;
-
- pContext = pPlugin->GetBaseContext();
-
- /* Generate a new serial ID, mark our dependencies with it. */
- g_mark_serial++;
- pPlugin->PropogateMarkSerial(g_mark_serial);
-
- native_count = pContext->GetNativesNum();
- for (i = 0; i < native_count; i++)
- {
- if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
- {
- continue;
- }
-
- /* If we're bound, check if there is a replacement available.
- * If not, this native is totally finalized.
- */
- if (native->status == SP_NATIVE_BOUND)
- {
- pEntry = (NativeEntry *)native->user;
- assert(pEntry != NULL);
- if (pEntry->replacement.owner == NULL
- || (pEntry->replacement.owner != NULL
- && pEntry->replacement.func == native->pfn))
- {
- continue;
- }
- }
- /* Otherwise, the native must be in our cache. */
- else if ((pEntry = FindNative(native->name)) == NULL)
- {
- continue;
- }
-
- if (bCoreOnly && pEntry->owner != g_pCoreNatives)
- {
- continue;
- }
-
- BindNativeToPlugin(pPlugin, native, i, pEntry);
- }
-}
-
-void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, NativeEntry *pEntry)
-{
- uint32_t i;
- sp_native_t *native;
- IPluginContext *pContext;
-
- pContext = pPlugin->GetBaseContext();
-
- if (pContext->FindNativeByName(pEntry->name, &i) != SP_ERROR_NONE)
- {
- return;
- }
- if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
- {
- return;
- }
-
- if (native->status == SP_NATIVE_BOUND)
- {
- return;
- }
-
- BindNativeToPlugin(pPlugin, native, i, pEntry);
-}
-
-void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin,
- sp_native_t *native,
- uint32_t index,
- NativeEntry *pEntry)
-{
- /* Mark as bound... we do the rest next. */
- native->status = SP_NATIVE_BOUND;
- native->user = pEntry;
-
- /* See if a replacement is available. */
- if (pEntry->replacement.owner != NULL)
- {
- /* Perform a replacement bind. */
- native->pfn = pEntry->replacement.func;
- pEntry->replacement.owner->AddWeakRef(WeakNative(pPlugin, index, pEntry));
- }
- else
- {
- /* Perform a normal bind. */
- native->pfn = pEntry->func;
-
- /* We don't bother with dependency crap if the owner is Core. */
- if (pEntry->owner != g_pCoreNatives)
- {
- /* The native is optional, this is a special case */
- if ((native->flags & SP_NTVFLAG_OPTIONAL) == SP_NTVFLAG_OPTIONAL)
- {
- /* Only add if there is a valid owner. */
- if (pEntry->owner != NULL)
- {
- pEntry->owner->AddWeakRef(WeakNative(pPlugin, index));
- }
- else
- {
- native->status = SP_NATIVE_UNBOUND;
- }
- }
- /* Otherwise, we're a strong dependent and not a weak one */
- else
- {
- /* See if this has already been marked as a dependent.
- * If it has, it means this relationship has already occurred,
- * and there is no reason to do it again.
- */
- if (pEntry->owner != pPlugin
- && pEntry->owner->GetMarkSerial() != g_mark_serial)
- {
- /* This has not been marked as a dependency yet */
- //pPlugin->AddDependency(pEntry->owner);
- pEntry->owner->AddDependent(pPlugin);
- pEntry->owner->SetMarkSerial(g_mark_serial);
- }
- }
- }
- }
-}
-
-NativeEntry *ShareSystem::AddNativeToCache(CNativeOwner *pOwner, const sp_nativeinfo_t *ntv)
-{
- NativeEntry *pEntry;
-
- if ((pEntry = FindNative(ntv->name)) == NULL)
- {
- pEntry = new NativeEntry;
-
- pEntry->owner = pOwner;
- pEntry->name = ntv->name;
- pEntry->func = ntv->func;
- pEntry->replacement.func = NULL;
- pEntry->replacement.owner = NULL;
- pEntry->fake = NULL;
-
- m_NtvCache.insert(ntv->name, pEntry);
-
- return pEntry;
- }
-
- if (pEntry->owner != NULL)
- {
- return NULL;
- }
-
- pEntry->owner = pOwner;
- pEntry->func = ntv->func;
- pEntry->name = ntv->name;
-
- return pEntry;
-}
-
-void ShareSystem::ClearNativeFromCache(CNativeOwner *pOwner, const char *name)
-{
- NativeEntry *pEntry;
-
- if ((pEntry = FindNative(name)) == NULL)
- {
- return;
- }
-
- if (pEntry->owner != pOwner)
- {
- return;
- }
-
- if (pEntry->fake != NULL)
- {
- g_pSourcePawn2->DestroyFakeNative(pEntry->func);
- delete pEntry->fake;
- pEntry->fake = NULL;
- }
-
- pEntry->func = NULL;
- pEntry->name = NULL;
- pEntry->owner = NULL;
- pEntry->replacement.func = NULL;
- pEntry->replacement.owner = NULL;
-}
-
-NativeEntry *ShareSystem::AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func)
-{
- FakeNative *pFake;
- NativeEntry *pEntry;
- SPVM_NATIVE_FUNC gate;
-
- if ((pEntry = FindNative(name)) != NULL && pEntry->owner != NULL)
- {
- return NULL;
- }
-
- pFake = new FakeNative;
-
- if ((gate = g_pSourcePawn2->CreateFakeNative(func, pFake)) == NULL)
- {
- delete pFake;
- return NULL;
- }
-
- if (pEntry == NULL)
- {
- pEntry = new NativeEntry;
- m_NtvCache.insert(name, pEntry);
- }
-
- pFake->call = pFunc;
- pFake->ctx = pFunc->GetParentContext();
- strncopy(pFake->name, name, sizeof(pFake->name));
-
- pEntry->fake = pFake;
- pEntry->func = gate;
- pEntry->name = pFake->name;
- pEntry->owner = g_PluginSys.GetPluginByCtx(pFake->ctx->GetContext());
- pEntry->replacement.func = NULL;
- pEntry->replacement.owner = NULL;
-
- return pEntry;
-}