core/logic/NativeOwner.cpp
author David Anderson <dvander@alliedmods.net>
Fri Aug 30 10:14:18 2013 -0700 (2013-08-30)
changeset 4108 dabaea5ab45c
parent 4107 5a723cf42aee
child 4109 10eb68d668af
permissions -rw-r--r--
Simplify NativeEntry state (bug 5852 part 3, r=ds).
     1 /**
     2  * vim: set ts=4 sw=4 tw=99 noet :
     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 	for (const sp_nativeinfo_t *native = natives; native->func && native->name; native++)
    62 		g_ShareSys.AddNativeToCache(this, native);
    63 
    64 	m_natives.append(natives);
    65 }
    66 
    67 void CNativeOwner::PropagateMarkSerial(unsigned int serial)
    68 {
    69 	CNativeOwner *pOwner;
    70 	List<CPlugin *>::iterator iter;
    71 
    72 	for (iter = m_Dependents.begin();
    73 		 iter != m_Dependents.end();
    74 		 iter++)
    75 	{
    76 		pOwner = (*iter);
    77 		pOwner->SetMarkSerial(serial);
    78 	}
    79 }
    80 
    81 void CNativeOwner::UnbindWeakRef(const WeakNative & ref)
    82 {
    83 	sp_native_t *native;
    84 	IPluginContext *pContext;
    85 
    86 	pContext = ref.pl->GetBaseContext();
    87 	if ((pContext->GetNativeByIndex(ref.idx, &native)) == SP_ERROR_NONE)
    88 	{
    89 		/* If there is no reference, the native must be unbound */
    90 		if (ref.entry == NULL)
    91 		{
    92 			native->status = SP_NATIVE_UNBOUND;
    93 			native->pfn = NULL;
    94 		}
    95 		/* If we've cached a reference, it's a core native we can 
    96 		 * rebind back to its original (this was a replacement).
    97 		 */
    98 		else
    99 		{
   100 			native->pfn = ref.entry->func();
   101 		}
   102 	}
   103 }
   104 
   105 void CNativeOwner::DropEverything()
   106 {
   107 	NativeEntry *pEntry;
   108 	List<WeakNative>::iterator iter;
   109 
   110 	/* Unbind and remove all weak references to us */
   111 	iter = m_WeakRefs.begin();
   112 	while (iter != m_WeakRefs.end())
   113 	{
   114 		UnbindWeakRef((*iter));
   115 		iter = m_WeakRefs.erase(iter);
   116 	}
   117 
   118 	/* Strip all of our natives from the cache */
   119 	for (size_t i = 0; i < m_natives.length(); i++) {
   120 		const sp_nativeinfo_t *natives = m_natives[i];
   121 		for (const sp_nativeinfo_t *native = natives; native->func && native->name; native++)
   122 			g_ShareSys.ClearNativeFromCache(this, native->name);
   123 	}
   124 
   125 	List<NativeEntry *>::iterator ntv_iter = m_Natives.begin();
   126 	while (ntv_iter != m_Natives.end())
   127 	{
   128 		g_ShareSys.ClearNativeFromCache(this, (*ntv_iter)->name());
   129 		ntv_iter = m_Natives.erase(ntv_iter);
   130 	}
   131 }
   132 
   133 void CNativeOwner::DropWeakRefsTo(CPlugin *pPlugin)
   134 {
   135 	List<WeakNative>::iterator iter;
   136 
   137 	iter = m_WeakRefs.begin();
   138 	while (iter != m_WeakRefs.end())
   139 	{
   140 		WeakNative & ref = (*iter);
   141 
   142 		if (ref.pl == pPlugin)
   143 		{
   144 			iter = m_WeakRefs.erase(iter);
   145 		}
   146 		else
   147 		{
   148 			iter++;
   149 		}
   150 	}
   151 }
   152 
   153 void CNativeOwner::DropRefsTo(CPlugin *pPlugin)
   154 {
   155 	m_Dependents.remove(pPlugin);
   156 	DropWeakRefsTo(pPlugin);
   157 }