Browse Source

Added GenericCommandNamespace

Removed IRC.cpp
release/0.19
Jessica James 8 years ago
parent
commit
5ea724e809
  1. 222
      Jupiter/GenericCommand.cpp
  2. 81
      Jupiter/GenericCommand.h
  3. 27
      Jupiter/IRC.cpp
  4. 22
      Jupiter/IRC.h
  5. 1
      Jupiter/Jupiter.vcxproj
  6. 15
      Jupiter/Jupiter.vcxproj.filters
  7. BIN
      Release/Jupiter.lib

222
Jupiter/GenericCommand.cpp

@ -19,14 +19,19 @@
#include "GenericCommand.h"
#include "Plugin.h"
Jupiter::ArrayList<Jupiter::GenericCommand> o_genericCommands;
Jupiter::ArrayList<Jupiter::GenericCommand> *Jupiter::g_generic_commands = &o_genericCommands;
using namespace Jupiter::literals;
constexpr const char GENERIC_COMMAND_WORD_DELIMITER = ' ';
constexpr const char *GENERIC_COMMAND_WORD_DELIMITER_CS = " ";
Jupiter::GenericCommandNamespace o_generic_commands;
Jupiter::GenericCommandNamespace &Jupiter::g_generic_commands = o_generic_commands;
/** GenericCommand */
Jupiter::GenericCommand::GenericCommand()
{
o_genericCommands.add(this);
Jupiter::GenericCommand::setNamespace(o_generic_commands);
for (size_t index = 0; index != Jupiter::plugins->size(); ++index)
Jupiter::plugins->get(index)->OnGenericCommandAdd(*this);
@ -34,18 +39,48 @@ Jupiter::GenericCommand::GenericCommand()
Jupiter::GenericCommand::~GenericCommand()
{
size_t count = o_genericCommands.size();
while (count != 0)
if (o_genericCommands.get(--count) == this)
{
o_genericCommands.remove(count);
break;
}
// Inform the parent
if (GenericCommand::m_parent == nullptr)
GenericCommand::m_parent->removeCommand(*this);
// Notify plugins
for (size_t index = 0; index != Jupiter::plugins->size(); ++index)
Jupiter::plugins->get(index)->OnGenericCommandRemove(*this);
}
bool Jupiter::GenericCommand::isNamespace() const
{
return false;
}
void Jupiter::GenericCommand::setNamespace(const Jupiter::ReadableString &in_namespace)
{
if (in_namespace.wordCount(GENERIC_COMMAND_WORD_DELIMITER_CS) == 0)
return; // We're already here
if (Jupiter::GenericCommand::m_parent == nullptr)
return; // We have no parent to start from
Jupiter::GenericCommand *command = Jupiter::GenericCommand::m_parent->getCommand(in_namespace);
if (command != nullptr && command->isNamespace())
Jupiter::GenericCommand::setNamespace(*reinterpret_cast<Jupiter::GenericCommandNamespace *>(command));
}
void Jupiter::GenericCommand::setNamespace(Jupiter::GenericCommandNamespace &in_namespace)
{
if (Jupiter::GenericCommand::m_parent != nullptr) // Remove from previous parent
Jupiter::GenericCommand::m_parent->removeCommand(*this);
// Add to new parent
Jupiter::GenericCommand::m_parent = &in_namespace;
in_namespace.addCommand(*this);
}
Jupiter::GenericCommandNamespace *Jupiter::GenericCommand::getNamespace() const
{
return Jupiter::GenericCommand::m_parent;
}
/** GenericCommand::ResponseLine */
Jupiter::GenericCommand::ResponseLine::ResponseLine(const Jupiter::ReadableString &response_, GenericCommand::DisplayType type_)
@ -61,14 +96,169 @@ Jupiter::GenericCommand::ResponseLine *Jupiter::GenericCommand::ResponseLine::se
return this;
}
Jupiter::GenericCommand *Jupiter::getGenericCommand(const Jupiter::ReadableString &trigger)
/** GenericCommandNamespace */
Jupiter::GenericCommandNamespace::~GenericCommandNamespace()
{
// Murder the children
Jupiter::GenericCommandNamespace::m_commands.emptyAndDelete();
}
Jupiter::GenericCommand::ResponseLine *Jupiter::GenericCommandNamespace::trigger(const Jupiter::ReadableString &in_input)
{
GenericCommand *command;
Jupiter::ReferenceString input(in_input);
if (input.wordCount(GENERIC_COMMAND_WORD_DELIMITER_CS) == 0) // No parameters; list commands
return new Jupiter::GenericCommand::ResponseLine(Jupiter::GenericCommandNamespace::m_help, Jupiter::GenericCommand::DisplayType::PrivateSuccess);
command = Jupiter::GenericCommandNamespace::getCommand(input.getWord(0, GENERIC_COMMAND_WORD_DELIMITER_CS));
if (command != nullptr)
return command->trigger(input.gotoWord(1, GENERIC_COMMAND_WORD_DELIMITER_CS));
return new Jupiter::GenericCommand::ResponseLine(Jupiter::ReferenceString::empty, Jupiter::GenericCommand::DisplayType::PrivateError);
}
const Jupiter::ReadableString &Jupiter::GenericCommandNamespace::getHelp(const Jupiter::ReadableString &parameters)
{
static Jupiter::ReferenceString not_found = "Error: Command not found"_jrs;
if (parameters.wordCount(GENERIC_COMMAND_WORD_DELIMITER_CS) == 0) // No parameters; list commands
return Jupiter::GenericCommandNamespace::m_help;
Jupiter::ReferenceString input(parameters);
GenericCommand *command;
// Search for command
command = Jupiter::GenericCommandNamespace::getCommand(input.getWord(0, GENERIC_COMMAND_WORD_DELIMITER_CS));
if (command != nullptr)
return command->getHelp(input.gotoWord(1, GENERIC_COMMAND_WORD_DELIMITER_CS));
// Command not found
return not_found;
}
bool Jupiter::GenericCommandNamespace::isNamespace() const
{
return true;
}
bool Jupiter::GenericCommandNamespace::isUsing() const
{
return m_using;
}
void Jupiter::GenericCommandNamespace::setUsing(bool in_value)
{
m_using = in_value;
if (Jupiter::GenericCommand::m_parent != nullptr)
Jupiter::GenericCommand::m_parent->updateHelp();
}
Jupiter::ArrayList<Jupiter::GenericCommand> Jupiter::GenericCommandNamespace::getCommands() const
{
size_t count = o_genericCommands.size();
while (count != 0)
Jupiter::ArrayList<Jupiter::GenericCommand> result(Jupiter::GenericCommandNamespace::m_commands.size());
Jupiter::GenericCommand *command;
size_t tmp_index;
for (size_t command_index = 0; command_index != Jupiter::GenericCommandNamespace::m_commands.size(); ++command_index)
{
Jupiter::GenericCommand *cmd = o_genericCommands.get(--count);
if (cmd->matches(trigger))
return cmd;
command = Jupiter::GenericCommandNamespace::m_commands.get(command_index);
result.add(command);
if (command->isNamespace() && reinterpret_cast<GenericCommandNamespace *>(command)->isUsing())
{
// Add commands from namespace
Jupiter::ArrayList<Jupiter::GenericCommand> tmp = reinterpret_cast<GenericCommandNamespace *>(command)->getCommands();
for (tmp_index = 0; tmp_index != tmp.size(); ++tmp_index)
result.add(tmp.get(tmp_index));
}
}
return result;
}
Jupiter::GenericCommand *Jupiter::GenericCommandNamespace::getCommand(const Jupiter::ReadableString &in_command) const
{
Jupiter::GenericCommand *command;
size_t command_index, namespaces = 0;
/** This is broken into 2 loops in order to insure that exact matches are ALWAYS prioritized over inexact matches */
// Search commands
for (command_index = 0; command_index != Jupiter::GenericCommandNamespace::m_commands.size(); ++command_index)
{
command = Jupiter::GenericCommandNamespace::m_commands.get(command_index);
if (command->matches(in_command)) // Command found
return command;
else if (command->isNamespace() && reinterpret_cast<GenericCommandNamespace *>(command)->isUsing()) // Search namespace for matches
++namespaces;
}
// None found; check namespaces
for (command_index = 0; namespaces != 0; ++command_index)
{
command = Jupiter::GenericCommandNamespace::m_commands.get(command_index);
if (command->isNamespace() && reinterpret_cast<GenericCommandNamespace *>(command)->isUsing())
{
command = reinterpret_cast<GenericCommandNamespace *>(command)->getCommand(in_command);
if (command != nullptr) // match found
return command;
--namespaces;
}
}
return nullptr;
}
void Jupiter::GenericCommandNamespace::addCommand(Jupiter::GenericCommand &in_command)
{
if (in_command.getNamespace() != this)
in_command.setNamespace(*this);
else
{
Jupiter::GenericCommandNamespace::m_commands.add(&in_command);
Jupiter::GenericCommandNamespace::updateHelp();
}
}
void Jupiter::GenericCommandNamespace::removeCommand(Jupiter::GenericCommand &in_command)
{
for (size_t index = 0; index != Jupiter::GenericCommandNamespace::m_commands.size(); ++index)
if (Jupiter::GenericCommandNamespace::m_commands.get(index) == &in_command)
{
Jupiter::GenericCommandNamespace::m_commands.remove(index);
Jupiter::GenericCommandNamespace::updateHelp();
return;
}
}
void Jupiter::GenericCommandNamespace::removeCommand(const Jupiter::ReadableString &in_command)
{
for (size_t index = 0; index != Jupiter::GenericCommandNamespace::m_commands.size(); ++index)
if (Jupiter::GenericCommandNamespace::m_commands.get(index)->matches(in_command))
{
Jupiter::GenericCommandNamespace::m_commands.remove(index);
Jupiter::GenericCommandNamespace::updateHelp();
return;
}
}
void Jupiter::GenericCommandNamespace::updateHelp()
{
Jupiter::ArrayList<Jupiter::GenericCommand> commands = Jupiter::GenericCommandNamespace::getCommands();
Jupiter::StringL tmp_help(commands.size() * 8);
for (size_t index = 0; index != commands.size(); ++index)
{
tmp_help += commands.get(index)->getTrigger();
tmp_help += ' ';
}
Jupiter::GenericCommandNamespace::m_help = tmp_help;
}

