queues.inc — FIFO & LIFO queues

the 'queues.inc' file provides two types of queue, first in - first out (FIFO) and last in - first out (LIFO), for the Persistence of Vision Raytracer SDL, version 3.8 or later.

the macros for LIFOs, aka stacks, are prefixed with 'qs', while the FIFO counterparts are prefixed 'qq'. the respective q?Create macros return "objects" which become required arguments to the other macros. when done using a queue, it should be q?Destroyed.

note that FIFO and LIFO queues differ wrt the permissible "payloads". FIFOs allow every value qqPut to be of a different type. however, stacked values, ie qsPushed, must all be of the same type as the first.

since the usage for both queue types is almost identical, the detailed information in the FIFO section mostly applies to both. the LIFO section only notes differences.

FIFO

QQ_MAXQUEUE

optionally declare this (integer) value to override the queue length limit, the default maximum is 10000 elements. this is the upper (length) limit for all queues created in that scene. must be declared before the '#include' statement.

qqCreate(len, optional strict)

this macro expands to a new queue object, sized for up to 'len' data elements, at least two. the corresponding identifier/variable becomes the mandatory first argument supplied to the other macros.

'strict' is a(n optional) boolean value which must be '0' or '1'. it selects the behaviour when a queue empty, or full, error condition arises. if true (that is '1') an error will be raised and parsing is aborted, otherwise the qqGet and qqPut macros will appear to work normal. strict true is the default.

qqDestroy(Q)

in spite of the name, qqDestroy only frees the memory occupied by the queue's data elements, it does not #undef the 'Q' variable itself.

qqGet(Q)

removes the first element from the queue and expands to (returns) that value.

calling qqGet with an empty queue is an error, unless the queue was created with strict false; in which case an empty queue returns empty strings.

qqLength(Q)

expands to the current length of queue 'Q'.

qqPut(Q,elem)

appends 'elem' to the end of queue 'Q'. unless strict is false, overfilling a queue will raise an error. note that if strict is false and the full condition arises, the macro will appear to have worked, when in fact 'elem' has simply been discarded. returns/expands to nothing.

code example

the simple code example shows a small number of dissimilar items of data first queued, then retrieved for display.

    #version 3.8;

    global_settings {assumed_gamma 1}

    #declare C = color rgbt <.123,.456,.789,1>;

    #include "queues.inc"

    #declare Q = qqCreate(5,);

    qqPut(Q,array [2] {.65, .6999999})

    qqPut(Q,501)

    qqPut(Q,C)

    qqPut(Q,concat("rgbft <",vstr(5,C,",",0,4),">"))

    #debug concat("queued ",str(qqLength(Q),0,0)," elements.\n")

    #declare R1 = qqGet(Q);
    #debug concat("array: ",str(R1[0],0,8),", ",str(R1[1],0,8),".\n")

    #declare R2 = qqGet(Q);
    #debug concat("integer: ",str(R2,0,0),".\n")

    #declare R3 = qqGet(Q);
    #debug concat("colour: ",vstr(5,R3,",",0,6),".\n")

    #declare R4 = qqGet(Q);
    #debug concat("string: \"",R4,"\".\n")

    qqDestroy(Q)

    #undef Q

LIFO

QS_MAXSTACK

as QQ_MAXLENGTH.

qsCreate(size, optional strict)

as qqCreate, but expands to a stack "object".

qsDestroy(S)

as qqDestroy.

qsPop(S)

removes the "top of stack" value from 'S' and expands to (returns) that. same provisos as qqGet.

qsPush(S,elem)

adds 'elem' as the new "top of stack" value of 'S'. the second and subsequent 'elem's must be of the same type as the first. otherwise as qqPut.

qsSize(S)

expands to the number of elements on stack 'S'.