/** @file /common/TCL/tcl_script.h Reprezentace TCL skriptu a jeho promennnych, realizujicich dilci casti pravidel. @author Petr Wolf */ #ifndef COMMON_TCL_TCL_SCRIPT_H #define COMMON_TCL_TCL_SCRIPT_H #include #include #include "common/TCL/tcl_var.h" /// pocet desetinnych mist, pouzitych pri konverzi cisel do TCL #define TCL_DOUBLE_PRECISION 4 /// nejnizsi pouzite ID TCL skriptu (v res/xml/other.xml) #define TCL_SCRIPT_MIN_ID 30 /// nejvyssi pouzite ID TCL skriptu (v res/xml/other.xml) #define TCL_SCRIPT_MAX_ID 56 /** Nazev prechodne promenne pouzivane pri zjistovani delky seznamu. Tento nazev neni mozne pouzit jako nazev uzivatelske promenne, lze jej povazovat za rezervovane slovo jazyka. */ #define TCL_SCRIPT_LENGTH_VARNAME "temp_length" /** Nazev prechodne promenne pouzivane pri zjistovani delky seznamu. Tento nazev neni mozne pouzit jako nazev uzivatelske promenne, lze jej povazovat za rezervovane slovo jazyka. */ #define TCL_SCRIPT_ITEM_VARNAME "temp_item" /// identifikatory jednotlivych TCL skriptu enum TCL_SCRPT_IDS { // 30 - 35 /// inicializace prostredi, nacteni knihoven a definice spolecnych funkci TS_INIT = 30 /// vypocet ceny pohybu jednotky z hexu na sousedni hex ,TS_MOVEMENT_COST /// vypocet viditelnosti z hexu na hex pro jednotku ,TS_UNIT_VISIBILITY /// vypocet viditelnosti z hexu na hex pro budovu ,TS_BUILDING_VISIBILITY /// vyznaceni moznych cilu utoku ,TS_UNIT_ATTACK_RANGE /// vypocet souboje ,TS_ATTACK // 36 - 40 /// akce jednotky ,TS_UNIT_ACTIONS /// akce budovy ,TS_BUILDING_ACTIONS /// vyroba jednotky ,TS_BUILDING_RECRUIT_UNIT /// moznost stavby budovy na danem umisteni ,TS_BUILDING_POSITION /// zahajeni stavby budovy ,TS_START_BUILDING // 41 - 45 /// moznost opravy budovy na danem umisteni ,TS_REPAIR_POSITION /// zahajeni opravy budovy ,TS_REPAIR_BUILDING /// nove kolo ,TS_NEXT_TURN /// vyhodnoceni obsazeni budov a mest ,TS_OCCUPY /// leceni jednotky ,TS_UNIT_HEAL // 46 - 50 /// doplneni jednotky (neelitni) ,TS_UNIT_RECRUIT /// doplneni jednotky (elitni) ,TS_UNIT_RECRUIT_ELITE /// vyhodnoceni obsazeni kralovstvi ,TS_KINGDOM_OCCUPY /// prodej bonusu ,TS_SELL_BONUS /// vyhodnoceni porazeni hrace ,TS_PLAYER_DEFEATED // 51 - 55 /// ukonceni hry ,TS_ENDGAME /// nove herni kolo ,TS_NEW_ROUND /// viditelnost mesta ,TS_TOWN_VISIBILITY /// sfery vlivu jednotek a mest ,TS_INFLUENCE /// samostatny test noveho vlastnika mesta ,TS_NEW_TOWN_OWNER // 56 - 60 /// samostatny test noveho vlastnika kralovstvi ,TS_NEW_KINGDOM_OWNER }; /** Typ TCL skriptu - zatim bez vetsiho vyznamu, ale muze jeste dojit k vyuziti */ enum TCL_SCRIPT_TYPE { TST_Normal ,TST_Special }; /** Definice vstupni nebo vystupni promenne TCL skriptu */ struct TCL_VAR { // jmeno promenne (melo by se skladat pouze z pripustnych znaku) char * name; // typ promenne TCL_VAR_TYPE type; }; /** Struktura spustitelneho TCL skriptu */ struct TCL_SCRIPT { // globalne jednoznacne ID skriptu int id; // typ skriptu TCL_SCRIPT_TYPE type; // seznam vstupnich promennych TCL_VAR * input; // pocet vstupnich promennych (velikost pole input) int input_size; // seznam vystupnich promennych TCL_VAR * output; // pocet vystupnich promennych (velikost pole output) int output_size; // samotny kod skriptu char * code; }; /** Interpret skriptu jazyka TCL Objektovy "obal" puvodnich TCL struktur. Vytvori se jako prostredi pro beh TCL skriptu pri spusteni programu a existuje az do jeho konce. V ramci jednoho interpretu zustavaji v pameti hodnoty drive pouzitych promennych, diky cemuz do nej lze "ulozit" nektere globalni konstanty, ktere jsou pak vyuzivany ze skriptu. */ class TTCL_Interpreter { private: Tcl_Interp * _interpreter; public: TTCL_Interpreter(); ~TTCL_Interpreter(); /** Inicializace prostredi TCL interpreteru. Nastaveni globalnich promennych, inkluze knihoven a definice spolecnych funkci. */ void init(TCL_SCRIPT * init_script); /** Ulozeni promenne do prostredi TCL interpretu @param name jmeno promenne @param type typ predane promenne (jak ma byt chapan void pointer) @param value ukazatel na data */ bool setVar(const char * name, const TCL_VAR_TYPE type, void * value); /** Nacteni hodnoty promenne z prostredi TCL interpretu @param name jmeno promenne @param type typ predane promenne (jak ma byt k datum v TCL pristupovano) @param value ukazatel, kam maji by nahrana data @retval true promenna v poradku nactena @retval false doslo k chybe */ bool getVar(const char * name, const TCL_VAR_TYPE type, void * value); /** Nacteni hodnot do pole pevne delky. Nacte prvky typove homogenniho pole z prostredi TCL interpretu do pameti. @param name jmeno promenne @param type typ prvku v poli (jak ma byt k datum v TCL pristupovano) @param count pocet prvku v poli @param values ukazatel na prvni prvek pole (jiz musi byt alokovano) @retval true promenna v poradku nactena @retval false doslo k chybe */ bool getArray(const char * name, const TCL_VAR_TYPE type, const int count, void * values); /** Ulozeni hodnot z pole pevne delky. Ulozi prvky typove homogenniho pole do prostredi TCL interpretu. @param name jmeno promenne @param type typ prvku v poli (jak ma byt k datum v TCL pristupovano) @param count pocet prvku v poli @param values ukazatel na prvni prvek pole @retval true promenna v poradku nactena @retval false doslo k chybe */ bool setArray(const char * name, const TCL_VAR_TYPE type, const int count, void * values); /** Ulozeni konstantni celociselne hodnoty do prostredi TCL interpretu. @param name jmeno konstanty (melo by odpovidat jejimu nazvu v prostredi C++) @param value hodnota konstanty */ bool setConstInt(const char * name, const int value); /** Ulozeni konstantni desetinne hodnoty do prostredi TCL interpretu. @param name jmeno konstanty (melo by odpovidat jejimu nazvu v prostredi C++) @param value hodnota konstanty */ bool setConstDouble(const char * name, const double value); /** Vykonani kodu @param code TCL kod @return 0, pokud vse probehlo v poradku, jinak kod chyby */ int eval(const char * code); /** Nacteni chyby vznikle pri vykonavani skriptu nebo nacitani/ukladani promennych @result Textovy popis chyby */ const char * getError(); /** Nastaveni uzivatelske funkce. Umozni asociovat volani funkce z TCL s funkci v C @param tclName jmeno funkce v TCL, jejiz volani chceme obsluhovat sami @param cName funkce z C, ktera bude realizovat telo funkce z TCL @param clientData arbitrary one-word value to pass to proc and deleteProc. @param deleteProc procedure to call before cmdName is deleted from the interpreter; allows for command-specific cleanup. If NULL, then no procedure is called before the command is deleted. */ Tcl_Command createCommand(const char * tclName, Tcl_CmdProc * cName, ClientData clientData = NULL, Tcl_CmdDeleteProc * deleteProc = NULL); /// Nastaveni navratove hodnoty funkce void setResult(TCL_VAR_TYPE type, void * value); }; class TTCL_Script { private: TTCL_Interpreter * _interpreter; TCL_SCRIPT * _script; TCL_VAR_TYPE _findType(const char * name, const bool input); public: /** Implicitni konstruktor Skript je zakladan bez vazby na interpret, nemuze tedy fungovat. */ TTCL_Script(); /** Zalozeni noveho skriptu (zatim prazdneho) s vazbou na interpret. Aby vse fungovalo tak, jak ma, musi se skript konstruovat uz s vazbou na jiz existujici interpret @param interpreter interpret TCL */ TTCL_Script(TTCL_Interpreter * interpreter); /** Nacteni skrptu ze struktury obsahujici definice vstupnich a vystupnich promennych a telo skriptu. Pozor! Metoda primo pouziva predana data ze struktury, a to po celou dobu, dokud nebudou nahrazena novou strukturou. Volajici funkce proto musi zajistit existenci a nemennost dat ve strukture, po dobu vykonavani skriptu az po nacitani vyslednych hodnot z nej. */ bool loadStruct(TCL_SCRIPT * script); /** Spusteni tela skriptu @return Navratovy kod TCL interpretu */ int run(); /** Ulozeni promenne do TCL @param name jmeno promenne, jejiz typ byl predtim specifikovan meodou loadStruct() @param value ukazatel na data @retval true promenna v poradku ulozena @retval false doslo k chybe */ bool setVar(const char * name, void * value); /** Nacteni hodnoty promenne z TCL @param name jmeno promenne, ktera byla predtim specifikovana jako vystupni v metode loadStruct() @param value ukazatel, kam maji by nahrana data @retval true promenna v poradku nactena @retval false doslo k chybe */ bool getVar(const char * name, void * value); /** Nactani dvou seznamu do asociativniho pole. @param ids jmeno seznamu indexu @param values jmeno seznamu hodnot @param target ukazatel na asociativni pole, do nejz maji byt data nahrana */ bool joinIntLists(const char * ids, const char * values, std::map & target); }; #endif /*****************************************************************************/