81
Jupiter/GenericCommand.h

@ -26,6 +26,7 @@
#include "Command.h"
#include "String.h"
#include "ArrayList.h"
/** DLL Linkage Nagging */
#if defined _MSC_VER
@ -35,6 +36,8 @@
namespace Jupiter
{
class GenericCommandNamespace;
/**
* @brief Provides the base for generic commands.
*/
@ -55,6 +58,7 @@ namespace Jupiter
{
Jupiter::StringS response;
GenericCommand::DisplayType type;
uint8_t error = 0; // 0 = no error; 1 = command not found
ResponseLine *next = nullptr;
/**
@ -65,8 +69,10 @@ namespace Jupiter
* @return This.
*/
ResponseLine *set(const Jupiter::ReadableString &response, GenericCommand::DisplayType type);
ResponseLine *set(uint8_t in_error);
ResponseLine() = default;
ResponseLine(const Jupiter::ReadableString &response, GenericCommand::DisplayType type);
ResponseLine(uint8_t in_error);
};
/**
@ -76,6 +82,35 @@ namespace Jupiter
*/
virtual ResponseLine *trigger(const Jupiter::ReadableString &input) = 0;
/**
* @brief Checks if this command is a namespace
*
* @return True if the command is a namespace, false otherwise
*/
virtual bool isNamespace() const;
/**
* @brief Places this command in a namespace, creating new namespaces as necessary
* Note: This moves the command into a namespace relative to its current namespace
*
* @param in_namespace Name of the namespace to move the command into
*/
void setNamespace(const Jupiter::ReadableString &in_namespace);
/**
* @brief Places this command in a namespace
*
* @param in_namespace Namespace to move the command into
*/
void setNamespace(GenericCommandNamespace &in_namespace);
/**
* @brief Fetches the namespace this command is in
*
* @return Namespace this command is in, or nullptr if there is none.
*/
GenericCommandNamespace *getNamespace() const;
/**
* @brief Default constructor for the generic command class.
*/
@ -85,18 +120,48 @@ namespace Jupiter
* @brief Destructor for the generic command class.
*/
virtual ~GenericCommand();
protected:
GenericCommandNamespace *m_parent = nullptr;
};
/**
* @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.
* @brief Provides the base for generic command namespaces
*/
JUPITER_API extern GenericCommand *getGenericCommand(const Jupiter::ReadableString &trigger);
class JUPITER_API GenericCommandNamespace : public Jupiter::GenericCommand
{
public: // Jupiter::Command
ResponseLine *trigger(const Jupiter::ReadableString &input) override;
const Jupiter::ReadableString &getHelp(const Jupiter::ReadableString &parameters) override;
public: // Jupiter::GenericCommand
bool isNamespace() const override;
public: // Jupiter::GenericCommandNamespace
bool isUsing() const;
void setUsing(bool in_value);
Jupiter::ArrayList<GenericCommand> getCommands() const; // differs from m_commands in that it checks if it's using a namespace
GenericCommand *getCommand(const Jupiter::ReadableString &in_command) const;
void addCommand(GenericCommand &in_command);
void removeCommand(GenericCommand &in_command);
void removeCommand(const Jupiter::ReadableString &in_command);
void updateHelp();
virtual ~GenericCommandNamespace();
protected:
bool m_using;
Jupiter::ArrayList<GenericCommand> m_commands;
private:
Jupiter::StringS m_help;
};
/** Generic command list */
JUPITER_API extern Jupiter::ArrayList<GenericCommand> *g_generic_commands;
JUPITER_API extern GenericCommandNamespace &g_generic_commands;
}
/** Generic Command Macros */
@ -105,8 +170,8 @@ namespace Jupiter
#define BASE_GENERIC_COMMAND(CLASS) \
public: \
CLASS(); \
Jupiter::GenericCommand::ResponseLine *trigger(const Jupiter::ReadableString &parameters); \
const Jupiter::ReadableString &getHelp(const Jupiter::ReadableString &parameters); \
Jupiter::GenericCommand::ResponseLine *trigger(const Jupiter::ReadableString &parameters) override; \
const Jupiter::ReadableString &getHelp(const Jupiter::ReadableString &parameters) override; \
static CLASS instance;
/** Expands to become the entire declaration for a generic command. In most cases, this will be sufficient. */

