From 30956eae5bb3547d62edbeb286eb361cc3ea3236 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 10 Nov 2006 18:08:13 +0000 Subject: [PATCH] added plugin sys initial import --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40178 --- core/systems/PluginSys.cpp | 170 +++++++++++++++++++++++++++++++++++++ core/systems/PluginSys.h | 52 ++++++++++++ 2 files changed, 222 insertions(+) create mode 100644 core/systems/PluginSys.cpp create mode 100644 core/systems/PluginSys.h diff --git a/core/systems/PluginSys.cpp b/core/systems/PluginSys.cpp new file mode 100644 index 00000000..487ebc32 --- /dev/null +++ b/core/systems/PluginSys.cpp @@ -0,0 +1,170 @@ +#include +#include "PluginSys.h" + +using namespace SourcePawn; + +CPlugin *CPlugin::CreatePlugin(const char *file, + bool debug_default, + PluginLifetime life, + char *error, + size_t maxlen) +{ + static unsigned int MySerial = 0; + FILE *fp = fopen(file, "rb"); + + if (!fp) + { + snprintf(error, maxlen, "Could not open file"); + return NULL; + } + + int err; + sp_plugin_t *pl = g_pSourcePawn->LoadFromFilePointer(fp, &err); + if (pl == NULL) + { + snprintf(error, maxlen, "Could not load plugin, error %d", err); + return NULL; + } + + fclose(fp); + + ICompilation *co = g_pVM->StartCompilation(pl); + + if (debug_default) + { + if (!g_pVM->SetCompilationOption(co, "debug", "1")) + { + g_pVM->AbortCompilation(co); + snprintf(error, maxlen, "Could not set plugin to debug mode"); + return NULL; + } + } + + sp_context_t *ctx = g_pVM->CompileToContext(co, &err); + if (ctx == NULL) + { + snprintf(error, maxlen, "Plugin failed to load, JIT error: %d", err); + return NULL; + } + + IPluginContext *base = g_pSourcePawn->CreateBaseContext(ctx); + CPlugin *pPlugin = new CPlugin; + + snprintf(pPlugin->m_filename, PLATFORM_MAX_PATH, "%s", file); + pPlugin->m_debugging = debug_default; + pPlugin->m_ctx_current.base = base; + pPlugin->m_ctx_current.ctx = ctx; + pPlugin->m_lifetime = life; + pPlugin->m_lock = false; + pPlugin->m_serial = ++MySerial; + pPlugin->m_status = Plugin_Loaded; + pPlugin->m_plugin = pl; + + pPlugin->UpdateInfo(); + + return pPlugin; +} + +void CPlugin::UpdateInfo() +{ + /* Now grab the info */ + uint32_t idx; + IPluginContext *base = GetBaseContext(); + int err = base->FindPubvarByName("myinfo", &idx); + + if (err == SP_ERROR_NONE) + { + struct sm_plugininfo_c_t + { + cell_t name; + cell_t description; + cell_t author; + cell_t version; + cell_t url; + }; + sm_plugininfo_c_t *cinfo; + cell_t local_addr; + + base->GetPubvarAddrs(idx, &local_addr, (cell_t **)&cinfo); + base->LocalToString(cinfo->name, (char **)&m_info.name); + base->LocalToString(cinfo->description, (char **)&m_info.description); + base->LocalToString(cinfo->author, (char **)&m_info.author); + base->LocalToString(cinfo->url, (char **)&m_info.url); + base->LocalToString(cinfo->version, (char **)&m_info.version); + } + + m_info.author = m_info.author ? m_info.author : ""; + m_info.description = m_info.description ? m_info.description : ""; + m_info.name = m_info.name ? m_info.name : ""; + m_info.url = m_info.url ? m_info.url : ""; + m_info.version = m_info.version ? m_info.version : ""; +} + +const sp_plugin_t *CPlugin::GetPluginStructure() const +{ + return m_plugin; +} + +IPluginContext *CPlugin::GetBaseContext() const +{ + return m_ctx_current.base; +} + +sp_context_t *CPlugin::GetContext() const +{ + return m_ctx_current.ctx; +} + +const char *CPlugin::GetFilename() const +{ + return m_filename; +} + +PluginLifetime CPlugin::GetLifetime() const +{ + return m_lifetime; +} + +bool CPlugin::GetLockForUpdates() const +{ + return m_lock; +} + +const sm_plugininfo_t *CPlugin::GetPublicInfo() const +{ + return &m_info; +} + +unsigned int CPlugin::GetSerial() const +{ + return m_serial; +} + +PluginStatus CPlugin::GetStatus() const +{ + return m_status; +} + +bool CPlugin::IsDebugging() const +{ + return m_debugging; +} + +void CPlugin::SetLockForUpdates(bool lock_status) +{ + m_lock = lock_status; +} + +bool CPlugin::SetPauseState(bool paused) +{ + if (paused && GetStatus() != Plugin_Paused) + { + return false; + } else if (!paused && GetStatus() != Plugin_Running) { + return false; + } + + /* :TODO: execute some forwards or some crap */ + + return true; +} diff --git a/core/systems/PluginSys.h b/core/systems/PluginSys.h new file mode 100644 index 00000000..c2d24a5e --- /dev/null +++ b/core/systems/PluginSys.h @@ -0,0 +1,52 @@ +#ifndef _INCLUDE_SOURCEMOD_PLUGINSYSTEM_H_ +#define _INCLUDE_SOURCEMOD_PLUGINSYSTEM_H_ + +#include +#include "sm_globals.h" + +struct ContextPair +{ + ContextPair() : base(NULL), ctx(NULL) + { + }; + IPluginContext *base; + sp_context_t *ctx; +}; + +class CPlugin : public IPlugin +{ +public: + virtual PluginLifetime GetLifetime() const; + virtual SourcePawn::IPluginContext *GetBaseContext() const; + virtual sp_context_t *GetContext() const; + virtual const sm_plugininfo_t *GetPublicInfo() const; + virtual const char *GetFilename() const; + virtual bool IsDebugging() const; + virtual PluginStatus GetStatus() const; + virtual bool SetPauseState(bool paused); + virtual void SetLockForUpdates(bool lock_status); + virtual bool GetLockForUpdates() const; + virtual unsigned int GetSerial() const; + virtual const sp_plugin_t *GetPluginStructure() const; +public: + static CPlugin *CreatePlugin(const char *file, + bool debug_default, + PluginLifetime life, + char *error, + size_t maxlen); +protected: + void UpdateInfo(); +private: + ContextPair m_ctx_current; + ContextPair m_ctx_backup; + PluginLifetime m_lifetime; + bool m_debugging; + char m_filename[PLATFORM_MAX_PATH+1]; + PluginStatus m_status; + bool m_lock; + unsigned int m_serial; + sm_plugininfo_t m_info; + sp_plugin_t *m_plugin; +}; + +#endif //_INCLUDE_SOURCEMOD_PLUGINSYSTEM_H_