core/systems/PluginSys.h
author David Anderson <dvander@alliedmods.net>
Mon Jul 07 06:25:15 2008 +0000 (2008-07-07)
branchrefac-jit
changeset 2175 54a8411faaac
parent 2168 c24a6fa957db
permissions -rw-r--r--
amazingly, core now builds. it probably crashes horribly but i'll test tomorrow.
dvander@2168
     1
/**
dvander@2168
     2
 * vim: set ts=4 :
dvander@2168
     3
 * =============================================================================
dvander@2168
     4
 * SourceMod
dvander@2168
     5
 * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
dvander@2168
     6
 * =============================================================================
dvander@2168
     7
 *
dvander@2168
     8
 * This program is free software; you can redistribute it and/or modify it under
dvander@2168
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
dvander@2168
    10
 * Free Software Foundation.
dvander@2168
    11
 * 
dvander@2168
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
dvander@2168
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dvander@2168
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
dvander@2168
    15
 * details.
dvander@2168
    16
 *
dvander@2168
    17
 * You should have received a copy of the GNU General Public License along with
dvander@2168
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
dvander@2168
    19
 *
dvander@2168
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
dvander@2168
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
dvander@2168
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
dvander@2168
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
dvander@2168
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
dvander@2168
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
dvander@2168
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
dvander@2168
    27
 * or <http://www.sourcemod.net/license.php>.
dvander@2168
    28
 *
dvander@2168
    29
 * Version: $Id$
dvander@2168
    30
 */
dvander@2168
    31
dvander@2168
    32
#ifndef _INCLUDE_SOURCEMOD_PLUGINSYSTEM_H_
dvander@2168
    33
#define _INCLUDE_SOURCEMOD_PLUGINSYSTEM_H_
dvander@2168
    34
dvander@2168
    35
#include <time.h>
dvander@2168
    36
#include <errno.h>
dvander@2168
    37
#include <sys/stat.h>
dvander@2168
    38
#include <IPluginSys.h>
dvander@2168
    39
#include <IHandleSys.h>
dvander@2168
    40
#include <IForwardSys.h>
dvander@2168
    41
#include <sh_list.h>
dvander@2168
    42
#include <sh_stack.h>
dvander@2168
    43
#include <sh_vector.h>
dvander@2168
    44
#include <sh_string.h>
dvander@2168
    45
#include "sm_globals.h"
dvander@2168
    46
#include "PluginInfoDatabase.h"
dvander@2168
    47
#include "sm_trie.h"
dvander@2168
    48
#include "sourcemod.h"
dvander@2168
    49
#include <IRootConsoleMenu.h>
dvander@2168
    50
#if defined ORANGEBOX_BUILD
dvander@2168
    51
#include "convar_sm_ob.h"
dvander@2168
    52
#else
dvander@2168
    53
#include "convar_sm.h"
dvander@2168
    54
#endif
dvander@2168
    55
#include "ITranslator.h"
dvander@2168
    56
#include "NativeOwner.h"
dvander@2168
    57
#include "ShareSys.h"
dvander@2168
    58
dvander@2168
    59
using namespace SourceHook;
dvander@2168
    60
dvander@2168
    61
