Skip to content
This repository was archived by the owner on Sep 27, 2023. It is now read-only.

Tutorial 3.3. Events

Adrodoc edited this page Jun 1, 2018 · 5 revisions

Next we will take a look at events wich can be used for inter-process communication and waiting for user input. Events are also the underlying mechanism that is used when calling a process.

There are two relevant keywords: waitfor and notify. Similar to start and stop, both waitfor and notify can have the modifier conditional or invert for extra control over the execution flow. With waitfor you can wait for an event or process and with notify you can fire an event to continue the execution. Here is a small example:

// start with: /execute @e[name=sendMessage] ~ ~ ~ setblock ~ ~ ~ redstone_block
impulse process sendMessage {
  /say Are you sure you want to do this?
  waitfor myevent
  /say hello!
}

// start with: /execute @e[name=continueSending] ~ ~ ~ setblock ~ ~ ~ redstone_block
impulse process continueSending {
  notify myevent
}

When you start the process sendMessage, the message "hello!" is not actually printed until you also start the process continueSending.

You can also manually notify a waiting process. If you compile your program with the compiler option transmitter you can do this by placing a redstone block:

/execute @e[name=myevent_NOTIFY] ~ ~ ~ setblock ~ ~ ~ redstone_block

If you are not using that compiler option you need to set the appropriate command block to be always active:

/execute @e[name=myevent_NOTIFY] ~ ~ ~ blockdata ~ ~ ~ {auto:1}

All impulse processes automatically notify before they finish, so you can use waitfor for processes. In fact starting and then waiting for a process is identical to calling a process:

install {
  start main
}

impulse process main {
  /say starting program
  start other
  waitfor other
  /say I am the main process
}

impulse process other {
  /say I am the other process
}

The output should look like the same as when calling the other process:

starting program
I am the other process
I am the main process

You can also omit the event name of waitfor. In that case it will use the process name of the last start.

Conditional waiting

If the condition of a conditional waitfor is not met, the program will just continue instead of waiting for the other process. Here is an example program:

// Tag yourself as the winner: /scoreboard players tag @p add winner
// Remove winner tag from yourself: /scoreboard players tag @p remove winner

// start with: /execute @e[name=main] ~ ~ ~ setblock ~ ~ ~ redstone_block
impulse process main {
  /say starting program
  /testfor @p[tag=winner]
  conditional: start calculateWinningScore
  conditional: waitfor
  /say code after waitfor
  /say main process finished
}

impulse process calculateWinningScore {
  /say starting calculation
  // Imagine a complicated calculation here
}

If there is a player with the tag winner the output is:

starting program
starting calculation
code after waitfor
main process finished

If there is no winner it is:

starting program
code after waitfor
main process finished

In both cases the code after waitfor is reached.

If you don't want the code after a conditional waitfor to be reached, when the condition is not met, you have to move that code into the other process:

impulse process main {
  /say starting program
  /testfor @p[tag=winner]
  conditional: start calculateWinningScore
  conditional: waitfor
  /say main process finished
}

impulse process calculateWinningScore {
  /say starting calculation
  // Imagine a complicated calculation here
  /say code that should not be reached
}