/* * This file is a part of Winix * and is distributed under the 2-Clause BSD licence. * Author: Tomasz Sowa */ /* * Copyright (c) 2008-2018, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include "plugin.h" #include "misc.h" #include "system.h" #include "sessionmanager.h" #include "functions/functions.h" #include "templates/templates.h" #include "winixrequest.h" namespace Winix { /* * * PluginInfo * * */ void PluginInfo::set_dependency_for(WinixBase * winix_base) { plugin->SetDependencyFor(winix_base); } void PluginInfo::set_dependency_for(WinixBase & winix_base) { set_dependency_for(&winix_base); } void PluginInfo::set_dependency_for(WinixModelDeprecated * winix_model) { plugin->SetDependencyFor(winix_model); //model_connector = winix_model->get_model_connector(); // CHECKME what about model_connector here? } void PluginInfo::set_dependency_for(WinixModelDeprecated & winix_model) { set_dependency_for(&winix_model); } /* * * Plugin * * */ void Plugin::UnloadPlugins() { size_t i; slots.clear(); for(i=0 ; iwinix_request = winix_request; } void Plugin::Lock() { if( synchro ) synchro->Lock(); } void Plugin::Unlock() { if( synchro ) synchro->Unlock(); } bool Plugin::SetDependency(PluginInfo & info) { // for safety we call a plugin function only when all our pointers are not null bool res = (db && config && cur && system && functions && templates && synchro && session_manager && winix_request); if( !res ) { log << log1 << "Plugin: cannot call a function - some of the winix pointers are null" << logend; } info.db = db; info.config = config; info.cur = cur; info.system = system; info.functions = functions; info.templates = templates; info.synchro = synchro; info.session_manager = session_manager; info.plugin = this; /* * FIXME * if we call a message from a different thread then a different model connector is needed * (each thread should have its own model connector) * */ info.model_connector = system->get_model_connector(); info.log.SetDependency(&log); return res; } void Plugin::SetDependencyFor(WinixBase * winix_base) { winix_base->set_dependency(winix_request); } void Plugin::SetDependencyFor(WinixModelDeprecated * winix_model) { winix_model->set_dependency(winix_request); } void Plugin::LoadPlugins(const std::wstring & plugins_dir, const std::vector & plugins) { for(size_t i=0 ; i(info.p1); plugins.push_back(item); current_plugin = old_current_plugin; } void Plugin::LoadPlugin(const std::wstring & filename) { LoadPlugin(filename.c_str()); } bool Plugin::HasPlugin(const wchar_t * name) { if( *name == 0 ) return false; for(size_t i=0 ; isecond.index; info.plugin_id = current_plugin; info.session = ses; if( current_plugin != -1 && ses ) info.plugin_data_base = ses->plugin_data.Get(current_plugin); else info.plugin_data_base = 0; if( !slot->second.is_running ) { if( config->log_plugin_call ) { log << log1 << "Plugin: calling plugin id: " << slot->second.index << ", message: " << message << logend; } slot->second.is_running = true; if( slot->second.fun1 ) slot->second.fun1(info); if( slot->second.fun2 ) slot->second.fun2(); slot->second.is_running = false; if( config->log_plugin_call ) { log << log1 << "Plugin: returning from plugin id: " << slot->second.index << ", message: " << message << ", result: " << (info.res? "true" : "false") << logend; } } else { log << log1 << "Plugin: id: " << slot->second.index << ", message: " << message << ", recurrences are not allowed" << logend; } } PluginRes Plugin::Call(Session * ses, int message, void * p1_, void * p2_, long l1_, long l2_) { PluginRes res; int old_current_plugin = current_plugin; PluginInfo info; Slots::iterator i = slots.lower_bound(message); for( ; i!=slots.end() && i->first==message ; ++i ) { info.Clear(); info.p1 = p1_; info.p2 = p2_; info.l1 = l1_; info.l2 = l2_; Call(ses, message, i, info); if( info.res ) ++res.res_true; else ++res.res_false; } current_plugin = old_current_plugin; return res; } PluginRes Plugin::Call(int message) { return Call(cur->session, message, 0, 0, 0, 0); } PluginRes Plugin::Call(int message, void * p1_) { return Call(cur->session, message, p1_, 0, 0, 0); } PluginRes Plugin::Call(int message, void * p1_, void * p2_) { return Call(cur->session, message, p1_, p2_, 0, 0); } PluginRes Plugin::Call(int message, long l1_) { return Call(cur->session, message, 0, 0, l1_, 0); } PluginRes Plugin::Call(int message, long l1_, long l2_) { return Call(cur->session, message, 0, 0, l1_, l2_); } PluginRes Plugin::Call(int message, void * p1_, long l1_) { return Call(cur->session, message, p1_, 0, l1_, 0); } PluginRes Plugin::Call(int message, void * p1_, long l1_, long l2_) { return Call(cur->session, message, p1_, 0, l1_, l2_); } PluginRes Plugin::Call(int message, void * p1_, void * p2_, long l1_) { return Call(cur->session, message, p1_, p2_, l1_, 0); } PluginRes Plugin::Call(Session * ses, int message) { return Call(ses, message, 0, 0, 0, 0); } PluginRes Plugin::Call(Session * ses, int message, void * p1_) { return Call(ses, message, p1_, 0, 0, 0); } PluginRes Plugin::Call(Session * ses, int message, void * p1_, void * p2_) { return Call(ses, message, p1_, p2_, 0, 0); } PluginRes Plugin::Call(Session * ses, int message, long l1_) { return Call(ses, message, 0, 0, l1_, 0); } PluginRes Plugin::Call(Session * ses, int message, long l1_, long l2_) { return Call(ses, message, 0, 0, l1_, l2_); } PluginRes Plugin::Call(Session * ses, int message, void * p1_, long l1_) { return Call(ses, message, p1_, 0, l1_, 0); } PluginRes Plugin::Call(Session * ses, int message, void * p1_, long l1_, long l2_) { return Call(ses, message, p1_, 0, l1_, l2_); } PluginRes Plugin::Call(Session * ses, int message, void * p1_, void * p2_, long l1_) { return Call(ses, message, p1_, p2_, l1_, 0); } size_t Plugin::Size() { return plugins.size(); } /* !! IMPROVE ME Assign() can work only if other threads are not started we can add some barrier/flag so when other threads starts then we cannot use Assign() method */ void Plugin::Assign(int message, Fun1 fun1) { Slot s; if( current_plugin == -1 ) return; s.fun1 = fun1; s.index = current_plugin; slots.insert( std::make_pair(message, s) ); log << log3 << "Plugin: added function for message: " << message << ", plugin index: " << s.index << logend; } void Plugin::Assign(int message, Fun2 fun2) { Slot s; if( current_plugin == -1 ) return; s.fun2 = fun2; s.index = current_plugin; slots.insert( std::make_pair(message, s) ); log << log3 << "Plugin: added function for message: " << message << ", plugin index: " << s.index << logend; } const Plugin::Plugins * Plugin::GetPlugins() { return &plugins; } } // namespace Winix