/**
dvander@2168
    62
 * NOTES:
dvander@2168
    63
 *
dvander@2168
    64
 * UPDATE 2008-03-11: These comments are horribly out of date.  They paint a good overall 
dvander@2168
    65
 * picture of how PluginSys works, but things like dependencies and fake natives have 
dvander@2168
    66
 * complicated things quite a bit.
dvander@2168
    67
 *
dvander@2168
    68
 *  Currently this system needs a lot of work but it's good skeletally.  Plugin creation 
dvander@2168
    69
 * is done without actually compiling anything.  This is done by Load functions in the 
dvander@2168
    70
 * manager.  This will need a rewrite when we add context switching.
dvander@2168
    71
 *
dvander@2168
    72
 *  The plugin object itself has a few things to note.  The most important is that it stores
dvander@2168
    73
 * a table of function objects.  The manager marshals allocation and freeing of these objects.
dvander@2168
    74
 * The plugin object can be in erroneous states, they are:
dvander@2168
    75
 *   Plugin_Error   --> Some error occurred any time during or after compilation.
dvander@2168
    76
 *						This error can be cleared since the plugin itself is valid.
dvander@2168
    77
 *						However, the state itself being set prevents any runtime action.
dvander@2168
    78
 *   Plugin_BadLoad	--> The plugin failed to load entirely and nothing can be done to save it.
dvander@2168
    79
 *
dvander@2168
    80
 *  If a plugin fails to load externally, it is never added to the internal tracker.  However, 
dvander@2168
    81
 * plugins that failed to load from the internal loading mechanism are always tracked.  This 
dvander@2168
    82
 * allows users to see which automatically loaded plugins failed, and makes the interface a bit
dvander@2168
    83
 * more flexible.
dvander@2168
    84
 *
dvander@2168
    85
 *  Once a plugin is compiled, it sets its own state to Plugin_Created.  This state is still invalid
dvander@2168
    86
 * for execution.  SourceMod is a two pass system, and even though the second pass is not implemented
dvander@2168
    87
 * yet, it is structured so Plugin_Created must be switched to Plugin_Running in the second pass.  When
dvander@2168
    88
 * implemented, a Created plugin will be switched to Error in the second pass if it not loadable.
dvander@2168
    89
 *
dvander@2168
    90
 *  The two pass loading mechanism is described below.  Modules/natives are not implemented yet.
dvander@2168
    91
 * PASS ONE: All loadable plugins are found and have the following steps performed:
dvander@2168
    92
 *			 1.  Loading and compilation is attempted.
dvander@2168
    93
 *			 2.  If successful, all natives from Core are added.
dvander@2168
    94
 *			 3.  OnPluginLoad() is called.
dvander@2168
    95
 *			 4.  If failed, any user natives are scrapped and the process halts here.
dvander@2168
    96
 *			 5.  If successful, the plugin is ready for Pass 2.
dvander@2168
    97
 * INTERMEDIATE:
dvander@2168
    98
 *			 1.  All forced modules are loaded.
dvander@2168
    99
 * PASS TWO: All loaded plugins are found and have these steps performed:
dvander@2168
   100
 *			 1. Any modules referenced in the plugin that are not already loaded, are loaded.
dvander@2168
   101
 *			 2. If any module fails to load and the plugin requires it, load fails and jump to step 6.
dvander@2168
   102
 *			 3. If any natives are unresolved, check if they are found in the user-natives pool.
dvander@2168
   103
 *			 4. If yes, load succeeds.  If not, natives are passed through a native acceptance filter.
dvander@2168
   104
 *			 5. If the filter fails, the plugin is marked as failed.
dvander@2168
   105
 *			 6. If the plugin has failed to load at this point, any dynamic natives it has added are scrapped.
dvander@2168
   106
 *			    Furthermore, any plugin that referenced these natives must now have pass 2 re-ran.
dvander@2168
   107
 * PASS THREE (not a real pass):
dvander@2168
   108
 *			 7. Once all plugins are deemed to be loaded, OnPluginStart() is called
dvander@2168
   109
 */
dvander@2168
   110
dvander@2168
   111
enum LoadRes
dvander@2168
   112
{
dvander@2168
   113
	LoadRes_Successful,
dvander@2168
   114
	LoadRes_AlreadyLoaded,
dvander@2168
   115
	LoadRes_Failure,
dvander@2168
   116
	LoadRes_NeverLoad
dvander@2168
   117
};
dvander@2168
   118
dvander@2168
   119
struct AutoConfig
dvander@2168
   120
{
dvander@2168
   121
	String autocfg;
dvander@2168
   122
	String folder;
dvander@2168
   123
	bool create;
dvander@2168
   124
};
dvander@2168
   125
dvander@2168
   126
class CPlugin;
dvander@2168
   127
dvander@2168
   128
class CPlugin : 
dvander@2168
   129
	public IPlugin,
dvander@2168
   130
	public CNativeOwner
