← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 3129: do away with dangerous lambdas in plugin callbacks

 

------------------------------------------------------------
revno: 3129
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Sun 2012-11-11 17:16:24 +0100
message:
  do away with dangerous lambdas in plugin callbacks
added:
  pluginsdk/cpp/pluginsdk/UI.cpp
  pluginsdk/cpp/pluginsdk/UI.h
modified:
  SConstruct
  plugins/Dev/Plugin.cpp
  plugins/Dev/Plugin.h
  plugins/Dev/SConscript
  plugins/Dev/pluginsdk.cpp
  plugins/Script/SConscript
  plugins/Test/SConscript
  pluginsdk/PluginDefs.h
  pluginsdk/cpp/pluginsdk/Config.cpp
  pluginsdk/cpp/pluginsdk/Config.h
  pluginsdk/cpp/pluginsdk/Core.cpp
  pluginsdk/cpp/pluginsdk/Core.h
  pluginsdk/cpp/pluginsdk/Hooks.cpp
  pluginsdk/cpp/pluginsdk/Hooks.h
  pluginsdk/cpp/pluginsdk/Logger.cpp
  pluginsdk/cpp/pluginsdk/Logger.h
  pluginsdk/cpp/pluginsdk/Util.cpp
  pluginsdk/cpp/pluginsdk/Util.h
  win32/PluginApiImpl.cpp


--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk

Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'SConstruct'
--- SConstruct	2012-11-08 17:36:44 +0000
+++ SConstruct	2012-11-11 16:16:24 +0000
@@ -14,8 +14,6 @@
 
 # TODO the ipa-cp-clone optimization is disabled; it causes a crash when starting a DL.
 
-# TODO the omit-frame-pointer is disabled; it causes freezes when using lambdas in plugin callbacks.
-
 # TODO add -Og when using GCC 4.8
 
 # TODO enable LTO when it doesn't ICE... (-flto)
