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); }