1.1 --- a/core/systems/PluginSys.cpp Thu Jan 18 21:07:10 2007 +0000
1.2 +++ b/core/systems/PluginSys.cpp Thu Jan 18 23:28:14 2007 +0000
1.3 @@ -693,7 +693,6 @@
1.4 }
1.5
1.6 //well i have discovered that gabe newell is very fat, so i wrote this comment now
1.7 -//:TODO: remove this function, create a better wrapper for LoadPlugin()/LoadAutoPlugin()
1.8 bool CPluginManager::_LoadPlugin(CPlugin **_plugin, const char *path, bool debug, PluginType type, char error[], size_t err_max)
1.9 {
1.10 /**
1.11 @@ -777,7 +776,11 @@
1.12 {
1.13 AddCoreNativesToPlugin(pPlugin);
1.14 pPlugin->InitIdentity();
1.15 - pPlugin->Call_AskPluginLoad(error, err_max);
1.16 + if (pPlugin->Call_AskPluginLoad(error, err_max))
1.17 + {
1.18 + /* Autoload any modules */
1.19 + LoadOrRequireExtensions(pPlugin, 1, error, err_max);
1.20 + }
1.21 }
1.22
1.23 if (_plugin)
1.24 @@ -800,6 +803,16 @@
1.25
1.26 AddPlugin(pl);
1.27
1.28 + /* Run second pass if we need to */
1.29 + if (IsLateLoadTime() && pl->GetStatus() == Plugin_Loaded)
1.30 + {
1.31 + if (!RunSecondPass(pl, error, err_max))
1.32 + {
1.33 + UnloadPlugin(pl);
1.34 + return NULL;
1.35 + }
1.36 + }
1.37 +
1.38 return pl;
1.39 }
1.40
1.41 @@ -837,20 +850,25 @@
1.42 List<CPlugin *>::iterator iter;
1.43 CPlugin *pPlugin;
1.44
1.45 + char error[256];
1.46 for (iter=m_plugins.begin(); iter!=m_plugins.end(); iter++)
1.47 {
1.48 pPlugin = (*iter);
1.49 if (pPlugin->GetStatus() == Plugin_Loaded)
1.50 {
1.51 - /* :TODO: fix */
1.52 - RunSecondPass(pPlugin, NULL, 0);
1.53 + error[0] = '\0';
1.54 + if (!RunSecondPass(pPlugin, error, sizeof(error)))
1.55 + {
1.56 + g_Logger.LogError("[SM] Unable to load plugin \"%s\": %s", pPlugin->GetFilename(), error);
1.57 + pPlugin->SetErrorState(Plugin_Failed, "%s", error);
1.58 + }
1.59 }
1.60 }
1.61
1.62 m_AllPluginsLoaded = true;
1.63 }
1.64
1.65 -bool CPluginManager::RunSecondPass(CPlugin *pPlugin, char *error, size_t maxlength)
1.66 +bool CPluginManager::LoadOrRequireExtensions(CPlugin *pPlugin, unsigned int pass, char *error, size_t maxlength)
1.67 {
1.68 /* Find any extensions this plugin needs */
1.69 struct _ext
1.70 @@ -888,36 +906,75 @@
1.71 {
1.72 continue;
1.73 }
1.74 - snprintf(path, PLATFORM_MAX_PATH, "%s.%s", file, PLATFORM_LIB_EXT);
1.75 - pExt = NULL;
1.76 - /* Attempt to auto-load if necessary */
1.77 - if (ext->autoload)
1.78 + if (pass == 1)
1.79 {
1.80 - pExt = g_Extensions.LoadAutoExtension(path);
1.81 - }
1.82 - /* See if we can find a similar extension */
1.83 - if (ext->required && !pExt)
1.84 - {
1.85 - if ((pExt = g_Extensions.FindExtensionByFile(path)) == NULL)
1.86 + /* Attempt to auto-load if necessary */
1.87 + if (ext->autoload)
1.88 + {
1.89 + g_LibSys.PathFormat(path, PLATFORM_MAX_PATH, "%s", file);
1.90 + g_Extensions.LoadAutoExtension(path);
1.91 + }
1.92 + } else if (pass == 2) {
1.93 + /* Is this required? */
1.94 + if (ext->required)
1.95 {
1.96 - pExt = g_Extensions.FindExtensionByName(name);
1.97 + g_LibSys.PathFormat(path, PLATFORM_MAX_PATH, "%s", file);
1.98 + if ((pExt = g_Extensions.FindExtensionByFile(path)) == NULL)
1.99 + {
1.100 + pExt = g_Extensions.FindExtensionByName(name);
1.101 + }
1.102 + /* :TODO: should we bind to unloaded extensions?
1.103 + * Currently the extension manager will ignore this.
1.104 + */
1.105 + if (!pExt || !pExt->IsRunning(NULL, 0))
1.106 + {
1.107 + if (error)
1.108 + {
1.109 + snprintf(error, maxlength, "Required extension \"%s\" file(\"%s\") not running", name, file);
1.110 + }
1.111 + pPlugin->m_status = Plugin_Failed;
1.112 + return false;
1.113 + } else {
1.114 + g_Extensions.BindChildPlugin(pExt, pPlugin);
1.115 + }
1.116 }
1.117 }
1.118 - /* If we're requiring and got an extension and it's loaded, bind it */
1.119 - if (ext->required && pExt && pExt->IsLoaded())
1.120 - {
1.121 - g_Extensions.BindChildPlugin(pExt, pPlugin);
1.122 - }
1.123 - /* If we're requiring and we didn't get an extension or it's not loaded, error */
1.124 - if (ext->required && (!pExt || !pExt->IsLoaded()))
1.125 + }
1.126 + }
1.127 +
1.128 + return true;
1.129 +}
1.130 +
1.131 +bool CPluginManager::RunSecondPass(CPlugin *pPlugin, char *error, size_t maxlength)
1.132 +{
1.133 + /* Second pass for extension requirements */
1.134 + if (!LoadOrRequireExtensions(pPlugin, 2, error, maxlength))
1.135 + {
1.136 + return false;
1.137 + }
1.138 +
1.139 + /* Bind all extra natives */
1.140 + g_Extensions.BindAllNativesToPlugin(pPlugin);
1.141 +
1.142 + /* Find any unbound natives
1.143 + * Right now, these are not allowed
1.144 + */
1.145 + IPluginContext *pContext = pPlugin->GetBaseContext();
1.146 + uint32_t num = pContext->GetNativesNum();
1.147 + sp_native_t *native;
1.148 + for (unsigned int i=0; i<num; i++)
1.149 + {
1.150 + if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
1.151 + {
1.152 + break;
1.153 + }
1.154 + if (native->status == SP_NATIVE_UNBOUND)
1.155 + {
1.156 + if (error)
1.157 {
1.158 - if (error)
1.159 - {
1.160 - snprintf(error, maxlength, "Required extension \"%s\" (file \"%s\") not found", name, file);
1.161 - }
1.162 - pPlugin->m_status = Plugin_Failed;
1.163 - return false;
1.164 + snprintf(error, maxlength, "Native \"%s\" was not found.", native->name);
1.165 }
1.166 + return false;
1.167 }
1.168 }
1.169
1.170 @@ -1268,7 +1325,7 @@
1.171
1.172 bool CPluginManager::IsLateLoadTime() const
1.173 {
1.174 - return (m_AllPluginsLoaded || g_SourceMod.IsLateLoadInMap());
1.175 + return (m_AllPluginsLoaded || !g_SourceMod.IsMapLoading());
1.176 }
1.177
1.178 void CPluginManager::OnSourceModAllInitialized()
1.179 @@ -1486,39 +1543,48 @@
1.180 return;
1.181 }
1.182
1.183 - IPluginIterator *iter = GetPluginIterator();
1.184 - for (; iter->MorePlugins() && id<num; iter->NextPlugin(), id++) {}
1.185 -
1.186 - IPlugin *pl = iter->GetPlugin();
1.187 + CPlugin *pl = GetPluginByOrder(num);
1.188 const sm_plugininfo_t *info = pl->GetPublicInfo();
1.189
1.190 g_RootMenu.ConsolePrint(" Filename: %s", pl->GetFilename());
1.191 - if (IS_STR_FILLED(info->name))
1.192 - {
1.193 - g_RootMenu.ConsolePrint(" Title: %s", info->name);
1.194 - }
1.195 - if (IS_STR_FILLED(info->author))
1.196 + if (pl->GetStatus() <= Plugin_Error)
1.197 {
1.198 - g_RootMenu.ConsolePrint(" Author: %s", info->author);
1.199 - }
1.200 - if (IS_STR_FILLED(info->version))
1.201 - {
1.202 - g_RootMenu.ConsolePrint(" Version: %s", info->version);
1.203 + if (IS_STR_FILLED(info->name))
1.204 + {
1.205 + g_RootMenu.ConsolePrint(" Title: %s", info->name);
1.206 + }
1.207 + if (IS_STR_FILLED(info->version))
1.208 + {
1.209 + g_RootMenu.ConsolePrint(" Version: %s", info->version);
1.210 + }
1.211 + if (IS_STR_FILLED(info->url))
1.212 + {
1.213 + g_RootMenu.ConsolePrint(" URL: %s", info->url);
1.214 + }
1.215 + if (IS_STR_FILLED(info->author))
1.216 + {
1.217 + g_RootMenu.ConsolePrint(" Author: %s", info->author);
1.218 + }
1.219 + if (IS_STR_FILLED(info->version))
1.220 + {
1.221 + g_RootMenu.ConsolePrint(" Version: %s", info->version);
1.222 + }
1.223 + if (IS_STR_FILLED(info->description))
1.224 + {
1.225 + g_RootMenu.ConsolePrint(" Description: %s", info->description);
1.226 + }
1.227 + g_RootMenu.ConsolePrint(" Debugging: %s", pl->IsDebugging() ? "yes" : "no");
1.228 + g_RootMenu.ConsolePrint(" Paused: %s", pl->GetStatus() == Plugin_Running ? "yes" : "no");
1.229 + } else {
1.230 + g_RootMenu.ConsolePrint(" Load error: %s", pl->m_errormsg);
1.231 + g_RootMenu.ConsolePrint(" File info: (title \"%s\") (version \"%s\")",
1.232 + info->name ? info->name : "<none>",
1.233 + info->version ? info->version : "<none>");
1.234 + if (IS_STR_FILLED(info->url))
1.235 + {
1.236 + g_RootMenu.ConsolePrint(" File URL: %s", info->url);
1.237 + }
1.238 }
1.239 - if (IS_STR_FILLED(info->description))
1.240 - {
1.241 - g_RootMenu.ConsolePrint(" Description: %s", info->description);
1.242 - }
1.243 - if (IS_STR_FILLED(info->url))
1.244 - {
1.245 - g_RootMenu.ConsolePrint(" URL: %s", info->url);
1.246 - }
1.247 - if (pl->GetStatus() >= Plugin_Error)
1.248 - {
1.249 - g_RootMenu.ConsolePrint(" Debugging: %s", pl->IsDebugging() ? "yes" : "no");
1.250 - }
1.251 -
1.252 - iter->Release();
1.253
1.254 return;
1.255 } else if (strcmp(cmd, "debug") == 0) {