dvander@2168
   131
{
dvander@2168
   132
	friend class CPluginManager;
dvander@2168
   133
	friend class CFunction;
dvander@2168
   134
public:
dvander@2168
   135
	CPlugin(const char *file);
dvander@2168
   136
	~CPlugin();
dvander@2168
   137
public:
dvander@2168
   138
	PluginType GetType();
dvander@2168
   139
	SourcePawn::IPluginContext *GetBaseContext();
dvander@2168
   140
	sp_context_t *GetContext();
dvander@2175
   141
	void *GetPluginStructure();
dvander@2168
   142
	const char *GetFilename();
dvander@2168
   143
	bool IsDebugging();
dvander@2168
   144
	PluginStatus GetStatus();
dvander@2175
   145
	const sm_plugininfo_t *GetPublicInfo();
dvander@2168
   146
	bool SetPauseState(bool paused);
dvander@2168
   147
	unsigned int GetSerial();
dvander@2168
   148
	IdentityToken_t *GetIdentity();
dvander@2168
   149
	unsigned int CalcMemUsage();
dvander@2168
   150
	bool SetProperty(const char *prop, void *ptr);
dvander@2168
   151
	bool GetProperty(const char *prop, void **ptr, bool remove=false);
dvander@2168
   152
	void DropEverything();
dvander@2175
   153
	SourcePawn::IPluginRuntime *GetRuntime();
dvander@2168
   154
public:
dvander@2168
   155
	/**
dvander@2168
   156
	 * Creates a plugin object with default values.
dvander@2168
   157
	 *   If an error buffer is specified, and an error occurs, the error will be copied to the buffer
dvander@2168
   158
	 * and NULL will be returned.
dvander@2168
   159
	 *   If an error buffer is not specified, the error will be copied to an internal buffer and 
dvander@2168
   160
	 * a valid (but error-stated) CPlugin will be returned.
dvander@2168
   161
	 */
dvander@2168
   162
	static CPlugin *CreatePlugin(const char *file, char *error, size_t maxlength);
dvander@2168
   163
public:
dvander@2168
   164
dvander@2168
   165
	/**
dvander@2168
   166
	 * Sets an error state on the plugin
dvander@2168
   167
	 */
dvander@2168
   168
	void SetErrorState(PluginStatus status, const char *error_fmt, ...);
dvander@2168
   169
dvander@2168
   170
	/**
dvander@2168
   171
	 * Initializes the plugin's identity information
dvander@2168
   172
	 */
dvander@2168
   173
	void InitIdentity();
dvander@2168
   174
dvander@2168
   175
	/**
dvander@2168
   176
	 * Calls the OnPluginLoad function, and sets any failed states if necessary.
dvander@2168
   177
	 * NOTE: Valid pre-states are: Plugin_Created
dvander@2168
   178
	 * NOTE: If validated, plugin state is changed to Plugin_Loaded
dvander@2168
   179
	 *
dvander@2168
   180
	 * If the error buffer is NULL, the error message is cached locally.
dvander@2168
   181
	 */
dvander@2168
   182
	bool Call_AskPluginLoad(char *error, size_t maxlength);
dvander@2168
   183
dvander@2168
   184
	/**
dvander@2168
   185
	 * Calls the OnPluginStart function.
dvander@2168
   186
	 * NOTE: Valid pre-states are: Plugin_Created
dvander@2168
   187
	 * NOTE: Post-state will be Plugin_Running
dvander@2168
   188
	 */
dvander@2168
   189
	void Call_OnPluginStart();
dvander@2168
   190
dvander@2168
   191
	/**
dvander@2168
   192
	 * Calls the OnPluginEnd function.
dvander@2168
   193
	 */
dvander@2168
   194
	void Call_OnPluginEnd();
dvander@2168
   195
dvander@2168
   196
	/**
dvander@2168
   197
	 * Calls the OnAllPluginsLoaded function.
dvander@2168
   198
	 */
dvander@2168
   199
	void Call_OnAllPluginsLoaded();
dvander@2168
   200
dvander@2168
   201
	/**
dvander@2168
   202
	 * Toggles debug mode in the plugin
dvander@2168
   203
	 */
dvander@2168
   204
	bool ToggleDebugMode(bool debug, char *error, size_t maxlength);
dvander@2168
   205
dvander@2168
   206
	/**
dvander@2168
   207
	 * Returns true if a plugin is usable.
dvander@2168
   208
	 */
dvander@2168
   209
	bool IsRunnable();
dvander@2168
   210
dvander@2168
   211
	/**
dvander@2168
   212
	 * Get languages info.
dvander@2168
   213
	 */
dvander@2168
   214
	IPhraseCollection *GetPhrases();
dvander@2168
   215
public:
dvander@2168
   216
	/**
dvander@2168
   217
	 * Returns the modification time during last plugin load.
dvander@2168
   218
	 */
dvander@2168
   219
	time_t GetTimeStamp();
dvander@2168
   220
dvander@2168
   221
	/**
dvander@2168
   222
	 * Returns the current modification time of the plugin file.
dvander@2168
   223
	 */
dvander@2168
   224
	time_t GetFileTimeStamp();
dvander@2168
   225
dvander@2168
   226
	/** 
dvander@2168
   227
	 * Returns true if the plugin was running, but is now invalid.
dvander@2168
   228
	 */
dvander@2168
   229
	bool WasRunning();
dvander@2168
   230
dvander@2168
   231
	Handle_t GetMyHandle();
dvander@2168
   232
dvander@2168
   233
	bool AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func);
