2. 处理脚本命令行参数

处理脚本命令行参数

  • 1. MyCommandLine
  • 2. The Argument Formats
      • (1) argument
      • (2) switch
      • (3) 例子
  • 3、arguments和switches的解析
    • (1) MyCommandLine::Switch(strname)
    • (2) MyCommandLine::Arguments(idx)
    • (3) 命令和参数绑定
  • 4. code example

一旦你的脚本开始变得更加高级,你就会想利用这个参数来让你的脚本执行多种操作。例如,如果你在写一个气闸脚本,你会想告诉脚本让一个气闸循环进出,甚至让哪个气闸循环。我不会告诉你如何写一个气闸脚本,但我将以此为例,向你展示如何检测和处理与这种脚本有关的参数。可编程块API有一个内置的命令行解析器,这是由你提供的,它被设计成快速和分配友好,以及易于使用。

对于那些只想继续使用它的人,这里是本教程中使用的简单演示脚本的链接。气闸门

1. MyCommandLine

这段代码初始化了命令行解析器,并试图解析传入的参数。如果它找到了参数,TryParse方法将返回true

MyCommandLine _commandLine = new MyCommandLine();

public void Main(string argument)
{
    if (_commandLine.TryParse(argument)) {
        // The command line parser found arguments in the string.
    }
}

2. The Argument Formats

传统的命令行中包含了argumentswitch

cycle "Airlock 1" in -emergency

(1) argument

argument: 是以空格为间隔的字符串(cycle)或("Airlock 1")字符串。当argument串有空格分开的过个单词组成,需要用引号概括。
argument的访问和数组一样,通过位置访问元素。第一个元素下标是0,依此类推。

(2) switch

格式: -emergency
访问:switches放置在任何地方都行,不通过位置访问。

(3) 例子

eg1和eg2显示,放置 -emergency 开关的位置无关紧要,它不会影响参数的索引。

cycle "Airlock 1" in -emergency  #eg1
-emergency cycle "Airlock 1" in   # eg2
  • eg1:
    arguments:
0: cycle
1: "Airclock 1"
2: in

switch:

-emergency
  • eg2:
    arguments:
0: cycle
1: "Airclock 1"
2: in

switch:

-emergency

3、arguments和switches的解析

MyCommandLine类提供方法:Switch(name),获取名字为name的switch的参数。

(1) MyCommandLine::Switch(strname)

// check if the -myflag switch is set
bool switchIsSet = _commandLine.Switch("myflag");

(2) MyCommandLine::Arguments(idx)

// retrieve the first argument of the string (either a word or a "quoted string"). The quotes are removed for you.
string arg = _commandLine.Argument(0);

(3) 命令和参数绑定

首先,我们将需要一种方法来区分命令。第一个参数,当然,将是命令指示器。我们将创建一个字典来保存这些命令。

Dictionary _commands = new Dictionary(StringComparer.OrdinalIgnoreCase);

注意,我们传入了一个不区分大小写的字符串比较器,所以我们可以接受CYCLE以及cycle。接下来我们需要初始化这些命令。这一点我们在脚本构造函数中完成。

  • _commands字典,绑定arguments和action
//_commands字典,绑定arguments和action
public Program() 
{
    // Associate the Cycle method with the cycle command
    _commands["cycle"] = Cycle;
}

public void Cycle()
{
	// This method will hold the code to perform the desired action
}
  • 编辑Main方法来使用这个字典来选择和执行命令。
public void Main(string argument)
{
	// 解析命令行参数
    if (_commandLine.TryParse(argument))
    {
        Action commandAction;

        // Retrieve the first argument. Switches are ignored.
        string command = _commandLine.Argument(0);

        // Now we must validate that the first argument is actually specified, 
        // then attempt to find the matching command delegate.
        if (command == null)
        {
            Echo("No command specified");
        } 
        else if (_commands.TryGetValue(command, out commandAction))
        {
            ///< 在Programs()中绑定了"cycle"字符串和函数Cycle()
            ///< 从字典_commands中取出"cycle"对应的Action执行
            commandAction();
        }
        else
        {
            Echo($"Unknown command {command}");
        }
    }
}
  • 最后,我们必须在与cycle命令相关的Cycle方法中完成对命令特定参数的处理。
public void Cycle()
{
    //解析switch参数emergency
    bool emergencyCycle = _commandLine.Switch("emergency");

    //命令行中解析气闸门的名字,用于cycle。这里index=1。没有气闸门就退出
    string airlockName = _commandLine.Argument(1);
    if (airlockName == null)
    {
        Echo("Cannot cycle, no airlock specified");
        return;
    }

    // Argument no. 2 should be either "in" or "out", indicating
    // which direction to cycle
    ///< 命令行中读取index=2的参数,确定进出方向in/out
    string direction = _commandLine.Argument(2);
    if (direction == null)
    {
        Echo($"Cannot cycle {airlockName}, no direction specified");
        return;
    }
    if (string.Equals(direction, "in", StringComparison.OrdinalIgnoreCase))
    {
        Echo($"Cycling airlock {airlockName} in...");
        // TODO: Begin the cycling of the airlock
    }
    else if (string.Equals(direction, "out", StringComparison.OrdinalIgnoreCase))
    {
        Echo($"Cycling airlock {airlockName} out...");
        // TODO: Begin the cycling of the airlock
    }
    else
    {
        // The argument was none of the expected values
        Echo($"Cannot cycle {airlockName}, cannot understand direction {direction}");
    }
}

4. code example

MyCommandLine _commandLine = new MyCommandLine();
Dictionary _commands = new Dictionary(StringComparer.OrdinalIgnoreCase);

public Program()
{
    _commands["cycle"] = Cycle;
}

public void Cycle()
{
    // Check if the "emergency" switch is set.
    bool emergencyCycle = _commandLine.Switch("emergency");

    // Argument no. 1 is the name of the airlock to cycle
    string airlockName = _commandLine.Argument(1);
    if (airlockName == null)
    {
        Echo("Cannot cycle, no airlock specified");
        return;
    }

    // Argument no. 2 should be either "in" or "out", indicating
    // which direction to cycle
    string direction = _commandLine.Argument(2);
    if (direction == null)
    {
        Echo($"Cannot cycle {airlockName}, no direction specified");
        return;
    }

    if (string.Equals(direction, "in", StringComparison.OrdinalIgnoreCase))
    {
        Echo($"Cycling airlock {airlockName} in...");
        // TODO: Begin the cycling of the airlock
    }
    else if (string.Equals(direction, "out", StringComparison.OrdinalIgnoreCase))
    {
        Echo($"Cycling airlock {airlockName} out...");
        // TODO: Begin the cycling of the airlock
    }
    else
    {
        // The argument was none of the expected values
        Echo($"Cannot cycle {airlockName}, cannot understand direction {direction}");
    }
}

public void Main(string argument)
{
    if (_commandLine.TryParse(argument))
    {
        Action commandAction;

        // Retrieve the first argument. Switches are ignored.
        string command = _commandLine.Argument(0);

        // Now we must validate that the first argument is actually specified, 
        // then attempt to find the matching command delegate.
        if (command == null)
        {
            Echo("No command specified");
        }
        else if (_commands.TryGetValue(_commandLine.Argument(0), out commandAction))
        {
            // We have found a command. Invoke it.
            commandAction();
        }
        else
        {
            Echo($"Unknown command {command}");
        }
    }
}

你可能感兴趣的:(游戏,太空工程师,SpaceEngineer)