---
# System prepended metadata

title: '[按鍵精靈] JRobot Script'
tags: [System Programming]

---

# JRobot Script

[GitHub](https://github.com/NeoJay0705/JRobotInterpreter.git)

# Robot 1.0

In Robot 1.0, we use one script to execute one transaction.

The basic step of execution is 
1. Read each char
2. If a keyword is found, do a corresponded function.

# Turning Point

All scripts in Robot 1.0 are constant. It means if you would like to execute a series of scripts that are a little different in some value, for example, username and user id, you have to create an equal amount of scripts for each user.

In the next work, we have to execute one transaction about 672 times. Using Robot 1.0, we have to create 672 scripts for the transaction. We can do it but is not efficient.

# Robot 2.0

The requirements are quite simple that we use every day, **ARRAY** and **LOOP**.

# Runtime

We need a runtime such as JVM to track variables and a program counter(`pc`).

In Robot 2.0, the runtime is quite simple.

```
for (int i = 0; i < pc; i++) {
    function = getFunctionByPC(i)
    functionManager.execute(function)
}
```

# Function Creating

```java=
public interface Functioner {
    String getCommandName();
    
    /**
     * Given two-part by the framework, 
     * 1. Command name
     * 2. Parameter pattern a function provider defines in this function
     */ 
    CommandContext parse(final String command
                             , String parameters) throws SyntaxErrorException;

    /**
     * How to do the function
     * - CommandContext storing parsed parameters
     * - FunctionManager for compounding the functions
     * - ContextManager storing variables 
     */
    void function(Robot robot
                , CommandContext cmdContext
                , FunctionManager functionManager
                , ContextManager ctxManager);
}
```

# Move Mouse

```java=
@Override
public CommandContext parse(String command, String parameters)
        throws SyntaxErrorException {
    return new CommandContext(command
                            , Stream.of(parameters.split(",")).map(Integer::parseInt).toArray());
}

@Override
public void function(Robot robot, CommandContext cmdContext, FunctionManager functionManager, ContextManager ctxManager) {
    try {
        robot.mouseMove((int)cmdContext.getParameters()[0]
                      , (int)cmdContext.getParameters()[1]);
        Thread.sleep(200);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

@Override
public String getCommandName() {
    return "MOVE";
}
```

# Variable

```
VAR KEY=VALUE
```

```java=
@Override
public CommandContext parse(String command, String parameters)
        throws SyntaxErrorException {
    return new CommandContext(command
                            , parameters.split("=", 2));
}

@Override
public void function(Robot robot, CommandContext cmdContext, FunctionManager functionManager, ContextManager ctxManager) {
    ctxManager.put((String)cmdContext.getParameters()[0]
                 , (String)cmdContext.getParameters()[1]);
}

@Override
public String getCommandName() {
    return "VAR";
}
```

# Loop

```
pc               command
9                LOOP
10(gotoIndex)~20 // ... <-|
21               END -----|
```
Loop Context
- current round
- max round
- gotoIndex

```
LOOP              
    LOOP <------| 
    // ... <-|  | 
    END -----|  | 
END ------------| 
```
```
LOOP     // Deque.push(LoopContext1)
    LOOP // Deque.push(LoopContext2)
    // ...
    END  // Deque.pop -> LoopContext2
         // if not meet max, Deque.push(LoopContext2)
         //     return LoopContext2.gotoIndex
END      // Deque.pop -> LoopContext1
```

# Available Commands

`COMMAND-NAME PARAMETER-PATTERN`

```
VAR <VARNAME>=<VALUE>;
VAR NAME=Neo;
// Default variable
CURR_ROUND

ARR <VARNAME>=<v1[, v2, ...]>;
ARR CLIENTS=01,02,03;

// Using variable in scripts
{NAME}
{CLIENTS[{CURR_ROUND}]}
    
LOOP CONST,<NUMBER>;
LOOP END;

LOOP IN,{<VAR_ARRAY>};
LOOP END;


CLICK;

// COMKEY is for combination of key clicks
COMKEY <DELAY>,<KEY>[,<KEY>, ...];
COMKEY 10,1234;  // press 1234
COMKEY 10,ENTER; // press <ENTER>
COMKEY 10,CTRL,V; // paste content in clip board

DELAY <Millisecond>;

MOVE <X>,<Y>;

PAST {<VARNAME>};
PAST <STRING>;

PENDBYRGB <R>,<G>,<B>,<X>,<Y>,<IsEqual>,<PollingTime>;
// blocked until color is white at 150,150
PENDBYRGB 0,0,0,150,150,true,1000;
// blocked until color is not white at 150,150
PENDBYRGB 0,0,0,150,150,false,1000;
```

###### tags: `System Programming`
