Package com.j3d.engine.interact.cmd.base


package com.j3d.engine.interact.cmd.base
The base for defining a command and how it executes.

Commands

A Command by itself, is a stateless side effect producing base class, where concrete implementations override Command.run(com.j3d.engine.interact.cmd.Invoker, com.j3d.ui.SafeJLabel, String, Object[], java.util.ArrayList) to do their specialised logic. Commands define their arguments within it's constructor super call and any aliases that relate to said command. The arguments are purely used for usage strings which form an important part of UX, giving user's a way to know the multiple ways a command can execute itself.

Specific argument definitions can be found within com.j3d.engine.interact.cmd.args. However to summarise, arguments are split within 2 distinct roles:

  1. A generic argument, so this is any argument that takes in some form of a type.
  2. A subcommand, this is a Command who is itself also an argument defined by Subcommand
These 2 argument definitions are mutually exclusive in context of the head Command, in that:

A command who defines an argument to take a type, cannot also define that same argument to be a subcommand. e.g.: If we have the command "engine"


         "engine" () {
             new TypedArg(boolean),
             new CloseSubcommand() // usually a concrete subcommand defintion
         }
         
this creates the two different possible usage "paths" for the "engine" command:

         engine <boolean>
         engine close
         // or
         engine <boolean> close
         
The reason this is, is because actual arguments and subcommands make the command's usage path slightly different. actual arguments create:

         "engine" () {
             new TypedArg(boolean|Vector3),
             new TypedArg(string),
             new ArgSet("clear", "remove")
         }

         engine <boolean> <string> [clear|remove] // typed args become a single possible usage.
         engine <Vector3> <string> [clear|remove] // for the other possible type of the first arg.
         
Whereas subcommands become:

         "engine" () {
             new ResourceSubCommand(),
             new ClearSubCommand(),
             new RemoveSubCommand()
         }

         engine resource
         engine clear
         engine remove
         
In the subcommand example, the command itself usually becomes a dispatcher to it's subcommands.

Interfaces

More than being a stateless nothing, there are more complicated interfaces a concrete Command can implement to enable certain functionality. These include:

  • SemiStatefulCommand an interface, which labels this command as one that has to disable usage of other commands while it is active. More info in it's own documentation
  • StatefulCommand is a specialised version of SemiStatefulCommand which allows command access to temporary KeyEvent.VK_ESCAPE and KeyEvent.VK_ENTER to clear or commit any state that the command has made. StatefulCommands also print output to the command line labels mentioning this, clearing telling the user they've entered a stateful command and need to interact with these keys to exit.
  • KeyedStatefulCommand is a further specialisation of StatefulCommand that allows for custom key bindings to interact with the command's state, beyond the default ESCAPE and ENTER keys. This enables more complex and interactive command workflows. It allows any key to be set but has specialised methods for setting the UP, DOWN, LEFT and RIGHT keys. It also includes a "gear" key to change input sizes for various commands.
  • PreCommandExecution an interface that allows a command to define logic that has to first pass before the command can continue execution. These are usually called "conditions" and live within com.j3d.engine.interact.cmd.base.conditions. These conditions are usually stored within the command itself via composition, and only run within the own command's Command.run(com.j3d.engine.interact.cmd.Invoker, com.j3d.ui.SafeJLabel, String, Object[], java.util.ArrayList). These conditions work by using EventEmitter to continue command execution if the condition passes. (Commands with these conditions usually also implement SemiStatefulCommand as the command can continue at any time and other commands need to be blocked.)

Author:
Lehlogonolo Poole