core/sourcemod.cpp
author David Anderson <dvander@alliedmods.net>
Sat Nov 11 05:49:52 2006 +0000 (2006-11-11)
changeset 176 c1699993453c
parent 160 c056af9b4aaf
child 177 d29ade52d953
permissions -rw-r--r--
Implemented a lot more of the plugin system
added aggressive caching O(1) function object retrieval
     1 #include <stdio.h>
     2 #include "sourcemod.h"
     3 #include "sourcemm_api.h"
     4 #include "systems/LibrarySys.h"
     5 #include "vm/sp_vm_engine.h"
     6 #include <sh_string.h>
     7 #include "PluginSys.h"
     8 
     9 SourcePawnEngine g_SourcePawn;
    10 SourceModBase g_SourceMod;
    11 
    12 ILibrary *g_pJIT = NULL;
    13 SourceHook::String g_BaseDir;
    14 ISourcePawnEngine *g_pSourcePawn = &g_SourcePawn;
    15 IVirtualMachine *g_pVM;
    16 
    17 typedef int (*GIVEENGINEPOINTER)(ISourcePawnEngine *);
    18 typedef unsigned int (*GETEXPORTCOUNT)();
    19 typedef IVirtualMachine *(*GETEXPORT)(unsigned int);
    20 typedef void (*NOTIFYSHUTDOWN)();
    21 
    22 void ShutdownJIT()
    23 {
    24 	NOTIFYSHUTDOWN notify = (NOTIFYSHUTDOWN)g_pJIT->GetSymbolAddress("NotifyShutdown");
    25 	if (notify)
    26 	{
    27 		notify();
    28 	}
    29 
    30 	g_pJIT->CloseLibrary();
    31 }
    32 
    33 bool SourceModBase::InitializeSourceMod(char *error, size_t err_max, bool late)
    34 {
    35 	//:TODO: we need a localinfo system!
    36 	g_BaseDir.assign(g_SMAPI->GetBaseDir());
    37 
    38 	/* Attempt to load the JIT! */
    39 	char file[PLATFORM_MAX_PATH];
    40 	char myerror[255];
    41 	g_SMAPI->PathFormat(file, sizeof(file), "%s/addons/sourcemod/bin/sourcepawn.jit.x86.%s",
    42 		g_BaseDir.c_str(),
    43 		PLATFORM_LIB_EXT
    44 		);
    45 
    46 	g_pJIT = g_LibSys.OpenLibrary(file, myerror, sizeof(myerror));
    47 	if (!g_pJIT)
    48 	{
    49 		if (error && err_max)
    50 		{
    51 			snprintf(error, err_max, "%s (failed to load bin/sourcepawn.jit.x86.%s)", 
    52 				myerror,
    53 				PLATFORM_LIB_EXT);
    54 		}
    55 		return false;
    56 	}
    57 
    58 	int err;
    59 	GIVEENGINEPOINTER jit_init = (GIVEENGINEPOINTER)g_pJIT->GetSymbolAddress("GiveEnginePointer");
    60 	if (!jit_init)
    61 	{
    62 		ShutdownJIT();
    63 		if (error && err_max)
    64 		{
    65 			snprintf(error, err_max, "Failed to find GiveEnginePointer in JIT!");
    66 		}
    67 		return false;
    68 	}
    69 
    70 	if ((err=jit_init(g_pSourcePawn)) != 0)
    71 	{
    72 		ShutdownJIT();
    73 		if (error && err_max)
    74 		{
    75 			snprintf(error, err_max, "GiveEnginePointer returned %d in the JIT", err);
    76 		}
    77 		return false;
    78 	}
    79 
    80 	GETEXPORTCOUNT jit_getnum = (GETEXPORTCOUNT)g_pJIT->GetSymbolAddress("GetExportCount");
    81 	GETEXPORT jit_get = (GETEXPORT)g_pJIT->GetSymbolAddress("GetExport");
    82 	if (!jit_get)
    83 	{
    84 		ShutdownJIT();
    85 		if (error && err_max)
    86 		{
    87 			snprintf(error, err_max, "JIT is missing a necessary export!");
    88 		}
    89 		return false;
    90 	}
    91 
    92 	unsigned int num = jit_getnum();
    93 	if (!num || ((g_pVM=jit_get(0)) == NULL))
    94 	{
    95 		ShutdownJIT();
    96 		if (error && err_max)
    97 		{
    98 			snprintf(error, err_max, "JIT did not export any virtual machines!");
    99 		}
   100 		return false;
   101 	}
   102 
   103 	unsigned int api = g_pVM->GetAPIVersion();
   104 	if (api != SOURCEPAWN_VM_API_VERSION)
   105 	{
   106 		ShutdownJIT();
   107 		if (error && err_max)
   108 		{
   109 			snprintf(error, err_max, "JIT is not a compatible version");
   110 		}
   111 		return false;
   112 	}
   113 
   114 	g_SMAPI->PathFormat(file, sizeof(file), "%s/addons/sourcemod/plugins/test.smx", g_BaseDir.c_str());
   115 	IPlugin *pPlugin = g_PluginMngr.LoadPlugin(file, false, PluginType_Global, error, err_max);
   116 	IPluginFunction *func = pPlugin->GetFunctionByName("OnPluginInit");
   117 	cell_t result;
   118 	func->CallFunction(NULL, 0, &result);
   119 	g_PluginMngr.UnloadPlugin(pPlugin);
   120 
   121 	return true;
   122 }