dvander@2168
   234
	void AddConfig(bool autoCreate, const char *cfg, const char *folder);
dvander@2168
   235
	unsigned int GetConfigCount();
dvander@2168
   236
	AutoConfig *GetConfig(unsigned int i);
dvander@2168
   237
	inline void AddLibrary(const char *name)
dvander@2168
   238
	{
dvander@2168
   239
		m_Libraries.push_back(name);
dvander@2168
   240
	}
dvander@2168
   241
	void LibraryActions(bool dropping);
dvander@2168
   242
protected:
dvander@2168
   243
	void UpdateInfo();
dvander@2168
   244
	void SetTimeStamp(time_t t);
dvander@2168
   245
	void DependencyDropped(CPlugin *pOwner);
dvander@2168
   246
private:
dvander@2168
   247
	PluginType m_type;
dvander@2168
   248
	char m_filename[PLATFORM_MAX_PATH];
dvander@2168
   249
	PluginStatus m_status;
dvander@2168
   250
	unsigned int m_serial;
dvander@2168
   251
	sm_plugininfo_t m_info;
dvander@2168
   252
	char m_errormsg[256];
dvander@2168
   253
	time_t m_LastAccess;
dvander@2168
   254
	IdentityToken_t *m_ident;
dvander@2168
   255
	Handle_t m_handle;
dvander@2168
   256
	bool m_WasRunning;
dvander@2168
   257
	IPhraseCollection *m_pPhrases;
dvander@2168
   258
	List<String> m_RequiredLibs;
dvander@2168
   259
	List<String> m_Libraries;
dvander@2168
   260
	Trie *m_pProps;
dvander@2168
   261
	bool m_FakeNativesMissing;
dvander@2168
   262
	bool m_LibraryMissing;
dvander@2168
   263
	CVector<AutoConfig *> m_configs;
dvander@2168
   264
	bool m_bGotAllLoaded;
dvander@2168
   265
	int m_FileVersion;
dvander@2168
   266
	char m_DateTime[256];
dvander@2175
   267
	IPluginRuntime *m_pRuntime;
dvander@2175
   268
	IPluginContext *m_pContext;
dvander@2168
   269
};
dvander@2168
   270
dvander@2168
   271
class CPluginManager : 
dvander@2168
   272
	public IPluginManager,
dvander@2168
   273
	public SMGlobalClass,
dvander@2168
   274
	public IHandleTypeDispatch,
dvander@2168
   275
	public IRootConsoleCommand
dvander@2168
   276
{
dvander@2168
   277
	friend class CPlugin;
dvander@2168
   278
public:
dvander@2168
   279
	CPluginManager();
dvander@2168
   280
	~CPluginManager();
dvander@2168
   281
public:
dvander@2168
   282
	/* Implements iterator class */
dvander@2168
   283
	class CPluginIterator : public IPluginIterator
dvander@2168
   284
	{
dvander@2168
   285
	public:
dvander@2168
   286
		CPluginIterator(List<CPlugin *> *mylist);
dvander@2168
   287
		virtual ~CPluginIterator();
dvander@2168
   288
		virtual bool MorePlugins();
dvander@2168
   289
		virtual IPlugin *GetPlugin();
dvander@2168
   290
		virtual void NextPlugin();
dvander@2168
   291
		void Release();
dvander@2168
   292
	public:
dvander@2168
   293
		void Reset();
dvander@2168
   294
	private:
dvander@2168
   295
		List<CPlugin *> *mylist;
dvander@2168
   296
		List<CPlugin *>::iterator current;
dvander@2168
   297
	};
dvander@2168
   298
	friend class CPluginManager::CPluginIterator;
dvander@2168
   299
public: //IPluginManager
dvander@2168
   300
	IPlugin *LoadPlugin(const char *path, 
dvander@2168
   301
								bool debug,
dvander@2168
   302
								PluginType type,
dvander@2168
   303
								char error[],
dvander@2168
   304
								size_t maxlength,
dvander@2168
   305
								bool *wasloaded);
dvander@2168
   306
	bool UnloadPlugin(IPlugin *plugin);
dvander@2168
   307
	IPlugin *FindPluginByContext(const sp_context_t *ctx);
dvander@2168
   308
	unsigned int GetPluginCount();
dvander@2168
   309
	IPluginIterator *GetPluginIterator();
dvander@2168
   310
	void AddPluginsListener(IPluginsListener *listener);
dvander@2168
   311
	void RemovePluginsListener(IPluginsListener *listener);
dvander@2168
   312
public: //SMGlobalClass
dvander@2168
   313
	void OnSourceModAllInitialized();
dvander@2168
   314
	void OnSourceModShutdown();
dvander@2168
   315
public: //IHandleTypeDispatch
dvander@2168
   316
	void OnHandleDestroy(HandleType_t type, void *object);
dvander@2168
   317
	bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize);