@@ -26,7 +24,7 @@
 gcc_flags = {
 	'common': ['-g', '-Wall', '-Wextra', '-Wno-unused-parameter', '-Wno-unused-value', '-Wno-missing-field-initializers', '-Wno-address', '-Wno-unknown-pragmas', '-Wno-format', '-fexceptions', '-mthreads'],
 	'debug': [], 
-	'release' : ['-O3', '-fno-omit-frame-pointer', '-fno-ipa-cp-clone', '-mwindows']
+	'release' : ['-O3', '-fno-ipa-cp-clone', '-mwindows']
 }
 
 gcc_xxflags = {

=== modified file 'plugins/Dev/Plugin.cpp'
--- plugins/Dev/Plugin.cpp	2012-11-11 15:12:15 +0000
+++ plugins/Dev/Plugin.cpp	2012-11-11 16:16:24 +0000
@@ -23,12 +23,14 @@
 #include <pluginsdk/Core.h>
 #include <pluginsdk/Hooks.h>
 #include <pluginsdk/Logger.h>
+#include <pluginsdk/UI.h>
 #include <pluginsdk/Util.h>
 
 using dcapi::Config;
 using dcapi::Core;
 using dcapi::Hooks;
 using dcapi::Logger;
+using dcapi::UI;
 using dcapi::Util;
 
 Plugin* Plugin::instance = nullptr;
@@ -39,8 +41,8 @@
 Plugin::~Plugin() {
 	clearHooks();
 
-	if(ui) {
-		ui->remove_command(commandName.c_str());
+	if(UI::handle()) {
+		UI::removeCommand(commandName);
 	}
 }
 
@@ -101,16 +103,15 @@
 }
 
 void Plugin::refreshSwitchCommand() {
-	ui->remove_command(commandName.c_str());
+	UI::removeCommand(commandName);
 	commandName = Hooks::empty() ? PLUGIN_NAME ": enable" : PLUGIN_NAME ": disable";
-	ui->add_command(commandName.c_str(), [] { instance->onSwitched(); });
+	UI::addCommand(commandName, [this] { onSwitched(); });
 }
 
 void Plugin::onLoad(DCCorePtr core, bool install, Bool& loadRes) {
 	hubs = reinterpret_cast<DCHubPtr>(core->query_interface(DCINTF_DCPP_HUBS, DCINTF_DCPP_HUBS_VER));
-	ui = reinterpret_cast<DCUIPtr>(core->query_interface(DCINTF_DCPP_UI, DCINTF_DCPP_UI_VER));
 
-	if(!Config::init(core) || !Hooks::init(core) || !Logger::init(core) || !Util::init(core) || !hubs || !ui) {
+	if(!Config::init(core) || !Hooks::init(core) || !Logger::init(core) || !UI::init(core) || !Util::init(core) || !hubs) {
 		loadRes = False;
 		return;
 	}

=== modified file 'plugins/Dev/Plugin.h'
--- plugins/Dev/Plugin.h	2012-11-11 15:12:15 +0000
+++ plugins/Dev/Plugin.h	2012-11-11 16:16:24 +0000
@@ -51,7 +51,6 @@
 	bool onChatCommand(HubDataPtr hub, CommandDataPtr cmd);
 
 	DCHubPtr hubs;
-	DCUIPtr ui;
 
 	Dialog dialog;
 

=== modified file 'plugins/Dev/SConscript'
--- plugins/Dev/SConscript	2012-11-04 19:15:24 +0000
+++ plugins/Dev/SConscript	2012-11-11 16:16:24 +0000
@@ -7,10 +7,6 @@
 
 env.Append(CPPPATH = ['#/pluginsdk/cpp'])
 
-# TODO remove this when GCC stops whining about stateless lambdas
-if dev.is_win32() and 'gcc' in env['TOOLS']:
-	env.Append(CPPFLAGS = ['-fpermissive'])
-
 res = env.RES(dev.get_sources(source_path, '*.rc'))
 env.Depends(res, 'resource.h')
 

=== modified file 'plugins/Dev/pluginsdk.cpp'
--- plugins/Dev/pluginsdk.cpp	2012-11-10 17:16:16 +0000
+++ plugins/Dev/pluginsdk.cpp	2012-11-11 16:16:24 +0000
@@ -7,4 +7,5 @@
 #include <pluginsdk/Config.cpp>
 #include <pluginsdk/Hooks.cpp>
 #include <pluginsdk/Logger.cpp>
+#include <pluginsdk/UI.cpp>
 #include <pluginsdk/Util.cpp>

=== modified file 'plugins/Script/SConscript'
--- plugins/Script/SConscript	2012-11-04 19:15:24 +0000
+++ plugins/Script/SConscript	2012-11-11 16:16:24 +0000
@@ -4,10 +4,6 @@
 
 env.Append(CPPPATH = ['#/pluginsdk/cpp', 'lua'])
 
-# TODO remove this when GCC stops whining about stateless lambdas
-if dev.is_win32() and 'gcc' in env['TOOLS']:
-	env.Append(CPPFLAGS = ['-fpermissive'])
-
 res = env.RES(dev.get_sources(source_path, '*.rc'))
 env.Depends(res, 'resource.h')
 

=== modified file 'plugins/Test/SConscript'
--- plugins/Test/SConscript	2012-11-04 19:15:24 +0000
+++ plugins/Test/SConscript	2012-11-11 16:16:24 +0000
@@ -7,10 +7,6 @@
 
 env.Append(CPPPATH = ['#/pluginsdk/cpp'])
 
-# TODO remove this when GCC stops whining about stateless lambdas
-if dev.is_win32() and 'gcc' in env['TOOLS']:
-	env.Append(CPPFLAGS = ['-fpermissive'])
-
 res = env.RES(dev.get_sources(source_path, '*.rc'))
 env.Depends(res, 'resource.h')
 

=== modified file 'pluginsdk/PluginDefs.h'
--- pluginsdk/PluginDefs.h	2012-11-11 15:12:15 +0000
+++ pluginsdk/PluginDefs.h	2012-11-11 16:16:24 +0000
@@ -418,7 +418,7 @@
 } DCTagger, *DCTaggerPtr;
 
 /* User interface */
-typedef void (DCAPI* DCCommandFunc)		();
+typedef void (DCAPI* DCCommandFunc)		(const char* name);
 
 typedef struct DCUI {
 	/* User interface API version */

=== modified file 'pluginsdk/cpp/pluginsdk/Config.cpp'
--- pluginsdk/cpp/pluginsdk/Config.cpp	2012-11-08 12:41:54 +0000
+++ pluginsdk/cpp/pluginsdk/Config.cpp	2012-11-11 16:16:24 +0000
@@ -29,6 +29,7 @@
 	return config;
 }
 void Config::init(DCConfigPtr coreConfig) { config = coreConfig; }
+DCConfigPtr Config::handle() { return config; }
 
 void Config::setConfig(const char* name, const char* value) { setConfig<ConfigStr>(name, CFG_TYPE_STRING, value); }
 void Config::setConfig(const char* name, const string& value) { setConfig(name, value.c_str()); }

=== modified file 'pluginsdk/cpp/pluginsdk/Config.h'
--- pluginsdk/cpp/pluginsdk/Config.h	2012-11-08 12:41:54 +0000
+++ pluginsdk/cpp/pluginsdk/Config.h	2012-11-11 16:16:24 +0000
@@ -35,6 +35,7 @@
 public:
 	static bool init(DCCorePtr core);
 	static void init(DCConfigPtr coreConfig);
+	static DCConfigPtr handle();
 
 	static void setConfig(const char* name, const char* value);
 	static void setConfig(const char* name, const string& value);

=== modified file 'pluginsdk/cpp/pluginsdk/Core.cpp'
--- pluginsdk/cpp/pluginsdk/Core.cpp	2012-11-08 12:41:54 +0000
+++ pluginsdk/cpp/pluginsdk/Core.cpp	2012-11-11 16:16:24 +0000
@@ -30,4 +30,6 @@
 	appName = core->host_name();
 }
 
+DCCorePtr Core::handle() { return core; }
+
 } // namespace dcapi

