From 884205ea0ddef0da9d3332fc3dac977335346759 Mon Sep 17 00:00:00 2001 From: JustinAJ Date: Tue, 30 Jun 2015 21:26:31 -0400 Subject: [PATCH] Simplified GenericCommand conversions with templates. Corrected some macro calls in RenX_Warn. --- Bot/Console_Command.h | 53 ++++++++---- Bot/Generic_Command.h | 6 +- Bot/IRC_Command.h | 144 +++++++++++++++++++++----------- CoreCommands/CoreCommands.cpp | 6 +- PluginManager/PluginManager.cpp | 3 +- Release/Bot.lib | Bin 25088 -> 25088 bytes Release/Plugins/RenX.Core.lib | Bin 129390 -> 129390 bytes RenX.Warn/RenX_Warn.cpp | 4 +- 8 files changed, 139 insertions(+), 77 deletions(-) diff --git a/Bot/Console_Command.h b/Bot/Console_Command.h index e7955ae..dcf2a4f 100644 --- a/Bot/Console_Command.h +++ b/Bot/Console_Command.h @@ -94,27 +94,44 @@ class CLASS : public ConsoleCommand { \ #define CONSOLE_COMMAND_INIT(CLASS) \ CLASS CLASS ## _instance; -/** Generates a console command implementation from a generic command. */ -#define GENERIC_COMMAND_AS_CONSOLE_COMMAND_IMPL(CLASS) \ - CLASS ## _AS_CONSOLE_COMMAND :: CLASS ## _AS_CONSOLE_COMMAND() { \ - size_t index = 0; \ - while (index != CLASS ## _instance.getTriggerCount()) this->addTrigger(CLASS ## _instance.getTrigger(index++)); } \ - void CLASS ## _AS_CONSOLE_COMMAND :: trigger(const Jupiter::ReadableString ¶meters) { \ - GenericCommand::ResponseLine *del; \ - GenericCommand::ResponseLine *ret = CLASS ## _instance.trigger(parameters); \ - while (ret != nullptr) { \ - ret->response.println(ret->type == GenericCommand::DisplayType::PublicError || ret->type == GenericCommand::DisplayType::PrivateError ? stderr : stdout); \ - del = ret; ret = ret->next; delete del; } } \ - const Jupiter::ReadableString & CLASS ## _AS_CONSOLE_COMMAND :: getHelp(const Jupiter::ReadableString ¶meters) { \ - return CLASS ## _instance.getHelp(parameters); } \ - CONSOLE_COMMAND_INIT(CLASS ## _AS_CONSOLE_COMMAND) - /** Generates a console command from a generic command. */ -#define GENERIC_COMMAND_AS_CONSOLE_COMMAND(CLASS) \ - GENERIC_CONSOLE_COMMAND(CLASS ## _AS_CONSOLE_COMMAND) \ - GENERIC_COMMAND_AS_CONSOLE_COMMAND_IMPL(CLASS); +template class Generic_Command_As_Console_Command : public ConsoleCommand +{ +public: + void trigger(const Jupiter::ReadableString ¶meters); + const Jupiter::ReadableString &getHelp(const Jupiter::ReadableString ¶meters); + + Generic_Command_As_Console_Command(); +}; +template Generic_Command_As_Console_Command::Generic_Command_As_Console_Command() : ConsoleCommand() +{ + size_t index = 0; + while (index != T::instance.getTriggerCount()) + this->addTrigger(T::instance.getTrigger(index++)); +} +template void Generic_Command_As_Console_Command::trigger(const Jupiter::ReadableString ¶meters) +{ + GenericCommand::ResponseLine *del; + GenericCommand::ResponseLine *ret = T::instance.trigger(parameters); + while (ret != nullptr) + { + ret->response.println(ret->type == GenericCommand::DisplayType::PublicError || ret->type == GenericCommand::DisplayType::PrivateError ? stderr : stdout); + del = ret; + ret = ret->next; + delete del; + } +} + +template const Jupiter::ReadableString &Generic_Command_As_Console_Command::getHelp(const Jupiter::ReadableString ¶meters) +{ + return T::instance.getHelp(parameters); +} + +/** Generates a console command implementation from a generic command. */ +#define GENERIC_COMMAND_AS_CONSOLE_COMMAND(CLASS) \ + Generic_Command_As_Console_Command< CLASS > CLASS ## _AS_CONSOLE_COMMAND_instance; /** Re-enable warnings */ #if defined _MSC_VER diff --git a/Bot/Generic_Command.h b/Bot/Generic_Command.h index 824f6bf..fb802f6 100644 --- a/Bot/Generic_Command.h +++ b/Bot/Generic_Command.h @@ -105,7 +105,8 @@ JUPITER_BOT_API extern GenericCommand *getGenericCommand(const Jupiter::Readable public: \ CLASS(); \ GenericCommand::ResponseLine *trigger(const Jupiter::ReadableString ¶meters); \ - const Jupiter::ReadableString &getHelp(const Jupiter::ReadableString ¶meters); + const Jupiter::ReadableString &getHelp(const Jupiter::ReadableString ¶meters); \ + static CLASS instance; /** Expands to become the entire declaration for a generic command. In most cases, this will be sufficient. */ #define GENERIC_GENERIC_COMMAND(CLASS) \ @@ -115,7 +116,8 @@ class CLASS : public GenericCommand { \ /** Instantiates a generic command. */ #define GENERIC_COMMAND_INIT(CLASS) \ - CLASS CLASS ## _instance; + CLASS CLASS :: instance = CLASS (); \ + CLASS & CLASS ## _instance = CLASS :: instance; /** Re-enable warnings */ #if defined _MSC_VER diff --git a/Bot/IRC_Command.h b/Bot/IRC_Command.h index 7540829..e590de7 100644 --- a/Bot/IRC_Command.h +++ b/Bot/IRC_Command.h @@ -30,6 +30,7 @@ #include "Jupiter_Bot.h" #include "ServerManager.h" #include "IRC_Bot.h" +#include "Generic_Command.h" class IRCCommand; @@ -168,10 +169,10 @@ private: /** Defines the core of an IRC command's declaration. This should be included in every IRC command. */ #define BASE_IRC_COMMAND(CLASS) \ public: \ - void trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters); \ - const Jupiter::ReadableString &getHelp(const Jupiter::ReadableString ¶meters); \ - CLASS *copy(); \ - void create(); \ + void trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters) override; \ + const Jupiter::ReadableString &getHelp(const Jupiter::ReadableString ¶meters) override; \ + IRCCommand *copy() override; \ + void create() override; \ CLASS() { this->create(); if (serverManager != nullptr) serverManager->addCommand(this); } /** Expands to become the entire declaration for an IRC command. In most cases, this will be sufficient. */ @@ -183,56 +184,99 @@ class CLASS : public IRCCommand { \ /** Instantiates an IRC command, and also defines neccessary core functions for compatibility. */ #define IRC_COMMAND_INIT(CLASS) \ CLASS CLASS ## _instance; \ - CLASS *CLASS::copy() { return new CLASS(*this); } - -/** Generates a base IRC command implementation from a generic command. */ -#define GENERIC_COMMAND_AS_IRC_COMMAND_IMPL_BASE(CLASS) \ - void CLASS ## _AS_IRC_COMMAND :: trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters) { \ - GenericCommand::ResponseLine *del; \ - GenericCommand::ResponseLine *ret = CLASS ## _instance.trigger(parameters); \ - while (ret != nullptr) { \ - switch(ret->type) { \ - case GenericCommand::DisplayType::PublicSuccess: \ - case GenericCommand::DisplayType::PublicError: \ - source->sendMessage(channel, ret->response); \ - break; \ - case GenericCommand::DisplayType::PrivateSuccess: \ - case GenericCommand::DisplayType::PrivateError: \ - source->sendNotice(nick, ret->response); \ - break; \ - default: \ - source->sendMessage(nick, ret->response); \ - break; \ - } \ - del = ret; ret = ret->next; delete del; } } \ - const Jupiter::ReadableString & CLASS ## _AS_IRC_COMMAND :: getHelp(const Jupiter::ReadableString ¶meters) { \ - return CLASS ##_instance.getHelp(parameters); } \ - IRC_COMMAND_INIT(CLASS ## _AS_IRC_COMMAND) - -/** Generates an IRC command implementation from a generic command. */ -#define GENERIC_COMMAND_AS_IRC_COMMAND_IMPL(CLASS) \ - void CLASS ## _AS_IRC_COMMAND :: create() { \ - size_t index = 0; \ - while (index != CLASS ## _instance.getTriggerCount()) this->addTrigger(CLASS ## _instance.getTrigger(index++)); } \ - GENERIC_COMMAND_AS_IRC_COMMAND_IMPL_BASE(CLASS) - -/** Generates an IRC command implementation from a generic command. */ -#define GENERIC_COMMAND_AS_IRC_COMMAND_IMPL_2(CLASS, ACCESS_LEVEL) \ - void CLASS ## _AS_IRC_COMMAND :: create() { \ - size_t index = 0; \ - while (index != CLASS ## _instance.getTriggerCount()) this->addTrigger(CLASS ## _instance.getTrigger(index++)); \ - this->setAccessLevel(ACCESS_LEVEL); } \ - GENERIC_COMMAND_AS_IRC_COMMAND_IMPL_BASE(CLASS) + IRCCommand *CLASS::copy() { return new CLASS(*this); } + +/** GenericCommand to IRCCommand conversion */ /** Generates an IRC command from a generic command. */ -#define GENERIC_COMMAND_AS_IRC_COMMAND(CLASS) \ - GENERIC_IRC_COMMAND(CLASS ## _AS_IRC_COMMAND) \ - GENERIC_COMMAND_AS_IRC_COMMAND_IMPL(CLASS); +template class Generic_Command_As_IRC_Command : public IRCCommand +{ +public: + virtual void trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters) override; + virtual const Jupiter::ReadableString &getHelp(const Jupiter::ReadableString ¶meters) override; + + void copyTriggers(); + Generic_Command_As_IRC_Command(); + Generic_Command_As_IRC_Command(const Generic_Command_As_IRC_Command &cmd); +}; + +template Generic_Command_As_IRC_Command::Generic_Command_As_IRC_Command() : IRCCommand() +{ + Generic_Command_As_IRC_Command::copyTriggers(); +} + +template Generic_Command_As_IRC_Command::Generic_Command_As_IRC_Command(const Generic_Command_As_IRC_Command &cmd) : IRCCommand(cmd) +{ + Generic_Command_As_IRC_Command::copyTriggers(); +} + +template void Generic_Command_As_IRC_Command::trigger(IRC_Bot *source, const Jupiter::ReadableString &channel, const Jupiter::ReadableString &nick, const Jupiter::ReadableString ¶meters) +{ + GenericCommand::ResponseLine *del; + GenericCommand::ResponseLine *ret = T::instance.trigger(parameters); + while (ret != nullptr) + { + switch (ret->type) + { + case GenericCommand::DisplayType::PublicSuccess: + case GenericCommand::DisplayType::PublicError: + source->sendMessage(channel, ret->response); + break; + case GenericCommand::DisplayType::PrivateSuccess: + case GenericCommand::DisplayType::PrivateError: + source->sendNotice(nick, ret->response); + break; + default: + source->sendMessage(nick, ret->response); + break; + } + del = ret; + ret = ret->next; + delete del; + } +} + +template const Jupiter::ReadableString &Generic_Command_As_IRC_Command::getHelp(const Jupiter::ReadableString ¶meters) +{ + return T::instance.getHelp(parameters); +} + +template void Generic_Command_As_IRC_Command::copyTriggers() +{ + size_t index = 0; + while (index != T::instance.getTriggerCount()) + this->addTrigger(T::instance.getTrigger(index++)); +} + +/** Defines the core of an IRC command's declaration. This should be included in every Generic to IRC command conversion. */ +#define GENERIC_COMMAND_AS_IRC_COMMAND_2_BASE(CLASS, NEW_CLASS) \ + public: \ + void create(); \ + IRCCommand *copy() override; \ + NEW_CLASS() : Generic_Command_As_IRC_Command< CLASS >() { \ + this->create(); \ + if (serverManager != nullptr) serverManager->addCommand(this); } \ + NEW_CLASS(const NEW_CLASS &cmd) : Generic_Command_As_IRC_Command< CLASS >(cmd) { this->create(); } + +/** Generates an IRC command from a generic command. */ +#define GENERIC_COMMAND_AS_IRC_COMMAND_2(CLASS, NEW_CLASS) \ + class NEW_CLASS : public Generic_Command_As_IRC_Command< CLASS > { \ + GENERIC_COMMAND_AS_IRC_COMMAND_2_BASE(CLASS, NEW_CLASS) }; \ + IRC_COMMAND_INIT(NEW_CLASS) /** Generates an IRC command from a generic command. */ -#define GENERIC_COMMAND_AS_IRC_COMMAND_2(CLASS, ACCESS_LEVEL) \ - GENERIC_IRC_COMMAND(CLASS ## _AS_IRC_COMMAND) \ - GENERIC_COMMAND_AS_IRC_COMMAND_IMPL_2(CLASS, ACCESS_LEVEL); +#define GENERIC_COMMAND_AS_IRC_COMMAND(CLASS) \ + GENERIC_COMMAND_AS_IRC_COMMAND_2(CLASS, CLASS ## _AS_IRC_COMMAND); + +/** Generates an IRC command from a generic command, and defines a default create() function. */ +#define GENERIC_COMMAND_AS_IRC_COMMAND_NO_CREATE(CLASS) \ + GENERIC_COMMAND_AS_IRC_COMMAND(CLASS) \ + void CLASS ## _AS_IRC_COMMAND::create() {} + +/** Generates an IRC command from a generic command, and defines an access-setting create() function. */ +#define GENERIC_COMMAND_AS_IRC_COMMAND_ACCESS_CREATE(CLASS, ACCESS_LEVEL) \ + GENERIC_COMMAND_AS_IRC_COMMAND(CLASS) \ + void CLASS ## _AS_IRC_COMMAND::create() { this->setAccessLevel(ACCESS_LEVEL); } /** Re-enable warnings */ #if defined _MSC_VER diff --git a/CoreCommands/CoreCommands.cpp b/CoreCommands/CoreCommands.cpp index ef5400b..78b6bdd 100644 --- a/CoreCommands/CoreCommands.cpp +++ b/CoreCommands/CoreCommands.cpp @@ -140,7 +140,7 @@ const Jupiter::ReadableString &VersionGenericCommand::getHelp(const Jupiter::Rea GENERIC_COMMAND_INIT(VersionGenericCommand) GENERIC_COMMAND_AS_CONSOLE_COMMAND(VersionGenericCommand) -GENERIC_COMMAND_AS_IRC_COMMAND(VersionGenericCommand) +GENERIC_COMMAND_AS_IRC_COMMAND_NO_CREATE(VersionGenericCommand) // Sync Command @@ -173,7 +173,7 @@ const Jupiter::ReadableString &SyncGenericCommand::getHelp(const Jupiter::Readab GENERIC_COMMAND_INIT(SyncGenericCommand) GENERIC_COMMAND_AS_CONSOLE_COMMAND(SyncGenericCommand) -GENERIC_COMMAND_AS_IRC_COMMAND_2(SyncGenericCommand, 4) +GENERIC_COMMAND_AS_IRC_COMMAND_ACCESS_CREATE(SyncGenericCommand, 4) // Rehash Command @@ -203,7 +203,7 @@ const Jupiter::ReadableString &RehashGenericCommand::getHelp(const Jupiter::Read GENERIC_COMMAND_INIT(RehashGenericCommand) GENERIC_COMMAND_AS_CONSOLE_COMMAND(RehashGenericCommand) -GENERIC_COMMAND_AS_IRC_COMMAND_2(RehashGenericCommand, 4) +GENERIC_COMMAND_AS_IRC_COMMAND_ACCESS_CREATE(RehashGenericCommand, 4) // Plugin instantiation and entry point. CoreCommandsPlugin pluginInstance; diff --git a/PluginManager/PluginManager.cpp b/PluginManager/PluginManager.cpp index 6c14312..c5e8171 100644 --- a/PluginManager/PluginManager.cpp +++ b/PluginManager/PluginManager.cpp @@ -81,9 +81,8 @@ const Jupiter::ReadableString &PluginGenericCommand::getHelp(const Jupiter::Read } GENERIC_COMMAND_INIT(PluginGenericCommand) - GENERIC_COMMAND_AS_CONSOLE_COMMAND(PluginGenericCommand) -GENERIC_COMMAND_AS_IRC_COMMAND_2(PluginGenericCommand, 5) +GENERIC_COMMAND_AS_IRC_COMMAND_ACCESS_CREATE(PluginGenericCommand, 5) // Plugin instantiation and entry point. PluginManager pluginInstance; diff --git a/Release/Bot.lib b/Release/Bot.lib index 97712ca887bde0e00c1b8b3cbe60f1db0109e2f4..71c83c17432e91d5d6b17a7fce687047aab805b6 100644 GIT binary patch delta 1817 zcmZWpT}V@57~aT5HZ9HR47DvsKmK7UqI1r(ztcANr_*hY>2^j$L_|ddL4<}u3=yoC zh$!(oBtpcC2$DePLL{Y2Zz|{}3G%873;TY~`<+?4+jHLcd7tNbzwet|)laVKXX_7k zpYQCpcff{ZUbL^*75!bZ)o+XcilYXadnyj-+_2>A+16v7;xL2Ud(=Si#4=1fEO4jy ztM>6UYbZGCv@&vBF+ogWC2u+DyA3=9B~xZ({I!r~FT$y?r zFGt)RCjRo4Q;=@ygkNs-2rjvqMbJ)4jB1HPGQxzX8krPgdeOt@e(-n^uJCe&PA|H~ zz+V4{ob+K0P&N`l8O{9!8Csz$(SiF&4fuTG4A3Qi_nBCFdfAQ>iB<+(lOqVBh##^T z@Kaq|?m`f&5ZclpDub+_@umE@Nv3X1;qXVlwl^ZEHDF>%^%2pv^st=lg2{l;OwKL5 z38o;GWNv)&tYjmF^~apgPMVd@W~*!$!823M+&o!XjPEg9w-NJd#seaqDeSu>wj~ zi1N|%Q6Uo7&=3=wp_NlHUimB*Lp3x^!=S2taHtqAsPO!tmNBvPEy=5!hAv|@b^2FEc#%mCRkNc8#eQf9xtk^emDa$!r+M#T$wD z;OV$Hbu{z6an4ztok9X?csa}AwQTW|>eIC k4yjK^UJ)-8y@vRrd{ML)MLkN1yx1nKe4FQrHuLR&0Zn`IA^-pY delta 1817 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 xSFX!t$ZdAG3 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