core/systems/ExtensionSys.cpp
changeset 315 5f48300aa103
parent 311 31192ed0fe13
child 317 e5342c8a0cf4
     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) {