=== modified file 'pluginsdk/cpp/pluginsdk/Core.h'
--- pluginsdk/cpp/pluginsdk/Core.h	2012-11-08 12:41:54 +0000
+++ pluginsdk/cpp/pluginsdk/Core.h	2012-11-11 16:16:24 +0000
@@ -34,6 +34,7 @@
 {
 public:
 	static void init(DCCorePtr corePtr);
+	static DCCorePtr handle();
 
 	static string appName;
 

=== modified file 'pluginsdk/cpp/pluginsdk/Hooks.cpp'
--- pluginsdk/cpp/pluginsdk/Hooks.cpp	2012-11-11 15:12:15 +0000
+++ pluginsdk/cpp/pluginsdk/Hooks.cpp	2012-11-11 16:16:24 +0000
@@ -30,6 +30,7 @@
 	return hooks;
 }
 void Hooks::init(DCHooksPtr coreHooks) { hooks = coreHooks; }
+DCHooksPtr Hooks::handle() { return hooks; }
 
 void Hooks::Chat::onIncomingChat(function<bool (HubDataPtr, char*, bool&)> f) {
 	addEvent(HOOK_CHAT_IN, [f](dcptr_t pObject, dcptr_t pData, bool& bBreak) {

=== modified file 'pluginsdk/cpp/pluginsdk/Hooks.h'
--- pluginsdk/cpp/pluginsdk/Hooks.h	2012-11-11 15:12:15 +0000
+++ pluginsdk/cpp/pluginsdk/Hooks.h	2012-11-11 16:16:24 +0000
@@ -41,13 +41,16 @@
 public:
 	static bool init(DCCorePtr core);
 	static void init(DCHooksPtr coreHooks);
+	static DCHooksPtr handle();
 
 	/* The following functions register events. See the Hooks section of PluginDefs.h to see a
 	description of each.
 	Callbacks return a bool to indicate whether they want to prevent the plugin host from doing any
 	further processing related to the event.
 	Callbacks are also given a "bool& bBreak" argument to indicate whether they want to prevent
-	other plugins from catching the event. */
+	other plugins from catching the event.
+	Remember to remove hooks the plugin has added by calling Hooks::clear() before destroying the
+	plugin. */
 
 	struct Chat {
 		static void onIncomingChat(function<bool (HubDataPtr, char*, bool&)> f);

=== modified file 'pluginsdk/cpp/pluginsdk/Logger.cpp'
--- pluginsdk/cpp/pluginsdk/Logger.cpp	2012-11-08 12:41:54 +0000
+++ pluginsdk/cpp/pluginsdk/Logger.cpp	2012-11-11 16:16:24 +0000
@@ -29,6 +29,7 @@
 	return logger;
 }
 void Logger::init(DCLogPtr coreLogger) { logger = coreLogger; }
+DCLogPtr Logger::handle() { return logger; }
 
 void Logger::log(const string& message) { logger->log(message.c_str()); }
 

=== modified file 'pluginsdk/cpp/pluginsdk/Logger.h'
--- pluginsdk/cpp/pluginsdk/Logger.h	2012-11-08 12:41:54 +0000
+++ pluginsdk/cpp/pluginsdk/Logger.h	2012-11-11 16:16:24 +0000
@@ -35,6 +35,7 @@
 public:
 	static bool init(DCCorePtr core);
 	static void init(DCLogPtr coreLogger);
+	static DCLogPtr handle();
 
 	static void log(const string& message);
 

=== added file 'pluginsdk/cpp/pluginsdk/UI.cpp'
--- pluginsdk/cpp/pluginsdk/UI.cpp	1970-01-01 00:00:00 +0000
+++ pluginsdk/cpp/pluginsdk/UI.cpp	2012-11-11 16:16:24 +0000
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2012 Jacek Sieka, arnetheduck on gmail point com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* Helpers around the DCUI interface. */
+
+#include "UI.h"
+
+namespace dcapi {
+
+DCUIPtr UI::ui;
+unordered_map<string, UI::Command> UI::commands;
+
+bool UI::init(DCCorePtr core) {
+	init(reinterpret_cast<DCUIPtr>(core->query_interface(DCINTF_DCPP_UI, DCINTF_DCPP_UI_VER)));
+	return ui;
+}
+void UI::init(DCUIPtr coreUI) { ui = coreUI; }
+DCUIPtr UI::handle() { return ui; }
+
+void UI::addCommand(string name, Command command) {
+	ui->add_command(commands.emplace(move(name), command).first->first.c_str(), commandCallback);
+}
+
+void UI::removeCommand(const string& name) {
+	ui->remove_command(name.c_str());
+	commands.erase(name);
+}
+
+void DCAPI UI::commandCallback(const char* name) {
+	commands[name]();
+}
+
+} // namespace dcapi

=== added file 'pluginsdk/cpp/pluginsdk/UI.h'
--- pluginsdk/cpp/pluginsdk/UI.h	1970-01-01 00:00:00 +0000
+++ pluginsdk/cpp/pluginsdk/UI.h	2012-11-11 16:16:24 +0000
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2012 Jacek Sieka, arnetheduck on gmail point com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* Helpers around the DCUI interface. */
+
+#ifndef PLUGINSDK_UI_H
+#define PLUGINSDK_UI_H
+
+#include <cstdint>
+#include <functional>
+#include <string>
+#include <unordered_map>
+
+#include <pluginsdk/PluginDefs.h>
+
+namespace dcapi {
+
+using std::function;
+using std::string;
+using std::unordered_map;
+
+class UI
+{
+public:
+	static bool init(DCCorePtr core);
+	static void init(DCUIPtr coreUI);
+	static DCUIPtr handle();
+
+	typedef function<void ()> Command;
+	static void addCommand(string name, Command command);
+	static void removeCommand(const string& name);
+
+private:
+	static void DCAPI commandCallback(const char* name);
+
+	static DCUIPtr ui;
+
+	static unordered_map<string, Command> commands;
+};
+
+} // namespace dcapi
+
+#endif

=== modified file 'pluginsdk/cpp/pluginsdk/Util.cpp'
--- pluginsdk/cpp/pluginsdk/Util.cpp	2012-11-08 12:41:54 +0000
+++ pluginsdk/cpp/pluginsdk/Util.cpp	2012-11-11 16:16:24 +0000
@@ -29,6 +29,7 @@
 	return utils;
 }
 void Util::init(DCUtilsPtr coreUtils) { utils = coreUtils; }
+DCUtilsPtr Util::handle() { return utils; }
 
 #ifdef _UNICODE
 string Util::fromT(const wstring& str) {

=== modified file 'pluginsdk/cpp/pluginsdk/Util.h'
--- pluginsdk/cpp/pluginsdk/Util.h	2012-11-08 12:41:54 +0000
+++ pluginsdk/cpp/pluginsdk/Util.h	2012-11-11 16:16:24 +0000
@@ -38,6 +38,7 @@
 public:
 	static bool init(DCCorePtr core);
 	static void init(DCUtilsPtr coreUtils);
+	static DCUtilsPtr handle();
 
 #ifdef _UNICODE
 	static string fromT(const wstring& str);

=== modified file 'win32/PluginApiImpl.cpp'
--- win32/PluginApiImpl.cpp	2012-11-01 22:13:45 +0000
+++ win32/PluginApiImpl.cpp	2012-11-11 16:16:24 +0000
@@ -31,7 +31,7 @@
 
 // Functions for DCUI
 void PluginApiImpl::addCommand(const char* name, DCCommandFunc command) {
-	MainWindow::addPluginCommand(Text::toT(name), command);
+	MainWindow::addPluginCommand(Text::toT(name), [=] { command(name); });
 }
 
 void PluginApiImpl::removeCommand(const char* name) {