core/systems/PluginSys.cpp
changeset 176 c1699993453c
parent 174 5611e4b3fa42
child 177 d29ade52d953
     1.1 --- a/core/systems/PluginSys.cpp	Sat Nov 11 05:47:00 2006 +0000
     1.2 +++ b/core/systems/PluginSys.cpp	Sat Nov 11 05:49:52 2006 +0000
     1.3 @@ -7,6 +7,34 @@
     1.4  {
     1.5  }
     1.6  
     1.7 +void CFunction::Set(funcid_t funcid, CPlugin *plugin)
     1.8 +{
     1.9 +	m_funcid = funcid;
    1.10 +	m_pPlugin = plugin;
    1.11 +}
    1.12 +
    1.13 +int CFunction::CallFunction(const cell_t *params, unsigned int num_params, cell_t *result)
    1.14 +{
    1.15 +	IPluginContext *ctx = m_pPlugin->m_ctx_current.base;
    1.16 +
    1.17 +	for (unsigned int i=0; i<num_params; i++)
    1.18 +	{
    1.19 +		ctx->PushCell(params[i]);
    1.20 +	}
    1.21 +
    1.22 +	return ctx->Execute(m_funcid, result);
    1.23 +}
    1.24 +
    1.25 +IPlugin *CFunction::GetParentPlugin()
    1.26 +{
    1.27 +	return m_pPlugin;
    1.28 +}
    1.29 +
    1.30 +CFunction::CFunction(funcid_t funcid, CPlugin *plugin) : 
    1.31 +	m_funcid(funcid), m_pPlugin(plugin)
    1.32 +{
    1.33 +}
    1.34 +
    1.35  CPlugin *CPlugin::CreatePlugin(const char *file, 
    1.36  								bool debug_default, 
    1.37  								PluginType type, 
    1.38 @@ -67,9 +95,89 @@
    1.39  
    1.40  	ctx->user[SM_CONTEXTVAR_MYSELF] = (void *)(IPlugin *)pPlugin;
    1.41  
    1.42 +	/* Build function information loosely */
    1.43 +	pPlugin->m_funcsnum = g_pVM->FunctionCount(ctx);
    1.44 +
    1.45 +	if (pPlugin->m_funcsnum)
    1.46 +	{
    1.47 +		pPlugin->m_priv_funcs = new CFunction *[pPlugin->m_funcsnum];
    1.48 +		memset(pPlugin->m_priv_funcs, 0, sizeof(CFunction *) * pPlugin->m_funcsnum);
    1.49 +	} else {
    1.50 +		pPlugin->m_priv_funcs = NULL;
    1.51 +	}
    1.52 +
    1.53 +	if (pl->info.publics_num)
    1.54 +	{
    1.55 +		pPlugin->m_pub_funcs = new CFunction *[pl->info.publics_num];
    1.56 +		memset(pPlugin->m_pub_funcs, 0, sizeof(CFunction *) * pl->info.publics_num);
    1.57 +	} else {
    1.58 +		pPlugin->m_pub_funcs = NULL;
    1.59 +	}
    1.60 +
    1.61  	return pPlugin;
    1.62  }
    1.63  
    1.64 +IPluginFunction *CPlugin::GetFunctionById(funcid_t func_id)
    1.65 +{
    1.66 +	CFunction *pFunc = NULL;
    1.67 +	funcid_t save = func_id;
    1.68 +
    1.69 +	if (func_id & 1)
    1.70 +	{
    1.71 +		func_id >>= 1;
    1.72 +		if (func_id >= m_plugin->info.publics_num)
    1.73 +		{
    1.74 +			return NULL;
    1.75 +		}
    1.76 +		pFunc = m_pub_funcs[func_id];
    1.77 +		if (!pFunc)
    1.78 +		{
    1.79 +			pFunc = g_PluginMngr.GetFunctionFromPool(save, this);
    1.80 +			m_pub_funcs[func_id] = pFunc;
    1.81 +		}
    1.82 +	} else {
    1.83 +		func_id >>= 1;
    1.84 +		unsigned int index;
    1.85 +		if (!g_pVM->FunctionLookup(m_ctx_current.ctx, func_id, &index))
    1.86 +		{
    1.87 +			return NULL;
    1.88 +		}
    1.89 +		pFunc = m_priv_funcs[func_id];
    1.90 +		if (!pFunc)
    1.91 +		{
    1.92 +			pFunc = g_PluginMngr.GetFunctionFromPool(save, this);
    1.93 +			m_priv_funcs[func_id] = pFunc;
    1.94 +		}
    1.95 +	}
    1.96 +
    1.97 +	return pFunc;
    1.98 +}
    1.99 +
   1.100 +IPluginFunction *CPlugin::GetFunctionByName(const char *public_name)
   1.101 +{
   1.102 +	uint32_t index;
   1.103 +	IPluginContext *base = m_ctx_current.base;
   1.104 +
   1.105 +	if (base->FindPublicByName(public_name, &index) != SP_ERROR_NONE)
   1.106 +	{
   1.107 +		return NULL;
   1.108 +	}
   1.109 +
   1.110 +	CFunction *pFunc = m_pub_funcs[index];
   1.111 +	if (!pFunc)
   1.112 +	{
   1.113 +		sp_public_t *pub = NULL;
   1.114 +		base->GetPublicByIndex(index, &pub);
   1.115 +		if (pub)
   1.116 +		{
   1.117 +			pFunc = g_PluginMngr.GetFunctionFromPool(pub->funcid, this);
   1.118 +			m_pub_funcs[index] = pFunc;
   1.119 +		}
   1.120 +	}
   1.121 +
   1.122 +	return pFunc;
   1.123 +}
   1.124 +
   1.125  void CPlugin::UpdateInfo()
   1.126  {
   1.127  	/* Now grab the info */
   1.128 @@ -242,6 +350,26 @@
   1.129  		pListener = (*iter);
   1.130  		pListener->OnPluginDestroyed(pPlugin);
   1.131  	}
   1.132 +	
   1.133 +	if (pPlugin->m_pub_funcs)
   1.134 +	{
   1.135 +		for (uint32_t i=0; i<pPlugin->m_plugin->info.publics_num; i++)
   1.136 +		{
   1.137 +			delete pPlugin->m_pub_funcs[i];
   1.138 +		}
   1.139 +		delete [] pPlugin->m_pub_funcs;
   1.140 +		pPlugin->m_pub_funcs = NULL;
   1.141 +	}
   1.142 +
   1.143 +	if (pPlugin->m_priv_funcs)
   1.144 +	{
   1.145 +		for (unsigned int i=0; i<pPlugin->m_funcsnum; i++)
   1.146 +		{
   1.147 +			delete pPlugin->m_priv_funcs[i];
   1.148 +		}
   1.149 +		delete [] pPlugin->m_priv_funcs;
   1.150 +		pPlugin->m_priv_funcs = NULL;
   1.151 +	}
   1.152  
   1.153  	if (pPlugin->m_ctx_current.base)
   1.154  	{
   1.155 @@ -304,3 +432,26 @@
   1.156  {
   1.157  	m_iters.push(iter);
   1.158  }
   1.159 +
   1.160 +void CPluginManager::ReleaseFunctionToPool(CFunction *func)
   1.161 +{
   1.162 +	m_funcpool.push(func);
   1.163 +}
   1.164 +
   1.165 +CFunction *CPluginManager::GetFunctionFromPool(funcid_t f, CPlugin *plugin)
   1.166 +{
   1.167 +	if (m_funcpool.empty())
   1.168 +	{
   1.169 +		return new CFunction(f, plugin);
   1.170 +	} else {
   1.171 +		CFunction *func = m_funcpool.front();
   1.172 +		m_funcpool.pop();
   1.173 +		func->Set(f, plugin);
   1.174 +		return func;
   1.175 +	}
   1.176 +}
   1.177 +
   1.178 +CPluginManager::~CPluginManager()
   1.179 +{
   1.180 +	//:TODO: we need a good way to free what we're holding
   1.181 +}