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: }