1.1 --- a/core/systems/ExtensionSys.cpp Thu Jan 18 21:07:10 2007 +0000
1.2 +++ b/core/systems/ExtensionSys.cpp Thu Jan 18 23:28:14 2007 +0000
1.3 @@ -17,6 +17,7 @@
1.4 m_pIdentToken = NULL;
1.5 m_PlId = 0;
1.6 unload_code = 0;
1.7 + m_FullyLoaded = false;
1.8
1.9 char path[PLATFORM_MAX_PATH+1];
1.10 g_LibSys.PathFormat(path, PLATFORM_MAX_PATH, "%s/extensions/%s", g_SourceMod.GetSMBaseDir(), filename);
1.11 @@ -56,7 +57,7 @@
1.12
1.13 m_pIdentToken = g_ShareSys.CreateIdentity(g_ExtType);
1.14
1.15 - if (!m_pAPI->OnExtensionLoad(this, &g_ShareSys, error, err_max, g_SourceMod.IsLateLoadInMap()))
1.16 + if (!m_pAPI->OnExtensionLoad(this, &g_ShareSys, error, err_max, !g_SourceMod.IsMapLoading()))
1.17 {
1.18 if (m_pAPI->IsMetamodExtension())
1.19 {
1.20 @@ -73,6 +74,12 @@
1.21 g_ShareSys.DestroyIdentity(m_pIdentToken);
1.22 m_pIdentToken = NULL;
1.23 return;
1.24 + } else {
1.25 + /* Check if we're past load time */
1.26 + if (!g_SourceMod.IsMapLoading())
1.27 + {
1.28 + m_pAPI->OnExtensionsAllLoaded();
1.29 + }
1.30 }
1.31 }
1.32
1.33 @@ -98,6 +105,16 @@
1.34 }
1.35 }
1.36
1.37 +void CExtension::MarkAllLoaded()
1.38 +{
1.39 + assert(m_FullyLoaded == false);
1.40 + if (!m_FullyLoaded)
1.41 + {
1.42 + m_FullyLoaded = true;
1.43 + m_pAPI->OnExtensionsAllLoaded();
1.44 + }
1.45 +}
1.46 +
1.47 void CExtension::AddPlugin(IPlugin *pPlugin)
1.48 {
1.49 m_Plugins.push_back(pPlugin);
1.50 @@ -204,6 +221,20 @@
1.51 m_Interfaces.push_back(pInterface);
1.52 }
1.53
1.54 +bool CExtension::IsRunning(char *error, size_t maxlength)
1.55 +{
1.56 + if (!IsLoaded())
1.57 + {
1.58 + if (error)
1.59 + {
1.60 + snprintf(error, maxlength, "%s", m_Error.c_str());
1.61 + }
1.62 + return false;
1.63 + }
1.64 +
1.65 + return m_pAPI->QueryRunning(error, maxlength);
1.66 +}
1.67 +
1.68 /*********************
1.69 * EXTENSION MANAGER *
1.70 *********************/
1.71 @@ -224,6 +255,13 @@
1.72
1.73 IExtension *CExtensionManager::LoadAutoExtension(const char *path)
1.74 {
1.75 + if (!strstr(path, "." PLATFORM_LIB_EXT))
1.76 + {
1.77 + char newpath[PLATFORM_MAX_PATH+1];
1.78 + snprintf(newpath, PLATFORM_MAX_PATH, "%s.%s", path, PLATFORM_LIB_EXT);
1.79 + return LoadAutoExtension(newpath);
1.80 + }
1.81 +
1.82 IExtension *pAlready;
1.83 if ((pAlready=FindExtensionByFile(path)) != NULL)
1.84 {
1.85 @@ -249,6 +287,13 @@
1.86 List<CExtension *>::iterator iter;
1.87 CExtension *pExt;
1.88
1.89 + if (!strstr(file, "." PLATFORM_LIB_EXT))
1.90 + {
1.91 + char path[PLATFORM_MAX_PATH];
1.92 + snprintf(path, PLATFORM_MAX_PATH, "%s.%s", file, PLATFORM_LIB_EXT);
1.93 + return FindExtensionByFile(path);
1.94 + }
1.95 +
1.96 /* Make sure the file direction is right */
1.97 char path[PLATFORM_MAX_PATH+1];
1.98 g_LibSys.PathFormat(path, PLATFORM_MAX_PATH, "%s", file);
1.99 @@ -315,6 +360,8 @@
1.100 return NULL;
1.101 }
1.102
1.103 + /* :TODO: do QueryRunning check if the map is loaded */
1.104 +
1.105 m_Libs.push_back(pExt);
1.106
1.107 return pExt;
1.108 @@ -372,6 +419,47 @@
1.109 return NULL;
1.110 }
1.111
1.112 +void CExtensionManager::BindAllNativesToPlugin(IPlugin *pPlugin)
1.113 +{
1.114 + List<CExtension *>::iterator iter;
1.115 + CExtension *pExt;
1.116 + IPluginContext *pContext = pPlugin->GetBaseContext();
1.117 + for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
1.118 + {
1.119 + pExt = (*iter);
1.120 + if (!pExt->IsLoaded())
1.121 + {
1.122 + continue;
1.123 + }
1.124 + if (!pExt->m_Natives.size())
1.125 + {
1.126 + continue;
1.127 + }
1.128 + bool set = false;
1.129 + List<const sp_nativeinfo_t *>::iterator n_iter;
1.130 + const sp_nativeinfo_t *natives;
1.131 + for (n_iter = pExt->m_Natives.begin();
1.132 + n_iter != pExt->m_Natives.end();
1.133 + n_iter++)
1.134 + {
1.135 + natives = (*n_iter);
1.136 + unsigned int i=0;
1.137 + while (natives[i].func != NULL && natives[i].name != NULL)
1.138 + {
1.139 + if (pContext->BindNative(&natives[i++]) == SP_ERROR_NONE)
1.140 + {
1.141 + set = true;
1.142 + }
1.143 + }
1.144 + }
1.145 + if (set && (pExt->m_Plugins.find(pPlugin) == pExt->m_Plugins.end()))
1.146 + {
1.147 + /* For now, mark this plugin as a requirement. Later we'll introduce native filtering. */
1.148 + pExt->m_Plugins.push_back(pPlugin);
1.149 + }
1.150 + }
1.151 +}
1.152 +
1.153 bool CExtensionManager::UnloadExtension(IExtension *_pExt)
1.154 {
1.155 if (!_pExt)
1.156 @@ -449,6 +537,33 @@
1.157 return true;
1.158 }
1.159
1.160 +void CExtensionManager::AddNatives(IExtension *pOwner, const sp_nativeinfo_t *natives)
1.161 +{
1.162 + CExtension *pExt = (CExtension *)pOwner;
1.163 +
1.164 + pExt->m_Natives.push_back(natives);
1.165 +}
1.166 +
1.167 +void CExtensionManager::MarkAllLoaded()
1.168 +{
1.169 + List<CExtension *>::iterator iter;
1.170 + CExtension *pExt;
1.171 +
1.172 + for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
1.173 + {
1.174 + pExt = (*iter);
1.175 + if (!pExt->IsLoaded())
1.176 + {
1.177 + continue;
1.178 + }
1.179 + if (pExt->m_FullyLoaded)
1.180 + {
1.181 + continue;
1.182 + }
1.183 + pExt->MarkAllLoaded();
1.184 + }
1.185 +}
1.186 +
1.187 void CExtensionManager::OnRootConsoleCommand(const char *cmd, unsigned int argcount)
1.188 {
1.189 if (argcount >= 3)
1.190 @@ -482,11 +597,17 @@
1.191 pExt = (*iter);
1.192 if (pExt->IsLoaded())
1.193 {
1.194 - IExtensionInterface *pAPI = pExt->GetAPI();
1.195 - const char *name = pAPI->GetExtensionName();
1.196 - const char *version = pAPI->GetExtensionVerString();
1.197 - const char *descr = pAPI->GetExtensionDescription();
1.198 - g_RootMenu.ConsolePrint("[%02d] %s (%s): %s", num, name, version, descr);
1.199 + char error[255];
1.200 + if (!pExt->IsRunning(error, sizeof(error)))
1.201 + {
1.202 + g_RootMenu.ConsolePrint("[%02d] <FAILED> file \"%s\": %s", num, pExt->GetFilename(), error);
1.203 + } else {
1.204 + IExtensionInterface *pAPI = pExt->GetAPI();
1.205 + const char *name = pAPI->GetExtensionName();
1.206 + const char *version = pAPI->GetExtensionVerString();
1.207 + const char *descr = pAPI->GetExtensionDescription();
1.208 + g_RootMenu.ConsolePrint("[%02d] %s (%s): %s", num, name, version, descr);
1.209 + }
1.210 } else {
1.211 g_RootMenu.ConsolePrint("[%02d] <FAILED> file \"%s\": %s", num, pExt->GetFilename(), pExt->m_Error.c_str());
1.212 }
1.213 @@ -542,13 +663,21 @@
1.214 g_RootMenu.ConsolePrint(" File: %s", pExt->GetFilename());
1.215 g_RootMenu.ConsolePrint(" Loaded: No (%s)", pExt->m_Error.c_str());
1.216 } else {
1.217 - IExtensionInterface *pAPI = pExt->GetAPI();
1.218 - g_RootMenu.ConsolePrint(" File: %s", pExt->GetFilename());
1.219 - g_RootMenu.ConsolePrint(" Loaded: Yes (version %s)", pAPI->GetExtensionVerString());
1.220 - g_RootMenu.ConsolePrint(" Name: %s (%s)", pAPI->GetExtensionName(), pAPI->GetExtensionDescription());
1.221 - g_RootMenu.ConsolePrint(" Author: %s (%s)", pAPI->GetExtensionAuthor(), pAPI->GetExtensionURL());
1.222 - g_RootMenu.ConsolePrint(" Binary info: API version %d (compiled %s)", pAPI->GetExtensionVersion(), pAPI->GetExtensionDateString());
1.223 - g_RootMenu.ConsolePrint(" Metamod enabled: %s", pAPI->IsMetamodExtension() ? "yes" : "no");
1.224 + char error[255];
1.225 + if (!pExt->IsRunning(error, sizeof(error)))
1.226 + {
1.227 + g_RootMenu.ConsolePrint(" File: %s", pExt->GetFilename());
1.228 + g_RootMenu.ConsolePrint(" Loaded: Yes");
1.229 + g_RootMenu.ConsolePrint(" Running: No (%s)", error);
1.230 + } else {
1.231 + IExtensionInterface *pAPI = pExt->GetAPI();
1.232 + g_RootMenu.ConsolePrint(" File: %s", pExt->GetFilename());
1.233 + g_RootMenu.ConsolePrint(" Loaded: Yes (version %s)", pAPI->GetExtensionVerString());
1.234 + g_RootMenu.ConsolePrint(" Name: %s (%s)", pAPI->GetExtensionName(), pAPI->GetExtensionDescription());
1.235 + g_RootMenu.ConsolePrint(" Author: %s (%s)", pAPI->GetExtensionAuthor(), pAPI->GetExtensionURL());
1.236 + g_RootMenu.ConsolePrint(" Binary info: API version %d (compiled %s)", pAPI->GetExtensionVersion(), pAPI->GetExtensionDateString());
1.237 + g_RootMenu.ConsolePrint(" Metamod enabled: %s", pAPI->IsMetamodExtension() ? "yes" : "no");
1.238 + }
1.239 }
1.240 return;
1.241 } else if (strcmp(cmd, "unload") == 0) {