dvander@2168
   318
public: //IRootConsoleCommand
dvander@2168
   319
	void OnRootConsoleCommand(const char *cmdname, const CCommand &command);
dvander@2168
   320
public:
dvander@2168
   321
	/**
dvander@2168
   322
	 * Loads all plugins not yet loaded
dvander@2168
   323
	 */
dvander@2168
   324
	void LoadAll_FirstPass(const char *config, const char *basedir);
dvander@2168
   325
dvander@2168
   326
	/**
dvander@2168
   327
	 * Runs the second loading pass for all plugins
dvander@2168
   328
	 */
dvander@2168
   329
	void LoadAll_SecondPass();
dvander@2168
   330
dvander@2168
   331
	/**
dvander@2168
   332
	 * Tests a plugin file mask against a local folder.
dvander@2168
   333
	 * The alias is searched backwards from localdir - i.e., given this input:
dvander@2168
   334
	 *   csdm/ban        csdm/ban
dvander@2168
   335
	 *   ban             csdm/ban
dvander@2168
   336
	 *   csdm/ban        optional/csdm/ban
dvander@2168
   337
	 * All of these will return true for an alias match.  
dvander@2168
   338
	 * Wildcards are allowed in the filename.
dvander@2168
   339
	 */
dvander@2168
   340
	bool TestAliasMatch(const char *alias, const char *localdir);
dvander@2168
   341
dvander@2168
   342
	/** 
dvander@2168
   343
	 * Returns whether anything loaded will be a late load.
dvander@2168
   344
	 */
dvander@2168
   345
	bool IsLateLoadTime() const;
dvander@2168
   346
dvander@2168
   347
	/**
dvander@2168
   348
	 * Converts a Handle to an IPlugin if possible.
dvander@2168
   349
	 */
dvander@2168
   350
	IPlugin *PluginFromHandle(Handle_t handle, HandleError *err);
dvander@2168
   351
dvander@2168
   352
	/**
dvander@2168
   353
	 * Finds a plugin based on its index. (starts on index 1)
dvander@2168
   354
	 */
dvander@2168
   355
	CPlugin *GetPluginByOrder(int num);
dvander@2168
   356
dvander@2168
   357
	int GetOrderOfPlugin(IPlugin *pl);
dvander@2168
   358
dvander@2168
   359
	/** 
dvander@2168
   360
	 * Internal version of FindPluginByContext()
dvander@2168
   361
	 */
dvander@2175
   362
	CPlugin *GetPluginByCtx(const sp_context_t *ctx);
dvander@2168
   363
dvander@2168
   364
	/**
dvander@2168
   365
	 * Gets status text for a status code 
dvander@2168
   366
	 */
dvander@2168
   367
	const char *GetStatusText(PluginStatus status);
dvander@2168
   368
dvander@2168
   369
	/**
dvander@2168
   370
	* Reload or update plugins on level shutdown.
dvander@2168
   371
	*/
dvander@2168
   372
	void ReloadOrUnloadPlugins();
dvander@2168
   373
dvander@2168
   374
	/**
dvander@2168
   375
	 * Add public functions from all running or paused
dvander@2168
   376
	 * plugins to the specified forward if the names match.
dvander@2168
   377
	 */
dvander@2168
   378
	void AddFunctionsToForward(const char *name, IChangeableForward *pForward);
dvander@2168
   379
