Channels in UnrealScript

class ChannelExample extends Object;

struct Message
{
    var string Content;
};

var array<Message> MessageQueue;
var int QueueIndex;

function Init()
{
    // Create a new "channel" with an array
    MessageQueue.Length = 1;
    
    // Send a value into the "channel" using a separate thread
    SendMessageAsync("ping");
    
    // Receive a value from the "channel" and print it out
    local Message ReceivedMessage;
    ReceivedMessage = ReceiveMessage();
    `log("Received: " $ ReceivedMessage.Content);
}

function SendMessageAsync(string Content)
{
    // Simulate asynchronous send with a latent function
    SetTimer(0.001, false, 'SendMessageDelayed', self);
}

function SendMessageDelayed()
{
    local Message NewMessage;
    NewMessage.Content = "ping";
    MessageQueue[0] = NewMessage;
}

function Message ReceiveMessage()
{
    local Message ReceivedMessage;
    
    // Wait until a message is available
    while(MessageQueue[0].Content == "")
    {
        Sleep(0.001);
    }
    
    ReceivedMessage = MessageQueue[0];
    MessageQueue[0].Content = "";
    return ReceivedMessage;
}

DefaultProperties
{
}

In UnrealScript, we don’t have built-in channels or goroutines like in some other languages. However, we can simulate similar behavior using arrays, timers, and latent functions.

The ChannelExample class demonstrates a basic implementation of channel-like communication:

  1. We define a Message struct to hold our message content.

  2. The MessageQueue array acts as our “channel”, with a single element for simplicity.

  3. The Init function sets up our example:

    • It initializes the “channel” (array).
    • It calls SendMessageAsync to simulate sending a message asynchronously.
    • It then receives and prints the message.
  4. SendMessageAsync uses a timer to simulate asynchronous sending. This is similar to using a separate thread or goroutine.

  5. SendMessageDelayed is called by the timer to actually place the message in the queue.

  6. ReceiveMessage simulates a blocking receive operation. It waits until a message is available, then returns it and clears the queue.

To run this example in UnrealScript:

  1. Create a new class extending from Object and paste the code.
  2. In your game’s main sequence or a test map, create an instance of this class and call the Init function.

When executed, it will output:

Received: ping

This example demonstrates how we can simulate channel-like behavior in UnrealScript. While it’s not as elegant or efficient as native channels in some other languages, it provides a similar concept of passing messages between different parts of your code.

Remember that UnrealScript is single-threaded, so true concurrency isn’t possible. However, this pattern can still be useful for managing asynchronous operations in game development.