winix/core/plugin.cpp

157 lines
2.5 KiB
C++
Executable File

/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2008-2010, Tomasz Sowa
* All rights reserved.
*
*/
#include <dlfcn.h>
#include "plugin.h"
#include "pluginmsg.h"
void Plugin::UnloadPlugins()
{
size_t i;
slots.clear();
for(i=0 ; i<plugins.size() ; ++i)
dlclose(plugins[i]);
plugins.clear();
}
Plugin::Plugin()
{
current_plugin = -1;
}
Plugin::~Plugin()
{
UnloadPlugins();
}
void Plugin::LoadPlugins(const std::vector<std::string> & plugins)
{
size_t i;
for(i=0 ; i<plugins.size() ; ++i)
LoadPlugin(plugins[i]);
}
void Plugin::LoadPlugin(const std::string & filename)
{
LoadPlugin(filename.c_str());
}
void Plugin::LoadPlugin(const char * filename)
{
void * p = dlopen(filename, RTLD_NOW | RTLD_LOCAL);
if( !p )
{
log << log1 << "Pl: cannot load a plugin: " << filename << logend;
/*
const char * t = dlerror();
if( t )
log << log1 << t << logend;
*/
return;
}
Fun fun = (Fun)dlfunc(p, "Init");
if( !fun )
{
log << log1 << "Pl: cannot load a plugin: " << filename << " (there is no Init() function)" << logend;
dlclose(p);
return;
}
arg.Clear();
int old_current_plugin = current_plugin;
current_plugin = (int)plugins.size();
arg.plugin_id = current_plugin;
if( fun(&arg) )
{
log << log1 << "Pl: plugin loaded: " << filename << ", index: " << plugins.size() << logend;
plugins.push_back(p);
}
else
{
log << log1 << "Pl: plugin Init() returned false (" << filename << ") " << logend;
dlclose(p);
}
current_plugin = old_current_plugin;
}
Arg * Plugin::Call(int message, void * a, void * a2, void * a3)
{
Slots::iterator i = slots.lower_bound(message);
arg.Clear();
int old_current_plugin = current_plugin;
for( ; i!=slots.end() && i->first==message ; ++i )
{
arg.app = a;
arg.app2 = a2;
arg.app3 = a3;
current_plugin = i->second.index;
arg.plugin_id = current_plugin;
if( request.session && current_plugin != -1 )
arg.plugin_data_base = request.session->plugin_data.Get(current_plugin);
else
arg.plugin_data_base = 0;
if( i->second.fun(&arg) )
arg.ret_true++;
else
arg.ret_false++;
}
current_plugin = old_current_plugin;
return &arg;
}
size_t Plugin::Size()
{
return plugins.size();
}
void Plugin::Assign(int message, Fun fun)
{
Slot s;
s.fun = fun;
s.index = current_plugin;
slots.insert( std::make_pair(message, s) );
log << log3 << "Plugin: added function for message: " << message << ", plugin index: " << s.index << logend;
}