dvander@2168
   380
	/**
dvander@2168
   381
	 * Iterates through plugins to call OnAllPluginsLoaded.
dvander@2168
   382
	 */
dvander@2168
   383
	void AllPluginsLoaded();
dvander@2168
   384
dvander@2168
   385
	CPlugin *GetPluginFromIdentity(IdentityToken_t *pToken);
dvander@2168
   386
dvander@2168
   387
	void Shutdown();
dvander@2168
   388
dvander@2168
   389
	void OnLibraryAction(const char *lib, bool is_a_plugin, bool drop);
dvander@2168
   390
dvander@2168
   391
	bool LibraryExists(const char *lib);
dvander@2168
   392
dvander@2168
   393
	bool ReloadPlugin(CPlugin *pl);
dvander@2168
   394
dvander@2168
   395
	void UnloadAll();
dvander@2168
   396
dvander@2168
   397
	CPlugin *FindPluginByConsoleArg(const char *arg);
dvander@2168
   398
private:
dvander@2168
   399
	LoadRes _LoadPlugin(CPlugin **pPlugin, const char *path, bool debug, PluginType type, char error[], size_t maxlength);
dvander@2168
   400
dvander@2168
   401
	void LoadAutoPlugin(const char *plugin);
dvander@2168
   402
dvander@2168
   403
	/**
dvander@2168
   404
	 * Recursively loads all plugins in the given directory.
dvander@2168
   405
	 */
dvander@2168
   406
	void LoadPluginsFromDir(const char *basedir, const char *localdir);
dvander@2168
   407
dvander@2168
   408
	/**
dvander@2168
   409
	 * Adds a plugin object.  This is wrapped by LoadPlugin functions.
dvander@2168
   410
	 */
dvander@2168
   411
	void AddPlugin(CPlugin *pPlugin);
dvander@2168
   412
dvander@2168
   413
	/**
dvander@2168
   414
	 * Runs the second loading pass on a plugin.
dvander@2168
   415
	 */
dvander@2168
   416
	bool RunSecondPass(CPlugin *pPlugin, char *error, size_t maxlength);
dvander@2168
   417
dvander@2168
   418
	/**
dvander@2168
   419
	 * Runs an extension pass on a plugin.
dvander@2168
   420
	 */
dvander@2168
   421
	bool LoadOrRequireExtensions(CPlugin *pPlugin, unsigned int pass, char *error, size_t maxlength);
dvander@2168
   422
dvander@2168
   423
	/**
dvander@2168
   424
	* Manages required natives.
dvander@2168
   425
	*/
dvander@2168
   426
	bool FindOrRequirePluginDeps(CPlugin *pPlugin, char *error, size_t maxlength);
dvander@2168
   427
dvander@2168
   428
	void _SetPauseState(CPlugin *pPlugin, bool pause);
dvander@2168
   429
protected:
dvander@2168
   430
	/**
dvander@2168
   431
	 * Caching internal objects
dvander@2168
   432
	 */
dvander@2168
   433
	void ReleaseIterator(CPluginIterator *iter);
dvander@2168
   434
public:
dvander@2168
   435
	inline IdentityToken_t *GetIdentity()
dvander@2168
   436
	{
dvander@2168
   437
		return m_MyIdent;
dvander@2168
   438
	}
dvander@2168
   439
private:
dvander@2168
   440
	void TryRefreshDependencies(CPlugin *pOther);
dvander@2168
   441
private:
dvander@2168
   442
	List<IPluginsListener *> m_listeners;
dvander@2168
   443
	List<CPlugin *> m_plugins;
dvander@2168
   444
	CStack<CPluginManager::CPluginIterator *> m_iters;
dvander@2168
   445
	CPluginInfoDatabase m_PluginInfo;
dvander@2168
   446
	Trie *m_LoadLookup;
dvander@2168
   447
	bool m_AllPluginsLoaded;
dvander@2168
   448
	IdentityToken_t *m_MyIdent;
dvander@2168
   449
dvander@2168
   450
	/* Dynamic native stuff */
dvander@2168
   451
	List<FakeNative *> m_Natives;
dvander@2168
   452
dvander@2168
   453
	bool m_LoadingLocked;
dvander@2168
   454
};
dvander@2168
   455
dvander@2168
   456
extern CPluginManager g_PluginSys;
dvander@2168
   457
dvander@2168
   458
#endif //_INCLUDE_SOURCEMOD_PLUGINSYSTEM_H_