diff --git a/Jupiter/GenericCommand.cpp b/Jupiter/GenericCommand.cpp new file mode 100644 index 0000000..12b3a4b --- /dev/null +++ b/Jupiter/GenericCommand.cpp @@ -0,0 +1,74 @@ +/** + * Copyright (C) 2015-2016 Jessica James. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Written by Jessica James + */ + +#include "GenericCommand.h" +#include "Plugin.h" + +Jupiter::ArrayList o_genericCommands; +Jupiter::ArrayList *Jupiter::g_generic_commands = &o_genericCommands; + +/** GenericCommand */ + +Jupiter::GenericCommand::GenericCommand() +{ + o_genericCommands.add(this); + + for (size_t index = 0; index != Jupiter::plugins->size(); ++index) + Jupiter::plugins->get(index)->OnGenericCommandAdd(*this); +} + +Jupiter::GenericCommand::~GenericCommand() +{ + size_t count = o_genericCommands.size(); + while (count != 0) + if (o_genericCommands.get(--count) == this) + { + o_genericCommands.remove(count); + break; + } + + for (size_t index = 0; index != Jupiter::plugins->size(); ++index) + Jupiter::plugins->get(index)->OnGenericCommandRemove(*this); +} + +/** GenericCommand::ResponseLine */ + +Jupiter::GenericCommand::ResponseLine::ResponseLine(const Jupiter::ReadableString &response_, GenericCommand::DisplayType type_) +{ + GenericCommand::ResponseLine::response = response_; + GenericCommand::ResponseLine::type = type_; +} + +Jupiter::GenericCommand::ResponseLine *Jupiter::GenericCommand::ResponseLine::set(const Jupiter::ReadableString &response_, GenericCommand::DisplayType type_) +{ + GenericCommand::ResponseLine::response = response_; + GenericCommand::ResponseLine::type = type_; + return this; +} + +Jupiter::GenericCommand *Jupiter::getGenericCommand(const Jupiter::ReadableString &trigger) +{ + size_t count = o_genericCommands.size(); + while (count != 0) + { + Jupiter::GenericCommand *cmd = o_genericCommands.get(--count); + if (cmd->matches(trigger)) + return cmd; + } + return nullptr; +} diff --git a/Jupiter/GenericCommand.h b/Jupiter/GenericCommand.h new file mode 100644 index 0000000..a162386 --- /dev/null +++ b/Jupiter/GenericCommand.h @@ -0,0 +1,128 @@ +/** + * Copyright (C) 2015-2016 Jessica James. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Written by Jessica James + */ + +#if !defined _GENERICCOMMAND_H_HEADER +#define _GENERICCOMMAND_H_HEADER + +/** +* @file GenericCommand.h +* @brief Provides an extendable command system. +*/ + +#include "Command.h" +#include "String.h" + +/** DLL Linkage Nagging */ +#if defined _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4251) +#endif + +namespace Jupiter +{ + /** + * @brief Provides the base for generic commands. + */ + class JUPITER_API GenericCommand : public Jupiter::Command + { + public: + /** Enumerated class to guide output in generic command interpreters */ + enum class DisplayType + { + PublicSuccess, + PrivateSuccess, + PublicError, + PrivateError, + }; + + /** Data entry returned by trigger() */ + struct JUPITER_API ResponseLine + { + Jupiter::StringS response; + GenericCommand::DisplayType type; + ResponseLine *next = nullptr; + + /** + * @brief Sets the response and type of the ResponseLine. + * + * @param in_response Value to set response to. + * @param in_type Value to set type to. + * @return This. + */ + ResponseLine *set(const Jupiter::ReadableString &response, GenericCommand::DisplayType type); + ResponseLine() = default; + ResponseLine(const Jupiter::ReadableString &response, GenericCommand::DisplayType type); + }; + + /** + * @brief Called when the command is to be executed. + * + * @param input Parameters passed to the command by the user. + */ + virtual ResponseLine *trigger(const Jupiter::ReadableString &input) = 0; + + /** + * @brief Default constructor for the generic command class. + */ + GenericCommand(); + + /** + * @brief Destructor for the generic command class. + */ + virtual ~GenericCommand(); + }; + + /** + * @brief Fetches a generic command based on its trigger. + * + * @param trigger Trigger of the command to fetch. + * @return A generic command if it exists, nullptr otherwise. + */ + JUPITER_API extern GenericCommand *getGenericCommand(const Jupiter::ReadableString &trigger); + + /** Generic command list */ + JUPITER_API extern Jupiter::ArrayList *g_generic_commands; +} + +/** Generic Command Macros */ + +/** Defines the core of a generic command's declaration. This should be included in every generic command. */ +#define BASE_GENERIC_COMMAND(CLASS) \ + public: \ + CLASS(); \ + GenericCommand::ResponseLine *trigger(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) \ +class CLASS : public GenericCommand { \ + BASE_GENERIC_COMMAND(CLASS) \ +}; + +/** Instantiates a generic command. */ +#define GENERIC_COMMAND_INIT(CLASS) \ + CLASS CLASS :: instance = CLASS (); \ + CLASS & CLASS ## _instance = CLASS :: instance; + +/** Re-enable warnings */ +#if defined _MSC_VER +#pragma warning(pop) +#endif + +#endif // _GENERICCOMMAND_H_HEADER diff --git a/Jupiter/Jupiter.vcxproj b/Jupiter/Jupiter.vcxproj index 73ed312..879f469 100644 --- a/Jupiter/Jupiter.vcxproj +++ b/Jupiter/Jupiter.vcxproj @@ -182,13 +182,13 @@ + - @@ -198,9 +198,6 @@ - - - @@ -213,6 +210,7 @@ + diff --git a/Jupiter/Jupiter.vcxproj.filters b/Jupiter/Jupiter.vcxproj.filters index 5b23d21..fb9aad8 100644 --- a/Jupiter/Jupiter.vcxproj.filters +++ b/Jupiter/Jupiter.vcxproj.filters @@ -111,21 +111,9 @@ Source Files\IRC - - Source Files\Files - Source Files\Files - - Source Files\Files - - - Source Files\Files - - - Source Files\Files - Source Files @@ -138,6 +126,9 @@ Source Files\HTTP + + Source Files\Object Extensions + @@ -272,6 +263,9 @@ Header Files\HTTP + + Header Files\Object Extensions + diff --git a/Jupiter/Plugin.cpp b/Jupiter/Plugin.cpp index 126f64c..cdd6287 100644 --- a/Jupiter/Plugin.cpp +++ b/Jupiter/Plugin.cpp @@ -392,4 +392,12 @@ void Jupiter::Plugin::OnMode(Jupiter::IRC::Client *, const Jupiter::ReadableStri void Jupiter::Plugin::OnThink(Jupiter::IRC::Client *) { return; -} \ No newline at end of file +} + +void Jupiter::Plugin::OnGenericCommandAdd(Jupiter::GenericCommand &) +{ +} + +void Jupiter::Plugin::OnGenericCommandRemove(Jupiter::GenericCommand &) +{ +} diff --git a/Jupiter/Plugin.h b/Jupiter/Plugin.h index b16afd7..ed433aa 100644 --- a/Jupiter/Plugin.h +++ b/Jupiter/Plugin.h @@ -40,6 +40,7 @@ namespace Jupiter { /** Forward declaration */ namespace IRC { class Client; } + class GenericCommand; /** * @brief Provides the basis for plugin interfacing. @@ -105,6 +106,8 @@ namespace Jupiter */ virtual bool initialize(); + /** IRC Listeners */ + /** * @brief This is called when a connection has been successfully established. * The current implementation calls this after the MOTD. @@ -262,6 +265,16 @@ namespace Jupiter */ virtual void OnThink(Jupiter::IRC::Client *server); + /** + * @brief This is called when a GenericCommand is instantiated. + */ + virtual void OnGenericCommandAdd(Jupiter::GenericCommand &command); + + /** + * @brief This is called when a GenericCommand is deleted. + */ + virtual void OnGenericCommandRemove(Jupiter::GenericCommand &command); + /** * @brief Constructor for the Plugin class. */ diff --git a/Release/Jupiter.lib b/Release/Jupiter.lib index d91dc8e..04b9d58 100644 Binary files a/Release/Jupiter.lib and b/Release/Jupiter.lib differ