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