27
Jupiter/IRC.cpp

@ -1,27 +0,0 @@
/**
* Copyright (C) 2013-2015 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 <jessica.aj@outlook.com>
*/
#include "IRC.h"
const char Jupiter::IRC::CTCP = IRCCTCP[0]; /** IRC CTCP character */
const char Jupiter::IRC::bold = IRCBOLD[0]; /** IRC bold character */
const char Jupiter::IRC::color = IRCCOLOR[0]; /** IRC color character */
const char Jupiter::IRC::normal = IRCNORMAL[0]; /** IRC normal character */
const char Jupiter::IRC::reverse = IRCREVERSE[0]; /** IRC reverse character */
const char Jupiter::IRC::italicize = IRCITALICIZE[0]; /** IRC italicize character */
const char Jupiter::IRC::underline = IRCUNDERLINE[0]; /** IRC underline character */

22
Jupiter/IRC.h

@ -1,5 +1,5 @@
/**
* Copyright (C) 2013-2015 Jessica James.
* Copyright (C) 2013-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
@ -42,13 +42,19 @@ namespace Jupiter
{
namespace IRC
{
JUPITER_API extern const char CTCP; /** IRC CTCP character */
JUPITER_API extern const char bold; /** IRC bold character */
JUPITER_API extern const char color; /** IRC color character */
JUPITER_API extern const char normal; /** IRC normal character */
JUPITER_API extern const char reverse; /** IRC reverse character */
JUPITER_API extern const char italicize; /** IRC italicize character */
JUPITER_API extern const char underline; /** IRC underline character */
constexpr const char CTCP = 0x01; /** IRC CTCP character */
constexpr const char bold = 0x02; /** IRC bold character */
constexpr const char BOLD = Jupiter::IRC::bold;
constexpr const char color = 0x03; /** IRC color character */
constexpr const char COLOR = Jupiter::IRC::color;
constexpr const char normal = 0x0F; /** IRC normal character */
constexpr const char NORMAL = Jupiter::IRC::normal;
constexpr const char reverse = 0x16; /** IRC reverse character */
constexpr const char REVERSE = Jupiter::IRC::reverse;
constexpr const char italicize = 0x1D; /** IRC italicize character */
constexpr const char ITALICIZE = Jupiter::IRC::italicize;
constexpr const char underline = 0x1F; /** IRC underline character */
constexpr const char UNDERLINE = Jupiter::IRC::underline;
}
}

