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