Actionstack functions
A stack. Functions to activate just one object(-instance) of many. Their main purpose are dice games. Example: -------- There are three objects: - dice - selecting a character - moving the character As vg4->object->call_run() calls the f_run() functions of all objects, there must be a distinction which object-instance shall be actually active: - either the dice picks a number - or the player selects a character - or the character moves So each f_run() function must check whether it is actually active by calling vg4->actionstack->get() and checking the returned name_id. At first the dice-object is activated by a vg4->actionstack->push(). If the dice has picked a number it calls vg4->actionstack->push() to activate the object moving the character. But this object does not know which character to move, so it calls vg4->actionstack->push() to activate the object selecting a character. This object selects a character and calls vg4->actionstack->parent() to set the selected character into the parent's data, then it calls vg4->actionstack->pop(). Now the object moving the character is activated again which moves the character and calls a vg4->actionstack->pop() to activate the dice-object again. In short: - push(dice): the dice picks a number - push(move): a character shall be moved, but which? - push(select): select the character and set the selection into the parent data (move) - pop(select): which activates move, which moves the selected character - pop(move): which activates dice, which rolls again
- Functions
- vg4->actionstack->freefunction()
Set function for freeing data of actionstack-elements. - vg4->actionstack->push()
Push element onto actionstack. - vg4->actionstack->get()
Get upmost element from actionstack. - vg4->actionstack->parent()
Get parent of upmost element from actionstack. - vg4->actionstack->pop()
Remove upmost element from actionstack. - vg4->actionstack->clear()
Clear actionstack.
Example 
/* just a demonstration how to use actionstack */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <vgagames4.h>
static void do_free(unsigned int, void *);
/* keys */
struct {
int k_quit;
int k_push;
int k_get;
int k_pop;
int k_clear;
} kref;
/* free function for element-data */
static void
do_free(unsigned int name_id, void *vdata)
{
if (vdata != NULL) {
printf("REMOVE: %u:%s\n", name_id, (char *)vdata);
free(vdata);
}
}
int main(int argc, char **argv) {
(void)argc; (void)argv;
if (!VG_init("test")) { exit(1); }
if (!vg4->window->open(VG_WINDOW_SIZE_LOW, VG_WINDOW_SCALE_NONE)) { VG_dest(); exit(1); }
vg4->window->flush();
/* set keys */
if ((kref.k_quit = vg4->input->key_insert("Quit", VG_FALSE, VG_FALSE)) == 0) { VG_dest(); exit(1); }
vg4->input->key_setkbd(kref.k_quit, VG_INPUT_KBDCODE_Q);
if ((kref.k_push = vg4->input->key_insert("PUSH", VG_FALSE, VG_FALSE)) == 0) { VG_dest(); exit(1); }
vg4->input->key_setkbd(kref.k_push, VG_INPUT_KBDCODE_UCURS);
if ((kref.k_get = vg4->input->key_insert("GET+PARENT", VG_FALSE, VG_FALSE)) == 0) { VG_dest(); exit(1); }
vg4->input->key_setkbd(kref.k_get, VG_INPUT_KBDCODE_SPACE);
if ((kref.k_pop = vg4->input->key_insert("POP", VG_FALSE, VG_FALSE)) == 0) { VG_dest(); exit(1); }
vg4->input->key_setkbd(kref.k_pop, VG_INPUT_KBDCODE_DCURS);
if ((kref.k_clear = vg4->input->key_insert("CLEAR", VG_FALSE, VG_FALSE)) == 0) { VG_dest(); exit(1); }
vg4->input->key_setkbd(kref.k_clear, VG_INPUT_KBDCODE_TAB);
/* set free function */
vg4->actionstack->freefunction(do_free);
/* info */
printf("\n");
printf("Keys:\n");
printf(" - quit: Q\n");
printf(" - push: cursor up\n");
printf(" - get: space-key\n");
printf(" - pop: cursor down\n");
printf(" - clear: tabulator\n");
printf("\n");
/* Gameloop */
for (;;) {
if (!vg4->input->update(VG_TRUE)) { break; }
if (vg4->input->key_newpressed(kref.k_quit)) { break; }
/* push element */
if (vg4->input->key_newpressed(kref.k_push)) {
/* element-data shall be just one of the following words */
static char dbuf[][16] = { "the", "dog", "is", "running", "fast" };
/* get a random name_id which shall correspond to the element-data */
unsigned int name_id = vg4->random->get(NULL, 1, 5);
/* push element */
printf("ADD: %u:%s\n", name_id, dbuf[name_id - 1]);
vg4->actionstack->push(name_id, strdup(dbuf[name_id - 1]));
}
/* get upmost and parent element */
if (vg4->input->key_newpressed(kref.k_get)) {
void *vdata;
unsigned int name_id;
printf("\n");
vdata = vg4->actionstack->get(&name_id);
if (name_id != 0) { printf("Upmost: %u:%s\n", name_id, (char *)vdata); }
vdata = vg4->actionstack->parent(&name_id);
if (name_id != 0) { printf("Parent: %u:%s\n", name_id, (char *)vdata); }
printf("\n");
}
/* pop upmost element */
if (vg4->input->key_newpressed(kref.k_pop)) {
vg4->actionstack->pop();
}
/* clear actionstack */
if (vg4->input->key_newpressed(kref.k_clear)) {
vg4->actionstack->clear();
}
/* wait */
vg4->misc->wait_time(50);
}
/* destroy and exit */
VG_dest();
exit(0);
}