How to Implement a Command Queue in pure AL

In this article I show how to implement the command pattern (https://en.wikipedia.org/wiki/Command_pattern) and include it in a queue

First of all we need the command interface

Interface ICommand

interface ICommand
{
    procedure Execute();
}

Because we want to add this to an queue we need a queue entry, i choose a codeunit to this put to be more generic it is also possible to use an interface and an implementing codeunit

Codeunit QueueEntry

codeunit 50102 "QueueEntry"
{
    procedure SetValue(var v: Interface ICommand);
    begin
        value := v;
    end;

    procedure GetValue(): Interface ICommand;
    begin
        exit(value);
    end;

    procedure GetNextEntry(): Codeunit QueueEntry;
    begin
        exit(NextEntry);
    end;

    procedure SetNextEntry(var Entry: Codeunit QueueEntry);
    begin
        NextEntry := Entry;
    end;

    var
        value: Interface ICommand;
        NextEntry: Codeunit QueueEntry;
}

Now we need a managing codeunit for this Queue Entry

Codeunit Queue

codeunit 50100 "Queue"
{
    procedure Push(var value: Interface ICommand)
    var
        Entry: Codeunit QueueEntry;
    begin
        Entry.SetValue(value);
        if count = 0 then begin
            first := Entry;
            last := Entry;
        end
        else begin
            last.SetNextEntry(Entry);
            last := Entry;
        end;
        count += 1;
    end;

    procedure Pop() value: Interface ICommand;
    begin
        if count > 0 then begin
            value := first.GetValue();
            first := first.GetNextEntry();
            count -= 1;
        end
        else
            Error('The Queue is empty!');
    end;

    procedure GetSize(): Integer
    begin
        exit(count);
    end;

    var
        first: Codeunit QueueEntry;
        last: Codeunit QueueEntry;
        count: Integer;
}


That’s it!

To this whole example if also implementet a MessageCommander

codeunit 50103 "MessageCommander" implements ICommand
{
    procedure SetText(value: Text);
    begin
        t := value;
    end;

    procedure Execute()
    begin
        Message(t);
    end;

    var
        t: Text;
}


page 50100 "Queue Test"
{
    PageType = Card;
    ApplicationArea = All;
    UsageCategory = Administration;

    layout
    {
        area(Content)
        {
            group(GroupName)
            {
                field(Input; input)
                {
                    Caption = 'Add Message';
                    ApplicationArea = All;
                }
            }
        }
    }

    actions
    {
        area(Processing)
        {
            action(AddEntry)
            {
                ApplicationArea = All;
                Caption = 'Add new Message';

                trigger OnAction()
                var
                    t: Codeunit MessageCommander;
                    object: Interface ICommand;
                begin
                    t.SetText(input);
                    object := t;
                    queue.Push(object);
                end;
            }
            action(ActionName)
            {
                ApplicationArea = All;
                Caption = 'Execute Next Message';

                trigger OnAction()
                var
                    object: Interface ICommand;
                begin
                    if queue.GetSize() > 0 then begin
                        object := queue.Pop();
                        object.Execute();
                    end;
                end;
            }
        }
    }

    var
        input: Text;
        queue: Codeunit Queue;
}

4 thoughts on “How to Implement a Command Queue in pure AL

  1. Pingback: Part 2: How to Implement a Command Queue in pure AL | Patrick Schiefer

  2. Pingback: How to Implement a Command Queue in pure AL | Pardaan.com

  3. Pingback: Part 2: How to Implement a Command Queue in pure AL | Pardaan.com

  4. Pingback: Exploring Interface Implementation: A Journey from Events to Enums | Patrick Schiefer

Leave a Reply