dvander@370: /**
ds@653: * vim: set ts=4 :
ds@1330: * =============================================================================
dvander@1231: * SourceMod
dvander@1231: * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
ds@1330: * =============================================================================
dvander@370: *
ds@1330: * This program is free software; you can redistribute it and/or modify it under
ds@1330: * the terms of the GNU General Public License, version 3.0, as published by the
ds@1330: * Free Software Foundation.
dvander@1231: *
ds@1330: * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1330: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1330: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
ds@1330: * details.
dvander@1231: *
ds@1330: * You should have received a copy of the GNU General Public License along with
ds@1330: * this program. If not, see .
dvander@1231: *
ds@1330: * As a special exception, AlliedModders LLC gives you permission to link the
ds@1330: * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1330: * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1330: * by the Valve Corporation. You must obey the GNU General Public License in
ds@1330: * all respects for all other code used. Additionally, AlliedModders LLC grants
ds@1330: * this exception to all derivative works. AlliedModders LLC defines further
ds@1330: * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1330: * or .
dvander@370: *
dvander@370: * Version: $Id$
dvander@370: */
dvander@370:
dvander@229: #include "ShareSys.h"
dvander@229: #include "HandleSys.h"
dvander@304: #include "ExtensionSys.h"
dvander@336: #include "LibrarySys.h"
dvander@229:
dvander@229: ShareSystem g_ShareSys;
dvander@229:
dvander@229: ShareSystem::ShareSystem()
dvander@229: {
dvander@229: m_IdentRoot.ident = 0;
dvander@229: m_TypeRoot = 0;
dvander@229: m_IfaceType = 0;
dvander@229: m_CoreType = 0;
dvander@229: }
dvander@229:
dvander@229: IdentityToken_t *ShareSystem::CreateCoreIdentity()
dvander@229: {
dvander@229: if (!m_CoreType)
dvander@229: {
dvander@229: m_CoreType = CreateIdentType("CORE");
dvander@229: }
dvander@229:
dvander@868: return CreateIdentity(m_CoreType, this);
dvander@229: }
dvander@229:
dvander@1770: void ShareSystem::Initialize()
dvander@229: {
dvander@262: TypeAccess sec;
dvander@229:
dvander@262: g_HandleSys.InitAccessDefaults(&sec, NULL);
dvander@262: sec.ident = GetIdentRoot();
dvander@262:
dvander@262: m_TypeRoot = g_HandleSys.CreateType("Identity", this, 0, &sec, NULL, NULL, NULL);
dvander@262: m_IfaceType = g_HandleSys.CreateType("Interface", this, 0, NULL, NULL, GetIdentRoot(), NULL);
dvander@229:
dvander@229: /* Initialize our static identity handle */
dvander@262: m_IdentRoot.ident = g_HandleSys.CreateHandle(m_TypeRoot, NULL, NULL, GetIdentRoot(), NULL);
dvander@305:
dvander@336: /* Add the Handle System and others... they are too innocent and pure to do it themselves */
dvander@305: AddInterface(NULL, &g_HandleSys);
dvander@336: AddInterface(NULL, &g_LibSys);
dvander@229: }
dvander@229:
dvander@229: void ShareSystem::OnSourceModShutdown()
dvander@229: {
dvander@229: if (m_CoreType)
dvander@229: {
dvander@229: g_HandleSys.RemoveType(m_CoreType, GetIdentRoot());
dvander@229: }
dvander@229:
dvander@229: g_HandleSys.RemoveType(m_IfaceType, GetIdentRoot());
dvander@229: g_HandleSys.RemoveType(m_TypeRoot, GetIdentRoot());
dvander@229: }
dvander@229:
dvander@229: IdentityType_t ShareSystem::FindIdentType(const char *name)
dvander@229: {
dvander@229: HandleType_t type;
dvander@229:
dvander@229: if (g_HandleSys.FindHandleType(name, &type))
dvander@229: {
dvander@229: if (g_HandleSys.TypeCheck(type, m_TypeRoot))
dvander@229: {
dvander@229: return type;
dvander@229: }
dvander@229: }
dvander@229:
dvander@229: return 0;
dvander@229: }
dvander@229:
dvander@229: IdentityType_t ShareSystem::CreateIdentType(const char *name)
dvander@229: {
dvander@229: if (!m_TypeRoot)
dvander@229: {
dvander@229: return 0;
dvander@229: }
dvander@229:
dvander@262: return g_HandleSys.CreateType(name, this, m_TypeRoot, NULL, NULL, GetIdentRoot(), NULL);
dvander@229: }
dvander@229:
dvander@229: void ShareSystem::OnHandleDestroy(HandleType_t type, void *object)
dvander@229: {
dvander@283: /* THIS WILL NEVER BE CALLED FOR ANYTHING WITH THE IDENTITY TYPE */
dvander@229: }
dvander@229:
dvander@868: IdentityToken_t *ShareSystem::CreateIdentity(IdentityType_t type, void *ptr)
dvander@229: {
dvander@229: if (!m_TypeRoot)
dvander@229: {
dvander@229: return 0;
dvander@229: }
dvander@229:
dvander@229: /* :TODO: Cache? */
dvander@229: IdentityToken_t *pToken = new IdentityToken_t;
dvander@528:
dvander@528: HandleSecurity sec;
dvander@528: sec.pOwner = sec.pIdentity = GetIdentRoot();
dvander@528:
dvander@528: pToken->ident = g_HandleSys.CreateHandleInt(type, NULL, &sec, NULL, NULL, true);
dvander@868: pToken->ptr = ptr;
dvander@868: pToken->type = type;
dvander@229:
dvander@229: return pToken;
dvander@229: }
dvander@229:
dvander@304: bool ShareSystem::AddInterface(IExtension *myself, SMInterface *iface)
dvander@229: {
dvander@229: if (!iface)
dvander@229: {
dvander@229: return false;
dvander@229: }
dvander@229:
dvander@229: IfaceInfo info;
dvander@229:
dvander@304: info.owner = myself;
dvander@229: info.iface = iface;
dvander@229:
dvander@229: m_Interfaces.push_back(info);
dvander@229:
dvander@229: return true;
dvander@229: }
dvander@229:
dvander@229: bool ShareSystem::RequestInterface(const char *iface_name,
dvander@229: unsigned int iface_vers,
dvander@311: IExtension *myself,
dvander@229: SMInterface **pIface)
dvander@229: {
dvander@229: /* See if the interface exists */
dvander@229: List::iterator iter;
dvander@229: SMInterface *iface;
dvander@304: IExtension *iface_owner;
dvander@229: bool found = false;
dvander@229: for (iter=m_Interfaces.begin(); iter!=m_Interfaces.end(); iter++)
dvander@229: {
dvander@229: IfaceInfo &info = (*iter);
dvander@229: iface = info.iface;
dvander@229: if (strcmp(iface->GetInterfaceName(), iface_name) == 0)
dvander@229: {
dvander@229: if (iface->GetInterfaceVersion() == iface_vers
dvander@229: || iface->IsVersionCompatible(iface_vers))
dvander@229: {
dvander@304: iface_owner = info.owner;
dvander@229: found = true;
dvander@229: break;
dvander@229: }
dvander@229: }
dvander@229: }
dvander@229:
dvander@229: if (!found)
dvander@229: {
dvander@229: return false;
dvander@229: }
dvander@229:
dvander@304: /* Add a dependency node */
dvander@229: if (iface_owner)
dvander@229: {
dvander@304: IfaceInfo info;
dvander@304: info.iface = iface;
dvander@304: info.owner = iface_owner;
dvander@311: g_Extensions.BindDependency(myself, &info);
dvander@229: }
dvander@229:
dvander@304: if (pIface)
dvander@304: {
dvander@304: *pIface = iface;
dvander@304: }
dvander@229:
dvander@304: return true;
dvander@229: }
dvander@229:
dvander@312: void ShareSystem::AddNatives(IExtension *myself, const sp_nativeinfo_t *natives)
dvander@229: {
dvander@315: g_Extensions.AddNatives(myself, natives);
dvander@229: }
dvander@229:
dvander@229: void ShareSystem::DestroyIdentity(IdentityToken_t *identity)
dvander@229: {
dvander@262: HandleSecurity sec;
dvander@262:
dvander@262: sec.pOwner = GetIdentRoot();
dvander@262: sec.pIdentity = GetIdentRoot();
dvander@262:
dvander@262: g_HandleSys.FreeHandle(identity->ident, &sec);
dvander@229: delete identity;
dvander@229: }
dvander@229:
dvander@229: void ShareSystem::DestroyIdentType(IdentityType_t type)
dvander@229: {
dvander@229: g_HandleSys.RemoveType(type, GetIdentRoot());
dvander@229: }
dvander@229:
dvander@304: void ShareSystem::RemoveInterfaces(IExtension *pExtension)
dvander@304: {
dvander@304: List::iterator iter = m_Interfaces.begin();
dvander@304:
dvander@304: while (iter != m_Interfaces.end())
dvander@304: {
dvander@304: if ((*iter).owner == pExtension)
dvander@304: {
dvander@304: iter = m_Interfaces.erase(iter);
dvander@304: } else {
dvander@304: iter++;
dvander@304: }
dvander@304: }
dvander@304: }
dvander@324:
dvander@324: void ShareSystem::AddDependency(IExtension *myself, const char *filename, bool require, bool autoload)
dvander@324: {
dvander@324: g_Extensions.AddDependency(myself, filename, require, autoload);
dvander@324: }
dvander@324:
dvander@1572: void ShareSystem::RegisterLibrary(IExtension *myself, const char *name)
dvander@1572: {
dvander@1572: g_Extensions.AddLibrary(myself, name);
dvander@1572: }
dvander@1689:
dvander@1689: void ShareSystem::OverrideNatives(IExtension *myself, const sp_nativeinfo_t *natives)
dvander@1689: {
dvander@1689: g_Extensions.OverrideNatives(myself, natives);
dvander@1689: }