From 51644369cbd3886132da70466202d1b7c99a499e Mon Sep 17 00:00:00 2001 From: krzys-h Date: Sun, 20 Dec 2015 18:35:52 +0100 Subject: [PATCH] Moved standard math and file functions into CBot library --- po/colobot.pot | 18 + po/de.po | 36 +- po/fr.po | 36 +- po/pl.po | 36 +- po/ru.po | 36 +- src/CBot/CBot.h | 5 +- src/CBot/CBotDefines.h | 13 +- src/CBot/CBotProgram.cpp | 17 +- src/CBot/CMakeLists.txt | 5 +- src/CBot/StringFunctions.h | 137 ---- src/CBot/stdlib/Compilation.cpp | 217 +++++ src/CBot/stdlib/Compilation.h | 37 + src/CBot/stdlib/FileFunctions.cpp | 375 +++++++++ src/CBot/stdlib/MathFunctions.cpp | 189 +++++ src/CBot/{ => stdlib}/StringFunctions.cpp | 140 +--- src/CBot/stdlib/stdlib.h | 7 + src/CBot/stdlib/stdlib_public.h | 34 + src/common/restext.cpp | 6 + src/level/robotmain.cpp | 2 +- src/script/scriptfunc.cpp | 923 +++++----------------- src/script/scriptfunc.h | 47 +- 21 files changed, 1166 insertions(+), 1150 deletions(-) delete mode 100644 src/CBot/StringFunctions.h create mode 100644 src/CBot/stdlib/Compilation.cpp create mode 100644 src/CBot/stdlib/Compilation.h create mode 100644 src/CBot/stdlib/FileFunctions.cpp create mode 100644 src/CBot/stdlib/MathFunctions.cpp rename src/CBot/{ => stdlib}/StringFunctions.cpp (65%) create mode 100644 src/CBot/stdlib/stdlib.h create mode 100644 src/CBot/stdlib/stdlib_public.h diff --git a/po/colobot.pot b/po/colobot.pot index 453930ac..28315a39 100644 --- a/po/colobot.pot +++ b/po/colobot.pot @@ -1712,6 +1712,9 @@ msgstr "" msgid "Bad argument for \"new\"" msgstr "" +msgid "\" [ \" expected" +msgstr "" + msgid "String missing" msgstr "" @@ -1733,6 +1736,9 @@ msgstr "" msgid "Negative value rejected by \"throw\"" msgstr "" +msgid "The function returned no value " +msgstr "" + msgid "No function running" msgstr "" @@ -1757,5 +1763,17 @@ msgstr "" msgid "Illegal object" msgstr "" +msgid "Can't open file" +msgstr "" + +msgid "File not open" +msgstr "" + +msgid "Read error" +msgstr "" + +msgid "Write error" +msgstr "" + msgid "Button %1" msgstr "" diff --git a/po/de.po b/po/de.po index ce9cf97a..ad1ac8cc 100644 --- a/po/de.po +++ b/po/de.po @@ -55,6 +55,9 @@ msgstr " Zusammenfassung:" msgid " or " msgstr " oder " +msgid "\" [ \" expected" +msgstr "Es fehlt eine offene eckige Klammer \" [ \"" + msgid "\" ] \" missing" msgstr "Es fehlt eine geschlossene eckige Klammer \" ] \"" @@ -352,6 +355,9 @@ msgstr "Das erforschte Objekt kann nicht produziert werden" msgid "Can not produce this object in this mission" msgstr "Das Objekt kann in dieser Mission nicht produziert werden" +msgid "Can't open file" +msgstr "Die Datei kann nicht geöffnet werden" + msgid "Cancel" msgstr "Abbrechen" @@ -548,6 +554,9 @@ msgstr "Brille:" msgid "Face type:" msgstr "Kopf:" +msgid "File not open" +msgstr "Die Datei wurde nicht geöffnet" + msgid "Filename:" msgstr "Dateiname:" @@ -1164,6 +1173,9 @@ msgstr "Mission verlassen\\Eine Mission oder Übung verlassen" msgid "Radar station" msgstr "Radar" +msgid "Read error" +msgstr "Fehler beim Lesezugriff" + msgid "Recorder" msgstr "Recorder" @@ -1460,6 +1472,9 @@ msgstr "" msgid "The expression must return a boolean value" msgstr "Der Ausdruck muss einen boolschen Wert ergeben" +msgid "The function returned no value " +msgstr "Die Funktion hat kein Ergebnis zurückgegeben" + msgid "" "The mission is not accomplished yet (press \\key help; for more details)" msgstr "" @@ -1664,6 +1679,9 @@ msgstr "Wurm tödlich verwundet" msgid "Wreckage" msgstr "Roboterwrack" +msgid "Write error" +msgstr "Fehler beim Schreibzugriff" + msgid "Wrong type for the assignment" msgstr "Der Ausdruck ergibt einen falschen Typ für die Zuweisung" @@ -1799,9 +1817,6 @@ msgstr "www.epsitec.com" #~ msgid " Missions on this level:" #~ msgstr " Missionen des Userlevels:" -#~ msgid "\" [ \" expected" -#~ msgstr "Es fehlt eine offene eckige Klammer \" [ \"" - #~ msgid "3D sound\\3D positioning of the sound" #~ msgstr "3D-Geräusche\\Orten der Geräusche im Raum" @@ -1814,9 +1829,6 @@ msgstr "www.epsitec.com" #~ msgid "Can not create this; there are too many objects" #~ msgstr "Kein neues Objekt kann erstellt werden (zu viele vorhanden)" -#~ msgid "Can't open file" -#~ msgstr "Die Datei kann nicht geöffnet werden" - #~ msgid "Cancel\\Keep current player name" #~ msgstr "Abbrechen\\Behält den bisherigen Spieler bei" @@ -1845,9 +1857,6 @@ msgstr "www.epsitec.com" #~ msgid "Exit film\\Film at the exit of exercises" #~ msgstr "Zurücksetzen \\Kleine Show beim Zurücksetzen in den Übungen" -#~ msgid "File not open" -#~ msgstr "Die Datei wurde nicht geöffnet" - #~ msgid "Friendly fire\\Your shooting can damage your own objects " #~ msgstr "Eigenbeschuss\\Ihre Einheiten werden von Ihren Waffen beschädigt" @@ -1887,9 +1896,6 @@ msgstr "www.epsitec.com" #~ msgid "Quit\\Quit COLOBOT" #~ msgstr "Schließen\\COLOBOT schließen" -#~ msgid "Read error" -#~ msgstr "Fehler beim Lesezugriff" - #~ msgid "Robbie\\Your assistant" #~ msgstr "Robby\\Ihr Assistent" @@ -1908,9 +1914,6 @@ msgstr "www.epsitec.com" #~ msgid "Textures\\Quality of textures " #~ msgstr "Qualität der Texturen\\Qualität der Anzeige" -#~ msgid "The function returned no value " -#~ msgstr "Die Funktion hat kein Ergebnis zurückgegeben" - #~ msgid "" #~ "The list is only available if a \\l;radar station\\u object\\radar; is " #~ "working.\n" @@ -1919,9 +1922,6 @@ msgstr "www.epsitec.com" #~ msgid "User\\User levels" #~ msgstr "User\\Userlevels" -#~ msgid "Write error" -#~ msgstr "Fehler beim Schreibzugriff" - #~ msgid "\\Return to COLOBOT" #~ msgstr "\\Zurück zu COLOBOT" diff --git a/po/fr.po b/po/fr.po index ed5d83d4..6ed78e66 100644 --- a/po/fr.po +++ b/po/fr.po @@ -48,6 +48,9 @@ msgstr " Résumé :" msgid " or " msgstr " ou " +msgid "\" [ \" expected" +msgstr "\" [ \" attendu" + msgid "\" ] \" missing" msgstr "\" ] \" attendu" @@ -349,6 +352,9 @@ msgstr "Impossible de créer un objet n'ayant pas été recherché" msgid "Can not produce this object in this mission" msgstr "Impossible de créer cet objet dans cette mission" +msgid "Can't open file" +msgstr "Ouverture du fichier impossible" + msgid "Cancel" msgstr "Annuler" @@ -543,6 +549,9 @@ msgstr "Lunettes :" msgid "Face type:" msgstr "Type de visage :" +msgid "File not open" +msgstr "Le fichier n'est pas ouvert" + msgid "Filename:" msgstr "Nom du fichier :" @@ -1155,6 +1164,9 @@ msgstr "Quitter la mission en cours\\Terminer un exercice ou une mssion" msgid "Radar station" msgstr "Radar" +msgid "Read error" +msgstr "Erreur à la lecture" + msgid "Recorder" msgstr "Enregistreur" @@ -1445,6 +1457,9 @@ msgstr "Textures" msgid "The expression must return a boolean value" msgstr "L'expression doit ętre un boolean" +msgid "The function returned no value " +msgstr "La fonction n'a pas retourné de résultat" + msgid "" "The mission is not accomplished yet (press \\key help; for more details)" msgstr "" @@ -1650,6 +1665,9 @@ msgstr "Ver mortellement touché" msgid "Wreckage" msgstr "Epave de robot" +msgid "Write error" +msgstr "Erreur à l'écriture" + msgid "Wrong type for the assignment" msgstr "Mauvais type de résultat pour l'assignation" @@ -1786,9 +1804,6 @@ msgstr "www.epsitec.com" #~ msgid " Missions on this level:" #~ msgstr " Missions du niveau :" -#~ msgid "\" [ \" expected" -#~ msgstr "\" [ \" attendu" - #~ msgid "3D sound\\3D positioning of the sound" #~ msgstr "Bruitages 3D\\Positionnement sonore dans l'espace" @@ -1801,9 +1816,6 @@ msgstr "www.epsitec.com" #~ msgid "Can not create this; there are too many objects" #~ msgstr "Création impossible; il y a trop d'objets" -#~ msgid "Can't open file" -#~ msgstr "Ouverture du fichier impossible" - #~ msgid "Cancel\\Keep current player name" #~ msgstr "Annuler\\Conserver le joueur actuel" @@ -1832,9 +1844,6 @@ msgstr "www.epsitec.com" #~ msgid "Exit film\\Film at the exit of exercises" #~ msgstr "Retour animé\\Retour animé dans les exercices" -#~ msgid "File not open" -#~ msgstr "Le fichier n'est pas ouvert" - #~ msgid "Friendly fire\\Your shooting can damage your own objects " #~ msgstr "Dégâts à soi-même\\Vos tirs infligent des dommages à vos unités" @@ -1874,9 +1883,6 @@ msgstr "www.epsitec.com" #~ msgid "Quit\\Quit COLOBOT" #~ msgstr "Quitter\\Quitter COLOBOT" -#~ msgid "Read error" -#~ msgstr "Erreur à la lecture" - #~ msgid "Robbie\\Your assistant" #~ msgstr "Robbie\\Votre assistant" @@ -1895,9 +1901,6 @@ msgstr "www.epsitec.com" #~ msgid "Textures\\Quality of textures " #~ msgstr "Qualité des textures\\Qualité des images" -#~ msgid "The function returned no value " -#~ msgstr "La fonction n'a pas retourné de résultat" - #~ msgid "" #~ "The list is only available if a \\l;radar station\\u object\\radar; is " #~ "working.\n" @@ -1906,9 +1909,6 @@ msgstr "www.epsitec.com" #~ msgid "User\\User levels" #~ msgstr "Suppl.\\Niveaux supplémentaires" -#~ msgid "Write error" -#~ msgstr "Erreur à l'écriture" - #~ msgid "\\Return to COLOBOT" #~ msgstr "\\Retourner dans COLOBOT" diff --git a/po/pl.po b/po/pl.po index d4572786..4180c418 100644 --- a/po/pl.po +++ b/po/pl.po @@ -54,6 +54,9 @@ msgstr " Streszczenie:" msgid " or " msgstr " lub " +msgid "\" [ \" expected" +msgstr "Oczekiwane \" [ \"" + msgid "\" ] \" missing" msgstr "Brak \" ] \"" @@ -355,6 +358,9 @@ msgstr "Nie można wyprodukować nie wynalezionego obiektu" msgid "Can not produce this object in this mission" msgstr "Nie można utworzyć tego obiektu w tej misji" +msgid "Can't open file" +msgstr "Nie można otworzyć pliku" + msgid "Cancel" msgstr "Anuluj" @@ -549,6 +555,9 @@ msgstr "Okulary:" msgid "Face type:" msgstr "Rodzaj twarzy:" +msgid "File not open" +msgstr "Plik nie jest otwarty" + msgid "Filename:" msgstr "Nazwa pliku:" @@ -1163,6 +1172,9 @@ msgstr "Zakończ\\Kończy bieżącą misję lub ćwiczenie" msgid "Radar station" msgstr "Stacja radarowa" +msgid "Read error" +msgstr "Błąd odczytu" + msgid "Recorder" msgstr "Nagrywanie" @@ -1453,6 +1465,9 @@ msgstr "Tekstury" msgid "The expression must return a boolean value" msgstr "Wyrażenie musi zwrócić wartość logiczną" +msgid "The function returned no value " +msgstr "Funkcja nie zwróciła żadnej wartości " + msgid "" "The mission is not accomplished yet (press \\key help; for more details)" msgstr "Misja nie jest wypełniona (naciśnij \\key help; aby uzyskać szczegóły)" @@ -1655,6 +1670,9 @@ msgstr "Robal śmiertelnie raniony" msgid "Wreckage" msgstr "Wrak" +msgid "Write error" +msgstr "Błąd zapisu" + msgid "Wrong type for the assignment" msgstr "Zły typ dla przypisania" @@ -1784,9 +1802,6 @@ msgstr "www.epsitec.com" #~ msgid " Drivers:" #~ msgstr " Sterowniki:" -#~ msgid "\" [ \" expected" -#~ msgstr "Oczekiwane \" [ \"" - #~ msgid "3D sound\\3D positioning of the sound" #~ msgstr "Dźwięk 3D\\Przestrzenne pozycjonowanie dźwięków" @@ -1796,9 +1811,6 @@ msgstr "www.epsitec.com" #~ msgid "Can not create this; there are too many objects" #~ msgstr "Nie można tego utworzyć, za dużo obiektów" -#~ msgid "Can't open file" -#~ msgstr "Nie można otworzyć pliku" - #~ msgid "Cancel\\Keep current player name" #~ msgstr "Anuluj\\Zachowuje bieżące imię gracza" @@ -1823,9 +1835,6 @@ msgstr "www.epsitec.com" #~ msgid "Exit film\\Film at the exit of exercises" #~ msgstr "Końcowy film\\Film na zakończenie ćwiczeń" -#~ msgid "File not open" -#~ msgstr "Plik nie jest otwarty" - #~ msgid "Friendly fire\\Your shooting can damage your own objects " #~ msgstr "Przyjacielski ogień\\Własne strzały uszkadzają Twoje obiekty" @@ -1867,9 +1876,6 @@ msgstr "www.epsitec.com" #~ msgid "Quit the mission?" #~ msgstr "Opuścić misję?" -#~ msgid "Read error" -#~ msgstr "Błąd odczytu" - #~ msgid "Robbie\\Your assistant" #~ msgstr "Robbie\\Twój asystent" @@ -1885,9 +1891,6 @@ msgstr "www.epsitec.com" #~ msgid "Textures\\Quality of textures " #~ msgstr "Tekstury\\Jakość tekstur " -#~ msgid "The function returned no value " -#~ msgstr "Funkcja nie zwróciła żadnej wartości " - #~ msgid "" #~ "The list is only available if a \\l;radar station\\u object\\radar; is " #~ "working.\n" @@ -1895,9 +1898,6 @@ msgstr "www.epsitec.com" #~ "Lista jest dostępna jedynie gdy działa \\l;stacja radarowa\\u object" #~ "\\radar;.\n" -#~ msgid "Write error" -#~ msgstr "Błąd zapisu" - #~ msgid "\\b;Aliens\n" #~ msgstr "\\b;Obcy\n" diff --git a/po/ru.po b/po/ru.po index dad69058..2248e642 100644 --- a/po/ru.po +++ b/po/ru.po @@ -53,6 +53,9 @@ msgstr " Итог:" msgid " or " msgstr " или " +msgid "\" [ \" expected" +msgstr "Ожидалось \" [ \"" + msgid "\" ] \" missing" msgstr "Отсутствует \"]\" " @@ -347,6 +350,9 @@ msgstr "" msgid "Can not produce this object in this mission" msgstr "" +msgid "Can't open file" +msgstr "Невозможно открыть файл" + msgid "Cancel" msgstr "Отмена" @@ -542,6 +548,9 @@ msgstr "Очки:" msgid "Face type:" msgstr "Лицо:" +msgid "File not open" +msgstr "Файл не открыт" + msgid "Filename:" msgstr "Имя файла:" @@ -1160,6 +1169,9 @@ msgstr "Выход\\Выход из текущей миссии" msgid "Radar station" msgstr "Радар" +msgid "Read error" +msgstr "Ошибка чтения" + msgid "Recorder" msgstr "Запись" @@ -1452,6 +1464,9 @@ msgstr "" msgid "The expression must return a boolean value" msgstr "Выражение должно возвращать логическое значение" +msgid "The function returned no value " +msgstr "Функция не возвратила значения" + msgid "" "The mission is not accomplished yet (press \\key help; for more details)" msgstr "" @@ -1655,6 +1670,9 @@ msgstr "Червь смертельно ранен" msgid "Wreckage" msgstr "Обломки" +msgid "Write error" +msgstr "Ошибка записи" + msgid "Wrong type for the assignment" msgstr "Неверный тип для назначения" @@ -1790,9 +1808,6 @@ msgstr "www.epsitec.com" #~ msgid " Missions on this level:" #~ msgstr " Миссии на этом уровне:" -#~ msgid "\" [ \" expected" -#~ msgstr "Ожидалось \" [ \"" - #~ msgid "3D sound\\3D positioning of the sound" #~ msgstr "3D-звук\\Стерео звук" @@ -1805,9 +1820,6 @@ msgstr "www.epsitec.com" #~ msgid "Can not create this; there are too many objects" #~ msgstr "Не удается это создать, слишком много объектов" -#~ msgid "Can't open file" -#~ msgstr "Невозможно открыть файл" - #~ msgid "Cancel\\Keep current player name" #~ msgstr "Отмена\\Отмена" @@ -1836,9 +1848,6 @@ msgstr "www.epsitec.com" #~ msgid "Exit film\\Film at the exit of exercises" #~ msgstr "Ролик при выходе\\Ролик во время выхода из упражнения" -#~ msgid "File not open" -#~ msgstr "Файл не открыт" - #~ msgid "Friendly fire\\Your shooting can damage your own objects " #~ msgstr "Огонь по своим\\Вы можете повредить собственные объекты" @@ -1878,9 +1887,6 @@ msgstr "www.epsitec.com" #~ msgid "Quit\\Quit COLOBOT" #~ msgstr "Выход\\Выход из COLOBOT" -#~ msgid "Read error" -#~ msgstr "Ошибка чтения" - #~ msgid "Robbie\\Your assistant" #~ msgstr "Робби\\Ваш помощник" @@ -1899,9 +1905,6 @@ msgstr "www.epsitec.com" #~ msgid "Textures\\Quality of textures " #~ msgstr "Текстуры\\Качество текстур " -#~ msgid "The function returned no value " -#~ msgstr "Функция не возвратила значения" - #~ msgid "" #~ "The list is only available if a \\l;radar station\\u object\\radar; is " #~ "working.\n" @@ -1911,9 +1914,6 @@ msgstr "www.epsitec.com" #~ msgid "User\\User levels" #~ msgstr "Польз.\\Пользовательские уровни" -#~ msgid "Write error" -#~ msgstr "Ошибка записи" - #~ msgid "\\Return to COLOBOT" #~ msgstr "\\Вернуться в COLOBOT" diff --git a/src/CBot/CBot.h b/src/CBot/CBot.h index 4ba45b0e..3f590057 100644 --- a/src/CBot/CBot.h +++ b/src/CBot/CBot.h @@ -23,7 +23,6 @@ * that should be included by any Colobot files outside of the CBot module. */ -// Modules inlcude #include "CBot/CBotFileUtils.h" #include "CBot/CBotClass.h" #include "CBot/CBotToken.h" @@ -32,6 +31,4 @@ #include "CBot/CBotVar/CBotVar.h" -// Local include - -// Global include +#include "CBot/stdlib/stdlib_public.h" diff --git a/src/CBot/CBotDefines.h b/src/CBot/CBotDefines.h index 93be12bb..514e733d 100644 --- a/src/CBot/CBotDefines.h +++ b/src/CBot/CBotDefines.h @@ -53,6 +53,8 @@ // Error Handling of compilation and execution //////////////////////////////////////////////////////////////////////// +// TODO: Why are all of those duplicated? This needs to be unified across the source code ~krzys_h + // Here are the list of errors that can be returned by the module // for compilation @@ -132,6 +134,7 @@ #define TX_BADLEFT 5004 #define TX_ENDOF 5005 #define TX_OUTCASE 5006 +#define TX_NOTERM 5007 #define TX_CLOSEBLK 5008 #define TX_ELSEWITHOUTIF 5009 #define TX_OPENBLK 5010 @@ -162,6 +165,7 @@ #define TX_CLBRK 5035 #define TX_RESERVED 5036 #define TX_BADNEW 5037 +#define TX_OPBRK 5038 #define TX_BADSTRING 5039 #define TX_BADINDEX 5040 #define TX_PRIVATE 5041 @@ -171,6 +175,7 @@ #define TX_DIVZERO 6000 #define TX_NOTINIT 6001 #define TX_BADTHROW 6002 +#define TX_NORETVAL 6003 #define TX_NORUN 6004 #define TX_NOCALL 6005 #define TX_NOCLASS 6006 @@ -179,6 +184,10 @@ #define TX_OUTARRAY 6009 #define TX_STACKOVER 6010 #define TX_DELETEDPT 6011 +#define TX_FILEOPEN 6012 +#define TX_NOTOPEN 6013 +#define TX_ERRREAD 6014 +#define TX_ERRWRITE 6015 -// Max errors -#define TX_MAX 6012 +// Max errors (NOTE: See above TODO near file errors) +#define TX_MAX 6016 diff --git a/src/CBot/CBotProgram.cpp b/src/CBot/CBotProgram.cpp index 0dd62f1e..6ac9f43b 100644 --- a/src/CBot/CBotProgram.cpp +++ b/src/CBot/CBotProgram.cpp @@ -29,9 +29,10 @@ #include "CBot/CBotInstr/CBotFunction.h" -#include "StringFunctions.h" #include "CBotKeywordStrings.h" +#include "CBot/stdlib/stdlib.h" + // Local include // Global include @@ -482,19 +483,21 @@ void CBotProgram::Init() CBotToken::DefineNum("CBotErrZeroDiv", TX_DIVZERO); // division by zero CBotToken::DefineNum("CBotErrNotInit", TX_NOTINIT); // uninitialized variable CBotToken::DefineNum("CBotErrBadThrow", TX_BADTHROW); // throw a negative value - //CBotToken::DefineNum("CBotErrNoRetVal", 6003); // function did not return results // TODO: Not used. I'm pretty sure not returning a value crashes the game :P + CBotToken::DefineNum("CBotErrNoRetVal", TX_NORETVAL); // function did not return results CBotToken::DefineNum("CBotErrNoRun", TX_NORUN); // active Run () without a function // TODO: Is this actually a runtime error? CBotToken::DefineNum("CBotErrUndefFunc", TX_NOCALL); // Calling a function that no longer exists - CBotToken::DefineNum("CBotErrUndefClass", TX_NOCLASS); // Class no longer exists - CBotToken::DefineNum("CBotErrNullPointer", TX_NULLPT); // Attempted to use a null pointer + CBotToken::DefineNum("CBotErrNotClass", TX_NOCLASS); // Class no longer exists + CBotToken::DefineNum("CBotErrNull", TX_NULLPT); // Attempted to use a null pointer CBotToken::DefineNum("CBotErrNan", TX_OPNAN); // Can't do operations on nan - CBotToken::DefineNum("CBotErrOutOfBounds", TX_OUTARRAY); // Attempted access out of bounds of an array - CBotToken::DefineNum("CBotErrStackOverflow", TX_STACKOVER); // Stack overflow - CBotToken::DefineNum("CBotErrDeletedObject", TX_DELETEDPT); // Attempted to use deleted object + CBotToken::DefineNum("CBotErrOutArray", TX_OUTARRAY); // Attempted access out of bounds of an array + CBotToken::DefineNum("CBotErrStackOver", TX_STACKOVER); // Stack overflow + CBotToken::DefineNum("CBotErrDeletedPtr", TX_DELETEDPT); // Attempted to use deleted object CBotProgram::AddFunction("sizeof", rSizeOf, cSizeOf ); InitStringFunctions(); + InitMathFunctions(); + InitFileFunctions(); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/CBot/CMakeLists.txt b/src/CBot/CMakeLists.txt index 08f83568..62f7d72f 100644 --- a/src/CBot/CMakeLists.txt +++ b/src/CBot/CMakeLists.txt @@ -11,7 +11,6 @@ set(SOURCES CBotCallMethode.cpp CBotTypResult.cpp CBotKeywordStrings.cpp - StringFunctions.cpp CBotInstr/CBotInstr.cpp CBotInstr/CBotInstrUtils.cpp CBotInstr/CBotWhile.cpp @@ -67,6 +66,10 @@ set(SOURCES CBotVar/CBotVarFloat.cpp CBotVar/CBotVarInt.cpp CBotVar/CBotVar.cpp + stdlib/FileFunctions.cpp + stdlib/StringFunctions.cpp + stdlib/MathFunctions.cpp + stdlib/Compilation.cpp ) # Includes diff --git a/src/CBot/StringFunctions.h b/src/CBot/StringFunctions.h deleted file mode 100644 index fd3618f4..00000000 --- a/src/CBot/StringFunctions.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * This file is part of the Colobot: Gold Edition source code - * Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam - * http://epsitec.ch; http://colobot.info; http://github.com/colobot - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see http://gnu.org/licenses - */ - -#pragma once - -// Modules inlcude -#include "CBot/CBotTypResult.h" - -// Local include - -// Global include - -// Forward declaration -class CBotVar; - -/*! - * \brief rStrLen Gives the length of a chain execution - * \param pVar - * \param pResult - * \param ex - * \param pUser - * \return - */ -bool rStrLen( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser ); - -/*! - * \brief cIntStr int xxx ( string ) compilation - * \param pVar - * \param pUser - * \return - */ -CBotTypResult cIntStr( CBotVar* &pVar, void* pUser ); - -/*! - * \brief rStrLeft Gives the left side of a chain execution - * \param pVar - * \param pResult - * \param ex - * \param pUser - * \return - */ -bool rStrLeft( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser ); - -/*! - * \brief cStrStrInt string xxx ( string, int ) compilation - * \param pVar - * \param pUser - * \return - */ -CBotTypResult cStrStrInt( CBotVar* &pVar, void* pUser ); - -/*! - * \brief rStrRight Gives the right of a string execution - * \param pVar - * \param pResult - * \param ex - * \param pUser - * \return - */ -bool rStrRight( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser ); - -/*! - * \brief rStrMid Gives the central part of a chain execution - * \param pVar - * \param pResult - * \param ex - * \param pUser - * \return - */ -bool rStrMid( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser ); - -/*! - * \brief rStrVal Gives the number stored in a string execution. - * \param pVar - * \param pResult - * \param ex - * \param pUser - * \return - */ -bool rStrVal( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser ); - -/*! - * \brief cIntStrStr int xxx ( string, string ) compilation - * \param pVar - * \param pUser - * \return - */ -CBotTypResult cIntStrStr( CBotVar* &pVar, void* pUser ); - -/*! - * \brief rStrUpper Gives a string to uppercase exécution - * \param pVar - * \param pResult - * \param ex - * \param pUser - * \return - */ -bool rStrUpper( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser ); - -/*! - * \brief rStrLower Gives a string to lowercase exécution. - * \param pVar - * \param pResult - * \param ex - * \param pUser - * \return - */ -bool rStrLower( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser ); - -/*! - * \brief cStrStr String xxx ( string ) compilation - * \param pVar - * \param pUser - * \return - */ -CBotTypResult cStrStr( CBotVar* &pVar, void* pUser ); - -/*! - * \brief InitStringFunctions - */ -void InitStringFunctions(); diff --git a/src/CBot/stdlib/Compilation.cpp b/src/CBot/stdlib/Compilation.cpp new file mode 100644 index 00000000..a0174a68 --- /dev/null +++ b/src/CBot/stdlib/Compilation.cpp @@ -0,0 +1,217 @@ +#include "CBot/stdlib/Compilation.h" + +#include "CBot/CBot.h" + +// Compiling a procedure without any parameters. + +CBotTypResult cNull(CBotVar* &var, void* user) +{ + if ( var != nullptr ) return CBotErrOverParam; + return CBotTypResult(CBotTypFloat); +} + +// Compiling a procedure with a single real number. + +CBotTypResult cOneFloat(CBotVar* &var, void* user) +{ + if ( var == nullptr ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + if ( var != nullptr ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypFloat); +} + +// Compiling a procedure with two real numbers. + +CBotTypResult cTwoFloat(CBotVar* &var, void* user) +{ + if ( var == nullptr ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var == nullptr ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + + if ( var != nullptr ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypFloat); +} + + +// Compiling a procedure with a single string. + +CBotTypResult cString(CBotVar* &var, void* user) +{ + if ( var == nullptr ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() != CBotTypString && + var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + if ( var != nullptr ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypFloat); +} + +// Compiling a procedure with a single string, returning string. + +CBotTypResult cStringString(CBotVar* &var, void* user) +{ + if ( var == nullptr ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() != CBotTypString && + var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + if ( var != nullptr ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypString); +} + +// compilation of instruction with one int returning int + +CBotTypResult cOneInt(CBotVar* &var, void* user) +{ + if ( var == nullptr ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() != CBotTypInt ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + if ( var != nullptr ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypInt); +} + +// compilation of instruction with one int returning boolean + +CBotTypResult cOneIntReturnBool(CBotVar* &var, void* user) +{ + if ( var == nullptr ) return CBotTypResult(CBotErrLowParam); + if ( var->GetType() != CBotTypInt ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); + if ( var != nullptr ) return CBotTypResult(CBotErrOverParam); + return CBotTypResult(CBotTypBoolean); +} + + + +CBotTypResult cStrStr(CBotVar*& var, void* user) +{ + // it takes a parameter + if ( var == nullptr ) return CBotTypResult( TX_LOWPARAM ); + + // to be a string + if ( var->GetType() != CBotTypString ) + return CBotTypResult( TX_BADSTRING ); + + // no second parameter + if ( var->GetNext() != nullptr ) return CBotTypResult( TX_OVERPARAM ); + + // the end result is a string + return CBotTypResult( CBotTypString ); +} + +CBotTypResult cIntStrStr(CBotVar*& var, void* user) +{ + // it takes a parameter + if ( var == nullptr ) return CBotTypResult( TX_LOWPARAM ); + + // to be a string + if ( var->GetType() != CBotTypString ) + return CBotTypResult( TX_BADSTRING ); + + // it takes a second parameter + var = var->GetNext(); + if ( var == nullptr ) return CBotTypResult( TX_LOWPARAM ); + + // to be a string + if ( var->GetType() != CBotTypString ) + return CBotTypResult( TX_BADSTRING ); + + // no third parameter + if ( var->GetNext() != nullptr ) return CBotTypResult( TX_OVERPARAM ); + + // the end result is a number + return CBotTypResult( CBotTypInt ); +} + +CBotTypResult cFloatStr(CBotVar*& var, void* user) +{ + // it takes a parameter + if ( var == nullptr ) return CBotTypResult(TX_LOWPARAM ); + + // to be a string + if ( var->GetType() != CBotTypString ) + return CBotTypResult( TX_BADSTRING ); + + // no second parameter + if ( var->GetNext() != nullptr ) return CBotTypResult( TX_OVERPARAM ); + + // the end result is a number + return CBotTypResult( CBotTypFloat ); +} + +CBotTypResult cStrStrIntInt(CBotVar*& var, void* user) +{ + // it takes a parameter + if ( var == nullptr ) return CBotTypResult( TX_LOWPARAM ); + + // to be a string + if ( var->GetType() != CBotTypString ) + return CBotTypResult( TX_BADSTRING ); + + // it takes a second parameter + var = var->GetNext(); + if ( var == nullptr ) return CBotTypResult( TX_LOWPARAM ); + + // which must be a number + if ( var->GetType() > CBotTypDouble ) + return CBotTypResult( TX_BADNUM ); + + // third parameter optional + if ( var->GetNext() != nullptr ) + { + + var = var->GetNext(); + // which must be a number + if ( var->GetType() > CBotTypDouble ) + return CBotTypResult( TX_BADNUM ); + + // no fourth parameter + if ( var->GetNext() != nullptr ) return CBotTypResult( TX_OVERPARAM ); + } + + // the end result is a string + return CBotTypResult( CBotTypString ); +} + +CBotTypResult cStrStrInt(CBotVar*& var, void* user) +{ + // it takes a parameter + if ( var == nullptr ) return CBotTypResult( TX_LOWPARAM ); + + // to be a string + if ( var->GetType() != CBotTypString ) + return CBotTypResult( TX_BADSTRING ); + + // it takes a second parameter + var = var->GetNext(); + if ( var == nullptr ) return CBotTypResult( TX_LOWPARAM ); + + // which must be a number + if ( var->GetType() > CBotTypDouble ) + return CBotTypResult( TX_BADNUM ); + + // no third parameter + if ( var->GetNext() != nullptr ) return CBotTypResult( TX_OVERPARAM ); + + // the end result is a string + return CBotTypResult( CBotTypString ); +} + +CBotTypResult cIntStr(CBotVar*& var, void* user) +{ + // it takes a parameter + if ( var == nullptr ) return CBotTypResult( TX_LOWPARAM ); + + // to be a string + if ( var->GetType() != CBotTypString ) + return CBotTypResult( TX_BADPARAM ); + + // no second parameter + if ( var->GetNext() != nullptr ) return CBotTypResult( TX_OVERPARAM ); + + // the end result is an integer + return CBotTypResult( CBotTypInt ); +} \ No newline at end of file diff --git a/src/CBot/stdlib/Compilation.h b/src/CBot/stdlib/Compilation.h new file mode 100644 index 00000000..b53519c8 --- /dev/null +++ b/src/CBot/stdlib/Compilation.h @@ -0,0 +1,37 @@ +#pragma once + +#include "CBot/CBotTypResult.h" + +class CBotVar; + +// Commonly used functions for parameter compilation +// type "number" is anything > CBotTypDouble + +// float foo() +CBotTypResult cNull(CBotVar* &var, void* user); +// float foo(number) +CBotTypResult cOneFloat(CBotVar* &var, void* user); +// float foo(number, number) +CBotTypResult cTwoFloat(CBotVar* &var, void* user); +// float foo(string) +CBotTypResult cString(CBotVar* &var, void* user); +// string foo(string) +CBotTypResult cStringString(CBotVar* &var, void* user); +// int foo(int) +CBotTypResult cOneInt(CBotVar* &var, void* user); +// bool foo(int) +CBotTypResult cOneIntReturnBool(CBotVar* &var, void* user); + + +// string foo(string) +CBotTypResult cStrStr(CBotVar*& var, void* user); +// int foo(string, string) +CBotTypResult cIntStrStr(CBotVar*& var, void* user); +// float foo(string) +CBotTypResult cFloatStr(CBotVar*& var, void* user); +// string foo(string, number[, number]) +CBotTypResult cStrStrIntInt(CBotVar*& var, void* user); +// string foo(string, number) +CBotTypResult cStrStrInt(CBotVar*& var, void* user); +// int foo(string) +CBotTypResult cIntStr(CBotVar*& var, void* user); \ No newline at end of file diff --git a/src/CBot/stdlib/FileFunctions.cpp b/src/CBot/stdlib/FileFunctions.cpp new file mode 100644 index 00000000..26836a90 --- /dev/null +++ b/src/CBot/stdlib/FileFunctions.cpp @@ -0,0 +1,375 @@ +#include "CBot/stdlib/stdlib.h" + +#include "CBot/CBot.h" + +#include +#include +#include + +namespace { +std::unique_ptr g_fileHandler; +std::unordered_map> g_files; +int g_nextFileId = 1; +} + + +bool FileClassOpenFile(CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) +{ + std::string mode; + + // must be a character string + if ( pVar->GetType() != CBotTypString ) { Exception = CBotErrBadString; return false; } + + std::string filename = pVar->GetValString(); + + // there may be a second parameter + pVar = pVar->GetNext(); + if ( pVar != nullptr ) + { + // recover mode + mode = pVar->GetValString(); + if ( mode != "r" && mode != "w" ) { Exception = CBotErrBadParam; return false; } + + // no third parameter + if ( pVar->GetNext() != nullptr ) { Exception = CBotErrOverParam; return false; } + } + + // saves the file name + pVar = pThis->GetItem("filename"); + pVar->SetValString(filename); + + // retrieve the item "handle" + pVar = pThis->GetItem("handle"); + // which must not be initialized + if ( pVar->IsDefined()) { Exception = CBotErrFileOpen; return false; } + + if ( !mode.empty() ) + { + // opens the requested file + assert(g_fileHandler != nullptr); + std::unique_ptr file = g_fileHandler->OpenFile(filename, mode == "r" ? CBotFileAccessHandler::OpenMode::Read : CBotFileAccessHandler::OpenMode::Write); + + if (!file->Opened()) { Exception = CBotErrFileOpen; return false; } + + int fileHandle = g_nextFileId++; + g_files[fileHandle] = std::move(file); + + // save the file handle + pVar = pThis->GetItem("handle"); + pVar->SetValInt(fileHandle); + } + return true; +} + +// constructor of the class +// get the filename as a parameter + +// execution +bool rfconstruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user) +{ + // accepts no parameters + if ( pVar == nullptr ) return true; + + return FileClassOpenFile(pThis, pVar, pResult, Exception); +} + +// compilation +CBotTypResult cfconstruct (CBotVar* pThis, CBotVar* &pVar) +{ + // accepts no parameters + if ( pVar == nullptr ) return CBotTypResult( 0 ); + + // must be a character string + if ( pVar->GetType() != CBotTypString ) + return CBotTypResult( CBotErrBadString ); + + // there may be a second parameter + pVar = pVar->GetNext(); + if ( pVar != nullptr ) + { + // which must be a string + if ( pVar->GetType() != CBotTypString ) + return CBotTypResult( CBotErrBadString ); + // no third parameter + if ( pVar->GetNext() != nullptr ) return CBotTypResult( CBotErrOverParam ); + } + + // the result is void (constructor) + return CBotTypResult( 0 ); +} + + +// destructor of the class + +// execution +bool rfdestruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user) +{ + // retrieve the item "handle" + pVar = pThis->GetItem("handle"); + + if (!pVar->IsDefined()) return true; // file not opened + g_files.erase(pVar->GetValInt()); + + pVar->SetInit(CBotVar::InitType::IS_NAN); + return true; +} + + +// process FILE :: open +// get the r/w mode as a parameter + +// execution +bool rfopen (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user) +{ + // there must be a parameter + if ( pVar == nullptr ) { Exception = CBotErrLowParam; return false; } + + bool result = FileClassOpenFile(pThis, pVar, pResult, Exception); + pResult->SetValInt(result); + return result; +} + +// compilation +CBotTypResult cfopen (CBotVar* pThis, CBotVar* &pVar) +{ + // there must be a parameter + if ( pVar == nullptr ) return CBotTypResult( CBotErrLowParam ); + + // which must be a string + if ( pVar->GetType() != CBotTypString ) + return CBotTypResult( CBotErrBadString ); + + // there may be a second parameter + pVar = pVar->GetNext(); + if ( pVar != nullptr ) + { + // which must be a string + if ( pVar->GetType() != CBotTypString ) + return CBotTypResult( CBotErrBadString ); + + // no third parameter + if ( pVar->GetNext() != nullptr ) return CBotTypResult( CBotErrOverParam ); + } + + // the result is bool + return CBotTypResult(CBotTypBoolean); +} + + +// process FILE :: close + +// execeution +bool rfclose (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user) +{ + // it shouldn't be any parameters + if (pVar != nullptr) { Exception = CBotErrOverParam; return false; } + + // retrieve the item "handle" + pVar = pThis->GetItem("handle"); + + if (!pVar->IsDefined()) { Exception = CBotErrNotOpen; return false; } + + int fileHandle = pVar->GetValInt(); + + const auto handleIter = g_files.find(fileHandle); + if (handleIter == g_files.end()) + { + Exception = CBotErrNotOpen; + return false; + } + + g_files.erase(handleIter); + + pVar->SetInit(CBotVar::InitType::IS_NAN); + return true; +} + +// compilation +CBotTypResult cfclose (CBotVar* pThis, CBotVar* &pVar) +{ + // it shouldn't be any parameters + if ( pVar != nullptr ) return CBotTypResult( CBotErrOverParam ); + + // function returns a result "void" + return CBotTypResult( 0 ); +} + +// process FILE :: writeln + +// execution +bool rfwrite (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user) +{ + // there must be a parameter + if ( pVar == nullptr ) { Exception = CBotErrLowParam; return false; } + + // which must be a character string + if ( pVar->GetType() != CBotTypString ) { Exception = CBotErrBadString; return false; } + + std::string param = pVar->GetValString(); + + // retrieve the item "handle" + pVar = pThis->GetItem("handle"); + + if ( !pVar->IsDefined()) { Exception = CBotErrNotOpen; return false; } + + int fileHandle = pVar->GetValInt(); + + const auto handleIter = g_files.find(fileHandle); + if (handleIter == g_files.end()) + { + Exception = CBotErrNotOpen; + return false; + } + + handleIter->second->Write(param + "\n"); + + // if an error occurs generate an exception + if ( handleIter->second->Errored() ) { Exception = CBotErrWrite; return false; } + + return true; +} + +// compilation +CBotTypResult cfwrite (CBotVar* pThis, CBotVar* &pVar) +{ + // there must be a parameter + if ( pVar == nullptr ) return CBotTypResult( CBotErrLowParam ); + + // which must be a character string + if ( pVar->GetType() != CBotTypString ) return CBotTypResult( CBotErrBadString ); + + // no other parameter + if ( pVar->GetNext() != nullptr ) return CBotTypResult( CBotErrOverParam ); + + // the function returns a void result + return CBotTypResult( 0 ); +} + +// process FILE :: readln + +// execution +bool rfread(CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user) +{ + // it shouldn't be any parameters + if (pVar != nullptr) { Exception = CBotErrOverParam; return false; } + + // retrieve the item "handle" + pVar = pThis->GetItem("handle"); + + if (!pVar->IsDefined()) { Exception = CBotErrNotOpen; return false; } + + int fileHandle = pVar->GetValInt(); + + const auto handleIter = g_files.find(fileHandle); + if (handleIter == g_files.end()) + { + Exception = CBotErrNotOpen; + return false; + } + + std::string line = handleIter->second->ReadLine(); + + // if an error occurs generate an exception + if ( handleIter->second->Errored() ) { Exception = CBotErrRead; return false; } + + pResult->SetValString( line.c_str() ); + + return true; +} + +// compilation +CBotTypResult cfread (CBotVar* pThis, CBotVar* &pVar) +{ + // it should not be any parameter + if ( pVar != nullptr ) return CBotTypResult( CBotErrOverParam ); + + // function returns a result "string" + return CBotTypResult( CBotTypString ); +} +// process FILE :: readln + + +// execution +bool rfeof (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user) +{ + // it should not be any parameter + if ( pVar != nullptr ) { Exception = CBotErrOverParam; return false; } + + // retrieve the item "handle" + pVar = pThis->GetItem("handle"); + + if ( !pVar->IsDefined()) { Exception = CBotErrNotOpen; return false; } + + int fileHandle = pVar->GetValInt(); + + const auto handleIter = g_files.find(fileHandle); + if (handleIter == g_files.end()) + { + Exception = CBotErrNotOpen; + return false; + } + + pResult->SetValInt( handleIter->second->IsEOF() ); + + return true; +} + +// compilation +CBotTypResult cfeof (CBotVar* pThis, CBotVar* &pVar) +{ + // it shouldn't be any parameter + if ( pVar != nullptr ) return CBotTypResult( CBotErrOverParam ); + + // the function returns a boolean result + return CBotTypResult( CBotTypBoolean ); +} + +// Instruction "deletefile(filename)". + +bool rDeleteFile(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + std::string filename = var->GetValString(); + assert(g_fileHandler != nullptr); + return g_fileHandler->DeleteFile(filename); +} + + +void InitFileFunctions() +{ + // create a class for file management + // the use is as follows: + // file canal( "NomFichier.txt" ) + // canal.open( "r" ); // open for read + // s = canal.readln( ); // reads a line + // canal.close(); // close the file + + // create the class FILE + CBotClass* bc = CBotClass::Create("file", nullptr); + // adds the component ".filename" + bc->AddItem("filename", CBotTypString); + // adds the component ".handle" + bc->AddItem("handle", CBotTypInt, PR_PRIVATE); + + // define a constructor and a destructor + bc->AddFunction("file", rfconstruct, cfconstruct); + bc->AddFunction("~file", rfdestruct, nullptr); + + // end of the methods associated + bc->AddFunction("open", rfopen, cfopen); + bc->AddFunction("close", rfclose, cfclose); + bc->AddFunction("writeln", rfwrite, cfwrite); + bc->AddFunction("readln", rfread, cfread); + bc->AddFunction("eof", rfeof, cfeof ); + + CBotProgram::AddFunction("deletefile", rDeleteFile, cString); + + //m_pFuncFile = new CBotProgram( ); + //std::stringArray ListFonctions; + //m_pFuncFile->Compile( "public file openfile(string name, string mode) {return new file(name, mode);}", ListFonctions); + //m_pFuncFile->SetIdent(-2); // restoreState in special identifier for this function +} + +void SetFileAccessHandler(std::unique_ptr fileHandler) +{ + g_fileHandler = std::move(fileHandler); +} \ No newline at end of file diff --git a/src/CBot/stdlib/MathFunctions.cpp b/src/CBot/stdlib/MathFunctions.cpp new file mode 100644 index 00000000..9375b92d --- /dev/null +++ b/src/CBot/stdlib/MathFunctions.cpp @@ -0,0 +1,189 @@ +#include "CBot/stdlib/stdlib.h" + +#include "CBot/CBot.h" + +#include + +// Instruction "sin(degrees)". + +bool rSin(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GetValFloat(); + result->SetValFloat(sinf(value*M_PI/180.0f)); + return true; +} + +// Instruction "cos(degrees)". + +bool rCos(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GetValFloat(); + result->SetValFloat(cosf(value*M_PI/180.0f)); + return true; +} + +// Instruction "tan(degrees)". + +bool rTan(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GetValFloat(); + result->SetValFloat(tanf(value*M_PI/180.0f)); + return true; +} + +// Instruction "asin(degrees)". + +bool raSin(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GetValFloat(); + result->SetValFloat(asinf(value)*180.0f/M_PI); + return true; +} + +// Instruction "acos(degrees)". + +bool raCos(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GetValFloat(); + result->SetValFloat(acosf(value)*180.0f/M_PI); + return true; +} + +// Instruction "atan(degrees)". + +bool raTan(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GetValFloat(); + result->SetValFloat(atanf(value)*180.0f/M_PI); + return true; +} + +// Instruction "atan2(y,x)". + +bool raTan2(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float y = var->GetValFloat(); + var = var->GetNext(); + float x = var->GetValFloat(); + + result->SetValFloat(atan2(y, x) * 180.0f / M_PI); + return true; +} + +// Instruction "sqrt(value)". + +bool rSqrt(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GetValFloat(); + result->SetValFloat(sqrtf(value)); + return true; +} + +// Instruction "pow(x, y)". + +bool rPow(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float x, y; + + x = var->GetValFloat(); + var = var->GetNext(); + y = var->GetValFloat(); + result->SetValFloat(powf(x, y)); + return true; +} + +// Instruction "rand()". + +bool rRand(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + result->SetValFloat(static_cast(rand()) / static_cast(RAND_MAX)); + return true; +} + +// Instruction "abs()". + +bool rAbs(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GetValFloat(); + result->SetValFloat(fabs(value)); + return true; +} + +// Instruction "floor()" + +bool rFloor(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GetValFloat(); + result->SetValFloat(floor(value)); + return true; +} + +// Instruction "ceil()" + +bool rCeil(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GetValFloat(); + result->SetValFloat(ceil(value)); + return true; +} + +// Instruction "round()" + +bool rRound(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GetValFloat(); + result->SetValFloat(round(value)); + return true; +} + +// Instruction "trunc()" + +bool rTrunc(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + float value; + + value = var->GetValFloat(); + result->SetValFloat(trunc(value)); + return true; +} + +void InitMathFunctions() +{ + CBotProgram::AddFunction("sin", rSin, cOneFloat); + CBotProgram::AddFunction("cos", rCos, cOneFloat); + CBotProgram::AddFunction("tan", rTan, cOneFloat); + CBotProgram::AddFunction("asin", raSin, cOneFloat); + CBotProgram::AddFunction("acos", raCos, cOneFloat); + CBotProgram::AddFunction("atan", raTan, cOneFloat); + CBotProgram::AddFunction("atan2", raTan2, cTwoFloat); + CBotProgram::AddFunction("sqrt", rSqrt, cOneFloat); + CBotProgram::AddFunction("pow", rPow, cTwoFloat); + CBotProgram::AddFunction("rand", rRand, cNull); + CBotProgram::AddFunction("abs", rAbs, cOneFloat); + CBotProgram::AddFunction("floor", rFloor, cOneFloat); + CBotProgram::AddFunction("ceil", rCeil, cOneFloat); + CBotProgram::AddFunction("round", rRound, cOneFloat); + CBotProgram::AddFunction("trunc", rTrunc, cOneFloat); +} \ No newline at end of file diff --git a/src/CBot/StringFunctions.cpp b/src/CBot/stdlib/StringFunctions.cpp similarity index 65% rename from src/CBot/StringFunctions.cpp rename to src/CBot/stdlib/StringFunctions.cpp index 7ffe4254..91c63629 100644 --- a/src/CBot/StringFunctions.cpp +++ b/src/CBot/stdlib/StringFunctions.cpp @@ -18,12 +18,10 @@ */ // Modules inlcude -#include "CBot/StringFunctions.h" +#include "CBot/stdlib/stdlib.h" -#include "CBot/CBotProgram.h" -#include "CBot/CBotEnums.h" +#include "CBot/CBot.h" -#include "CBot/CBotVar/CBotVar.h" #include "CBot/CBotUtils.h" @@ -52,23 +50,6 @@ bool rStrLen( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser ) return true; } -//////////////////////////////////////////////////////////////////////////////// -CBotTypResult cIntStr( CBotVar* &pVar, void* pUser ) -{ - // it takes a parameter - if ( pVar == nullptr ) return CBotTypResult( TX_LOWPARAM ); - - // to be a string - if ( pVar->GetType() != CBotTypString ) - return CBotTypResult( TX_BADPARAM ); - - // no second parameter - if ( pVar->GetNext() != nullptr ) return CBotTypResult( TX_OVERPARAM ); - - // the end result is an integer - return CBotTypResult( CBotTypInt ); -} - //////////////////////////////////////////////////////////////////////////////// bool rStrLeft( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser ) { @@ -102,31 +83,6 @@ bool rStrLeft( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser ) return true; } -//////////////////////////////////////////////////////////////////////////////// -CBotTypResult cStrStrInt( CBotVar* &pVar, void* pUser ) -{ - // it takes a parameter - if ( pVar == nullptr ) return CBotTypResult( TX_LOWPARAM ); - - // to be a string - if ( pVar->GetType() != CBotTypString ) - return CBotTypResult( TX_BADSTRING ); - - // it takes a second parameter - pVar = pVar->GetNext(); - if ( pVar == nullptr ) return CBotTypResult( TX_LOWPARAM ); - - // which must be a number - if ( pVar->GetType() > CBotTypDouble ) - return CBotTypResult( TX_BADNUM ); - - // no third parameter - if ( pVar->GetNext() != nullptr ) return CBotTypResult( TX_OVERPARAM ); - - // the end result is a string - return CBotTypResult( CBotTypString ); -} - //////////////////////////////////////////////////////////////////////////////// bool rStrRight( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser ) { @@ -210,41 +166,6 @@ bool rStrMid( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser ) return true; } -//////////////////////////////////////////////////////////////////////////////// -CBotTypResult cStrStrIntInt( CBotVar* &pVar, void* pUser ) -{ - // it takes a parameter - if ( pVar == nullptr ) return CBotTypResult( TX_LOWPARAM ); - - // to be a string - if ( pVar->GetType() != CBotTypString ) - return CBotTypResult( TX_BADSTRING ); - - // it takes a second parameter - pVar = pVar->GetNext(); - if ( pVar == nullptr ) return CBotTypResult( TX_LOWPARAM ); - - // which must be a number - if ( pVar->GetType() > CBotTypDouble ) - return CBotTypResult( TX_BADNUM ); - - // third parameter optional - if ( pVar->GetNext() != nullptr ) - { - - pVar = pVar->GetNext(); - // which must be a number - if ( pVar->GetType() > CBotTypDouble ) - return CBotTypResult( TX_BADNUM ); - - // no fourth parameter - if ( pVar->GetNext() != nullptr ) return CBotTypResult( TX_OVERPARAM ); - } - - // the end result is a string - return CBotTypResult( CBotTypString ); -} - //////////////////////////////////////////////////////////////////////////////// bool rStrVal( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser ) { @@ -267,23 +188,6 @@ bool rStrVal( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser ) return true; } -//////////////////////////////////////////////////////////////////////////////// -CBotTypResult cFloatStr( CBotVar* &pVar, void* pUser ) -{ - // it takes a parameter - if ( pVar == nullptr ) return CBotTypResult( TX_LOWPARAM ); - - // to be a string - if ( pVar->GetType() != CBotTypString ) - return CBotTypResult( TX_BADSTRING ); - - // no second parameter - if ( pVar->GetNext() != nullptr ) return CBotTypResult( TX_OVERPARAM ); - - // the end result is a number - return CBotTypResult( CBotTypFloat ); -} - //////////////////////////////////////////////////////////////////////////////// bool rStrFind( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser ) { @@ -316,31 +220,6 @@ bool rStrFind( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser ) return true; } -//////////////////////////////////////////////////////////////////////////////// -CBotTypResult cIntStrStr( CBotVar* &pVar, void* pUser ) -{ - // it takes a parameter - if ( pVar == nullptr ) return CBotTypResult( TX_LOWPARAM ); - - // to be a string - if ( pVar->GetType() != CBotTypString ) - return CBotTypResult( TX_BADSTRING ); - - // it takes a second parameter - pVar = pVar->GetNext(); - if ( pVar == nullptr ) return CBotTypResult( TX_LOWPARAM ); - - // to be a string - if ( pVar->GetType() != CBotTypString ) - return CBotTypResult( TX_BADSTRING ); - - // no third parameter - if ( pVar->GetNext() != nullptr ) return CBotTypResult( TX_OVERPARAM ); - - // the end result is a number - return CBotTypResult( CBotTypInt ); -} - //////////////////////////////////////////////////////////////////////////////// bool rStrUpper( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser ) { @@ -387,22 +266,7 @@ bool rStrLower( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser ) return true; } -//////////////////////////////////////////////////////////////////////////////// -CBotTypResult cStrStr( CBotVar* &pVar, void* pUser ) -{ - // it takes a parameter - if ( pVar == nullptr ) return CBotTypResult( TX_LOWPARAM ); - // to be a string - if ( pVar->GetType() != CBotTypString ) - return CBotTypResult( TX_BADSTRING ); - - // no second parameter - if ( pVar->GetNext() != nullptr ) return CBotTypResult( TX_OVERPARAM ); - - // the end result is a string - return CBotTypResult( CBotTypString ); -} //////////////////////////////////////////////////////////////////////////////// void InitStringFunctions() diff --git a/src/CBot/stdlib/stdlib.h b/src/CBot/stdlib/stdlib.h new file mode 100644 index 00000000..fd75279b --- /dev/null +++ b/src/CBot/stdlib/stdlib.h @@ -0,0 +1,7 @@ +#pragma once + +#include "CBot/stdlib/stdlib_public.h" + +void InitStringFunctions(); +void InitFileFunctions(); +void InitMathFunctions(); \ No newline at end of file diff --git a/src/CBot/stdlib/stdlib_public.h b/src/CBot/stdlib/stdlib_public.h new file mode 100644 index 00000000..0497906e --- /dev/null +++ b/src/CBot/stdlib/stdlib_public.h @@ -0,0 +1,34 @@ +#pragma once + +#include "CBot/stdlib/Compilation.h" + +#include + +class CBotFile +{ +public: + virtual ~CBotFile() {} + + virtual bool Opened() = 0; + virtual bool Errored() = 0; + virtual bool IsEOF() = 0; + + virtual std::string ReadLine() = 0; + virtual void Write(const std::string& s) = 0; + + //TODO +}; + +class CBotFileAccessHandler +{ +public: + virtual ~CBotFileAccessHandler() {} + + enum class OpenMode : char { Read = 'r', Write = 'w' }; + virtual std::unique_ptr OpenFile(const std::string& filename, OpenMode mode) = 0; + virtual bool DeleteFile(const std::string& filename) = 0; +}; + +void SetFileAccessHandler(std::unique_ptr fileHandler); + +// TODO: provide default implementation of CBotFileAccessHandler \ No newline at end of file diff --git a/src/common/restext.cpp b/src/common/restext.cpp index 8b2cb435..db7a6c40 100644 --- a/src/common/restext.cpp +++ b/src/common/restext.cpp @@ -707,6 +707,7 @@ void InitializeRestext() stringsCbot[TX_CLBRK] = TR("\" ] \" missing"); stringsCbot[TX_RESERVED] = TR("Reserved keyword of CBOT language"); stringsCbot[TX_BADNEW] = TR("Bad argument for \"new\""); + stringsCbot[TX_OPBRK] = TR("\" [ \" expected"); stringsCbot[TX_BADSTRING] = TR("String missing"); stringsCbot[TX_BADINDEX] = TR("Incorrect index type"); stringsCbot[TX_PRIVATE] = TR("Private element"); @@ -714,6 +715,7 @@ void InitializeRestext() stringsCbot[TX_DIVZERO] = TR("Dividing by zero"); stringsCbot[TX_NOTINIT] = TR("Variable not initialized"); stringsCbot[TX_BADTHROW] = TR("Negative value rejected by \"throw\""); + stringsCbot[TX_NORETVAL] = TR("The function returned no value "); stringsCbot[TX_NORUN] = TR("No function running"); stringsCbot[TX_NOCALL] = TR("Calling an unknown function"); stringsCbot[TX_NOCLASS] = TR("This class does not exist"); @@ -722,6 +724,10 @@ void InitializeRestext() stringsCbot[TX_OUTARRAY] = TR("Access beyond array limit"); stringsCbot[TX_STACKOVER] = TR("Stack overflow"); stringsCbot[TX_DELETEDPT] = TR("Illegal object"); + stringsCbot[TX_FILEOPEN] = TR("Can't open file"); + stringsCbot[TX_NOTOPEN] = TR("File not open"); + stringsCbot[TX_ERRREAD] = TR("Read error"); + stringsCbot[TX_ERRWRITE] = TR("Write error"); } diff --git a/src/level/robotmain.cpp b/src/level/robotmain.cpp index 59265711..3929cf3f 100644 --- a/src/level/robotmain.cpp +++ b/src/level/robotmain.cpp @@ -4472,7 +4472,7 @@ std::string CRobotMain::GetNewScriptName(ObjectType type, int rank) //! Seeks if an object occupies in a spot, to prevent a backup of the game bool CRobotMain::IOIsBusy() { - if (CScriptFunctions::m_numberOfOpenFiles > 0) return true; + if (CScriptFunctions::CheckOpenFiles()) return true; for (CObject* obj : m_objMan->GetAllObjects()) { diff --git a/src/script/scriptfunc.cpp b/src/script/scriptfunc.cpp index 060dddc6..93e02419 100644 --- a/src/script/scriptfunc.cpp +++ b/src/script/scriptfunc.cpp @@ -68,49 +68,14 @@ #include "ui/displaytext.h" -// Compiling a procedure without any parameters. - -CBotTypResult CScriptFunctions::cNull(CBotVar* &var, void* user) -{ - if ( var != nullptr ) return CBotErrOverParam; - return CBotTypResult(CBotTypFloat); -} - CBotTypResult CScriptFunctions::cClassNull(CBotVar* thisclass, CBotVar* &var) { - return CScriptFunctions::cNull(var, nullptr); -} - -// Compiling a procedure with a single real number. - -CBotTypResult CScriptFunctions::cOneFloat(CBotVar* &var, void* user) -{ - if ( var == nullptr ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - if ( var != nullptr ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); + return cNull(var, nullptr); } CBotTypResult CScriptFunctions::cClassOneFloat(CBotVar* thisclass, CBotVar* &var) { - return CScriptFunctions::cOneFloat(var, nullptr); -} - -// Compiling a procedure with two real numbers. - -CBotTypResult CScriptFunctions::cTwoFloat(CBotVar* &var, void* user) -{ - if ( var == nullptr ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var == nullptr ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - - if ( var != nullptr ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); + return cOneFloat(var, nullptr); } // Compiling a procedure with a "dot". @@ -154,53 +119,6 @@ CBotTypResult CScriptFunctions::cOnePoint(CBotVar* &var, void* user) return CBotTypResult(CBotTypFloat); } -// Compiling a procedure with a single string. - -CBotTypResult CScriptFunctions::cString(CBotVar* &var, void* user) -{ - if ( var == nullptr ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() != CBotTypString && - var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - if ( var != nullptr ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); -} - -// Compiling a procedure with a single string, returning string. - -CBotTypResult CScriptFunctions::cStringString(CBotVar* &var, void* user) -{ - if ( var == nullptr ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() != CBotTypString && - var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - if ( var != nullptr ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypString); -} - -// compilation of instruction with one int returning int - -CBotTypResult CScriptFunctions::cOneInt(CBotVar* &var, void* user) -{ - if ( var == nullptr ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() != CBotTypInt ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - if ( var != nullptr ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypInt); -} - -// compilation of instruction with one int returning boolean - -CBotTypResult CScriptFunctions::cOneIntReturnBool(CBotVar* &var, void* user) -{ - if ( var == nullptr ) return CBotTypResult(CBotErrLowParam); - if ( var->GetType() != CBotTypInt ) return CBotTypResult(CBotErrBadNum); - var = var->GetNext(); - if ( var != nullptr ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypBoolean); -} - - // Seeking value in an array of integers. bool FindList(CBotVar* array, int type) @@ -259,171 +177,6 @@ bool GetPoint(CBotVar* &var, int& exception, Math::Vector& pos) } -// Instruction "sin(degrees)". - -bool CScriptFunctions::rSin(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GetValFloat(); - result->SetValFloat(sinf(value*Math::PI/180.0f)); - return true; -} - -// Instruction "cos(degrees)". - -bool CScriptFunctions::rCos(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GetValFloat(); - result->SetValFloat(cosf(value*Math::PI/180.0f)); - return true; -} - -// Instruction "tan(degrees)". - -bool CScriptFunctions::rTan(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GetValFloat(); - result->SetValFloat(tanf(value*Math::PI/180.0f)); - return true; -} - -// Instruction "asin(degrees)". - -bool raSin(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GetValFloat(); - result->SetValFloat(asinf(value)*180.0f/Math::PI); - return true; -} - -// Instruction "acos(degrees)". - -bool raCos(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GetValFloat(); - result->SetValFloat(acosf(value)*180.0f/Math::PI); - return true; -} - -// Instruction "atan(degrees)". - -bool raTan(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GetValFloat(); - result->SetValFloat(atanf(value)*180.0f/Math::PI); - return true; -} - -// Instruction "atan2(y,x)". - -bool raTan2(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float y = var->GetValFloat(); - var = var->GetNext(); - float x = var->GetValFloat(); - - result->SetValFloat(atan2(y, x) * 180.0f / Math::PI); - return true; -} - -// Instruction "sqrt(value)". - -bool CScriptFunctions::rSqrt(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GetValFloat(); - result->SetValFloat(sqrtf(value)); - return true; -} - -// Instruction "pow(x, y)". - -bool CScriptFunctions::rPow(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float x, y; - - x = var->GetValFloat(); - var = var->GetNext(); - y = var->GetValFloat(); - result->SetValFloat(powf(x, y)); - return true; -} - -// Instruction "rand()". - -bool CScriptFunctions::rRand(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - result->SetValFloat(Math::Rand()); - return true; -} - -// Instruction "abs()". - -bool CScriptFunctions::rAbs(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GetValFloat(); - result->SetValFloat(fabs(value)); - return true; -} - -// Instruction "floor()" - -bool CScriptFunctions::rFloor(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GetValFloat(); - result->SetValFloat(floor(value)); - return true; -} - -// Instruction "ceil()" - -bool CScriptFunctions::rCeil(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GetValFloat(); - result->SetValFloat(ceil(value)); - return true; -} - -// Instruction "round()" - -bool CScriptFunctions::rRound(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GetValFloat(); - result->SetValFloat(round(value)); - return true; -} - -// Instruction "trunc()" - -bool CScriptFunctions::rTrunc(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - float value; - - value = var->GetValFloat(); - result->SetValFloat(trunc(value)); - return true; -} - // Compilation of the instruction "endmission(result, delay)" CBotTypResult CScriptFunctions::cEndMission(CBotVar* &var, void* user) @@ -3132,391 +2885,6 @@ bool CScriptFunctions::rCameraFocus(CBotVar* var, CBotVar* result, int& exceptio return true; } -// Static variables - -int CScriptFunctions::m_numberOfOpenFiles = 0; -std::unordered_map> CScriptFunctions::m_files; -int CScriptFunctions::m_nextFile = 1; - - - -// Prepares a file name. - -void PrepareFilename(std::string &filename) -{ - CResourceManager::CreateDirectory("files"); - filename = "files/" + filename; - GetLogger()->Debug("CBot accessing file '%s'\n", filename.c_str()); -} - - -bool CScriptFunctions::FileClassOpenFile(CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception) -{ - std::string mode; - - // must be a character string - if ( pVar->GetType() != CBotTypString ) { Exception = CBotErrBadString; return false; } - - std::string filename = pVar->GetValString(); - PrepareFilename(filename); - - // there may be a second parameter - pVar = pVar->GetNext(); - if ( pVar != nullptr ) - { - // recover mode - mode = pVar->GetValString(); - if ( mode != "r" && mode != "w" ) { Exception = CBotErrBadParam; return false; } - - // no third parameter - if ( pVar->GetNext() != nullptr ) { Exception = CBotErrOverParam; return false; } - } - - // saves the file name - pVar = pThis->GetItem("filename"); - pVar->SetValString(filename); - - // retrieve the item "handle" - pVar = pThis->GetItem("handle"); - // which must not be initialized - if ( pVar->IsDefined()) { Exception = CBotErrFileOpen; return false; } - - if ( !mode.empty() ) - { - // opens the requested file - bool ok = false; - std::unique_ptr file; - if (mode == "r") - { - auto is = MakeUnique(filename); - ok = is->is_open(); - file = std::move(is); - } - else if (mode == "w") - { - auto os = MakeUnique(filename); - ok = os->is_open(); - file = std::move(os); - } - if (!ok) { Exception = CBotErrFileOpen; return false; } - - m_numberOfOpenFiles ++; - - int fileHandle = m_nextFile++; - - m_files[fileHandle] = std::move(file); - - // save the file handle - pVar = pThis->GetItem("handle"); - pVar->SetValInt(fileHandle); - } - return true; -} - -// constructor of the class -// get the filename as a parameter - -// execution -bool CScriptFunctions::rfconstruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user) -{ - // accepts no parameters - if ( pVar == nullptr ) return true; - - return FileClassOpenFile(pThis, pVar, pResult, Exception); -} - -// compilation -CBotTypResult CScriptFunctions::cfconstruct (CBotVar* pThis, CBotVar* &pVar) -{ - // accepts no parameters - if ( pVar == nullptr ) return CBotTypResult( 0 ); - - // must be a character string - if ( pVar->GetType() != CBotTypString ) - return CBotTypResult( CBotErrBadString ); - - // there may be a second parameter - pVar = pVar->GetNext(); - if ( pVar != nullptr ) - { - // which must be a string - if ( pVar->GetType() != CBotTypString ) - return CBotTypResult( CBotErrBadString ); - // no third parameter - if ( pVar->GetNext() != nullptr ) return CBotTypResult( CBotErrOverParam ); - } - - // the result is void (constructor) - return CBotTypResult( 0 ); -} - - -// destructor of the class - -// execution -bool CScriptFunctions::rfdestruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user) -{ - // retrieve the item "handle" - pVar = pThis->GetItem("handle"); - - // don't open? no problem :) - if ( pVar->IsDefined()) return true; - - int fileHandle = pVar->GetValInt(); - - std::ios* file = m_files[fileHandle].get(); - CInputStream* is = dynamic_cast(file); - if(is != nullptr) is->close(); - COutputStream* os = dynamic_cast(file); - if(os != nullptr) os->close(); - - m_numberOfOpenFiles--; - - pVar->SetInit(CBotVar::InitType::IS_NAN); - - m_files.erase(fileHandle); - - return true; -} - - -// process FILE :: open -// get the r/w mode as a parameter - -// execution -bool CScriptFunctions::rfopen (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user) -{ - // there must be a parameter - if ( pVar == nullptr ) { Exception = CBotErrLowParam; return false; } - - bool result = FileClassOpenFile(pThis, pVar, pResult, Exception); - pResult->SetValInt(result); - return result; -} - -// compilation -CBotTypResult CScriptFunctions::cfopen (CBotVar* pThis, CBotVar* &pVar) -{ - // there must be a parameter - if ( pVar == nullptr ) return CBotTypResult( CBotErrLowParam ); - - // which must be a string - if ( pVar->GetType() != CBotTypString ) - return CBotTypResult( CBotErrBadString ); - - // there may be a second parameter - pVar = pVar->GetNext(); - if ( pVar != nullptr ) - { - // which must be a string - if ( pVar->GetType() != CBotTypString ) - return CBotTypResult( CBotErrBadString ); - - // no third parameter - if ( pVar->GetNext() != nullptr ) return CBotTypResult( CBotErrOverParam ); - } - - // the result is bool - return CBotTypResult(CBotTypBoolean); -} - - -// process FILE :: close - -// execeution -bool CScriptFunctions::rfclose (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user) -{ - // it shouldn't be any parameters - if (pVar != nullptr) { Exception = CBotErrOverParam; return false; } - - // retrieve the item "handle" - pVar = pThis->GetItem("handle"); - - if ( !pVar->IsDefined()) { Exception = CBotErrNotOpen; return false; } - - int fileHandle = pVar->GetValInt(); - - const auto handleIter = m_files.find(fileHandle); - if (handleIter == m_files.end()) - { - Exception = CBotErrNotOpen; - return false; - } - - assert(handleIter->second); - - std::ios* file = handleIter->second.get(); - CInputStream* is = dynamic_cast(file); - if(is != nullptr) is->close(); - COutputStream* os = dynamic_cast(file); - if(os != nullptr) os->close(); - - m_numberOfOpenFiles--; - - pVar->SetInit(CBotVar::InitType::IS_NAN); - - m_files.erase(handleIter); - - return true; -} - -// compilation -CBotTypResult CScriptFunctions::cfclose (CBotVar* pThis, CBotVar* &pVar) -{ - // it shouldn't be any parameters - if ( pVar != nullptr ) return CBotTypResult( CBotErrOverParam ); - - // function returns a result "void" - return CBotTypResult( 0 ); -} - -// process FILE :: writeln - -// execution -bool CScriptFunctions::rfwrite (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user) -{ - // there must be a parameter - if ( pVar == nullptr ) { Exception = CBotErrLowParam; return false; } - - // which must be a character string - if ( pVar->GetType() != CBotTypString ) { Exception = CBotErrBadString; return false; } - - std::string param = pVar->GetValString(); - - // retrieve the item "handle" - pVar = pThis->GetItem("handle"); - - if ( !pVar->IsDefined()) { Exception = CBotErrNotOpen; return false; } - - int fileHandle = pVar->GetValInt(); - - const auto handleIter = m_files.find(fileHandle); - if (handleIter == m_files.end()) - { - Exception = CBotErrNotOpen; - return false; - } - - COutputStream* os = dynamic_cast(handleIter->second.get()); - if (os == nullptr) { Exception = CBotErrWrite; return false; } - - *os << param << "\n"; - - // if an error occurs generate an exception - if ( os->bad() ) { Exception = CBotErrWrite; return false; } - - return true; -} - -// compilation -CBotTypResult CScriptFunctions::cfwrite (CBotVar* pThis, CBotVar* &pVar) -{ - // there must be a parameter - if ( pVar == nullptr ) return CBotTypResult( CBotErrLowParam ); - - // which must be a character string - if ( pVar->GetType() != CBotTypString ) return CBotTypResult( CBotErrBadString ); - - // no other parameter - if ( pVar->GetNext() != nullptr ) return CBotTypResult( CBotErrOverParam ); - - // the function returns a void result - return CBotTypResult( 0 ); -} - -// process FILE :: readln - -// execution -bool CScriptFunctions::rfread(CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user) -{ - // it shouldn't be any parameters - if (pVar != nullptr) { Exception = CBotErrOverParam; return false; } - - // retrieve the item "handle" - pVar = pThis->GetItem("handle"); - - if (!pVar->IsDefined()) { Exception = CBotErrNotOpen; return false; } - - int fileHandle = pVar->GetValInt(); - - const auto handleIter = m_files.find(fileHandle); - if (handleIter == m_files.end()) - { - Exception = CBotErrNotOpen; - return false; - } - - CInputStream* is = dynamic_cast(handleIter->second.get()); - if (is == nullptr) { Exception = CBotErrRead; return false; } - - std::string line; - std::getline(*is, line); - - // if an error occurs generate an exception - if ( is->bad() ) { Exception = CBotErrRead; return false; } - - pResult->SetValString( line.c_str() ); - - return true; -} - -// compilation -CBotTypResult CScriptFunctions::cfread (CBotVar* pThis, CBotVar* &pVar) -{ - // it should not be any parameter - if ( pVar != nullptr ) return CBotTypResult( CBotErrOverParam ); - - // function returns a result "string" - return CBotTypResult( CBotTypString ); -} -// process FILE :: readln - - -// execution -bool CScriptFunctions::rfeof (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user) -{ - // it should not be any parameter - if ( pVar != nullptr ) { Exception = CBotErrOverParam; return false; } - - // retrieve the item "handle" - pVar = pThis->GetItem("handle"); - - if ( !pVar->IsDefined()) { Exception = CBotErrNotOpen; return false; } - - int fileHandle = pVar->GetValInt(); - - const auto handleIter = m_files.find(fileHandle); - if (handleIter == m_files.end()) - { - Exception = CBotErrNotOpen; - return false; - } - - pResult->SetValInt( handleIter->second->eof() ); - - return true; -} - -// compilation -CBotTypResult CScriptFunctions::cfeof (CBotVar* pThis, CBotVar* &pVar) -{ - // it shouldn't be any parameter - if ( pVar != nullptr ) return CBotTypResult( CBotErrOverParam ); - - // the function returns a boolean result - return CBotTypResult( CBotTypBoolean ); -} - -// Instruction "deletefile(filename)". - -bool CScriptFunctions::rDeleteFile(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - std::string filename; - - filename = var->GetValString(); - PrepareFilename(filename); - return CResourceManager::Remove(filename); -} // Compilation of class "point". @@ -3608,6 +2976,112 @@ bool CScriptFunctions::rPointConstructor(CBotVar* pThis, CBotVar* var, CBotVar* return true; // no interruption } +class CBotFileAccessHandlerColobot; +class CBotFileColobot : public CBotFile +{ +public: + static int m_numFilesOpen; + + CBotFileColobot(const std::string& filename, CBotFileAccessHandler::OpenMode mode) + { + if (mode == CBotFileAccessHandler::OpenMode::Read) + { + auto is = MakeUnique(filename); + if (is->is_open()) + { + m_file = std::move(is); + } + } + else if (mode == CBotFileAccessHandler::OpenMode::Write) + { + auto os = MakeUnique(filename); + if (os->is_open()) + { + m_file = std::move(os); + } + } + + if (Opened()) + { + GetLogger()->Info("CBot open file '%s'\n", filename.c_str()); + m_numFilesOpen++; + } + } + + ~CBotFileColobot() + { + if (Opened()) + { + GetLogger()->Debug("CBot close file\n"); + m_numFilesOpen--; + } + + std::ios* file = m_file.get(); + CInputStream* is = dynamic_cast(file); + if(is != nullptr) is->close(); + COutputStream* os = dynamic_cast(file); + if(os != nullptr) os->close(); + } + + virtual bool Opened() override + { + return m_file != nullptr; + } + + virtual bool Errored() override + { + return m_file->bad(); + } + + virtual bool IsEOF() override + { + return m_file->eof(); + } + + virtual std::string ReadLine() override + { + CInputStream* is = dynamic_cast(m_file.get()); + assert(is != nullptr); + + std::string line; + std::getline(*is, line); + return line; + } + + virtual void Write(const std::string& s) override + { + COutputStream* os = dynamic_cast(m_file.get()); + assert(os != nullptr); + + *os << s; + } + +private: + std::unique_ptr m_file; +}; +int CBotFileColobot::m_numFilesOpen = 0; + +class CBotFileAccessHandlerColobot : public CBotFileAccessHandler +{ +public: + virtual std::unique_ptr OpenFile(const std::string& filename, OpenMode mode) override + { + return MakeUnique(PrepareFilename(filename), mode); + } + + virtual bool DeleteFile(const std::string& filename) override + { + GetLogger()->Info("CBot delete file '%s'\n", filename.c_str()); + return CResourceManager::Remove(PrepareFilename(filename)); + } + +private: + static std::string PrepareFilename(const std::string& filename) + { + CResourceManager::CreateDirectory("files"); + return "files/" + filename; + } +}; @@ -3705,7 +3179,7 @@ void CScriptFunctions::Init() bc->AddItem("x", CBotTypFloat); bc->AddItem("y", CBotTypFloat); bc->AddItem("z", CBotTypFloat); - bc->AddFunction("point", CScriptFunctions::rPointConstructor, CScriptFunctions::cPointConstructor); + bc->AddFunction("point", rPointConstructor, cPointConstructor); // Adds the class Object. bc = CBotClass::Create("object", nullptr); @@ -3724,123 +3198,77 @@ void CScriptFunctions::Init() bc->AddItem("id", CBotTypResult(CBotTypInt), PR_READ); bc->AddItem("team", CBotTypResult(CBotTypInt), PR_READ); bc->AddItem("velocity", CBotTypResult(CBotTypClass, "point"), PR_READ); - bc->AddFunction("busy", CScriptFunctions::rBusy, CScriptFunctions::cBusy); - bc->AddFunction("factory", CScriptFunctions::rFactory, CScriptFunctions::cFactory); - bc->AddFunction("research", CScriptFunctions::rResearch, CScriptFunctions::cClassOneFloat); - bc->AddFunction("takeoff", CScriptFunctions::rTakeOff, CScriptFunctions::cClassNull); - bc->AddFunction("destroy", CScriptFunctions::rDestroy, CScriptFunctions::cClassNull); + bc->AddFunction("busy", rBusy, cBusy); + bc->AddFunction("factory", rFactory, cFactory); + bc->AddFunction("research", rResearch, cClassOneFloat); + bc->AddFunction("takeoff", rTakeOff, cClassNull); + bc->AddFunction("destroy", rDestroy, cClassNull); - // InitClassFILE: - // create a class for file management - // the use is as follows: - // file canal( "NomFichier.txt" ) - // canal.open( "r" ); // open for read - // s = canal.readln( ); // reads a line - // canal.close(); // close the file + CBotProgram::AddFunction("endmission",rEndMission,cEndMission); + CBotProgram::AddFunction("playmusic", rPlayMusic ,cPlayMusic); + CBotProgram::AddFunction("stopmusic", rStopMusic ,cNull); - // create the class FILE - bc = CBotClass::Create("file", nullptr); - // adds the component ".filename" - bc->AddItem("filename", CBotTypString); - // adds the component ".handle" - bc->AddItem("handle", CBotTypInt, PR_PRIVATE); + CBotProgram::AddFunction("getbuild", rGetBuild, cNull); + CBotProgram::AddFunction("getresearchenable", rGetResearchEnable, cNull); + CBotProgram::AddFunction("getresearchdone", rGetResearchDone, cNull); + CBotProgram::AddFunction("setbuild", rSetBuild, cOneInt); + CBotProgram::AddFunction("setresearchenable", rSetResearchEnable, cOneInt); + CBotProgram::AddFunction("setresearchdone", rSetResearchDone, cOneInt); - // define a constructor and a destructor - bc->AddFunction("file", CScriptFunctions::rfconstruct, CScriptFunctions::cfconstruct ); - bc->AddFunction("~file", CScriptFunctions::rfdestruct, nullptr ); + CBotProgram::AddFunction("canbuild", rCanBuild, cOneIntReturnBool); + CBotProgram::AddFunction("canresearch", rCanResearch, cOneIntReturnBool); + CBotProgram::AddFunction("researched", rResearched, cOneIntReturnBool); + CBotProgram::AddFunction("buildingenabled", rBuildingEnabled, cOneIntReturnBool); - // end of the methods associated - bc->AddFunction("open", CScriptFunctions::rfopen, CScriptFunctions::cfopen ); - bc->AddFunction("close", CScriptFunctions::rfclose, CScriptFunctions::cfclose ); - bc->AddFunction("writeln", CScriptFunctions::rfwrite, CScriptFunctions::cfwrite ); - bc->AddFunction("readln", CScriptFunctions::rfread, CScriptFunctions::cfread ); - bc->AddFunction("eof", CScriptFunctions::rfeof, CScriptFunctions::cfeof ); + CBotProgram::AddFunction("build", rBuild, cOneInt); - //m_pFuncFile = new CBotProgram( ); - //std::stringArray ListFonctions; - //m_pFuncFile->Compile( "public file openfile(string name, string mode) {return new file(name, mode);}", ListFonctions); - //m_pFuncFile->SetIdent(-2); // restoreState in special identifier for this function - - CBotProgram::AddFunction("sin", rSin, CScriptFunctions::cOneFloat); - CBotProgram::AddFunction("cos", rCos, CScriptFunctions::cOneFloat); - CBotProgram::AddFunction("tan", rTan, CScriptFunctions::cOneFloat); - CBotProgram::AddFunction("asin", raSin, CScriptFunctions::cOneFloat); - CBotProgram::AddFunction("acos", raCos, CScriptFunctions::cOneFloat); - CBotProgram::AddFunction("atan", raTan, CScriptFunctions::cOneFloat); - CBotProgram::AddFunction("atan2", raTan2, CScriptFunctions::cTwoFloat); - CBotProgram::AddFunction("sqrt", rSqrt, CScriptFunctions::cOneFloat); - CBotProgram::AddFunction("pow", rPow, CScriptFunctions::cTwoFloat); - CBotProgram::AddFunction("rand", rRand, CScriptFunctions::cNull); - CBotProgram::AddFunction("abs", rAbs, CScriptFunctions::cOneFloat); - CBotProgram::AddFunction("floor", rFloor, CScriptFunctions::cOneFloat); - CBotProgram::AddFunction("ceil", rCeil, CScriptFunctions::cOneFloat); - CBotProgram::AddFunction("round", rRound, CScriptFunctions::cOneFloat); - CBotProgram::AddFunction("trunc", rTrunc, CScriptFunctions::cOneFloat); - - CBotProgram::AddFunction("endmission",rEndMission,CScriptFunctions::cEndMission); - CBotProgram::AddFunction("playmusic", rPlayMusic ,CScriptFunctions::cPlayMusic); - CBotProgram::AddFunction("stopmusic", rStopMusic ,CScriptFunctions::cNull); - - CBotProgram::AddFunction("getbuild", rGetBuild, CScriptFunctions::cNull); - CBotProgram::AddFunction("getresearchenable", rGetResearchEnable, CScriptFunctions::cNull); - CBotProgram::AddFunction("getresearchdone", rGetResearchDone, CScriptFunctions::cNull); - CBotProgram::AddFunction("setbuild", rSetBuild, CScriptFunctions::cOneInt); - CBotProgram::AddFunction("setresearchenable", rSetResearchEnable, CScriptFunctions::cOneInt); - CBotProgram::AddFunction("setresearchdone", rSetResearchDone, CScriptFunctions::cOneInt); - - CBotProgram::AddFunction("canbuild", rCanBuild, CScriptFunctions::cOneIntReturnBool); - CBotProgram::AddFunction("canresearch", rCanResearch, CScriptFunctions::cOneIntReturnBool); - CBotProgram::AddFunction("researched", rResearched, CScriptFunctions::cOneIntReturnBool); - CBotProgram::AddFunction("buildingenabled", rBuildingEnabled, CScriptFunctions::cOneIntReturnBool); - - CBotProgram::AddFunction("build", rBuild, CScriptFunctions::cOneInt); - - CBotProgram::AddFunction("retobject", rGetObject, CScriptFunctions::cGetObject); - CBotProgram::AddFunction("retobjectbyid", rGetObjectById, CScriptFunctions::cGetObject); - CBotProgram::AddFunction("delete", rDelete, CScriptFunctions::cDelete); - CBotProgram::AddFunction("search", rSearch, CScriptFunctions::cSearch); - CBotProgram::AddFunction("radar", rRadar, CScriptFunctions::cRadar); - CBotProgram::AddFunction("radarall", rRadarAll, CScriptFunctions::cRadarAll); - CBotProgram::AddFunction("detect", rDetect, CScriptFunctions::cDetect); - CBotProgram::AddFunction("direction", rDirection, CScriptFunctions::cDirection); - CBotProgram::AddFunction("produce", rProduce, CScriptFunctions::cProduce); - CBotProgram::AddFunction("distance", rDistance, CScriptFunctions::cDistance); - CBotProgram::AddFunction("distance2d",rDistance2d,CScriptFunctions::cDistance); - CBotProgram::AddFunction("space", rSpace, CScriptFunctions::cSpace); - CBotProgram::AddFunction("flatspace", rFlatSpace, CScriptFunctions::cFlatSpace); - CBotProgram::AddFunction("flatground",rFlatGround,CScriptFunctions::cFlatGround); - CBotProgram::AddFunction("wait", rWait, CScriptFunctions::cOneFloat); - CBotProgram::AddFunction("move", rMove, CScriptFunctions::cOneFloat); - CBotProgram::AddFunction("turn", rTurn, CScriptFunctions::cOneFloat); - CBotProgram::AddFunction("goto", rGoto, CScriptFunctions::cGoto); - CBotProgram::AddFunction("grab", rGrab, CScriptFunctions::cGrabDrop); - CBotProgram::AddFunction("drop", rDrop, CScriptFunctions::cGrabDrop); - CBotProgram::AddFunction("sniff", rSniff, CScriptFunctions::cNull); - CBotProgram::AddFunction("receive", rReceive, CScriptFunctions::cReceive); - CBotProgram::AddFunction("send", rSend, CScriptFunctions::cSend); - CBotProgram::AddFunction("deleteinfo",rDeleteInfo,CScriptFunctions::cDeleteInfo); - CBotProgram::AddFunction("testinfo", rTestInfo, CScriptFunctions::cTestInfo); - CBotProgram::AddFunction("thump", rThump, CScriptFunctions::cNull); - CBotProgram::AddFunction("recycle", rRecycle, CScriptFunctions::cNull); - CBotProgram::AddFunction("shield", rShield, CScriptFunctions::cShield); - CBotProgram::AddFunction("fire", rFire, CScriptFunctions::cFire); - CBotProgram::AddFunction("aim", rAim, CScriptFunctions::cAim); - CBotProgram::AddFunction("motor", rMotor, CScriptFunctions::cMotor); - CBotProgram::AddFunction("jet", rJet, CScriptFunctions::cOneFloat); - CBotProgram::AddFunction("topo", rTopo, CScriptFunctions::cTopo); - CBotProgram::AddFunction("message", rMessage, CScriptFunctions::cMessage); - CBotProgram::AddFunction("cmdline", rCmdline, CScriptFunctions::cOneFloat); - CBotProgram::AddFunction("ismovie", rIsMovie, CScriptFunctions::cNull); - CBotProgram::AddFunction("errmode", rErrMode, CScriptFunctions::cOneFloat); - CBotProgram::AddFunction("ipf", rIPF, CScriptFunctions::cOneFloat); - CBotProgram::AddFunction("abstime", rAbsTime, CScriptFunctions::cNull); - CBotProgram::AddFunction("deletefile",rDeleteFile,CScriptFunctions::cString); - CBotProgram::AddFunction("pendown", rPenDown, CScriptFunctions::cPenDown); - CBotProgram::AddFunction("penup", rPenUp, CScriptFunctions::cNull); - CBotProgram::AddFunction("pencolor", rPenColor, CScriptFunctions::cOneFloat); - CBotProgram::AddFunction("penwidth", rPenWidth, CScriptFunctions::cOneFloat); + CBotProgram::AddFunction("retobject", rGetObject, cGetObject); + CBotProgram::AddFunction("retobjectbyid", rGetObjectById, cGetObject); + CBotProgram::AddFunction("delete", rDelete, cDelete); + CBotProgram::AddFunction("search", rSearch, cSearch); + CBotProgram::AddFunction("radar", rRadar, cRadar); + CBotProgram::AddFunction("radarall", rRadarAll, cRadarAll); + CBotProgram::AddFunction("detect", rDetect, cDetect); + CBotProgram::AddFunction("direction", rDirection, cDirection); + CBotProgram::AddFunction("produce", rProduce, cProduce); + CBotProgram::AddFunction("distance", rDistance, cDistance); + CBotProgram::AddFunction("distance2d",rDistance2d,cDistance); + CBotProgram::AddFunction("space", rSpace, cSpace); + CBotProgram::AddFunction("flatspace", rFlatSpace, cFlatSpace); + CBotProgram::AddFunction("flatground",rFlatGround,cFlatGround); + CBotProgram::AddFunction("wait", rWait, cOneFloat); + CBotProgram::AddFunction("move", rMove, cOneFloat); + CBotProgram::AddFunction("turn", rTurn, cOneFloat); + CBotProgram::AddFunction("goto", rGoto, cGoto); + CBotProgram::AddFunction("grab", rGrab, cGrabDrop); + CBotProgram::AddFunction("drop", rDrop, cGrabDrop); + CBotProgram::AddFunction("sniff", rSniff, cNull); + CBotProgram::AddFunction("receive", rReceive, cReceive); + CBotProgram::AddFunction("send", rSend, cSend); + CBotProgram::AddFunction("deleteinfo",rDeleteInfo,cDeleteInfo); + CBotProgram::AddFunction("testinfo", rTestInfo, cTestInfo); + CBotProgram::AddFunction("thump", rThump, cNull); + CBotProgram::AddFunction("recycle", rRecycle, cNull); + CBotProgram::AddFunction("shield", rShield, cShield); + CBotProgram::AddFunction("fire", rFire, cFire); + CBotProgram::AddFunction("aim", rAim, cAim); + CBotProgram::AddFunction("motor", rMotor, cMotor); + CBotProgram::AddFunction("jet", rJet, cOneFloat); + CBotProgram::AddFunction("topo", rTopo, cTopo); + CBotProgram::AddFunction("message", rMessage, cMessage); + CBotProgram::AddFunction("cmdline", rCmdline, cOneFloat); + CBotProgram::AddFunction("ismovie", rIsMovie, cNull); + CBotProgram::AddFunction("errmode", rErrMode, cOneFloat); + CBotProgram::AddFunction("ipf", rIPF, cOneFloat); + CBotProgram::AddFunction("abstime", rAbsTime, cNull); + CBotProgram::AddFunction("pendown", rPenDown, cPenDown); + CBotProgram::AddFunction("penup", rPenUp, cNull); + CBotProgram::AddFunction("pencolor", rPenColor, cOneFloat); + CBotProgram::AddFunction("penwidth", rPenWidth, cOneFloat); CBotProgram::AddFunction("camerafocus", rCameraFocus, CScriptFunctions::cOneObject); + + SetFileAccessHandler(MakeUnique()); } @@ -4016,3 +3444,8 @@ void CScriptFunctions::DestroyObjectVar(CBotVar* botVar, bool permanent) if (permanent) CBotVar::Destroy(botVar); } + +bool CScriptFunctions::CheckOpenFiles() +{ + return CBotFileColobot::m_numFilesOpen > 0; +} \ No newline at end of file diff --git a/src/script/scriptfunc.h b/src/script/scriptfunc.h index e739ecdd..8746ae57 100644 --- a/src/script/scriptfunc.h +++ b/src/script/scriptfunc.h @@ -42,17 +42,13 @@ class CScriptFunctions { public: static void Init(); + static CBotVar* CreateObjectVar(CObject* obj); static void DestroyObjectVar(CBotVar* botVar, bool permanent); + static bool CheckOpenFiles(); + private: - static CBotTypResult cNull(CBotVar* &var, void* user); - static CBotTypResult cOneFloat(CBotVar* &var, void* user); - static CBotTypResult cTwoFloat(CBotVar* &var, void* user); - static CBotTypResult cString(CBotVar* &var, void* user); - static CBotTypResult cStringString(CBotVar* &var, void* user); - static CBotTypResult cOneInt(CBotVar* &var, void* user); - static CBotTypResult cOneIntReturnBool(CBotVar* &var, void* user); static CBotTypResult cEndMission(CBotVar* &var, void* user); static CBotTypResult cPlayMusic(CBotVar* &var, void* user); static CBotTypResult cGetObject(CBotVar* &var, void* user); @@ -80,22 +76,11 @@ private: static CBotTypResult cTopo(CBotVar* &var, void* user); static CBotTypResult cMessage(CBotVar* &var, void* user); static CBotTypResult cPenDown(CBotVar* &var, void* user); + static CBotTypResult cOnePoint(CBotVar* &var, void* user); static CBotTypResult cPoint(CBotVar* &var, void* user); static CBotTypResult cOneObject(CBotVar* &var, void* user); - - static bool rSin(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rCos(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rTan(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rSqrt(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rPow(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rRand(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rAbs(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rFloor(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rCeil(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rRound(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rTrunc(CBotVar* var, CBotVar* result, int& exception, void* user); static bool rEndMission(CBotVar* var, CBotVar* result, int& exception, void* user); static bool rPlayMusic(CBotVar* var, CBotVar* result, int& exception, void* user); static bool rStopMusic(CBotVar* var, CBotVar* result, int& exception, void* user); @@ -149,7 +134,6 @@ private: static bool rErrMode(CBotVar* var, CBotVar* result, int& exception, void* user); static bool rIPF(CBotVar* var, CBotVar* result, int& exception, void* user); static bool rAbsTime(CBotVar* var, CBotVar* result, int& exception, void* user); - static bool rDeleteFile(CBotVar* var, CBotVar* result, int& exception, void* user); static bool rPenDown(CBotVar* var, CBotVar* result, int& exception, void* user); static bool rPenUp(CBotVar* var, CBotVar* result, int& exception, void* user); static bool rPenColor(CBotVar* var, CBotVar* result, int& exception, void* user); @@ -168,37 +152,14 @@ private: static bool rTakeOff(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception, void* user); static bool rDestroy(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception, void* user); - - static CBotTypResult cfconstruct (CBotVar* pThis, CBotVar* &pVar); - static CBotTypResult cfopen (CBotVar* pThis, CBotVar* &pVar); - static CBotTypResult cfclose (CBotVar* pThis, CBotVar* &pVar); - static CBotTypResult cfwrite (CBotVar* pThis, CBotVar* &pVar); - static CBotTypResult cfread (CBotVar* pThis, CBotVar* &pVar); - static CBotTypResult cfeof (CBotVar* pThis, CBotVar* &pVar); - static bool rfconstruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user); - static bool rfdestruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user); - static bool rfopen (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user); - static bool rfclose (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user); - static bool rfwrite (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user); - static bool rfread (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user); - static bool rfeof (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, void* user); - static CBotTypResult cPointConstructor(CBotVar* pThis, CBotVar* &var); static bool rPointConstructor(CBotVar* pThis, CBotVar* var, CBotVar* pResult, int& Exception, void* user); static void uObject(CBotVar* botThis, void* user); -public: - static int m_numberOfOpenFiles; - private: static bool WaitForForegroundTask(CScript* script, CBotVar* result, int &exception); static bool WaitForBackgroundTask(CScript* script, CBotVar* result, int &exception); static bool ShouldTaskStop(Error err, int errMode); static CExchangePost* FindExchangePost(CObject* object, float power); - - static bool FileClassOpenFile(CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception); - - static std::unordered_map> m_files; - static int m_nextFile; };