1
Jupiter/Jupiter.vcxproj

@ -186,7 +186,6 @@
<ClCompile Include="Hash.c" />
<ClCompile Include="HTTP_Server.cpp" />
<ClCompile Include="INIFile.cpp" />
<ClCompile Include="IRC.cpp" />
<ClCompile Include="IRC_Client.cpp" />
<ClCompile Include="IRC_Server.cpp" />
<ClCompile Include="Jupiter.cpp" />

15
Jupiter/Jupiter.vcxproj.filters

@ -63,9 +63,6 @@
<ClCompile Include="Jupiter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="IRC.cpp">
<Filter>Source Files\IRC</Filter>
</ClCompile>
<ClCompile Include="IRC_Server.cpp">
<Filter>Source Files\IRC</Filter>
</ClCompile>
@ -87,9 +84,6 @@
<ClCompile Include="INIFile.cpp">
<Filter>Source Files\Files</Filter>
</ClCompile>
<ClCompile Include="Command.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="File.cpp">
<Filter>Source Files\Files</Filter>
</ClCompile>
@ -129,6 +123,9 @@
<ClCompile Include="GenericCommand.cpp">
<Filter>Source Files\Object Extensions</Filter>
</ClCompile>
<ClCompile Include="Command.cpp">
<Filter>Source Files\Object Extensions</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Functions.h">
@ -188,9 +185,6 @@
<ClInclude Include="INIFile.h">
<Filter>Header Files\Files</Filter>
</ClInclude>
<ClInclude Include="Command.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="File.h">
<Filter>Header Files\Files</Filter>
</ClInclude>
@ -266,6 +260,9 @@
<ClInclude Include="GenericCommand.h">
<Filter>Header Files\Object Extensions</Filter>
</ClInclude>
<ClInclude Include="Command.h">
<Filter>Header Files\Object Extensions</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Jupiter.rc">

BIN
Release/Jupiter.lib

Binary file not shown.
Loading…
Cancel
Save