[SNIPPET] Simple command system!

Started by ., Mar 28, 2015, 11:59 PM

Previous topic - Next topic

.

I noticed that most of you simply add all your commands in one huge function. That's not cool. Not only that you have one huge/slow function with a ton of code to read but it's also a pain for people wishing to create new commands and share them. Because then you have to cut and paste their commands and some of us can't even do that. And when they fail, they go and spam you all day about it. Which is why I created this small system to allow you to bind functions to command names:
// --------------------------------------------------------------------------------------
_Command <- {
    // ----------------------------------------------------------------------------------
    __Cmd__ = {} // NEVER MODIFY THIS DIRECTLY!
    // ----------------------------------------------------------------------------------
    Attach = function(command, listener)
    {
        // Make sure that the specified arguments are correct
        if (typeof command != "string" || typeof listener != "function") return false;
        // Attach that listener to the command
        __Cmd__.rawset(command, listener);
        // Everything went as it should
        return true;
    }
    // ----------------------------------------------------------------------------------
    Detach = function(command)
    {
        // Make sure that the specified arguments are correct
        if (typeof command != "string") return false;
        // Detach that listener to the command
        __Cmd__.rawdelete(command);
        // Everything went as it should
        return true;
    }
    // ----------------------------------------------------------------------------------
    Exists = function(command)
    {
        // Return boolean true/false if you find that command
        return __Cmd__.rawin(command);
    }
}

// --------------------------------------------------------------------------------------
// Never use this command directly
function onPlayerCommand(invoker, command, arguments)
{
    // Forward the command to the listener (if any!)
    if (_Command.__Cmd__.rawin(command)) {
        // Call the function with the specified arguments
        _Command.__Cmd__.rawget(command).call(this, invoker, command, arguments);
    }
    // Notify the invoker that there's is no such command
    else MessagePlayer("[#FF8202][WARNING][#F4F3EE] Unknown command: " + command, invoker);
}

I could have added a bunch of features but I tried to keep it very simple. So here's how you would use it.

Global function to allow you to reuse the functions in code:
// Global function
function MyCommand(player, cmd, args)
{
    MessagePlayer("[#698433][SUCCESS][#F4F3EE] You called global: MyCommand", player);
}

// Now bind the global function
_Command.Attach("mycmd", MyCommand);

Anonymous functions to allow you to keep a clean root/global table and prevent you from cluttering the global namespace:
// Anonymous functions
_Command.Attach("yourcmd", function(player, cmd, args) {
    MessagePlayer("[#698433][SUCCESS][#F4F3EE] You called anonymous: YourCommand", player);
});

The global function MyCommand() will get called when the command "mycmd" is requested and the anonymous function will be called when the command "yourcmd" is requested. If a command doesn't exists then the user is warned about it.

This is a very clean system that allows anyone to attach to any command they'd like. So let's create a few example command and post them here. To see if you can use this system. Let's see what command you can create :P
.

.

#1
Just call it repeatedly.

_Command.Attach("mycmd", MyCommandFunction);
_Command.Attach("mycmd2", MyCommandFunction);
_Command.Attach("mycmd3", MyCommandFunction);
_Command.Attach("and_so_on", MyCommandFunction);

You could also modify it to pass an array of names:

_Command.Attach(["mycmd", "mycmd2", "mycmd3", "and_so_on"], MyCommandFunction);
Otherwise you're just unnecessarily over-complicate things.
.