core/logic/NativeOwner.cpp
author Nicholas Hastings <skamonkey@gmail.com>
Wed Aug 14 14:20:57 2013 -0400 (2013-08-14)
changeset 4008 490b01aa0683
parent 3872 4c93f74cae51
child 4106 a39557bde4ac
permissions -rw-r--r--
Updated some CS:GO gamedata.
     1 /**
     2  * vim: set ts=4 :
     3  * =============================================================================
     4  * SourcePawn
     5  * Copyright (C) 2004-2009 AlliedModders LLC.  All rights reserved.
     6  * =============================================================================
     7  *
     8  * This program is free software; you can redistribute it and/or modify it under
     9  * the terms of the GNU General Public License, version 3.0, as published by the
    10  * Free Software Foundation.
    11  * 
    12  * This program is distributed in the hope that it will be useful, but WITHOUT
    13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    15  * details.
    16  *
    17  * You should have received a copy of the GNU General Public License along with
    18  * this program.  If not, see <http://www.gnu.org/licenses/>.
    19  *
    20  * As a special exception, AlliedModders LLC gives you permission to link the
    21  * code of this program (as well as its derivative works) to "Half-Life 2," the
    22  * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    23  * by the Valve Corporation.  You must obey the GNU General Public License in
    24  * all respects for all other code used.  Additionally, AlliedModders LLC grants
    25  * this exception to all derivative works.  AlliedModders LLC defines further
    26  * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    27  * or <http://www.sourcemod.net/license.php>.
    28  *
    29  * Version: $Id$
    30  */
    31 #include "NativeOwner.h"
    32 #include "ShareSys.h"
    33 #include "PluginSys.h"
    34 
    35 CNativeOwner::CNativeOwner() : m_nMarkSerial(0)
    36 {
    37 }
    38 
    39 void CNativeOwner::SetMarkSerial(unsigned int serial)
    40 {
    41 	m_nMarkSerial = serial;
    42 }
    43 
    44 unsigned int CNativeOwner::GetMarkSerial()
    45 {
    46 	return m_nMarkSerial;
    47 }
    48 
    49 void CNativeOwner::AddDependent(CPlugin *pPlugin)
    50 {
    51 	m_Dependents.push_back(pPlugin);
    52 }
    53 
    54 void CNativeOwner::AddWeakRef(const WeakNative & ref)
    55 {
    56 	m_WeakRefs.push_back(ref);
    57 }
    58 
    59 void CNativeOwner::AddNatives(const sp_nativeinfo_t *natives)
    60 {
    61 	NativeEntry *pEntry;
    62 
    63 	for (unsigned int i = 0; natives[i].func != NULL && natives[i].name != NULL; i++)
    64 	{
    65 		if ((pEntry = g_ShareSys.AddNativeToCache(this, &natives[i])) == NULL)
    66 		{
    67 			continue;
    68 		}
    69 
    70 		m_Natives.push_back(pEntry);
    71 	}
    72 }
    73 
    74 void CNativeOwner::PropagateMarkSerial(unsigned int serial)
    75 {
    76 	CNativeOwner *pOwner;
    77 	List<CPlugin *>::iterator iter;
    78 
    79 	for (iter = m_Dependents.begin();
    80 		 iter != m_Dependents.end();
    81 		 iter++)
    82 	{
    83 		pOwner = (*iter);
    84 		pOwner->SetMarkSerial(serial);
    85 	}
    86 }
    87 
    88 void CNativeOwner::UnbindWeakRef(const WeakNative & ref)
    89 {
    90 	sp_native_t *native;
    91 	IPluginContext *pContext;
    92 
    93 	pContext = ref.pl->GetBaseContext();
    94 	if ((pContext->GetNativeByIndex(ref.idx, &native)) == SP_ERROR_NONE)
    95 	{
    96 		/* If there is no reference, the native must be unbound */
    97 		if (ref.entry == NULL)
    98 		{
    99 			native->status = SP_NATIVE_UNBOUND;
   100 			native->pfn = NULL;
   101 		}
   102 		/* If we've cached a reference, it's a core native we can 
   103 		 * rebind back to its original (this was a replacement).
   104 		 */
   105 		else
   106 		{
   107 			native->pfn = ref.entry->func;
   108 		}
   109 	}
   110 }
   111 
   112 void CNativeOwner::DropEverything()
   113 {
   114 	NativeEntry *pEntry;
   115 	List<WeakNative>::iterator iter;
   116 	List<NativeEntry *>::iterator ntv_iter;
   117 
   118 	/* Unbind and remove all weak references to us */
   119 	iter = m_WeakRefs.begin();
   120 	while (iter != m_WeakRefs.end())
   121 	{
   122 		UnbindWeakRef((*iter));
   123 		iter = m_WeakRefs.erase(iter);
   124 	}
   125 
   126 	/* Unmark our replacement natives */
   127 	ntv_iter = m_ReplacedNatives.begin();
   128 	while (ntv_iter != m_ReplacedNatives.end())
   129 	{
   130 		pEntry = (*ntv_iter);
   131 		pEntry->replacement.func = NULL;
   132 		pEntry->replacement.owner = NULL;
   133 		ntv_iter = m_ReplacedNatives.erase(ntv_iter);
   134 	}
   135 
   136 	/* Strip all of our natives from the cache */
   137 	ntv_iter = m_Natives.begin();
   138 	while (ntv_iter != m_Natives.end())
   139 	{
   140 		g_ShareSys.ClearNativeFromCache(this, (*ntv_iter)->name);
   141 		ntv_iter = m_Natives.erase(ntv_iter);
   142 	}
   143 }
   144 
   145 void CNativeOwner::DropWeakRefsTo(CPlugin *pPlugin)
   146 {
   147 	List<WeakNative>::iterator iter;
   148 
   149 	iter = m_WeakRefs.begin();
   150 	while (iter != m_WeakRefs.end())
   151 	{
   152 		WeakNative & ref = (*iter);
   153 
   154 		if (ref.pl == pPlugin)
   155 		{
   156 			iter = m_WeakRefs.erase(iter);
   157 		}
   158 		else
   159 		{
   160 			iter++;
   161 		}
   162 	}
   163 }
   164 
   165 void CNativeOwner::DropRefsTo(CPlugin *pPlugin)
   166 {
   167 	m_Dependents.remove(pPlugin);
   168 	DropWeakRefsTo(pPlugin);
   169 }
   170 
   171 void CNativeOwner::AddReplacedNative(NativeEntry *pEntry)
   172 {
   173 	m_ReplacedNatives.push_back(pEntry);
   174 }