Advertisement
egor230

lua api c++

Feb 19th, 2019
688
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 461.42 KB | None | 0 0
  1. lua c++ api подготовка проекта
  2. Начальная проверка
  3.  
  4. #include<iostream>
  5. using namespace std;
  6.  
  7. int main(int argc, char *argv[]) {
  8.  
  9. return 0;
  10. };
  11.  
  12.  
  13. Проверка lua
  14.  
  15. #include<iostream>
  16. #include"incude/lua.hpp"
  17. using namespace std;
  18.  
  19. int main(int argc, char *argv[]) {
  20.  
  21. return 0;
  22. };
  23.  
  24. lua api c++. Работа со стеком.
  25.  
  26. #include<iostream>
  27. #include"lua/lua.hpp"
  28. using namespace std;
  29.  
  30. //Стек(англ.stack — стопка; читается стэк) — абстрактный тип данных, представляющий собой список элементов,
  31. //организованных по принципу LIFO(англ.last in — first out, «последний вошёл — первым вышел»)
  32. int main(int argc, char *argv[]) {
  33.  
  34.     lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  35.     lua_pushnumber(L, 10);// отправить в стек число.
  36.     lua_pushnumber(L, 20);// отправить в стек число.
  37.     lua_pushnumber(L, 30);// отправить в стек число.
  38.     int number = lua_tonumber(L, -3);// получить 10 из стека 1
  39.     cout << number << endl;
  40.     int number2 = lua_tonumber(L, -2);// получить 20 из стека 2
  41.     cout << number2 << endl;
  42.     int number3 = lua_tonumber(L, -1);// получить 30 из стека 3
  43.     cout << number3 << endl;
  44.  
  45.     lua_close(L);// закрыть состояние
  46. return 0;
  47. };
  48.  
  49.  
  50. lua c++ api. Работа со стеком. Полезность отрицательных индексов стека.
  51.  
  52. int main(int argc, char *argv[]) {lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  53.  
  54.     lua_pushnumber(L, 10);// 1
  55.     lua_pushnumber(L, 20);// 2
  56.     lua_pushnumber(L, 30);// 3
  57.     /* стек выглядит так
  58.     3 = 30    -1 = 30  
  59.     2 = 20    -2 = 20
  60.     1 = 10    -3 = 10
  61.     */
  62.     cout << lua_tonumber(L, -1) << endl;// 30
  63.     lua_pop(L, 1);// удалить n элементы из стека с его вершины. Если 3, выводится 0.
  64.     cout << lua_tonumber(L, -1) << endl;// 20
  65.     lua_close(L);// закрыть состояние
  66.     cin.get();//ожидает ввода символа программа завершается.
  67.     return 0;}
  68.  
  69.  
  70. еще пример.
  71.  
  72. int checklua(lua_State *L, const char *file) {
  73.     int status = luaL_loadfile(L, file);// проверка есть ли ошибки.
  74.     try {
  75.         if (status == 0) {// если нет ошибки в файле.
  76.             luaL_dofile(L, file);// запуск файла, в которым все происходит.
  77.             return 0;
  78.         }
  79.         else {
  80.             string x = lua_tostring(L, -1);
  81.             throw x;
  82.         }
  83.     }
  84.     catch (string x) {
  85.         cout << x << endl;
  86.         //luaL_error(L,"error");
  87.     }
  88. };
  89.  
  90. template <class T>
  91. void pushlua(lua_State * L, const T & value) {// функция добавление любого значение в стек.
  92.     if constexpr (std::is_same_v<T, std::string>)
  93.         lua_pushstring(L, value.c_str());
  94.     else if constexpr (std::is_array_v<T> && std::is_same_v<std::remove_extent_t<T>, char>)
  95.         lua_pushstring(L, value);
  96.     else if constexpr (std::is_same_v<T, int>)
  97.         lua_pushinteger(L, value);
  98.     else if constexpr (std::is_same_v<T, double>)
  99.         lua_pushnumber(L, value);
  100.     else if constexpr (std::is_same_v<T, bool>)
  101.         lua_pushboolean(L, value);
  102.     else
  103.         std::cerr << "I do not know what to do :(" << std::endl;
  104. };
  105.  
  106. void showstack(lua_State* L) {// вывести весь стек.
  107.     int i = lua_gettop(L);/* получаем количество элементов в стеке.*/
  108.     cout << "\n  the number on the stack = " << i << "\n\n\n";
  109.     int j = (i) * -1-1;
  110.     i = -1;
  111.     for (i; i > j; i--) {
  112.         int t = lua_type(L, i);
  113.         cout << "\t " << i << "  " << (j - i) * -1 << "\t";
  114.         if (LUA_TSTRING == t) {
  115.             cout << lua_tostring(L, i) << endl;
  116.         }
  117.         if (LUA_TNUMBER == t) {
  118.             double x = lua_tonumber(L, i);
  119.             int x2 = (int)x;
  120.             if (x == x2) { cout << x2 << endl; }
  121.             else { cout << x << endl; }
  122.         }
  123.         if (LUA_TBOOLEAN == t) {
  124.             cout << lua_toboolean(L, i) << endl;
  125.         }
  126.         if (LUA_TLIGHTUSERDATA == t) {
  127.             cout << "LIGHTUSERDATA " << endl;
  128.         }
  129.         if (LUA_TTABLE == t) {
  130.             cout << "LUA_TTABLE " << endl;
  131.         }
  132.         if (LUA_TFUNCTION == t) {
  133.             cout << "LUA_TFUNCTION " << endl;
  134.         }
  135.         if (LUA_TUSERDATA == t) {
  136.             cout << "LUA_TUSERDATA " << endl;
  137.         }
  138.         if (LUA_TNIL == t) {
  139.             cout << "LUA_TNIL " << endl;
  140.         }
  141.     }
  142. };
  143.  
  144. int main() {
  145.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  146.     luaL_openlibs(L);
  147.     pushlua(L, 10);// отправить любое значение в стек.  
  148.     pushlua(L, 20);// отправить любое значение в стек.  
  149.     pushlua(L, 30);// отправить любое значение в стек.
  150.     showstack(L);// вывести стек.
  151.  
  152.     cin.get();//ожидает ввода символа.
  153.  
  154.     pushlua(L, "a");// отправить любое значение в стек.
  155.     pushlua(L, "b");// отправить любое значение в стек. 
  156.     pushlua(L, "c");// отправить любое значение в стек. 
  157.     showstack(L);// вывести стек.
  158.  
  159.     cin.get();//ожидает ввода символа.
  160.  
  161.     lua_pop(L, 4); //удалить 4 элемента из стека.
  162.  
  163.     showstack(L);// вывести стек.
  164.  
  165.     cin.get();//ожидает ввода символа.
  166.  
  167. Выводится.
  168.  
  169.  
  170.   the number on the stack = 3
  171.  
  172.  
  173.          -1  3  30
  174.          -2  2  20
  175.          -3  1  10
  176.  
  177.  
  178.   the number on the stack = 6
  179.  
  180.  
  181.          -1  6  c
  182.          -2  5  b
  183.          -3  4  a
  184.          -4  3  30
  185.          -5  2  20
  186.          -6  1  10
  187.  
  188.  
  189.   the number on the stack = 2
  190.  
  191.  
  192.          -1  2  20
  193.          -2  1  10
  194.  
  195.  
  196. C:\Users\e\source\repos\Project1luaapi\Debug\Project1luaapi.exe (процесс 4608) завершает работу с кодом 0.
  197. Чтобы закрыть это окно, нажмите любую клавишу…
  198.  
  199. lua c++ api. Получение значения переменных из lua.
  200.  
  201. #include<iostream>
  202. #include<string>
  203. #include"lua/lua.hpp"
  204. using namespace std;
  205. int main() {
  206.     lua_State *L = luaL_newstate();
  207.     luaL_openlibs(L);
  208.     luaL_dofile(L, "man.lua");
  209.     lua_getglobal(L, "x");
  210.     lua_getglobal(L, "y");
  211.     lua_getglobal(L, "z");
  212.     int x = lua_tonumber(L, 1);
  213.     cout << x << endl;
  214.     string y = lua_tostring(L, 2);
  215.     cout << y << endl;
  216.     bool z = lua_toboolean(L, 3);
  217.     cout << z << endl;
  218.     lua_close(L);
  219.     return 0;
  220.  
  221. lua
  222. x=3
  223. y="jh"
  224. z =false
  225.  
  226. lua c++ api. Получение значения переменных из lua с помощью отрицательных индексов стека.
  227.  
  228. int checklua(lua_State *L, const char *file) {
  229.     int status = luaL_loadfile(L, file);// проверка есть ли ошибки.
  230.     try {
  231.         if (status == 0) {// если нет ошибки в файле.
  232.             luaL_dofile(L, file);// запуск файла, в которым все происходит.
  233.             return 0;
  234.         }
  235.         else {
  236.             string x = lua_tostring(L, -1);
  237.             throw x;
  238.         }
  239.     }
  240.     catch (string x) {
  241.         cout << x << endl;
  242.         //luaL_error(L,"error");
  243.     }
  244. };
  245.  
  246. int main() {int t;
  247.     lua_State *L = luaL_newstate();
  248.    checklua(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  249.     lua_getglobal(L, "x");// получить значение глобальной переменной x.
  250.    
  251.     t = lua_type(L, -1);
  252.     if (LUA_TSTRING == t) { cout << "string x " << lua_tostring(L, -1) << endl; }
  253.     else { cout << "not string  x " << endl; }
  254.  
  255.     lua_getglobal(L, "y");// получить значение глобальной переменной x.
  256.     t = lua_type(L, -1);
  257.     if (LUA_TSTRING == t) { cout << "string y " << lua_tostring(L, -1) << endl; }
  258.     else { cout << "not string  y " << endl; }
  259.  
  260.     int n = lua_gettop(L);/* получаем количество элементов в стеке.*/
  261.     cout <<"\nthe number on the stack = "  << n<<"\n";
  262.     lua_settop(L, 0);// уст кол-во элементов в стеке. 0 - очистить стек.
  263.  
  264.        n = lua_gettop(L);/* получаем количество элементов в стеке.*/
  265.     cout << "\nthe number on the stack = " << n << "\n";
  266.  
  267.     lua_close(L);// закрыть состояние
  268.     cin.get();//ожидает ввода символа программа завершается.
  269.  
  270.     return 0;
  271. }
  272.  
  273. Lua
  274. y="i str"
  275. x=23
  276.  
  277. выводится.
  278.  
  279. not string  x
  280. string y i str
  281.  
  282. the number on the stack = 3
  283.  
  284. the number on the stack = 0
  285.  
  286.  
  287. lua c++ api. Функции вывода элементов из стека и добавление лобого значение в стек.
  288.  
  289.  
  290. int checklua(lua_State *L, const char *file) {
  291.     int status = luaL_loadfile(L, file);// проверка есть ли ошибки.
  292.     try {
  293.         if (status == 0) {// если нет ошибки в файле.
  294.             luaL_dofile(L, file);// запуск файла, в которым все происходит.
  295.             return 0;
  296.         }
  297.         else {
  298.             string x = lua_tostring(L, -1);
  299.             throw x;
  300.         }
  301.     }
  302.     catch (string x) {
  303.         cout << x << endl;
  304.         //luaL_error(L,"error");
  305.     }
  306. };
  307. int main() {
  308.     lua_State *L = luaL_newstate();
  309.     checklua(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  310.    pushlua(L, "yes");// отправить любое значение в стек.
  311.     pushlua(L,true);// отправить любое значение в стек. 
  312.     pushlua(L,100);// отправить любое значение в стек.
  313.     pushlua(L,33.23);// отправить любое значение в стек.
  314.     pushlua(L, "no");// отправить любое значение в стек.
  315.     pushlua(L, 202);// отправить любое значение в стек. 
  316.     showstack(L);
  317.     lua_pushvalue(L, 3);// отправляет копию элемент на вершину стека.
  318.     showstack(L);
  319.     lua_close(L);// закрыть состояние
  320.     cin.get();//ожидает ввода символа программа завершается.
  321.     return 0;
  322. };
  323.  
  324.  
  325. Выводится на экран.
  326.  
  327.  
  328.   the number on the stack = 6
  329.  
  330.  
  331.          6  202
  332.          5  no
  333.          4  33.23
  334.          3  100
  335.          2  1
  336.          1  yes
  337.  
  338.   the number on the stack = 7
  339.  
  340.  
  341.          7  100
  342.          6  202
  343.          5  no
  344.          4  33.23
  345.          3  100
  346.          2  1
  347.          1  yes
  348.  
  349.  
  350.  
  351. lua c++ api. Функции вывода элементов через отрицательные индексы из стека и добавление лобого значение в стек.
  352.  
  353. int checklua(lua_State *L, const char *file) {
  354.     int status = luaL_loadfile(L, file);// проверка есть ли ошибки.
  355.     try {
  356.         if (status == 0) {// если нет ошибки в файле.
  357.             luaL_dofile(L, file);// запуск файла, в которым все происходит.
  358.             return 0;
  359.         }
  360.         else {
  361.             string x = lua_tostring(L, -1);
  362.             throw x;
  363.         }
  364.     }
  365.     catch (string x) {
  366.         cout << x << endl;
  367.         //luaL_error(L,"error");
  368.     }
  369. };
  370.  
  371. int main() {
  372.     lua_State *L = luaL_newstate();
  373.     pushlua(L, "yes");// отправить любое значение в стек.   
  374.     pushlua(L, true);// отправить любое значение в стек.
  375.     pushlua(L, 100);// отправить любое значение в стек.
  376.     pushlua(L, 33.23);// отправить любое значение в стек.
  377.    pushlua(L, "no");// отправить любое значение в стек. 
  378.     pushlua(L, 202);// отправить любое значение в стек. 
  379.     showstack(L);
  380.     lua_pushvalue(L, -3);// отправляет копию элемент на вершину стека.
  381.     showstack(L);
  382.     lua_close(L);// закрыть состояние
  383.     cin.get();//ожидает ввода символа программа завершается.
  384.     return 0;
  385. }
  386.  
  387.  
  388. Выводится
  389.  
  390.   the number on the stack = 6
  391.  
  392.  
  393.          -1  202
  394.          -2  no
  395.          -3  33.23
  396.          -4  100
  397.          -5  1
  398.          -6  yes
  399.  
  400.   the number on the stack = 7
  401.  
  402.  
  403.          -1  33.23
  404.          -2  202
  405.          -3  no
  406.          -4  33.23
  407.          -5  100
  408.          -6  1
  409.          -7  yes
  410.  
  411.  
  412. lua c++ api. Получение значения переменных из lua,  обработка ошибок в lua.
  413.  
  414.  
  415. int checklua(lua_State *L, const char *file) {
  416.     int status = luaL_loadfile(L, file);// проверка есть ли ошибки.
  417.     try {if (status == 0) {// если нет ошибки в файле.
  418.             luaL_dofile(L, file);// запуск файла, в которым все происходит.
  419.     return 0;}
  420.     else {  string x =lua_tostring(L, -1);
  421.     throw x;    }
  422.     }
  423.     catch (string x) {
  424.         cout << x << endl; 
  425.         //luaL_error(L,"error");
  426.     }
  427. };
  428.  
  429. int main() {
  430.     lua_State *L = luaL_newstate();
  431.     luaL_openlibs(L);
  432.     checklua(L, "main.lua");
  433.     lua_getglobal(L, "x");
  434.     int x = lua_tonumber(L, -1);
  435.  
  436.     cout << x << endl;
  437.     lua_close(L);
  438.     return 0;
  439. };
  440.  
  441. Lua
  442.  
  443. X=23
  444.  
  445.  
  446. lua c++ api. Получение значение переменной любого типа из lua.
  447.  
  448. using namespace std;
  449.  
  450. int checklua(lua_State *L, const char *file) {
  451.     int status = luaL_loadfile(L, file);// проверка есть ли ошибки.
  452.     try {if (status == 0) {// если нет ошибки в файле.
  453.             luaL_dofile(L, file);// запуск файла, в которым все происходит.
  454.     return 0;}
  455.     else {  string x =lua_tostring(L, -1);
  456.     throw x;    }
  457.     }
  458.     catch (string x) {
  459.         cout << x << endl; 
  460.         //luaL_error(L,"error");
  461.     }
  462. };
  463.  
  464. int main(int argc, char *argv[]) {
  465.  
  466.     lua_State *L = luaL_newstate();
  467.     luaL_openlibs(L);//открыть все стандартные библиотеки lua.
  468.     checklua(lua, "main.lua");// Загружает и запускает заданный файл. Файл в котором все происходит.
  469.     lua_getglobal(L, "x");// получить значение x
  470.     if (lua_isnumber(L, 1)) {//  если 1 позиция в стеке число.
  471.         int number = lua_tonumber(L, 1);// получить число.
  472.         cout << "number x = " << number << endl;}
  473.  
  474.     else if (lua_isstring(L, 1)) {//  если 1 позиция в стеке строка.
  475.         string str = lua_tostring(L, 1);// получить строка.
  476.         cout << "string x = " << str << endl;}
  477.  
  478.     else if (lua_isboolean(L, 1)) {//  если 1 позиция в стеке булевая переменная.
  479.         bool bo = lua_toboolean(L, 1);// получить булевая переменная.
  480.         cout << "bool x = " << bo << endl;}
  481.     else {  cout << "not x " <<endl;}
  482.     lua_close(L);// закрыть состояние
  483.     cin.get();//ожидает ввода символа программа завершается.
  484. return 0;
  485. }
  486.  
  487. Lua
  488.  x=false
  489.  
  490.  
  491.  
  492. lua c++ api. Узнать тип переменной.
  493.  
  494. int main() {
  495.     lua_State *L = luaL_newstate();
  496.     luaL_openlibs(L);//открыть все стандартные библиотеки lua.
  497.     checklua(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  498.     lua_getglobal(L, "x");// получить значение глобальной переменной x.
  499.     int t = lua_type(L, 1); /* LUA_TNIL, LUA_TNUMBER, LUA_TBOOLEAN, LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD,
  500.     и LUA_TLIGHTUSERDATA.*/
  501.     if (LUA_TSTRING == t){
  502.         cout << "string x " << lua_tostring(L, 1) << endl;  }
  503.     if (LUA_TNUMBER == t) {
  504.         double x = lua_tonumber(L, 1);
  505.         int x2 = (int)x;
  506.         if (x==x2){ cout << "number int x "<<x2 << endl;}
  507.         else {cout << "number double x "<< x << endl;   }   }
  508.     if (LUA_TBOOLEAN == t) {    cout << "bool x = " << lua_toboolean(L, 1) << endl;
  509.     }
  510.     if (LUA_TNIL == t) { // если x нет.
  511.         cout << "not x " << endl;   }
  512.     lua_close(L);// закрыть состояние
  513.    
  514.     cin.get();//ожидает ввода символа программа завершается.
  515.  
  516.     return 0;
  517. }
  518.  
  519. Lua
  520. x=20.1
  521.  
  522. lua api. Определение типа переменной в lua через структуру.
  523.  
  524. using namespace std;
  525. struct st{ string str; int x2; double x; bool bo;
  526. double copyx = x; int copyx2 = x2; bool bo2 = bo;// это нужно,чтобы, избежать вывода мусор.
  527. st(){}
  528. st(string str) {
  529.     this->str = str;}
  530. st(int x2) {
  531.     this->x2 = x2;}
  532. st(double x) {
  533.     this->x = x;}
  534. st(bool bo) {
  535.     this->bo = bo;}
  536. void show() {
  537.     if (str != "") {
  538.         cout << str << endl;    }; 
  539.     if (x != copyx) {
  540.         cout << x << endl;  };
  541.     if (x2 != copyx2) {
  542.         cout << x2 << endl; };
  543.     if (bo != bo2) {
  544.     cout << bo << endl; };};
  545. };
  546.  
  547. st getvar(lua_State *lua, const char *var ) {
  548.     lua_getglobal(lua, var);// получить значение x
  549.     st s;
  550.     if (LUA_TSTRING == lua_type(lua, -1)) {// если  строка.
  551.         s.str = lua_tostring(lua, -1);
  552.         lua_pop(lua, 1);
  553.         return s;   }
  554.     if (LUA_TNUMBER == lua_type(lua, -1)) {// значение число.
  555.         double x = lua_tonumber(lua, -1);
  556.         int x2 = (int)x;
  557.         if (x == x2) { s.x2=x2;
  558.         lua_pop(lua, 1);
  559.         return s;       }
  560.         else {  s.x=x;
  561.         lua_pop(lua, 1);
  562.         return s;   }
  563.     }
  564.  
  565.     if (LUA_TBOOLEAN == lua_type(lua, -1)) {// значение булевая переменная.
  566.         s.bo = lua_toboolean(lua, 1);
  567.         lua_pop(lua, 1);
  568.         return s;
  569.     }
  570.  
  571.     if (LUA_TNIL == lua_type(lua, -1)) { { cout << "not x " << endl; }
  572.     }
  573. }
  574.  
  575.  
  576. int checklua(lua_State *L, const char *file) {
  577.     int status = luaL_loadfile(L, file);// проверка есть ли ошибки.
  578.     try {if (status == 0) {// если нет ошибки в файле.
  579.             luaL_dofile(L, file);// запуск файла, в которым все происходит.
  580.     return 0;}
  581.     else {  string x =lua_tostring(L, -1);
  582.     throw x;    }
  583.     }
  584.     catch (string x) {
  585.         cout << x << endl; 
  586.         //luaL_error(L,"error");
  587.     }
  588. };
  589.  
  590. int main(int argc, char *argv[]) {
  591.  
  592.     lua_State *L = luaL_newstate();
  593.     luaL_openlibs(L);//открыть все стандартные библиотеки lua.
  594.     checklua(L, "main.lua");// Загружает и запускает заданный файл. Файл в котором все происходит.
  595.     st t = getvar(L, "y");
  596.     t.show();
  597.     lua_close(L);// закрыть состояние
  598.     cin.get();//ожидает ввода символа программа завершается.
  599.     return 0;
  600. }
  601.  
  602. Lua
  603.  
  604.  
  605. x =10.3
  606. y="hi lua"
  607. z=true
  608.  
  609.  
  610.  
  611. Отправка в стек любого значение.
  612.  
  613. void pushtolua(lua_State *L, const char* v) {
  614.     lua_pushstring(L, v);
  615. }
  616.  
  617. void pushtolua(lua_State *L, int v) {
  618.     lua_pushinteger(L, v);
  619. }
  620.  
  621. void pushtolua(lua_State *L, double v) {
  622.     lua_pushnumber(L, v);
  623. }
  624.  
  625. void pushtolua(lua_State *L, bool v) {
  626.     lua_pushboolean(L, v);
  627. }
  628.  
  629. int main(int argc, char *argv[]) {
  630.     lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  631.     luaL_openlibs(L);
  632.     checkerror(L, LUA);//Функция проверка на ошибки.
  633.     pushlua(L, 10);
  634.     pushlua(L, 10.20);
  635.     pushlua(L, "10");
  636.     pushlua(L, true);
  637.     showstack(L);
  638.  
  639.     lua_close(L);
  640.  
  641.     return 0;
  642. }
  643.  
  644. lua c++ api. Присвовение значение переменной в lua.
  645.  
  646. int main(int argc, char *argv[]) {
  647.  
  648.     lua_State *L = luaL_newstate();
  649.     luaL_openlibs(L);//открыть все стандартные библиотеки lua.
  650.     lua_pushinteger(L, 30);// отправить целое число в стек.
  651.     lua_setglobal(L, "c");// уст значение переменной в lua.
  652.     checklua(L, "main.lua");// Загружает и запускает заданный файл. Файл в котором все происходит.
  653.     lua_pcall(L, 0, 0, 0);// вызов функции в lua файле. 1 параметр кол-во передаваемых, кол-во возвращаемых, обработчик ошибок.
  654.     lua_close(L);// закрыть состояние
  655.     cin.get();//ожидает ввода символа программа завершается.
  656.     return 0;
  657. }
  658.  
  659. Lua
  660.  
  661. print(c)
  662.  
  663. выводится 30.
  664.  
  665.  
  666. lua c++ api. функция вывода ключей и значений таблицы.
  667.  
  668. int pri(lua_State *L, const char t[] ) {// передаем указатель на состояние.
  669.     lua_getglobal(L, t);// получить значение глобальной переменной, таблица.
  670.     lua_assert(lua_istable(L, -1));// проверить является 1 элемент стека таблицей.
  671.     if (LUA_TTABLE == lua_type(L, -1)) {// это таблица.
  672.     lua_pushnil(L);//кладем на вершину стека NULL
  673.   while (lua_next(L, 1) != 0) {/* получает ключ из стека и отправляет пару ключ - значение из таблицы.
  674.       Ключ имеет - 2, а значение - 1.*/
  675.         if (LUA_TSTRING == lua_type(L, -2)) {// если ключ строка.
  676.         if (LUA_TNUMBER == lua_type(L, -1)) {// значение число.
  677.         cout << "key " << lua_tostring(L, -2) << " value " << lua_tonumber(L, -1) << endl;}
  678.         lua_pop(L, 1);// удалить n элементы из стека.
  679.         }
  680.     }
  681. }
  682. return 1;// вернуть 1.
  683. };
  684. int main() {
  685.     lua_State *L = luaL_newstate();
  686.     luaL_openlibs(L);
  687.     checklua(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  688.     pri(L,"t");// вывести ключи и значения таблицы.
  689.     lua_pcall(L, 0, 0, 0);// вызов функции в lua файле. 1 параметр кол-во передаваемых, кол-во возвращаемых, обработчик ошибок.
  690.     lua_close(L);// закрыть состояние
  691.     cin.get();//ожидает ввода символа программа завершается.
  692.     return 0;}
  693.  
  694. lua
  695.  
  696. t= {x=10, y=20, z=30}
  697. t1= {x=1, y=2, z=3}
  698.  
  699. выводится.
  700. key y value 20
  701. key x value 10
  702. key z value 30
  703.  
  704.  
  705. lua c++ api. Функции вывода ключей и значений таблицы, добавление ключа и значение в таблицу.
  706.  
  707. int checklua(lua_State *L, const char *file) {
  708.     int status = luaL_loadfile(L, file);// проверка есть ли ошибки.
  709.     try {
  710.         if (status == 0) {// если нет ошибки в файле.
  711.             //luaL_dofile(L, file);// запуск файла, в которым все происходит.  
  712.             return 0;
  713.         }
  714.         else {
  715.             string x = lua_tostring(L, -1);
  716.             throw x;
  717.             return 0;
  718.         }
  719.     }
  720.     catch (string x) {
  721.         cout << x << endl;
  722.         return 0;
  723.         //luaL_error(L,"error");
  724.     }
  725. };
  726.  
  727. int pri(lua_State *L, const char t[]) {// передаем указатель на состояние.
  728.     lua_getglobal(L, t);// получить значение глобальной переменной, таблица.
  729.     lua_assert(lua_istable(L, -1));// проверить является 1 элемент стека таблицей.
  730.     if (LUA_TTABLE == lua_type(L, -1)) {// это таблица.
  731.         lua_pushnil(L);//кладем на вершину стека NULL
  732.         while (lua_next(L, 1) != 0) {/* получает ключ из стека и отправляет пару ключ - значение из таблицы.
  733.             Ключ имеет - 2, а значение - 1.*/
  734.             if (LUA_TSTRING == lua_type(L, -2)) {// если ключ строка.
  735.                 if (LUA_TNUMBER == lua_type(L, -1)) {// значение число.
  736.                     cout << "key " << lua_tostring(L, -2) << " value " << lua_tonumber(L, -1) << endl;
  737.                 }
  738.                 lua_pop(L, 1);// удалить n элементы из стека.
  739.             }
  740.         }
  741.     }cout << "\n";
  742.     return 1;// вернуть 1.
  743. }
  744.  
  745. int addtab(lua_State *L, const char t[], const char key[], int value) {// передаем указатель на состояние.
  746.     lua_getglobal(L, t);// получить значение глобальной переменной, таблицей.
  747.     lua_pushnumber(L, value);// отправить значение в таблицу..
  748.     lua_setfield(L, -2, key);// уст ключ для него.
  749.     lua_getglobal(L, t);// получить значение глобальной переменной, таблицей.
  750.     lua_getfield(L, -1, key);// отправить ключ в таблицу.
  751.     return 0;// вернуть 1.
  752. }
  753. int main() {
  754.     lua_State *L = luaL_newstate();
  755.     //checklua(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  756.  
  757.     luaL_dofile(L, "main.lua");// запуск файла, в которым все происходит.  
  758.     pri(L, "t");// вывести ключи и значения таблицы.
  759.     addtab(L, "t", "a", 1000);// уст ключ и значение для таблицы
  760.     pri(L, "t");// вывести ключи и значения таблицы.
  761.     addtab(L, "t", "b", 99);// уст ключ и значение для таблицы
  762.     pri(L, "t");// вывести ключи и значения таблицы.
  763.     lua_pcall(L, 0, 0, 0);// вызов функции в lua файле. 1 параметр кол-во передаваемых, кол-во возвращаемых, обработчик ошибок.
  764.     lua_close(L);// закрыть состояние
  765.     cin.get();//ожидает ввода символа программа завершается.
  766.     return 0;
  767. }
  768.  
  769.  
  770. lua
  771.  
  772. t= {x=10, y=20, z=30}
  773. t1= {x=1, y=2, z=3}
  774.  
  775. выводится.
  776.  
  777. key z value 30
  778. key y value 20
  779. key x value 10
  780.  
  781. key z value 30
  782. key y value 20
  783. key x value 10
  784. key a value 1000
  785.  
  786. key x value 10
  787. key z value 30
  788. key a value 1000
  789. key b value 99
  790. key y value 20
  791.  
  792. вариант 2.
  793.  
  794.  
  795. void getstack(lua_State* L, int pos) {
  796.     if (LUA_TSTRING == lua_type(L, pos)) {
  797.         cout << lua_tostring(L, pos);
  798.     }
  799.     if (LUA_TNUMBER == lua_type(L, pos)) {
  800.         double x = lua_tonumber(L, pos);
  801.         int x2 = (int)x;
  802.         if (x == x2) { cout << x2; }
  803.         else { cout << x; }
  804.     }
  805.     if (LUA_TBOOLEAN == lua_type(L, pos)) {
  806.         cout << (lua_toboolean(L, pos) ? "true " : "false ");
  807.     }
  808.     if (LUA_TNIL == lua_type(L, pos)) {
  809.         cout << "not /n";
  810.     }
  811.     if (LUA_TTABLE == lua_type(L, pos)) {
  812.         cout << "LUA_TTABLE " << endl;
  813.     }
  814.     if (LUA_TFUNCTION == lua_type(L, pos)) {
  815.         cout << "LUA_TFUNCTION " << endl;
  816.     }
  817.     if (LUA_TLIGHTUSERDATA == lua_type(L, pos)) {
  818.         cout << "LIGHTUSERDATA " << endl;
  819.     }
  820.     if (LUA_TTABLE == lua_type(L, pos)) {
  821.         cout << "LUA_TTABLE " << endl;
  822.     }
  823.     if (LUA_TFUNCTION == lua_type(L, pos)) {
  824.         cout << "LUA_TFUNCTION " << endl;
  825.     }
  826.     if (LUA_TUSERDATA == lua_type(L, pos)) {
  827.         cout << "LUA_TUSERDATA " << endl;
  828.     }
  829.     if (LUA_TNIL == lua_type(L, pos)) { // если x нет.
  830.         cout << "nill " << endl;
  831.     }
  832. };
  833. int pri(lua_State* L, const char t[]) {// передаем указатель на состояние.
  834.     lua_getglobal(L, t);// получить значение глобальной переменной, таблица.
  835.     lua_assert(lua_istable(L, -1));// проверить является 1 элемент стека таблицей.
  836.     if (LUA_TTABLE == lua_type(L, -1)) {// это таблица.
  837.         lua_pushnil(L);//кладем на вершину стека NULL
  838.         while (lua_next(L, 1) != 0) {/* получает ключ из стека и отправляет пару ключ - значение из таблицы.
  839.             Ключ имеет - 2, а значение - 1.*/
  840.             cout << "key "; getstack(L, -2); cout << " value "; getstack(L, -1); cout << endl;
  841.             lua_pop(L, 1);// удалить n элементы из стека.
  842.         }
  843.        
  844.     }
  845. return 0;// вернуть 1.
  846. };
  847. int main() {
  848.     lua_State* L = luaL_newstate();
  849.     luaL_openlibs(L);
  850.     luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  851.     pri(L, "t");// вывести ключи и значения таблицы.
  852.     lua_close(L);// закрыть состояние
  853.     return 0;
  854. };
  855.  
  856.  
  857.  
  858.  
  859.  
  860. lua c++ api. Работа с таблицей.
  861.  
  862. int main() {
  863.     lua_State *L = luaL_newstate();
  864.     luaL_openlibs(L);//открыть все стандартные библиотеки lua.
  865.     checklua(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  866.     lua_getglobal(L, "t");// получить значение глобальной переменной, таблица.
  867.     lua_assert(lua_istable(L, 1));// проверить является 1 элемент стека таблицей.
  868.     lua_pushstring(L, "x");// отправить ключ x в стек.
  869.     lua_gettable(L, 1);// получить значение по ключу из стека.
  870.     lua_assert(lua_isnumber(L, 2));// проверить является значение 2 элемента стека число.  
  871.     int x = lua_tonumber(L, 2);
  872.     lua_getglobal(L, "t");// получить значение глобальной переменной таблица.
  873.     lua_pushstring(L, "y");
  874.     lua_gettable(L, 1);
  875.     lua_assert(lua_isstring(L, 4));
  876.     string y = lua_tostring(L, 4);
  877.     lua_getglobal(L, "t");// получить значение глобальной переменной, таблицей.
  878.     lua_getfield(L, 5, "z");// отправить ключ в таблицу.
  879.     lua_assert(lua_isboolean(L, 5));
  880.     bool z = lua_toboolean(L, 5);// получить булевое значение по ключу.
  881.     lua_getglobal(L, "t");// получить значение глобальной переменной, таблицей.
  882.     lua_pushstring(L, "dog");// отправить значение в таблицу.
  883.     lua_setfield(L, 5, "a");// уст ключ для него.
  884.     lua_getglobal(L, "t");// получить значение глобальной переменной, таблицей.
  885.     lua_getfield(L, 5, "a");// отправить ключ в таблицу.
  886.     lua_assert(lua_isstring(L, 5));
  887.     string a = lua_tostring(L, -1);
  888.     cout << "x = " << x << "\ny = " << y << "\nz = " << z << "\na = " << a << endl;
  889.     lua_close(L);// закрыть состояние
  890.  
  891.     cin.get();//ожидает ввода символа программа завершается.
  892.  
  893.     return 0;
  894. }
  895.  
  896. Lua
  897.  
  898. t= {x=300,y="ok you y",z=true}
  899.  
  900.  
  901. lua c++ api. Работа с таблицей 2.
  902.  
  903.  
  904. int main() {
  905.     lua_State *L = luaL_newstate();
  906.     luaL_openlibs(L);//открыть все стандартные библиотеки lua.
  907.     checklua(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  908.     lua_getglobal(L, "t");// получить значение глобальной переменной, таблица.
  909.     lua_assert(lua_istable(L, 1));// проверить является 1 элемент стека таблицей.
  910.     lua_pushstring(L, "x");// отправить ключ x в стек.
  911.     lua_gettable(L, 1);{// получить значение по ключу из стека.
  912.     int t = lua_type(L, 2); /*Возвращает тип значения в указанном допустимом индексе или LUA_TNONE для недопустимого индекса
  913.     (то есть индекса для «пустой» позиции стека). Типы возвращаемых lua_type кодируются с помощью следующих констант,
  914.     определенных в lua.h: LUA_TNIL, LUA_TNUMBER, LUA_TBOOLEAN, LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD,
  915.     и LUA_TLIGHTUSERDATA.*/
  916.     switch (t) {
  917.     case LUA_TSTRING:// если строка.
  918.         cout << "string x "<< lua_tostring(L, 2) << endl;
  919.         break;
  920.     case LUA_TBOOLEAN:// если булевая.
  921.         cout <<"bool x = "<< lua_toboolean(L, 2)<<  endl;
  922.         break;
  923.     case LUA_TNUMBER:  // если число.
  924.         cout << "number x = "<< lua_tonumber(L, 2) << endl;
  925.         break;
  926.     case LUA_TNIL:  // если x нет.
  927.         cout << "not x " << endl;
  928.         break;
  929.     default:  // иначе.
  930.         cout <<"other x = "<< lua_typename(L, t) << endl;
  931.         break;  } }
  932.     lua_close(L);// закрыть состояние
  933.    
  934.     cin.get();//ожидает ввода символа программа завершается.
  935.  
  936.     return 0;
  937. }
  938.  
  939. Lua
  940.  
  941. t= {x="20"}
  942.  
  943.  
  944. lua c++ api. Работа с таблицей. Извлечение из таблицы ключа и значение.
  945.  
  946.  
  947. int pri(lua_State *lua) {// передаем указатель на состояние.
  948.  
  949.     if (LUA_TTABLE == lua_type(lua, 1)) {// это таблица.
  950.         lua_pushnil(lua);//кладем на вершину стека NULL
  951.         while (lua_next(lua, 1) !=0) {/* получает ключ из стека и отправляет пару ключ - значение из таблицы
  952.           по заданному индексу(«следующая» пара после заданного ключа). Если в таблице больше нет элементов.
  953.           Ключ имеет - 2, а значение - 1.*/
  954.         if (LUA_TSTRING == lua_type(lua, -2)) {// если ключ строка.
  955.             if (LUA_TNUMBER == lua_type(lua, -1)) {// значение число.
  956.                 cout << "key " << lua_tostring(lua, -2) << " value " << lua_tonumber(lua, -1) << endl;}
  957.            
  958.             if (LUA_TSTRING == lua_type(lua, -1)) {// значение строка.
  959.             cout << "key " << lua_tostring(lua, -2) << " value " << lua_tostring(lua, -1) << endl; }
  960.             lua_pop(lua, 1);// удалить n элементы из стека.
  961.         }}
  962. }
  963.     return 1;// вернуть 1.
  964. }
  965. int main() {
  966.     lua_State *L = luaL_newstate();
  967.     luaL_openlibs(L);//открыть все стандартные библиотеки lua.
  968.     lua_register(L, "pri", pri);// регистрируем функцию- имя состояние, имя функ в lua, имя функ тут.
  969.     checklua(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  970.     lua_pcall(L, 0, 0, 0);// вызов функции в lua файле. 1 параметр кол-во передаваемых, кол-во возвращаемых, обработчик ошибок.
  971.     lua_close(L);// закрыть состояние
  972.     cin.get();//ожидает ввода символа программа завершается.
  973.     return 0;
  974. }
  975.  
  976. Lua
  977.  
  978. t={z="kj", x=23, y="dog",a=30,b=33}
  979. pri(t)
  980.  
  981.  
  982.  
  983. lua c++ api работа с таблицей. Функция принимающую таблицу для изменения значений ключей.
  984.  
  985. #include<iostream>
  986. #include<string>
  987. #include<vector>
  988.  
  989. #include"include/lua.hpp"
  990. using namespace std;
  991.  
  992. int pri(lua_State *L) {// передаем указатель на состояние.
  993.  
  994.     vector<string>v; // вектор для хранение ключей таблиции.
  995.     if (LUA_TNUMBER != lua_type(L, 2)) {//проверка, второй аргумент является числом.
  996.     cout << "bad second argument in function " << endl;
  997.     return 1;   };
  998.     int n = lua_tonumber(L, 2);
  999.     if (LUA_TTABLE == lua_type(L, 1)) {
  1000.         cout << "\nthis is table \n" << endl;
  1001.         lua_pushnil(L);//кладем на вершину стека NULL.
  1002.         while (lua_next(L, 1) != 0) {// получает ключ из стека и отправляет пару ключ - значение из таблицы.
  1003.  
  1004.             if (LUA_TSTRING == lua_type(L, -2)) {// значение число.
  1005.                 cout << "key " << lua_tostring(L, -2) << " value ";
  1006.                 v.push_back(lua_tostring(L, -2));
  1007.                 double x = lua_tonumber(L, -1);
  1008.                 int x2 = (int)x;
  1009.                 if (x == x2) {// int
  1010.                     cout << "number int  " << x2 << endl;   }
  1011.                 else { cout << "number double " << x << endl; }
  1012.                 lua_pop(L, 1);// удалить n элементы из стека.
  1013.             }
  1014.         }
  1015.     }
  1016.     else {  cout << "NOT table " << endl;
  1017.         if (LUA_TSTRING == lua_type(L, 1)) {
  1018.             cout << "this string " << lua_tostring(L, 1) << endl;   }
  1019.         if (LUA_TNUMBER == lua_type(L, 1)) {
  1020.             double x = lua_tonumber(L, 1);
  1021.             int x2 = (int)x;
  1022.             if (x == x2) { cout << "this number int " << x2 << endl; }
  1023.             else { cout << "this number double this " << x << endl; }
  1024.         }
  1025.         if (LUA_TBOOLEAN == lua_type(L, 1)) { cout << "this bool " << lua_toboolean(L, 1) << endl; }
  1026.         if (LUA_TNIL == lua_type(L, 1)) { // если нет.
  1027.             cout << "Nothing was passed.  " << endl;}
  1028.     }
  1029.     for (auto i : v){
  1030.         const char* x = i.c_str(); // из строки массив char.
  1031.         lua_getglobal(L, "t");// получить значение глобальной переменной, таблицей.
  1032.         lua_pushinteger(L, n);// отправить значение в таблицу.
  1033.         lua_setfield(L, 1, x);// уст ключ для него.
  1034.         lua_getglobal(L, "t");// получить значение глобальной переменной, таблицей.
  1035.         lua_getfield(L, 1, x);// отправить ключ в таблицу.
  1036. }
  1037.     return 1;// вернуть 1.
  1038. }
  1039. int main() {
  1040.     lua_State *L = luaL_newstate();
  1041.     luaL_openlibs(L);//открыть все стандартные библиотеки lua.
  1042.     lua_register(L, "pri", pri);// регистрируем функцию- имя состояние, имя функ в lua, имя функ тут.
  1043.     checklua(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  1044.     lua_pcall(L, 0, 0, 0);// вызов функции в lua файле. 1 параметр кол-во передаваемых, кол-во возвращаемых, обработчик ошибок.
  1045.     lua_close(L);// закрыть состояние
  1046.     cin.get();//ожидает ввода символа программа завершается.
  1047.     return 0;
  1048. }
  1049.  
  1050.  
  1051. Lua
  1052.  
  1053. t={x=1, y=2 ,a=3,b=4}
  1054. a=nil
  1055.  
  1056. for k,v in pairs(t) do
  1057.     print(k,v)
  1058. end
  1059. pri(a,100)
  1060.  
  1061.     print("\n After \n")
  1062. for k,v in pairs(t) do
  1063.     print(k,v)
  1064. end
  1065.  
  1066.  
  1067. lua c++ api. Отправить таблицу с ключами и значением в lua.
  1068.  
  1069.  
  1070. int checklua(lua_State *L, const char *file) {
  1071.     int status = luaL_loadfile(L, file);// проверка есть ли ошибки.
  1072.     try {
  1073.         if (status == 0) {// если нет ошибки в файле.
  1074.             luaL_dofile(L, file);// запуск файла, в которым все происходит.
  1075.             return 0;
  1076.         }
  1077.         else {
  1078.             string x = lua_tostring(L, -1);
  1079.             throw x;
  1080.         }
  1081.     }
  1082.     catch (string x) {
  1083.         cout << x << endl;
  1084.         //luaL_error(L,"error");
  1085.     }
  1086. };
  1087. int main() {
  1088.     lua_State *L = luaL_newstate();
  1089.     luaL_openlibs(L);
  1090.     lua_newtable(L); /*создать пустую таблицу */
  1091.  
  1092.     lua_pushstring(L, "key x"); /* отправить ключ в стек */
  1093.     lua_pushstring(L, "value x"); /* отправить значение ключа в стек. */
  1094.     lua_rawset(L, -3); /*Сохраняет пару в таблице */
  1095.     lua_pushstring(L, "key y"); /* */
  1096.     lua_pushstring(L, "value y"); /*  */
  1097.     lua_rawset(L, -3); /*Сохраняет пару в таблице */
  1098.     lua_setglobal(L, "foo");// уст имя таблицы в lua.
  1099.  
  1100.     checklua(L, "main.lua");
  1101.     lua_close(L);
  1102.     return 0;
  1103. };
  1104.  
  1105. Lua
  1106.  
  1107. print(foo)
  1108. for k,v in pairs(foo) do
  1109. print(k.." "..v)
  1110. end
  1111.  
  1112. выводит
  1113.  
  1114. table: 013154E0
  1115. key x value x
  1116. key y value y
  1117.  
  1118. еще так можно.
  1119.  
  1120. void addkeyintab(lua_State *L, const char* key, const char* value){
  1121.  
  1122.     lua_pushstring(L, key); /* отправить ключ в стек */
  1123.     lua_pushstring(L, value); /* отправить значение ключа в стек. */
  1124.     lua_rawset(L, -3); /*Сохраняет пару в таблице */
  1125. }
  1126. void addkeyintab(lua_State *L, const char* key, int value) {
  1127.  
  1128.     lua_pushstring(L, key); /* отправить ключ в стек */
  1129.     lua_pushinteger(L, value); /* отправить значение ключа в стек. */
  1130.     lua_rawset(L, -3); /*Сохраняет пару в таблице */
  1131. }
  1132. int main() {lua_State *L = luaL_newstate();
  1133.     luaL_openlibs(L);
  1134.     lua_newtable(L); /*создать пустую таблицу */
  1135.     addkeyintab(L, "key y", "10"); /*добавить ключ и значение в таблицу */
  1136.     addkeyintab(L, "key x", 10); /*добавить ключ и значение в таблицу */
  1137.     lua_setglobal(L, "foo");// уст имя таблицы в lua.
  1138.  
  1139.     checklua(L, "main.lua");
  1140.     showstack(L);// вывести стек.
  1141.     lua_close(L);
  1142.     return 0;
  1143. };
  1144.  
  1145. Lua
  1146.  
  1147. print(foo)
  1148. for k,v in pairs(foo) do
  1149. print(k.." "..v)
  1150. end
  1151.  
  1152. Выводится
  1153.  
  1154. table: 00855520
  1155. key x 10
  1156. key y 10
  1157.  
  1158.   the number on the stack = 0
  1159.  
  1160.  
  1161. lua c++ api. Запуск lua файла.
  1162.  
  1163. #include"include/lua.hpp"
  1164.  
  1165. using namespace std;
  1166.  
  1167. int checklua(lua_State *L, const char *file) {
  1168.     int status = luaL_loadfile(L, file);// проверка есть ли ошибки.
  1169.     try {
  1170.         if (status == 0) {// если нет ошибки в файле.
  1171.             luaL_dofile(L, file);// запуск файла, в которым все происходит.
  1172.             return 0;
  1173.         }
  1174.         else {
  1175.             string x = lua_tostring(L, -1);
  1176.             throw x;
  1177.         }
  1178.     }
  1179.     catch (string x) {
  1180.         cout << x << endl;
  1181.         //luaL_error(L,"error");
  1182.     }
  1183. };
  1184.  
  1185.  
  1186. int main(int argc, char *argv[]) {
  1187.  
  1188.     lua_State *L = luaL_newstate();
  1189.     luaL_openlibs(L);//открыть все стандартные библиотеки lua.
  1190.     checklua(L, "main.lua");// Загружает и запускает заданный файл. Файл в котором все происходит.
  1191.     lua_pcall(L, 0, 0, 0);// вызов функции в lua файле. 1 параметр кол-во передаваемых, кол-во возвращаемых, обработчик ошибок.
  1192.     lua_close(L);// закрыть состояние
  1193.     cin.get();//ожидает ввода символа программа завершается.
  1194. return 0;
  1195. }
  1196.  
  1197. Lua
  1198. a = 3
  1199. b = 6
  1200. c= a+b
  1201. print(c)
  1202.  
  1203. lua c++ api. Регистрация новой C функции в lua.
  1204.  
  1205. int q(lua_State *L) {// передаем указатель на состояние.
  1206.     int x = lua_tonumber(L, 1); // получаем 1 элемент из стека.
  1207.     x = x * x;
  1208.    //cout << x << endl;
  1209.     lua_pushnumber(L, x);// умножаем x и отправляет в стек.
  1210.     return 1;// вернуть 1.
  1211. }
  1212. int main() {
  1213.     lua_State *L = luaL_newstate();
  1214.     luaL_openlibs(L);//открыть все стандартные библиотеки lua.
  1215.     lua_register(L, "q", q);// регистрируем функцию- имя состояние, имя функ в lua, имя функ тут.
  1216.     checklua(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  1217.     lua_pcall(L, 0, 0, 0);// вызов функции в lua файле. 1 параметр кол-во передаваемых, кол-во возвращаемых, обработчик ошибок.
  1218.     lua_close(L);// закрыть состояние
  1219.     cin.get();//ожидает ввода символа программа завершается.
  1220.     return 0;}
  1221.  
  1222. lua
  1223. x = q(2)
  1224. print(x)
  1225.  
  1226.  
  1227.  
  1228. lua c++ api. Регистрация C функции в lua.
  1229.  
  1230.  
  1231. int foo(lua_State *L) {
  1232.  
  1233.     int x= lua_tonumber(L, -1);
  1234.     cout << x << endl;
  1235.     return 0; /* number of results */
  1236. }
  1237. int main(int argc, char *argv[]) {
  1238.  
  1239.     lua_State *L = luaL_newstate();
  1240.     luaL_openlibs(L);//открыть все стандартные библиотеки lua.
  1241.     lua_register(L, "foo", foo);// регистрируем функцию- имя состояние, имя функ в lua, имя функ тут.
  1242.  
  1243.     checklua(L, "main.lua");
  1244.     lua_pcall(L, 0, 0, 0);// вызов функции в lua файле. 1 параметр кол-во передаваемых, кол-во возвращаемых, обработчик ошибок.
  1245.     lua_close(L);// закрыть состояние
  1246.     cin.get();//ожидает ввода символа программа завершается.
  1247.     return 0;
  1248. }
  1249.  
  1250.  
  1251. Lua
  1252. foo(2)
  1253.  
  1254. lua c++ api. Запуск C функции в lua.
  1255.  
  1256.  
  1257. int checklua(lua_State *L, const char *file) {
  1258.     int status = luaL_loadfile(L, file);// проверка есть ли ошибки.
  1259.     try {if (status == 0) {// если нет ошибки в файле.
  1260.             luaL_dofile(L, file);// запуск файла, в которым все происходит.
  1261.     return 0;}
  1262.     else {  string x =lua_tostring(L, -1);
  1263.     throw x;    }
  1264.     }
  1265.     catch (string x) {
  1266.         cout << x << endl; 
  1267.         //luaL_error(L,"error");
  1268.     }
  1269. };
  1270. int foo(lua_State *L) {
  1271.     cout << "hi foo c++" << endl;
  1272.     return 0;
  1273. }
  1274. int main() {
  1275.     lua_State *L = luaL_newstate();
  1276.     luaL_openlibs(L);
  1277.     checklua(L, "main.lua");
  1278.     lua_pushcfunction(L, foo);// отправить c функцию в стек.
  1279.     lua_pcall(L, 0, 0, 0);// вызвать функцию foo.
  1280.     lua_close(L);
  1281.     return 0;
  1282. };
  1283.  
  1284.  
  1285. Lua
  1286.  
  1287. Foo()
  1288.  
  1289.  
  1290. lua c++ api. Запуск функции на lua, с возвращаемыми параметрами.
  1291.  
  1292. int main() {
  1293.     lua_State *L = luaL_newstate();
  1294.     luaL_openlibs(L);//открыть все стандартные библиотеки lua.
  1295.     checklua(L, "main.lua");
  1296.     lua_getglobal(L, "pri");// получаем из lua функцию pri.
  1297.     lua_pushnumber(L, 5);// отправляем в стек число.
  1298.     lua_pushnumber(L, 10);// отправляем в стек число.
  1299.  
  1300.     lua_pcall(L, 2, 1, 0);// вызов функции, передаем 2 параметра, возвращаем 1.
  1301.     cout << lua_tonumber(L, 1) << endl;// получаем из стека возвращаемое значение из функции.
  1302.     lua_close(L);// закрыть состояние
  1303.     cin.get();//ожидает ввода символа программа завершается.
  1304.  
  1305.     return 0;
  1306. }
  1307.  
  1308. Lua
  1309.  
  1310. function pri(x,y)
  1311. sum = x+y
  1312. return sum
  1313. end
  1314.  
  1315.  
  1316. lua c++ api. Вызов определенной функции из lua.
  1317.  
  1318. int main() {
  1319.     lua_State *L = luaL_newstate();
  1320.     int x = 5, y = 6;
  1321.     luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  1322.     lua_getglobal(L, "f"); /* вызываемая функция */
  1323.     lua_pushnumber(L, x); /* поместить на стек 1-й аргумент */
  1324.     lua_pushnumber(L, y); /* поместить на стек 2-й аргумент */
  1325.     if (lua_pcall(L, 2, 1, 0) != 0) {/* вызвать функцию (2 аргумента, 1 результат) */
  1326.         luaL_error(L, "error running function 'f': %s", lua_tostring(L, -1));}/* получить результат */
  1327.     cout << lua_tonumber(L, -1) << "\n";
  1328.     lua_pop(L, 1);
  1329.     lua_close(L);
  1330.     cin.get();//ожидает ввода символа программа завершается.
  1331.     return 0;
  1332. }
  1333.  
  1334. Lua
  1335.  
  1336. function f(x, y)
  1337.     return (x*y)
  1338. end
  1339.  
  1340.  
  1341. lua c++ api. Функция, принимающая переменное количество аргументов.
  1342.  
  1343. //Эта функция может принимать переменное число параметров через L
  1344. int pri(lua_State * L) {// передаем указатель на состояние.
  1345.     int n = lua_gettop(L);/* получаем количество параметров переданных в функцию.
  1346.     Возвращает индекс верхнего элемента в стеке. Поскольку индексы начинаются с 1, этот результат
  1347.     равен количеству элементов в стеке (и поэтому 0 означает пустой стек).*/
  1348.     cout <<"count elements "<< n << endl;
  1349.     for (int i = 1; i <= n; ++i) {
  1350.     int t = lua_type(L, i); /* LUA_TNIL, LUA_TNUMBER, LUA_TBOOLEAN, LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD,
  1351.        и LUA_TLIGHTUSERDATA.*/
  1352.     if (LUA_TSTRING == t) {
  1353.             cout <<i << " string = " << lua_tostring(L, i) << endl;}
  1354.     if (LUA_TNUMBER == t) {
  1355.             double x = lua_tonumber(L, i);
  1356.             int x2 = (int)x;
  1357.             if (x == x2) { cout << i<<" number int = " << x2 << endl; }
  1358.             else { cout << i<<" number double = " << x << endl; }}
  1359.     if (LUA_TBOOLEAN == t) {cout <<i<< " bool = " << lua_toboolean(L, i) << endl;   }
  1360.  
  1361.     }
  1362.     return 1;// вернуть 1.
  1363. }
  1364. int main() {
  1365.     lua_State *L = luaL_newstate();
  1366.     luaL_openlibs(L);//открыть все стандартные библиотеки lua.
  1367.     lua_register(L, "pri", pri);// регистрируем функцию- имя состояние, имя функ в lua, имя функ тут.
  1368.     checklua(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  1369.     lua_pcall(L, 0, 0, 0);// вызов функции в lua файле. 1 параметр кол-во передаваемых, кол-во возвращаемых, обработчик ошибок.
  1370.     lua_close(L);// закрыть состояние
  1371.     cin.get();//ожидает ввода символа программа завершается.
  1372.     return 0;
  1373. }
  1374.  
  1375. Lua
  1376.  
  1377. pri(2,"youtube", false, 6,"end",5.236, true)
  1378.  
  1379.  
  1380.  
  1381. lua c++ api. мета таблицы.
  1382.  
  1383.  
  1384. void addkeyintab(lua_State *L, const char* key, int value) {
  1385.     lua_pushstring(L, key); /* отправить ключ в стек */
  1386.     lua_pushinteger(L, value); /* отправить значение ключа в стек. */
  1387.     lua_rawset(L, -3); /*Сохраняет пару в таблице */
  1388. }
  1389. struct vec{ static int vector(lua_State* L) {// методы классы должны быть статик.
  1390.         lua_newtable(L); //создать новую таблицу.
  1391.         addkeyintab(L, "x", 0);// установить значение ключа таблицы.
  1392.         luaL_getmetatable(L, "mt");// получить мета таблицу.
  1393.         lua_setmetatable(L, -2);
  1394.         return 1;   }
  1395.  
  1396.     static int __add(lua_State* L)  {
  1397.         lua_pushstring(L, "x");
  1398.         lua_gettable(L, -3);
  1399.         int firts = lua_tonumber(L, -1);
  1400.  
  1401.         lua_pushstring(L, "x");
  1402.         lua_gettable(L, -3);
  1403.         int second = lua_tonumber(L, -1);
  1404.  
  1405.         vec::vector(L);// вывоз метода обнулиние таблицы суммы ключей.
  1406.         lua_pushstring(L, "z");// ключ таблицы со значение ее суммы.
  1407.         lua_pushnumber(L, firts + second);// сумму отправить в стек как ключ таблицы.
  1408.         lua_rawset(L, -3);// уст таблицу без мета.методов.
  1409.         return 1;
  1410.     }
  1411. };
  1412.  
  1413. const char * LUA_FILE = R"(
  1414.         v1 = vector()   -- v1 is a table
  1415.         v2 = vector() -- v2 is a table
  1416.         v1.x = 5  v2.x = 18
  1417.         v3 = v1 + v2
  1418.         result = v3.z)";
  1419. int main(){lua_State* L = luaL_newstate();
  1420.  
  1421. lua_pushcfunction(L, vec::vector);
  1422. lua_setglobal(L, "vector");
  1423.  
  1424. luaL_newmetatable(L, "mt");
  1425. lua_pushstring(L, "__add");
  1426. lua_pushcfunction(L, vec::__add);
  1427. lua_settable(L, -3);
  1428.  
  1429. luaL_dostring(L, LUA_FILE);
  1430.  
  1431. lua_getglobal(L, "result");
  1432. cout << "result = " <<lua_tonumber(L, -1)<< endl;
  1433. lua_close(L);
  1434. }
  1435.  
  1436.  
  1437. lua c++ api. мета таблицы 2.
  1438.  
  1439.  
  1440. struct Sprite { int x;// структура.
  1441.  
  1442.     Sprite() : x(0) {}//конструктор по умолчанию.
  1443.  
  1444.     ~Sprite() { cout << "destror "<< this << endl; }
  1445.  
  1446.     void set(int x) {this->x = x;}// уст значение x.
  1447.  
  1448.     void show() {
  1449.         printf("sprite(%p): x = %d\n", this, x);
  1450.     }
  1451. };
  1452.  
  1453. int create(lua_State* L) {// создать структуру.
  1454.     void* st = lua_newuserdata(L, sizeof(Sprite));// выделить память под польз.данные отправить в стек.
  1455.     new (st) Sprite();//выделить память под новый объект класса.
  1456.     luaL_getmetatable(L, "mt");// получить мета таблицу.
  1457.     lua_setmetatable(L, -2);// уст мета таблицу.
  1458.     return 1;
  1459. };
  1460.  
  1461. int set(lua_State* L) {
  1462.     Sprite* sprite = (Sprite*)lua_touserdata(L, -2);// получить польз.данные.
  1463.     int x = lua_tonumber(L, -1);
  1464.     sprite->set(x);// вызов метода класса, уст значение x
  1465.     return 0;
  1466. };
  1467.  
  1468. int show(lua_State* L) {
  1469.     Sprite* sprite = (Sprite*)lua_touserdata(L, -1);
  1470.     sprite->show();
  1471.     return 0;
  1472. };
  1473. int DestroySprite(lua_State* L) {
  1474.     Sprite* sprite = (Sprite*)lua_touserdata(L, -1);
  1475.     sprite->~Sprite();
  1476.     return 0;
  1477. };
  1478.  
  1479. const char* LUA_FILE = R"(
  1480.         sprite = create()
  1481.         set( sprite, 5 )
  1482.         show( sprite )
  1483.         set( sprite, 12 )
  1484.         show( sprite )
  1485.         sprite2 = create()
  1486.         set( sprite2, 33 )
  1487.         show( sprite2 )
  1488.         )";
  1489.  
  1490. int main() {lua_State* L = luaL_newstate();
  1491.  
  1492.     luaL_newmetatable(L, "mt");// создать метп таблицу.
  1493.     lua_pushstring(L, "__gc");// отправить в стек сборщик мусора.
  1494.     lua_pushcfunction(L, DestroySprite);// установить значение ключа, как вызов деструктор.
  1495.     lua_settable(L, -3);// установить таблицу.
  1496.  
  1497.     lua_pushcfunction(L, create);// отправить ключ как функцию в стек.
  1498.     lua_setglobal(L, "create");
  1499.     lua_pushcfunction(L, set);// отправить ключ как функцию в стек.
  1500.     lua_setglobal(L, "set");
  1501.     lua_pushcfunction(L, show);// отправить ключ как функцию в стек.
  1502.     lua_setglobal(L, "show");
  1503.  
  1504.     luaL_dostring(L, LUA_FILE);
  1505.  
  1506.     lua_close(L);
  1507. }
  1508.  
  1509.  
  1510. lua c++ api. мета таблицы 3.
  1511.  
  1512.  
  1513. static int numberOfSpritesExisting = 0;
  1514.  
  1515. struct Sprite
  1516. {
  1517.     int x;
  1518.     int y;
  1519.  
  1520.     Sprite() : x(0), y(0)
  1521.     {
  1522.         numberOfSpritesExisting++;
  1523.     }
  1524.  
  1525.     ~Sprite()
  1526.     {
  1527.         numberOfSpritesExisting--;
  1528.     }
  1529.  
  1530.     void Move(int velX, int velY)
  1531.     {
  1532.         x += velX;
  1533.         y += velY;
  1534.     }
  1535.  
  1536.     void Draw()
  1537.     {
  1538.         printf("sprite(%p): x = %d, y = %d\n", this, x, y);
  1539.     }
  1540. };
  1541.  
  1542. int CreateSprite(lua_State* L){
  1543.     void* pointerToASprite = lua_newuserdata(L, sizeof(Sprite));
  1544.     new (pointerToASprite) Sprite();
  1545.     luaL_getmetatable(L, "SpriteMetaTable");
  1546.     lua_assert(lua_istable(L, -1));
  1547.     lua_setmetatable(L, -2);
  1548.     return 1;
  1549. };
  1550.  
  1551. int DestroySprite(lua_State* L){
  1552.     Sprite* sprite = (Sprite*)lua_touserdata(L, -1);
  1553.     sprite->~Sprite();
  1554.     return 0;
  1555. };
  1556.  
  1557. int MoveSprite(lua_State* L){
  1558.     Sprite* sprite = (Sprite*)lua_touserdata(L, -3);
  1559.     lua_Number velX = lua_tonumber(L, -2);
  1560.     lua_Number velY = lua_tonumber(L, -1);
  1561.     sprite->Move((int)velX, (int)velY);
  1562.     return 0;
  1563. };
  1564.  
  1565. int DrawSprite(lua_State* L){
  1566.     Sprite* sprite = (Sprite*)lua_touserdata(L, -1);
  1567.     sprite->Draw();
  1568.     return 0;
  1569. };
  1570.  
  1571. const char* LUA_FILE = R"(
  1572.     sprite = Sprite.new()
  1573.     sprite:Move( 5, 7 )     -- Sprite.Move( sprite, 5, 7 )
  1574.     sprite:Draw()
  1575.     sprite:Move( 1, 2 )
  1576.     sprite:Draw()
  1577.     sprite2 = Sprite.new()
  1578.     sprite2:Move( 3, 3 )
  1579.     sprite2:Draw()
  1580.         -- sprite   -> sprite is a userdatum
  1581.         --      has a metatable called SpriteMetaTable
  1582.         --          dont have Move(), use the __index metamethod
  1583.         --          __index metamethod is a table which is Sprite
  1584.         --          Sprite has a field called Move(), invoke that
  1585.         --          Move() is a c function
  1586.         --          invoke, pass the userdatum as the first parameter.
  1587.         )";
  1588.  
  1589.  
  1590. int main() {
  1591.     lua_State* L = luaL_newstate();
  1592.  
  1593.     lua_newtable(L);
  1594.     int spriteTableIdx = lua_gettop(L);
  1595.     lua_pushvalue(L, spriteTableIdx);
  1596.     lua_setglobal(L, "Sprite");
  1597.  
  1598.     lua_pushcfunction(L, CreateSprite);
  1599.     lua_setfield(L, -2, "new");
  1600.     lua_pushcfunction(L, MoveSprite);
  1601.     lua_setfield(L, -2, "Move");
  1602.     lua_pushcfunction(L, DrawSprite);
  1603.     lua_setfield(L, -2, "Draw");
  1604.  
  1605.     luaL_newmetatable(L, "SpriteMetaTable");
  1606.     lua_pushstring(L, "__gc");
  1607.     lua_pushcfunction(L, DestroySprite);
  1608.     lua_settable(L, -3);
  1609.  
  1610.     lua_pushstring(L, "__index");
  1611.     lua_pushvalue(L, spriteTableIdx);
  1612.     lua_settable(L, -3);
  1613.  
  1614.     luaL_dostring(L, LUA_FILE);
  1615.     lua_close(L);
  1616.  
  1617.     lua_assert(numberOfSpritesExisting == 0);
  1618.     return 0;
  1619. }
  1620.  
  1621.  
  1622. lua c++ api. мета таблицы 4.
  1623.  
  1624.  
  1625. static int numberOfSpritesExisting = 0;
  1626.  
  1627. struct Sprite {
  1628.     int x;
  1629.     int y;
  1630.  
  1631.     Sprite() : x(0), y(0)
  1632.     {
  1633.         numberOfSpritesExisting++;
  1634.     }
  1635.  
  1636.     ~Sprite()
  1637.     {
  1638.         numberOfSpritesExisting--;
  1639.     }
  1640.  
  1641.     void Move(int velX, int velY)
  1642.     {
  1643.         x += velX;
  1644.         y += velY;
  1645.     }
  1646.  
  1647.     void Draw()
  1648.     {
  1649.         printf("sprite(%p): x = %d, y = %d\n", this, x, y);
  1650.     }
  1651. };
  1652.  
  1653. auto CreateSprite = [](lua_State* L) -> int
  1654. {
  1655.     void* pointerToASprite = lua_newuserdata(L, sizeof(Sprite));
  1656.     new (pointerToASprite) Sprite();
  1657.     luaL_getmetatable(L, "mt");
  1658.     lua_assert(lua_istable(L, -1));
  1659.     lua_setmetatable(L, -2);
  1660.     return 1;
  1661. };
  1662.  
  1663. auto DestroySprite = [](lua_State* L) -> int
  1664. {
  1665.     Sprite* sprite = (Sprite*)lua_touserdata(L, -1);
  1666.     sprite->~Sprite();
  1667.     return 0;
  1668. };
  1669.  
  1670. auto MoveSprite = [](lua_State* L) -> int
  1671. {
  1672.     Sprite* sprite = (Sprite*)lua_touserdata(L, -3);
  1673.     lua_Number velX = lua_tonumber(L, -2);
  1674.     lua_Number velY = lua_tonumber(L, -1);
  1675.     sprite->Move((int)velX, (int)velY);
  1676.     return 0;
  1677. };
  1678.  
  1679. auto DrawSprite = [](lua_State* L) -> int
  1680. {
  1681.     Sprite* sprite = (Sprite*)lua_touserdata(L, -1);
  1682.     sprite->Draw();
  1683.     return 0;
  1684. };
  1685.  
  1686. auto SpriteIndex = [](lua_State* L) -> int
  1687. {
  1688.     lua_assert(lua_isuserdata(L, -2));
  1689.     lua_assert(lua_isstring(L, -1));
  1690.  
  1691.     Sprite* sprite = (Sprite*)lua_touserdata(L, -2);
  1692.     const char* index = lua_tostring(L, -1);
  1693.     if (strcmp(index, "x") == 0)
  1694.     {
  1695.         lua_pushnumber(L, sprite->x);
  1696.         return 1;
  1697.     }
  1698.     else if (strcmp(index, "y") == 0)
  1699.     {
  1700.         lua_pushnumber(L, sprite->y);
  1701.         return 1;
  1702.     }
  1703.     else
  1704.     {
  1705.         lua_getglobal(L, "Sprite");
  1706.         lua_pushstring(L, index);
  1707.         lua_rawget(L, -2);
  1708.         return 1;
  1709.     }
  1710. };
  1711.  
  1712. const char* LUA_FILE = R"(
  1713.     sprite = Sprite.new()
  1714.     sprite:Move( 6, 7 )     -- Sprite.Move( sprite, 6, 7 )
  1715.     sprite:Draw()
  1716.     temp_x = sprite.x
  1717.     )";
  1718. int main(){
  1719.     lua_State* L = luaL_newstate();
  1720.  
  1721.     lua_newtable(L);
  1722.     int spriteTableIdx = lua_gettop(L);
  1723.     lua_pushvalue(L, spriteTableIdx);
  1724.     lua_setglobal(L, "Sprite");
  1725.  
  1726.     lua_pushcfunction(L, CreateSprite);
  1727.     lua_setfield(L, -2, "new");
  1728.     lua_pushcfunction(L, MoveSprite);
  1729.     lua_setfield(L, -2, "Move");
  1730.     lua_pushcfunction(L, DrawSprite);
  1731.     lua_setfield(L, -2, "Draw");
  1732.  
  1733.     luaL_newmetatable(L, "mt");
  1734.     lua_pushstring(L, "__gc");
  1735.     lua_pushcfunction(L, DestroySprite);
  1736.     lua_settable(L, -3);
  1737.  
  1738.     lua_pushstring(L, "__index");
  1739.     lua_pushcfunction(L, SpriteIndex);
  1740.     lua_settable(L, -3);
  1741.  
  1742.     int doResult = luaL_dostring(L, LUA_FILE);
  1743.     if (doResult != LUA_OK)
  1744.     {
  1745.         printf("Error: %s\n", lua_tostring(L, -1));
  1746.     }
  1747.  
  1748.     lua_getglobal(L, "temp_x");
  1749.     lua_Number temp_x = lua_tonumber(L, -1);
  1750.     lua_assert(temp_x == 6);
  1751.  
  1752.     lua_close(L);
  1753.  
  1754.     lua_assert(numberOfSpritesExisting == 0);
  1755. }
  1756.  
  1757.  
  1758. lua c++ api. Функции для работы с указателем.
  1759.  
  1760. struct st { int number =10;
  1761.     int *x = &number;
  1762.     st() { this->x = *&x; }
  1763.     st(int number) { this->number = *&number; }
  1764. };
  1765. int create(lua_State* L) {//Функция создания объекта структуры.
  1766.    int x = lua_tonumber(L, -1);
  1767.    void *s = lua_newuserdata(L, sizeof(st));/*Эта функция выделяет новый блок памяти с заданным размером,*/
  1768.    new(s) st(x);  luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при
  1769.      заданном приемлемом индексе.*/
  1770.    lua_setmetatable(L, 1);//получает таблицу из стека и уст ее в качестве  новой метатаблицы для значения с заданным допустимым индексом.
  1771.     return 1;
  1772. };
  1773.  
  1774. int show(lua_State* L) {
  1775.     st *s = (st*)lua_touserdata(L, -1);;// получаем польз. данные.
  1776.     cout << "andress " << &(s->x) <<" value " << *(s->x)<<endl;// адрес памяти
  1777.     s->~st();//вызов метода деструктор.
  1778.     return 0;
  1779. };
  1780.  
  1781. int checklua(lua_State *L, const char *file) {
  1782.     int status = luaL_loadfile(L, file);// проверка есть ли ошибки.
  1783.     try {if (status == 0) {// если нет ошибки в файле.
  1784.             luaL_dofile(L, file);// запуск файла, в которым все происходит.
  1785.     return 0;}
  1786.     else {  string x =lua_tostring(L, -1);
  1787.     throw x;    }
  1788.     }
  1789.     catch (string x) {
  1790.         cout << x << endl; 
  1791.         //luaL_error(L,"error");
  1792.     }
  1793. };
  1794.  
  1795. int main() {lua_State* L = luaL_newstate();
  1796.     lua_newtable(L);
  1797.     lua_pushcfunction(L, create);//уст указатель на функцию C++ и создает внутри Lua
  1798.     lua_setglobal(L, "get"); //получает значение из стека и уст значение global name.
  1799.     lua_pushcfunction(L, show);
  1800.     lua_setglobal(L, "show"); //получает значение из стека и уст значение global name.
  1801.     luaL_newmetatable(L, "mt");/*int luaL_newmetatable (lua_State * L, const    char * t); */
  1802.     lua_settable(L, 2);
  1803.     checklua(L, "main.lua");// Загружает и запускает заданный файл. файл в котором все происходит.
  1804.     lua_close(L);// закрыть состояние
  1805.     cin.get();//ожидает ввода символа программа завершается.
  1806.     return 0;
  1807. }
  1808.  
  1809.  
  1810.  
  1811. lua c++ api. Работа с указателем.
  1812.  
  1813. int get_point_number(lua_State *L) {// передаем указатель на состояние
  1814.     int s = 10;//значение переменной по умолчанию.
  1815.     int *a = &s;// указатель на переменную.
  1816.     (int*)lua_newuserdata(L, sizeof(a));// выделяет памяти с заданным размером,
  1817.     //помещает в стек пользовательские данные и возвращает этот адрес.
  1818.     if (LUA_TNUMBER == lua_type(L, 1)) {
  1819.         double x = lua_tonumber(L, 1);
  1820.         int x2 = (int)x;
  1821.         if (x == x2) { lua_pushinteger(L, x);// отправить в стек целое число.
  1822.             cout << "this number int " << x2 << endl;       }
  1823.         else { cout << "this number double this " << x << endl;
  1824.         lua_pushnumber(L, x);   }
  1825.     }
  1826.     else {  cout <<"the default number  "<< s  << endl;
  1827.         lua_pushinteger(L, s);}
  1828.     return 2;// вернуть 2.
  1829. }
  1830. int getpoint(lua_State *L) {// передаем указатель на состояние 
  1831.     if (LUA_TUSERDATA == lua_type(L, 1)) {// если это польз. данные.
  1832.         void *x = lua_touserdata(L, 1);/*Если значение в данном приемлемом индексе является полными данными пользователя,
  1833.  возвращает адрес его блока. Если значение является легким userdata, возвращает его указатель. В противном случае возвращается NULL.*/
  1834.         cout << "address point " << x << endl;  }
  1835.     return 1;// вернуть 1.
  1836. }
  1837. int main() {
  1838.     lua_State *L = luaL_newstate();
  1839.     luaL_openlibs(L);//открыть все стандартные библиотеки lua.
  1840.     lua_pushcfunction(L, get_point_number);//уст указатель на функцию C++ и создает внутри Lua
  1841.     lua_setglobal(L, "getpointnum"); //получает значение из стека и уст значение global name.
  1842.     lua_pushcfunction(L, getpoint);//уст указатель на функцию C++ и создает внутри Lua
  1843.     lua_setglobal(L, "getpoint"); //получает значение из стека и уст значение global name.
  1844.     luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  1845.     lua_pcall(L, 0, 0, 0);// вызов функции в lua файле.
  1846.     lua_close(L);// закрыть состояние
  1847.     cin.get();//ожидает ввода символа программа завершается.
  1848.     return 0;
  1849. }
  1850.  
  1851. Lua
  1852.  
  1853. adress, num =getpointnum(5.3)
  1854. --print(adress, num ) --адрес памяти выводится
  1855. getpoint(adress)
  1856.  
  1857. легкие польз.данные.
  1858.  
  1859. int main() {
  1860.     lua_State* L = luaL_newstate(); luaL_openlibs(L);
  1861.     checkerror(L, LUA);
  1862.     lua_State* L1 = lua_newthread(L);
  1863.     int ret = 3;
  1864.     void *key = &ret;
  1865.     cout << key << endl;
  1866.     lua_pushlightuserdata(L, key);  /*отправить адресс, который является ключом в стек. */
  1867.        const void *v = lua_topointer(L,-1);
  1868.        cout << v << endl;
  1869.     return 0;
  1870. };
  1871.  
  1872. Вызывает функцию в защищенном режиме.
  1873. Оба nargs и nresults имеют то же значение, что и в lua_call. Если при звонке ошибок нет, lua_pcall ведет себя точно так же lua_call. Однако, если есть какая-либо ошибка, lua_pcall она перехватывает ее, помещает в стек одно значение (сообщение об ошибке) и возвращает код ошибки. Мол lua_call, lua_pcall всегда удаляет функцию и ее аргументы из стека.
  1874. Если errfunc равно 0, то сообщение об ошибке, возвращаемое в стеке, является точно исходным сообщением об ошибке. В противном случае errfunc это индекс стека функции обработчика ошибок . (В текущей реализации этот индекс не может быть псевдоиндексом.) В случае ошибок времени выполнения эта функция будет вызываться с сообщением об ошибке, а ее возвращаемое значение будет сообщением, возвращаемым в стеке lua_pcall.
  1875. Как правило, функция обработчика ошибок используется для добавления дополнительной отладочной информации к сообщению об ошибке, такой как трассировка стека. Такая информация не может быть собрана после возврата lua_pcall, так как к тому времени стек уже размотан.
  1876. lua_pcall Функция возвращает 0 в случае успеха или один из следующих кодов ошибок (определены в lua.h):
  1877. LUA_ERRRUN: ошибка во время выполнения.
  1878. LUA_ERRMEM: ошибка выделения памяти. Для таких ошибок Lua не вызывает функцию обработчика ошибок.
  1879. LUA_ERRERR: ошибка при запуске функции обработчика ошибок.
  1880.  
  1881.  
  1882.  
  1883.  
  1884.  
  1885. api lua c++. Реализация ООП через функции. Структура конструктор по умолчанию.
  1886.  
  1887. int checklua(lua_State *L, const char *file) {
  1888.     int status = luaL_loadfile(L, file);// проверка есть ли ошибки.
  1889.     try {
  1890.         if (status == 0) {// если нет ошибки в файле.
  1891.             luaL_dofile(L, file);// запуск файла, в которым все происходит.
  1892.             return 0;
  1893.         }
  1894.         else {
  1895.             string x = lua_tostring(L, -1);
  1896.             throw x;
  1897.         }
  1898.     }
  1899.     catch (string x) {
  1900.         cout << x << endl;
  1901.         //luaL_error(L,"error");
  1902.     }
  1903. };
  1904. struct a {  int x = 30;
  1905. a() { this->x = x; }//конструктор по умолчанию
  1906.     void show() { cout << "x = " << x << endl; }    
  1907. ~a() { cout << "destory object " << this << endl << endl; }
  1908. };
  1909. int destroy(lua_State* L) {// Функция вызывает деструктор для объекта.
  1910.     a* st = (a*)lua_touserdata(L, -1);/* Если значение в данном приемлемом индексе является полными данными пользователя.*/
  1911.     st->~a();//вызов метода деструктор.
  1912.     return 0;};
  1913.  
  1914. int create(lua_State* L) {//Функция создания объекта структуры.
  1915.     void* st = lua_newuserdata(L, sizeof(a));/*Эта функция выделяет новый блок памяти с заданным размером,*/
  1916.     new (st) a();// Выделить память под польз. данные.
  1917.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  1918.     lua_setmetatable(L, 1);//получает таблицу из стека и уст ее в качестве новой метатаблицы для значения с заданным допустимым индексом.
  1919.     return 1;};
  1920.  
  1921. int show(lua_State* L) {
  1922.     a* st = (a*)lua_touserdata(L, -1);// получаем польз. данные.
  1923.     st->show();// вызов метода.
  1924.     return 0;};
  1925.  
  1926. int main() {
  1927.     lua_State* L = luaL_newstate();
  1928.     lua_newtable(L);
  1929.     lua_pushcfunction(L, create);//уст указатель на функцию C++ и создает внутри Lua
  1930.     lua_setglobal(L, "get"); //получает значение из стека и уст значение global name.
  1931.     lua_pushcfunction(L, show);
  1932.     lua_setglobal(L, "show"); //получает значение из стека и уст значение global name.
  1933.     luaL_newmetatable(L, "mt");/*int luaL_newmetatable (lua_State * L, const char * t); */
  1934.     lua_pushstring(L, "__gc");
  1935.     lua_pushcfunction(L, destroy);
  1936.     lua_settable(L, 2);
  1937.     checklua(L, "main.lua");
  1938.     showstack(L);// вывести стек.
  1939.     lua_close(L);// закрыть состояние
  1940.     cin.get();//ожидает ввода символа программа завершается.
  1941. return 0;}
  1942.  
  1943. lua
  1944. a= get()
  1945. show(a)
  1946.  
  1947. передача польз. Данных.
  1948.  
  1949. struct a {  int x = 3010;
  1950. a() { this->x = x; }//конструктор по умолчанию
  1951.     void show() { cout << "x = " << x << endl; }
  1952. };
  1953.  
  1954. int create(lua_State* L) {//    Функция создания объекта структуры.
  1955.     void* st = lua_newuserdata(L, sizeof(a));/*Эта функция выделяет новый блок памяти с заданным размером,*/
  1956.     new (st) a();// Выделить память под польз. данные.
  1957.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  1958.     lua_setmetatable(L, 1);//получает таблицу из стека и уст ее в качестве новой метатаблицы для значения с заданным допустимым индексом.
  1959.     return 1;};
  1960.  
  1961. int destroy(lua_State* L) {// Функция вызывает деструктор для объекта.
  1962.     a* st = (a*)lua_touserdata(L, 1);/* Если значение в данном приемлемом индексе является полными данными пользователя.*/
  1963.     st->~a();//вызов метода деструктор.
  1964.     return 0;};
  1965.  
  1966. int show(lua_State* L) {
  1967.     a* st = (a*)lua_touserdata(L, -1);
  1968.     st->show();
  1969.     return 0;};
  1970.  
  1971. int main() {
  1972.     lua_State* L = luaL_newstate();
  1973.     lua_newtable(L);
  1974.     lua_pushcfunction(L, create);//уст указатель на функцию C++ и создает внутри Lua
  1975.     lua_setglobal(L, "get"); //получает значение из стека и уст значение global name.
  1976.     lua_pushcfunction(L, show);
  1977.     lua_setglobal(L, "show"); //получает значение из стека и уст значение global name.
  1978.     luaL_newmetatable(L, "mt");/*int luaL_newmetatable (lua_State * L, const char * t); */
  1979.     lua_pushstring(L, "__gc");
  1980.     lua_pushcfunction(L, destroy);
  1981.     lua_settable(L, 2);
  1982.     luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  1983.     lua_close(L);// закрыть состояние
  1984.     cin.get();//ожидает ввода символа программа завершается.
  1985. return 0;
  1986. }
  1987. Lua
  1988.  
  1989. a = get()
  1990. show(a)
  1991.  
  1992.  
  1993.  
  1994.  
  1995. api lua c++. Реализация ООП через функции 2. Структура конструктор по умолчанию.
  1996.  
  1997. struct a {
  1998.     int x = 10;
  1999.     a() { cout << "create object " << this << endl; }//конструктор по умолчанию
  2000.  
  2001.     void show() { cout << "\nobject - " << this << "\tx = " << x <<"\n\n"; }//вывести значение x на экран.
  2002.  
  2003.     ~a() { cout << "destory object " << this << endl << endl; }//вызов деструктора.
  2004. };
  2005.  
  2006. int destroy(lua_State* L) {// Функция вызывает деструктор для объекта.
  2007.     cout << "destroy " << endl;
  2008.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  2009.     a** st = (a**)lua_touserdata(L, -2); // получаем польз. данные.
  2010.     //a *b = &**st;
  2011.     //b->~a();//вызов метода деструктор.
  2012.     delete *st;
  2013.     return 0;
  2014.  
  2015. };
  2016. int create(lua_State* L) {//    Функция создания объекта структуры.
  2017.     luaL_newmetatable(L, "mt");// создать мета таблицу.
  2018.     lua_pushstring(L, "__gc");// отправить в стек сборщик мусора.
  2019.     lua_pushcfunction(L, destroy);// установить значение ключа, как вызов деструктор.
  2020.  
  2021.     lua_settable(L, -3);// установить таблицу.
  2022.     a** c = (a**)lua_newuserdata(L, sizeof(a*));/*Эта функция выделяет новый блок памяти с заданным размером,*/
  2023.     *c = new a();
  2024.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  2025.  
  2026.     lua_setmetatable(L, -2); //получает таблицу из стека и уст ее в качестве новой метатаблицы для значения с заданным допустимым индексом.
  2027.  
  2028. return 1;
  2029. };
  2030. int show(lua_State* L) {
  2031.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  2032.     a** st = (a**)lua_touserdata(L, -2);// получаем польз. данные.
  2033.     a *b = &**st;
  2034.     b->show();// вызов метода.  
  2035.     return 0;
  2036. };
  2037.  
  2038. int main() {
  2039.     lua_State* L = luaL_newstate();
  2040.     lua_register(L, "create", create );//уст указатель на функцию C++ и создает внутри Lua
  2041.     lua_register(L, "show", show); //получает значение из стека и уст значение global name.
  2042.     lua_register(L, "__gc", destroy); //получает значение из стека и уст значение global name.
  2043.     luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  2044.  
  2045.     lua_close(L);// закрыть состояние
  2046.     cin.get();//ожидает ввода символа программа завершается.
  2047.     return 0;
  2048. }
  2049.  
  2050.  
  2051. lua
  2052. a= create()
  2053. show(a)
  2054.  
  2055.  
  2056. Выводится
  2057. create object 0152FD78
  2058.  
  2059. object - 0152FD78       x = 10
  2060.  
  2061. destroy
  2062. destory object 0152FD78
  2063.  
  2064.  
  2065.  
  2066.  
  2067. api lua c++. Реализация ООП через функции 2. 2 класса. Структура конструктор по умолчанию.
  2068.  
  2069.  
  2070. struct a {
  2071.     int x = 10;
  2072.     a() { cout << "create object " << this << endl; }//конструктор по умолчанию
  2073.  
  2074.     void show() { cout << "\nobject - " << this << "\tx = " << x << "\n\n"; }//вывести значение x на экран.
  2075.     void get() { cout << "\nget "<< "\n\n"; }//вывести значение x на экран.
  2076.  
  2077.     ~a() { cout << "destory object " << this << endl << endl; }//вызов деструктора.
  2078. };
  2079. struct b {
  2080.     int y = 10;
  2081.     b() { cout << "create object b" << this << endl; }//конструктор по умолчанию
  2082.  
  2083.     void get() { cout << "\ngeta " << "\n\n"; }//вывести значение x на экран.
  2084.  
  2085.     ~b() { cout << "destory object " << this << endl << endl; }//вызов деструктора.
  2086. };
  2087. int destroy(lua_State* L) {// Функция вызывает деструктор для объекта.
  2088.     cout << "destroy " << endl;
  2089.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  2090.     a** st = (a**)lua_touserdata(L, -2); // получаем польз. данные.
  2091.     //a *b = &**st;
  2092.     //b->~a();//вызов метода деструктор.
  2093.     delete *st;
  2094.     return 0;
  2095.  
  2096. };
  2097. int create(lua_State* L) {//    Функция создания объекта структуры.
  2098.     luaL_newmetatable(L, "mt");// создать мета таблицу.
  2099.     lua_pushstring(L, "__gc");// отправить в стек сборщик мусора.
  2100.     lua_pushcfunction(L, destroy);// установить значение ключа, как вызов деструктор.
  2101.  
  2102.     lua_settable(L, -3);// установить таблицу.
  2103.     a** c = (a**)lua_newuserdata(L, sizeof(a*));/*Эта функция выделяет новый блок памяти с заданным размером,*/
  2104.     *c = new a();
  2105.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  2106.  
  2107.     lua_setmetatable(L, -2); //получает таблицу из стека и уст ее в качестве новой метатаблицы для значения с заданным допустимым индексом.
  2108.  
  2109. return 1;
  2110. };
  2111. int create1(lua_State* L) {//   Функция создания объекта структуры.
  2112.     luaL_newmetatable(L, "mt");// создать мета таблицу.
  2113.     lua_pushstring(L, "__gc");// отправить в стек сборщик мусора.
  2114.     lua_pushcfunction(L, destroy);// установить значение ключа, как вызов деструктор.
  2115.  
  2116.     lua_settable(L, -3);// установить таблицу.
  2117.     b** c = (b**)lua_newuserdata(L, sizeof(b*));/*Эта функция выделяет новый блок памяти с заданным размером,*/
  2118.     *c = new b();
  2119.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  2120.  
  2121.     lua_setmetatable(L, -2); //получает таблицу из стека и уст ее в качестве новой метатаблицы для значения с заданным допустимым индексом.
  2122.  
  2123.     return 1;
  2124. };
  2125. int show(lua_State* L) {
  2126.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  2127.     a** st = (a**)lua_touserdata(L, -2);// получаем польз. данные.
  2128.     a *b = &**st;
  2129.     b->show();// вызов метода.  
  2130.     return 0;
  2131. };
  2132. int get(lua_State* L) {
  2133.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  2134.     a** st = (a**)lua_touserdata(L, -2);// получаем польз. данные.
  2135.     a *b = &**st;
  2136.     b->get();// вызов метода.   
  2137.     return 0;
  2138. };
  2139.  
  2140. int geta(lua_State* L) {
  2141.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  2142.     b** st = (b**)lua_touserdata(L, -2);// получаем польз. данные.
  2143.     b *c = &**st;
  2144.     c->get();// вызов метода.   
  2145.     return 0;
  2146. };
  2147.  
  2148. int main() {
  2149.     lua_State* L = luaL_newstate();
  2150.     lua_register(L, "create", create);//уст указатель на функцию C++ и создает внутри Lua
  2151.     lua_register(L, "create1", create1);//уст указатель на функцию C++ и создает внутри Lua
  2152.     lua_register(L, "show", show); //получает значение из стека и уст значение global name.
  2153.     lua_register(L, "get", get); //получает значение из стека и уст значение global name.
  2154.     lua_register(L, "geta", geta); //получает значение из стека и уст значение global name.
  2155.     lua_register(L, "__gc", destroy); //получает значение из стека и уст значение global name.
  2156.     luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  2157.  
  2158.     lua_close(L);// закрыть состояние
  2159.     cin.get();//ожидает ввода символа программа завершается.
  2160.     return 0;
  2161. }
  2162.  
  2163.  
  2164.  
  2165.  
  2166.  
  2167. lua
  2168. a1 = create()
  2169. show(a1)
  2170. get(a1)
  2171. a2 = create1()
  2172. show(a2)
  2173. geta(a2)
  2174. a3 = create()
  2175. show(a3)
  2176.  
  2177. Выводится
  2178.  
  2179.  
  2180. create object 0157AE00
  2181.  
  2182. object - 0157AE00       x = 10
  2183.  
  2184.  
  2185. get
  2186.  
  2187. create object b01582220
  2188.  
  2189. object - 01582220       x = 10
  2190.  
  2191.  
  2192. geta
  2193.  
  2194. create object 0157FDA0
  2195.  
  2196. object - 0157FDA0       x = 10
  2197.  
  2198. destroy
  2199. destory object 0157FDA0
  2200.  
  2201. destroy
  2202. destory object 01582220
  2203.  
  2204. destroy
  2205. destory object 0157AE00
  2206.  
  2207.  
  2208.  
  2209.  
  2210.  
  2211. api lua c++. Реализация ООП через функции. Структура, конструктор с парамертами.
  2212.  
  2213. struct a {  int x = 10;
  2214. a() { this->x = x; cout << "create object " << this << endl;}//конструктор по умолчанию
  2215.  
  2216. a(int x) { this->x = x; cout << "create object " << this << endl; }//конструктор с параметрами.
  2217. void show() { cout << "\nobject - " << this << "\nx = " << x << endl; }//вывести значение x на экран.
  2218.  
  2219. ~a() { cout << "destory object " << this << endl << endl; }//вызов деструктора.
  2220. };
  2221. int destroy(lua_State* L) {// Функция вызывает деструктор для объекта.
  2222.     a* st = (a*)lua_touserdata(L, -1);/* Если значение в данном приемлемом индексе является полными данными пользователя.*/
  2223.     st->~a();//вызов метода деструктор.
  2224.     return 0;};
  2225.  
  2226. int create(lua_State* L) {//    Функция создания объекта структуры.
  2227.     void* st = lua_newuserdata(L, sizeof(a));/*Эта функция выделяет новый блок памяти с заданным размером,*/
  2228.        
  2229.     if (LUA_TNUMBER == lua_type(L, -2)) {// значение число.
  2230.         int x = lua_tointeger(L, -2);
  2231.         new (st) a(x);// Выделить память под польз. данные.
  2232.         luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  2233.         lua_setmetatable(L, -2);//получает таблицу из стека и уст ее в качестве новой метатаблицы для значения с заданным допустимым индексом.
  2234.     }
  2235.     else {  new (st) a();// Выделить память под польз. данные.
  2236.         luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  2237.         lua_setmetatable(L, -2);};//получает таблицу из стека и уст ее в качестве новой метатаблицы для значения с заданным допустимым индексом.
  2238.     return 1;};
  2239.  
  2240. int show(lua_State* L) {
  2241.     a* st = (a*)lua_touserdata(L, -1);// получаем польз. данные.
  2242.     st->show();// вызов метода.
  2243.     return 0;};
  2244.  
  2245. int main() {
  2246.     lua_State* L = luaL_newstate();
  2247.     lua_newtable(L);
  2248.     lua_pushcfunction(L, create);//уст указатель на функцию C++ и создает внутри Lua
  2249.     lua_setglobal(L, "get"); //получает значение из стека и уст значение global name.
  2250.     lua_pushcfunction(L, show);
  2251.     lua_setglobal(L, "show"); //получает значение из стека и уст значение global name.
  2252.     luaL_newmetatable(L, "mt");/*int luaL_newmetatable (lua_State * L, const char * t); */
  2253.     lua_pushstring(L, "__gc");
  2254.     lua_pushcfunction(L, destroy);
  2255.     lua_settable(L, -3);
  2256.     luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  2257.     lua_close(L);// закрыть состояние
  2258.     cin.get();//ожидает ввода символа программа завершается.
  2259. return 0;
  2260. }
  2261.  
  2262. Lua
  2263. a1 = get()
  2264. show(a1)
  2265. a2 = get(2)
  2266. show(a2)
  2267. a3 = get(3)
  2268. show(a3)
  2269.  
  2270. struct a {
  2271.     int x = 10;
  2272.     a() { cout << "create object " << this << endl; }//конструктор по умолчанию
  2273.  
  2274.     void show() { cout << "\nobject - " << this << "\tx = " << x <<"\n\n"; }//вывести значение x на экран.
  2275.  
  2276.     ~a() { cout << "destory object " << this << endl << endl; }//вызов деструктора.
  2277. };
  2278.  
  2279. int create(lua_State* L) {//    Функция создания объекта структуры.
  2280.     a** c = (a**)lua_newuserdata(L, sizeof(a*));/*Эта функция выделяет новый блок памяти с заданным размером,*/
  2281.     *c = new a();
  2282.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  2283.     lua_setmetatable(L, -1); //получает таблицу из стека и уст ее в качестве новой метатаблицы для значения с заданным допустимым индексом.
  2284.  
  2285. return 1;
  2286. };
  2287.  int show(lua_State* L) {
  2288.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  2289.  
  2290.     a** st = (a**)lua_touserdata(L, -2);// получаем польз. данные.
  2291.     (*st)->show();// вызов метода.
  2292.     a *b = &**st;
  2293.     b->show();// вызов метода.
  2294.     return 0;
  2295. };
  2296.  
  2297. int main() {
  2298.     lua_State* L = luaL_newstate();
  2299.     lua_register(L, "create", create );//уст указатель на функцию C++ и создает внутри Lua
  2300.     lua_register(L, "show", show); //получает значение из стека и уст значение global name.
  2301.     luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  2302.     lua_close(L);// закрыть состояние
  2303.     cin.get();//ожидает ввода символа программа завершается.
  2304.     return 0;
  2305. }
  2306.  
  2307. Вариант 2.
  2308.  
  2309.  
  2310. struct a{int x=0;
  2311.   a() : x() { cout <<"create object "<< this << endl; }//конструктор по умолчанию
  2312.  
  2313.     void set(int x){this->x = x;}//уст значение x.
  2314.  
  2315.     void show() {cout << "object - " << this << " x = " << x << endl;}
  2316.     //вывести значение x на экран.
  2317.     ~a() {cout <<"destory object "<< this << endl;  }//вызов деструктора.
  2318. };
  2319.  
  2320. int create(lua_State* L){// Функция создания объекта структуры.
  2321.     void* pointerToAa = lua_newuserdata(L, sizeof(a));/*Эта функция выделяет новый блок памяти с заданным размером,
  2322. помещает в стек новые полные пользовательские данные с адресом блока и возвращает этот адрес. Пользовательские данные
  2323. представляют значения C в Lua. Полный UserData представляет собой блок памяти. Это объект (например, таблица):
  2324. вы должны создать его, у него может быть свой собственный метатабль, и вы можете определить, когда он собирается.
  2325. Полные пользовательские данные равны только себе (при необработанном равенстве). Когда Lua собирает полные данные
  2326. пользователя с gcметаметодом, Lua вызывает метаметод и помечает данные пользователя как завершенные.
  2327. Когда эти пользовательские данные собираются снова, Lua освобождает соответствующую память.*/
  2328.     new (pointerToAa) a();// Выделить память под польз. данные.
  2329.     luaL_getmetatable(L, "aMetaTable"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.
  2330.     Если индекс не является действительным, или если значение не имеет метатаблицы, функция возвращает 0 и не отправляет ничего в стеке.*/
  2331.     lua_assert(lua_istable(L, 2));//ловит исключения если ли условия ложное.
  2332.     lua_setmetatable(L, 1);//получает таблицу из стека и уст ее в качестве новой метатаблицы для значения с заданным допустимым индексом.
  2333.     return 1;
  2334. };
  2335.  
  2336. int destroy(lua_State* L){// Функция вызывает деструктор для объекта.
  2337.     a* st = (a*)lua_touserdata(L, 1);/* Если значение в данном приемлемом индексе является полными данными пользователя,
  2338.     возвращает адрес его блока. Если значение является легким userdata, возвращает его указатель.В противном случае возвращается NULL.*/
  2339.     st->~a();//вызов метода деструктор.
  2340.     return 0;};
  2341.  
  2342. int set(lua_State* L){
  2343.     a* st = (a*)lua_touserdata(L, 1);
  2344.     lua_Number x = lua_tonumber(L, 2);
  2345.     st->set((int)x);
  2346.     return 0;};
  2347.  
  2348. int show(lua_State* L){
  2349.     a* st = (a*)lua_touserdata(L, 1);
  2350.     st->show();
  2351.     return 0;};
  2352.  
  2353. int index(lua_State* L){
  2354.     lua_assert(lua_isuserdata(L, 1));
  2355.     lua_assert(lua_isstring(L, 2));
  2356.  
  2357.     a* st = (a*)lua_touserdata(L, 1);
  2358.     const char* index = lua_tostring(L, 2);
  2359.     if (strcmp(index, "x") == 0){
  2360.         lua_pushnumber(L, st->x);
  2361.         return 1;   }
  2362.     else{lua_getglobal(L, "a");
  2363.         lua_pushstring(L, index);
  2364.         lua_rawget(L, 3);// Аналогично lua_settable, но делает необработанное назначение(т.Е.Без метаметодов).
  2365.         return 1;   }
  2366. };
  2367.  
  2368. int newindex(lua_State* L){
  2369.     lua_assert(lua_isuserdata(L, -3));
  2370.     lua_assert(lua_isstring(L, -2));//
  2371.     a* st = (a*)lua_touserdata(L, -3);
  2372.     const char* index = lua_tostring(L, -2);
  2373.     if (strcmp(index, "x") == 0){
  2374.         st->x = (int)lua_tonumber(L, -1);   }
  2375.     else{lua_assert(false); }
  2376.     return 0;
  2377. };
  2378.  
  2379. int main() {
  2380.     lua_State* L = luaL_newstate();
  2381.     lua_newtable(L);
  2382.     int stTableIdx = lua_gettop(L);
  2383.     lua_pushvalue(L, stTableIdx);// отправляет копию элемента с заданным допустимым индексом в стек.
  2384.     lua_setglobal(L, "a");// Установить значение глобальной переменной.
  2385.  
  2386.     lua_pushcfunction(L, create);/* отправляет функцию C в стек. функция получает указатель на функцию C и отправляет в стек
  2387.      значение типа Lua, function которое при вызове вызывает соответствующую функцию C.   Любая функция, которая должна быть
  2388.      зарегистрирована в Lua, должна следовать правильному протоколу, чтобы получать свои параметры и возвращать свои результаты*/
  2389.     lua_setfield(L, 1, "new");/*(lua_State * L, int index, const char * k); Соответствует ли t[k] = v, где t значение данного
  2390.     заданного допустимого индекса и vзначение в верхней части стека. Эта функция извлекает значение из стека. Как и в Lua,
  2391.     эта функция может запускать метаметод для события «newindex» (см. §2.8 ). уст ключ для new.   */
  2392.     lua_pushcfunction(L, set);
  2393.     lua_setfield(L, 1, "set");
  2394.     lua_pushcfunction(L, show);
  2395.     lua_setfield(L, 1, "show");
  2396.  
  2397.     luaL_newmetatable(L, "aMetaTable");/*int luaL_newmetatable (lua_State * L, const char * t); Если в реестре уже есть ключ t,
  2398.      возвращает 0. В противном случае создает новую таблицу, которая будет использоваться в качестве метатаблицы
  2399.      для пользовательских данных, добавляет ее в реестр с ключом tnameи возвращает 1. В обоих случаях помещает в стек
  2400.      окончательное значение, связанное с t реестром.*/
  2401.     lua_pushstring(L, "__gc");
  2402.     lua_pushcfunction(L, destroy);
  2403.     lua_settable(L, 2);
  2404.  
  2405.     lua_pushstring(L, "__index");
  2406.     lua_pushcfunction(L, index);
  2407.     lua_settable(L, 2);
  2408.  
  2409.     lua_pushstring(L, "__newindex");
  2410.     lua_pushcfunction(L, newindex);
  2411.     lua_settable(L, 2);
  2412.  
  2413.     int x = luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  2414.  
  2415.     if (x == LUA_OK) {  lua_close(L);// если поллучилось открыть файл.
  2416.         cin.get();}//ожидает ввода символа программа завершается.
  2417.    
  2418.     else {  cout << "Error: "<<lua_tostring(L, -1)<<endl;
  2419.         lua_close(L);// закрыть состояние
  2420.         cin.get();//ожидает ввода символа программа завершается.
  2421.         return 0;   }
  2422. }
  2423. Lua
  2424. st = a.new()
  2425. --st:show()
  2426. st:set(100)
  2427. st:show()
  2428. st1 = a.new()
  2429. st1:set(200)   
  2430. st1:show()
  2431.  
  2432.  
  2433.  
  2434. выделение памяти.
  2435.  
  2436. struct ArenaAllocator
  2437. {
  2438.     void* m_begin;
  2439.     void* m_end;
  2440.     char* m_curr;
  2441.  
  2442.  
  2443.     ArenaAllocator(void* begin, void* end) :
  2444.         m_begin(begin),
  2445.         m_end(end),
  2446.         m_curr(static_cast<char*>(m_begin) )
  2447.     {   }
  2448.  
  2449.     void* Allocate(size_t sizeBytes){
  2450.         assert(m_curr + sizeBytes < m_end);
  2451.         printf("-- allocated from the freelist --\n");
  2452.         void* ptr = m_curr;
  2453.         m_curr += sizeBytes;
  2454.         return ptr;
  2455.     }
  2456.  
  2457.     void DeAllocate(void* ptr, size_t osize)    {
  2458.         assert(ptr != nullptr);     //can't decallocate null!!!
  2459.         printf("DeAllocated %d bytes\n", (int)osize);
  2460.     }
  2461.  
  2462.     void* ReAllocate(void* ptr, size_t osize, size_t nsize){
  2463.         printf("ReAllocated %d bytes\n", (int)nsize);
  2464.         void* newPtr = Allocate(nsize);
  2465.         memcpy(newPtr, ptr, osize);
  2466.         DeAllocate(ptr, osize);
  2467.         return newPtr;
  2468.     }
  2469.  
  2470.     static void *l_alloc(void *ud, void *ptr, size_t osize, size_t nsize) {
  2471.         ArenaAllocator * pool = static_cast<ArenaAllocator *>(ud);
  2472.         if (nsize == 0)
  2473.         {
  2474.             if (ptr != nullptr)
  2475.             {
  2476.                 pool->DeAllocate(ptr, osize);
  2477.             }
  2478.             return NULL;
  2479.         }
  2480.         else
  2481.         {
  2482.             if (ptr == nullptr)
  2483.             {
  2484.                 return pool->Allocate(nsize);
  2485.             }
  2486.             else
  2487.             {
  2488.                 return pool->ReAllocate(ptr, osize, nsize);
  2489.             }
  2490.         }
  2491.     }
  2492. };
  2493. int main() {
  2494.     constexpr int pool_size = 1024 * 10;
  2495.     char memory[pool_size];
  2496.     ArenaAllocator pool(memory, &memory[pool_size-1]);
  2497.  
  2498.     lua_State *L = lua_newstate(ArenaAllocator::l_alloc, &pool);
  2499.     //luaL_openlibs(L);
  2500.     assert(L != nullptr);
  2501.     lua_close(L);
  2502.     //cin.get();//ожидает ввода символа программа завершается.  
  2503.     return 0;
  2504. }
  2505.  
  2506.  
  2507.  
  2508. Нативнный код, позволяет писать lua скрипт в cpp файле, мы можем вносит в него изменения не переключаясь на lua файл, однако изменения, требуют собрать проект заново.
  2509.  
  2510. Определение типа переменной и вывод ее на экран.
  2511.  
  2512. void showstack(lua_State* L) {
  2513.     int i = lua_gettop(L);/* получаем количество элементов в стеке.*/
  2514.     cout << "\n  the number on the stack = " << i << "\n\n\n";
  2515.     int j = (i) * -1-1;
  2516.     i = -1;
  2517.     for (i; i > j; i--) {
  2518.         int t = lua_type(L, i);
  2519.         cout << "\t " << i << "  " << (j - i) * -1 << "\t";
  2520.         if (LUA_TSTRING == t) {
  2521.             cout << lua_tostring(L, i) << endl;
  2522.         }
  2523.         if (LUA_TNUMBER == t) {
  2524.             double x = lua_tonumber(L, i);
  2525.             int x2 = (int)x;
  2526.             if (x == x2) { cout << x2 << endl; }
  2527.             else { cout << x << endl; }
  2528.         }
  2529.         if (LUA_TBOOLEAN == t) {cout << "LUA_TBOOLEAN "<< lua_toboolean(L, i) << endl;      }
  2530.  
  2531.         if (LUA_TLIGHTUSERDATA == t) {  cout << "LIGHTUSERDATA " << endl;       }
  2532.        
  2533.        if (LUA_TTABLE == t) {   cout << "LUA_TTABLE " << endl;  }
  2534.  
  2535.         if (LUA_TFUNCTION == t) {   cout << "LUA_TFUNCTION " << endl;   }
  2536.  
  2537.         if (LUA_TUSERDATA == t) {cout << "LUA_TUSERDATA " << endl;  }
  2538.  
  2539.         if (LUA_TTHREAD == t) { cout << "LUA_TTHREAD " << endl;     }
  2540.  
  2541.         if (LUA_TNIL == t) {cout << "LUA_TNIL " << endl;        }
  2542.     }
  2543. };
  2544.  
  2545. void getvar(lua_State* L, const char* var) {
  2546.     lua_getglobal(L, var);// получить значение глобальной переменной x.
  2547.     if (LUA_TSTRING == lua_type(L, -1)) {
  2548.         cout << "string " << var << " = " << lua_tostring(L, -1);
  2549.     }
  2550.     if (LUA_TNUMBER == lua_type(L, -1)) {
  2551.         double x = lua_tonumber(L, -1);
  2552.         int x2 = (int)x;
  2553.         if (x == x2) { cout << "number int " << var << " = " << x2; }
  2554.         else { cout << "number double " << var << " = " << x; }
  2555.     }
  2556.     if (LUA_TBOOLEAN == lua_type(L, -1)) {
  2557.         cout << "bool " << var << " = " << (lua_toboolean(L, -1) ? "true " : "false ");
  2558.     }
  2559.     if (LUA_TTABLE == lua_type(L, -1)) {
  2560.         cout << "LUA_TTABLE " << var << " = " << endl;
  2561.     }
  2562.     if (LUA_TFUNCTION == lua_type(L, -1)) {
  2563.         cout << "LUA_TFUNCTION " << var << " = " << endl;
  2564.     }
  2565.     if (LUA_TNIL == lua_type(L, -1)) { // если var нет.
  2566.         cout << "not " << var;
  2567.     }
  2568.     cout << endl;
  2569. };
  2570.  
  2571. void getstack(lua_State* L, int pos) {// Посмотреть позицию в стеке.
  2572.     if (LUA_TSTRING == lua_type(L, pos)) {
  2573.         cout << lua_tostring(L, pos);
  2574.     }
  2575.     if (LUA_TNUMBER == lua_type(L, pos)) {
  2576.         double x = lua_tonumber(L, pos);
  2577.         int x2 = (int)x;
  2578.         if (x == x2) { cout << x2; }
  2579.         else { cout << x; }
  2580.     }
  2581.     if (LUA_TBOOLEAN == lua_type(L, pos)) {
  2582.         cout << (lua_toboolean(L, pos) ? "true " : "false ");
  2583.     }
  2584.     if (LUA_TTABLE == lua_type(L, pos)) {
  2585.         cout << "LUA_TTABLE " << endl;
  2586.     }
  2587.     if (LUA_TLIGHTUSERDATA == lua_type(L, pos)) {
  2588.         cout << "LIGHTUSERDATA " << endl;
  2589.     }
  2590.     if (LUA_TTABLE == lua_type(L, pos)) {
  2591.         cout << "LUA_TTABLE " << endl;
  2592.     }
  2593.     if (LUA_TFUNCTION == lua_type(L, pos)) {
  2594.         cout << "LUA_TFUNCTION " << endl;
  2595.     }
  2596.     if (LUA_TUSERDATA == lua_type(L, pos)) {
  2597.         cout << "LUA_TUSERDATA " << endl;
  2598.     }
  2599.     if (LUA_TTHREAD == lua_type(L, pos)) {
  2600.         cout << "LUA_TTHREAD " << endl;
  2601.     }
  2602.     if (LUA_TNIL == lua_type(L, pos)) {
  2603.         cout << "nill " << endl;// если NILL.
  2604.     }
  2605. };
  2606.  
  2607. int checkerror(lua_State* L, const char* file) {
  2608.     int status = luaL_loadfile(L, file);// проверка есть ли ошибки.
  2609.     try {
  2610.         if (luaL_dostring(L, file) == LUA_OK) {
  2611.             return 0;
  2612.         }
  2613.         else {
  2614.             string x = lua_tostring(L, -1);
  2615.             throw x;
  2616.             return 0;
  2617.         }
  2618.     }
  2619.     catch (string x) {
  2620.         cout << x << endl;
  2621.         //luaL_error(L,"error");
  2622.         return 0;
  2623.     }
  2624. };
  2625.  
  2626. template <class T>//любое значение отправить в стек.
  2627. void pushlua(lua_State * L, const T & value) {
  2628.     if constexpr (std::is_same_v<T, std::string>)
  2629.         lua_pushstring(L, value.c_str());
  2630.     else if constexpr (std::is_array_v<T> && std::is_same_v<std::remove_extent_t<T>, char>)
  2631.         lua_pushstring(L, value);
  2632.     else if constexpr (std::is_same_v<T, int>)
  2633.         lua_pushinteger(L, value);
  2634.     else if constexpr (std::is_same_v<T, double>)
  2635.         lua_pushnumber(L, value);
  2636.     else if constexpr (std::is_same_v<T, bool>)
  2637.         lua_pushboolean(L, value);
  2638.     else
  2639.         std::cerr << "I do not know what to do :(" << std::endl;
  2640. };
  2641. template <class t1, class t2>
  2642. void addkeyintab(lua_State* L, t1 key, t2 value) {
  2643.     /* Устанавливает реальное значение t[i] = value  как value, без вызова метаметода. t это таблица, i - любым числом, отличным от nil и NaN,
  2644.     а value - значение. Данная функция возвращает table. */
  2645.     if (std::is_same_v<t1, const char*> && std::is_same_v<t2, int>) {
  2646.         cout << "key string " << key << " int " << value << endl;
  2647.         const char* key1 = (const char*)key;
  2648.         int value1 = (int)value;
  2649.         lua_pushstring(L, key1); /* отправить ключ в стек */
  2650.         lua_pushinteger(L, value1); /* отправить значение ключа в стек. */
  2651.         lua_rawset(L, -3);  } /*Сохраняет пару в таблице */
  2652.  
  2653.     else if (std::is_same_v<t1, int> && std::is_same_v<t2, const char*>) {
  2654.         cout << "key int " << key << " string " << value << endl;
  2655.         int key1 = (int)key;
  2656.         const char* value1 = (const char*)value;
  2657.         lua_pushinteger(L, key1); /* отправить ключ в стек */
  2658.         lua_pushstring(L, value1); /* отправить значение ключа в стек. */
  2659.         lua_rawset(L, -3);  } /*Сохраняет пару в таблице */
  2660.  
  2661.     else if (std::is_same_v<t1, const char*> && std::is_same_v<t2, const char*>) {
  2662.         cout << "key string " << key << " value string " << value << endl;
  2663.         const char* key1 = (const char*)key;
  2664.         const char* value1 = (const char*)value;
  2665.         lua_pushstring(L, key1); /* отправить ключ в стек */
  2666.         lua_pushstring(L, value1); /* отправить значение ключа в стек. */
  2667.         lua_rawset(L, -3);} /*Сохраняет пару в таблице */
  2668.  
  2669.     else if (std::is_same_v<t1, int> && std::is_same_v<t2, int>) {
  2670.         cout << "key int " << key << " value int " << value << endl;
  2671.         int key1 = (int)key;
  2672.         int value1 = (int)value;
  2673.         lua_pushinteger(L, key1); /* отправить ключ в стек */
  2674.         lua_pushinteger(L, value1); /* отправить значение ключа в стек. */
  2675.         lua_rawset(L, -3); /*Сохраняет пару в таблице */
  2676.     }
  2677. };
  2678.  
  2679. int main(int argc, char *argv[]) {
  2680.     const char* LUA = R"(
  2681. x = true
  2682. )";
  2683.     lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  2684.     luaL_openlibs(L);
  2685.     checkerror(L, LUA);//Функция проверка на ошибки.
  2686.     getvar(L, "x");
  2687.  
  2688.     lua_close(L);
  2689.  
  2690.     return 0;
  2691.  
  2692.  
  2693. Присвоение значения переменной через отправку в стек.
  2694.  
  2695. int main(int argc, char *argv[]) {
  2696.     const char* LUA = R"(
  2697. print(c)
  2698.  
  2699. )";
  2700.     lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  2701.     luaL_openlibs(L);
  2702.     pushlua(L, 12);
  2703.     lua_setglobal(L, "c");// уст значение переменной в lua.
  2704.     checkerror(L, LUA);//Функция проверка на ошибки.
  2705.  
  2706.     lua_close(L);
  2707.  
  2708.     return 0;
  2709. }
  2710.  
  2711.  
  2712. Вызов функции в нативном коде через получение переменной.
  2713.  
  2714. int main(int argc, char *argv[]) {
  2715. const char* LUA = R"(
  2716.  function foo()
  2717.   return 4
  2718.  end )";
  2719.     lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  2720.     luaL_openlibs(L);  
  2721.     checkerror(L, LUA);//Функция проверка на ошибки.
  2722.     lua_getglobal(L, "foo");
  2723.    
  2724.     if (lua_isfunction(L, -1)) {
  2725.         lua_pcall(L, 0, 1, 0);
  2726.         cout << lua_tonumber(L, -1) << endl;    }
  2727.     lua_close(L);
  2728.     return 0;
  2729. }
  2730.  
  2731. Вызов функции в нативном коде через присвоение.
  2732.  
  2733. int foo(lua_State *L) {
  2734.     cout << "hi foo c++" << endl;
  2735.     return 0;
  2736. };
  2737.  
  2738. int main(int argc, char *argv[]) {
  2739.     const char* LUA = R"(
  2740. foo()
  2741.  
  2742. )";
  2743.     lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  2744.     luaL_openlibs(L);
  2745.     lua_pushcfunction(L, foo);// отправить c функцию в стек.
  2746.  
  2747.     lua_setglobal(L, "foo");// уст для переменной значение в виде функции.
  2748.  
  2749.     checkerror(L, LUA);//Функция проверка на ошибки.
  2750.  
  2751.     lua_close(L);
  2752.  
  2753.     return 0;
  2754. };
  2755.  
  2756. Вызов функции в нативном коде через отправку в таблицу.
  2757.  
  2758. int foo(lua_State *L) {
  2759.     cout << "hi foo c++" << endl;
  2760.     return 0;
  2761. }
  2762.  
  2763. int main(int argc, char *argv[]) {
  2764.     const char* LUA = R"(
  2765. foo()
  2766. )";
  2767.     lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  2768.     luaL_openlibs(L);
  2769.  
  2770.     lua_newtable(L); /*создать пустую таблицу */
  2771.     lua_pushcfunction(L, foo);// отправить c функцию в стек как ключ.
  2772.     lua_setglobal(L, "foo");// уст для переменой(ключ) значение в новой пустой таблицы в виде функции.
  2773.  
  2774.     checkerror(L, LUA);//Функция проверка на ошибки.
  2775.  
  2776.     lua_close(L);
  2777.  
  2778.     return 0;
  2779. };
  2780.  
  2781.  
  2782. Вызов функции с параметром в нативном коде через отправку в таблицу.
  2783.  
  2784. int foo(lua_State *L) {
  2785.     int x = lua_tointeger(L, -1);
  2786.     pushlua(L, x * 2);
  2787.  
  2788. return 1;
  2789. }
  2790.  
  2791. int main(int argc, char *argv[]) {
  2792.     const char* LUA = R"(
  2793. g=foo(12)
  2794. print(g)
  2795. )";
  2796.     lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  2797.     luaL_openlibs(L);
  2798.  
  2799.     lua_newtable(L); /*создать пустую таблицу */
  2800.     lua_pushcfunction(L, foo);// отправить c функцию в стек.
  2801.     lua_setglobal(L, "foo");// уст для переменой(ключ) значение в новой пустой таблицы в виде функции.
  2802.  
  2803.     checkerror(L, LUA);//Функция проверка на ошибки.
  2804.  
  2805.     lua_close(L);
  2806.  
  2807.     return 0;
  2808. };
  2809.  
  2810. Таблица в стеке, добавления в нее элементов.
  2811.  
  2812. int main(int argc, char *argv[]) {
  2813.     lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  2814.     luaL_openlibs(L);
  2815.     lua_newtable(L);
  2816.     lua_pushstring(L, "key");
  2817.     lua_pushnumber(L, 100);
  2818.     lua_rawset(L,-3);
  2819.  
  2820.     lua_pushstring(L, "key");
  2821.     lua_gettable(L, -2);
  2822.    cout << lua_tonumber(L,-1) << endl; //Функция 100.
  2823.  
  2824.     lua_close(L);
  2825.  
  2826.     return 0;
  2827. };
  2828.  
  2829. Вариант 2.
  2830.  
  2831. int main(int argc, char* argv[]) {
  2832.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  2833.     luaL_openlibs(L);
  2834.     lua_newtable(L);
  2835.     lua_pushnumber(L, 100);
  2836.     lua_setfield(L, -2, "key");// уст в таблицу ключ - key со значение 100.
  2837.  
  2838.     pushlua(L, "key");
  2839.     lua_gettable(L, -2);
  2840.     getlaststack(L); //Функция 100.
  2841.  
  2842.     lua_close(L);
  2843.  
  2844.     return 0;
  2845. };
  2846.  
  2847. Добавление следующего ключа со значением в таблицу.
  2848.  
  2849. int main(int argc, char* argv[]) {
  2850.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  2851.     luaL_openlibs(L);
  2852.     lua_newtable(L);
  2853.  
  2854.     pushlua(L, "key");
  2855.     pushlua(L, 100);
  2856.     lua_rawset(L, -3);// table["key"] = 100.
  2857.    
  2858.     pushlua(L, "a");
  2859.     pushlua(L, 6);
  2860.     lua_rawset(L, -3);// table["a"] = 6.
  2861.  
  2862.  
  2863.     pushlua(L, "a");
  2864.     lua_gettable(L, -2);
  2865.     getlaststack(L); // 6.
  2866.  
  2867.     lua_close(L);
  2868.  
  2869.     return 0;
  2870. };
  2871.  
  2872.  
  2873. Функция добавление в таблицу нового ключа со значением.
  2874.  
  2875. template <class t1, class t2>
  2876. void addkeyintab(lua_State* L, t1 key, t2 value) {
  2877.     /* Устанавливает реальное значение t[i] = value  как value, без вызова метаметода. t это таблица, i - любым числом, отличным от nil и NaN,
  2878.     а value - значение. Данная функция возвращает table. */
  2879.     if (std::is_same_v<t1, const char*> && std::is_same_v<t2, int>) {
  2880.         cout << "key string " << key << " value int " << value << endl;
  2881.         const char* key1 = (const char*)key;
  2882.         int value1 = (int)value;
  2883.         lua_pushstring(L, key1); /* отправить ключ в стек */
  2884.         lua_pushinteger(L, value1); /* отправить значение ключа в стек. */
  2885.         lua_rawset(L, -3);  } /*Сохраняет пару в таблице */
  2886.  
  2887.     else if (std::is_same_v<t1, int> && std::is_same_v<t2, const char*>) {
  2888.         cout << "key int " << key << " value string " << value << endl;
  2889.         int key1 = (int)key;
  2890.         const char* value1 = (const char*)value;
  2891.         lua_pushinteger(L, key1); /* отправить ключ в стек */
  2892.         lua_pushstring(L, value1); /* отправить значение ключа в стек. */
  2893.         lua_rawset(L, -3);  } /*Сохраняет пару в таблице */
  2894.  
  2895.     else if (std::is_same_v<t1, const char*> && std::is_same_v<t2, const char*>) {
  2896.         cout << "key string " << key << " value string " << value << endl;
  2897.         const char* key1 = (const char*)key;
  2898.         const char* value1 = (const char*)value;
  2899.         lua_pushstring(L, key1); /* отправить ключ в стек */
  2900.         lua_pushstring(L, value1); /* отправить значение ключа в стек. */
  2901.         lua_rawset(L, -3);} /*Сохраняет пару в таблице */
  2902.  
  2903.     else if (std::is_same_v<t1, int> && std::is_same_v<t2, int>) {
  2904.         cout << "key int " << key << " value int " << value << endl;
  2905.         int key1 = (int)key;
  2906.         int value1 = (int)value;
  2907.         lua_pushinteger(L, key1); /* отправить ключ в стек */
  2908.         lua_pushinteger(L, value1); /* отправить значение ключа в стек. */
  2909.         lua_rawset(L, -3); /*Сохраняет пару в таблице */
  2910.     }
  2911. };
  2912. int main(int argc, char *argv[]) {
  2913. const char* LUA = R"(
  2914. print(foo)
  2915. for k,v in pairs(foo) do
  2916. print(k.." "..v)
  2917. end
  2918.  
  2919. )";
  2920.     lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  2921.     luaL_openlibs(L);
  2922.  
  2923.     lua_newtable(L); /*создать пустую таблицу */
  2924.     addkeyintab(L, "a", " 10 z "); /*добавить ключ и значение в таблицу */
  2925.     addkeyintab(L, "x1", 99); /*добавить ключ и значение в таблицу */
  2926.     addkeyintab(L, 100, 10); /*добавить ключ и значение в таблицу */
  2927.     addkeyintab(L, 100, "y"); /*добавить ключ и значение в таблицу */
  2928.     lua_setglobal(L, "foo");// уст имя таблицы в lua.
  2929.     cout << "\n" << endl;
  2930.     checkerror(L, LUA);//Функция проверка на ошибки.
  2931.  
  2932.     lua_close(L);
  2933.     return 0;
  2934. };
  2935.  
  2936. Выводится.
  2937. key string a value string  10 z
  2938. key string x1 int 99
  2939. key int 100 value int 10
  2940. key int 100 string y
  2941.  
  2942.  
  2943. table: 009F0830
  2944. 100 y
  2945. x1 99
  2946. a  10 z
  2947.  
  2948. C:\Users\e\source\repos\Project1luaapi\Debug\Project1luaapi.exe (процесс 6000) завершает работу с кодом 0.
  2949. Чтобы закрыть это окно, нажмите любую клавишу…
  2950.  
  2951.  
  2952.  
  2953. Функция возвращает таблицу с ключами в качестве функциями.
  2954.  
  2955. int square(lua_State* L) {//    Функция создания объекта структуры.
  2956.     cout << lua_tonumber(L,-1)*2 << endl;
  2957.     return 0;
  2958. };
  2959. int cube(lua_State* L) {//  Функция создания объекта структуры.
  2960.     cout << lua_tonumber(L, -1) * 3 << endl;
  2961.     return 0;
  2962. };
  2963.  
  2964.  
  2965. int create(lua_State* L) {//    Функция создания объекта структуры.
  2966.     lua_newtable(L);
  2967.     lua_pushcfunction(L, square);  
  2968.     lua_setfield(L, -2, "square");
  2969.     lua_pushcfunction(L, cube);
  2970.     lua_setfield(L, -2, "cube");
  2971.     return 1;
  2972. };
  2973.  
  2974. int main(int argc, char* argv[]) {
  2975. const char* LUA = R"(
  2976.  
  2977. a = create()
  2978. a.square(5) --10
  2979. a.square(10)--20
  2980. a.cube(4)--12
  2981. a.cube(6)--18
  2982. print(a)
  2983. )";
  2984.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  2985.     luaL_openlibs(L);
  2986.    
  2987.     lua_pushcfunction(L, create);/* отправляет функцию C в стек. функция получает указатель на функцию C и отправляет в стек*/
  2988.     lua_setglobal(L, "create");
  2989.  
  2990.     checkerror(L, LUA);//Функция проверка на ошибки.
  2991.  
  2992.     lua_close(L);
  2993.  
  2994.     return 0;
  2995. };
  2996.  
  2997.  
  2998. Вывод всех ключей и значений неизвестной таблицы.
  2999.  
  3000. int pri(lua_State* L, const char t[]) {
  3001.     lua_getglobal(L, t);// получить значение глобальной переменной, таблица.
  3002.     lua_pushvalue(L, -1);
  3003.     lua_pushnil(L);
  3004.     while (lua_next(L, -2)) {
  3005.         lua_pushvalue(L, -2);
  3006.         cout << "key "; getstack(L, -1); cout << " value "; getstack(L, -2); cout << endl;
  3007.         lua_pop(L, 2);
  3008.     }
  3009.     lua_pop(L, 1);
  3010.     return 0;
  3011. };
  3012. int main() {
  3013.     const char* LUA = R"(
  3014. t= {x=10, y=20, z=30}
  3015. )";
  3016.  
  3017.     lua_State* L = luaL_newstate();
  3018.     luaL_openlibs(L);
  3019.  
  3020.     checkerror(L, LUA);//Функция проверка на ошибки.
  3021.     pri(L, "t");// вывести ключи и значения таблицы.  
  3022.  
  3023.     lua_close(L);// закрыть состояние
  3024.     return 0;
  3025. };
  3026.  
  3027. Сохранение всех ключей таблицы в реестре.
  3028.  
  3029. int pritab(lua_State* L, const char t[]) {
  3030.     int x = 0;
  3031.     lua_getglobal(L, t);// получить значение глобальной переменной, таблица.
  3032.     lua_pushvalue(L, -1);
  3033.     lua_pushnil(L);
  3034.     while (lua_next(L, -2)) {
  3035.     //. cout << " key ";
  3036.         lua_pushvalue(L, -2);
  3037.         lua_rawseti(L, LUA_REGISTRYINDEX, x);
  3038.         //getstack(L, -2);
  3039.         lua_pushvalue(L, -2);
  3040.         //cout << "key "; getstack(L, -1); cout << " value "; getstack(L, -2); cout << endl;
  3041.         lua_pop(L, 2);
  3042.         x++;
  3043.     }
  3044.     lua_pop(L, 1);
  3045.     pushlua(L, x);
  3046.     return 1;
  3047. };
  3048. int main() {
  3049.     const char* LUA = R"(
  3050. t= {x=10, y=20, z=30}
  3051. )";
  3052.  
  3053.     lua_State* L = luaL_newstate();
  3054.     luaL_openlibs(L);
  3055.  
  3056.     checkerror(L, LUA);//Функция проверка на ошибки.
  3057.     pritab(L, "t");// вывести ключи и значения таблицы.
  3058.     int len = lua_tointeger(L,-1);
  3059.     for (int i = 0; i < len; i++){
  3060.     lua_rawgeti(L, LUA_REGISTRYINDEX, i);/* вернуть значение для ключа в реестр. */
  3061.     cout << "key "; getstack(L, -1);  cout << endl;}
  3062.     lua_close(L);// закрыть состояние
  3063.     return 0;
  3064. };
  3065.  
  3066. Вывод всех значений ключей из реестра.
  3067.  
  3068. int pritab(lua_State* L, const char t[]) {
  3069.     int x = 0;
  3070.     lua_getglobal(L, t);// получить значение глобальной переменной, таблица.
  3071.     lua_pushvalue(L, -1);
  3072.     lua_pushnil(L);
  3073.     while (lua_next(L, -2)) {
  3074.         //. cout << " key ";
  3075.         lua_pushvalue(L, -2);
  3076.         lua_rawseti(L, LUA_REGISTRYINDEX, x);
  3077.         //getstack(L, -2);
  3078.         lua_pushvalue(L, -2);
  3079.         //cout << "key "; getstack(L, -1); cout << " value "; getstack(L, -2); cout << endl;
  3080.         lua_pop(L, 2);
  3081.         x++;
  3082.     }
  3083.     lua_pop(L, 1);
  3084.     pushlua(L, x);
  3085.     return 1;
  3086. };
  3087. int main() {
  3088.     const char* LUA = R"(
  3089. t= {x=10, y=20, z=30}
  3090. )";
  3091.  
  3092.     lua_State* L = luaL_newstate();
  3093.     luaL_openlibs(L);
  3094.  
  3095.     checkerror(L, LUA);//Функция проверка на ошибки.
  3096.     pritab(L, "t");// вывести ключи и значения таблицы.
  3097.     int len = lua_tointeger(L, -1);
  3098.     lua_pop(L, 1);
  3099.     for (int i = 0; i < len; i++) {
  3100.         lua_rawgeti(L, LUA_REGISTRYINDEX, i);/* вернуть значение для ключа в реестр. */
  3101.                
  3102.         cout << "key "; getstack(L, -1);
  3103.  
  3104.         lua_getglobal(L, "t");
  3105.         lua_pushvalue(L, -2);
  3106.         lua_gettable(L, -4);
  3107.         cout << " value "; getstack(L, -1);  cout << endl;
  3108.         lua_pop(L, 3);
  3109.  
  3110.     }
  3111.     lua_close(L);// закрыть состояние
  3112.     return 0;
  3113. };
  3114.  
  3115.  
  3116. Отправить в стек таблицу.
  3117.  
  3118. int rettab(lua_State* L) {// Функция отправить в стек таблицу.
  3119.     lua_newtable(L);
  3120.     for (int i = 1; i < 10; i++){
  3121.     pushlua(L, i);
  3122.     pushlua(L, i*10);
  3123.     lua_rawset(L, -3);
  3124.     }
  3125.     return 1;
  3126. };
  3127.  
  3128. int main(int argc, char* argv[]) {
  3129.     const char* LUA = R"(
  3130.  
  3131. a = rettab()
  3132. print(a[3]) --30
  3133. )";
  3134.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  3135.     luaL_openlibs(L);
  3136.  
  3137.     lua_pushcfunction(L, rettab);/* отправляет функцию C в стек. функция получает указатель на функцию C и отправляет в стек*/
  3138.     lua_setglobal(L, "rettab");
  3139.  
  3140.     checkerror(L, LUA);//Функция проверка на ошибки.
  3141.  
  3142.     lua_close(L);
  3143.  
  3144.     return 0;
  3145. };
  3146.  
  3147. Отправить таблицу в функцию.
  3148.  
  3149. int readtab(lua_State* L) {// Функция отправить в стек таблицу.
  3150.     if (LUA_TTABLE == lua_type(L, -1)) {
  3151.  
  3152.         lua_pushinteger(L, 1);
  3153.  
  3154.         lua_gettable(L, -2);
  3155.         int x = lua_tointeger(L, -1);
  3156.         getstack(L, -1); cout << endl;
  3157.         lua_pop(L, 1);
  3158.         lua_pushinteger(L, 2);
  3159.         lua_gettable(L, -2);
  3160.         int y = lua_tointeger(L, -1);
  3161.         getstack(L, -1); cout << endl;
  3162.         lua_pop(L, 1);
  3163.         lua_pushinteger(L, 3);
  3164.         lua_gettable(L, -2);
  3165.         int z = lua_tointeger(L, -1);
  3166.         getstack(L, -1); cout << endl;
  3167.         lua_pop(L, 1);
  3168.  
  3169.     }
  3170.     return 0;
  3171. };
  3172.  
  3173. int main(int argc, char* argv[]) {
  3174.     const char* LUA = R"(
  3175. t = {10,20,30}
  3176. readtab(t)
  3177. )";
  3178.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  3179.     luaL_openlibs(L);
  3180.  
  3181.     lua_pushcfunction(L, readtab);/* отправляет функцию C в стек. функция получает указатель на функцию C и отправляет в стек*/
  3182.     lua_setglobal(L, "readtab");
  3183.  
  3184.     checkerror(L, LUA);//Функция проверка на ошибки.
  3185.  
  3186.     lua_close(L);
  3187.  
  3188.     return 0;
  3189. };
  3190.  
  3191.  
  3192. Модуль с. Писать модули для lua на c++.
  3193.  
  3194. int q(lua_State* L) {
  3195.     int d = lua_tonumber(L, -1);
  3196.     pushlua(L, d * 2);
  3197.     return 1; /*число умножено на 2*/
  3198. }
  3199. int foo(lua_State * L) {
  3200.     int d = lua_tonumber(L, -1);
  3201.     pushlua(L, d * 3);
  3202.     return 1; /*число умножено на 3*/
  3203. }
  3204.  struct luaL_Reg mylib[] = {
  3205.     { "q", q },{ "foo", foo }, { NULL, NULL } /*регистрация функций, на вершину отправим NULL NULL*/
  3206. };
  3207.  
  3208. int lua_lib(lua_State * L) {
  3209.     luaL_newlib(L, mylib);/*void luaL_newlib (lua_State * L, const luaL_Reg lib []); Создает новую таблицу и
  3210.       регистрирует там свои функции в списке lib. Это реализовано в виде следующего макроса:
  3211.   (luaL_newlibtable (L, lib), luaL_setfuncs (L, l, 0))
  3212.   Массив lib должен быть фактическим массивом, а не указателем на него.*/
  3213.   return 1;
  3214. }
  3215.  
  3216. int main(int argc, char* argv[]) {
  3217.     const char* LUA = R"(
  3218. mylib = require 'mylib'
  3219. print(mylib.q(2))
  3220. print(mylib.foo(2)) )";
  3221.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  3222.     luaL_openlibs(L);
  3223.  
  3224.     luaL_requiref(L, "mylib", lua_lib, 1);/* модуль. void luaL_requiref (lua_State * L, const char * modname,
  3225.  lua_CFunction cfunc, int glb); Если modname еще нет, package.loaded, вызывает функцию cfunc со строкой modname
  3226.  в качестве аргумента и устанавливает результат вызова package.loaded[modname], как если бы эта функция была вызвана
  3227.  require. Если glb это правда, также сохраняет модуль в глобальном modname. Оставляет копию модуля в стеке.*/
  3228.     checkerror(L, LUA);//Функция проверка на ошибки.
  3229.  
  3230.     return 0;
  3231. };
  3232.  
  3233.  
  3234. Реестр глобальная таблица.
  3235.  
  3236.  
  3237. int main(int argc, char* argv[]) {
  3238.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  3239.     luaL_openlibs(L);
  3240.    
  3241.     pushlua(L, 9);//отправить значение для ключа 12.  
  3242.     lua_rawseti(L, LUA_REGISTRYINDEX, 12);// отправить ключ в реестре. установить ключ со значение в реестр.
  3243.  
  3244.     lua_rawgeti(L, LUA_REGISTRYINDEX, 12);/* вернуть значение для ключа в реестр. */
  3245.     getlaststack(L);// 9
  3246.  
  3247.     lua_close(L);
  3248.  
  3249.     return 0;
  3250. };
  3251.  
  3252.  
  3253. Реестр передача значение между функциями.
  3254.  
  3255. int show(lua_State* L) {
  3256.     lua_rawgeti(L, LUA_REGISTRYINDEX, 12);/* вернуть значение для ключа в реестр. */
  3257.     getlaststack(L);// 100
  3258.     return 0;
  3259. };
  3260. int create(lua_State * L) {//   Функция создания объекта структуры.
  3261.     pushlua(L, 100);//отправить значение для ключа 12.
  3262.     lua_rawseti(L, LUA_REGISTRYINDEX, 12);// отправить ключ в реестре. установить ключ со значение в реестр.
  3263.     return 0;
  3264. };
  3265.  
  3266. int main(int argc, char* argv[]) {
  3267.     const char* LUA = R"(
  3268. create()
  3269. show()
  3270. )";
  3271.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  3272.     luaL_openlibs(L);
  3273.  
  3274.     lua_newtable(L);
  3275.     lua_pushcfunction(L, create);
  3276.     lua_setglobal(L, "create");// уст глоб имя в таблице как С функцию.
  3277.  
  3278.     lua_pushcfunction(L, show);
  3279.     lua_setglobal(L, "show");
  3280.  
  3281.     checkerror(L, LUA);//Функция проверка на ошибки.
  3282.  
  3283.     lua_close(L);
  3284.  
  3285.     return 0;
  3286. };
  3287.  
  3288.  
  3289. Реестр, отправка и получение значение по уникальному ключу. В качестве ключей ссылка на псевдоиндекс.
  3290.  
  3291.  
  3292. int main(int argc, char* argv[]) {
  3293.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  3294.     luaL_openlibs(L);
  3295.    
  3296.     int ref = luaL_ref(L, LUA_REGISTRYINDEX); /*Возвращает ссылку - это уникальный целочисленный ключ. Для значения в реестре*/
  3297.  
  3298.     pushlua(L, 9);//отправить значение для ключа ref. 
  3299.     lua_rawseti(L, LUA_REGISTRYINDEX, ref);// установить ключ со значение в реестр.
  3300.  
  3301.     pushlua(L, ref);
  3302.     lua_rawgeti(L, LUA_REGISTRYINDEX, ref);/* вернуть значение для ключа в реестр. */
  3303.     getlaststack(L);// 9
  3304.  
  3305.     lua_close(L);
  3306.  
  3307.     return 0;
  3308. };
  3309.  
  3310.  
  3311. Работа в реестр. Отправка значение переменной в реестр, получение из него.
  3312.  
  3313. int main(int argc, char* argv[]) {
  3314.     const char* LUA = R"(
  3315. x=4
  3316. )";
  3317.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  3318.     luaL_openlibs(L);
  3319.     checkerror(L, LUA);//Функция проверка на ошибки.
  3320.     lua_getglobal(L, "x");
  3321.     int ref = luaL_ref(L, LUA_REGISTRYINDEX); /*Создает и возвращает ссылку в таблице в индексе t для объекта на вершине стека(и извлекает объект).
  3322.     Ссылка - это уникальный целочисленный ключ. Пока вы не добавляете вручную целочисленные ключи в таблицу t, вы luaL_ref гарантируете уникальность возвращаемого ключа. Вы можете получить объект, на который ссылается ссылка r, вызывая lua_rawgeti(L, t, r).
  3323. Функция luaL_unref освобождает ссылку и связанный с ней объект.
  3324.     Если объект на вершине стека равен нулю, luaL_ref возвращает константу LUA_REFNIL. Константа LUA_NOREF
  3325. гарантированно будет отличаться от любой ссылки, возвращаемой luaL_ref.*/
  3326.  
  3327.  
  3328.     lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
  3329.     cout <<"x = "<< lua_tonumber(L, -1) << endl;
  3330.     lua_rawseti(L, LUA_REGISTRYINDEX, ref);/*
  3331.     Функции, которые API предоставляет для работы с массивами:
  3332.  
  3333.     void lua_rawgeti (lua_State * L, int index, int key);
  3334.     void lua_rawseti (lua_State * L, int index, int key); Описание lua_rawgeti и lua_rawseti немного сбивает с толку,
  3335.     поскольку включает в себя два индекса:
  3336.     index указывает, где таблица находится в стеке;
  3337.     key относится к тому, где элемент находится в таблице.
  3338.     Вызов lua_rawgeti(L, t, key) эквивалентен последовательности lua_pushnumber (L, ключ); lua_rawget (L, t);
  3339.  
  3340.     когда t положительно (в противном случае вы должны компенсировать новый элемент в стеке).
  3341.     Вызов lua_rawseti(L, t, key)(опять же для t положительного) эквивалентен
  3342.     lua_pushnumber (L, ключ);
  3343.     lua_insert (L, -2); // поставить `ключ 'ниже предыдущего значения
  3344.     lua_rawset (L, t); Обратите внимание, что обе функции используют необработанные операции.
  3345.     Они быстрее и, в любом случае, таблицы, используемые в качестве массивов, редко используют метаметоды.
  3346.      В качестве конкретного примера использования этих функций мы могли бы переписать тело цикла
  3347.      из нашей предыдущей l_dirфункции из
  3348.  
  3349.         lua_pushnumber (L, i ++); // ключ  /
  3350.         lua_pushstring (L, entry-> d_name); / значение /
  3351.     lua_settable(L, -3);
  3352.                                            */
  3353.     luaL_unref(L, LUA_REGISTRYINDEX, ref); // удалить значение по ключу ref.
  3354.     cout << lua_tonumber(L, -1) << endl;
  3355.  
  3356.     lua_close(L);
  3357.  
  3358.     return 0;
  3359. };
  3360.  
  3361.  
  3362. Выводится.
  3363.  
  3364. x = 4
  3365. 0
  3366.  
  3367. Вариант 2.
  3368.  
  3369. int main(int argc, char* argv[]) {
  3370.     const char* LUA = R"(
  3371. x=4
  3372. )";
  3373.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  3374.     luaL_openlibs(L);
  3375.     checkerror(L, LUA);//Функция проверка на ошибки.
  3376.     int ref = luaL_ref(L, LUA_REGISTRYINDEX); /*Создает и возвращает ссылку в таблице в индексе t для объекта на вершине стека(и извлекает объект).*/
  3377.  
  3378.     lua_getglobal(L, "x");
  3379.  
  3380.     lua_rawseti(L, LUA_REGISTRYINDEX, ref);/* установить в таблице*/
  3381.  
  3382.     lua_rawgeti(L, LUA_REGISTRYINDEX, ref);/* получить значение по ключу */
  3383.     cout << "x = " ;
  3384.     getlaststack(L);
  3385.  
  3386. //  luaL_unref(L, LUA_REGISTRYINDEX, ref); // удалить значение по ключу ref.
  3387.  
  3388.     lua_rawgeti(L, LUA_REGISTRYINDEX, ref);/*              */
  3389.     getlaststack(L);
  3390.  
  3391.     lua_close(L);
  3392.  
  3393.     return 0;
  3394. };
  3395.  
  3396.  
  3397. Уникальность ключа в реестре, обеспечивается адресом в памяти переменной.
  3398. Использовать lua_settable и lua_gettable.
  3399.  
  3400. int main(int argc, char* argv[]) {
  3401.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  3402.     luaL_openlibs(L);
  3403.     static char Key = 'k';// лучше стастик переменная.
  3404.  
  3405.     lua_pushlightuserdata(L, &Key);  /* отправить адрес памяти переменной в стек */
  3406.     lua_pushstring(L, &Key);  /* отправить значение в стек */
  3407.     lua_settable(L, LUA_REGISTRYINDEX);  /* уст ключа и значение таблице реестре.  */
  3408.  
  3409.     lua_pushlightuserdata(L, &Key);  /*отправить адрес, который является ключом в стек. */
  3410.     lua_gettable(L, LUA_REGISTRYINDEX);  /* получить таблицу и значение ключа будет в -1 */
  3411.     cout << lua_tostring(L, -1) << endl;// k
  3412.  
  3413.     lua_close(L);
  3414.     return 0;
  3415. };
  3416.  
  3417.  
  3418. Реестр способен хранить польз. данные, ключ может их адрес в пямяти.
  3419.  
  3420. int main(int argc, char* argv[]) {
  3421.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  3422.     luaL_openlibs(L);
  3423.  
  3424.     static char Key = 'k';// лучше стастик переменная.
  3425.  
  3426.     lua_pushlightuserdata(L, &Key);  /* отправить адресс в стек */
  3427.     lua_rawsetp(L, LUA_REGISTRYINDEX,  &Key);/* Имеет ли эквивалент t[k] = v, где t таблица,
  3428.  k указатель, представленный в виде легких пользовательских данных, и v значение в верхней части стека.
  3429.  Эта функция извлекает значение из стека. Не вызывает метаметоды.*/
  3430.    
  3431.     lua_pushlightuserdata(L, &Key);  /*отправить адресс, который является ключом в стек. */
  3432.     lua_rawgetp(L, LUA_REGISTRYINDEX, &Key); /* получить таблицу и значение ключа будет в -1 */
  3433.  
  3434.     char* k = (char*)lua_touserdata(L, -1);// получить польз.данные.
  3435.     cout << k <<" adress "<< &k << endl;// k.
  3436.    
  3437.     lua_close(L);
  3438.     return 0;
  3439. };
  3440.  
  3441. int main(int argc, char* argv[]) {
  3442.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  3443.     luaL_openlibs(L);
  3444.  
  3445.      int Key = 100;// лучше стастик переменная.
  3446.  
  3447.     lua_pushlightuserdata(L, &Key);  /* отправить адресс в стек */
  3448.     lua_rawsetp(L, LUA_REGISTRYINDEX, &Key);/* Имеет ли эквивалент t[k] = v, где t таблица,
  3449.  k указатель, представленный в виде легких пользовательских данных, и v значение в верхней части стека.
  3450.  Эта функция извлекает значение из стека. Не вызывает метаметоды.*/
  3451.  
  3452.     lua_pushlightuserdata(L, &Key);  /*отправить адресс, который является ключом в стек. */
  3453.     lua_rawgetp(L, LUA_REGISTRYINDEX, &Key); /* получить таблицу и значение ключа будет в -1 */
  3454.  
  3455.     int* k = (int*)lua_touserdata(L, -1);// получить польз.данные.
  3456.     cout << *k << " adress " << &k << endl;// 100.
  3457.  
  3458.     lua_close(L);
  3459.     return 0;
  3460. };
  3461.  
  3462. Реестр адрес переменной k ключ.
  3463.  
  3464. int main(int argc, char* argv[]) {
  3465.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  3466.     luaL_openlibs(L);
  3467.     static char k = 'key';// лучше стастик переменная она выступает ключом в реестре.
  3468.  
  3469.     int i = 5;
  3470.     lua_pushlightuserdata(L, &i);  /* отправить адрес памяти числа 5 в стек */
  3471.     lua_rawsetp(L, LUA_REGISTRYINDEX, &k);  /* уст ключ в реестре адрес k.
  3472.  void lua_rawsetp (lua_State * L, int index, const void * p);  Записывает ли эквивалент t[p] = v,
  3473. где t таблица с заданным индексом, p как легкие пользовательские данные и v является значением в верхней части стека.
  3474.  
  3475. Эта функция извлекает значение из стека. Назначение является необработанным,  */
  3476.  
  3477.     lua_pushlightuserdata(L, &i);  /*отправить адрес памяти, который является ключом в стек.*/
  3478.  
  3479.     lua_rawgetp(L, LUA_REGISTRYINDEX, &k);/* получить значение по ключу адрес k*/
  3480.     int* number = (int*)lua_touserdata(L, -1);// получить польз.данные.
  3481.  
  3482.     cout << *number << " adress " << number << endl;// 5.
  3483.  
  3484.  
  3485.     lua_close(L);
  3486.     return 0;
  3487. };
  3488.  
  3489. Реестр. Передача значение из функции в ключ возвращаемой таблицы.
  3490.  
  3491. int show(lua_State* L) {
  3492.     luaL_getmetatable(L, "mt"); /* получить метатаблицу.*/
  3493.     lua_pushstring(L, "key");//отправить key, чтобы получить ref
  3494.     lua_gettable(L, -2);
  3495.     int ref = lua_tonumber(L, -1);
  3496.     lua_rawgeti(L, LUA_REGISTRYINDEX, ref);/* получить значение по ключу ref.*/
  3497.  
  3498.     getlaststack(L);
  3499.     return 0;
  3500. };
  3501. int create(lua_State * L) {//   Функция создания объекта структуры.
  3502.     lua_gettable(L, -3);// получить глоб. таблицу.
  3503.     luaL_newmetatable(L, "mt");// создать мета таблицу.
  3504.     lua_pushcfunction(L, show);
  3505.     lua_setfield(L, -2, "show");// ключ таблицы является функцией.  
  3506.     int ref = luaL_ref(L, LUA_REGISTRYINDEX);// получить уникальный ключ.
  3507.     pushlua(L, 5);// значение для ключа. mt.ref = 5.
  3508.     lua_rawseti(L, LUA_REGISTRYINDEX, ref); /* уст ключ со значением 5 в реестре адрес. */
  3509.  
  3510.     lua_setmetatable(L, -2); //уст метатаблицу.
  3511.  
  3512.     lua_gettable(L, -2);// получить таблицу.
  3513.     luaL_getmetatable(L, "mt"); /* получить метатаблицу.*/
  3514.  
  3515.     lua_pushstring(L, "key");// это ключ для получение ref.
  3516.     lua_pushnumber(L, ref);
  3517.     lua_rawset(L, -3);
  3518.  
  3519.     luaL_getmetatable(L, "mt"); /* получить метатаблицу.*/
  3520.     return 1;
  3521. };
  3522.  
  3523. int main(int argc, char* argv[]) {
  3524.     const char* LUA = R"(
  3525. a = create()
  3526. a.show()
  3527. )";
  3528.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  3529.     luaL_openlibs(L);
  3530.  
  3531.     lua_newtable(L);
  3532.     lua_pushcfunction(L, create);
  3533.     lua_setglobal(L, "create");// уст глоб имя в таблице как С функцию.
  3534.  
  3535.  
  3536.     checkerror(L, LUA);//Функция проверка на ошибки.
  3537.  
  3538.     lua_close(L);
  3539.  
  3540.     return 0;
  3541. };
  3542.  
  3543. Реестр. Передача числа из функции в ключ возвращаемой таблицы с помощью мета таблицы.
  3544.  
  3545. int show(lua_State* L) {
  3546.     luaL_getmetatable(L, "mt"); /* получить метатаблицу.*/
  3547.     lua_pushstring(L, "key");//отправить key, чтобы получить ref
  3548.     lua_gettable(L, -2);
  3549.     int ref = lua_tonumber(L, -1);
  3550.     lua_rawgeti(L, LUA_REGISTRYINDEX, ref);/* получить значение по ключу ref.*/
  3551.  
  3552.     getlaststack(L);
  3553.     return 0;
  3554. };
  3555. int create(lua_State * L) {//  
  3556.     int k = lua_tointeger(L, -1);
  3557.     lua_gettable(L, -4);// получить глоб. таблицу.
  3558.     luaL_newmetatable(L, "mt");// создать мета таблицу.
  3559.     lua_pushcfunction(L, show);
  3560.     lua_setfield(L, -2, "show");// ключ таблицы является функцией.  
  3561.     int ref = luaL_ref(L, LUA_REGISTRYINDEX);// получить уникальный ключ.
  3562.  
  3563.     pushlua(L, k);// значение для ключа. mt.ref = 5.
  3564.     lua_rawseti(L, LUA_REGISTRYINDEX, ref); /* уст ключ со значением 5 в реестре адрес. */
  3565.  
  3566.     lua_setmetatable(L, -2); //уст метатаблицу.
  3567.  
  3568.     lua_gettable(L, -3);// получить таблицу.
  3569.     luaL_getmetatable(L, "mt"); /* получить метатаблицу.*/
  3570.  
  3571.     lua_pushstring(L, "key");// это ключ для получение ref.
  3572.     lua_pushnumber(L, ref);
  3573.     lua_rawset(L, -3);
  3574.  
  3575.     luaL_getmetatable(L, "mt"); /* получить метатаблицу.*/
  3576.     return 1;
  3577. };
  3578.  
  3579. int main(int argc, char* argv[]) {
  3580.     const char* LUA = R"(
  3581. a = create(6)
  3582. a.show()
  3583. )";
  3584.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  3585.     luaL_openlibs(L);
  3586.  
  3587.     lua_newtable(L);
  3588.     lua_pushcfunction(L, create);
  3589.     lua_setglobal(L, "create");// уст глоб имя в таблице как С функцию.
  3590.  
  3591.  
  3592.     checkerror(L, LUA);//Функция проверка на ошибки.
  3593.  
  3594.     lua_close(L);
  3595.  
  3596.     return 0;
  3597. };
  3598.  
  3599.  
  3600. Реестр хранить мета таблицу с польз.данными.
  3601.  
  3602. int main(int argc, char* argv[]) {
  3603.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  3604.     luaL_openlibs(L);
  3605.  
  3606.     luaL_newmetatable(L, "mt");// создать мета таблицу.
  3607.     luaL_getmetatable(L, "mt"); /* получить метатаблицу.*/
  3608.  
  3609.     lua_pushstring(L, "key");// это ключ для получение 5.
  3610.  
  3611.     a** c = (a * *)lua_newuserdata(L, sizeof(a*));/*Эта функция выделяет новый блок памяти с заданным размером,*/
  3612.     *c = new a();
  3613.  
  3614.     lua_rawsetp(L, LUA_REGISTRYINDEX, "mt");  /* уст ключ в реестре адрес k.  */
  3615.    
  3616.  
  3617.     lua_pushstring(L, "key");// это ключ для получение объекта.*/
  3618.     lua_rawgetp(L, LUA_REGISTRYINDEX, "mt");/* получить значение по ключу key объект*/
  3619.    
  3620.     a** st = (a** )lua_touserdata(L, -1);// получаем польз. данные.
  3621.     a * b = &**st;
  3622.     b->show();// вызов метода.  
  3623.  
  3624.     b->~a();//вызов метода деструктор.
  3625.  
  3626.     lua_close(L);
  3627.     return 0;
  3628. };
  3629.  
  3630. Реестр и метатаблицы, реализация ооп через таблицу с функциями.
  3631.  
  3632. struct a {  int x = 10;
  3633.     a() { cout << "create object " << this << endl; }//конструктор по умолчанию
  3634.  
  3635.     void show() { cout << "\nobject - " << this << "\tx = " << x << "\n\n"; }//вывести значение x на экран.
  3636.  
  3637.     ~a() { cout << "destory object " << this << endl << endl; }//вызов деструктора.
  3638. };
  3639.  
  3640.  
  3641. int destroy(lua_State* L) {// Функция вызывает деструктор для объекта.
  3642.     lua_pushstring(L, "key");// это ключ для получение объекта.*/
  3643.     lua_rawgetp(L, LUA_REGISTRYINDEX, "mt");/* получить значение (объект) по ключу key */
  3644.     a** st = (a * *)lua_touserdata(L, -1);// получаем польз. данные.
  3645.     a * b = &**st;
  3646.     b->~a();//вызов метода деструктор.
  3647.     return 0;
  3648. };
  3649.  
  3650. int show(lua_State * L) {
  3651.     lua_pushstring(L, "key");// это ключ для получение объекта.*/
  3652.     lua_rawgetp(L, LUA_REGISTRYINDEX, "mt");/* получить значение (объект) по ключу key */
  3653.     a** st = (a * *)lua_touserdata(L, -1);// получаем польз. данные.
  3654.     a * b = &**st;
  3655.     b->show();// вызов метода.  
  3656.     return 0;
  3657. };
  3658. int create(lua_State * L) {//   Функция создания объекта структуры.
  3659.     lua_newtable(L);
  3660.     luaL_newmetatable(L, "mt");// создать мета таблицу.
  3661.     lua_pushcfunction(L, destroy);
  3662.     lua_setfield(L, -2, "__gc");
  3663.  
  3664.     lua_pushstring(L, "key");// это ключ для получение объекта.
  3665.  
  3666.     a** c = (a * *)lua_newuserdata(L, sizeof(a*));/*Эта функция выделяет новый блок памяти с заданным размером,*/
  3667.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  3668.     *c = new a();
  3669.     lua_setmetatable(L, -2); //получает таблицу из стека и уст ее в качестве новой метатаблицы для значения с заданным допустимым индексом.
  3670.  
  3671.     lua_rawsetp(L, LUA_REGISTRYINDEX, "mt");  /* уст ключ в реестре адрес k.  */
  3672.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  3673.     lua_pushcfunction(L, show);
  3674.     lua_setfield(L, -2, "show");
  3675.  
  3676.     return 1;
  3677. };
  3678.  
  3679. int main(int argc, char* argv[]) {
  3680.     const char* LUA = R"(
  3681.  
  3682. a = create()
  3683. a.show()
  3684.  
  3685. )";
  3686.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  3687.     luaL_openlibs(L);
  3688.  
  3689.     lua_pushcfunction(L, create);
  3690.     lua_setglobal(L, "create");//уст указатель на функцию C++ и создает внутри Lua
  3691.  
  3692.     checkerror(L, LUA);//Функция проверка на ошибки.
  3693.  
  3694.     lua_close(L);
  3695.  
  3696.     return 0;
  3697. };
  3698.  
  3699.  
  3700. Метатаблица, передача значение между функциями.
  3701.  
  3702.  
  3703. int show(lua_State* L) {
  3704.     luaL_getmetatable(L, "mt"); /* получить метатаблицу.*/
  3705.     lua_pushstring(L, "key");//отправить key, чтобы получить ref
  3706.     lua_gettable(L, -2);
  3707.     cout << lua_tonumber(L, -1) << " == 5" << endl;//должно быть 5.
  3708.     return 0;
  3709. };
  3710. int create(lua_State * L) {//   Функция создания объекта структуры.
  3711.     luaL_newmetatable(L, "mt");// создать мета таблицу.
  3712.     luaL_getmetatable(L, "mt"); /* получить метатаблицу.*/
  3713.  
  3714.     lua_pushstring(L, "key");// это ключ для получение 5.
  3715.     lua_pushnumber(L, 5);// значение ключа key это 5.
  3716.     lua_settable(L, -3);// установить таблицу.
  3717.     return 1;
  3718. };
  3719.  
  3720. int main(int argc, char* argv[]) {
  3721.     const char* LUA = R"(
  3722. create()
  3723. show()
  3724. )";
  3725.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  3726.     luaL_openlibs(L);
  3727.  
  3728.     lua_newtable(L);
  3729.     lua_pushcfunction(L, create);
  3730.     lua_setglobal(L, "create");// уст глоб имя в таблице как С функцию.
  3731.  
  3732.     lua_pushcfunction(L, show);
  3733.     lua_setglobal(L, "show");
  3734.  
  3735.     checkerror(L, LUA);//Функция проверка на ошибки.
  3736.  
  3737.     lua_close(L);
  3738.  
  3739.     return 0;
  3740. };
  3741.  
  3742.  
  3743. Метатаблица, передача польз.данных(объекта структуры) между функциями.
  3744.  
  3745.  
  3746. struct a {
  3747.     int x = 10;
  3748.     a() { cout << "create object " << this << endl; }//конструктор по умолчанию
  3749.  
  3750.     void show() { cout << "\nobject - " << this << "\tx = " << x << "\n\n"; }//вывести значение x на экран.
  3751.  
  3752.     ~a() { cout << "destory object " << this << endl << endl; }//вызов деструктора.
  3753. };
  3754.  
  3755. int destroy(lua_State* L) {// Функция вызывает деструктор для объекта.
  3756.     cout << "destroy " << endl;
  3757.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  3758.     a** st = (a * *)lua_touserdata(L, -2); // получаем польз. данные.
  3759.     a * b = &**st;
  3760.     b->~a();//вызов метода деструктор.
  3761.     return 0;
  3762.  
  3763. };
  3764.  
  3765. int show(lua_State* L) {
  3766.     luaL_getmetatable(L, "mt"); /* получить метатаблицу.*/
  3767.     lua_pushstring(L, "key");//отправить key, чтобы получить объект.
  3768.     lua_gettable(L, -2);   
  3769.     a** st = (a * *)lua_touserdata(L, -1);// получаем польз. данные.
  3770.     a * b = &**st;
  3771.     b->show();// вызов метода.  
  3772.     b->~a();//вызов метода деструктор.
  3773.  
  3774.     return 0;
  3775. };
  3776. int create(lua_State * L) {//   Функция создания объекта структуры.
  3777.     luaL_newmetatable(L, "mt");// создать мета таблицу.
  3778.     luaL_getmetatable(L, "mt"); /* получить метатаблицу.*/
  3779.  
  3780.     lua_pushstring(L, "key");// это ключ для получение 5.
  3781.  
  3782.     a** c = (a **)lua_newuserdata(L, sizeof(a*));/*Эта функция выделяет новый блок памяти с заданным размером,*/
  3783.     *c = new a();
  3784.  
  3785.     lua_settable(L, -3);// установить таблицу.
  3786.     return 1;
  3787. };
  3788.  
  3789. int main(int argc, char* argv[]) {
  3790.     const char* LUA = R"(
  3791. create()
  3792. show()
  3793. )";
  3794.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  3795.     luaL_openlibs(L);
  3796.  
  3797.     lua_newtable(L);
  3798.     lua_pushcfunction(L, create);
  3799.     lua_setglobal(L, "create");// уст глоб имя в таблице как С функцию.
  3800.  
  3801.     lua_pushcfunction(L, show);
  3802.     lua_setglobal(L, "show");
  3803.  
  3804.     checkerror(L, LUA);//Функция проверка на ошибки.
  3805.  
  3806.     lua_close(L);
  3807.  
  3808.     return 0;
  3809. };
  3810.  
  3811.  
  3812.  
  3813.  
  3814.  
  3815.  
  3816.  
  3817.  
  3818.  
  3819. int destroy(lua_State* L) {// Функция вызывает деструктор для объекта.
  3820.     cout << "destroy " << endl;
  3821.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  3822.     a** st = (a * *)lua_touserdata(L, -2); // получаем польз. данные.
  3823.     a *b = &**st;
  3824.  
  3825.     b->~a();//вызов метода деструктор.
  3826.     return 0;
  3827.  
  3828. };
  3829.  
  3830. int show(lua_State * L) {
  3831.  
  3832.     cout << "show " << endl;
  3833.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/ 
  3834.     cout << lua_type(L,-2) << endl;
  3835.     //a** st = (a * *)lua_touserdata(L, -2);// получаем польз. данные.
  3836.     //a * b = &**st;
  3837.     //b->show();// вызов метода.
  3838.     return 0;
  3839. };
  3840.     //lua_newtable(L);
  3841.     //luaL_newmetatable(L, "mt");// создать мета таблицу.
  3842.     //pushlua(L, "__gc");
  3843.     //lua_pushcfunction(L, destroy);
  3844.     //lua_settable(L, -3); //получает таблицу из стека и уст ее в качестве новой метатаблицы для значения с заданным допустимым индексом.
  3845.  
  3846. int create(lua_State* L) {//    Функция создания объекта структуры.
  3847.     lua_newtable(L);
  3848.     luaL_newmetatable(L, "mt");// создать мета таблицу.
  3849.     lua_pushcfunction(L, destroy);
  3850.     lua_setfield(L, -2, "__gc");
  3851.    
  3852.     a** c = (a * *)lua_newuserdata(L, sizeof(a*));/*Эта функция выделяет новый блок памяти с заданным размером,*/
  3853.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  3854.     *c = new a();
  3855.     lua_setmetatable(L, -2); //получает таблицу из стека и уст ее в качестве новой метатаблицы для значения с заданным допустимым индексом.
  3856.  
  3857.     lua_gettable(L, -3);
  3858.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  3859.  
  3860.    lua_pushcfunction(L, show);
  3861.     lua_setfield(L, -2, "show");
  3862.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  3863.  
  3864.     return 1;
  3865. };
  3866.  
  3867. int main(int argc, char* argv[]) {
  3868. const char* LUA = R"(
  3869.  
  3870. a= create()
  3871. a.show()
  3872.  
  3873. )";
  3874.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  3875.     luaL_openlibs(L);
  3876.    
  3877.     lua_pushcfunction(L, create);
  3878.     lua_setglobal(L, "create");//уст указатель на функцию C++ и создает внутри Lua
  3879.  
  3880.     checkerror(L, LUA);//Функция проверка на ошибки.
  3881.  
  3882.     lua_close(L);
  3883.  
  3884.     return 0;
  3885. };
  3886.  
  3887.  
  3888.  
  3889. По указателю.
  3890. int destroy(lua_State* L) {// Функция вызывает деструктор для объекта.
  3891.     cout << "destroy " << endl;
  3892.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  3893.     a* st = (a* )lua_touserdata(L, -2); // получаем польз. данные.
  3894.  
  3895.     st->~a();//вызов метода деструктор.
  3896.     return 0;
  3897. };
  3898.  
  3899. int create(lua_State * L) {//   Функция создания объекта структуры.
  3900.     lua_newtable(L);
  3901.     luaL_newmetatable(L, "mt");// создать мета таблицу.
  3902.     pushlua(L, "__gc");
  3903.     lua_pushcfunction(L, destroy);
  3904.     lua_settable(L, -3); //получает таблицу из стека и уст ее в качестве новой метатаблицы для значения с заданным допустимым индексом.
  3905.  
  3906.  
  3907.     a* c = (a *)lua_newuserdata(L, sizeof(a));/*Эта функция выделяет новый блок памяти с заданным размером,*/
  3908.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  3909.     c = new a();
  3910.     lua_setmetatable(L, -2); //получает таблицу из стека и уст ее в качестве новой метатаблицы для значения с заданным допустимым индексом.
  3911.  
  3912.     return 1;
  3913. };
  3914.  
  3915.  
  3916. Через реестр.
  3917.  
  3918. struct a {
  3919.     int x = 10;
  3920.     a() { cout << "create object " << this << endl; }//конструктор по умолчанию
  3921.  
  3922.     void show() { cout << "\nobject - " << this << "\tx = " << x << "\n\n"; }//вывести значение x на экран.
  3923.  
  3924.     ~a() { cout << "destory object " << this << endl << endl; }//вызов деструктора.
  3925. };
  3926.  
  3927. int destroy(lua_State* L) {// Функция вызывает деструктор для объекта.
  3928.     cout << "destroy " << endl;
  3929.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  3930.     a** st = (a * *)lua_touserdata(L, -2); // получаем польз. данные.
  3931.     a *b = &**st;
  3932.  
  3933.     b->~a();//вызов метода деструктор.
  3934.  
  3935.  
  3936.     return 0;
  3937.  
  3938. };
  3939.  
  3940. int show(lua_State * L) {
  3941.  
  3942. luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/ 
  3943.  
  3944.     lua_pushstring(L, "key");
  3945.     lua_gettable(L, -2);
  3946.     cout << lua_tonumber(L, -1)<<"ref \n";
  3947.     int ref = 3;
  3948.     pushlua(L, ref);
  3949.     lua_rawgetp(L, LUA_REGISTRYINDEX, &ref);/* получить значение по ключу адрес k*/
  3950.  
  3951.     //getlaststack(L);
  3952. cout << lua_type(L,-1) << endl;
  3953. //  a** st = (a * *)lua_touserdata(L, -1);// получаем польз. данные.
  3954. //  a * b = &**st;
  3955. //  b->show();// вызов метода.  
  3956.     return 0;
  3957. };
  3958. int create(lua_State* L) {//    Функция создания объекта структуры.
  3959.     lua_gettable(L, -3);
  3960.     luaL_newmetatable(L, "mt");// создать мета таблицу.
  3961.     lua_pushcfunction(L, destroy);
  3962.     lua_setfield(L, -2, "__gc");
  3963.    
  3964.     lua_pushcfunction(L, show);
  3965.     lua_setfield(L, -2, "show");
  3966.     int ref = luaL_ref(L, LUA_REGISTRYINDEX);
  3967.  
  3968.     //luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  3969.     a** c = (a * *)lua_newuserdata(L, sizeof(a*));/*Эта функция выделяет новый блок памяти с заданным размером,*/
  3970.     *c = new a();
  3971.     lua_rawsetp(L, LUA_REGISTRYINDEX, &ref);  /* уст ключ в реестре адрес k.  */
  3972.  
  3973.     lua_setmetatable(L, -2); //получает таблицу из стека и уст ее в качестве новой метатаблицы для значения с заданным допустимым индексом.
  3974.  
  3975.     lua_gettable(L, -2);
  3976.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  3977.  
  3978.     lua_pushcfunction(L, show);
  3979.     lua_setfield(L, -2, "show");
  3980.     lua_pushstring(L, "key");
  3981.     lua_pushnumber(L, ref);
  3982.     lua_rawset(L, -3);
  3983.  
  3984.     cout << ref<<" kkmj\n";
  3985.  
  3986.     luaL_getmetatable(L, "mt"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  3987.     return 1;
  3988. };
  3989.  
  3990. int main(int argc, char* argv[]) {
  3991. const char* LUA = R"(
  3992.  
  3993. a= create()
  3994. a.show()
  3995.  
  3996. )";
  3997.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  3998.     luaL_openlibs(L);
  3999.  
  4000.     lua_newtable(L);
  4001.     lua_pushcfunction(L, create);
  4002.     lua_setglobal(L, "create");//уст указатель на функцию C++ и создает внутри Lua
  4003.  
  4004.     checkerror(L, LUA);//Функция проверка на ошибки.
  4005.  
  4006.     lua_close(L);
  4007.  
  4008.     return 0;
  4009. };
  4010.  
  4011. Реестр. Передача значение между функциями через метатаблицу.
  4012.  
  4013. int show(lua_State * L) {
  4014.     luaL_getmetatable(L, "mt"); /* получить метатаблицу.*/
  4015.     lua_pushstring(L, "key");//отправить key, чтобы получить ref
  4016.     lua_gettable(L, -2);
  4017.     int ref = lua_tonumber(L, -1);
  4018.     lua_rawgetp(L, LUA_REGISTRYINDEX, &ref);/* получить значение по ключу ref.*/
  4019.     cout << lua_tonumber(L, -1) << " value 5" << endl;//должно быть 5.
  4020.     return 0;
  4021. };
  4022. int create(lua_State * L) {//   Функция создания объекта структуры.
  4023.     lua_gettable(L, -3);// получить глоб. таблицу.
  4024.     luaL_newmetatable(L, "mt");// создать мета таблицу.
  4025.     int ref = luaL_ref(L, LUA_REGISTRYINDEX);// получить уникальный ключ.
  4026.     pushlua(L, 5);// отправить значение для ключа. mt.ref = 5.
  4027.     lua_rawsetp(L, LUA_REGISTRYINDEX, &ref); /* уст ключ со значением 5 в реестре адрес. */
  4028.  
  4029.     lua_pushstring(L, "key");// это ключ для получение ref.
  4030.     lua_pushnumber(L, ref);
  4031.  
  4032.     lua_setmetatable(L, -2); //уст метатаблицу.
  4033.     luaL_getmetatable(L, "mt"); /* получить метатаблицу.*/
  4034.     return 1;
  4035. };
  4036.  
  4037. int main(int argc, char* argv[]) { 
  4038.     const char* LUA = R"(
  4039. create()
  4040. show()
  4041. )";
  4042.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  4043.     luaL_openlibs(L);
  4044.  
  4045.     lua_newtable(L);
  4046.     lua_pushcfunction(L, create);
  4047.     lua_setglobal(L, "create");// уст глоб имя в таблице как С функцию.
  4048.    
  4049.     lua_pushcfunction(L, show);
  4050.     lua_setglobal(L, "show");
  4051.  
  4052.     checkerror(L, LUA);//Функция проверка на ошибки.
  4053.  
  4054.     lua_close(L);
  4055.  
  4056.     return 0;
  4057. };
  4058.  
  4059. Выводится.
  4060. 5 value 5
  4061.  
  4062. C:\Users\e\source\repos\Project1luaapi\Debug\Project1luaapi.exe (процесс 2764) завершает работу с кодом 0.
  4063. Чтобы закрыть это окно, нажмите любую клавишу…
  4064.  
  4065. Реестр. Передача в функцию числа, возвращаем из другой функции.
  4066.  
  4067. int show(lua_State* L) {
  4068.     luaL_getmetatable(L, "mt"); /* получить метатаблицу.*/
  4069.    
  4070.     pushlua(L, "key");
  4071.     lua_gettable(L, -2);
  4072.     int ref = lua_tonumber(L, -1);
  4073.     cout << "in func show regis key " << ref  << endl;
  4074.     lua_rawgetp(L, LUA_REGISTRYINDEX, &ref);/* получить значение по ключу ref.*/
  4075.  
  4076.     cout << lua_tonumber(L, -1) << " value 5" << endl;//должно быть 5.
  4077.     return 0;
  4078. };
  4079. int create(lua_State * L) {//   Функция создания объекта структуры.
  4080.     int k = lua_tonumber(L, -1);
  4081.     cout << k << endl;// 5
  4082.     int ref = luaL_ref(L, LUA_REGISTRYINDEX);// получить уникальный ключ.
  4083.     cout <<"in func create regis key " << ref  << endl;
  4084.    
  4085.     luaL_newmetatable(L, "mt");// создать мета таблицу.
  4086.     luaL_getmetatable(L, "mt"); /* получить метатаблицу.*/
  4087.     lua_gettable(L, -2);// получить глоб. таблицу.
  4088.     pushlua(L, k);// значение для ключа. mt.ref = 5.
  4089.     lua_rawsetp(L, LUA_REGISTRYINDEX, &k); /* уст ключ со значением 5 в реестре адрес. */
  4090.     lua_setmetatable(L, -2); //уст метатаблицу.
  4091.     luaL_getmetatable(L, "mt"); /* получить метатаблицу.*/
  4092.     pushlua(L, "key");// это ключ для получение ref.
  4093.     pushlua(L, ref);
  4094.     lua_settable(L, -3);
  4095. return 1;
  4096. };
  4097.  
  4098. int main(int argc, char* argv[]) {
  4099.     const char* LUA = R"(
  4100. create(5)
  4101. show()
  4102. )";
  4103.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  4104.     luaL_openlibs(L);
  4105.  
  4106.     lua_newtable(L);
  4107.     lua_pushcfunction(L, create);
  4108.     lua_setglobal(L, "create");// уст глоб имя в таблице как С функцию.
  4109.  
  4110.     lua_pushcfunction(L, show);
  4111.     lua_setglobal(L, "show");
  4112.  
  4113.     checkerror(L, LUA);//Функция проверка на ошибки.
  4114.  
  4115.     lua_close(L);
  4116.  
  4117.     return 0;
  4118. };
  4119. Выводится.
  4120. 5
  4121. in func create regis key 3
  4122. in func show regis key 3
  4123. 5 value 5
  4124.  
  4125. C:\Users\e\source\repos\Project1luaapi\Debug\Project1luaapi.exe (процесс 5912) завершает работу с кодом 0.
  4126. Чтобы закрыть это окно, нажмите любую клавишу…
  4127.  
  4128.  
  4129. test1.lua
  4130. x = 1
  4131. function hi()
  4132.     print("hi1");
  4133.     print(x);
  4134. end
  4135. hi()
  4136. test2.lua
  4137. x =2
  4138. function hi()
  4139.     print("hi2");
  4140.     print(x);
  4141. end
  4142. hi()
  4143.  
  4144.  
  4145. int main(int argc, char *argv[]) {
  4146.  
  4147.     lua_State* L = luaL_newstate();
  4148.     luaL_openlibs(L);
  4149.  
  4150.     const char* file1 = "test1.lua";
  4151.     const char* file2 = "test2.lua";
  4152.  
  4153.     //We load the file
  4154.     luaL_loadfile(L, file1);
  4155.     //Create _ENV tables
  4156.     lua_newtable(L);
  4157.     //Create metatable
  4158.     lua_newtable(L);
  4159.     //Get the global table
  4160.     lua_getglobal(L, "_G");
  4161.     lua_setfield(L, -2, "__index");
  4162.     //Set global as the metatable
  4163.     lua_setmetatable(L, -2);
  4164.     //Push to registry with a unique name.
  4165.     //I feel like these 2 steps could be merged or replaced but I'm not sure how
  4166.     lua_setfield(L, LUA_REGISTRYINDEX, "test1");
  4167.     //Retrieve it.
  4168.     lua_getfield(L, LUA_REGISTRYINDEX, "test1");
  4169.     //Set the upvalue (_ENV)
  4170.     lua_setupvalue(L, 1, 1);
  4171.     //Run chunks
  4172.     lua_pcall(L, 0, LUA_MULTRET, 0);
  4173.  
  4174.     //Repeat
  4175.     luaL_loadfile(L, file2);
  4176.     lua_newtable(L);
  4177.     lua_newtable(L);
  4178.     lua_getglobal(L, "_G");
  4179.     lua_setfield(L, -2, "__index");
  4180.     lua_setmetatable(L, -2);
  4181.     lua_setfield(L, LUA_REGISTRYINDEX, "test2");
  4182.     lua_getfield(L, LUA_REGISTRYINDEX, "test2");
  4183.     lua_setupvalue(L, 1, 1);
  4184.     lua_pcall(L, 0, LUA_MULTRET, 0);
  4185.  
  4186.     //Retrieve the table containing the functions of the chunk
  4187.     lua_getfield(L, LUA_REGISTRYINDEX, "test1");
  4188.     //Get the function we want to call
  4189.     lua_getfield(L, -1, "hi");
  4190.     //Call it
  4191.     lua_call(L, 0, 0);
  4192.     //Repeat
  4193.     lua_getfield(L, LUA_REGISTRYINDEX, "test2");
  4194.     lua_getfield(L, -1, "hi");
  4195.     lua_call(L, 0, 0);
  4196.     lua_getfield(L, LUA_REGISTRYINDEX, "test2");
  4197.     lua_getfield(L, -1, "hi");
  4198.     lua_call(L, 0, 0);
  4199.     lua_getfield(L, LUA_REGISTRYINDEX, "test1");
  4200.     lua_getfield(L, -1, "hi");
  4201.     lua_call(L, 0, 0);
  4202.  
  4203.  
  4204.     lua_close(L);// закрыть состояние
  4205.     cin.get();//ожидает ввода символа программа завершается.
  4206.  
  4207.     return 0;
  4208. }
  4209.  
  4210.  
  4211. Замыкание.
  4212.  
  4213. struct Sprite
  4214.     {
  4215.         int x;
  4216.         int y;
  4217.  
  4218.         Sprite() : x(0), y(0) {}
  4219.         ~Sprite() {}
  4220.  
  4221.         void Move(int velX, int velY)
  4222.         {
  4223.             x += velX;
  4224.             y += velY;
  4225.         }
  4226.  
  4227.         void Draw()
  4228.         {
  4229.             printf("sprite(%p): x = %d, y = %d\n", this, x, y);
  4230.         }
  4231.     };
  4232.  
  4233.     struct SpriteManager
  4234.     {
  4235.         std::vector<Sprite*> m_sprites;
  4236.         int numberOfSpritesExisting = 0;
  4237.         int numberOfSpritesMade = 0;
  4238.  
  4239.         void LookAfterSprite(Sprite* sprite)
  4240.         {
  4241.             numberOfSpritesExisting++;
  4242.             numberOfSpritesMade++;
  4243.             m_sprites.push_back(sprite);
  4244.         }
  4245.  
  4246.         void ForgetSprite(Sprite* sprite)
  4247.         {
  4248.             int i = 0;
  4249.             for (auto& s : m_sprites)
  4250.             {
  4251.                 if (s == sprite)
  4252.                 {
  4253.                     numberOfSpritesExisting--;
  4254.                     m_sprites.erase(m_sprites.begin() + i);
  4255.                     return;
  4256.                 }
  4257.                 i++;
  4258.             }
  4259.         }
  4260.     };
  4261.  
  4262.     SpriteManager spriteManager;
  4263.  
  4264.     int CreateSprite(lua_State* L){
  4265.         SpriteManager* sm = (SpriteManager*)lua_touserdata(L, lua_upvalueindex(1));
  4266.         lua_assert(sm);
  4267.  
  4268.         void* pointerToASprite = lua_newuserdata(L, sizeof(Sprite));
  4269.         new (pointerToASprite) Sprite();
  4270.         luaL_getmetatable(L, "SpriteMetaTable");
  4271.         lua_assert(lua_istable(L, -1));
  4272.         lua_setmetatable(L, -2);
  4273.  
  4274.         lua_newtable(L);
  4275.         lua_setuservalue(L, 1);
  4276.  
  4277.         sm->LookAfterSprite((Sprite*)pointerToASprite);
  4278.  
  4279.         return 1;
  4280.     };
  4281.  
  4282.     int DestroySprite(lua_State* L){
  4283.         SpriteManager* sm = (SpriteManager*)lua_touserdata(L, lua_upvalueindex(1));
  4284.         lua_assert(sm);
  4285.  
  4286.         Sprite* sprite = (Sprite*)lua_touserdata(L, -1);
  4287.         sm->ForgetSprite(sprite);
  4288.         sprite->~Sprite();
  4289.         return 0;
  4290.     };
  4291.  
  4292.     int MoveSprite(lua_State* L){
  4293.         Sprite* sprite = (Sprite*)lua_touserdata(L, -3);
  4294.         lua_Number velX = lua_tonumber(L, -2);
  4295.         lua_Number velY = lua_tonumber(L, -1);
  4296.         sprite->Move((int)velX, (int)velY);
  4297.         return 0;
  4298.     };
  4299.  
  4300.     int DrawSprite(lua_State* L){
  4301.         Sprite* sprite = (Sprite*)lua_touserdata(L, -1);
  4302.         sprite->Draw();
  4303.         return 0;
  4304.     };
  4305.  
  4306.     int SpriteIndex(lua_State* L){
  4307.         lua_assert(lua_isuserdata(L, -2));  //1
  4308.         lua_assert(lua_isstring(L, -1));    //2
  4309.  
  4310.         Sprite* sprite = (Sprite*)lua_touserdata(L, -2);
  4311.         const char* index = lua_tostring(L, -1);
  4312.         if (strcmp(index, "x") == 0)
  4313.         {
  4314.             lua_pushnumber(L, sprite->x);
  4315.             return 1;
  4316.         }
  4317.         else if (strcmp(index, "y") == 0)
  4318.         {
  4319.             lua_pushnumber(L, sprite->y);
  4320.             return 1;
  4321.         }
  4322.         else
  4323.         {
  4324.             lua_getuservalue(L, 1);
  4325.             lua_pushvalue(L, 2);
  4326.             lua_gettable(L, -2);
  4327.             if (lua_isnil(L, -1))
  4328.             {
  4329.                 lua_getglobal(L, "Sprite");
  4330.                 lua_pushstring(L, index);
  4331.                 lua_rawget(L, -2);
  4332.             }
  4333.             return 1;
  4334.         }
  4335.     };
  4336.  
  4337.     int SpriteNewIndex(lua_State* L){
  4338.         lua_assert(lua_isuserdata(L, -3));  //1
  4339.         lua_assert(lua_isstring(L, -2));    //2
  4340.                                         // -1 - value we want to set    //3
  4341.  
  4342.         Sprite* sprite = (Sprite*)lua_touserdata(L, -3);
  4343.         const char* index = lua_tostring(L, -2);
  4344.         if (strcmp(index, "x") == 0)
  4345.         {
  4346.             sprite->x = (int)lua_tonumber(L, -1);
  4347.         }
  4348.         else if (strcmp(index, "y") == 0)
  4349.         {
  4350.             sprite->y = (int)lua_tonumber(L, -1);
  4351.         }
  4352.         else
  4353.         {
  4354.             lua_getuservalue(L, 1); //1
  4355.             lua_pushvalue(L, 2);    //2
  4356.             lua_pushvalue(L, 3);    //3
  4357.             lua_settable(L, -3);    //1[2] = 3
  4358.         }
  4359.  
  4360.         return 0;
  4361.     };
  4362.  
  4363. int main(int argc, char *argv[]) {
  4364.     const char* LUA_FILE = R"(
  4365.         sprite = Sprite.new()
  4366.         sprite:Move( 6, 7 )     -- Sprite.Move( sprite, 6, 7 )
  4367.         sprite:Draw()
  4368.         sprite.y = 10
  4369.         sprite.zzz = 99
  4370.         sprite.x = sprite.zzz
  4371.         sprite:Draw()
  4372.         Sprite.new()
  4373.         Sprite.new()
  4374.         )";
  4375.  
  4376.     lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  4377.     luaL_openlibs(L);
  4378.  
  4379.     lua_newtable(L);
  4380.     int spriteTableIdx = lua_gettop(L);
  4381.     lua_pushvalue(L, spriteTableIdx);
  4382.     lua_setglobal(L, "Sprite");
  4383.  
  4384.     constexpr int NUMBER_OF_UPVALUES = 1;
  4385.     lua_pushlightuserdata(L, &spriteManager);
  4386.     lua_pushcclosure(L, CreateSprite, NUMBER_OF_UPVALUES);
  4387.     lua_setfield(L, -2, "new");
  4388.     lua_pushcfunction(L, MoveSprite);
  4389.     lua_setfield(L, -2, "Move");
  4390.     lua_pushcfunction(L, DrawSprite);
  4391.     lua_setfield(L, -2, "Draw");
  4392.  
  4393.     luaL_newmetatable(L, "SpriteMetaTable");
  4394.     lua_pushstring(L, "__gc");
  4395.     lua_pushlightuserdata(L, &spriteManager);
  4396.     lua_pushcclosure(L, DestroySprite, NUMBER_OF_UPVALUES);
  4397.     lua_settable(L, -3);
  4398.  
  4399.     lua_pushstring(L, "__index");
  4400.     lua_pushcfunction(L, SpriteIndex);
  4401.     lua_settable(L, -3);
  4402.  
  4403.     lua_pushstring(L, "__newindex");
  4404.     lua_pushcfunction(L, SpriteNewIndex);
  4405.     lua_settable(L, -3);
  4406.  
  4407.     int doResult = luaL_dostring(L, LUA_FILE);
  4408.     if (doResult != LUA_OK)
  4409.     {
  4410.         printf("Error: %s\n", lua_tostring(L, -1));
  4411.     }
  4412.  
  4413.     lua_close(L);
  4414.  
  4415.     lua_assert(spriteManager.numberOfSpritesExisting == 0);
  4416.     lua_assert(spriteManager.numberOfSpritesMade == 3);
  4417.  
  4418.     cin.get();//ожидает ввода символа программа завершается.
  4419.     return 0;
  4420. }
  4421.  
  4422.  
  4423. struct Sprite
  4424.     {
  4425.         int x;
  4426.  
  4427.         Sprite() : x(0) {}
  4428.         ~Sprite() {}
  4429.  
  4430.         void Move(int velX)
  4431.         {
  4432.             x += velX;
  4433.         }
  4434.  
  4435.         void Draw()
  4436.         {
  4437.             printf("sprite(%p): x = %d\n", this, x);
  4438.         }
  4439.     };
  4440.  
  4441.     struct SpriteManager
  4442.     {
  4443.         std::vector<Sprite*> m_sprites;
  4444.         void ForgetSprite(Sprite* sprite)
  4445.         {
  4446.             int i = 0;
  4447.             for (auto& s : m_sprites)
  4448.             {
  4449.                 if (s == sprite){
  4450.                     m_sprites.erase(m_sprites.begin() + i);
  4451.                     return;
  4452.                 }
  4453.                 i++;
  4454.             }
  4455.         }
  4456.     };
  4457.  
  4458. SpriteManager sp;
  4459.  
  4460.     int CreateSprite(lua_State* L){
  4461.  
  4462.         SpriteManager* sm = (SpriteManager*)lua_touserdata(L, lua_upvalueindex(1));
  4463.         void* pointerToASprite = lua_newuserdata(L, sizeof(Sprite));
  4464.         new (pointerToASprite) Sprite();
  4465.         luaL_getmetatable(L, "mt");
  4466.         lua_setmetatable(L, -2);
  4467.         lua_newtable(L);
  4468.         lua_setuservalue(L, 1);
  4469.         return 1;
  4470.     };
  4471.  
  4472.     int DestroySprite(lua_State* L){
  4473.         SpriteManager* sm = (SpriteManager*)lua_touserdata(L, lua_upvalueindex(1));
  4474.         Sprite* sprite = (Sprite*)lua_touserdata(L, -1);
  4475.         sm->ForgetSprite(sprite);
  4476.         sprite->~Sprite();
  4477.         return 0;
  4478.     };
  4479.    
  4480.     int DrawSprite(lua_State* L){
  4481.         Sprite* sprite = (Sprite*)lua_touserdata(L, -2);
  4482.         sprite->Move(lua_tonumber(L, -1));
  4483.         sprite->Draw();
  4484.         return 0;
  4485.     };
  4486.  
  4487.     int SpriteIndex(lua_State* L){
  4488.  
  4489.         Sprite* sprite = (Sprite*)lua_touserdata(L, -2);
  4490.         const char* index = lua_tostring(L, -1);
  4491.             lua_getuservalue(L, 1);
  4492.             lua_pushvalue(L, 2);
  4493.             lua_gettable(L, -2);
  4494.  
  4495.             lua_getglobal(L, "sprite");
  4496.             lua_pushstring(L, index);
  4497.             lua_rawget(L, -2);
  4498.            
  4499.             return 1;
  4500.     };
  4501.  
  4502.  
  4503. int main(int argc, char *argv[]) {
  4504.     const char* LUA_FILE = R"(
  4505.         sp = sprite.new()
  4506.         sp:draw(6)
  4507.         )";
  4508.  
  4509.     lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  4510.     luaL_openlibs(L);
  4511.  
  4512.     lua_newtable(L);
  4513.     lua_pushvalue(L, 1);
  4514.     lua_setglobal(L, "sprite");
  4515.  
  4516.     lua_pushlightuserdata(L, &sp);
  4517.     lua_pushcclosure(L, CreateSprite, 1);
  4518.     lua_setfield(L, -2, "new");
  4519.     lua_pushcfunction(L, DrawSprite);
  4520.     lua_setfield(L, -2, "draw");
  4521.  
  4522.     luaL_newmetatable(L, "mt");
  4523.     lua_pushstring(L, "__gc");
  4524.     lua_pushlightuserdata(L, &sp);
  4525.     lua_pushcclosure(L, DestroySprite, 1);
  4526.     lua_settable(L, -3);
  4527.  
  4528.     lua_pushstring(L, "__index");
  4529.     lua_pushcfunction(L, SpriteIndex);
  4530.     lua_settable(L, -3);
  4531.     luaL_dostring(L, LUA_FILE);
  4532.  
  4533.     lua_close(L);
  4534.    
  4535.     cin.get();//ожидает ввода символа программа завершается.
  4536.     return 0;
  4537. };
  4538.  
  4539.  
  4540. Замыкание 2.
  4541.  
  4542. struct Sprite
  4543.     {
  4544.         int x;
  4545.  
  4546.         Sprite() : x(0) {}
  4547.         ~Sprite() {}
  4548.  
  4549.         void Move(int velX)
  4550.         {
  4551.             x += velX;
  4552.         }
  4553.  
  4554.         void Draw()
  4555.         {
  4556.             printf("sprite(%p): x = %d\n", this, x);
  4557.         }
  4558.     };
  4559.  
  4560.     struct SpriteManager
  4561.     {
  4562.         std::vector<Sprite*> m_sprites;
  4563.         void ForgetSprite(Sprite* sprite)
  4564.         {
  4565.             int i = 0;
  4566.             for (auto& s : m_sprites)
  4567.             {
  4568.                 if (s == sprite){
  4569.                     m_sprites.erase(m_sprites.begin() + i);
  4570.                     return;
  4571.                 }
  4572.                 i++;
  4573.             }
  4574.         }
  4575.     };
  4576.     int pri(lua_State* L) { cout << "pri " << endl;
  4577.     return 0;
  4578.     }
  4579. SpriteManager sp;
  4580.  
  4581.     int CreateSprite(lua_State* L){
  4582.         SpriteManager* sm = (SpriteManager*)lua_touserdata(L, lua_upvalueindex(1));
  4583.         void* pointerToASprite = lua_newuserdata(L, sizeof(Sprite));
  4584.         new (pointerToASprite) Sprite();
  4585.         luaL_getmetatable(L, "mt");
  4586.         lua_setmetatable(L, -2);
  4587.         lua_newtable(L);
  4588.         lua_setuservalue(L, 1);
  4589.         return 1;
  4590.     };
  4591.  
  4592.     int DestroySprite(lua_State* L){
  4593.         SpriteManager* sm = (SpriteManager*)lua_touserdata(L, lua_upvalueindex(1));
  4594.         Sprite* sprite = (Sprite*)lua_touserdata(L, -1);
  4595.         sm->ForgetSprite(sprite);
  4596.         sprite->~Sprite();
  4597.         return 0;
  4598.     };
  4599.    
  4600.     int DrawSprite(lua_State* L){
  4601.         Sprite* sprite = (Sprite*)lua_touserdata(L, -2);
  4602.         sprite->Move(lua_tonumber(L, -1));
  4603.         sprite->Draw();
  4604.         return 0;
  4605.     };
  4606.  
  4607.     int SpriteIndex(lua_State* L){
  4608.  
  4609.         Sprite* sprite = (Sprite*)lua_touserdata(L, -2);
  4610.         const char* index = lua_tostring(L, -1);
  4611.             lua_getuservalue(L, 1);
  4612.             lua_pushvalue(L, 2);
  4613.             lua_gettable(L, -2);
  4614.  
  4615.             lua_getglobal(L, "sprite");
  4616.             lua_pushstring(L, index);
  4617.             lua_rawget(L, -2);
  4618.            
  4619.             return 1;
  4620.     };
  4621.  
  4622.  
  4623. int main(int argc, char *argv[]) {
  4624.     const char* LUA_FILE = R"(
  4625.         sp = sprite.new()
  4626.         sp:draw(6)
  4627.         )";
  4628.  
  4629.     lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  4630.     luaL_openlibs(L);
  4631.  
  4632.     lua_newtable(L);
  4633.     lua_pushvalue(L, 1);
  4634.     lua_setglobal(L, "sprite");
  4635.  
  4636.     lua_pushlightuserdata(L, &sp);
  4637.     lua_pushcclosure(L, CreateSprite, 1);
  4638.     lua_setfield(L, -2, "new");
  4639.     lua_pushcfunction(L, DrawSprite);
  4640.     lua_setfield(L, -2, "draw");
  4641.  
  4642.     luaL_newmetatable(L, "mt");
  4643.     lua_pushstring(L, "__gc");
  4644.     lua_pushlightuserdata(L, &sp);
  4645.     lua_pushcclosure(L, DestroySprite, 1);
  4646.     lua_settable(L, -3);
  4647.  
  4648.     lua_pushstring(L, "__index");
  4649.     lua_pushcfunction(L, SpriteIndex);
  4650.     lua_settable(L, -3);
  4651.     luaL_dostring(L, LUA_FILE);
  4652.  
  4653.     lua_close(L);
  4654.    
  4655.     cin.get();//ожидает ввода символа программа завершается.
  4656.     return 0;
  4657. }
  4658.  
  4659. Замыкание 3
  4660.  
  4661. struct Sprite
  4662. {
  4663.     int x;
  4664.  
  4665.     Sprite() : x(0) { cout << " sp" << endl; }
  4666.     ~Sprite() { cout << " des " << endl; }
  4667.  
  4668. };
  4669.  
  4670.  
  4671. int pri(lua_State* L) {
  4672.     cout << "pri " << endl;
  4673.     return 0;
  4674. }
  4675.  
  4676. int CreateSprite(lua_State* L) {
  4677.     void* pointerToASprite = lua_newuserdata(L, sizeof(Sprite));
  4678.     new (pointerToASprite) Sprite();
  4679.     luaL_getmetatable(L, "mt");
  4680.     lua_setmetatable(L, -2);
  4681.     lua_newtable(L);
  4682.     lua_setuservalue(L, 1);
  4683.     return 1;
  4684. };
  4685.  
  4686. int DestroySprite(lua_State* L) {
  4687.     Sprite* sprite = (Sprite*)lua_touserdata(L, -1);
  4688.     sprite->~Sprite();
  4689.     return 0;
  4690. };
  4691.  
  4692.  
  4693. int main(int argc, char *argv[]) {
  4694.     const char* LUA_FILE = R"(
  4695.         sp = sprite.new()
  4696.         )";
  4697.  
  4698.     lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  4699.     luaL_openlibs(L);
  4700.  
  4701.     lua_newtable(L);
  4702.     lua_pushvalue(L, 1);
  4703.     lua_setglobal(L, "sprite");
  4704.  
  4705.     lua_pushinteger(L, 2);
  4706.     lua_pushcclosure(L, CreateSprite, 1);
  4707.     lua_setfield(L, -2, "new");
  4708.  
  4709.     luaL_newmetatable(L, "mt");
  4710.     lua_pushstring(L, "__gc");
  4711.  
  4712.     lua_pushinteger(L, 2);
  4713.     lua_pushcclosure(L, DestroySprite, 1);
  4714.     lua_settable(L, -3);
  4715.  
  4716.     luaL_dostring(L, LUA_FILE);
  4717.  
  4718.     lua_close(L);
  4719.  
  4720.     cin.get();//ожидает ввода символа программа завершается.
  4721.     return 0;
  4722. }
  4723.  
  4724. Замыкание 4.
  4725.  
  4726. int pri(lua_State* L) {
  4727.     showstack(L);
  4728.     cout << "pri " << endl;
  4729.     return 0;
  4730. }
  4731.  
  4732. int CreateSprite(lua_State* L) {
  4733.     cout << "cre " << endl;
  4734.     lua_gettable(L, -2);
  4735.     lua_setuservalue(L, 1);
  4736.     return 1;
  4737. };
  4738.  
  4739. int main(int argc, char *argv[]) {
  4740.     const char* LUA_FILE = R"(
  4741.         sp = sprite.new()
  4742.         )";
  4743.  
  4744.     lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  4745.     luaL_openlibs(L);
  4746.  
  4747.     lua_newtable(L);
  4748.     lua_pushvalue(L, 1);
  4749.     lua_setglobal(L, "sprite");
  4750.    
  4751.     lua_pushinteger(L, 2);
  4752.     lua_pushcclosure(L, pri, 1);
  4753.     lua_setfield(L, -2, "new");
  4754.  
  4755.     luaL_dostring(L, LUA_FILE);
  4756.     lua_close(L);
  4757.  
  4758.     cin.get();//ожидает ввода символа программа завершается.
  4759.     return 0;
  4760. }
  4761.  
  4762. Замыкание 5.
  4763.  
  4764. static int newcounter(lua_State *L) {
  4765.     cout << lua_tonumber(L, -1) << endl;
  4766.     cout << " new" << endl;
  4767.     int val = lua_tointeger(L, lua_upvalueindex(1));
  4768.     lua_pushinteger(L, 1);  /* new value */
  4769.     lua_copy(L, -1, lua_upvalueindex(1));  /* update upvalue */
  4770.     return 1;
  4771. }
  4772. static int counter(lua_State *L) {
  4773.     cout << "coun " << endl;
  4774.     lua_pushinteger(L, 10);
  4775.     lua_pushcclosure(L, newcounter, 1);
  4776.     return 1;  /* return new value */
  4777. }
  4778.  
  4779.  
  4780. int main(int argc, char *argv[]) {
  4781.     const char* LUA = R"(
  4782. c1 = counter()
  4783.    print(c1(), c1(), c1())   --> 1    2    3
  4784.     -- c2 = newcounter()
  4785.      --print(c2(), c2(), c1())   --> 1    2    4
  4786.  
  4787.        )";
  4788.  
  4789.     lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  4790.     luaL_openlibs(L);
  4791.     //lua_newtable(L);
  4792.    
  4793.     //lua_pushnumber(L, 142);
  4794.     lua_register(L,"counter", counter);// отправить c функцию в стек.
  4795.     luaL_dostring(L, LUA);
  4796.     //lua_pushnumber(L, 142);
  4797.   lua_pushcclosure(L, newcounter, 1);
  4798.  
  4799. //  lua_settable(L, -3);
  4800.  
  4801.     lua_pcall(L, 0, 0, 0);// вызвать функцию foo.
  4802.  
  4803.     lua_close(L);
  4804.  
  4805.     cin.get();//ожидает ввода символа программа завершается.
  4806.     return 0;
  4807. }
  4808.  
  4809.  
  4810. Замыкание 6.
  4811.  
  4812.  
  4813. static int newcounter(lua_State *L) {
  4814.     int val = lua_tointeger(L, lua_upvalueindex(1));/*Возвращает псевдоиндекс, который представляет
  4815.     i-ковою внешнюю локальную переменную (upvalue) выполняемой функции.*/
  4816.     lua_pushinteger(L, ++val);  /*  новое  значение    */
  4817.     lua_pushvalue(L, -1);   /*дублирует    его  */
  4818.     lua_replace(L, lua_upvalueindex(1));/*  обновляет  верхнее  значение*/
  4819.     return 1;
  4820. }
  4821. static int counter(lua_State *L) {
  4822.     lua_pushinteger(L, 0);
  4823.     lua_pushcclosure(L, newcounter, 1);
  4824.     return 1;  /* return new value */
  4825. }
  4826.  
  4827. int main(int argc, char *argv[]) {
  4828.     const char* LUA = R"(
  4829.   c1 = counter()
  4830.   print(c1(), c1(), c1())   --> 1    2    3
  4831.   )";
  4832.  
  4833.     lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  4834.     luaL_openlibs(L);
  4835.  
  4836.     lua_register(L,"counter", counter);// отправить c функцию в стек.
  4837.     checkerror(L, LUA);
  4838.  
  4839.     lua_pushcclosure(L, newcounter, 1);/* Помещает в стек новое C замыкание. При создании C функций, можно увязать
  4840. с ней некоторые значения, таким образом создавая C замыкания (closure); затем эти значения будут доступны функции
  4841. каждый раз при её вызове. Для связывания значений с C функцией, вначале эти значения помещаются в стек
  4842. (когда имеется несколько значений, первое значение помещается первым). Затем вызывается lua_pushcclosure для
  4843. создания и помещения в стек C функции, с аргументом n, сообщающим сколько значений будет связано с этой функцией.
  4844. lua_pushcclosure также выводит из стека эти значения. Макс значением для n является 255. При n равным нулю,
  4845. эта функция создает легкую C функцию, которая является просто указателем на C функцию. В этом случае, она никогда
  4846. не вызывает ошибку памяти.*/
  4847.  
  4848.     lua_close(L);
  4849.     return 0;
  4850.  
  4851. };
  4852.  
  4853. Замыкание 7.
  4854.  
  4855.  
  4856. int newcounter(lua_State* L) {
  4857.     int val = lua_tointeger(L, lua_upvalueindex(1));/*Возвращает псевдоиндекс, который представляет
  4858.     i-ковою внешнюю локальную переменную (upvalue) выполняемой функции.*/
  4859.     lua_pushinteger(L, val++);  /*  новое  значение    */
  4860.     lua_pushvalue(L, -1);   /*дублирует    его  */
  4861.     lua_replace(L, lua_upvalueindex(1));/*  обновляет верхнее значение. снимает значение с вершины стека
  4862.                 и устанавливает его как значение элемента с заданным индексом.*/
  4863.     return 1;
  4864. }
  4865. int counter(lua_State * L) {
  4866.     lua_pushinteger(L, 1);
  4867.     lua_pushcclosure(L, newcounter, 1);/* Помещает в стек новое C замыкание. При создании C функций, можно увязать
  4868. с ней некоторые значения, таким образом создавая C замыкания (closure); затем эти значения будут доступны функции
  4869. каждый раз при её вызове. Для связывания значений с C функцией, вначале эти значения помещаются в стек
  4870. (когда имеется несколько значений, первое значение помещается первым). Затем вызывается lua_pushcclosure для
  4871. создания и помещения в стек C функции, с аргументом n, сообщающим сколько значений будет связано с этой функцией.
  4872. lua_pushcclosure также выводит из стека эти значения. Макс значением для n является 255. При n равным нулю,
  4873. эта функция создает легкую C функцию, которая является просто указателем на C функцию. В этом случае, она никогда
  4874. не вызывает ошибку памяти.*/
  4875.  
  4876.     return 1;  /* return new value */
  4877. }
  4878.  
  4879. int main(int argc, char* argv[]) {
  4880.     const char* LUA = R"(
  4881.   c = counter()
  4882.   print(c(), c(), c())   --> 1    2    3
  4883.   )";
  4884.  
  4885.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  4886.     luaL_openlibs(L);
  4887.  
  4888.     lua_register(L, "counter", counter);// отправить c функцию в стек.
  4889.     checkerror(L, LUA);
  4890.  
  4891.    
  4892.     lua_close(L);
  4893.     return 0;
  4894.  
  4895. };
  4896.  
  4897.  
  4898.  
  4899.  
  4900. luaL_setfuncs
  4901.  
  4902. int foo1(lua_State * L){
  4903.     cout << "foo1 " << endl;
  4904.     return 0;
  4905. }
  4906.  
  4907. int foo2(lua_State * L) {
  4908.     cout << "foo2 " << endl;
  4909.     return 0;
  4910. }
  4911.  
  4912. void RegisterFoo(lua_State * L){
  4913.     luaL_Reg sFooRegs[] =
  4914.     {
  4915.         { "foo1", foo1 },
  4916.         { "foo2", foo2 },
  4917.         { NULL, NULL }
  4918.     };
  4919.  
  4920.     luaL_newmetatable(L, "luaL_Foo");
  4921.  
  4922.     // Register the C functions _into_ the metatable we just created.
  4923.     luaL_setfuncs(L, sFooRegs, 0);/*    void luaL_setfuncs(lua_State * L, const luaL_Reg * l, int nup);
  4924.     Регистрирует все функции в массиве l(см.luaL_Reg) В таблице на вершине стека(ниже необязательных
  4925.     значений повышений).Когда nupне ноль, все функции создаются с nup общими значениями повышения, которые
  4926.     должны быть предварительно помещены в стек поверх таблицы библиотеки. Эти значения выталкиваются
  4927.     из стека после регистрации.*/   
  4928.    
  4929.     lua_pushvalue(L, -1);
  4930.     lua_setfield(L, -1, "__index");
  4931.  
  4932.     lua_setglobal(L, "Foo");
  4933. }
  4934. int main(int argc, char *argv[]) {
  4935.     const char* LUA = R"(
  4936. Foo.foo1()
  4937. Foo.foo2()
  4938.   )";
  4939.  
  4940.     lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  4941.     luaL_openlibs(L);
  4942.     RegisterFoo(L);
  4943.     checkerror(L, LUA);
  4944.  
  4945.     lua_close(L);
  4946.     return 0;
  4947. };
  4948.  
  4949. Еще пример.
  4950.  
  4951.  
  4952. int foo1(lua_State* L) {
  4953.     int val = lua_tointeger(L, lua_upvalueindex(1));/*Возвращает псевдоиндекс, который представляет
  4954.    i-ковою внешнюю локальную переменную (upvalue) выполняемой функции.*/
  4955.     cout << "foo " << val << endl;
  4956.     return 0;
  4957. };
  4958.  
  4959. int foo2(lua_State* L) {
  4960.     int val = lua_tointeger(L, lua_upvalueindex(1));/*Возвращает псевдоиндекс, который представляет
  4961. i-ковою внешнюю локальную переменную (upvalue) выполняемой функции.*/
  4962.     cout << "foo2 " << val << endl;
  4963.     return 0;
  4964. };
  4965.  
  4966. void RegisterFoo(lua_State* L) {
  4967.     luaL_Reg sFooRegs[] =
  4968.     {
  4969.         { "foo1", foo1 },
  4970.         { "foo2", foo2 },
  4971.         { NULL, NULL }
  4972.     };
  4973.  
  4974.     luaL_newmetatable(L, "luaL_Foo");
  4975.  
  4976.     lua_pushinteger(L, 1);
  4977.     // Register the C functions _into_ the metatable we just created.
  4978.     luaL_setfuncs(L, sFooRegs, 1);/* void luaL_setfuncs(lua_State * L, const luaL_Reg * l, int nup);
  4979.     Регистрирует все функции в массиве l) В таблице на вершине стека(ниже необязательных
  4980.     значений повышений).Когда nupне ноль, все функции создаются с nup общими значениями повышения, которые
  4981.     должны быть предварительно помещены в стек поверх таблицы библиотеки. Эти значения выталкиваются
  4982.     из стека после регистрации.*/
  4983.  
  4984.     lua_pushvalue(L, -1);
  4985.     lua_setfield(L, -1, "__index");
  4986.  
  4987.     lua_setglobal(L, "Foo");
  4988. }
  4989.  
  4990. int main(int argc, char* argv[]) {
  4991.     const char* LUA = R"(
  4992. Foo.foo1()
  4993. Foo.foo2()
  4994.   )";
  4995.  
  4996.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  4997.     luaL_openlibs(L);
  4998.     RegisterFoo(L);
  4999.     checkerror(L, LUA);
  5000.        
  5001.     lua_close(L);
  5002.  
  5003.     return 0;
  5004. };
  5005.  
  5006. Мета метод _index
  5007.  
  5008. int main(int argc, char* argv[]) {
  5009. const char* LUA = R"(
  5010. foo={} foo.key="value"
  5011. bar = setmetatable({},{__index=foo},print("index\n") )
  5012. print(bar.key)-- value
  5013. )";
  5014.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  5015.     luaL_openlibs(L);
  5016.     checkerror(L, LUA);//Функция проверка на ошибки.
  5017.     lua_close(L);
  5018.  
  5019.     return 0;
  5020. };
  5021.  
  5022.  
  5023.  
  5024. Потоки. Многопоточность — это принцип построения программы, при котором несколько блоков могут выполняться одновременно и не мешать друг другу.
  5025.  
  5026.  
  5027. Lua. Это по сути однопоточная система.
  5028. lua_State * lua_newthread ( lua_State * L);
  5029. Создает новый поток, помещает его в стек и возвращает указатель на объект lua_State, представляющий этот новый поток. Новое состояние, возвращаемое этой функцией, совместно использует с исходным состоянием все глобальные объекты (например, таблицы), но имеет независимый стек выполнения.
  5030. Не существует явной функции для закрытия или уничтожения потока. Потоки подлежат сборке мусора, как и любой объект Lua.
  5031.  
  5032. Без вызова потока. Вызов функции в одном потоке.
  5033.  
  5034. int foo(lua_State* L) {
  5035.     cout << " func foo c++ " << L << endl;
  5036.     return 0;
  5037. };
  5038.  
  5039. int main(int argc, char* argv[]) {
  5040.     const char* LUA = R"(
  5041. foo()
  5042.  
  5043. )";
  5044.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  5045.     luaL_openlibs(L);
  5046.     lua_State* L1 = lua_newthread(L);
  5047.     lua_pushcfunction(L, foo);// отправить c функцию в стек.
  5048.     showstack(L); cout <<  endl;
  5049.     lua_setglobal(L, "foo");// уст для переменной значение в виде функции.
  5050.         luaL_dostring(L, LUA);
  5051.     cout <<"\n";
  5052.     showstack(L);
  5053.     cout << "\n adrees L  "<<  L << "\n adrees L1 "<< L1 << "\n";
  5054.     lua_close(L);
  5055.  
  5056.     return 0;
  5057. };
  5058.  
  5059. Эта функция возвращает указатель на lua_State, представляющее новой поток, а также отправить новой поток в стек как значение типа "thread". Например, после выполнения оператора L1 = lua_newthread(L);
  5060. у нас будет два потока, L1 и L, которые будут внутренне ссылаться на одно и то же состояние Lua. Каждый поток обладает собственным стеком.
  5061. Новый поток L1 начинает с пустого стека; у старого потока L есть новый поток на вершине стека:
  5062. printf("%d\n", lua_gettop(L1)); --> 0
  5063. printf("%s\n", luaL_typename(L, -1)); --> thread
  5064.  
  5065. За исключением главноого, все потоки подвержены сборке мусора, как и любой другой объект Lua. Когда вы создаете новый поток, то значение, которое отправляется в стек, гарантирует, что эта поток не
  5066. является мусором. Вы никогда не должны использовать поток, который должным образом не привязан к состоянию. (Главный поток внутренне привязан с самого начала, поэтому о нем можно не беспокоиться.)
  5067.  
  5068.  
  5069. Функция вызвается в 2 потоках.
  5070.  
  5071. int main(int argc, char* argv[]) {
  5072.     const char* LUA = R"(
  5073. foo()
  5074.  
  5075. )";
  5076.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  5077.     luaL_openlibs(L);
  5078.     lua_State* L1 = lua_newthread(L);
  5079.     lua_pushcfunction(L, foo);// отправить c функцию в стек.
  5080.     showstack(L); cout << "\n";
  5081.  
  5082.     lua_setglobal(L, "foo");// уст для переменной значение в виде функции.
  5083.     luaL_dostring(L, LUA);
  5084.     showstack(L1);  cout << "\n";// Стек потока L1 пуст.
  5085.     luaL_dostring(L1, LUA);
  5086.     cout << "\n adrees L  " << L << "\n adrees L1 " << L1 << "\n";
  5087.     lua_close(L);
  5088.  
  5089.     return 0;
  5090. };
  5091.  
  5092. Вариант 2
  5093.  
  5094. int main(int argc, char* argv[]) {
  5095.     const char* LUA = R"(
  5096. foo()
  5097.  
  5098. )";
  5099.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  5100.     luaL_openlibs(L);
  5101.     lua_State* L1 = lua_newthread(L);
  5102.     lua_pushcfunction(L, foo);// отправить c функцию в стек.
  5103.     showstack(L); cout <<"\n";
  5104.    
  5105.     lua_setglobal(L, "foo");// уст для переменной значение в виде функции.
  5106.     luaL_dostring(L, LUA);
  5107.     lua_xmove(L, L1, 1);// Снимает с L1 элементов передает L.
  5108.     showstack(L1);  cout << "\n";
  5109.     luaL_dostring(L1, LUA);
  5110.     cout << "\n adrees L  "<<  L << "\n adrees L1 "<< L1 << "\n";
  5111.     lua_close(L);
  5112.  
  5113.     return 0;
  5114. };
  5115.  
  5116. Запуск 2 функций в 2 потоках.
  5117.  
  5118. const char* LUA = R"(
  5119. function foo()
  5120. for i = 1, 3 do
  5121. print(" func foo "..i.."\n")
  5122. end     end
  5123.  
  5124. function main()
  5125. for i = 1, 3 do
  5126. print(" func main "..i.."\n")
  5127. end  end
  5128. )";
  5129. int main(int argc, char* argv[]) {
  5130.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  5131.     luaL_openlibs(L);
  5132.     lua_State* L1 = lua_newthread(L);
  5133.     checkerror(L, LUA);
  5134.     lua_getglobal(L, "main");
  5135.     lua_pcall(L, 0, 0, 0);// запустить функцию main в потоке L.
  5136.    
  5137.     lua_getglobal(L1, "foo");// запустить функцию foo в потоке L1.
  5138.     lua_pcall(L1, 0, 0, 0);
  5139.  
  5140.     lua_close(L);
  5141.     return 0;
  5142. };
  5143.  
  5144.  
  5145.  
  5146. Функции выполняются поочередно в двух потоках.
  5147.  
  5148. Для запуска выполнения сопрограммы мы используем lua_resume так же, как мы используем lua_pcall: мы заталкиваем функцию для вызова, заталкиваем ее аргументы и вызываем lua_resume,
  5149.  передавая в narg число аргументов. (Параметр from — это нить, которая совершает вызов.) Данное поведение также очень похоже на lua_pcall, но с тремя отличиями.
  5150.  
  5151. Во-первых, у lua_resume нет параметра для числа требуемых  результатов; она всегда возвращает все значения из вызванной функции.
  5152.  
  5153. Во-вторых, у нее нет параметра для обработчика сообщений; ошибка не раскручивает стек, поэтому после нее вы можете изучить стек.
  5154.  
  5155.  В-третьих, если выполняемая функция уступает управление, то lua_resume возвращает особый код LUA_YIELD и оставляет поток в состоянии, из которого она может быть возобновлена позже.
  5156.  
  5157. Когда lua_resume возвращает LUA_YIELD, видимая часть стека потока содержит только значения, переданные yield. Вызов lua_gettop вернет число выработанных значений. Для перемещения этих значений
  5158. В другой потоке мы можем использовать lua_xmove. Чтобы возобновить приостановленный поток, мы вновь вызываем lua_resume. При таких вызовах Lua считает, что все значения в стеке должны быть возвращены вызовом yield. Например, если вы не трогаете стек потока между возвращением из lua_resume и следующим возобновлением, то yield вернет именно те значения, которые он выработал при уступке управления. Обычно мы запускаем сопрограмму с функцией Lua в качестве ее тела. Эта функция Lua может вызывать другие функции, и любая из этих функций порой может уступать управление, завершая вызов lua_resume.
  5159.  
  5160.  
  5161. int my_yield(lua_State* L) {
  5162.     return lua_yield(L, 0);/*Эта функция должна вызываться только как возвращаемое выражение функции C следующим образом:
  5163.     return lua_yield(L, res); Когда функция C вызывает lua_yield таким образом, запущенная сопрограмма приостанавливает
  5164.     свое выполнение, и вызов lua_resume этой запущенной процедуры возвращается. Параметр res - это число значений из стека,
  5165.     которые передаются как результаты lua_resume.*/
  5166. };
  5167. const char* LUA = R"(
  5168. function foo()
  5169. print(" func foo \n")
  5170. end
  5171.  
  5172. function main()
  5173. for i = 1, 3 do
  5174. print(" func main "..i.."\n")
  5175. my_yield()
  5176. end  end
  5177. )";
  5178. int main(int argc, char* argv[]) {
  5179.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  5180.     luaL_openlibs(L);
  5181.     lua_State* L1 = lua_newthread(L);
  5182.     cout << "\n";
  5183.     lua_register(L, "my_yield", my_yield);
  5184.     checkerror(L, LUA);
  5185.     lua_getglobal(L, "main");
  5186.     while (true) {
  5187.         int ret = lua_resume(L, L1, 0); /* Запускает и продолжает сопрограмму в данном потоке L.
  5188.     вы отправляйте в стек главную функцию и её аргументы; затем вызываете lua_resume,nargs - кол-во аргументов.
  5189.     Вызов возвращается, когда приостанавливается или завершается. При возвращении, стек содержит все значения,
  5190.     переданные в lua_yield, или возвращенныеции. Чтобы продолжить сопрограмму, вы удаляете все результаты
  5191.     из последнего lua_yield, отправьте в её стек только значения, передаваемые в качестве результатов из yield, и
  5192.     затем вызываете lua_resume.   Параметр L представляет сопрограмму, которая продолжает L. */
  5193.         if (ret == LUA_YIELD) {
  5194.             lua_getglobal(L1, "foo");
  5195.             lua_pcall(L1, 0, 0, 0);
  5196.         }
  5197.         else if (ret == 0) {
  5198.  
  5199.             break;
  5200.         }
  5201.     };
  5202.  
  5203.     lua_close(L);
  5204.     return 0;
  5205. };
  5206.  
  5207. 1.
  5208.  
  5209. Функции выполняются поочередно в двух потоках с передачей значение в main.
  5210.  
  5211. int my_yield(lua_State* L) {
  5212.     return lua_yield(L, 0);/*Эта функция должна вызываться только как возвращаемое выражение функции C следующим образом:
  5213.     return lua_yield(L, res); Когда функция C вызывает lua_yield таким образом, запущенная сопрограмма приостанавливает
  5214.     свое выполнение, и вызов lua_resume этой запущенной процедуры возвращается. Параметр res - это число значений из стека,
  5215.     которые передаются как результаты lua_resume.*/
  5216. };
  5217.  
  5218. const char* LUA = R"(
  5219. function foo()
  5220. print(" func foo \n")
  5221. end
  5222.  
  5223. function main(n)
  5224. for i = 1, 3 do
  5225. print(" func main "..n.."\n")
  5226. my_yield()
  5227. end  end
  5228. )";
  5229. int main(int argc, char* argv[]) {
  5230.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  5231.     luaL_openlibs(L);
  5232.     lua_State* L1 = lua_newthread(L);
  5233.  
  5234.     lua_register(L, "my_yield", my_yield);// регистрация функций.
  5235.     checkerror(L, LUA);
  5236.     lua_getglobal(L, "main");// получить функцию.
  5237.     lua_pushinteger(L, 10); // передаем в функцию main 10.
  5238.     while (true) {
  5239.         int ret = lua_resume(L, L1, 1); /* Запускает и продолжает сопрограмму в данном потоке L.
  5240.     вы отправляйте в стек главную функцию и её аргументы; затем вызываете lua_resume,nargs - кол-во аргументов.
  5241.     Вызов возвращается, когда приостанавливается или завершается. При возвращении, стек содержит все значения,
  5242.     переданные в lua_yield, или возвращенные. Чтобы продолжить сопрограмму, вы удаляете все результаты
  5243.     из последнего lua_yield, отправьте в её стек только значения, передаваемые в качестве результатов из yield, и
  5244.     затем вызываете lua_resume.   Параметр L представляет сопрограмму, которая продолжает L. */
  5245.         if (ret == LUA_YIELD) {
  5246.             lua_getglobal(L1, "foo");
  5247.             lua_pcall(L1, 0, 0, 0);
  5248.         }
  5249.         else if (ret == 0) {
  5250.  
  5251.             break;
  5252.         }
  5253.     };
  5254.  
  5255.     lua_close(L);
  5256.     return 0;
  5257. };
  5258.  
  5259. 2.
  5260. Функции выполняются поочередно в двух потоках с передачей значение из main в foo.
  5261.  
  5262. const char* LUA = R"(
  5263. function foo(x)
  5264. x=x*10
  5265. print(" func foo "..x.."\n")
  5266. end
  5267.  
  5268. function main()
  5269. for i = 1, 3 do
  5270. print(" func main "..i.."\n")
  5271. my_yield(i)
  5272. end  end
  5273. )";
  5274. int main(int argc, char* argv[]) {
  5275.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  5276.     luaL_openlibs(L);
  5277.     lua_State* L1 = lua_newthread(L);
  5278.  
  5279.     lua_register(L, "my_yield", my_yield);// регистрация функций.
  5280.     checkerror(L, LUA);
  5281.     lua_getglobal(L, "main");// получить функцию.
  5282.     while (true) {
  5283.         int ret = lua_resume(L, L1, 0);
  5284.  
  5285.         if (ret == LUA_YIELD) {
  5286.             lua_getglobal(L1, "foo");
  5287.             lua_xmove(L, L1, 1);/*перемещает значение Lua между двумя стеками в
  5288.             одном и том же состоянии.*/
  5289.             lua_pcall(L1, 1, 0, 0);
  5290.         }
  5291.         else if (ret == 0) {/*Когда функция lua_resume возвращается, стек содержит все значения,
  5292.         переданные в lua_yield, или все значения, возвращенные телом функции.*/
  5293.         //showstack(L);
  5294.             break;
  5295.         }
  5296.     };
  5297.  
  5298.     lua_close(L);
  5299.     return 0;
  5300. };
  5301.  
  5302. 3.
  5303. int my_yield(lua_State* L) {
  5304.  
  5305.     lua_State* L1 = lua_newthread(L);
  5306.     lua_pushthread(L1);
  5307.    
  5308.     return lua_yield(L, 0);/*Эта функция должна вызываться только как возвращаемое выражение функции C следующим образом:
  5309.     return lua_yield(L, res); Когда функция C вызывает lua_yield таким образом, запущенная сопрограмма приостанавливает
  5310.     свое выполнение, и вызов lua_resume этой запущенной процедуры возвращается. Параметр res - это число значений из стека,
  5311.     которые передаются как результаты lua_resume.*/
  5312. };
  5313. const char* LUA = R"(
  5314. function foo()
  5315. print(" func foo \n")
  5316. end
  5317.  
  5318. function main()
  5319. for i = 1, 3 do
  5320. print(" func main "..i.."\n")
  5321. my_yield(foo)
  5322. end  end
  5323. )";
  5324. int main(int argc, char* argv[]) {
  5325.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  5326.     luaL_openlibs(L);
  5327.     lua_register(L, "my_yield", my_yield);
  5328.     cout << "\n";
  5329.     checkerror(L, LUA);
  5330.     lua_getglobal(L, "main");
  5331.     while (true) {
  5332.         int ret = lua_resume(L, NULL, 0); /* Запускает и продолжает сопрограмму в данном потоке L. */
  5333.         if (ret == LUA_YIELD) {
  5334.             lua_State* L1 = lua_tothread(L, -1);
  5335.  
  5336.             lua_getglobal(L1, "foo");
  5337.             lua_pcall(L1, 0, 0, 0);
  5338.         }
  5339.         else if (ret == 0) {
  5340.  
  5341.             break;
  5342.         }
  5343.     };
  5344.  
  5345.     lua_close(L);
  5346.     return 0;
  5347. };
  5348.  
  5349.  
  5350.  
  5351. Функции выполняются поочередно в двух потоках с передачей значение в main из main в foo.
  5352.  
  5353. const char* LUA = R"(
  5354. function foo(x)
  5355. x=x*10
  5356. print(" func foo "..x.."\n")
  5357. end
  5358.  
  5359. function main(n)
  5360. for i = 1, 3 do
  5361. print(" func main "..n.."\n")
  5362. my_yield(i)
  5363. end  end
  5364. )";
  5365. int main(int argc, char* argv[]) {
  5366.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  5367.     luaL_openlibs(L);
  5368.     lua_State* L1 = lua_newthread(L);
  5369.  
  5370.     lua_register(L, "my_yield", my_yield);// регистрация функций.
  5371.     checkerror(L, LUA);
  5372.     lua_getglobal(L, "main");// получить функцию.
  5373.     lua_pushinteger(L, 10); // передаем в функцию main 10.
  5374.  
  5375.     while (true) {
  5376.         int ret = lua_resume(L, L1, 1); /* Запускает и продолжает сопрограмму в данном потоке L.
  5377.     вы отправляйте в стек главную функцию и её аргументы; затем вызываете lua_resume,nargs - кол-во аргументов.
  5378.     Вызов возвращается, когда приостанавливается или завершается. При возвращении, стек содержит все значения,
  5379.     переданные в lua_yield, или возвращенные. Чтобы продолжить сопрограмму, вы удаляете все результаты
  5380.     из последнего lua_yield, отправьте в её стек только значения, передаваемые в качестве результатов из yield, и
  5381.     затем вызываете lua_resume.   Параметр L представляет сопрограмму, которая продолжает L. */
  5382.  
  5383.         if (ret == LUA_YIELD) {
  5384.             lua_getglobal(L1, "foo");
  5385.             lua_xmove(L, L1, 1);/*перемещает значение Lua между двумя стеками в
  5386.             одном и том же состоянии.*/
  5387.             lua_pcall(L1, 1, 0, 0);
  5388.         }
  5389.         else if (ret == 0) {/*Когда функция lua_resume возвращается, стек содержит все значения,
  5390.         переданные в lua_yield, или все значения, возвращенные телом функции.*/
  5391.         //showstack(L);
  5392.             break;
  5393.         }
  5394.     };
  5395.  
  5396.     lua_close(L);
  5397.     return 0;
  5398. };
  5399.  
  5400. Функции выполняются поочередно в двух потоках. Вернуть значений из lua_yield.
  5401.  
  5402. int my_yield(lua_State* L) {
  5403.     return lua_yield(L, 1);/*Эта функция должна вызываться только как возвращаемое выражение функции C следующим образом:
  5404.     return lua_yield(L, res); Когда функция C вызывает lua_yieldтаким образом, запущенная сопрограмма приостанавливает
  5405.     свое выполнение, и вызов lua_resume этой запущенной процедуры возвращается. Параметр res - это число значений из стека,
  5406.     которые передаются как результаты lua_resume.*/
  5407. };
  5408.  
  5409. const char* LUA = R"(
  5410. function foo()
  5411. x=10
  5412. print(" func foo "..x.."\n")
  5413. end
  5414.  
  5415. function main()
  5416. for i = 1, 3 do
  5417. print(" func main "..i.."\n")
  5418. my_yield(i)
  5419. end  end
  5420. )";
  5421. int main(int argc, char* argv[]) {
  5422.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  5423.     luaL_openlibs(L);
  5424.     lua_State* L1 = lua_newthread(L);
  5425.  
  5426.     lua_register(L, "my_yield", my_yield);// регистрация функций.
  5427.     checkerror(L, LUA);
  5428.     lua_getglobal(L, "main");// получить функцию.
  5429.     while (true) {
  5430.         int ret = lua_resume(L, L1, 0);
  5431.  
  5432.         if (ret == LUA_YIELD) {
  5433.             lua_xmove(L, L1, 1);// отравить значение из yield потока L в стек L1.
  5434.             lua_getglobal(L1, "foo");
  5435.             lua_pcall(L1, 0, 0, 0);
  5436.         }
  5437.         else if (ret == 0) {/*Когда функция lua_resume возвращается, стек содержит все значения,
  5438.         переданные в lua_yield, или все значения, возвращенные телом функции.*/
  5439.  
  5440.             break;
  5441.         }
  5442.     };
  5443.        
  5444. showstack(L1);
  5445.  
  5446.     lua_close(L);
  5447.     return 0;
  5448. };
  5449.  
  5450.  
  5451. Функции выполняются поочередно в двух потоках с передачей значение в main из main в foo. Вернуть значений из lua_yield.
  5452.  
  5453. int my_yield(lua_State* L) {
  5454.     return lua_yield(L, 0);/*Эта функция должна вызываться только как возвращаемое выражение функции C следующим образом:
  5455.     return lua_yield(L, res); Когда функция C вызывает lua_yield таким образом, запущенная сопрограмма приостанавливает
  5456.     свое выполнение, и вызов lua_resume этой запущенной процедуры возвращается. Параметр res - это число значений из стека,
  5457.     которые передаются как результаты lua_resume.*/
  5458. };
  5459.  
  5460. const char* LUA = R"(
  5461. function foo(x1)
  5462. x= x1 * 10
  5463. print(" func foo "..x.."\n")
  5464. return x
  5465. end
  5466.  
  5467. function main(n)
  5468. for i = 1, 3 do
  5469. print(" func main "..n.."\n")
  5470. my_yield(i)
  5471. end  end
  5472. )";
  5473. int main(int argc, char* argv[]) {
  5474.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  5475.     luaL_openlibs(L);
  5476.     lua_State* L1 = lua_newthread(L);
  5477.  
  5478.     lua_register(L, "my_yield", my_yield);// регистрация функций.
  5479.     checkerror(L, LUA);
  5480.     lua_getglobal(L, "main");// получить функцию.
  5481.     lua_pushinteger(L, 10);
  5482.     while (true) {
  5483.         int ret = lua_resume(L, L1, 1); /* Запускает и продолжает сопрограмму в данном потоке L.
  5484.     вы отправляйте в стек главную функцию и её аргументы; затем вызываете lua_resume,nargs - кол-во аргументов.
  5485.     Вызов возвращается, когда приостанавливается или завершается. При возвращении, стек содержит все значения,
  5486.     переданные в lua_yield, или возвращенныеции. Чтобы продолжить сопрограмму, вы удаляете все результаты
  5487.     из последнего lua_yield, отправьте в её стек только значения, передаваемые в качестве результатов из yield, и
  5488.     затем вызываете lua_resume.   Параметр L представляет сопрограмму, которая продолжает L. */
  5489.  
  5490.         if (ret == LUA_YIELD) {
  5491.             cout << "\n res from func my_yield "<< lua_tointeger(L, -1) << "\n\n";/*Когда lua_resume возвращает LUA_YIELD,
  5492.              стек потока содержит значения, переданные yield. число выработанных значений.*/
  5493.             lua_getglobal(L1, "foo");
  5494.             lua_xmove(L, L1, 1);/*перемещает значение Lua между двумя стеками в
  5495.             одном и том же состоянии.*/
  5496.             lua_pcall(L1, 1, 0, 0);    
  5497.  
  5498.         }
  5499.         else if (ret == 0) {/*Когда функция lua_resume возвращается, стек содержит все значения,
  5500.         переданные в lua_yield, или все значения, возвращенные телом функции.*/
  5501.             break;
  5502.         }
  5503.     };
  5504.  
  5505.     lua_close(L);
  5506.     return 0;
  5507. };
  5508.  
  5509. Вариант 2.
  5510.  
  5511. int my_yield(lua_State* L) {
  5512.     return lua_yield(L, 0);/*Эта функция должна вызываться только как возвращаемое выражение функции C следующим образом:
  5513.     return lua_yield(L, res); Когда функция C вызывает lua_yieldтаким образом, запущенная сопрограмма приостанавливает
  5514.     свое выполнение, и вызов lua_resume этой запущенной процедуры возвращается. Параметр res - это число значений из стека,
  5515.     которые передаются как результаты lua_resume.*/
  5516. };
  5517.  
  5518. const char* LUA = R"(
  5519. function foo(x1)
  5520. x= x1 * 10
  5521. print(" func foo "..x.."\n")
  5522. return x
  5523. end
  5524.  
  5525. function main(n)
  5526. for i = 1, 3 do
  5527. print(" func main "..n.."\n")
  5528. my_yield(i)
  5529. end  end
  5530. )";
  5531. int main(int argc, char* argv[]) {
  5532.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  5533.     luaL_openlibs(L);
  5534.     lua_State* L1 = lua_newthread(L);
  5535.  
  5536.     lua_register(L, "my_yield", my_yield);// регистрация функций.
  5537.     checkerror(L, LUA);
  5538.     lua_getglobal(L, "main");// получить функцию.
  5539.     lua_pushinteger(L, 10);
  5540.     while (true) {
  5541.         int ret = lua_resume(L, L1, 1); /* Запускает и продолжает сопрограмму в данном потоке L.
  5542.     вы отправляйте в стек главную функцию и её аргументы; затем вызываете lua_resume,nargs - кол-во аргументов.
  5543.     Вызов возвращается, когда приостанавливается или завершается. При возвращении, стек содержит все значения,
  5544.     переданные в lua_yield, или возвращенныеции. Чтобы продолжить сопрограмму, вы удаляете все результаты
  5545.     из последнего lua_yield, отправьте в её стек только значения, передаваемые в качестве результатов из yield, и
  5546.     затем вызываете lua_resume.   Параметр L представляет сопрограмму, которая продолжает L. */
  5547.  
  5548.         if (ret == LUA_YIELD) {
  5549.             cout << "\n res from func my_yield " << lua_tointeger(L, -1) << "\n\n";/*Когда lua_resume возвращает LUA_YIELD,
  5550.              стек потока содержит значения, переданные yield. число выработанных значений.*/
  5551.             lua_xmove(L, L1, 1);/*перемещает значение Lua между двумя стеками в
  5552.             одном и том же состоянии.*/
  5553.             lua_pop(L, 1);
  5554.             lua_getglobal(L1, "foo");
  5555.             lua_xmove(L, L1, 1);/*перемещает значение Lua между двумя стеками в
  5556.             одном и том же состоянии.*/
  5557.             lua_pcall(L1, 1, 0, 0);
  5558.         }
  5559.         else if (ret == 0) {/*Когда функция lua_resume возвращается, стек содержит все значения,
  5560.         переданные в lua_yield, или все значения, возвращенные телом функции.*/
  5561.             break;
  5562.         }
  5563.        
  5564.     };
  5565.    showstack(L1);
  5566.     lua_close(L);
  5567.     return 0;
  5568. };
  5569.  
  5570.  
  5571. Функции main и foo с циклом for, выполняются поочередно в двух потоках.
  5572.  
  5573. int my_yield2(lua_State* L) {
  5574.     return lua_yield(L, 0);/*Эта функция должна вызываться только как возвращаемое выражение функции C следующим образом:
  5575.     return lua_yield(L, res); Когда функция C вызывает lua_yieldтаким образом, запущенная сопрограмма приостанавливает
  5576.     свое выполнение, и вызов lua_resume этой запущенной процедуры возвращается. Параметр res - это число значений из стека,
  5577.     которые передаются как результаты lua_resume.*/
  5578. };
  5579.  
  5580.  
  5581. int my_yield(lua_State* L) {
  5582.     return lua_yield(L, 0);/*Эта функция должна вызываться только как возвращаемое выражение функции C следующим образом:
  5583.     return lua_yield(L, res); Когда функция C вызывает lua_yieldтаким образом, запущенная сопрограмма приостанавливает
  5584.     свое выполнение, и вызов lua_resume этой запущенной процедуры возвращается. Параметр res - это число значений из стека,
  5585.     которые передаются как результаты lua_resume.*/
  5586. };
  5587.  
  5588. const char* LUA = R"(
  5589. function foo()
  5590. for i = 1, 3 do
  5591. print(" func foo "..i.."\n")
  5592. my_yield2(i)
  5593. end
  5594. end
  5595.  
  5596. function main()
  5597. for i = 1, 3 do
  5598. print(" func main "..i.."\n")
  5599. my_yield(i)
  5600. end  end
  5601. )";
  5602. int main(int argc, char* argv[]) {
  5603.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  5604.     luaL_openlibs(L);
  5605.     lua_State* L1 = lua_newthread(L);
  5606.  
  5607.     lua_register(L, "my_yield", my_yield);// регистрация функций.
  5608.     lua_register(L, "my_yield2", my_yield2);// регистрация функций.  
  5609.     checkerror(L, LUA);
  5610.     lua_getglobal(L, "main");// получить функцию.
  5611.  
  5612.     while (true) {
  5613.         int ret = lua_resume(L, L1, 0); /* Запускает и продолжает сопрограмму в данном потоке L.
  5614.                                         Параметр L представляет сопрограмму, которая продолжает L. */
  5615.         if (ret == LUA_YIELD) {
  5616.             lua_getglobal(L1, "foo");
  5617.             lua_resume(L1, L, 0);
  5618.         }
  5619.         else if (ret == 0) {/*Когда функция lua_resume возвращается, стек содержит все значения,
  5620.         переданные в lua_yield, или все значения, возвращенные телом функции.*/
  5621.             break;
  5622.         }
  5623.  
  5624.     };
  5625.     lua_close(L);
  5626.     return 0;
  5627. };
  5628.  
  5629.  
  5630. Функции main и foo с циклом for, выполняются поочередно в двух потоках с поочередным приостановлением.
  5631.  
  5632. int my_yield(lua_State* L) {
  5633.     return lua_yield(L, 0);/*Эта функция должна вызываться только как возвращаемое выражение функции C следующим образом:
  5634.     return lua_yield(L, res); Когда функция C вызывает lua_yield таким образом, запущенная сопрограмма приостанавливает
  5635.     свое выполнение, и вызов lua_resume этой запущенной процедуры возвращается. Параметр res - это число значений из стека,
  5636.     которые передаются как результаты lua_resume.*/
  5637. };
  5638.  
  5639. const char* LUA = R"(
  5640. function main()
  5641. for i = 1, 3 do
  5642. print(" func main "..i.."\n")
  5643. my_yield()
  5644. end  end
  5645. function foo()
  5646. for i = 1, 3 do
  5647. print(" func foo "..i.."\n")
  5648. my_yield()
  5649. end end
  5650.  
  5651. )";
  5652. int main(int argc, char* argv[]) {
  5653.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  5654.     luaL_openlibs(L);
  5655.     lua_State* L1 = lua_newthread(L);
  5656.  
  5657.     lua_register(L, "my_yield", my_yield);// регистрация функций.
  5658.     checkerror(L, LUA);
  5659.     lua_getglobal(L, "main");// получить функцию.
  5660.     int ret, ret1;
  5661.     while (true) {
  5662.          ret = lua_resume(L, NULL, 0); /* Запускает и продолжает сопрограмму в данном потоке L. */
  5663.         if (ret == LUA_YIELD) {
  5664.             lua_getglobal(L1, "foo");
  5665.             ret1 = lua_resume(L1, NULL, 0);
  5666.         }
  5667.         else if ((ret == LUA_OK) || (ret1 = LUA_OK)) {break;    }
  5668.     };
  5669.  
  5670.     lua_close(L);
  5671.     return 0;
  5672. };
  5673.  
  5674. Вариант 2.
  5675.  
  5676. int my_yield(lua_State* L) {
  5677.     int args = lua_gettop(L);args++;
  5678.     lua_State* L1 = lua_newthread(L);
  5679.     lua_pushthread(L1);
  5680.     return lua_yield(L, args);/* Когда функция C вызывает lua_yield таким образом, запущенная сопрограмма приостанавливает
  5681.     свое выполнение, и вызов lua_resume этой запущенной процедуры возвращается.*/
  5682. };
  5683. int yield(lua_State* L) {return lua_yield(L, 0);/*  Параметр res - это число значений из стека,
  5684.     которые передаются как результаты lua_resume.*/
  5685. };
  5686. const char* LUA = R"(
  5687. function foo(x)    x = x or 3
  5688. print(" func foo "..x.. " \n")
  5689. for i = 1, x do
  5690. print(" func foo "..i.."\n")
  5691. yield()
  5692. end
  5693. end
  5694.  
  5695. function main()
  5696. for i = 1, 3 do
  5697. print(" func main "..i.."\n")
  5698. if i ==1
  5699. then my_yield(foo,9)
  5700. else yield()
  5701. end
  5702. end  end
  5703. )";
  5704.  
  5705. int main(int argc, char* argv[]) {
  5706.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  5707.     luaL_openlibs(L); lua_State* L1 = NULL;
  5708.     lua_register(L, "my_yield", my_yield);
  5709.     lua_register(L, "yield",  yield);
  5710.     cout << "\n";int ret, ret1;
  5711.     checkerror(L, LUA);
  5712.  
  5713.     lua_getglobal(L, "main");
  5714.     ret = lua_resume(L, NULL, 0); /* Запускает и продолжает сопрограмму в данном потоке L. */
  5715.     L1 = lua_tothread(L, -1);lua_pop(L, 1); lua_xmove(L, L1, lua_gettop(L)); lua_remove(L1, 1); int args = lua_gettop(L1);
  5716.         for (int i = 1; i > args; i++) {lua_pushvalue(L1, i);}
  5717.         args--; ret1 = lua_resume(L1, L, args); lua_xmove(L, L1, 1);
  5718.  
  5719.     while (ret =! LUA_OK) {
  5720.         ret = lua_resume(L, L1, 0); // main
  5721.     if (ret == 0) {     break;  }
  5722.     else{
  5723.         ret1 = lua_resume(L1, L, 0);// foo
  5724.     }
  5725.     };
  5726.    
  5727.     lua_close(L);
  5728.     return 0;
  5729. };
  5730.  
  5731.  
  5732.  
  5733. Многопоточнось через функцию my_yield.
  5734.  
  5735. int my_yield(lua_State* L) {
  5736.     return lua_yield(L, 0);/*Эта функция должна вызываться только как возвращаемое
  5737.    выражение функции C следующим образом: return lua_yield(L, res); */
  5738. };
  5739.  
  5740. const char* LUA = R"(
  5741. function foo()
  5742. print(" func foo \n")
  5743. end
  5744.  
  5745. function main()
  5746. for i = 1, 3 do
  5747. print(" func main "..i.."\n")
  5748. my_yield()
  5749. end  end
  5750. )";
  5751. int main(int argc, char* argv[]) {
  5752.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  5753.     luaL_openlibs(L);
  5754.  
  5755.     lua_register(L, "my_yield", my_yield);// регистрация функций.
  5756.     lua_State* L1 = lua_newthread(L);
  5757.     checkerror(L, LUA);
  5758.     lua_getglobal(L, "main");// получить функцию.
  5759.     while (true) {
  5760.         int ret = lua_resume(L, L1, 0); /* Запускает и продолжает сопрограмму в данном потоке L. */
  5761.         if (ret == LUA_YIELD) {
  5762.             lua_getglobal(L1, "foo");
  5763.             lua_pcall(L1, 0, 0, 0);
  5764.         }
  5765.         else if (ret == 0) {
  5766.             break;
  5767.         }
  5768.     };
  5769.  
  5770.     lua_close(L);
  5771.     return 0;
  5772. };
  5773.  
  5774.  
  5775. Многопоточность через строку кода.
  5776.  
  5777. void LUAHook(lua_State* L, lua_Debug* ar) {
  5778.     if (ar->currentline == 7) {
  5779.         lua_yield(L, 0);
  5780.     }
  5781. };
  5782. const char* LUA = R"(
  5783. function foo()
  5784. print(" func foo \n")
  5785. end
  5786.  
  5787. function main()
  5788. for i = 1, 3 do
  5789. print(" func main "..i.."\n")
  5790.  
  5791. end  end
  5792. )";
  5793. int main() {
  5794.     lua_State* L = luaL_newstate(); luaL_openlibs(L);
  5795.     checkerror(L, LUA);
  5796.     lua_State* L1 = lua_newthread(L);
  5797.     lua_sethook(L1, LUAHook, LUA_MASKLINE, 25); // Добавить подсчет счетчика, который сработает после указания числа
  5798.     int ret;
  5799.     lua_getglobal(L1, "main");// функция lua возобновляется с последней прерванной позиции.
  5800.     while (true) {
  5801.  
  5802.         ret = lua_resume(L1, L, 0);
  5803.         if (ret == LUA_YIELD) {
  5804.             lua_getglobal(L, "foo");
  5805.             lua_pcall(L, 0, 0, 0);
  5806.         }
  5807.         if (ret == 0) { break; }
  5808.     }
  5809.     return 0;
  5810. };
  5811.  
  5812.  
  5813. Многопоточность через таймер.
  5814.  
  5815. void LUAHook(lua_State* L, lua_Debug* ar) {
  5816.     lua_yield(L, 0);
  5817. };
  5818.  
  5819. const char* LUA = R"(
  5820. function foo()
  5821. print(" func foo \n")
  5822. end
  5823.  
  5824. function main()
  5825. for i = 1, 3 do
  5826. print(" func main "..i.."\n")
  5827. end  end
  5828. )";
  5829. int main() {
  5830.     lua_State* L = luaL_newstate(); luaL_openlibs(L);
  5831.     lua_sethook(L, LUAHook, LUA_MASKCOUNT, 6);  // Добавить подсчет счетчика, который сработает после указания числа
  5832.     checkerror(L, LUA);
  5833.     lua_State* L1 = lua_newthread(L);
  5834.     int ret;
  5835.     lua_getglobal(L, "main");// функция lua возобновляется с последней прерванной позиции.
  5836.  
  5837.     while (true) {
  5838.         if (ret = !0) {
  5839.             ret = lua_resume(L, L1, 0);
  5840.         };
  5841.  
  5842.         if (ret == LUA_YIELD ) {
  5843.             lua_getglobal(L1, "foo");
  5844.             lua_pcall(L1, 0, 0, 0);
  5845.         }
  5846.         if (ret == 0) {// Успешно завершение функции.
  5847.             break;
  5848.         }
  5849.     };
  5850.  
  5851.     return 0;
  5852. };
  5853.  
  5854.  
  5855. Многопоточность через событие строки.
  5856.  
  5857. void LUAHook(lua_State* L, lua_Debug* ar) {
  5858.     lua_yield(L, 0);};
  5859. const char* LUA = R"(
  5860. function foo()
  5861. print(" func foo \n")
  5862. end
  5863.  
  5864. function main()
  5865. for i = 1, 3 do
  5866. print(" func main "..i.."\n")
  5867.  
  5868. end  end
  5869. )";
  5870. int main() {
  5871.     lua_State* L = luaL_newstate(); luaL_openlibs(L);
  5872.     checkerror(L, LUA);
  5873.     lua_State* L1 = lua_newthread(L);
  5874.     lua_sethook(L1, LUAHook, LUA_MASKLINE, 1);  // Добавить подсчет счетчика, который сработает после указания числа
  5875.     int ret;
  5876.     lua_getglobal(L1, "main");// функция lua возобновляется с последней прерванной позиции.
  5877.     while (true) {
  5878.  
  5879.         ret = lua_resume(L1, L, 0);
  5880.         if (ret == LUA_YIELD) {
  5881.             lua_getglobal(L, "foo");
  5882.             lua_pcall(L, 0, 0, 0);
  5883.         }
  5884.         if (ret == 0) { break; }
  5885.     }
  5886.     return 0;
  5887. };
  5888.  
  5889. Многопоточность через отладчик событий.
  5890.  
  5891. void LUAHook(lua_State* L, lua_Debug* ar) {
  5892.     lua_getglobal(L, "main");  /* функция для ловушки дебага */
  5893.  
  5894.     lua_getinfo(L, ">L", ar);// таблица номеров строк с возможностю остановки.
  5895.     static vector<int>v;
  5896.     if (LUA_TTABLE == lua_type(L, -1)) {
  5897.         lua_pushvalue(L, -1);
  5898.         lua_pushnil(L);
  5899.         while (lua_next(L, -2)) {
  5900.             lua_pushvalue(L, -2);
  5901.             v.push_back((lua_tointeger(L, -1))); lua_pop(L, 2);
  5902.         }
  5903.         lua_pop(L, 1);
  5904.     };
  5905.     for (auto& i : v) {
  5906.         if (i == ar->currentline){// текущую строку можно приостановить.
  5907.     //  cout << i << endl;
  5908.             lua_yield(L, 0);
  5909.         }
  5910.     }
  5911.     v.clear();
  5912. };
  5913.  
  5914. const char* LUA = R"(
  5915. function main()
  5916. for i = 1, 3 do
  5917. print(" func main "..i.."\n")
  5918. end
  5919. end
  5920. function foo()
  5921. for i = 1, 3 do
  5922. print(" func foo "..i.."\n")
  5923. end end
  5924. )";
  5925. int main() {
  5926.     lua_State* L = luaL_newstate(); luaL_openlibs(L);
  5927.     checkerror(L, LUA);
  5928.     lua_State* L1 = lua_newthread(L);
  5929.     lua_sethook(L, LUAHook, LUA_MASKLINE, 1);   // Добавить подсчет счетчика, который сработает после указания числа
  5930.     int ret;
  5931.     lua_getglobal(L, "main");// функция lua возобновляется с последней прерванной позиции.
  5932.     while (true) {
  5933.  
  5934.         ret = lua_resume(L, NULL, 0);
  5935.         if (ret == LUA_YIELD) {
  5936.             lua_getglobal(L1, "foo");
  5937.             lua_pcall(L1, 0, 0, 0);
  5938.         }
  5939.     if (ret == 0) { break; }
  5940.     }
  5941. //      cout << ret << endl;
  5942.     return 0;
  5943. };
  5944.  
  5945. 2.
  5946. static int step = 0;
  5947. void LUAHook(lua_State* L, lua_Debug* ar) {
  5948.  
  5949.     //cout << ar->lastlinedefined << endl;
  5950.     lua_getglobal(L, "main");  /* функция для ловушки дебага */
  5951.  
  5952.     lua_getinfo(L, ">L", ar);// таблица номеров строк с возможностю остановки.
  5953.  
  5954.     static vector<int>v;
  5955.     if (LUA_TTABLE == lua_type(L, -1)) {
  5956.         lua_pushvalue(L, -1);
  5957.         lua_pushnil(L);
  5958.         while (lua_next(L, -2)) {
  5959.             lua_pushvalue(L, -2);
  5960.             v.push_back((lua_tointeger(L, -1))); lua_pop(L, 2);
  5961.         }       lua_pop(L, 1);
  5962.     };
  5963.     for (auto& i : v) {
  5964.         if (i == ar->currentline) {// текущую строку можно приостановить.
  5965.             step++;
  5966.             if (step > 2 && (i != 2) && (i != 5)) {
  5967.             lua_yield(L, 0);//  cout << i << endl;
  5968.             }
  5969.         }
  5970.     }
  5971. //  cin.get();
  5972.     v.clear();
  5973. };
  5974.  
  5975. const char* LUA = R"(
  5976. function main()
  5977. for i = 1, 3 do
  5978. print(" func main "..i.."\n")
  5979. end
  5980. end
  5981. function foo()
  5982. for i = 1, 2 do
  5983. print(" func foo "..i.."\n")
  5984. end end
  5985. )";
  5986. int main() {
  5987.     lua_State* L = luaL_newstate(); luaL_openlibs(L);
  5988.     checkerror(L, LUA);
  5989.     lua_State* L1 = lua_newthread(L);
  5990.     lua_sethook(L, LUAHook, LUA_MASKLINE, 1);   // Добавить подсчет счетчика, который сработает после указания числа
  5991.     int ret;
  5992.     lua_getglobal(L, "main");// функция lua возобновляется с последней прерванной позиции.
  5993.     while (true) {
  5994.  
  5995.         ret = lua_resume(L, NULL, 0);
  5996.         if (ret == LUA_YIELD) {
  5997.             lua_getglobal(L1, "foo");
  5998.             lua_pcall(L1, 0, 0, 0);
  5999.         }
  6000.         if (ret == LUA_OK) { break; }
  6001.     }
  6002.     //      cout << ret << endl;
  6003.     return 0;
  6004. };
  6005.  
  6006. С помощью функции hook.
  6007.  
  6008. const char* LUA = R"(
  6009. function foo()
  6010. for i = 1, 3 do
  6011. print(" func foo "..i.."\n")
  6012. end  end
  6013.  
  6014. function main()
  6015. for i = 1, 5 do
  6016. print(" func main "..i.."\n")
  6017. end  end
  6018. )";
  6019. void m(lua_State* L, const char* func1, const char* func2) {
  6020.     lua_State* L1 = lua_newthread(L);
  6021.     lua_sethook(L, LUAHook, LUA_MASKCOUNT, 6);  // Добавить подсчет счетчика, который сработает после указания числа
  6022.     lua_sethook(L1, LUAHook, LUA_MASKCOUNT, 5); // Добавить подсчет счетчика, который сработает после указания числа
  6023.     int ret;   
  6024.     lua_getglobal(L, func1);// функция lua возобновляется с последней прерванной позиции.
  6025.     lua_resume(L, L1, 0);
  6026.  
  6027.     while (true) {
  6028.         if (ret = !0) {
  6029.             ret = lua_resume(L, L1, 0);
  6030.         };
  6031.  
  6032.         if (ret == LUA_YIELD ) {
  6033.             lua_getglobal(L1, func2);
  6034.             ret = lua_resume(L1, L, 0);
  6035.         }
  6036.         if (ret == 0) {// Успешно завершение функции.
  6037.             break;
  6038.         }
  6039.     };
  6040.  
  6041. };
  6042. int main() {
  6043.     lua_State* L = luaL_newstate(); luaL_openlibs(L);
  6044.     checkerror(L, LUA);
  6045.     m(L,"main", "foo");
  6046.     return 0;
  6047. };
  6048.  
  6049. Вариант 2.
  6050.  
  6051. static int star1 = 0;
  6052. bool timer1(int t) {
  6053.     double timer = t * 0.001;
  6054.     timer -= 0.5;// Погрешность
  6055.     static  time_t start_time;
  6056.     if (star1 == 0) {
  6057.         star1++; start_time = time(NULL);
  6058.         return false;
  6059.     }
  6060.     else {
  6061.         if (time(NULL) <= start_time + timer) { return false; }
  6062.  
  6063.         else { star1 = 0;   return true; }
  6064.     }
  6065. };
  6066. static int star2 = 0;
  6067. bool timer2(int t) {
  6068.     double timer = t * 0.001;
  6069.     timer -= 0.5;// Погрешность
  6070.     static  time_t start_time;
  6071.     if (star2 == 0) {
  6072.         star2++; start_time = time(NULL);
  6073.         return false;
  6074.     }
  6075.     else {
  6076.         if (time(NULL) <= start_time + timer) { return false; }
  6077.  
  6078.         else { star2 = 0;   return true; }
  6079.     }
  6080. };
  6081. void LUAHook(lua_State* L, lua_Debug* ar) {
  6082.     if (timer1(3000)) {//На столько остановить первый поток.
  6083.         cout << "main stop " << endl;
  6084.         lua_yield(L, 0);
  6085.     }
  6086. };
  6087. void LUAHook1(lua_State* L, lua_Debug* ar) {
  6088.     if (timer2(2000)) {//На столько остановить второй поток.
  6089.         cout << "foo stop " << endl;
  6090.        lua_yield(L, 0);
  6091.     }
  6092. };
  6093.  
  6094. const char* LUA = R"(
  6095. function foo()
  6096. for i = 1, 6000 do
  6097. print(" func foo "..i.."\n")
  6098. end  end
  6099.  
  6100. function main()
  6101. i ="koi"
  6102. while true do
  6103. --for i = 1, 80000000000000000000000 do
  6104. --print(" func main "..i.."\n")
  6105. end  end
  6106. )";
  6107. void m(lua_State* L, const char* func1, const char* func2) {
  6108.     lua_State* L1 = lua_newthread(L);
  6109.     lua_sethook(L, LUAHook, LUA_MASKCOUNT, 1);  // Добавить подсчет счетчика, который сработает после указания числа
  6110.     lua_sethook(L1, LUAHook1, LUA_MASKCOUNT, 1);    // Добавить подсчет счетчика, который сработает после указания числа
  6111.     int ret,ret1;
  6112.     lua_getglobal(L, func1);// функция lua возобновляется с последней прерванной позиции.
  6113.     ret= lua_resume(L, L1, 0);
  6114.  
  6115.     while (true) {
  6116.         if (ret == LUA_YIELD) {
  6117.             lua_getglobal(L1, func2);
  6118.             ret1 = lua_resume(L1, L, 0);}
  6119.             if (ret == LUA_OK) {// Успешно завершение функции.
  6120.             cout << "end " << endl;
  6121.             break;     
  6122.         }
  6123.         if (ret1 = LUA_YIELD) {
  6124.             ret = lua_resume(L, L1, 0);
  6125.         }      
  6126.     };
  6127. };
  6128.  
  6129.  
  6130. static map<lua_State*, lua_State*> l;
  6131. int main() {
  6132.     lua_State* L = luaL_newstate(); luaL_openlibs(L);
  6133.     checkerror(L, LUA);
  6134.     m(L, "main", "foo");
  6135.     lua_close(L);
  6136.     return 0;
  6137. };
  6138.  
  6139.  
  6140. Вариант 3.
  6141.  
  6142. int hookFunc(lua_State* L, lua_Debug* ar) {
  6143.     return lua_yield(L, 0);
  6144. };
  6145.  
  6146. int hookFunc1(lua_State* L, lua_Debug* ar) {
  6147.     return lua_yield(L, 0);
  6148. };
  6149.  
  6150. const char* LUA = R"(
  6151. function foo()
  6152. for i = 1, 300 do
  6153. print(" func foo "..i.."\n")
  6154. end
  6155. end
  6156.  
  6157. function main()
  6158. for i = 1, 300 do
  6159. print(" func main "..i.."\n")
  6160. end  end
  6161. )";
  6162. int main() {
  6163.     lua_State* L = luaL_newstate(); luaL_openlibs(L);
  6164.     checkerror(L, LUA);
  6165.     lua_State* L1 = lua_newthread(L);
  6166.     int time = 80;
  6167.     int time1 = 16;
  6168.     lua_sethook(L, (lua_Hook)hookFunc, LUA_MASKCOUNT, time);    // Добавить подсчет счетчика, который сработает после указания числа
  6169.     lua_getglobal(L, "main");// функция lua возобновляется с последней прерванной позиции.
  6170.     lua_resume(L, L1, 0);
  6171.         while (LUA_OK != lua_status(L)) {   // пока поток main не завершен.
  6172.  
  6173.             if (LUA_YIELD == lua_status(L1)) {// если поток 2 на паузе.
  6174.                 lua_sethook(L1, (lua_Hook)hookFunc1, LUA_MASKCOUNT, 0);// отключить хук foo.
  6175.                 cout << " pause foo" << endl;
  6176.                 lua_sethook(L, (lua_Hook)hookFunc, LUA_MASKCOUNT, time);//включить хук для потока main.
  6177.                 lua_getglobal(L, "main");
  6178.                 lua_resume(L, L1, 0);
  6179.                 lua_sethook(L1, (lua_Hook)hookFunc1, LUA_MASKCOUNT, 0);// отключить хук foo.
  6180.             }// main
  6181.  
  6182.             if (LUA_YIELD == lua_status(L)) {// если поток main на паузе.
  6183.                 lua_sethook(L, (lua_Hook)hookFunc, LUA_MASKCOUNT, 0);// отключить хук main.
  6184.                 lua_sethook(L1, (lua_Hook)hookFunc1, LUA_MASKCOUNT, time1);// включить хук foo.
  6185.                 cout << " pause main" << endl;
  6186.                 lua_getglobal(L1, "foo");
  6187.                 lua_resume(L1, L, 0);// foo
  6188.                 lua_sethook(L1, (lua_Hook)hookFunc1, LUA_MASKCOUNT, 0);// отключить хук foo.
  6189.             }
  6190.  
  6191.             if (LUA_OK == lua_status(L1)) {// если поток foo завершен.
  6192.                 cout << "foo end " << endl;
  6193.                 lua_sethook(L, (lua_Hook)hookFunc, LUA_MASKCOUNT, 0);// отключить хук main.
  6194.                 lua_sethook(L1, (lua_Hook)hookFunc1, LUA_MASKCOUNT, 0);// отключить хук foo.
  6195.                 lua_resume(L, NULL, 0);
  6196.             }
  6197.             if (LUA_OK == lua_status(L)) { break; }// если поток main  завершен.  
  6198.  
  6199.         };
  6200.  
  6201.     return 0;
  6202. };
  6203.  
  6204. С помощью класса.
  6205.  
  6206.  
  6207. struct ScriptRunner_impl {
  6208.     lua_State* L = nullptr;
  6209. };
  6210. class ScriptRunner
  6211. {
  6212. public:
  6213.     ScriptRunner(lua_State* L, const char* funcrun, unsigned int Count) : m_L(L), m_funcrun(funcrun),
  6214.         m_Count(Count), m_pScriptRunner_impl(make_unique<ScriptRunner_impl>()) {
  6215.         m_pScriptRunner_impl->L = L;    // Add a count hook that will trigger after "count" number instructions
  6216.         lua_sethook(m_pScriptRunner_impl->L, LUAHook, LUA_MASKCOUNT, m_Count);
  6217.     }
  6218.        
  6219.     void Update(float dt);
  6220.     ~ScriptRunner(){}
  6221. private:
  6222.     lua_State*        m_L;
  6223.     const char*       m_funcrun;
  6224.     unsigned int      m_Count;
  6225.     unique_ptr<ScriptRunner_impl> m_pScriptRunner_impl = nullptr;
  6226. };
  6227.  
  6228. int func_block(lua_State* L, const char* functionName) {
  6229.     int errorState = lua_getglobal(L, functionName);    // lua function is resumed from the last interrupted position.
  6230.     errorState = lua_resume(L, L, 0);
  6231.     if (errorState == LUA_YIELD) {  // lua function execution is interrupted.
  6232.         return 1;
  6233.     }
  6234.     else if (errorState == LUA_OK) {// lua function is returned successfully.
  6235.         return 0;
  6236.     }
  6237. };
  6238. void ScriptRunner::Update(float dt) {
  6239.     // Update a lua function with preemptive scheduling.
  6240.     int status = func_block(m_pScriptRunner_impl->L, m_funcrun);
  6241.     if (status == 0) {  // lua function executed successfully.
  6242.         return; }// Run the non script loop
  6243. };
  6244.  
  6245.  
  6246. const char* LUA = R"(
  6247. function main()
  6248. i = 0;
  6249. while i < 800 do
  6250.  i = i + 1;
  6251.   print("lua script in control, stack variable count = ", i)   
  6252.  end
  6253. end
  6254. )";
  6255. int main(int argc, char* argv[]) {
  6256.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  6257.     luaL_openlibs(L);
  6258.     int ret = luaL_dostring(L, LUA);
  6259.     ScriptRunner scriptRunner(L, "main", 100);
  6260.     scriptRunner.Update(1);
  6261.     cout << " 2 loop " << endl;
  6262.     scriptRunner.Update(1);
  6263.     cout << " 3 loop " << endl;
  6264.     scriptRunner.Update(1);
  6265.     return 0;
  6266. };
  6267.  
  6268. Вариант 2.
  6269.  
  6270.  
  6271. int yield(lua_State* L) {
  6272.    
  6273.     return lua_yield(L, 0);/*  Параметр res - это число значений из стека,
  6274.     которые передаются как результаты lua_resume.*/
  6275. };
  6276. void LUAHook(lua_State* L, lua_Debug* ar) {
  6277.     lua_yield(L, 0);
  6278. };
  6279.  
  6280. struct ScriptRunner_impl {
  6281.     lua_State* L = nullptr;
  6282. };
  6283. class ScriptRunner{
  6284. public:
  6285.     ScriptRunner(lua_State* L, const char* funcrun, unsigned int Count) : m_L(L), m_funcrun(funcrun),
  6286.         m_Count(Count), m_pScriptRunner_impl(make_unique<ScriptRunner_impl>()) {
  6287.         m_pScriptRunner_impl->L = L;    // Add a count hook that will trigger after "count" number instructions
  6288.         lua_sethook(m_pScriptRunner_impl->L, LUAHook, LUA_MASKCOUNT, m_Count);
  6289.     }
  6290.  
  6291.     void Update(float dt);
  6292.     ~ScriptRunner() {}
  6293. private:
  6294.     lua_State* m_L;
  6295.     const char* m_funcrun;
  6296.     unsigned int m_Count;
  6297.     unique_ptr<ScriptRunner_impl> m_pScriptRunner_impl = nullptr;
  6298. };
  6299.  
  6300. int func_block(lua_State* L, const char* functionName) {
  6301.     int errorState = lua_getglobal(L, functionName);    // lua function is resumed from the last interrupted position.
  6302.     errorState = lua_resume(L, L, 0);
  6303.     if (errorState == LUA_YIELD) {  // lua function execution is interrupted.
  6304.         return 1;
  6305.     }
  6306.     else if (errorState == LUA_OK) {// lua function is returned successfully.
  6307.         return 0;
  6308.     }
  6309. };
  6310. void ScriptRunner::Update(float dt) {
  6311.     // Update a lua function with preemptive scheduling.
  6312.     int status = func_block(m_pScriptRunner_impl->L, m_funcrun);
  6313.     if (status == 0) {  // lua function executed successfully.
  6314.         return;
  6315.     }// Run the non script loop
  6316. };
  6317.  
  6318.  
  6319. int my_yield(lua_State* L) {
  6320.     int args = lua_gettop(L);args++;
  6321.     lua_State* L1 = lua_newthread(L);
  6322.     lua_pushthread(L1);
  6323.     return lua_yield(L, args);/* Когда функция C вызывает lua_yield таким образом, запущенная сопрограмма приостанавливает
  6324.     свое выполнение, и вызов lua_resume этой запущенной процедуры возвращается.*/
  6325. };
  6326. const char* LUA = R"(
  6327. function foo(x)    x = x or 3
  6328. print(" func foo "..x.. " \n")
  6329. for i = 1, x do
  6330. print(" func foo "..i.."\n")
  6331. yield()
  6332. end
  6333. end
  6334.  
  6335. function main()
  6336. for i = 1, 1200 do
  6337. print(" func main "..i.."\n")
  6338. if i ==3
  6339. then my_yield(foo,3150)
  6340. end
  6341. end  end
  6342. )";
  6343. int main(int argc, char* argv[]) {
  6344.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  6345.     luaL_openlibs(L); lua_State* L1 = NULL;
  6346.     lua_register(L, "my_yield", my_yield);
  6347.     lua_register(L, "yield",  yield);
  6348.     cout << "\n"; checkerror(L, LUA);
  6349.     lua_getglobal(L, "main");
  6350.     lua_resume(L, NULL, 0); /* Запускает и продолжает сопрограмму в данном потоке L. */
  6351.     L1 = lua_tothread(L, -1); lua_pop(L, 1); lua_xmove(L, L1, lua_gettop(L));lua_remove(L1, 1);
  6352.     int args = lua_gettop(L1);//    cout << args << endl;// Аргументы.
  6353.    
  6354.         for (int i = 1; i > args; i++) {lua_pushvalue(L1, i);}
  6355.         args--;  lua_resume(L1, L, args);   lua_xmove(L, L1, 1);
  6356.   while ( LUA_OK != lua_status(L)) {    // пока поток main не завершен.
  6357.  
  6358.       if (LUA_YIELD == lua_status(L1)) {// если поток 2 на паузе.
  6359.           cout << " pause foo" << endl;
  6360.          
  6361.           ScriptRunner scriptRunner(L, "main", 10);
  6362.           scriptRunner.Update(1);
  6363.           lua_sethook(L, LUAHook, LUA_MASKCOUNT, 0);// отключить хук main.
  6364.         //  cin.get();
  6365.       };// main
  6366.        
  6367.        if (LUA_YIELD == lua_status(L) && LUA_OK != lua_status(L1)){// если поток main на паузе.
  6368.            lua_sethook(L, LUAHook, LUA_MASKCOUNT, 0);// отключить хук main.
  6369.          cout << " pause main" << endl;
  6370.          lua_resume(L1, NULL, 0);// foo
  6371.        
  6372.         }
  6373.  
  6374.     if (LUA_OK == lua_status(L1)) {// если поток foo  завершен.   
  6375.         lua_sethook(L, LUAHook, LUA_MASKCOUNT, 0);// отключить хук main.
  6376.     //  cout << "foo end " << endl;
  6377.         lua_resume(L, NULL, 0); cout << lua_status(L) << endl; //break;
  6378.  
  6379.     }
  6380.     if (LUA_OK == lua_status(L)) { break; }// если поток main  завершен.  
  6381. };
  6382.     lua_close(L);
  6383.     return 0;
  6384. };
  6385.  
  6386. Функция продолжения.
  6387.  
  6388. Вариант 1.
  6389.  
  6390.  
  6391.  
  6392. int hookFunc(lua_State* L, lua_Debug* ar) {
  6393.     return lua_yield(L, 0);
  6394. };
  6395.  
  6396. int hookFunc1(lua_State* L, lua_Debug* ar) {
  6397.     return lua_yield(L, 0);
  6398. };
  6399.  
  6400. /*Внутри себя, Lua использует возможность C - ишного longjmp для выхода(приостановки выполнения) из сопрограммы.
  6401. Поэтому, если C - ишная функция foo вызывает функцию API и эта функция API приостанавливает выполнение(непосредственно
  6402. сама или косвенно вызывая другую функцию, которая делает выход), Lua не может ничего больше возвратить в foo,
  6403. потому что longjmp удалил его фрейм из C - ишного стека. Во избежание проблем такого рода, Lua выдает ошибку всякий раз
  6404. при попытке выхода через вызов API, за исключением трех функций : lua_yieldk, lua_callk, и lua_pcallk.
  6405. Все эти функции принимают функцию - продолжение(в качестве параметра с именем k) чтобы продолжить выполнение после выхода.
  6406. Чтобы объяснить продолжения, следует установить некоторую терминологию. У нас есть функция C вызываемая из Lua,
  6407. которую мы будем называть исходной функцией. Эта исходная функция затем вызывает одну из этих трех функций в С - ишном API,
  6408. которая будет называться вызываемой функцией, которая затем приостанавливает выполнение текущего потока.
  6409. (Это может произойти, когда вызываемой функцией является lua_yieldk, или, когда вызываемая функция - либо lua_callk,
  6410. либо lua_pcallk, а функция, вызванная ими, приостанавливает выполнение.)
  6411.  
  6412. Предположим, что работающий поток приостанавливается на время выполнения вызываемой функции. После возобновления
  6413. работы потока, она, в конечном счете, завершит работу вызываемой функции. Однако, вызываемая функция не может
  6414. возвратиться к исходной функции, так как её фрейм в С - ишном стеке был разрушен приостановкой выполнения потока.
  6415. Вместо этого, Lua вызывает функцию продолжения(continuation function), которая будет задана в качестве аргумента
  6416. вызываемой функции. Как следует из названия, функция продолжения должна продолжить задачу исходной функции.
  6417.  
  6418. В качестве иллюстрации, рассмотрим следующую функцию :
  6419. int original_function(lua_State* L) { code 1
  6420.         status = lua_pcall(L, n, m, h);   calls Lua
  6421.  code 2 }
  6422. Теперь нужно позволить коду Lua запустить lua_pcall для приостановки. Во - первых, можно переписать нашу функцию вот так :
  6423. int k(lua_State* L, int status, lua_KContext ctx) {
  6424.      code 2
  6425. }
  6426. int original_function(lua_State* L) {
  6427.     ...   code 1
  6428.     return k(L, lua_pcall(L, n, m, h), ctx);
  6429. }
  6430. В приведенном выше коде, новая функция k является функцией продолжения(с типом lua_KFunction), которая должна выполнять
  6431. всю работу, что делала исходная функция после вызова lua_pcall.Теперь нужно сообщить Lua, что он должен вызывать k,
  6432. если код Lua выполняемый lua_pcall прерывается каким - то образом(ошибки или выход), так что можно переписать код
  6433. следующим образом, заменив lua_pcall на lua_pcallk :
  6434. int original_function(lua_State* L) {
  6435.      code 1
  6436.      return k(L, lua_pcallk(L, n, m, h, ctx2, k), ctx1);
  6437. }
  6438. Обратите внимание на внешний, явный вызов продолжения : Lua вызовет продолжение только при необходимости, то есть,
  6439. в случае ошибок или возобновления после выхода из выполнения.Если вызванная функция возвращается как обычно без
  6440. приостановки выполнения когда - либо, lua_pcallk(и lua_callk) также будет возвращаться нормально.
  6441. (Конечно, в данном случае вместо вызова продолжения можно сделать аналогичную работу непосредственно внутри исходной функции.)
  6442.  
  6443. Помимо Lua состояния, функция продолжения имеет два других параметра : конечное состояние вызова плюс значение контекста(ctx),
  6444. которые первоначально были переданы lua_pcallk. (Lua не использует это значение контекста; он только передает это значение из
  6445. исходной функции в функцию продолжения.) При выполнении после приостановки, для lua_pcallk, состоянием является тоже самое значение,
  6446. что было бы возвращено lua_pcallk, за исключением того, что это LUA_YIELD(вместо LUA_OK).Когда Lua вызывает продолжение,
  6447. для lua_yieldk и lua_callk, состоянием всегда будет LUA_YIELD. (Для этих двух функций, Lua не будет вызывать продолжения
  6448. в случае ошибок, так как они не обрабатывают ошибки.) Точно также, при использовании lua_callk, следует вызывать функцию
  6449. продолжения с LUA_OK в качестве состояния. (Для lua_yieldk, в прямом вызове функции продолжения нет особого смысла, поскольку
  6450. lua_yieldk обычно ничего не возвращает.)
  6451.  
  6452. Lua рассматривает функцию продолжения как если бы она была исходной функцией. Функция продолжения принимает тот
  6453. же самый Lua стек от исходной функции, в том же самом состоянии, как если бы он был возвращен вызываемой функцией.
  6454. (Например, после lua_callk функция и её аргументы удаляются из стека и заменяются результатами из вызова.)
  6455. Она также имеет те же самые внешние локальные переменные.Все что она возвращает, обрабатывается Lua как если
  6456. бы это было возвращено исходной функцией.*/
  6457. lua_KFunction cont(lua_State* L){
  6458.     showstack(L); lua_getglobal(L, "f");// получить функцию.
  6459.     lua_pcall(L, 0, NULL, 0);
  6460.     return 0;
  6461. }
  6462.  
  6463. int my_yield(lua_State* L) {
  6464.     cout << " lua  yielding... " << lua_tointeger(L, -1) << "\n";
  6465.     //lua_pushinteger(L, lua_tointeger(L, -1) * 2);
  6466.     return lua_yieldk(L, 0, lua_yield(L, 0), cont(L));/* int lua_yieldk(lua_State * L, int res, lua_KContext ctx, lua_KFunction k);
  6467.     Приостанавливает выполнение сопрограммы(поток).   Когда функция C вызывает lua_yieldk, работающая
  6468.     сопрограмма приостанавливает свое выполнение и вызывает lua_resume, которая начинает возврат данной сопрограммы.
  6469.     Параметр res - это число значений из стека, которые будут переданы в качестве результатов в lua_resume.
  6470.     Когда сопрограмма снова возобновит выполнение, Lua вызовет заданную функцию продолжения k для продолжения выполнения
  6471.     приостановленной C функции(смотрите §4.7). Эта функция продолжения получит тот же самый стек от предыдущей функции,
  6472.     с n - ным числом результатов, удаленных и замененных посредством аргументов, переданных в lua_resume. Кроме того,
  6473.     функция продолжения получает значение ctx, которое было передано в lua_yieldk. Как правило, эта функция ничего
  6474.     не возвращает; когда сопрограмма в конце концов возобновляется, она продолжает выполнение функции продолжения.
  6475.     Тем не менее, существует один особый случай, который появляется когда эта функция вызывается внутри строковой
  6476.     ловушки(смотрите §4.9).В этом случае, lua_yieldk следует вызывать без продолжения(вероятно в виде lua_yield),
  6477.     и ловушка должна возвращать сразу после вызова.Lua будет приостановлена и, когда сопрограмма снова возобновит
  6478.     выполнение, продолжит нормальное выполнение функции(Lua), которая вызвала ловушку.   Данная функция может выдавать
  6479.     ошибку, если она вызвана из нити(thread) с ожиданием C вызова без функции продолжения или из нити, которая не работает
  6480.     внутри возобновления(например, основная нить).*/
  6481. };
  6482. const char* LUA = R"(
  6483. function f()
  6484. print("func f ")
  6485. end
  6486.  
  6487. function foo(x)
  6488. print("func foo "..x.."\n")
  6489. end
  6490.  
  6491. function main()
  6492. for i = 1, 3 do
  6493. my_yield(10)
  6494. end  end
  6495. )";
  6496. int main(int argc, char* argv[]) {
  6497.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  6498.     luaL_openlibs(L);
  6499.     lua_State* L1 = lua_newthread(L);
  6500.  
  6501.     lua_register(L, "my_yield", my_yield);// регистрация функций.
  6502.     checkerror(L, LUA);
  6503.     lua_getglobal(L, "main");// получить функцию.
  6504.     while (true) {
  6505.         int ret = lua_resume(L, L1, 0); /* Запускает и продолжает сопрограмму в данном потоке L.
  6506.     вы отправляйте в стек главную функцию и её аргументы; затем вызываете lua_resume,nargs - кол-во аргументов.
  6507.     Вызов возвращается, когда приостанавливается или завершается. При возвращении, стек содержит все значения,
  6508.     переданные в lua_yield, или возвращенныеции. Чтобы продолжить сопрограмму, вы удаляете все результаты
  6509.     из последнего lua_yield, отправьте в её стек только значения, передаваемые в качестве результатов из yield, и
  6510.     затем вызываете lua_resume.   Параметр L представляет сопрограмму, которая продолжает L. */
  6511.  
  6512.         if (ret == LUA_YIELD) {
  6513.             lua_getglobal(L1, "foo");
  6514.             lua_xmove(L, L1, 1);
  6515.             lua_resume(L1, L, 1);
  6516.         }
  6517.         else if (ret == 0) {/*Когда функция lua_resume возвращается, стек содержит все значения,
  6518.         переданные в lua_yield, или все значения, возвращенные телом функции.*/
  6519.         //showstack(L);
  6520.             break;
  6521.         }
  6522.     };
  6523.  
  6524.  
  6525.     lua_close(L);
  6526.     return 0;
  6527. };
  6528.  
  6529. Вариант 2.
  6530.  
  6531. lua_KFunction cont(lua_State* L);
  6532. int yield(lua_State* L) {
  6533.     return lua_yield(L, 0);/*  Параметр res - это число значений из стека,
  6534. которые передаются как результаты lua_resume.*/
  6535. };
  6536.  
  6537. int my_yield(lua_State* L, int yieid) {
  6538.     return lua_yieldk(L, 0, lua_yield(L, 0), cont(L));/* int lua_yieldk(lua_State * L, int res, lua_KContext ctx, lua_KFunction k);
  6539.     Приостанавливает выполнение сопрограммы(поток).   Когда функция C вызывает lua_yieldk, работающая
  6540.     сопрограмма приостанавливает свое выполнение и вызывает lua_resume, которая начинает возврат данной сопрограммы.
  6541.     Параметр res - это число значений из стека, которые будут переданы в качестве результатов в lua_resume.
  6542.     Когда сопрограмма снова возобновит выполнение, Lua вызовет заданную функцию продолжения k для продолжения выполнения
  6543.     приостановленной C функции(смотрите §4.7). */
  6544. };
  6545. int hookFunc(lua_State* L, lua_Debug* ar) { return my_yield(L, 0);// хук./
  6546. };
  6547.  
  6548. lua_KFunction cont(lua_State* L) {// функция продолжения.
  6549.     if (LUA_YIELD == lua_status(L)) {
  6550.     cout << " off hook "<< L << endl;
  6551.         lua_sethook(L, (lua_Hook)hookFunc, LUA_MASKCOUNT, 0);// отключить хук foo.
  6552.     }
  6553.     return 0;
  6554. };
  6555.  
  6556. const char* LUA = R"(
  6557. function foo()
  6558. for i = 1, 13 do
  6559. print(" func foo "..i.."\n")
  6560. end
  6561. end
  6562.  
  6563. function main()
  6564. for i = 1, 13 do
  6565. print(" func main "..i.."\n")
  6566. end  end
  6567. )";
  6568. int main() {
  6569.     lua_State* L = luaL_newstate(); luaL_openlibs(L);
  6570.     checkerror(L, LUA);
  6571.     lua_State* L1 = lua_newthread(L);
  6572.     int time = 10;// сколько работает main.
  6573.     int time1 = 8;// сколько работает foo.
  6574.     lua_sethook(L, (lua_Hook)hookFunc, LUA_MASKCOUNT, time);// хух для main.
  6575.     lua_getglobal(L, "main");
  6576.     lua_resume(L, L1, 0);
  6577.     while (LUA_OK != lua_status(L)) {   // пока поток main не завершен.
  6578.  
  6579.         if (LUA_YIELD == lua_status(L1)) {// если поток 2 на паузе.
  6580.             cout << " pause foo" << endl;
  6581.             lua_sethook(L, (lua_Hook)hookFunc, LUA_MASKCOUNT, time);//включить хук для потока main.
  6582.             lua_resume(L, L1, 0);
  6583.         }// main.
  6584.  
  6585.         if (LUA_YIELD == lua_status(L)) {// если поток main на паузе.
  6586.             lua_sethook(L1, (lua_Hook)hookFunc, LUA_MASKCOUNT, time1);// включить хук foo.
  6587.             cout << " pause main" << endl;
  6588.             lua_getglobal(L1, "foo");
  6589.             lua_resume(L1, L, 0);
  6590.         }// foo.
  6591.  
  6592.         if (LUA_OK == lua_status(L1)) {// если поток foo завершен.
  6593.             cout << "foo end " << endl;
  6594.             lua_resume(L, NULL, 0);
  6595.         }
  6596.         if (LUA_OK == lua_status(L)) { // если поток main  завершен.
  6597.             cout << "  main ok" << endl;
  6598.             break;
  6599.         }  
  6600.     };
  6601.  
  6602.     return 0;
  6603. };
  6604.  
  6605.  
  6606.  
  6607.  
  6608.  
  6609.  
  6610.  
  6611.  
  6612.  
  6613. void LUAHook(lua_State* L, lua_Debug* ar) {
  6614.     lua_yield(L, 0);
  6615. };
  6616.  const char* LUA = R"(
  6617. function foo()
  6618. for i = 1, 4 do
  6619. print(" func foo \n")
  6620. end end
  6621.  
  6622. function main()
  6623. for i = 1, 3 do
  6624. print(" func main "..i.."\n")
  6625. if j == nil
  6626. then
  6627. foo1()
  6628. j=1
  6629. end
  6630. end  end
  6631. )";
  6632. int foo1(lua_State* L) {
  6633.     lua_State* L1 = lua_newthread(L);
  6634.     lua_sethook(L, LUAHook, LUA_MASKLINE, 1);
  6635.     lua_getglobal(L1, "foo");
  6636.     lua_sethook(L1, LUAHook, LUA_MASKLINE, 1);
  6637.     lua_resume(L1, L, 0);
  6638.  
  6639.  
  6640. return  0;
  6641. };
  6642. int main() {
  6643.     lua_State* L = luaL_newstate(); luaL_openlibs(L);
  6644.     lua_register(L, "foo1", foo1);
  6645.     luaL_dostring(L, LUA);
  6646.     int ret;
  6647.     lua_getglobal(L, "main");// функция lua возобновляется с последней
  6648.     //  прерванной позиции.
  6649.     ret = lua_resume(L, NULL, 0);
  6650.  
  6651.  
  6652.     return 0;
  6653. };
  6654.  
  6655.  
  6656. Что в lua файле.
  6657.  
  6658.  
  6659. void LUAHook(lua_State* L, lua_Debug* ar) {
  6660.     lua_getglobal(L, "main");  /* get global 'f' */
  6661.     lua_getinfo(L, ">S", ar);
  6662.     printf("%s\n", ar->source); /* (n) */
  6663.  
  6664. lua_Debug
  6665. typedef struct lua_Debug {
  6666.   int event;
  6667.   const char *name;           /* (n) */
  6668.   const char *namewhat;       /* (n) */
  6669.   const char *what;           /* (S) */
  6670.   const char *source;         /* (S) */
  6671.   int currentline;            /* (l) */
  6672.   int linedefined;            /* (S) */
  6673.   int lastlinedefined;        /* (S) */
  6674.   unsigned char nups;         /* (u) число upvalue */
  6675.   unsigned char nparams;      /* (u) число параметров */
  6676.   char isvararg;              /* (u) */
  6677.   char istailcall;            /* (t) */
  6678.   char short_src[LUA_IDSIZE]; /* (S) */
  6679.   /* private part (отдельная часть) */
  6680.   other fields (другие поля)
  6681. } lua_Debug;
  6682. Структура, используемая для переноса различных частей сведений о функции или записи активации. lua_getstack заполняет только отдельную часть этой структуры, для последующего использования. Для наполнения полезной информацией других полей lua_Debug, вызывайте функцию lua_getinfo.
  6683.  
  6684. Поля структуры lua_Debug имеют следующее значение:
  6685. source: имя порции (chunk), которая создала функцию. Если source начинается с '@', это значит что функция была определена в файле, где за символом '@' следует имя файла. Если source начинается с '=', то остальная часть его содержимого описана исходником, зависимым от пользователя. В противном случае, функция была определена в строке, где source является этой строкой.
  6686. short_src: "печатабельная" версия source, для использования в сообщениях об ошибках.
  6687. linedefined: номер строки, с которой начинается определение функции.
  6688. lastlinedefined: номер строки, на которой оканчивается определение функции.
  6689. what: строка "Lua", если функция является Lua функцией, "C" - если это C функция, "main" - если это основная часть порции (chunk).
  6690. currentline: текущая строка, где выполняется данная функция. Если нет доступных сведений о строке, currentline устанавливается равной -1.
  6691. name: допустимое имя для заданной функции. Так как функции в Lua являются значениями первого класса, у них нет фиксированного имени: некоторые функции могут быть значением нескольких глобальных переменных, в то время как другие могут только сохраняться в поле таблицы. Функция lua_getinfo проверяет, как функция была названа для поиска соответствующего имени. Если имя найти не удается, то name устанавливается как NULL.
  6692. namewhat: поясняет поле name. Значением namewhat может быть "global", "local", "method", "field", "upvalue", или "" (пустая строка), в соответствии с тем, как функция была вызвана. (Lua использует пустую строку когда нет другого выбора, представленного к применению.)
  6693. istailcall: значение true, если данный вызов функции был вызван хвостовым вызовом. В этом случае, функция, вызывающая этот уровень не находится в стеке.
  6694. nups: число внешних локальных переменных (upvalue) функции.
  6695. nparams: число фиксированных (установленных) параметров функции (для C-ишных функций значение всегда равно 0).
  6696. isvararg: значение true, если у функции переменное число аргументов т.е. vararg функция (для C-ишных функций значение всегда истинно).
  6697.  
  6698. void LUAHook(lua_State* L, lua_Debug* ar) {
  6699.     lua_getglobal(L, "main");  /* функция для ловушки дебага */
  6700.     lua_getinfo(L, ">L", ar);// таблица номеров строк с возможностю остановки.
  6701.     static vector<int>v;
  6702.     if (LUA_TTABLE == lua_type(L, -1)) {
  6703.         lua_pushvalue(L, -1);
  6704.         lua_pushnil(L);
  6705.         while (lua_next(L, -2)) {
  6706.             lua_pushvalue(L, -2);
  6707.             v.push_back((lua_tointeger(L, -1))); lua_pop(L, 2);
  6708.         }
  6709.         lua_pop(L, 2);
  6710.     };
  6711.     for (auto& i : v) {
  6712.         if (i == ar->currentline ){// текущую строку можно приостановить.
  6713.             lua_yield(L, 0);
  6714.         }
  6715.     }
  6716.     v.clear();
  6717. };
  6718.  
  6719. const char* LUA = R"(
  6720. function foo()
  6721. for i = 1, 2 do
  6722. print(" func foo "..i.."\n")
  6723. end end
  6724. function main()
  6725. for i = 1, 2 do
  6726. print(" func main "..i.."\n")
  6727. end
  6728. end
  6729. )";
  6730. int main() {
  6731.     lua_State* L = luaL_newstate(); luaL_openlibs(L);
  6732.     checkerror(L, LUA);
  6733.     lua_State* L1 = lua_newthread(L);
  6734.     int ret;
  6735.     lua_sethook(L, LUAHook, LUA_MASKLINE, 1);   // Добавить подсчет счетчика, который сработает после указания числа
  6736.     lua_getglobal(L, "main");// функция lua возобновляется с последней прерванной позиции.
  6737.  
  6738.     while (true) {
  6739.  
  6740.         ret = lua_resume(L, L1, 0);
  6741.         if (ret == LUA_YIELD) {
  6742.             lua_getglobal(L1, "foo");
  6743.             lua_pcall(L1, 0, 0, 0);
  6744.         }
  6745.     if (ret == 0) { break; }
  6746.     }
  6747.     return 0;
  6748. };
  6749. int checkerror(lua_State* L, const char* file) {
  6750.     int status = luaL_loadfile(L, file);// проверка есть ли ошибки.
  6751.     try {
  6752.         if (luaL_dostring(L, file) == LUA_OK) {
  6753.             return 0;
  6754.         }
  6755.         else {
  6756.             string x = lua_tostring(L, -1);
  6757.             throw x;
  6758.             return 0;
  6759.         }
  6760.     }
  6761.     catch (string x) {
  6762.         cout << x << endl;
  6763.         return 0;
  6764.     }
  6765.     return 0;
  6766. };
  6767. void LUAHook(lua_State* L, lua_Debug* ar) {
  6768.     lua_yield(L, 0);
  6769. };
  6770.  
  6771. const char* LUA = R"(
  6772. function foo()
  6773. for i = 1, 6 do
  6774. print(" func foo "..i.."\n")
  6775. end  end
  6776.  
  6777. function main()
  6778. for i = 1, 9 do
  6779. print(" func main "..i.."\n")
  6780. end  end
  6781. )";
  6782. void m(lua_State* L, const char* func1, const char* func2) {
  6783.     lua_State* L1 = lua_newthread(L);
  6784.     lua_sethook(L, LUAHook, LUA_MASKCOUNT, 6);  // Добавить подсчет счетчика, который сработает после указания числа
  6785.     lua_sethook(L1, LUAHook, LUA_MASKCOUNT, 5); // Добавить подсчет счетчика, который сработает после указания числа
  6786.     int ret;   
  6787.     lua_getglobal(L, func1);// функция lua возобновляется с последней прерванной позиции.
  6788.     lua_resume(L, L1, 0);
  6789.  
  6790.     while (true) {
  6791.         if (ret = !0) {
  6792.             ret = lua_resume(L, L1, 0);
  6793.         };
  6794.  
  6795.         if (ret == LUA_YIELD ) {
  6796.             lua_getglobal(L1, func2);
  6797.             ret = lua_resume(L1, L, 0);
  6798.         }
  6799.         if (ret == 0) {// Успешно завершение функции.
  6800.             break;
  6801.         }
  6802.     };
  6803.  
  6804. };
  6805. int main() {
  6806.     lua_State* L = luaL_newstate(); luaL_openlibs(L);
  6807.     checkerror(L, LUA);
  6808.     lua_getglobal(L, "main");// функция lua возобновляется с последней прерванной позиции.
  6809.     lua_resume(L, NULL, 0);
  6810.     m(L,"main", "foo");
  6811.     return 0;
  6812. };
  6813.  
  6814. Вариант 2.
  6815.  
  6816.  
  6817. static int s = 0;
  6818. void LUAHook(lua_State* L, lua_Debug* ar) {
  6819.     s++;
  6820.     if (s > 25) {   //cout << s << endl;
  6821.         s = 0;
  6822.         lua_yield(L, 0);
  6823.     }
  6824. };
  6825. static int s1 = 0;
  6826. void LUAHook1(lua_State* L, lua_Debug* ar) {
  6827.     s1++;
  6828.     if (s1 > 5) {   //cout << s << endl;
  6829.         s1 = 0;
  6830.         lua_yield(L, 0);
  6831.     }
  6832. };
  6833.  
  6834. const char* LUA = R"(
  6835. function foo()
  6836. for i = 1, 6 do
  6837. print(" func foo "..i.."\n")
  6838. end  end
  6839.  
  6840. function main()
  6841. for i = 1, 109 do
  6842. print(" func main "..i.."\n")
  6843. end  end
  6844. )";
  6845. void m(lua_State* L, const char* func1, const char* func2) {
  6846.     lua_State* L1 = lua_newthread(L);
  6847.     lua_sethook(L, LUAHook, LUA_MASKCOUNT, 1);  // Добавить подсчет счетчика, который сработает после указания числа
  6848.     lua_sethook(L1, LUAHook1, LUA_MASKCOUNT, 1);    // Добавить подсчет счетчика, который сработает после указания числа
  6849.     int ret;
  6850.     lua_getglobal(L, func1);// функция lua возобновляется с последней прерванной позиции.
  6851.     lua_resume(L, L1, 0);
  6852.  
  6853.     while (true) {
  6854.         if (ret = !0) {
  6855.             ret = lua_resume(L, L1, 0);
  6856.         };
  6857.  
  6858.         if (ret == LUA_YIELD) {
  6859.             lua_getglobal(L1, func2);
  6860.             ret = lua_resume(L1, L, 0);
  6861.         }
  6862.         if (ret == 0) {// Успешно завершение функции.
  6863.             break;
  6864.         }
  6865.     };
  6866.  
  6867. };
  6868. int main() {
  6869.     lua_State* L = luaL_newstate(); luaL_openlibs(L);
  6870.     checkerror(L, LUA);
  6871.     //lua_getglobal(L, "main");// функция lua возобновляется с последней прерванной позиции.
  6872.     //.lua_resume(L, NULL, 0);
  6873.     m(L, "main", "foo");
  6874.     return 0;
  6875. };
  6876.  
  6877.  
  6878. Сохранение потока в реестре.
  6879.  
  6880.     lua_State* L1 = lua_newthread(L);
  6881.     lua_pushthread(L);
  6882.     lua_rawseti(L, LUA_REGISTRYINDEX, 2);/* установить в таблице*/
  6883.     cout << L << endl;
  6884.  
  6885.     pushlua(L, 2);
  6886.     lua_rawget(L, LUA_REGISTRYINDEX); /* получить таблицу и значение ключа будет в -1 */
  6887.     lua_State* L2 = lua_tothread(L, -1);
  6888.     cout << L2 << endl;
  6889.  
  6890.  
  6891.  
  6892.  
  6893.  
  6894. int my_yield(lua_State* L) {
  6895.     lua_yield(L, 1);
  6896.     return 1;
  6897. }
  6898. const char* LUA = R"(
  6899. function foo()
  6900.   print("  foo")
  6901. end
  6902.  
  6903. function main()
  6904. for i = 1, 3 do
  6905.   print(" main".."\n")
  6906. my_yield()
  6907. end  end
  6908. )";
  6909. int main(int argc, char* argv[]) {
  6910.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  6911.     luaL_openlibs(L);
  6912.     lua_register(L, "my_yield", my_yield);
  6913.     lua_State* L1 = lua_newthread(L);
  6914.  
  6915.     luaL_dostring(L, LUA);
  6916.     lua_getglobal(L, "main");
  6917.  
  6918.     while (true) {
  6919.         if (LUA_YIELD == lua_resume(L, L1, 0)) {
  6920.             lua_getglobal(L1, "foo");
  6921.             lua_pcall(L1, 0, 0, 0);
  6922.         }
  6923.         if (LUA_OK == lua_resume(L, L1, 0)) {
  6924.             break;
  6925.         }
  6926.     };
  6927.  
  6928.     lua_close(L);
  6929.     return 0;
  6930. };
  6931.  
  6932. int main(int argc, char* argv[]) {
  6933.     const char* LUA = R"(
  6934. foo()
  6935.  
  6936. )";
  6937.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  6938.     luaL_openlibs(L);
  6939.     lua_State* L1 = lua_newthread(L);
  6940.     lua_pushcfunction(L1, foo);// отправить c функцию в стек.
  6941.     luaL_loadfile(L1, LUA);
  6942.     lua_setglobal(L1, "foo");// уст для переменной значение в виде функции.
  6943.     lua_pushvalue(L1, -1);// Дублируем вершину стека.
  6944.     showstack(L1);
  6945.     lua_pcall(L1, 0, 0, 0);
  6946.     lua_xmove(L1, L, 2);// Снимает с L1 элементов передает L.
  6947.     showstack(L); cout << endl;
  6948.     lua_pcall(L, 0, 0, 0);
  6949.     //  checkerror(L1, LUA);//Функция проверка на ошибки.
  6950.     cout << endl << L << endl; cout << L1 << endl;
  6951.     lua_close(L);
  6952.  
  6953.     return 0;
  6954. };
  6955.  
  6956.  
  6957. int my_func(lua_State* L) {
  6958.     int narg = lua_gettop(L);
  6959.     if (narg == 0)
  6960.         fprintf(stderr, "[LUA] Hello from lua!\n");
  6961.     else
  6962.         fprintf(stderr, "[LUA] Hello from lua! Value passed: \"%s\"\n", lua_tostring(L, 1));
  6963.     return 0;  
  6964. };
  6965.  
  6966. /* own yield function for use from lua */
  6967. /* note that we don't pass/return any arguments from/to our lua
  6968.    function, so we always pass 0 to lua_yield and lua_resume */
  6969. int my_yield(lua_State* L) {
  6970.     fprintf(stderr, "[LUA] Now yielding...\n");
  6971.     return lua_yield(L, 0);
  6972. }
  6973.  
  6974. int main() {
  6975.     int ret;
  6976.  
  6977.     /* create lua state */
  6978.     lua_State* L = luaL_newstate();
  6979.  
  6980.     /* register own lua functions */
  6981.     /* note that we don't use any lua libraries */
  6982.     lua_register(L, "my_func", my_func);
  6983.     lua_register(L, "my_yield", my_yield);
  6984.  
  6985.     /* load lua code; may use luaL_dofile instead */
  6986.     ret = luaL_dostring(L, "function main() my_func(\"Hello, world!\"); my_yield(); for i = 1,9 do my_func(i); if i % 3 == 0 then my_yield(); end end my_yield(); my_func(\"Bye!\"); end");
  6987.     //assert(ret == 0); /* may indicate syntax error in our code */
  6988.  
  6989.     /* push lua main() function onto the stack */
  6990.     lua_getglobal(L, "main");
  6991.  
  6992.     /* mainloop which runs "in parallel" to lua main(), switching back and forth */
  6993.     fprintf(stderr, "[ C ] Starting mainloop...\n");
  6994.     while (1) {
  6995.         fprintf(stderr, "[ C ] Running/resuming lua...\n");
  6996.         ret = lua_resume(L, NULL, 0);
  6997.  
  6998.         if (ret == LUA_YIELD) {
  6999.             fprintf(stderr, "[ C ] Lua has yielded!\n");
  7000.         }
  7001.         else if (ret == 0) {
  7002.             fprintf(stderr, "[ C ] Lua has finished!\n");
  7003.             break;
  7004.         }
  7005.         else {
  7006.             //  assert(0); /* something gone wrong with lua */
  7007.         }
  7008.  
  7009.         fprintf(stderr, "[ C ] Hello from C!\n");
  7010.     }
  7011.  
  7012.     fprintf(stderr, "[ C ] We're done!\n");
  7013.  
  7014.     lua_close(L);
  7015.     return 0;
  7016. };
  7017.  
  7018. Вариант 2.
  7019.  
  7020. int my_yield(lua_State* L) {
  7021.     cout << " lua  yielding...\n";
  7022.     return lua_yield(L, 0);
  7023. }
  7024. const char* LUA = R"(
  7025. function main()
  7026. for i = 1,3 do
  7027. my_yield()
  7028. end  end
  7029. )";
  7030.  
  7031. int main() {
  7032.     lua_State* L = luaL_newstate();
  7033.     lua_register(L, "my_yield", my_yield);
  7034.     checkerror(L, LUA);
  7035.     lua_getglobal(L, "main");
  7036.     while (true) {int ret = lua_resume(L, NULL, 0);
  7037.       if (ret == LUA_YIELD) {   cout << "C++ !\n ";
  7038.       }
  7039.         else if (ret == 0) { break; }
  7040.     };
  7041.     lua_close(L);
  7042.     return 0;
  7043. };
  7044.  
  7045. Вариант 3.
  7046.  
  7047. int my_yield(lua_State* L) {
  7048.     cout << " lua  yielding...\n";
  7049.     return lua_yield(L, 0);
  7050. }
  7051. const char* LUA = R"(
  7052. function foo()
  7053.   print("foo")
  7054. end
  7055.  
  7056. function main()
  7057. for i = 1, 3 do
  7058. my_yield()
  7059. end  end
  7060. )";
  7061. int main(int argc, char* argv[]) {
  7062.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  7063.     luaL_openlibs(L);
  7064.     lua_register(L, "my_yield", my_yield);
  7065.     checkerror(L, LUA);
  7066.  
  7067.     lua_getglobal(L, "main");
  7068.     while (true) {
  7069.         int ret = lua_resume(L, NULL, 0);
  7070.         if (ret == LUA_YIELD) {
  7071.             lua_getglobal(L, "foo");
  7072.             lua_pcall(L, 0, 0, 0);
  7073.         }
  7074.         else if (ret == 0) {
  7075.            
  7076.             break; }
  7077.     };
  7078.            
  7079.  
  7080.    
  7081.     lua_close(L);
  7082.     return 0;
  7083. };
  7084. Вариант 4
  7085.  
  7086. int my_yield(lua_State* L) {
  7087.     //cout << " lua  yielding...\n";
  7088.     lua_yield(L, 1);
  7089.     lua_pushinteger(L, 10);
  7090.     showstack(L);
  7091.     return 2;
  7092. }
  7093. const char* LUA = R"(
  7094. function foo()
  7095.   print("foo")
  7096. end
  7097.  
  7098. function main()
  7099. for i = 1, 3 do
  7100. my_yield()
  7101. end  end
  7102. )";
  7103. int main(int argc, char* argv[]) {
  7104.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  7105.     luaL_openlibs(L);
  7106.     lua_register(L, "my_yield", my_yield);
  7107.     checkerror(L, LUA);
  7108.  
  7109.     lua_getglobal(L, "main");
  7110.     while (true) {
  7111.     if (LUA_YIELD == lua_resume(L, L, 0)) {
  7112.             lua_getglobal(L, "foo");
  7113.             lua_pcall(L, 0, 0, 0);
  7114.         }
  7115.      if (LUA_OK == lua_resume(L, L, 0)) {
  7116.         break; }
  7117.     };
  7118.    
  7119.     lua_close(L);
  7120.     return 0;
  7121. };
  7122.  
  7123. static int func_k1(lua_State* L)
  7124. {
  7125.     printf("continuation got %d values\n", lua_gettop(L));
  7126.     return 0;
  7127. }
  7128.  
  7129. static int func(lua_State* L){
  7130. lua_pushinteger(L, 10);
  7131.     return lua_yield(L, 1, 0, func_k1);
  7132. }
  7133.  
  7134. int main()
  7135. {
  7136.     lua_State* L, * T;
  7137.     int result, i;
  7138.     L = luaL_newstate();
  7139.     T = lua_newthread(L);
  7140.     lua_pushcfunction(T, func);
  7141.     lua_pushstring(T, "starting value 1");
  7142.     showstack(L);
  7143.     result = lua_resume(T, L, 1);
  7144.     if (result == LUA_YIELD)    {
  7145.         printf("main thread \n");
  7146.         showstack(T);
  7147.     }
  7148.  
  7149.     lua_close(L);
  7150.     return 0;
  7151. };
  7152.  
  7153.  
  7154. Вариант 5.
  7155. int foo(lua_State* L) {
  7156.     cout << " func foo c++ " << L << " " << lua_tointeger(L, -1)<< "\n";
  7157.     return 0;
  7158. };
  7159.  
  7160. int my_yield(lua_State* L) {
  7161.     //cout << " lua  yielding..." << lua_tointeger(L, -1) << "\n";
  7162.     return lua_yield(L, 1);
  7163. }
  7164. const char* LUA = R"(
  7165. foo(n)
  7166.  
  7167. function main(n)
  7168. for i = 1, 3 do
  7169. my_yield(n)
  7170. end  end
  7171. )";
  7172. int main(int argc, char* argv[]) {
  7173.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  7174.     luaL_openlibs(L);
  7175.     lua_State* L1 = lua_newthread(L);
  7176.  
  7177.     lua_register(L, "my_yield", my_yield);
  7178.     lua_register(L, "foo", foo);
  7179.     checkerror(L, LUA);
  7180.     lua_getglobal(L, "main");
  7181.     lua_pushinteger(L, 2);
  7182.     while (true) {
  7183.         int ret = lua_resume(L, L1, 1);
  7184.         if (ret == LUA_YIELD) {
  7185.             lua_pushvalue(L, -1);
  7186.             lua_getglobal(L1, "foo");
  7187.             lua_xmove(L, L1, 1);
  7188.             lua_pcall(L1, 1, 0, 0);
  7189.         }
  7190.         else if (ret == 0) {
  7191.  
  7192.             break;
  7193.         }
  7194.     };
  7195.  
  7196.  
  7197.  
  7198.     lua_close(L);
  7199.     return 0;
  7200. };
  7201.  
  7202. Вариант 6.
  7203.  
  7204. int foo(lua_State* L) {
  7205.     cout << " func foo c++ " << L << " " << lua_tointeger(L, -1)<< "\n";
  7206.     return 0;
  7207. };
  7208.  
  7209. int my_yield(lua_State* L) {
  7210.     cout << " lua  yielding..." << lua_tointeger(L, -1) << "\n";
  7211.     return lua_yield(L, 1);
  7212. }
  7213. const char* LUA = R"(
  7214. function foo(n)
  7215. print(" "..n)
  7216. end
  7217.  
  7218. function main(n)
  7219. for i = 1, 3 do
  7220. my_yield(i*n)
  7221. end  end
  7222. )";
  7223. int main(int argc, char* argv[]) {
  7224.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  7225.     luaL_openlibs(L);
  7226.     lua_State* L1 = lua_newthread(L);
  7227.  
  7228.     lua_register(L, "my_yield", my_yield);
  7229.     checkerror(L, LUA);
  7230.     lua_getglobal(L, "main");
  7231.     lua_pushinteger(L, 2);
  7232.     while (true) {
  7233.         int ret = lua_resume(L, L1, 1);
  7234.         if (ret == LUA_YIELD) {
  7235.             lua_pushvalue(L, -1);
  7236.             lua_getglobal(L1, "foo");
  7237.             lua_xmove(L, L1, 1);
  7238.             lua_pcall(L1, 1, 0, 0);
  7239.         }
  7240.         else if (ret == 0) {
  7241.  
  7242.             break;
  7243.         }
  7244.     };
  7245.  
  7246.  
  7247.  
  7248.     lua_close(L);
  7249.     return 0;
  7250. };
  7251.  
  7252. Вариант 7.
  7253.  
  7254.  
  7255. int foo(lua_State* L) {
  7256.     cout << " func foo c++ " << L << " " << lua_tointeger(L, -1)<< "\n";
  7257.     return 0;
  7258. };
  7259.  
  7260. int my_yield(lua_State* L) {
  7261.     cout << " lua  yielding..." << lua_tointeger(L, -1) << "\n";
  7262.     return lua_yield(L, 0);
  7263. }
  7264. const char* LUA = R"(
  7265. function foo(x)
  7266. print("func foo "..x.."\n")
  7267. end
  7268.  
  7269. function main(n)
  7270. for i = 1, 3 do
  7271. my_yield(i*n)
  7272. end  end
  7273. )";
  7274. int main(int argc, char* argv[]) {
  7275.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  7276.     luaL_openlibs(L);
  7277.     lua_State* L1 = lua_newthread(L);
  7278.  
  7279.     lua_register(L, "my_yield", my_yield);// регистрация функций.
  7280.     checkerror(L, LUA);
  7281.     lua_getglobal(L, "main");// получить функцию.
  7282.     lua_pushinteger(L, 2);// отправить аргументы в функцию main.
  7283.     while (true) {
  7284.         int ret = lua_resume(L, L1, 1); /* Запускает и продолжает сопрограмму в данном потоке L.
  7285.     вы отправляйте в стек главную функцию и её аргументы; затем вызываете lua_resume,nargs - кол-во аргументов.
  7286.     Вызов возвращается, когда приостанавливается или завершается. При возвращении, стек содержит все значения,
  7287.     переданные в lua_yield, или возвращенныеции. Чтобы продолжить сопрограмму, вы удаляете все результаты
  7288.     из последнего lua_yield, отправьте в её стек только значения, передаваемые в качестве результатов из yield, и
  7289.     затем вызываете lua_resume.   Параметр L представляет сопрограмму, которая продолжает L. */
  7290.    
  7291.         if (ret == LUA_YIELD) {
  7292.             lua_getglobal(L1, "foo");
  7293.             lua_xmove(L, L1, 1);
  7294.             lua_pcall(L1, 1, 0, 0);
  7295.         }
  7296.         else if (ret == 0) {/*Когда функция lua_resume возвращается, стек содержит все значения,
  7297.         переданные в lua_yield, или все значения, возвращенные телом функции.*/
  7298.         //showstack(L);
  7299.             break;
  7300.         }
  7301.     };
  7302.  
  7303.     lua_close(L);
  7304.     return 0;
  7305. };
  7306.  
  7307.  
  7308. Вариант 7.
  7309.  
  7310. /*Внутри себя, Lua использует возможность C - ишного longjmp для выхода(приостановки выполнения) из сопрограммы.
  7311. Поэтому, если C - ишная функция foo вызывает функцию API и эта функция API приостанавливает выполнение(непосредственно
  7312. сама или косвенно вызывая другую функцию, которая делает выход), Lua не может ничего больше возвратить в foo,
  7313. потому что longjmp удалил его фрейм из C - ишного стека. Во избежание проблем такого рода, Lua выдает ошибку всякий раз
  7314. при попытке выхода через вызов API, за исключением трех функций : lua_yieldk, lua_callk, и lua_pcallk.
  7315. Все эти функции принимают функцию - продолжение(в качестве параметра с именем k) чтобы продолжить выполнение после выхода.
  7316. Чтобы объяснить продолжения, следует установить некоторую терминологию. У нас есть функция C вызываемая из Lua,
  7317. которую мы будем называть исходной функцией. Эта исходная функция затем вызывает одну из этих трех функций в С - ишном API,
  7318. которая будет называться вызываемой функцией, которая затем приостанавливает выполнение текущего потока.
  7319. (Это может произойти, когда вызываемой функцией является lua_yieldk, или, когда вызываемая функция - либо lua_callk,
  7320. либо lua_pcallk, а функция, вызванная ими, приостанавливает выполнение.)
  7321.  
  7322. Предположим, что работающий поток приостанавливается на время выполнения вызываемой функции. После возобновления
  7323. работы потока, она, в конечном счете, завершит работу вызываемой функции. Однако, вызываемая функция не может
  7324. возвратиться к исходной функции, так как её фрейм в С - ишном стеке был разрушен приостановкой выполнения потока.
  7325. Вместо этого, Lua вызывает функцию продолжения(continuation function), которая будет задана в качестве аргумента
  7326. вызываемой функции. Как следует из названия, функция продолжения должна продолжить задачу исходной функции.
  7327.  
  7328. В качестве иллюстрации, рассмотрим следующую функцию :
  7329. int original_function(lua_State* L) { code 1
  7330.         status = lua_pcall(L, n, m, h);   calls Lua
  7331.  code 2 }
  7332. Теперь нужно позволить коду Lua запустить lua_pcall для приостановки. Во - первых, можно переписать нашу функцию вот так :
  7333. int k(lua_State* L, int status, lua_KContext ctx) {
  7334.      code 2
  7335. }
  7336. int original_function(lua_State* L) {
  7337.     ...   code 1
  7338.     return k(L, lua_pcall(L, n, m, h), ctx);
  7339. }
  7340. В приведенном выше коде, новая функция k является функцией продолжения(с типом lua_KFunction), которая должна выполнять
  7341. всю работу, что делала исходная функция после вызова lua_pcall.Теперь нужно сообщить Lua, что он должен вызывать k,
  7342. если код Lua выполняемый lua_pcall прерывается каким - то образом(ошибки или выход), так что можно переписать код
  7343. следующим образом, заменив lua_pcall на lua_pcallk :
  7344. int original_function(lua_State* L) {
  7345.      code 1
  7346.      return k(L, lua_pcallk(L, n, m, h, ctx2, k), ctx1);
  7347. }
  7348. Обратите внимание на внешний, явный вызов продолжения : Lua вызовет продолжение только при необходимости, то есть,
  7349. в случае ошибок или возобновления после выхода из выполнения.Если вызванная функция возвращается как обычно без
  7350. приостановки выполнения когда - либо, lua_pcallk(и lua_callk) также будет возвращаться нормально.
  7351. (Конечно, в данном случае вместо вызова продолжения можно сделать аналогичную работу непосредственно внутри исходной функции.)
  7352.  
  7353. Помимо Lua состояния, функция продолжения имеет два других параметра : конечное состояние вызова плюс значение контекста(ctx), которые первоначально были переданы lua_pcallk. (Lua не использует это значение контекста; он только передает это значение из исходной функции в функцию продолжения.) При выполнении после приостановки, для lua_pcallk, состоянием является тоже самое значение, что было бы возвращено lua_pcallk, за исключением того, что это LUA_YIELD(вместо LUA_OK).Когда Lua вызывает продолжение, для lua_yieldk и lua_callk, состоянием всегда будет LUA_YIELD. (Для этих двух функций, Lua не будет вызывать продолжения в случае ошибок, так как они не обрабатывают ошибки.) Точно также, при использовании lua_callk, следует вызывать функцию продолжения с LUA_OK в качестве состояния. (Для lua_yieldk, в прямом вызове функции продолжения нет особого смысла, поскольку lua_yieldk обычно ничего не возвращает.)
  7354.  
  7355. Lua рассматривает функцию продолжения как если бы она была исходной функцией.Функция продолжения принимает тот
  7356. же самый Lua стек от исходной функции, в том же самом состоянии, как если бы он был возвращен вызываемой функцией.
  7357. (Например, после lua_callk функция и её аргументы удаляются из стека и заменяются результатами из вызова.)
  7358. Она также имеет те же самые внешние локальные переменные.Все что она возвращает, обрабатывается Lua как если
  7359. бы это было возвращено исходной функцией.*/
  7360. lua_KFunction cont(int x)
  7361. {
  7362. //  cout << x<< endl;
  7363.     return 0;
  7364. }
  7365.  
  7366. int my_yield(lua_State* L) {
  7367.     cout << " lua  yielding... " << lua_tointeger(L, -1) << "\n";
  7368.     lua_pushinteger(L, lua_tointeger(L, -1) * 2);
  7369.     return lua_yieldk(L, 1, lua_yield(L, 0), cont(0));/* int lua_yieldk(lua_State * L, int res, lua_KContext ctx, lua_KFunction k);
  7370.     Приостанавливает выполнение сопрограммы(поток).   Когда функция C вызывает lua_yieldk, работающая
  7371.     сопрограмма приостанавливает свое выполнение и вызывает lua_resume, которая начинает возврат данной сопрограммы.
  7372.     Параметр res - это число значений из стека, которые будут переданы в качестве результатов в lua_resume.
  7373.     Когда сопрограмма снова возобновит выполнение, Lua вызовет заданную функцию продолжения k для продолжения выполнения
  7374.     приостановленной C функции(смотрите §4.7). Эта функция продолжения получит тот же самый стек от предыдущей функции,
  7375.     с n - ным числом результатов, удаленных и замененных посредством аргументов, переданных в lua_resume. Кроме того,
  7376.     функция продолжения получает значение ctx, которое было передано в lua_yieldk. Как правило, эта функция ничего
  7377.     не возвращает; когда сопрограмма в конце концов возобновляется, она продолжает выполнение функции продолжения.
  7378.     Тем не менее, существует один особый случай, который появляется когда эта функция вызывается внутри строковой
  7379.     ловушки(смотрите §4.9).В этом случае, lua_yieldk следует вызывать без продолжения(вероятно в виде lua_yield),
  7380.     и ловушка должна возвращать сразу после вызова.Lua будет приостановлена и, когда сопрограмма снова возобновит
  7381.     выполнение, продолжит нормальное выполнение функции(Lua), которая вызвала ловушку.   Данная функция может выдавать
  7382.     ошибку, если она вызвана из нити(thread) с ожиданием C вызова без функции продолжения или из нити, которая не работает
  7383.     внутри возобновления(например, основная нить).*/
  7384. };
  7385. const char* LUA = R"(
  7386. function foo(x)
  7387. print("func foo "..x.."\n")
  7388. end
  7389.  
  7390. function main(n)
  7391. for i = 1, n do
  7392. my_yield(i)
  7393. end  end
  7394. )";
  7395. int main(int argc, char* argv[]) {
  7396.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  7397.     luaL_openlibs(L);
  7398.     lua_State* L1 = lua_newthread(L);
  7399.  
  7400.     lua_register(L, "my_yield", my_yield);// регистрация функций.
  7401.     checkerror(L, LUA);
  7402.     lua_getglobal(L, "main");// получить функцию.
  7403.     lua_pushinteger(L, 2);// отправить аргументы в функцию main.
  7404.     while (true) {
  7405.         int ret = lua_resume(L, L1, 1); /* Запускает и продолжает сопрограмму в данном потоке L.
  7406.     вы отправляйте в стек главную функцию и её аргументы; затем вызываете lua_resume,nargs - кол-во аргументов.
  7407.     Вызов возвращается, когда приостанавливается или завершается. При возвращении, стек содержит все значения,
  7408.     переданные в lua_yield, или возвращенныеции. Чтобы продолжить сопрограмму, вы удаляете все результаты
  7409.     из последнего lua_yield, отправьте в её стек только значения, передаваемые в качестве результатов из yield, и
  7410.     затем вызываете lua_resume.   Параметр L представляет сопрограмму, которая продолжает L. */
  7411.    
  7412.         if (ret == LUA_YIELD) {
  7413.             lua_getglobal(L1, "foo");
  7414.             lua_xmove(L, L1, 1);
  7415.             lua_pcall(L1, 1, 0, 0);
  7416.         }
  7417.         else if (ret == 0) {/*Когда функция lua_resume возвращается, стек содержит все значения,
  7418.         переданные в lua_yield, или все значения, возвращенные телом функции.*/
  7419.         //showstack(L);
  7420.             break;
  7421.         }
  7422.     };
  7423.  
  7424.  
  7425.     lua_close(L);
  7426.     return 0;
  7427. };
  7428.  
  7429. Вариант 8.
  7430.  
  7431. static int timerfirsttread = 0;// таймер для первого потока.
  7432. void LUAHook(lua_State* L, lua_Debug* ar) {
  7433.     timerfirsttread++;
  7434.     if (timerfirsttread > 16) {// сколько будет работать первый поток.
  7435.         timerfirsttread = 0; lua_yield(L, 0);
  7436.     }
  7437. };
  7438. int my_yield(lua_State* L) {
  7439.     int args = lua_gettop(L);args++;
  7440.     lua_State* L1 = lua_newthread(L);
  7441.     lua_pushthread(L1);
  7442.     return lua_yield(L, args);/* Когда функция C вызывает lua_yield таким образом, запущенная сопрограмма приостанавливает
  7443.     свое выполнение, и вызов lua_resume этой запущенной процедуры возвращается.*/
  7444. };
  7445. int yield(lua_State* L) {return lua_yield(L, 0);/*  Параметр res - это число значений из стека,
  7446.     которые передаются как результаты lua_resume.*/
  7447. };
  7448. const char* LUA = R"(
  7449. function foo(x)    x = x or 3
  7450. print(" func foo "..x.. " \n")
  7451. for i = 1, x do
  7452. print(" func foo "..i.."\n")
  7453. yield()
  7454. end
  7455. end
  7456.  
  7457. function main()
  7458. for i = 1, 320 do
  7459. x=i*6
  7460. print(" func main "..i.."\n")
  7461. if i ==1
  7462. then my_yield(foo,40)
  7463. end
  7464. end  end
  7465. )";
  7466. int main(int argc, char* argv[]) {
  7467.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  7468.     luaL_openlibs(L); lua_State* L1 = NULL;
  7469.     lua_register(L, "my_yield", my_yield);
  7470.     lua_register(L, "yield",  yield);
  7471.     cout << "\n"; checkerror(L, LUA);
  7472.     lua_getglobal(L, "main");
  7473.     lua_resume(L, NULL, 0); /* Запускает и продолжает сопрограмму в данном потоке L. */
  7474.     L1 = lua_tothread(L, -1); lua_pop(L, 1); lua_xmove(L, L1, lua_gettop(L));lua_remove(L1, 1);
  7475.     int args = lua_gettop(L1);//    cout << args << endl;// Аргументы.
  7476.  
  7477.  
  7478.         for (int i = 1; i > args; i++) {lua_pushvalue(L1, i);}
  7479.         args--; res1 = lua_resume(L1, L, args);
  7480.         lua_xmove(L, L1, 1);
  7481.   while ( LUA_OK != lua_status(L)) {    // пока поток main не завершен. 
  7482.        if (LUA_YIELD == lua_status(L1)) {// если поток 2 на паузе.
  7483.             lua_sethook(L, LUAHook, LUA_MASKCOUNT, 6);//Пауза после 6 итерации.
  7484.             lua_resume(L, L1, 0);
  7485.         }// main
  7486.         if (LUA_YIELD == lua_status(L)){// если поток main на паузе.
  7487.          lua_sethook(L, LUAHook, LUA_MASKCOUNT, 0);// отключить хук.
  7488.          lua_resume(L1, L, 0);// foo
  7489.         }
  7490.     if (LUA_OK == lua_status(L1)) {// если поток foo  завершен.   
  7491.         lua_sethook(L, LUAHook, LUA_MASKCOUNT, 0);// отключить хук.
  7492.         lua_resume(L, NULL, 0);
  7493.         lua_settop(L1, 0);
  7494.     }
  7495.     if (LUA_OK == lua_status(L)) { break; }// если поток main  завершен.  
  7496. };
  7497.     lua_close(L);
  7498.     return 0;
  7499. };
  7500.  
  7501.  
  7502.  
  7503. void LUAHook(lua_State* L, lua_Debug* ar){  lua_yield(L, 0);
  7504. };
  7505.  
  7506. int NONblock(lua_State* L, const char* functionName, float dt){
  7507.     lua_getglobal(L, functionName); // функция lua возобновляется с последней прерванной позиции.
  7508.  
  7509.  
  7510.     int ret = lua_resume(L, NULL, NULL);
  7511.     if (ret == LUA_YIELD) {
  7512.         return 1;
  7513.     }
  7514.     else if (ret == 0) {    // функция lua возвращается успешно.
  7515.         return 0;   }
  7516.     else {      // Обработка ошибки lua.
  7517.         return -1;  }
  7518. };
  7519. const char* LUA = R"(
  7520. function heavy_function(dt)
  7521. i = 0;
  7522. while i < 3 do
  7523.  i = i + 1;
  7524.   print(" main ", i)   
  7525.     end
  7526. end
  7527.  
  7528. function foo()
  7529. for i = 1, 3 do
  7530. print(" func foo "..i.."\n")
  7531. end
  7532. end
  7533. )";
  7534. int main() {
  7535.     lua_State* L = luaL_newstate();
  7536.     luaL_openlibs(L);
  7537.  
  7538.     checkerror(L, LUA);
  7539.     lua_sethook(L, LUAHook, LUA_MASKCOUNT, 10); // Добавить подсчет счетчика, который сработает после указания числа
  7540.     while (true)
  7541.     {
  7542.         printf("  lua script resumu \n\n");// Обновляем функцию lua с упреждающим планированием.
  7543.         int functionState = NONblock(L, "heavy_function", 0.0);
  7544.         if (functionState == 0) {// Успешно завершение функции.
  7545.             break;
  7546.         }
  7547.     }
  7548.  
  7549.     return 0;
  7550. };
  7551.  
  7552.  
  7553. int my_yield(lua_State* L) {
  7554.     cout << " lua  yielding... " << lua_tointeger(L, -1) << "\n";
  7555.     lua_pushinteger(L, lua_tointeger(L, -1) * 2);
  7556.     return  lua_yield(L, 0);
  7557. };
  7558. const char* LUA = R"(
  7559. function foo(x)
  7560. print("func foo "..x.."\n")
  7561. return 8
  7562. end
  7563.  
  7564. function main(n)
  7565. for i = 1, n do
  7566. my_yield(i)
  7567. end  end
  7568. )";
  7569. int main(int argc, char* argv[]) {
  7570.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  7571.     luaL_openlibs(L);
  7572.     lua_State* L1 = lua_newthread(L);
  7573.  
  7574.     lua_register(L, "my_yield", my_yield);// регистрация функций.
  7575.     checkerror(L, LUA);
  7576.     lua_getglobal(L, "main");// получить функцию.
  7577.     lua_pushinteger(L, 6);// отправить аргументы в функцию main.
  7578.     while (true) {
  7579.         int ret = lua_resume(L, L1, 1); /* Запускает и продолжает сопрограмму в данном потоке L.
  7580.     вы отправляйте в стек главную функцию и её аргументы; затем вызываете lua_resume,nargs - кол-во аргументов.
  7581.     Вызов возвращается, когда приостанавливается или завершается. При возвращении, стек содержит все значения,
  7582.     переданные в lua_yield, или возвращенныеции. Чтобы продолжить сопрограмму, вы удаляете все результаты
  7583.     из последнего lua_yield, отправьте в её стек только значения, передаваемые в качестве результатов из yield, и
  7584.     затем вызываете lua_resume.   Параметр L представляет сопрограмму, которая продолжает L. */
  7585.    
  7586.         if (ret == LUA_YIELD) {
  7587.             int x = lua_tointeger(L, -1);// Из функции foo.
  7588.             cout << x << endl;
  7589.             lua_getglobal(L1, "foo");
  7590.             lua_xmove(L, L1, 1);
  7591.             lua_pcall(L1, 1, 0, 0);
  7592.         }
  7593.         else if (ret == 0) {/*Когда функция lua_resume возвращается, стек содержит все значения,
  7594.         переданные в lua_yield, или все значения, возвращенные телом функции.*/
  7595.         //showstack(L);
  7596.             break;
  7597.         }
  7598.     };
  7599.  
  7600.  
  7601.     lua_close(L);
  7602.     return 0;
  7603. };
  7604.  
  7605.  
  7606.  
  7607.  
  7608.  
  7609.  
  7610.  
  7611.  
  7612. int yield(lua_State* L) {
  7613.     return lua_yield(L, 0);/*  Параметр res - это число значений из стека,
  7614. которые передаются как результаты lua_resume.*/
  7615. };
  7616. int hookFunc(lua_State* L, lua_Debug* ar) {
  7617.     int  m = L->l_G->seed;
  7618.     cout << m << endl;
  7619.     return lua_yield(L, 0);
  7620. };
  7621.  
  7622. int my_yield(lua_State* L) {
  7623.     int args = lua_gettop(L);args++;
  7624.     lua_State* L1 = lua_newthread(L);
  7625.     lua_pushthread(L1);
  7626.     return lua_yield(L, args);/* Когда функция C вызывает lua_yield таким образом, запущенная сопрограмма приостанавливает
  7627.     свое выполнение, и вызов lua_resume этой запущенной процедуры возвращается.*/
  7628. };
  7629. const char* LUA = R"(
  7630. function foo(x)    x = x or 3
  7631. print(" func foo "..x.. " \n")
  7632. for i = 1, x do
  7633. print(" func foo "..i.."\n")
  7634. yield()
  7635. end
  7636. end
  7637.  
  7638. function main()
  7639. for i = 1, 1460 do
  7640. z=i*6
  7641. print(" func main "..i.."\n")
  7642. if i ==3
  7643. then my_yield(foo,106)
  7644. end
  7645. end  end
  7646. )";
  7647. int main(int argc, char* argv[]) {
  7648.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  7649.     luaL_openlibs(L); lua_State* L1 = NULL;
  7650.     lua_register(L, "my_yield", my_yield);
  7651.     lua_register(L, "yield",  yield);
  7652.     cout << "\n"; checkerror(L, LUA);
  7653.     lua_getglobal(L, "main");
  7654.     lua_resume(L, NULL, 0); /* Запускает и продолжает сопрограмму в данном потоке L. */
  7655.     L1 = lua_tothread(L, -1); lua_pop(L, 1); lua_xmove(L, L1, lua_gettop(L));lua_remove(L1, 1);
  7656.     int args = lua_gettop(L1);//    cout << args << endl;// Аргументы.
  7657.    
  7658.         for (int i = 1; i > args; i++) {lua_pushvalue(L1, i);}
  7659.         args--;  lua_resume(L1, L, args);   lua_xmove(L, L1, 1); //showstack(L1);
  7660.  
  7661.        
  7662.         //lua_sethook(L, LUAHook, LUA_MASKCOUNT, 6);//Пауза после 6 итерации.
  7663.   while ( LUA_OK != lua_status(L)) {    // пока поток main не завершен.
  7664.  
  7665.        if (LUA_YIELD == lua_status(L1)) {// если поток 2 на паузе.
  7666.          // lua_sethook(L, LUAHook, LUA_MASKCOUNT, 0);// отключить хук main.
  7667.         cout << " pause foo" << endl;
  7668.           lua_sethook(L, (lua_Hook)hookFunc, LUA_MASKCOUNT, 26);//Пауза после 6 итерации поток main.
  7669.           lua_resume(L, L1, 0);
  7670.         // lua_sethook(L, LUAHook, LUA_MASKCOUNT, 6);// отключить хук main.
  7671.         }// main
  7672.        
  7673.        if (LUA_YIELD == lua_status(L)){// если поток main на паузе.
  7674.           lua_sethook(L, (lua_Hook)hookFunc,  LUA_MASKCOUNT, 0);// отключить хук main.
  7675.          cout << " pause main" << endl;
  7676.          lua_resume(L1, L, 0);// foo
  7677.        
  7678.         }
  7679.  
  7680.     if (LUA_OK == lua_status(L1)) {// если поток foo  завершен.   
  7681.         cout << "foo end " << endl;
  7682.         //lua_sethook(L, LUAHook, LUA_MASKCOUNT, 0);// отключить хук main.
  7683.         lua_resume(L, NULL, 0);
  7684.     }
  7685.     if (LUA_OK == lua_status(L)) { break; }// если поток main  завершен.  
  7686. };
  7687.     lua_close(L);
  7688.     return 0;
  7689. };
  7690.  
  7691.  
  7692.  
  7693.  
  7694.  
  7695. static int func_k1(lua_State* L)
  7696. {
  7697.     int i;
  7698.     printf("continuation got %d values\n", lua_gettop(L));
  7699.     return 0;
  7700. }
  7701.  
  7702. static int func(lua_State* L)
  7703. {
  7704.     int i;
  7705.     lua_pushstring(L, "data 1");
  7706.     printf("coroutine yields %d values out of %d:\n", 2, lua_gettop(L));
  7707.     return lua_yield(L, 2, 0, func_k1);
  7708. }
  7709.  
  7710. int main()
  7711. {
  7712.     lua_State* L, * T;
  7713.     int result, i;
  7714.     L = luaL_newstate();
  7715.     T = lua_newthread(L);
  7716.     lua_pushcfunction(T, func);
  7717.     lua_pushstring(T, "starting value 1");
  7718.     lua_pushstring(T, "starting value 2");
  7719.     result = lua_resume(T, L, 2);
  7720.     if (result != 0 && result != LUA_YIELD)
  7721.         printf("error in first resume: %s\n", lua_tostring(T, -1));
  7722.     else
  7723.     {
  7724.         printf("main thread got %d values:\n", lua_gettop(T));
  7725.         for (i = 1; i <= lua_gettop(T); ++i)
  7726.         {
  7727.             printf("\t%s %s\n", luaL_typename(T, i), lua_type(T,
  7728.                 i) == LUA_TSTRING ? lua_tostring(T, i) : "");
  7729.         }
  7730.     }
  7731.     lua_pushstring(T, "resumed value 1");
  7732.     printf("resuming with 1 argument out of %d:\n", lua_gettop(T));
  7733.     for (i = 1; i <= lua_gettop(T); ++i)
  7734.     {
  7735.         printf("\t%s %s\n", luaL_typename(T, i), lua_type(T,
  7736.             i) == LUA_TSTRING ? lua_tostring(T, i) : "");
  7737.     }
  7738.     result = lua_resume(T, L, 1);
  7739.     if (result != 0 && result != LUA_YIELD)
  7740.         printf("error in second resume: %s\n", lua_tostring(T, -1));
  7741.     lua_close(L);
  7742.     return 0;
  7743. };
  7744.  
  7745. Hi list,
  7746.  
  7747. I'm trying to port to C a framework of mine that is basically a
  7748. coroutine scheduler hidden under a pseudo-blocking I/O API (not mature
  7749. enough to be released, but ask for a URL if interested). I have
  7750. several pure-Lua implementations (with various backend dependencies),
  7751. and I'm trying to re-implement it in C. That was the perfect occasion
  7752. to dive into Lua 5.2's new lua_yieldk feature. But I'm faced with an
  7753. oddity, which I believe is either a bug or a documentation problem.
  7754.  
  7755. When a first call to lua_resume returns, only the yielded values are
  7756. on the stack. Any other values in the thread stack (in the
  7757. lua_CFunction that called lua_yieldk) are not accessible (but will be
  7758. in the continuation). So far so good. However if I let those return
  7759. values there, push a couple other ones, and call lua_resume with nargs
  7760. equal to 1 or 2, the continuation receives 1) the non returned value
  7761. from the initial coroutine resume at the bottom, 2) the nargs values
  7762. passed to the second resume at the top, but also 3) any other yielded
  7763. values, and any other pushed values before the second call to
  7764. lua_resume. In other words it seems the nargs of a second lua_resume
  7765. seems to be ignored, and all values on the thread stack at the moment
  7766. of the resume are passed to the continuation function.
  7767.  
  7768. Here is a small program showing the problem:
  7769.  
  7770. #include <lua.h>
  7771. #include <lauxlib.h>
  7772. #include <stdlib.h>
  7773.  
  7774. static int func_k1(lua_State* L)
  7775. {
  7776.     int i;
  7777.     printf("continuation got %d values\n", lua_gettop(L));
  7778.     for (i=1; i<=lua_gettop(L); ++i)
  7779.     {
  7780.         printf("\t%s %s\n", luaL_typename(L, i), lua_type(L,
  7781. i)==LUA_TSTRING ? lua_tostring(L, i) : "");
  7782.     }
  7783.     return 0;
  7784. }
  7785.  
  7786. static int func(lua_State* L)
  7787. {
  7788.     int i;
  7789.     lua_pushstring(L, "data 1");
  7790.     lua_pushstring(L, "data 2");
  7791.     lua_pushstring(L, "yielded value 1");
  7792.     lua_pushstring(L, "yielded value 2");
  7793.     printf("coroutine yields %d values out of %d:\n", 2, lua_gettop(L));
  7794.     for (i=1; i<=lua_gettop(L); ++i)
  7795.     {
  7796.         printf("\t%s %s\n", luaL_typename(L, i), lua_type(L,
  7797. i)==LUA_TSTRING ? lua_tostring(L, i) : "");
  7798.     }
  7799.     return lua_yieldk(L, 2, 0, func_k1);
  7800. }
  7801.  
  7802. int main()
  7803. {
  7804.     lua_State* L,* T;
  7805.     int result, i;
  7806.     L = luaL_newstate();
  7807.     T = lua_newthread(L);
  7808.     lua_pushcfunction(T, func);
  7809.     lua_pushstring(T, "starting value 1");
  7810.     lua_pushstring(T, "starting value 2");
  7811.     result = lua_resume(T, L, 2);
  7812.     if (result != 0 && result != LUA_YIELD)
  7813.         printf("error in first resume: %s\n", lua_tostring(T, -1));
  7814.     else
  7815.     {
  7816.         printf("main thread got %d values:\n", lua_gettop(T));
  7817.         for (i=1; i<=lua_gettop(T); ++i)
  7818.         {
  7819.             printf("\t%s %s\n", luaL_typename(T, i), lua_type(T,
  7820. i)==LUA_TSTRING ? lua_tostring(T, i) : "");
  7821.         }
  7822.     }
  7823.     lua_pushstring(T, "resumed value 1");
  7824.     lua_pushstring(T, "resumed value 2");
  7825.     printf("resuming with 1 argument out of %d:\n", lua_gettop(T));
  7826.     for (i=1; i<=lua_gettop(T); ++i)
  7827.     {
  7828.         printf("\t%s %s\n", luaL_typename(T, i), lua_type(T,
  7829. i)==LUA_TSTRING ? lua_tostring(T, i) : "");
  7830.     }
  7831.     result = lua_resume(T, L, 1);
  7832.     if (result != 0 && result != LUA_YIELD)
  7833.         printf("error in second resume: %s\n", lua_tostring(T, -1));
  7834.     lua_close(L);
  7835.     return 0;
  7836. }
  7837.  
  7838. And here is the output I get:
  7839.  
  7840. coroutine yields 2 values out of 6:
  7841.         string starting value 1
  7842.         string starting value 2
  7843.         string data 1
  7844.         string data 2
  7845.         string yielded value 1
  7846.         string yielded value 2
  7847. main thread got 2 values:
  7848.         string yielded value 1
  7849.         string yielded value 2
  7850. resuming with 1 argument out of 4:
  7851.         string yielded value 1
  7852.         string yielded value 2
  7853.         string resumed value 1
  7854.         string resumed value 2
  7855. continuation got 8 values
  7856.         string starting value 1
  7857.         string starting value 2
  7858.         string data 1
  7859.         string data 2
  7860.         string yielded value 1
  7861.         string yielded value 2
  7862.         string resumed value 1
  7863.         string resumed value 2
  7864.  
  7865. Instead I expected the last section to read:
  7866. continuation got 5 values
  7867.         string starting value 1
  7868.         string starting value 2
  7869.         string data 1
  7870.         string data 2
  7871.         string resumed value 2
  7872.  
  7873. Did I misinterpret something, or is there a problem somewhere (with
  7874. lua_resume, lua_yieldk, or the doc of one of these)?
  7875.  
  7876. Doub.
  7877.  
  7878. lua_State* CreateThread(lua_State* MainState)
  7879. {
  7880.     lua_State* thread = lua_newthread(MainState);
  7881.     //making the stuff
  7882.     return thread;
  7883. };
  7884. int LuaYield(lua_State* L){
  7885.     return lua_yield(L, 1);
  7886. };
  7887. const char* LUA = R"(
  7888. function main()
  7889. count = 0
  7890. while 1 do
  7891.    count = count + 1;
  7892.    print("Count:", count);
  7893.    yield();
  7894. end
  7895. end
  7896. )";
  7897. int main(int argc, char* argv[]) {
  7898.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  7899.     luaL_openlibs(L);
  7900.  
  7901.  
  7902.     lua_register(L, "yield", LuaYield);
  7903.     lua_State* L1 = CreateThread(L);
  7904.  
  7905.     luaL_dostring(L, LUA);
  7906.     lua_getglobal(L, "main");
  7907.  
  7908.     while (true) {
  7909.         if (LUA_YIELD == lua_resume(L,NULL, 0)) {
  7910.         }
  7911.         if (LUA_OK == lua_resume(L, NULL, 0)) {
  7912.             break;
  7913.         }
  7914.     };
  7915.  
  7916.     lua_close(L);
  7917.     return 0;
  7918. };
  7919.  
  7920. int main(int argc, char* argv[]) {
  7921.     const char* LUA = R"(
  7922. foo()
  7923.  
  7924. )";
  7925.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  7926.     luaL_openlibs(L);
  7927.     lua_State* L1 = lua_newthread(L);
  7928.     lua_pushcfunction(L1, foo);// отправить c функцию в стек.
  7929.     luaL_loadfile(L1, LUA);
  7930.     lua_setglobal(L1, "foo");// уст для переменной значение в виде функции.
  7931.    
  7932.     lua_resume(L1, L, 0); /*
  7933.     int lua_resume(lua_State *L, lua_State *from, int nargs); Запускает и продолжает сопрограмму в данном потоке L.
  7934.     Для запуска подпрограммы, вы отправляйте в стек потока главную функцию и её аргументы; затем вызываете lua_resume,
  7935.     nargs - количество аргументов. Этот вызов возвращается, когда сопрограмма приостанавливается или завершается.
  7936.     Когда функция возвращается, стек содержит все значения, переданные в lua_yield, или все значения, возвращенные
  7937.     телом функции.  lua_resume возвращает LUA_YIELD - если сопрограмма уступила, LUA_OK - если сопрограмма завершила
  7938.     свое исполнение без ошибок, или код ошибки в случае ошибок(см.lua_pcall).
  7939.     В случае ошибок, стек не раскручивается, так вы можете использовать отладочные API на нём.
  7940.     Сообщение об ошибке находится на вершине стека. Чтобы продолжить сопрограмму, вы удаляете все результаты
  7941.     из последнего lua_yield, отправьте в её стек только значения, передаваемые в качестве результатов из yield, и
  7942.     затем вызываете lua_resume.   Параметр from представляет сопрограмму, которая продолжает L. Если такой сопрограммы
  7943.     нет, этот параметр может быть равен NULL.  */
  7944.     //lua_pcall(L, 0, 0, 0);
  7945.  
  7946.     cout << endl << L << endl; cout << L1 << endl;
  7947.     lua_close(L);
  7948.  
  7949.     return 0;
  7950. };
  7951.  
  7952. const char* LUA = R"(
  7953. counter= 0
  7954.    while true
  7955.    do
  7956.        print("Sending " .. counter);
  7957.        coroutine.yield(counter);
  7958.        counter = counter + 1;
  7959.    end
  7960. )";
  7961.  
  7962. int main(int argc, char* argv[]) {
  7963.     lua_State* L = luaL_newstate();
  7964.     luaL_openlibs(L);
  7965.  
  7966.     lua_State* thread1 = lua_newthread(L);
  7967.     lua_State* thread2 = lua_newthread(L);
  7968.  
  7969.     // load chunk as a function and copy it to the top of each thread stack
  7970.     checkerror(L, LUA);
  7971.     lua_pushvalue(L, -1);
  7972.     lua_xmove(L, thread1, 1);
  7973.     lua_pushvalue(L, -1);
  7974. //  lua_xmove(L, thread2, 1);
  7975.  
  7976.     lua_resume(thread1, NULL, 0);
  7977. //  lua_resume(thread2, NULL, 0);
  7978.     lua_close(L);// закрыть состояние.
  7979.  
  7980.     return 0;
  7981. };
  7982.  
  7983. int main() {
  7984.     const char* LUA = R"(
  7985. function loop()
  7986.    while counter
  7987.    do
  7988.        print("Sending " .. counter);
  7989.        coroutine.yield(counter);
  7990.        counter = counter + 1;
  7991.    end
  7992. end
  7993. )";
  7994.  
  7995.     lua_State* L = luaL_newstate();
  7996.     luaL_openlibs(L);
  7997.     if (!luaL_loadfile(L, LUA)) {
  7998.         lua_pcall(L, 0, 0, 0);
  7999.         lua_State* L2 = lua_newthread(L);
  8000.         lua_getglobal(L2, "loop");
  8001.  
  8002.         while (1) {
  8003.             puts("while top");
  8004.             int res = lua_resume(L2, NULL, 0);
  8005.             if (res != 0) {
  8006.                 break;
  8007.             }
  8008.  
  8009.             if (lua_isnumber(L2, lua_gettop(L2)) == 1) {
  8010.                 printf( "Got %d\n", lua_tonumber(L2, lua_gettop(L2))
  8011.                 );
  8012.             }
  8013.         }
  8014.     }
  8015.     lua_close(L);// закрыть состояние
  8016.     return 0;
  8017. };
  8018.  
  8019.  
  8020. int lua_finish(lua_State*) {
  8021.     running = false;
  8022.     printf("lua_finish called\n");
  8023.     return 0;
  8024. }
  8025. int lua_sleep(lua_State* L) {
  8026.     printf("lua_sleep called\n");
  8027.     return lua_yield(L, 0);
  8028. }
  8029. int main() {
  8030.     const char* LUA = R"(
  8031. print("loop.lua")
  8032.  
  8033. local i = 0
  8034. while true do
  8035.    print("lua_loop iteration")
  8036.    sleep()
  8037.  
  8038.    i = i + 1
  8039.    if i == 4 then
  8040.        break
  8041.    end
  8042. end
  8043.  
  8044. finish()
  8045. )";
  8046.  
  8047.     lua_State* L = luaL_newstate();
  8048.     luaL_openlibs(L);
  8049.     lua_register(L, "sleep", lua_sleep);
  8050.     lua_register(L, "finish", lua_finish);
  8051.  
  8052.     lua_State* cL = lua_newthread(L);
  8053.     luaL_dofile(cL, LUA);
  8054.  
  8055.     while (running) {
  8056.         int status;
  8057.         status = lua_resume(cL, L, 0);
  8058.         if (status == LUA_YIELD) {
  8059.             printf("loop yielding\n");
  8060.         }
  8061.         else {
  8062.             running = false; // you can't try to resume if it didn't yield
  8063.             // catch any errors below
  8064.             if (status == LUA_ERRRUN && lua_isstring(cL, -1)) {
  8065.                 printf("isstring: %s\n", lua_tostring(cL, -1));
  8066.                 lua_pop(cL, -1);
  8067.             }
  8068.         }
  8069.     }
  8070.     lua_close(L);
  8071.     return 0;
  8072. };
  8073.  
  8074. static lua_State* getco(lua_State* L) {
  8075.     lua_State* co = lua_tothread(L, 1);
  8076.     luaL_argcheck(L, co, 1, "thread expected");
  8077.     return co;
  8078. };
  8079.  
  8080. static int auxresume(lua_State* L, lua_State* co, int narg) {
  8081.     int status;
  8082.     if (!lua_checkstack(co, narg)) {
  8083.         lua_pushliteral(L, "too many arguments to resume");
  8084.         return -1;  /* error flag */
  8085.     }
  8086.     if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) {
  8087.         lua_pushliteral(L, "cannot resume dead coroutine");
  8088.         return -1;  /* error flag */
  8089.     }
  8090.     lua_xmove(L, co, narg);
  8091.     status = lua_resume(co, L, narg);
  8092.     if (status == LUA_OK || status == LUA_YIELD) {
  8093.         int nres = lua_gettop(co);
  8094.         if (!lua_checkstack(L, nres + 1)) {
  8095.             lua_pop(co, nres);  /* remove results anyway */
  8096.             lua_pushliteral(L, "too many results to resume");
  8097.             return -1;  /* error flag */
  8098.         }
  8099.         lua_xmove(co, L, nres);  /* move yielded values */
  8100.         return nres;
  8101.     }
  8102.     else {
  8103.         lua_xmove(co, L, 1);  /* move error message */
  8104.         return -1;  /* error flag */
  8105.     }
  8106. };
  8107.  
  8108.  
  8109. static int luaB_coresume(lua_State* L) {
  8110.     lua_State* co = getco(L);
  8111.     int r;
  8112.     r = auxresume(L, co, lua_gettop(L) - 1);
  8113.     if (r < 0) {
  8114.         lua_pushboolean(L, 0);
  8115.         lua_insert(L, -2);
  8116.         return 2;  /* return false + error message */
  8117.     }
  8118.     else {
  8119.         lua_pushboolean(L, 1);
  8120.         lua_insert(L, -(r + 1));
  8121.         return r + 1;  /* return true + 'resume' returns */
  8122.     }
  8123. };
  8124.  
  8125.  
  8126. static int luaB_auxwrap(lua_State* L) {
  8127.     lua_State* co = lua_tothread(L, lua_upvalueindex(1));
  8128.     int r = auxresume(L, co, lua_gettop(L));
  8129.     if (r < 0) {
  8130.         if (lua_type(L, -1) == LUA_TSTRING) {  /* error object is a string? */
  8131.             luaL_where(L, 1);  /* add extra info */
  8132.             lua_insert(L, -2);
  8133.             lua_concat(L, 2);
  8134.         }
  8135.         return lua_error(L);  /* propagate error */
  8136.     }
  8137.     return r;
  8138. };
  8139.  
  8140.  
  8141. static int luaB_cocreate(lua_State* L) {
  8142.     lua_State* NL;
  8143.     luaL_checktype(L, 1, LUA_TFUNCTION);
  8144.     NL = lua_newthread(L);
  8145.     lua_pushvalue(L, 1);  /* move function to top */
  8146.     lua_xmove(L, NL, 1);  /* move function from L to NL */
  8147.     return 1;
  8148. };
  8149.  
  8150.  
  8151. static int luaB_cowrap(lua_State* L) {
  8152.     luaB_cocreate(L);
  8153.     lua_pushcclosure(L, luaB_auxwrap, 1);
  8154.     return 1;
  8155. };
  8156.  
  8157.  
  8158. static int luaB_yield(lua_State* L) {
  8159.     return lua_yield(L, lua_gettop(L));
  8160. };
  8161.  
  8162.  
  8163. static int luaB_costatus(lua_State* L) {
  8164.     lua_State* co = getco(L);
  8165.     if (L == co) lua_pushliteral(L, "running");
  8166.     else {
  8167.         switch (lua_status(co)) {
  8168.         case LUA_YIELD:
  8169.             lua_pushliteral(L, "suspended");
  8170.             break;
  8171.         case LUA_OK: {
  8172.             lua_Debug ar;
  8173.             if (lua_getstack(co, 0, &ar) > 0)  /* does it have frames? */
  8174.                 lua_pushliteral(L, "normal");  /* it is running */
  8175.             else if (lua_gettop(co) == 0)
  8176.                 lua_pushliteral(L, "dead");
  8177.             else
  8178.                 lua_pushliteral(L, "suspended");  /* initial state */
  8179.             break;
  8180.         }
  8181.         default:  /* some error occurred */
  8182.             lua_pushliteral(L, "dead");
  8183.             break;
  8184.         }
  8185.     }
  8186.     return 1;
  8187. };
  8188.  
  8189.  
  8190. static int luaB_yieldable(lua_State* L) {
  8191.     lua_pushboolean(L, lua_isyieldable(L));
  8192.     return 1;
  8193. };
  8194.  
  8195.  
  8196. static int luaB_corunning(lua_State* L) {
  8197.     int ismain = lua_pushthread(L);
  8198.     lua_pushboolean(L, ismain);
  8199.     return 2;
  8200. };
  8201.  
  8202. static const luaL_Reg co_funcs[] = {
  8203.   {"create", luaB_cocreate},
  8204.   {"resume", luaB_coresume},
  8205.   {"running", luaB_corunning},
  8206.   {"status", luaB_costatus},
  8207.   {"wrap", luaB_cowrap},
  8208.   {"yield", luaB_yield},
  8209.   {"isyieldable", luaB_yieldable},
  8210.   {NULL, NULL}
  8211. };
  8212.  
  8213. LUAMOD_API int luaopen_coroutines(lua_State* L) {
  8214.     luaL_newlib(L, co_funcs);
  8215.     return 1;
  8216. };
  8217.  
  8218.  
  8219. const char* LUA = R"(
  8220. mylib = require 'mylib'
  8221. function foo()
  8222.   print("foo")
  8223. end
  8224. thread4 = mylib.create(function(a, b)
  8225.    local c = a+b
  8226.    coroutine.yield()
  8227.    return c
  8228. end)
  8229.  
  8230. mylib.resume(thread4, 1, 2)
  8231. print(mylib.resume(thread4))
  8232.  
  8233. )";
  8234. int main(int argc, char* argv[]) {
  8235.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  8236.     luaL_openlibs(L);
  8237.  
  8238.     luaL_requiref(L, "mylib", luaopen_coroutines, 1);
  8239.     checkerror(L, LUA);
  8240.  
  8241.     lua_close(L);
  8242.     return 0;
  8243. };
  8244.  
  8245. Вариант 2.
  8246.  
  8247. static lua_State* getco(lua_State* L) {
  8248.     lua_State* L1 = lua_tothread(L, 1);
  8249.     luaL_argcheck(L, L1, 1, "thread expected");
  8250.     return L1;
  8251. };
  8252.  
  8253. static int auxresume(lua_State* L, lua_State* L1, int narg) {
  8254.     int status;
  8255.     if (!lua_checkstack(L1, narg)) {
  8256.         lua_pushliteral(L, "too many arguments to resume");
  8257.         return -1;  /* error flag */
  8258.     }
  8259.     if (lua_status(L1) == LUA_OK && lua_gettop(L1) == 0) {
  8260.         lua_pushliteral(L, "cannot resume dead coroutine");
  8261.         return -1;  /* error flag */
  8262.     }
  8263.     lua_xmove(L, L1, narg);
  8264.     status = lua_resume(L1, L, narg);
  8265.     if (status == LUA_OK || status == LUA_YIELD) {
  8266.         int nres = lua_gettop(L1);
  8267.         if (!lua_checkstack(L, nres + 1)) {
  8268.             lua_pop(L1, nres);  /* remove results anyway */
  8269.             lua_pushliteral(L, "too many results to resume");
  8270.             return -1;  /* error flag */
  8271.         }
  8272.         lua_xmove(L1, L, nres);  /* move yielded values */
  8273.         return nres;
  8274.     }
  8275.     else {
  8276.         lua_xmove(L1, L, 1);  /* move error message */
  8277.         return -1;  /* error flag */
  8278.     }
  8279. };
  8280.  
  8281.  
  8282. static int coresume(lua_State* L) {
  8283.     lua_State* L1 = getco(L);
  8284.     int r = auxresume(L, L1, lua_gettop(L) - 1);
  8285.     if (r < 0) {
  8286.         lua_pushboolean(L, 0);
  8287.         lua_insert(L, -2);
  8288.         return 2;  /* return false + error message */
  8289.     }
  8290.     else {
  8291.         lua_pushboolean(L, 1);
  8292.         lua_insert(L, -(r + 1));
  8293.         return r + 1;  /* return true + 'resume' returns */
  8294.     }
  8295. };
  8296.  
  8297.  
  8298. static int wrap(lua_State* L) {
  8299.     lua_State* L2 = lua_tothread(L, lua_upvalueindex(1));
  8300.     int r = auxresume(L, L2, lua_gettop(L));
  8301.     if (r < 0) {
  8302.         if (lua_type(L, -1) == LUA_TSTRING) {  /* error object is a string? */
  8303.             luaL_where(L, 1);  /* add extra info */
  8304.             lua_insert(L, -2);
  8305.             lua_concat(L, 2);
  8306.         }
  8307.         return lua_error(L);  /* propagate error */
  8308.     }
  8309.     return r;
  8310. };
  8311.  
  8312. static int cocreate(lua_State* L) {
  8313.     luaL_checktype(L, 1, LUA_TFUNCTION);
  8314.     lua_State* L2 = lua_newthread(L);
  8315.     lua_pushvalue(L, 1);  /* move function to top */
  8316.     lua_xmove(L, L2, 1);  /* move function from L to NL */
  8317.     return 1;
  8318. };
  8319.  
  8320. static int cowrap(lua_State* L) {
  8321.     cocreate(L);
  8322.     lua_pushcclosure(L, cowrap, 1);
  8323.     return 1;
  8324. };
  8325.  
  8326. static int coyield(lua_State* L) {
  8327.     return lua_yield(L, lua_gettop(L));
  8328. };
  8329.  
  8330. static int costatus(lua_State* L) {
  8331.     lua_State* L1 = getco(L);
  8332.     if (L == L1) lua_pushliteral(L, "running");
  8333.     else {
  8334.         switch (lua_status(L1)) {
  8335.         case LUA_YIELD:
  8336.             lua_pushliteral(L, "suspended");
  8337.             break;
  8338.         case LUA_OK: {
  8339.             lua_Debug ar;
  8340.             if (lua_getstack(L1, 0, &ar) > 0)  /* does it have frames? */
  8341.                 lua_pushliteral(L, "normal");  /* it is running */
  8342.             else if (lua_gettop(L1) == 0)
  8343.                 lua_pushliteral(L, "dead");
  8344.             else
  8345.                 lua_pushliteral(L, "suspended");  /* initial state */
  8346.             break;
  8347.         }
  8348.         default:  /* some error occurred */
  8349.             lua_pushliteral(L, "dead");
  8350.             break;
  8351.         }
  8352.     }
  8353.     return 1;
  8354. };
  8355.  
  8356. static int coyieldable(lua_State* L) {
  8357.     lua_pushboolean(L, lua_isyieldable(L));
  8358.     return 1;
  8359. };
  8360.  
  8361. static int corunning(lua_State* L) {
  8362.     int ismain = lua_pushthread(L);
  8363.     lua_pushboolean(L, ismain);
  8364.     return 2;
  8365. };
  8366.  
  8367. const char* LUA = R"(
  8368. th = create(function(a, b)
  8369.    local c = a+b
  8370.   print("a = "..a.." b = "..b)
  8371.    coroutine.yield()
  8372.    return c
  8373. end)
  8374.  
  8375. co, res = resume(th, 1, 2)
  8376. print("status = "..tostring(co).." res = ".. tostring(res))
  8377.  
  8378. co, res = resume(th)
  8379. print("status = "..tostring(co).." res = ".. tostring(res))
  8380.  
  8381. co, res = resume(th)
  8382. print("status = "..tostring(co).." res = ".. tostring(res))
  8383.  
  8384. )";
  8385. int main(int argc, char* argv[]) {
  8386.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  8387.     luaL_openlibs(L);
  8388.     lua_register(L, "create", cocreate);
  8389.     lua_register(L, "resume", coresume);
  8390.     checkerror(L, LUA);
  8391.  
  8392.     lua_close(L);
  8393.     return 0;
  8394. };
  8395.  
  8396. Вариант 3.
  8397.  
  8398. static lua_State* getthread(lua_State* L) {
  8399.     lua_State* L1 = lua_tothread(L, 1);
  8400.     luaL_argcheck(L, L1, 1, "thread expected"); /*void luaL_argcheck(lua_State * L, int cond,
  8401.     int arg, const char* extramsg); Проверяет истинно ли условие cond. Если это не так, выдает ошибку
  8402.     со стандартным сообщением об ошибке(смотрите luaL_argerror).*/
  8403.     return L1;
  8404. };
  8405.  
  8406. static int checkresume(lua_State* L, lua_State* L1, int narg) {
  8407.     int status;
  8408.     if (!lua_checkstack(L1, narg)) {/*Гарантирует, что в стеке есть хотя бы свободные слоты стека.
  8409.         Он возвращает false, если не может увеличить стек до этого размера. Эта функция никогда не сжимает стек;
  8410.         если стек уже больше нового размера, он остается без изменений.*/
  8411.         lua_pushliteral(L, "too many arguments to resume");/*Этот макрос эквивалентен lua_pushlstring, но может
  8412.          использоваться только тогда, когда sявляется литеральной строкой. В этих случаях он автоматически
  8413.          предоставляет длину строки. */
  8414.         return -1;  /* error flag */
  8415.     }
  8416.     if (lua_status(L1) == LUA_OK && lua_gettop(L1) == 0) {
  8417.         lua_pushliteral(L, "cannot resume dead coroutine");
  8418.         return -1;  /* error flag */
  8419.     }
  8420.     lua_xmove(L, L1, narg);
  8421.     status = lua_resume(L1, L, narg);
  8422.     if (status == LUA_OK || status == LUA_YIELD) {
  8423.         int nres = lua_gettop(L1);
  8424.         if (!lua_checkstack(L, nres + 1)) {
  8425.             lua_pop(L1, nres);  /* remove results anyway */
  8426.             lua_pushliteral(L, "too many results to resume");
  8427.             return -1;  /* error flag */
  8428.         }
  8429.         lua_xmove(L1, L, nres);  /* move yielded values */
  8430.         return nres;
  8431.     }
  8432.     else {
  8433.         lua_xmove(L1, L, 1);  /* move error message */
  8434.         return -1;  /* error flag */
  8435.     }
  8436. };
  8437.  
  8438. static int coresume(lua_State* L) {
  8439.     lua_State* L1 = getthread(L);
  8440.     int r = checkresume(L, L1, lua_gettop(L) - 1);
  8441.     if (r < 0) {
  8442.         lua_pushboolean(L, 0);
  8443.         lua_insert(L, -2);
  8444.         return 2;  /* return false + error message */
  8445.     }
  8446.     else {
  8447.         lua_pushboolean(L, 1);
  8448.         lua_insert(L, -(r + 1));
  8449.         return r + 1;  /* return true + 'resume' returns */
  8450.     }
  8451. };
  8452.  
  8453.  
  8454.  
  8455.  
  8456. static int cocreate(lua_State* L) {
  8457.     luaL_checktype(L, 1, LUA_TFUNCTION);
  8458.     lua_State* L2 = lua_newthread(L);
  8459.     lua_pushvalue(L, 1);  /* move function to top */
  8460.     lua_xmove(L, L2, 1);  /* move function from L to NL */
  8461.     return 1;
  8462. };
  8463.  
  8464. static int coyield(lua_State* L) {
  8465.     return lua_yield(L, lua_gettop(L));
  8466. };
  8467.  
  8468.  
  8469.  
  8470.  
  8471. const char* LUA = R"(
  8472. th = create(function(a, b)
  8473.    local c = a+b
  8474.   print("a = "..a.." b = "..b)
  8475.    coroutine.yield()
  8476.    return c
  8477. end)
  8478.  
  8479. co, res = resume(th, 1, 2)
  8480. print("status = "..tostring(co).." res = ".. tostring(res))
  8481.  
  8482. co, res = resume(th)
  8483. print("status = "..tostring(co).." res = ".. tostring(res))
  8484.  
  8485. co, res = resume(th)
  8486. print("status = "..tostring(co).." res = ".. tostring(res))
  8487.  
  8488. )";
  8489. int main(int argc, char* argv[]) {
  8490.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  8491.     luaL_openlibs(L);
  8492.     lua_register(L, "create", cocreate);
  8493.     lua_register(L, "resume", coresume);
  8494.     checkerror(L, LUA);
  8495.  
  8496.     lua_close(L);
  8497.     return 0;
  8498. };
  8499.  
  8500.  
  8501.  
  8502.  
  8503. Копирование стека и создания нового состояния.
  8504. lua_State* copystack(lua_State* L) {
  8505.     lua_State* L1 = luaL_newstate();
  8506.     int stacksize = lua_gettop(L);
  8507.     stacksize++;
  8508.     for (int i = 1; i < stacksize; i++) {
  8509.         lua_pushvalue(L, i);// копировать на вершину стека.
  8510.         lua_xmove(L, L1, 1);// Снимает с L1 элементов передает L.
  8511.     };
  8512.     return L1;
  8513. };
  8514. int main(int argc, char* argv[]) {
  8515.  
  8516.     lua_State* L = luaL_newstate();
  8517.     luaL_openlibs(L);
  8518.     for (int i = 1; i < 8; i++) {
  8519.         pushlua(L, i*2);    }
  8520.  
  8521.     showstack(L);
  8522.     lua_State* L1 = copystack(L);
  8523.     showstack(L1);
  8524.     showstack(L);
  8525.  
  8526.     lua_close(L1);
  8527.     lua_close(L);
  8528.     return 0;
  8529. };
  8530.  
  8531.  
  8532.  
  8533.  
  8534. Копирование стека между потоками.
  8535.  
  8536. lua_State* copystack(lua_State* L) {
  8537.     int stacksize = lua_gettop(L);
  8538.     stacksize++;
  8539.     for (int i = 1; i < stacksize; i++){lua_pushvalue(L, i);
  8540.     }
  8541.  
  8542.     lua_State* L1 = lua_newthread(L);
  8543.     lua_insert(L, 1); stacksize--;
  8544.     lua_xmove(L, L1, stacksize);// Снимает с L1 элементов передает L.
  8545.     return L1;
  8546. };
  8547. int main() {
  8548.     lua_State* L = luaL_newstate();
  8549.     luaL_openlibs(L);
  8550.     for (int i = 1; i < 5; i++){pushlua(L, i);
  8551.     }
  8552.  
  8553.     showstack(L);
  8554.     lua_State* L1 = copystack(L);
  8555.     showstack(L);
  8556.     showstack(L1);
  8557.  
  8558.     lua_close(L);
  8559.     return 0;
  8560. };
  8561.  
  8562. Вариант 2.
  8563. lua_State* copystack(lua_State* L) {
  8564.     lua_State* L1 = lua_newthread(L);
  8565.     lua_insert(L, 1);
  8566.     int stacksize = lua_gettop(L);
  8567.     stacksize++;
  8568.     for (int i = 1; i < stacksize; i++) {
  8569.         lua_pushvalue(L, i);// копировать на вершину стека.
  8570.         lua_xmove(L, L1, 1);// Снимает с L1 элементов передает L.
  8571.     };
  8572.     lua_remove(L1, 1);//удалить по индексу из стека.
  8573.     return L1;
  8574. };
  8575.  
  8576. const char* LUA = R"(
  8577. foo()
  8578. )";
  8579. const char* LUA1 = R"(
  8580. foo1()
  8581. )";
  8582. int f(lua_State* L) {
  8583.     cout << "hi foo c++" << endl;
  8584.     return 0;
  8585. };
  8586. int f1(lua_State* L) {
  8587.     for (int i = 0; i < 10; i++)    {
  8588.         cout << i << endl;
  8589.     }
  8590.     return 0;
  8591. };
  8592.  
  8593. int main(int argc, char* argv[]) {
  8594.  
  8595.     lua_State* L = luaL_newstate();
  8596.     luaL_openlibs(L);
  8597.     lua_register(L, "foo", f);
  8598.     lua_register(L, "foo1", f1);
  8599.  
  8600.     lua_State* L1 = copystack(L);
  8601.  
  8602.     thread th(checkerror, L1, LUA1);
  8603.     checkerror(L, LUA);
  8604.     th.join();
  8605.     lua_close(L);
  8606.     return 0;
  8607. };
  8608.  
  8609. lua_State* movetostack(lua_State* L, lua_State* L1) {
  8610.     int stacksize = lua_gettop(L);
  8611.     stacksize++;
  8612.     for (int i = 1; i < stacksize; i++) {
  8613.         if ( LUA_TTHREAD ==lua_type(L, i) )
  8614.         {
  8615.             continue;
  8616.         }
  8617.         lua_pushvalue(L, i);// копировать на вершину стека.
  8618.         lua_xmove(L, L1, 1);// Снимает с L1 элементов передает L.
  8619.     };
  8620.     return L1;
  8621. };
  8622. Поход ооп.
  8623.  
  8624. struct state{
  8625.     lua_State* L=NULL;
  8626.     state() {
  8627.         lua_State* L1 = luaL_newstate();
  8628.         luaL_openlibs(L1);
  8629.          this->L = L1;
  8630.         cout << L << endl;
  8631. }
  8632.     lua_State* get(){
  8633.         this->L = L;
  8634.         return L;
  8635.     }
  8636. ~state(){
  8637.     cout << "dec state " << L << endl;
  8638.     lua_close(L);
  8639.     }
  8640. };
  8641.  
  8642. int main(int argc, char* argv[]) {
  8643.     state Lua;
  8644.     lua_State* L = Lua.get();
  8645.  
  8646.     cout << L << endl;
  8647.     return 0;
  8648. };
  8649.  
  8650. lua_State* copystack(lua_State* L);
  8651. int newthread(lua_State* L) {// новый поток
  8652. //  if (LUA_TSTRING == lua_type(L, -1)){
  8653.     //  CMessages::AddMessageJumpQ(L"Create", 4000, 1);//выводит сообщение на экран
  8654.     CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 100;// дать денег  
  8655. //  }
  8656.     //char const* funs = Stack<char const*>::get(L, 1);
  8657.     //lua_getglobal(L, funs);
  8658.     //  LUA_TFUNCTION == lua_type(L, -1))
  8659.     return 0;
  8660. };
  8661.  
  8662. lua_State* copystack(lua_State* L) {
  8663.     lua_State* L1 = luaL_newstate();
  8664.     luaL_openlibs(L1);
  8665.     int stacksize = lua_gettop(L);
  8666.     stacksize++;
  8667.     for (int i = 1; i < stacksize; i++) {
  8668.         lua_pushvalue(L, i);// копировать на вершину стека.
  8669.         lua_xmove(L, L1, 1);// Снимает с L1 элементов передает L.
  8670.     };
  8671.     return L1;
  8672. };
  8673.  
  8674.  
  8675. alignas - это новая штука с с++11 стандарта и предназначена, чтобы устаканить то, что творится в разных компиляторах. Чтобы не говорили разработчики других языков, но иногда нужно писать немножко низкоуровневого кода, чтобы получить существенный плюс в скорости.
  8676. Как известно, процессоры лучше работают с данными в памяти, если они выровнены по границе в 4/8/16 байт. А в некоторых случаях данные обязаны быть выровнены (например, с некоторыми SSE командами и на некоторых ARM процессорах).
  8677. Что такое выравнивание по границе? Это просто адрес, который кратен заданной степени двойки. То есть, адрес 24 выровнен по границе 2, 4, 8, но не 16. Адрес 1024 выровнен по 2, 4, 8, 16, 32 и многим другим. Можно сказать и по-другому - адрес, выровненный по границе 16 в бинарном виде заканчивается на 4 нуля.
  8678. alignas как раз и заставляет компилятор сделать это выравнивание. Да, часто это идет в ущерб памяти (появляются пустоты), но в некоторых случаях (с SSE) можно получить двукратный прирост просто по той причине, что адрес выровнен по границе 16/32. Почему так происходит? Все просто - современные процессоры уже давно не загружают данные по байту из памяти - они обычно грузят как минимум по 4 байта сразу, более того, грузят по выровненным адресам по границе 4. И если нужно загрузить 4 невыровненных байта, то процессору приходится делать это в три этапа - загружаем первые байт (но при этом загружаем 4 байта), потом загружаем вторую половину, а потом складываем в памяти. А так как операция обращения к памяти - медленная - это длится достаточно долго.
  8679. Нужно ли в своем коде постоянно писать выравнивание? Нет, не нужно. Компиляторы достаточно умные и сами могут догадаться. Но есть случаи, когда это лучше сделать.
  8680. переменная используется для SSE/MMX.
  8681. переменная-массив, достаточно большого размера, по которому нужно будет много итерироваться (бегать).
  8682. числодробилки.
  8683. Почему расстояние равно 2016, а без него 24?
  8684. а на ideone вообще получилось -252:)
  8685. alignas говорит "выровняй", а как именно разместить в памяти - это другое дело. В Вашем случае компилятор вначале разместил первую переменную по адресу кратному 16. Вторую, нужно разместить по адресу кратному 1024. Логично, что такое может быть как сразу (потому что первая переменная занимает ровно 16 байт, так и через много-много байт (мы же не знаем адреса первой переменной).
  8686. Многие компиляторы в отладочном режиме за массивами всегда добавляют несколько байт - для того, что бы препятствовать классическому выходу за пределы массива на один элемент. Поэтому, чтобы понять, почему там именно 2016 - нужно смотреть в конкретную версию компилятора и параметры компиляции.
  8687.  
  8688.  
  8689.  
  8690.  
  8691. int main(int argc, char *argv[]) {
  8692.     lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  8693.     luaL_openlibs(L);  
  8694.     int *i= NULL;
  8695.     lua_pushnumber(L, 10);// отправить в стек число.
  8696.     lua_pushstring(L, "yes");
  8697.     cout <<  lua_tonumberx(L, 2, i) << endl;// если в позиции не число, то вернет 0.
  8698.     /* i булевое значение. */
  8699.  
  8700.  cout << i << endl;
  8701.     lua_close(L);// закрыть состояние
  8702.     cin.get();//ожидает ввода символа программа завершается.
  8703.  
  8704.     return 0;
  8705. }
  8706.  
  8707.     lua_pushstring(L, "yes");
  8708.     size_t len;// len длина строки.
  8709.     const char *s = lua_tolstring(L, -1, &len);
  8710.     cout << s<<"\n " << endl;
  8711.     cout << len << endl;
  8712.  
  8713.  
  8714.     lua_pushstring(L, "yes");
  8715.     lua_copy(L, -1, -2);//копировать из одной позиции в другую.
  8716.     cout << lua_tostring(L, -2);
  8717.  
  8718.  
  8719.  
  8720. //эта функция берет значение из стека (по индексу -1),
  8721.             //и использует его в качестве ключа для поиска по таблице, которая
  8722.             //находится в стеке по индексу i, в случае если находит, добавляет в
  8723.             //стек пару ключ - значение, следующие в таблице после ключа находившегося в стеке
  8724.             //если больше нет значений, ф-я возвращает 0
  8725.             //lua_next используется для перебора элементов таблицы
  8726.  
  8727.     int n = lua_gettop(L);/* получаем количество элементов в стеке.*/
  8728.     cout <<"\nthe number on the stack = "  << n<<"\n";
  8729.     lua_settop(L, 0);// уст кол-во элементов в стеке. 0 - очистить стек.
  8730.  
  8731.     for (int i = 1; i <= n; ++i) {
  8732.         cout << lua_typename(L, i) << endl; }
  8733.  
  8734.  
  8735.  
  8736.  
  8737. int main(int argc, char *argv[]) {
  8738.  
  8739.     lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  8740.     luaL_openlibs(L);        /* opens the standard libraries */
  8741.  
  8742.     char buff[256];
  8743.     int error;
  8744.  
  8745.     while (fgets(buff, sizeof(buff), stdin) != NULL) {
  8746.         error = luaL_loadstring(L, buff) || lua_pcall(L, 0, 0, 0);
  8747.         if (error) {
  8748.             fprintf(stderr, "%s\n", lua_tostring(L, -1));
  8749.             lua_pop(L, 1);  /* pop error message from the stack */
  8750.         }
  8751.     }
  8752.  
  8753.     lua_close(L);// закрыть состояние
  8754.     cin.get();//ожидает ввода символа программа завершается.
  8755.  
  8756.     return 0;
  8757. }
  8758.  
  8759.  
  8760.  
  8761.  
  8762.  
  8763.  
  8764.       int getglobint (lua_State *L, const char *var) {
  8765.         int isnum, result;
  8766.         lua_getglobal(L, var);
  8767.         result = (int)lua_tointegerx(L, -1, &isnum);
  8768.         if (!isnum)
  8769.           error(L, "'%s' should be a number\n", var);
  8770.         lua_pop(L, 1);   /* remove result from the stack */
  8771.         return result;
  8772.       }
  8773.      
  8774.       void load (lua_State *L, const char *fname, int *w, int *h) {
  8775.         if (luaL_loadfile(L, fname) || lua_pcall(L, 0, 0, 0))
  8776.           error(L, "cannot run config. file: %s", lua_tostring(L, -1));
  8777.         *w = getglobint(L, "width");
  8778.         *h = getglobint(L, "height");
  8779.       }
  8780.  
  8781.  
  8782.  
  8783.  
  8784.   BLUE = {red = 0, green = 0, blue = 1.0}
  8785.       other color definitions
  8786.      
  8787.       background = BLUE
  8788.  
  8789.  
  8790.         lua_getglobal(L, "background");
  8791.         if (!lua_istable(L, -1))
  8792.           error(L, "'background' is not a table");
  8793.      
  8794.         red = getcolorfield(L, "red");
  8795.         green = getcolorfield(L, "green");
  8796.         blue = getcolorfield(L, "blue");
  8797.  
  8798.   /* assume that table is on the top of the stack */
  8799.       int getcolorfield (lua_State *L, const char *key) {
  8800.         int result, isnum;
  8801.         lua_pushstring(L, key);  /* push key */
  8802.         lua_gettable(L, -2);  /* get background[key] */
  8803.         result = (int)(lua_tonumberx(L, -1, &isnum) * MAX_COLOR);
  8804.         if (!isnum)
  8805.           error(L, "invalid component '%s' in color", key);
  8806.         lua_pop(L, 1);  /* remove number */
  8807.         return result;
  8808.       }
  8809.   struct ColorTable {
  8810.         char *name;
  8811.         unsigned char red, green, blue;
  8812.       } colortable[] = {
  8813.         {"WHITE",   MAX_COLOR, MAX_COLOR, MAX_COLOR},
  8814.         {"RED",     MAX_COLOR,         0,         0},
  8815.         {"GREEN",           0, MAX_COLOR,         0},
  8816.         {"BLUE",            0,         0, MAX_COLOR},
  8817.         other colors
  8818.         {NULL, 0, 0, 0}  /* sentinel */
  8819.       };
  8820.  
  8821.   WHITE = {red = 1.0, green = 1.0, blue = 1.0}
  8822.       RED   = {red = 1.0, green = 0,   blue = 0}
  8823.  
  8824.      /* assume that table is on top */
  8825.       void setcolorfield (lua_State *L, const char *index, int value) {
  8826.         lua_pushstring(L, index); /* key */
  8827.         lua_pushnumber(L, (double)value / MAX_COLOR);  /* value */
  8828.         lua_settable(L, -3);
  8829.       }
  8830.  
  8831.       void setcolor (lua_State *L, struct ColorTable *ct) {
  8832.         lua_newtable(L);                 /* creates a table */
  8833.         setcolorfield(L, "red", ct->red);
  8834.         setcolorfield(L, "green", ct->green);
  8835.         setcolorfield(L, "blue", ct->blue);
  8836.         lua_setglobal(L, ct->name);      /* 'name' = table */
  8837.       }
  8838.  
  8839.  
  8840.       int i = 0;
  8841.       while (colortable[i].name != NULL)
  8842.         setcolor(L, &colortable[i++]);
  8843.  
  8844.  
  8845.       void call_va (lua_State *L, const char *func,
  8846.                                   const char *sig, ...) {
  8847.         va_list vl;
  8848.         int narg, nres;  /* number of arguments and results */
  8849.      
  8850.         va_start(vl, sig);
  8851.         lua_getglobal(L, func);  /* push function */
  8852.      
  8853.         push and count arguments (Figure 28.6, “Pushing arguments for the generic call function”)
  8854.      
  8855.         nres = strlen(sig);  /* number of expected results */
  8856.      
  8857.         if (lua_pcall(L, narg, nres, 0) != 0)  /* do the call */
  8858.           error(L, "error calling '%s': %s", func,
  8859.                                              lua_tostring(L, -1));
  8860.      
  8861.         retrieve results (Figure 28.7, “Retrieving results for the generic call function”)
  8862.      
  8863.         va_end(vl);
  8864.       }
  8865. Figure 28.6. Pushing arguments for the generic call function
  8866.         for (narg = 0; *sig; narg++) {  /* repeat for each argument */
  8867.      
  8868.           /* check stack space */
  8869.           luaL_checkstack(L, 1, "too many arguments");
  8870.      
  8871.           switch (*sig++) {
  8872.      
  8873.             case 'd':  /* double argument */
  8874.               lua_pushnumber(L, va_arg(vl, double));
  8875.               break;
  8876.      
  8877.             case 'i':  /* int argument */
  8878.               lua_pushinteger(L, va_arg(vl, int));
  8879.               break;
  8880.      
  8881.             case 's':  /* string argument */
  8882.               lua_pushstring(L, va_arg(vl, char *));
  8883.               break;
  8884.      
  8885.             case '>':  /* end of arguments */
  8886.               goto endargs;  /* break the loop */
  8887.      
  8888.             default:
  8889.               error(L, "invalid option (%c)", *(sig - 1));
  8890.           }
  8891.      
  8892.         }
  8893.         endargs: Extending Your Application
  8894. 245
  8895. Figure 28.7. Retrieving results for the generic call function
  8896.         nres = -nres;  /* stack index of first result */
  8897.         while (*sig) {  /* repeat for each result */
  8898.           switch (*sig++) {
  8899.      
  8900.             case 'd': {  /* double result */
  8901.               int isnum;
  8902.               double n = lua_tonumberx(L, nres, &isnum);
  8903.               if (!isnum)
  8904.                 error(L, "wrong result type");
  8905.               *va_arg(vl, double *) = n;
  8906.               break;
  8907.             }
  8908.      
  8909.             case 'i': {  /* int result */
  8910.               int isnum;
  8911.               int n = lua_tointegerx(L, nres, &isnum);
  8912.               if (!isnum)
  8913.                 error(L, "wrong result type");
  8914.               *va_arg(vl, int *) = n;
  8915.               break;
  8916.             }
  8917.      
  8918.             case 's': {  /* string result */
  8919.               const char *s = lua_tostring(L, nres);
  8920.               if (s == NULL)
  8921.                 error(L, "wrong result type");
  8922.               *va_arg(vl, const char **) = s;
  8923.               break;
  8924.             }
  8925.      
  8926.             default:
  8927.               error(L, "invalid option (%c)", *(sig - 1));
  8928.           }
  8929.           nres++;
  8930.         }
  8931.  
  8932.  
  8933.  
  8934.  
  8935. function is minimal:
  8936.       static int l_sin (lua_State *L) {
  8937.         double d = luaL_checknumber(L, 1);
  8938.         lua_pushnumber(L, sin(d));
  8939.         return 1;  /* number of results */
  8940.       }
  8941.       static int l_dir (lua_State *L) {
  8942.         DIR *dir;
  8943.         struct dirent *entry;
  8944.         int i;
  8945.         const char *path = luaL_checkstring(L, 1);
  8946.      
  8947.         /* open directory */
  8948.         dir = opendir(path);
  8949.         if (dir == NULL) {  /* error opening the directory? */
  8950.           lua_pushnil(L);  /* return nil... */
  8951.           lua_pushstring(L, strerror(errno));  /* and error message */
  8952.           return 2;  /* number of results */
  8953.         }
  8954.      
  8955.         /* create result table */
  8956.         lua_newtable(L);
  8957.         i = 1;
  8958.         while ((entry = readdir(dir)) != NULL) {  /* for each entry */
  8959.           lua_pushinteger(L, i++);  /* push key */
  8960.           lua_pushstring(L, entry->d_name);  /* push value */
  8961.           lua_settable(L, -3);    /* table[i] = entry name */
  8962.         }
  8963.      
  8964.         closedir(dir);
  8965.         return 1;  /* table is already on top */
  8966.       }
  8967.  
  8968. static int l_dir (lua_State *L) {
  8969.          as before
  8970.       }
  8971.       static const struct luaL_Reg mylib [] = {
  8972.         {"dir", l_dir},
  8973.         {NULL, NULL}  /* sentinel */
  8974.       };
  8975.  
  8976.  
  8977.       int luaopen_mylib (lua_State *L) {
  8978.         luaL_newlib(L, mylib);
  8979.         return 1;
  8980.       }
  8981.       local mylib = require "mylib"
  8982.  
  8983.       int l_map (lua_State *L) {
  8984.         int i, n;
  8985.      
  8986.         /* 1st argument must be a table (t) */
  8987.         luaL_checktype(L, 1, LUA_TTABLE);
  8988.      
  8989.         /* 2nd argument must be a function (f) */
  8990.         luaL_checktype(L, 2, LUA_TFUNCTION);
  8991.      
  8992.         n = luaL_len(L, 1);  /* get size of table */
  8993.      
  8994.         for (i = 1; i <= n; i++) {
  8995.           lua_pushvalue(L, 2);   /* push f */
  8996.           lua_geti(L, 1, i);  /* push t[i] */
  8997.           lua_call(L, 1, 1);     /* call f(t[i]) */
  8998.           lua_seti(L, 1, i);  /* t[i] = result */
  8999.         }
  9000.      
  9001.         return 0;  /* no results */
  9002.       }
  9003.  
  9004. static int l_split (lua_State *L) {
  9005.         const char *s = luaL_checkstring(L, 1);      /* subject */
  9006.         const char *sep = luaL_checkstring(L, 2);  /* separator */
  9007.         const char *e;
  9008.         int i = 1;
  9009.      
  9010.         lua_newtable(L);  /* result table */
  9011.      
  9012.         /* repeat for each separator */
  9013.         while ((e = strchr(s, *sep)) != NULL) {
  9014.           lua_pushlstring(L, s, e - s);  /* push substring */
  9015.           lua_rawseti(L, -2, i++);   /* insert it in table */
  9016.           s = e + 1;  /* skip separator */
  9017.         }
  9018.      
  9019.         /* insert last substring */
  9020.         lua_pushstring(L, s);
  9021.         lua_rawseti(L, -2, i);
  9022.      
  9023.         return 1;  /* return the table */
  9024.       }
  9025.  
  9026.       static int str_upper (lua_State *L) {
  9027.         size_t l;
  9028.         size_t i;
  9029.         luaL_Buffer b;
  9030.         const char *s = luaL_checklstring(L, 1, &l);
  9031.         char *p = luaL_buffinitsize(L, &b, l);
  9032.         for (i = 0; i < l; i++)
  9033.           p[i] = toupper(uchar(s[i]));
  9034.         luaL_pushresultsize(&b, l);
  9035.         return 1;
  9036.       }
  9037. static int tconcat (lua_State *L) {
  9038.         luaL_Buffer b;
  9039.         int i, n;
  9040.         luaL_checktype(L, 1, LUA_TTABLE);
  9041.         n = luaL_len(L, 1);
  9042.         luaL_buffinit(L, &b);
  9043.         for (i = 1; i <= n; i++) {
  9044.           lua_geti(L, 1, i);  /* get string from table */
  9045.           luaL_addvalue(b);   /* add it to the buffer */
  9046.         }
  9047.         luaL_pushresult(&b);
  9048.         return 1;
  9049.       }
  9050.  
  9051. Статические переменные это реестр.
  9052.    /* store a string */
  9053.       lua_pushlightuserdata(L, (void *)&Key);  /* push address */
  9054.       lua_pushstring(L, myStr);  /* push value */
  9055.       lua_settable(L, LUA_REGISTRYINDEX);  /* registry[&Key] = myStr */
  9056.      
  9057.       /* retrieve a string */
  9058.       lua_pushlightuserdata(L, (void *)&Key);  /* push address */
  9059.       lua_gettable(L, LUA_REGISTRYINDEX);  /* retrieve value */
  9060.       myStr = lua_tostring(L, -1);  /* convert to string */
  9061. We will discuss light userdata in more detail in the section called “Light Userdata”.
  9062. To  simplify  the  use  of  variable  addresses  as  unique  keys,  Lua  5.2  introduced  two  new  functions:
  9063. lua_rawgetp and lua_rawsetp. They are similar to lua_rawgeti and lua_rawseti, but they
  9064. use C pointers (translated to light userdata) as keys. With them, we can write the previous code like this:
  9065.       static char Key = 'k';
  9066.      
  9067.       /* store a string */
  9068.       lua_pushstring(L, myStr);
  9069.       lua_rawsetp(L, LUA_REGISTRYINDEX, (void *)&Key);
  9070.      
  9071.       /* retrieve a string */
  9072.       lua_rawgetp(L, LUA_REGISTRYINDEX, (void *)&Key);
  9073.       myStr = lua_tostring(L, -1);
  9074. int t_tuple (lua_State  *L) {
  9075.         int op  =   luaL_optint(L,  10);
  9076.         if  (op ==  0)  {   /*  нет  аргументов?   */
  9077.                 int i;
  9078.                 /*  заталкивает  каждое    допустимое    верхнее  значение    в  стек    */
  9079.                 for (=   1;  !lua_isnone(L,  lua_upvalueindex(i));   i++)
  9080.                         lua_pushvalue(L,    lua_upvalueindex(i));
  9081.                 return  i   -   1;  /*  число  значений    в  стеке  */
  9082.         }
  9083.         else    {   /*  получает    поле    'op'    */
  9084.                 luaL_argcheck(L,    0   <   op, 1"index  out of  range");
  9085.                 if  (lua_isnone(L,  lua_upvalueindex(op)))
  9086.                         return  0;  /*  такого    поля    нет  */
  9087.                 lua_pushvalue(L,    lua_upvalueindex(op));
  9088.                 return  1;
  9089.         }
  9090. } int   t_new   (lua_State  *L) {
  9091.         lua_pushcclosure(L, t_tuple,    lua_gettop(L));
  9092.         return  1;
  9093. }
  9094. static  const   struct  luaL_Reg    tuplelib    []  =   {
  9095.         {"new", t_new},
  9096.         {NULLNULL}
  9097. };
  9098. int luaopen_tuple   (lua_State  *L) {
  9099.         luaL_newlib(L,  tuplelib);
  9100.         return  1;
  9101.  
  9102.  
  9103.  
  9104.  
  9105. INT lua_next ( lua_State * L, INT индекс);
  9106. получает ключ из стека и отправляет пару ключ-значение из таблицы по заданному индексу («следующая» пара после заданного ключа). Если в таблице больше нет элементов. Ключ имеет -2, а значение -1.
  9107.  
  9108.  lua_next возвращается 0 (и ничего не выдвигается).
  9109. Типичный обход выглядит так:
  9110.      / * таблица находится в стеке с индексом 't' * /
  9111.      lua_pushnil (L); / * первый ключ * /
  9112.      while (lua_next (L, t)! = 0) {
  9113.        / * использует 'ключ' (в индексе -2) и 'значение' (в индексе -1) * /
  9114.        printf ("% s -% s \ n",
  9115.               lua_typename (L, lua_type (L, -2)),
  9116.               lua_typename (L, lua_type (L, -1)));
  9117.        / * удаляет «значение»; держит «ключ» для следующей итерации * /
  9118.        lua_pop (L, 1);
  9119.      }
  9120. При обходе таблицы не вызывайте lua_tolstringнапрямую ключ, если только вы не знаете, что ключ на самом деле является строкой. Напомним, что изменяется значение по заданному индексу; это смущает следующий звонок . lua_tolstring lua_next
  9121.  
  9122. недействительными * lua_newuserdata ( lua_State * L, size_t размера);
  9123. Эта функция выделяет новый блок памяти с заданным размером, помещает в стек новые полные пользовательские данные с адресом блока и возвращает этот адрес.
  9124. Пользовательские данные представляют значения C в Lua. Полный UserData представляет собой блок памяти. Это объект (например, таблица): вы должны создать его, у него может быть свой собственный метатабль, и вы можете определить, когда он собирается. Полные пользовательские данные равны только себе (при необработанном равенстве).
  9125. Когда Lua собирает полные данные пользователя с gcметаметодом, Lua вызывает метаметод и помечает данные пользователя как завершенные. Когда эти пользовательские данные собираются снова, Lua освобождает соответствующую память.
  9126. недействительный lua_pushlightuserdata ( lua_State * L, недействительный * р);
  9127. Помещает легкие пользовательские данные в стек.
  9128. Пользовательские данные представляют значения C в Lua. Свет UserData представляет собой указатель. Это значение (например, число): вы не создаете его, у него нет индивидуального метатабора, и оно не собирается (как оно никогда не создавалось). Легкие пользовательские данные равны «любым» легким пользовательским данным с тем же C-адресом.
  9129.  
  9130. недействительными * lua_touserdata ( lua_State * L, INT индекс);
  9131. Если значение в данном приемлемом индексе является полными данными пользователя, возвращает адрес его блока. Если значение является легким userdata, возвращает его указатель. В противном случае возвращается NULL.
  9132.  
  9133.  
  9134.     //cout << lua_tostring(lua, 1)<< endl;
  9135.     lua_assert(lua_isstring);
  9136.     lua_pop(lua, 1);// удалить n элементы из стека.
  9137.  
  9138.  
  9139. cout << "\t " << lua_tostring(L, -4) << endl;
  9140.     cout << "\t " << lua_toboolean(L, -3) << endl;
  9141.     cout << "\t " << lua_tonumber(L, -2) << endl;
  9142.     cout << "\t " << lua_tonumber(L, -1) << endl;*/
  9143.  
  9144. static void stackDump(lua_State *L) {
  9145.     int i;
  9146.     int top = lua_gettop(L); /* глубина стека */
  9147.     for (i = 1; i <= top; i++) { /* повторить для каждого уровня */
  9148.         int t = lua_type(L, i); switch (t) {
  9149.         case LUA_TSTRING: { /* strings */ printf("'%s' ", lua_tostring(L, i)); break;   }
  9150.         case LUA_TBOOLEAN: { /* booleans */
  9151.             printf(lua_toboolean(L, i) ? "true " : "false "); break;
  9152.         case LUA_TNUMBER: { /* numbers */ printf("%g ", lua_tonumber(L, i)); break; }
  9153.  
  9154.         default: { /* other values */
  9155.             printf("%s ", lua_typename(L, t)); break;  }
  9156.                  printf(" "); /* put a separator */     }       }
  9157.     }
  9158.     printf("\n"); /* end the listing */
  9159.     return;
  9160. }
  9161. int main(int argc, char *argv[]) {
  9162.  
  9163.     lua_State *L = luaL_newstate();
  9164.     luaL_openlibs(L);//открыть все стандартные библиотеки lua.
  9165.     luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. Файл в котором все происходит.
  9166.     lua_pushboolean(L, 1);
  9167.     lua_pushnumber(L, 10);
  9168.     lua_pushnil(L);
  9169.     lua_pushstring(L, "hello");
  9170.     stackDump(L);   /* true 10 nil 'hello' */
  9171.     lua_pushvalue(L, -4);// копировать элемент в стеке -1.
  9172.     stackDump(L);   /* true 10 nil 'hello' true */
  9173.     lua_replace(L, 3);// снимает значение с вершины стека и устанавливает его как значение элемента с заданным индексом.
  9174.     stackDump(L);   /* true 10 true 'hello' */
  9175.     lua_settop(L, 6);
  9176.     stackDump(L);   /* true 10 true 'hello' nil nil */
  9177.     lua_remove(L, -3);
  9178.     stackDump(L);/* true 10 true nil nil */
  9179.     lua_settop(L, -5);
  9180.     stackDump(L);   /* true */
  9181.  
  9182.     lua_close(L);// закрыть состояние
  9183.     cin.get();//ожидает ввода символа программа завершается.
  9184.     return 0;
  9185. }
  9186.  
  9187.  
  9188. int main(int argc, char *argv[]) {
  9189. constexpr char* LUA_FILE = R"(
  9190.  function Return4()
  9191.   return 4
  9192. end
  9193.  )";
  9194.         lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  9195.         luaL_dostring(L, LUA_FILE);
  9196.         lua_getglobal(L, "Return4");
  9197.  
  9198.         if (lua_iscfunction(L, -1)) {
  9199.  
  9200.             lua_pcall(L, 0, 1, 0);
  9201.  
  9202.             lua_Number number = lua_tonumber(L, -1);// получить 10 из стека 1
  9203.             cout << (int)number << endl;
  9204.         }
  9205.         lua_close(L);
  9206.    
  9207. return 0;
  9208. }
  9209.  
  9210.  
  9211. #include<iostream>
  9212. #include<string>
  9213. #include <stdio.h>
  9214. #include <string>
  9215. #include"lua/lua.hpp"
  9216. using namespace std;
  9217.  
  9218. int main(int argc, char *argv[]) {
  9219. lua_State *lua = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией
  9220.  выделения памяти на основе стандартной функции C realloc и затем устанавливает "тревожную" (panic) функцию,
  9221.  которая печатает сообщение об ошибке к стандартному выводу ошибки в случае фатальных (неустранимых) ошибок.
  9222.  Возвращает новое состояние или значение NULL, если есть ошибка выделения памяти.*/
  9223.     luaL_dostring(lua, "x = 2");/*отправляет строку- переменную = 2 в стек. Функция определяется как следующий макрос */
  9224.     lua_getglobal(lua, "x");// получить значение x
  9225.     if (lua_isnumber(lua, 1)) {//  если 1 позиция в стеке число.
  9226.         int number = lua_tonumber(lua, 1);
  9227.         cout <<"x = "<< number;
  9228.     }
  9229.     return 0;
  9230. }
  9231.     lua_pushcfunction(L, getst);//уст указатель на функцию C++ и создает внутри Lua
  9232.     lua_setglobal(L, "getst"); //получает значение из стека и уст значение global name.
  9233.     luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  9234.     //lua_pcall(L, 0, 0, 0);// вызов функции в lua файле.
  9235.  
  9236. #include<iostream>
  9237. #include"lua/lua.hpp"
  9238. using namespace std;
  9239. int main() {
  9240.     lua_State *lua = luaL_newstate();
  9241.     luaL_openlibs(lua);//открыть все стандартные библиотеки lua.
  9242.     luaL_dofile(lua, "main.lua");// Загружает и запускает заданный файл. Файл в котором все происходит.
  9243.     lua_pcall(lua, 0, 0, 0);// вызов функции в lua файле.  1 параметр кол-во передаваемых, кол-во возвращаемых, обработчик ошибок.
  9244.    
  9245.     lua_close(lua);// закрыть состояние
  9246.     cin.get();//ожидает ввода символа программа завершается.
  9247.  
  9248.     return 0;
  9249. }
  9250. lua
  9251. --print(2362)
  9252.  
  9253.  
  9254.  
  9255.  
  9256. int lua_sq(lua_State *L) {// передаем указатель на состояние.
  9257.     int x = lua_tonumber(L, 1); // получаем 1 элемент из стека.
  9258.     lua_pushnumber(L, x*x);// умножаем x и отправляет в стек.
  9259.     return 1;// вернуть 1.
  9260. }
  9261. int main() {
  9262.     lua_State *L = luaL_newstate();
  9263.     luaL_openlibs(L);//открыть все стандартные библиотеки lua.
  9264.     lua_register(L, "sq", lua_sq);// регистрируем функцию- имя состояние, имя функ в lua, имя функ тут.
  9265.     luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  9266.     lua_pcall(L, 0, 0, 0);// вызов функции, передаем 2 параметра, возвращаем 1.
  9267.     lua_close(L);// закрыть состояние
  9268.     cin.get();//ожидает ввода символа программа завершается.
  9269. return 0;}
  9270.  
  9271. на Lua.
  9272.  
  9273. print(sq(2))
  9274.  
  9275. struct st
  9276. {
  9277.     int x;
  9278.  
  9279. };
  9280.  
  9281. int getst(lua_State *L) {// передаем указатель на состояние
  9282.     st* sp = (st*)lua_newuserdata(L, sizeof(sp));// выделяет памяти с заданным размером,
  9283.     //помещает в стек пользовательские данныеа и возвращает этот адрес.
  9284.     int x1;
  9285.     if (lua_isnumber(L, 1)) {//  если 1 позиция в стеке число.
  9286.          x1 = lua_tonumber(L, 1);} // получаем 1 элемент из стека.
  9287.     else x1 = 0;// что мы передим в getst(2), то будет в структуре
  9288.     sp->x = x1;
  9289.     return 1;// вернуть 1.
  9290. }
  9291. int main() {
  9292.     lua_State *L = luaL_newstate();
  9293.     luaL_openlibs(L);//открыть все стандартные библиотеки lua.
  9294.     lua_pushcfunction(L, getst);//уст указатель на функцию C++ и создает внутри Lua
  9295.     lua_setglobal(L, "getst"); //получает значение из стека и уст значение global name.
  9296.     luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  9297.     //lua_pcall(L, 0, 0, 0);// вызов функции в lua файле.
  9298.     lua_getglobal(L, "sp");// получить значение глобальной переменной.
  9299.     st* sp = (st*)lua_touserdata(L, -1);// получить значение поля структруры из стека.
  9300.     cout << sp->x  << endl;//  
  9301.     lua_close(L);// закрыть состояние
  9302.     cin.get();//ожидает ввода символа программа завершается.
  9303. return 0;}
  9304.  
  9305. lua
  9306. sp=getst()
  9307. print(sp)—адрес памяти выводится
  9308.  
  9309.  
  9310.  
  9311. #include<iostream>
  9312. #include<string>
  9313. #include <stdio.h>
  9314. #include"lua/lua.hpp"
  9315. using namespace std;
  9316.  
  9317. int main() {
  9318.     lua_State *L = luaL_newstate();
  9319.     luaL_openlibs(L);//открыть все стандартные библиотеки lua.
  9320.        luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  9321.     //lua_pcall(L, 0, 0, 0);// вызов функции в lua файле.
  9322.     lua_getglobal(L, "t");// получить значение глобальной переменной, таблица.
  9323.     lua_assert(lua_istable(L, 1));// проверить является 1 элемент стека таблицей
  9324.     lua_pushstring(L, "x");// отправить ключ x в стек.
  9325.     lua_gettable(L, 1);// получить значение по ключу из стека.
  9326.     lua_assert(lua_isnumber(L, 2));// проверить является значение 2 элемента стека число.  
  9327.     int x = lua_tonumber(L, 2);
  9328.     lua_getglobal(L, "t");// получить значение глобальной переменной таблица.
  9329.     lua_pushstring(L, "y");
  9330.     lua_gettable(L, 1);
  9331.     lua_assert(lua_isstring(L, 4));
  9332.     string y = lua_tostring(L, 4);
  9333.     lua_getglobal(L, "t");// получить значение глобальной переменной, таблицей.
  9334.     lua_getfield(L, 5, "z");// отправить ключ в таблицу.
  9335.     lua_assert(lua_isboolean(L, 5));
  9336.     bool z = lua_toboolean(L, 5);// получить булевое значение по ключу.
  9337.     lua_getglobal(L, "t");// получить значение глобальной переменной, таблицей.
  9338.     lua_pushstring(L, "dog");// отправить значение в таблицу.
  9339.     lua_setfield(L, 5, "a");// уст ключ для него.
  9340.     lua_getglobal(L, "t");// получить значение глобальной переменной, таблицей.
  9341.     lua_getfield(L, 5, "a");// отправить ключ в таблицу.
  9342.     lua_assert(lua_isstring(L, 5));
  9343.     string a = lua_tostring(L, -1);
  9344.     cout <<"x = "<<x <<"\ny = "<<y<<"\nz = "<< z << "\na = " << a <<endl;
  9345.     lua_close(L);// закрыть состояние
  9346.     cin.get();//ожидает ввода символа программа завершается.
  9347. return 0;}
  9348. lua
  9349.  
  9350. t= {x=23,y="yes",z=true}
  9351.  
  9352. struct strlua
  9353. {   int x;
  9354. strlua(int x){
  9355.     this->x = x;
  9356. }
  9357. void st(int x){
  9358.     this->x = x;
  9359. }
  9360.  
  9361. };
  9362. int LUA_new(lua_State *S) {
  9363.     strlua *p = new strlua(lua_tonumber(S, 1));
  9364.     lua_pushlightuserdata(S,p);
  9365.     return 0;
  9366. }
  9367. int LUA_set(lua_State *S){
  9368.   strlua *p = (strlua*)lua_touserdata(S,1);
  9369.   p->st(lua_tonumber(S, 1 ));
  9370.     return 0;
  9371. }
  9372. int main() {
  9373.     lua_State *S = luaL_newstate();
  9374.     luaL_openlibs(S);
  9375.     lua_register(S, "new", LUA_new);
  9376.     lua_register(S,"set", LUA_set);
  9377.     luaL_loadfile(S, "man.lua");
  9378.     lua_call(S, 0, 0);
  9379.     cin.get();
  9380.     return 0;
  9381.  
  9382. a=new(2)
  9383. b=set(3)
  9384. print(a)
  9385. print(b)
  9386. struct color{ char r,g,b;
  9387. };
  9388. void LUA_set(lua_State *S, string str, color *& pal) {
  9389.     lua_getglobal(S, str.c_str());
  9390.     lua_pushstring(S, "co");
  9391.     lua_gettable(S, -2);
  9392.     lua_call(S, 0, 4);
  9393.     pal[0] = *(color*)lua_touserdata(S, -4);
  9394.     pal[1] = *(color*)lua_touserdata(S, -3);
  9395.     pal[2] = *(color*)lua_touserdata(S, -2);
  9396.     pal[3] = *(color*)lua_touserdata(S, -1);
  9397.     lua_pop(S, 5);
  9398. }
  9399. int LUA_make(lua_State *S) {
  9400.     color *p = (color*)lua_newuserdata(S, sizeof(color));
  9401.     new (p) color;
  9402.     p->r = lua_tointeger(S, 1);
  9403.     p->g = lua_tointeger(S, 2);
  9404.     p->b = lua_tointeger(S, 3);
  9405.     return 1;
  9406. }
  9407. int main() {
  9408.     lua_State *S = luaL_newstate();
  9409.     luaL_openlibs(S);
  9410.     lua_register(S,"make", LUA_set);
  9411.     lua_register(S, "make", LUA_make);
  9412.     luaL_loadfile(S, "man.lua");
  9413.     lua_call(S, 0, 0);
  9414.     cin.get();
  9415.     return 0;
  9416. }
  9417.  
  9418. int main() {
  9419.     lua_State *l = luaL_newstate();
  9420.     luaL_openlibs(l);
  9421.     luaL_dofile(l, "man.lua");
  9422.     lua_close(l);
  9423.     return 0;
  9424. }
  9425.  
  9426. int main() {
  9427.     lua_State *l = luaL_newstate();
  9428.     luaL_openlibs(l);
  9429.     luaL_dofile(l, "man.lua");
  9430.     lua_getglobal(l, "pri");
  9431.     lua_pushfstring(l, "lua");
  9432.     lua_pushnumber(l, 5);
  9433.     lua_pcall(l, 2, 0, 0);
  9434.     lua_close(l);
  9435.     return 0;
  9436. }
  9437.  
  9438. Lua
  9439.  
  9440. function pri(ms,x)
  9441. for i=1,x do
  9442. print(ms) end
  9443. end
  9444.  
  9445. это вызывается в lua.
  9446. #include<iostream>
  9447. #include<string>
  9448. #include <stdio.h>
  9449. #include <string>
  9450. #include"lua/lua.hpp"
  9451. using namespace std;
  9452.  
  9453. int main() {
  9454.     lua_State *L = luaL_newstate();
  9455.     luaL_openlibs(L);//открыть все стандартные библиотеки lua.
  9456.     luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  9457.     lua_getglobal(L, "pri");// имя функции, которую вызываем в main.lua.
  9458.     lua_pushnumber(L, 3);// отправляем в стек число.
  9459.     lua_pushnumber(L, 5);
  9460.     lua_pcall(L, 2, 1, 0);// вызов функции, передаем 2 параметра, возвращаем 1.
  9461.     cout << lua_tonumber(L, 1) << endl;// получаем из стека возвращаемое значение из функции.
  9462.     lua_close(L);// закрыть состояние
  9463.  
  9464. return 0;
  9465. }
  9466.  
  9467. lua
  9468.  
  9469. function pri(x,y)
  9470. sum = x+y
  9471. return sum
  9472. end
  9473.  
  9474.  
  9475.  
  9476. struct a {
  9477.     int x = 0;
  9478.     a() : x() { }//конструктор по умолчанию
  9479.     void show() { cout << " x = " << x << endl; }~a() { }//вызов деструктора.
  9480. };
  9481.  
  9482. int create(lua_State* L) {//    Функция создания объекта структуры.
  9483.     void* pointerToAa = lua_newuserdata(L, sizeof(a));/*Эта функция выделяет новый блок памяти с заданным размером,*/
  9484.     new (pointerToAa) a();// Выделить память под польз. данные.
  9485.     luaL_getmetatable(L, "aMetaTable"); /* отправляет в стек метатаблицу значения при заданном приемлемом индексе.*/
  9486.     lua_setmetatable(L, 1);//получает таблицу из стека и уст ее в качестве новой метатаблицы для значения с заданным допустимым индексом.
  9487.     return 1;};
  9488.  
  9489. int destroy(lua_State* L) {// Функция вызывает деструктор для объекта.
  9490.     a* st = (a*)lua_touserdata(L, 1);/* Если значение в данном приемлемом индексе является полными данными пользователя,
  9491.     возвращает адрес его блока. Если значение является легким userdata, возвращает его указатель.В противном случае возвращается NULL.*/
  9492.     st->~a();//вызов метода деструктор.
  9493.     return 0;};
  9494.  
  9495. int show(lua_State* L) {
  9496.     a* st = (a*)lua_touserdata(L, 1);
  9497.     st->show();
  9498.     return 0;
  9499. };
  9500.  
  9501. int index(lua_State* L) {
  9502.     a* st = (a*)lua_touserdata(L, 1);
  9503.     const char* index = lua_tostring(L, 2);
  9504.     if (strcmp(index, "x") == 0) {
  9505.         lua_pushnumber(L, st->x);
  9506.         return 1;
  9507.     }
  9508.     else {lua_getglobal(L, "a");
  9509.         lua_pushstring(L, index);
  9510.         lua_rawget(L, 3);// Аналогично lua_settable, но делает необработанное назначение(т.Е.Без метаметодов).
  9511.         return 1;
  9512.     }
  9513. };
  9514.  
  9515. int newindex(lua_State* L) {
  9516.     a* st = (a*)lua_touserdata(L, -3);
  9517.     const char* index = lua_tostring(L, -2);
  9518.     if (strcmp(index, "x") == 0) {
  9519.         st->x = (int)lua_tonumber(L, -1);   }
  9520.     else { lua_assert(false); }
  9521.     return 0;
  9522. };
  9523.  
  9524. int main() {
  9525.     lua_State* L = luaL_newstate();
  9526.     lua_newtable(L);
  9527.     int stTableIdx = lua_gettop(L);
  9528.     lua_pushvalue(L, stTableIdx);// отправляет копию элемента с заданным допустимым индексом в стек.
  9529.     lua_setglobal(L, "a");// Установить значение глобальной переменной.
  9530.     lua_pushcfunction(L, create);/* отправляет функцию C в стек. функция получает указатель на функцию C и отправляет в стек*/
  9531.     lua_setfield(L, 1, "new");
  9532.     lua_pushcfunction(L, show);
  9533.     lua_setfield(L, 1, "show");
  9534.     luaL_newmetatable(L, "aMetaTable");/*int luaL_newmetatable (lua_State * L, const char * t); */
  9535.     lua_pushstring(L, "__gc");
  9536.     lua_pushcfunction(L, destroy);
  9537.     lua_settable(L, 2);
  9538.  
  9539.     lua_pushstring(L, "__index");
  9540.     lua_pushcfunction(L, index);
  9541.     lua_settable(L, 2);
  9542.  
  9543.     lua_pushstring(L, "__newindex");
  9544.     lua_pushcfunction(L, newindex);
  9545.     lua_settable(L, 2);
  9546.  
  9547.     int x = luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  9548.  
  9549.     if (x == LUA_OK) {  lua_close(L);// если поллучилось открыть файл.
  9550.         cin.get();  }//ожидает ввода символа программа завершается.
  9551.  
  9552.     else {
  9553.         cout << "Error: " << lua_tostring(L, -1) << endl;
  9554.         lua_close(L);// закрыть состояние
  9555.         cin.get();//ожидает ввода символа программа завершается.
  9556.         return 0;
  9557.     }
  9558. }
  9559.  
  9560.  
  9561.  
  9562.  
  9563.  
  9564.  
  9565.  
  9566. struct vec
  9567. {
  9568.     static int vector(lua_State* L)
  9569.     {
  9570.         lua_newtable(L); //Создает новую пустую таблицу и помещает ее в стек.Это эквивалентно lua_createtable(L, 0, 0
  9571.         lua_pushstring(L, "x");
  9572.         lua_pushnumber(L, 0);
  9573.         lua_settable(L, 1);// уст ключ и значение из стек
  9574.  
  9575.         lua_pushstring(L, "y");
  9576.         lua_pushnumber(L, 0);
  9577.         lua_settable(L, 1);
  9578.  
  9579.         luaL_getmetatable(L, "VectorMetaTable");// получает в стек метатаблицу значения с заданным допустимым индексом.
  9580.         //Если индекс недопустим или значение не имеет метатаблицы, функция возвращает 0 и ничего не помещает в стек.
  9581.         lua_setmetatable(L, -2);// получает таблицу из стека и устанавливает ее в качестве новой метатаблицы для значения
  9582.         //с заданным допустимым индексом.
  9583.  
  9584.         return 1;
  9585.     }
  9586.  
  9587.     static int __add(lua_State* L)
  9588.     {
  9589.     //  printf("__add was called\n");
  9590.         lua_assert(lua_istable(L, -2));     // left table
  9591.         lua_assert(lua_istable(L, -1));     // right table
  9592.  
  9593.         lua_pushstring(L, "x");
  9594.         lua_gettable(L, 1);
  9595.         lua_Number xfirst = lua_tonumber(L, -1);// получить x из первой таблицы.
  9596.         lua_pop(L, 1);
  9597.  
  9598.         lua_pushstring(L, "x");
  9599.         lua_gettable(L, 2);
  9600.         lua_Number xsecond = lua_tonumber(L, -1);// получить x из второй таблицы.
  9601.         lua_pop(L, 1);
  9602.  
  9603.         lua_Number sum = xfirst + xfirst;// сложить значения x двух таблиц.
  9604.         vec::vector(L);
  9605.         lua_pushstring(L, "x");
  9606.         lua_pushnumber(L, sum);// сумму отправить в стек
  9607.         lua_rawset(L, 3); //Аналогичен lua_settable, но выполняет необработанное назначение(т.Е.Без метаметодов).
  9608.         return 1;
  9609.     }
  9610. };
  9611.  
  9612. int main() {
  9613.  
  9614.     lua_State* L = luaL_newstate();
  9615.  
  9616.     lua_pushcfunction(L, vec::vector);
  9617.     lua_setglobal(L, "vector");// уст таблицу
  9618.  
  9619.     luaL_newmetatable(L, "VectorMetaTable");// уста новую метатаблицу.
  9620.     lua_pushstring(L, "__add");
  9621.     lua_pushcfunction(L, vec::__add);
  9622.     lua_settable(L, -3);
  9623.  
  9624.     int x = luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  9625.  
  9626.     if (x == LUA_OK){   lua_getglobal(L, "result");
  9627.         lua_Number result = lua_tonumber(L, -1);
  9628.         printf("result = %d\n", (int)result);
  9629.         lua_close(L);
  9630.         cin.get();//ожидает ввода символа программа завершается.
  9631.     }
  9632.     else
  9633.     {
  9634.         printf("Error: %s\n", lua_tostring(L, -1));
  9635.         lua_close(L);// закрыть состояние
  9636.         return 0;   }}
  9637. lua
  9638.  
  9639.     v1 = vector()   -- v1 is a table
  9640.         v2 = vector()     -- v2 is a table
  9641.         v1.x = 4
  9642.         v2.x = 42
  9643.         v3 = v1 + v2
  9644.         result = v3.x
  9645.  
  9646.  
  9647. static int __mul(lua_State* L)  {
  9648.         //  printf("__add was called\n");
  9649.         lua_assert(lua_istable(L, -2));     // left table
  9650.         lua_assert(lua_istable(L, -1));     // right table
  9651.  
  9652.         lua_pushstring(L, "x");
  9653.         lua_gettable(L, 1);
  9654.         lua_Number xfirst = lua_tonumber(L, -1);// получить x из первой таблицы.
  9655.         lua_pop(L, 1);
  9656.  
  9657.         lua_pushstring(L, "x");
  9658.         lua_gettable(L, 2);
  9659.         lua_Number xsecond = lua_tonumber(L, -1);// получить x из второй таблицы.
  9660.         lua_pop(L, 1);
  9661.  
  9662.         lua_Number mul = xfirst * xfirst;// умножить значения x двух таблиц.
  9663.         vec::vector(L);
  9664.         lua_pushstring(L, "x");
  9665.         lua_pushnumber(L, mul);// произведение отправить в стек
  9666.         lua_rawset(L, 3); //Аналогичен lua_settable, но выполняет необработанное назначение(т.Е.Без метаметодов).
  9667.         return 1;   }
  9668. };
  9669.  
  9670. int main() {
  9671.  
  9672.     lua_State* L = luaL_newstate();
  9673.  
  9674.     lua_pushcfunction(L, vec::vector);
  9675.     lua_setglobal(L, "vector");// уст таблицу
  9676.     lua_pushstring(L, "__mul");
  9677.     lua_pushcfunction(L, vec::__mul);
  9678.     lua_settable(L, -2);
  9679.     int x = luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  9680.  
  9681.  
  9682. static int numberOfSpritesExisting = 0;
  9683.  
  9684. struct Sprite
  9685. {
  9686.     int x;
  9687.     int y;
  9688.  
  9689.     Sprite() : x(0), y(0)
  9690.     {
  9691.         numberOfSpritesExisting++;
  9692.     }
  9693.  
  9694.     ~Sprite()
  9695.     {
  9696.         numberOfSpritesExisting--;
  9697.     }
  9698.  
  9699.     void Move(int velX, int velY)
  9700.     {
  9701.         x += velX;
  9702.         y += velY;
  9703.     }
  9704.  
  9705.     void Draw()
  9706.     {
  9707.         printf("sprite(%p): x = %d, y = %d\n", this, x, y);
  9708.     }
  9709. };
  9710.  
  9711. auto CreateSprite = [](lua_State* L) -> int
  9712. {
  9713.     void* pointerToASprite = lua_newuserdata(L, sizeof(Sprite));
  9714.     new (pointerToASprite) Sprite();
  9715.     luaL_getmetatable(L, "SpriteMetaTable");
  9716.     lua_assert(lua_istable(L, -1));
  9717.     lua_setmetatable(L, -2);
  9718.     return 1;
  9719. };
  9720.  
  9721. auto DestroySprite = [](lua_State* L) -> int
  9722. {
  9723.     Sprite* sprite = (Sprite*)lua_touserdata(L, -1);
  9724.     sprite->~Sprite();
  9725.     return 0;
  9726. };
  9727.  
  9728. auto MoveSprite = [](lua_State* L) -> int
  9729. {
  9730.     Sprite* sprite = (Sprite*)lua_touserdata(L, -3);
  9731.     lua_Number velX = lua_tonumber(L, -2);
  9732.     lua_Number velY = lua_tonumber(L, -1);
  9733.     sprite->Move((int)velX, (int)velY);
  9734.     return 0;
  9735. };
  9736.  
  9737. auto DrawSprite = [](lua_State* L) -> int
  9738. {
  9739.     Sprite* sprite = (Sprite*)lua_touserdata(L, -1);
  9740.     sprite->Draw();
  9741.     return 0;
  9742. };
  9743.  
  9744. int main() {
  9745.  
  9746.     lua_State* L = luaL_newstate();
  9747.     luaL_newmetatable(L, "SpriteMetaTable");
  9748.     lua_pushstring(L, "__gc");
  9749.     lua_pushcfunction(L, DestroySprite);
  9750.     lua_settable(L, -3);
  9751.  
  9752.     lua_pushcfunction(L, CreateSprite);
  9753.     lua_setglobal(L, "CreateSprite");
  9754.     lua_pushcfunction(L, MoveSprite);
  9755.     lua_setglobal(L, "MoveSprite");
  9756.     lua_pushcfunction(L, DrawSprite);
  9757.     lua_setglobal(L, "DrawSprite");
  9758.  
  9759.     int x = luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  9760.  
  9761.     if (x == LUA_OK){  
  9762.  
  9763.         lua_assert(numberOfSpritesExisting == 0);
  9764.  
  9765.         lua_close(L);
  9766.         cin.get();//ожидает ввода символа программа завершается.
  9767.     }
  9768.     else
  9769.     {
  9770.         printf("Error: %s\n", lua_tostring(L, -1));
  9771.         lua_close(L);// закрыть состояние
  9772.         return 0;   }}
  9773.  
  9774. lua
  9775.         sprite = CreateSprite()
  9776.         MoveSprite( sprite, 5, 7 )
  9777.         DrawSprite( sprite )
  9778.         MoveSprite( sprite, 1, 2 )
  9779.         DrawSprite( sprite )
  9780.         sprite2 = CreateSprite()
  9781.         MoveSprite( sprite2, 3, 3 )
  9782.         DrawSprite( sprite2 )
  9783.  
  9784.  
  9785.  Object Oriented Access
  9786.  
  9787. static int numberOfSpritesExisting = 0;
  9788.  
  9789. struct Sprite
  9790. {
  9791.     int x;
  9792.     int y;
  9793.  
  9794.     Sprite() : x(0), y(0)
  9795.     {
  9796.         numberOfSpritesExisting++;
  9797.     }
  9798.  
  9799.     ~Sprite()
  9800.     {
  9801.         numberOfSpritesExisting--;
  9802.     }
  9803.  
  9804.     void Move(int velX, int velY)
  9805.     {
  9806.         x += velX;
  9807.         y += velY;
  9808.     }
  9809.  
  9810.     void Draw()
  9811.     {
  9812.         printf("sprite(%p): x = %d, y = %d\n", this, x, y);
  9813.     }
  9814. };
  9815.  
  9816. auto CreateSprite = [](lua_State* L) -> int
  9817. {
  9818.     void* pointerToASprite = lua_newuserdata(L, sizeof(Sprite));
  9819.     new (pointerToASprite) Sprite();
  9820.     luaL_getmetatable(L, "SpriteMetaTable");
  9821.     lua_assert(lua_istable(L, -1));
  9822.     lua_setmetatable(L, -2);
  9823.     return 1;
  9824. };
  9825.  
  9826. auto DestroySprite = [](lua_State* L) -> int
  9827. {
  9828.     Sprite* sprite = (Sprite*)lua_touserdata(L, -1);
  9829.     sprite->~Sprite();
  9830.     return 0;
  9831. };
  9832.  
  9833. auto MoveSprite = [](lua_State* L) -> int
  9834. {
  9835.     Sprite* sprite = (Sprite*)lua_touserdata(L, -3);
  9836.     lua_Number velX = lua_tonumber(L, -2);
  9837.     lua_Number velY = lua_tonumber(L, -1);
  9838.     sprite->Move((int)velX, (int)velY);
  9839.     return 0;
  9840. };
  9841.  
  9842. auto DrawSprite = [](lua_State* L) -> int
  9843. {
  9844.     Sprite* sprite = (Sprite*)lua_touserdata(L, -1);
  9845.     sprite->Draw();
  9846.     return 0;
  9847. };
  9848.  
  9849.  
  9850. int main() {
  9851.  
  9852.     lua_State* L = luaL_newstate();
  9853.     lua_newtable(L);
  9854.     int spriteTableIdx = lua_gettop(L);
  9855.     lua_pushvalue(L, spriteTableIdx);
  9856.     lua_setglobal(L, "Sprite");
  9857.  
  9858.     lua_pushcfunction(L, CreateSprite);
  9859.     lua_setfield(L, -2, "new");
  9860.     lua_pushcfunction(L, MoveSprite);
  9861.     lua_setfield(L, -2, "Move");
  9862.     lua_pushcfunction(L, DrawSprite);
  9863.     lua_setfield(L, -2, "Draw");
  9864.  
  9865.     luaL_newmetatable(L, "SpriteMetaTable");
  9866.     lua_pushstring(L, "__gc");
  9867.     lua_pushcfunction(L, DestroySprite);
  9868.     lua_settable(L, -3);
  9869.  
  9870.     lua_pushstring(L, "__index");
  9871.     lua_pushvalue(L, spriteTableIdx);
  9872.     lua_settable(L, -3);
  9873.  
  9874.  
  9875.     int x = luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  9876.  
  9877.     if (x == LUA_OK){  
  9878.  
  9879.         lua_assert(numberOfSpritesExisting == 0);
  9880.  
  9881.         lua_close(L);
  9882.         cin.get();//ожидает ввода символа программа завершается.
  9883.     }
  9884.     else
  9885.     {
  9886.         printf("Error: %s\n", lua_tostring(L, -1));
  9887.         lua_close(L);// закрыть состояние
  9888.         return 0;   }}
  9889.  
  9890.  
  9891. lua
  9892.  
  9893. sprite = Sprite.new()
  9894.         sprite:Move( 5, 7 )     -- Sprite.Move( sprite, 5, 7 )
  9895.         sprite:Draw()
  9896.         sprite:Move( 1, 2 )
  9897.         sprite:Draw()
  9898.         sprite2 = Sprite.new()
  9899.         sprite2:Move( 3, 3 )
  9900.         sprite2:Draw()
  9901.         -- sprite   -> sprite is a userdatum
  9902.         --      has a metatable called SpriteMetaTable
  9903.         --          dont have Move(), use the __index metamethod
  9904.         --          __index metamethod is a table which is Sprite
  9905.         --          Sprite has a field called Move(), invoke that
  9906.         --          Move() is a c function
  9907.         --          invoke, pass the userdatum as the first parameter.
  9908.  
  9909.  
  9910. using namespace std;
  9911.  
  9912. class MyObject {
  9913. private:
  9914.     double x;
  9915. public:
  9916.     MyObject(double x) : x(x) {}
  9917.     void set(double x) { this->x = x; }
  9918.     double get() const { return this->x; }
  9919. };
  9920. // Create & return MyObject instance to Lua
  9921. static int myobject_new(lua_State* L) {
  9922.     double x = luaL_checknumber(L, 1);
  9923.     *reinterpret_cast<MyObject**>(lua_newuserdata(L, sizeof(MyObject*))) = new MyObject(x);
  9924.     luaL_setmetatable(L, "MyObject" );
  9925.     return 1;
  9926. }
  9927.  
  9928. // Free MyObject instance by Lua garbage collection
  9929. static int myobject_delete(lua_State* L) {
  9930.     delete *reinterpret_cast<MyObject**>(lua_touserdata(L, 1));
  9931.     return 0;
  9932. }
  9933.  
  9934. // MyObject member functions in Lua
  9935. static int myobject_set(lua_State* L) {
  9936.     (*reinterpret_cast<MyObject**>(luaL_checkudata(L, 1, "MyObject")))->set(luaL_checknumber(L, 2));
  9937.     return 0;
  9938. }
  9939. static int myobject_get(lua_State* L) {
  9940.     lua_pushnumber(L, (*reinterpret_cast<MyObject**>(luaL_checkudata(L, 1, "MyObject")))->get());
  9941.     return 1;
  9942. }
  9943.  
  9944. int main(int argc, char** argv) {
  9945.         lua_State* L = luaL_newstate();
  9946.         luaL_openlibs(L);
  9947.         lua_register(L, "MyObject", myobject_new);
  9948.         luaL_newmetatable(L, "MyObject");
  9949.         lua_pushcfunction(L, myobject_delete); lua_setfield(L, -2, "__gc");
  9950.         lua_pushvalue(L, -1); lua_setfield(L, -2, "__index");
  9951.         lua_pushcfunction(L, myobject_set); lua_setfield(L, -2, "set");
  9952.         lua_pushcfunction(L, myobject_get); lua_setfield(L, -2, "get");
  9953.         lua_pop(L, 1);
  9954.         luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  9955.         lua_pcall(L, 0, 0, 0);// вызов функции в lua файле. 1 параметр кол-во передаваемых, кол-во возвращаемых, обработчик ошибок.
  9956.         lua_close(L);// закрыть состояние
  9957.         cin.get();//ожидает ввода символа программа завершается.
  9958.         return 0;
  9959.  
  9960. }
  9961.  
  9962. Lua
  9963.  
  9964. local obj = MyObject(42)
  9965. print(obj:get())    -- 42
  9966. obj:set(-1.5)
  9967. print(obj:get())    -- -1.5
  9968.  
  9969.  
  9970.  
  9971.  
  9972.  
  9973.  
  9974.  
  9975. ("---- Reading Object Properties -----\
  9976.  
  9977. static int numberOfSpritesExisting = 0;
  9978.  
  9979. struct Sprite
  9980. {
  9981.     int x;
  9982.     int y;
  9983.  
  9984.     Sprite() : x(0), y(0)
  9985.     {
  9986.         numberOfSpritesExisting++;
  9987.     }
  9988.  
  9989.     ~Sprite()
  9990.     {
  9991.         numberOfSpritesExisting--;
  9992.     }
  9993.  
  9994.     void Move(int velX, int velY)
  9995.     {
  9996.         x += velX;
  9997.         y += velY;
  9998.     }
  9999.  
  10000.     void Draw()
  10001.     {
  10002.         printf("sprite(%p): x = %d, y = %d\n", this, x, y);
  10003.     }
  10004. };
  10005.  
  10006. auto CreateSprite = [](lua_State* L) -> int
  10007. {
  10008.     void* pointerToASprite = lua_newuserdata(L, sizeof(Sprite));
  10009.     new (pointerToASprite) Sprite();
  10010.     luaL_getmetatable(L, "SpriteMetaTable");
  10011.     lua_assert(lua_istable(L, -1));
  10012.     lua_setmetatable(L, -2);
  10013.     return 1;
  10014. };
  10015.  
  10016. auto DestroySprite = [](lua_State* L) -> int
  10017. {
  10018.     Sprite* sprite = (Sprite*)lua_touserdata(L, -1);
  10019.     sprite->~Sprite();
  10020.     return 0;
  10021. };
  10022.  
  10023. auto MoveSprite = [](lua_State* L) -> int
  10024. {
  10025.     Sprite* sprite = (Sprite*)lua_touserdata(L, -3);
  10026.     lua_Number velX = lua_tonumber(L, -2);
  10027.     lua_Number velY = lua_tonumber(L, -1);
  10028.     sprite->Move((int)velX, (int)velY);
  10029.     return 0;
  10030. };
  10031.  
  10032. auto DrawSprite = [](lua_State* L) -> int
  10033. {
  10034.     Sprite* sprite = (Sprite*)lua_touserdata(L, -1);
  10035.     sprite->Draw();
  10036.     return 0;
  10037. };
  10038.  
  10039. auto SpriteIndex = [](lua_State* L) -> int
  10040. {
  10041.     lua_assert(lua_isuserdata(L, -2));
  10042.     lua_assert(lua_isstring(L, -1));
  10043.  
  10044.     Sprite* sprite = (Sprite*)lua_touserdata(L, -2);
  10045.     const char* index = lua_tostring(L, -1);
  10046.     if (strcmp(index, "x") == 0)
  10047.     {
  10048.         lua_pushnumber(L, sprite->x);
  10049.         return 1;
  10050.     }
  10051.     else if (strcmp(index, "y") == 0)
  10052.     {
  10053.         lua_pushnumber(L, sprite->y);
  10054.         return 1;
  10055.     }
  10056.     else
  10057.     {
  10058.         lua_getglobal(L, "Sprite");
  10059.         lua_pushstring(L, index);
  10060.         lua_rawget(L, -2);
  10061.         return 1;
  10062.     }
  10063. };
  10064.  
  10065.  
  10066.  
  10067. int main() {
  10068.  
  10069.     lua_State* L = luaL_newstate();
  10070.  
  10071.     lua_newtable(L);
  10072.     int spriteTableIdx = lua_gettop(L);
  10073.     lua_pushvalue(L, spriteTableIdx);
  10074.     lua_setglobal(L, "Sprite");
  10075.  
  10076.     lua_pushcfunction(L, CreateSprite);
  10077.     lua_setfield(L, -2, "new");
  10078.     lua_pushcfunction(L, MoveSprite);
  10079.     lua_setfield(L, -2, "Move");
  10080.     lua_pushcfunction(L, DrawSprite);
  10081.     lua_setfield(L, -2, "Draw");
  10082.  
  10083.     luaL_newmetatable(L, "SpriteMetaTable");
  10084.     lua_pushstring(L, "__gc");
  10085.     lua_pushcfunction(L, DestroySprite);
  10086.     lua_settable(L, -3);
  10087.  
  10088.     lua_pushstring(L, "__index");
  10089.     lua_pushcfunction(L, SpriteIndex);
  10090.     lua_settable(L, -3);
  10091.  
  10092.  
  10093.  
  10094.     int x = luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  10095.  
  10096.     if (x == LUA_OK){  
  10097.         lua_getglobal(L, "temp_x");
  10098.         lua_Number temp_x = lua_tonumber(L, -1);
  10099.         lua_assert(temp_x == 6);
  10100.  
  10101.         lua_close(L);
  10102.  
  10103.         lua_assert(numberOfSpritesExisting == 0);
  10104.  
  10105.         lua_close(L);
  10106.         cin.get();//ожидает ввода символа программа завершается.
  10107.     }
  10108.     else
  10109.     {
  10110.         printf("Error: %s\n", lua_tostring(L, -1));
  10111.         lua_close(L);// закрыть состояние
  10112.         return 0;   }}
  10113.  
  10114. lua
  10115.         sprite = Sprite.new()
  10116.         sprite:Move( 6, 7 )     -- Sprite.Move( sprite, 6, 7 )
  10117.         sprite:Draw()
  10118.         temp_x = sprite.x
  10119.  
  10120. Writing Object Properties
  10121.  
  10122.  
  10123. static int numberOfSpritesExisting = 0;
  10124.  
  10125. struct Sprite
  10126. {
  10127.     int x;
  10128.     int y;
  10129.  
  10130.     Sprite() : x(0), y(0)
  10131.     {
  10132.         numberOfSpritesExisting++;
  10133.     }
  10134.  
  10135.     ~Sprite()
  10136.     {
  10137.         numberOfSpritesExisting--;
  10138.     }
  10139.  
  10140.     void Move(int velX, int velY)
  10141.     {
  10142.         x += velX;
  10143.         y += velY;
  10144.     }
  10145.  
  10146.     void Draw()
  10147.     {
  10148.         printf("sprite(%p): x = %d, y = %d\n", this, x, y);
  10149.     }
  10150. };
  10151.  
  10152. auto CreateSprite = [](lua_State* L) -> int
  10153. {
  10154.     void* pointerToASprite = lua_newuserdata(L, sizeof(Sprite));
  10155.     new (pointerToASprite) Sprite();
  10156.     luaL_getmetatable(L, "SpriteMetaTable");
  10157.     lua_assert(lua_istable(L, -1));
  10158.     lua_setmetatable(L, -2);
  10159.     return 1;
  10160. };
  10161.  
  10162. auto DestroySprite = [](lua_State* L) -> int
  10163. {
  10164.     Sprite* sprite = (Sprite*)lua_touserdata(L, -1);
  10165.     sprite->~Sprite();
  10166.     return 0;
  10167. };
  10168.  
  10169. auto MoveSprite = [](lua_State* L) -> int
  10170. {
  10171.     Sprite* sprite = (Sprite*)lua_touserdata(L, -3);
  10172.     lua_Number velX = lua_tonumber(L, -2);
  10173.     lua_Number velY = lua_tonumber(L, -1);
  10174.     sprite->Move((int)velX, (int)velY);
  10175.     return 0;
  10176. };
  10177.  
  10178. auto DrawSprite = [](lua_State* L) -> int
  10179. {
  10180.     Sprite* sprite = (Sprite*)lua_touserdata(L, -1);
  10181.     sprite->Draw();
  10182.     return 0;
  10183. };
  10184.  
  10185. auto SpriteIndex = [](lua_State* L) -> int
  10186. {
  10187.     lua_assert(lua_isuserdata(L, -2));
  10188.     lua_assert(lua_isstring(L, -1));
  10189.  
  10190.     Sprite* sprite = (Sprite*)lua_touserdata(L, -2);
  10191.     const char* index = lua_tostring(L, -1);
  10192.     if (strcmp(index, "x") == 0)
  10193.     {
  10194.         lua_pushnumber(L, sprite->x);
  10195.         return 1;
  10196.     }
  10197.     else if (strcmp(index, "y") == 0)
  10198.     {
  10199.         lua_pushnumber(L, sprite->y);
  10200.         return 1;
  10201.     }
  10202.     else
  10203.     {
  10204.         lua_getglobal(L, "Sprite");
  10205.         lua_pushstring(L, index);
  10206.         lua_rawget(L, -2);
  10207.         return 1;
  10208.     }
  10209. };
  10210.  
  10211. auto SpriteNewIndex = [](lua_State* L) -> int
  10212. {
  10213.     lua_assert(lua_isuserdata(L, -3));
  10214.     lua_assert(lua_isstring(L, -2));
  10215.     // -1 - value we want to set
  10216.  
  10217.     Sprite* sprite = (Sprite*)lua_touserdata(L, -3);
  10218.     const char* index = lua_tostring(L, -2);
  10219.     if (strcmp(index, "x") == 0)
  10220.     {
  10221.         sprite->x = (int)lua_tonumber(L, -1);
  10222.     }
  10223.     else if (strcmp(index, "y") == 0)
  10224.     {
  10225.         sprite->y = (int)lua_tonumber(L, -1);
  10226.     }
  10227.     else
  10228.     {
  10229.         lua_assert(false);  //don't want you to write to my native object!!
  10230.     }
  10231.  
  10232.     return 0;
  10233. };
  10234.  
  10235. int main() {
  10236.     lua_State* L = luaL_newstate();
  10237.  
  10238.     lua_newtable(L);
  10239.     int spriteTableIdx = lua_gettop(L);
  10240.     lua_pushvalue(L, spriteTableIdx);
  10241.     lua_setglobal(L, "Sprite");
  10242.  
  10243.     lua_pushcfunction(L, CreateSprite);
  10244.     lua_setfield(L, -2, "new");
  10245.     lua_pushcfunction(L, MoveSprite);
  10246.     lua_setfield(L, -2, "Move");
  10247.     lua_pushcfunction(L, DrawSprite);
  10248.     lua_setfield(L, -2, "Draw");
  10249.  
  10250.     luaL_newmetatable(L, "SpriteMetaTable");
  10251.     lua_pushstring(L, "__gc");
  10252.     lua_pushcfunction(L, DestroySprite);
  10253.     lua_settable(L, -3);
  10254.  
  10255.     lua_pushstring(L, "__index");
  10256.     lua_pushcfunction(L, SpriteIndex);
  10257.     lua_settable(L, -3);
  10258.  
  10259.     lua_pushstring(L, "__newindex");
  10260.     lua_pushcfunction(L, SpriteNewIndex);
  10261.     lua_settable(L, -3);
  10262.  
  10263.     int x = luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  10264.  
  10265.     if (x == LUA_OK){  
  10266.         lua_getglobal(L, "temp_x");
  10267.         lua_Number temp_x = lua_tonumber(L, -1);
  10268.         lua_assert(temp_x == 6);
  10269.         lua_assert(numberOfSpritesExisting == 0);
  10270.  
  10271.         lua_close(L);
  10272.         cin.get();//ожидает ввода символа программа завершается.
  10273.     }
  10274.     else
  10275.     {
  10276.         printf("Error: %s\n", lua_tostring(L, -1));
  10277.         lua_close(L);// закрыть состояние
  10278.         return 0;   }}
  10279.  
  10280. lua
  10281.  
  10282. sprite = Sprite.new()
  10283.     sprite:Move( 6, 7 )     -- Sprite.Move( sprite, 6, 7 )
  10284.     sprite:Draw()
  10285.     sprite.y = 10
  10286.     temp_x = sprite.x
  10287.     sprite:Draw()
  10288.  
  10289. user values
  10290.  
  10291. static int numberOfSpritesExisting = 0;
  10292.  
  10293. struct Sprite
  10294. {
  10295.     int x;
  10296.     int y;
  10297.  
  10298.     Sprite() : x(0), y(0)
  10299.     {
  10300.         numberOfSpritesExisting++;
  10301.     }
  10302.  
  10303.     ~Sprite()
  10304.     {
  10305.         numberOfSpritesExisting--;
  10306.     }
  10307.  
  10308.     void Move(int velX, int velY)
  10309.     {
  10310.         x += velX;
  10311.         y += velY;
  10312.     }
  10313.  
  10314.     void Draw()
  10315.     {
  10316.         printf("sprite(%p): x = %d, y = %d\n", this, x, y);
  10317.     }
  10318. };
  10319.  
  10320. auto CreateSprite = [](lua_State* L) -> int
  10321. {
  10322.     void* pointerToASprite = lua_newuserdata(L, sizeof(Sprite));
  10323.     new (pointerToASprite) Sprite();
  10324.     luaL_getmetatable(L, "SpriteMetaTable");
  10325.     lua_assert(lua_istable(L, -1));
  10326.     lua_setmetatable(L, -2);
  10327.     return 1;
  10328. };
  10329.  
  10330. auto DestroySprite = [](lua_State* L) -> int
  10331. {
  10332.     Sprite* sprite = (Sprite*)lua_touserdata(L, -1);
  10333.     sprite->~Sprite();
  10334.     return 0;
  10335. };
  10336.  
  10337. auto MoveSprite = [](lua_State* L) -> int
  10338. {
  10339.     Sprite* sprite = (Sprite*)lua_touserdata(L, -3);
  10340.     lua_Number velX = lua_tonumber(L, -2);
  10341.     lua_Number velY = lua_tonumber(L, -1);
  10342.     sprite->Move((int)velX, (int)velY);
  10343.     return 0;
  10344. };
  10345.  
  10346. auto DrawSprite = [](lua_State* L) -> int
  10347. {
  10348.     Sprite* sprite = (Sprite*)lua_touserdata(L, -1);
  10349.     sprite->Draw();
  10350.     return 0;
  10351. };
  10352.  
  10353. auto SpriteIndex = [](lua_State* L) -> int
  10354. {
  10355.     lua_assert(lua_isuserdata(L, -2));
  10356.     lua_assert(lua_isstring(L, -1));
  10357.  
  10358.     Sprite* sprite = (Sprite*)lua_touserdata(L, -2);
  10359.     const char* index = lua_tostring(L, -1);
  10360.     if (strcmp(index, "x") == 0)
  10361.     {
  10362.         lua_pushnumber(L, sprite->x);
  10363.         return 1;
  10364.     }
  10365.     else if (strcmp(index, "y") == 0)
  10366.     {
  10367.         lua_pushnumber(L, sprite->y);
  10368.         return 1;
  10369.     }
  10370.     else
  10371.     {
  10372.         lua_getglobal(L, "Sprite");
  10373.         lua_pushstring(L, index);
  10374.         lua_rawget(L, -2);
  10375.         return 1;
  10376.     }
  10377. };
  10378.  
  10379. auto SpriteNewIndex = [](lua_State* L) -> int
  10380. {
  10381.     lua_assert(lua_isuserdata(L, -3));
  10382.     lua_assert(lua_isstring(L, -2));
  10383.     // -1 - value we want to set
  10384.  
  10385.     Sprite* sprite = (Sprite*)lua_touserdata(L, -3);
  10386.     const char* index = lua_tostring(L, -2);
  10387.     if (strcmp(index, "x") == 0)
  10388.     {
  10389.         sprite->x = (int)lua_tonumber(L, -1);
  10390.     }
  10391.     else if (strcmp(index, "y") == 0)
  10392.     {
  10393.         sprite->y = (int)lua_tonumber(L, -1);
  10394.     }
  10395.     else
  10396.     {
  10397.         lua_assert(false);  //don't want you to write to my native object!!
  10398.     }
  10399.  
  10400.     return 0;
  10401. };
  10402.  
  10403. int main() {
  10404.     lua_State* L = luaL_newstate();
  10405.  
  10406.     lua_newtable(L);
  10407.     int spriteTableIdx = lua_gettop(L);
  10408.     lua_pushvalue(L, spriteTableIdx);
  10409.     lua_setglobal(L, "Sprite");
  10410.  
  10411.     lua_pushcfunction(L, CreateSprite);
  10412.     lua_setfield(L, -2, "new");
  10413.     lua_pushcfunction(L, MoveSprite);
  10414.     lua_setfield(L, -2, "Move");
  10415.     lua_pushcfunction(L, DrawSprite);
  10416.     lua_setfield(L, -2, "Draw");
  10417.  
  10418.     luaL_newmetatable(L, "SpriteMetaTable");
  10419.     lua_pushstring(L, "__gc");
  10420.     lua_pushcfunction(L, DestroySprite);
  10421.     lua_settable(L, -3);
  10422.  
  10423.     lua_pushstring(L, "__index");
  10424.     lua_pushcfunction(L, SpriteIndex);
  10425.     lua_settable(L, -3);
  10426.  
  10427.     lua_pushstring(L, "__newindex");
  10428.     lua_pushcfunction(L, SpriteNewIndex);
  10429.     lua_settable(L, -3);
  10430.  
  10431.     int x = luaL_dofile(L, "main.lua");// Загружает и запускает заданный файл. файл в которым все происходит.
  10432.  
  10433.     if (x == LUA_OK){  
  10434.         lua_getglobal(L, "temp_x");
  10435.         lua_Number temp_x = lua_tonumber(L, -1);
  10436.         lua_assert(temp_x == 6);
  10437.         lua_assert(numberOfSpritesExisting == 0);
  10438.  
  10439.         lua_close(L);
  10440.         cin.get();//ожидает ввода символа программа завершается.
  10441.     }
  10442.     else
  10443.     {
  10444.         printf("Error: %s\n", lua_tostring(L, -1));
  10445.         lua_close(L);// закрыть состояние
  10446.         return 0;   }}
  10447.  
  10448. lua
  10449. sprite = Sprite.new()
  10450.     sprite:Move( 6, 7 )     -- Sprite.Move( sprite, 6, 7 )
  10451.     sprite:Draw()
  10452.     sprite.y = 10
  10453.     temp_x = sprite.x
  10454.     sprite:Draw()
  10455.  
  10456.  
  10457. const char *c_function = "local a=5 local b=10 local c=a+b return c";
  10458.  
  10459. int main(int argc, char *argv[]) {
  10460.  
  10461.     lua_State *L = luaL_newstate();
  10462.     luaL_openlibs(L);//открыть все стандартные библиотеки lua.
  10463.     luaL_dostring(L, c_function);
  10464.     int r = luaL_checkinteger(L, -1);
  10465.     printf("\nResult = %d", r);
  10466.  
  10467.  
  10468.  
  10469.  
  10470. void writelog(const char* x) {
  10471.    string path = "lualoader\\log.txt";
  10472.    fstream f1; {f1.open(path, fstream::in | fstream::out | fstream::app);
  10473.    f1 << x;
  10474.    time_t rawtime; struct tm * timeinfo;
  10475.    char buffer[80]; time(&rawtime);
  10476.    timeinfo = localtime(&rawtime);
  10477.  
  10478.    strftime(buffer, sizeof(buffer), " %I:%M:%S %d-%m-%Y", timeinfo);
  10479.    string er2(buffer);
  10480.    f1<<er2 << "\n"; }
  10481.    f1.close();
  10482. };
  10483.  
  10484. void search(lua_State *L) {
  10485.    for (auto const& de : fs::recursive_directory_iterator{ fs::current_path() / "lualoader" })  // папка для поиска
  10486.    { if (de.path().extension() == ".lua" || de.path().extension() == ".LUA")
  10487.        {   string res = de.path().string();// имя в файла в строку  
  10488.            char *file = new char[res.size() + 1];
  10489.            copy(res.begin(), res.end(), file);
  10490.            file[res.size()] = '\0';// преобразуем строку в char.
  10491.            int status = luaL_loadfile(L, file);// проверка есть ли ошибки.
  10492.            try {
  10493.                if (status == 0) {// если нет ошибки в файле.
  10494.                    luaL_dofile(L, file);// запуск файла.
  10495.                    string s1(file);
  10496.                    string load = "loaded ";
  10497.                    string er0 = load + s1;
  10498.                    delete[] file;
  10499.                    char * x = new char[er0.size() + 1];
  10500.                    copy(er0.begin(), er0.end(), x);
  10501.                    x[er0.size()] = '\0';
  10502.                    writelog(x);
  10503.                    delete[] x; }//.
  10504.                else {delete[] file;
  10505.                    string er1 = lua_tostring(L, -1);
  10506.                    string er = "could not load ";
  10507.                    string er0 = er + er1;
  10508.                    char * x = new char[er0.size() + 1];
  10509.                    copy(er0.begin(), er0.end(), x);
  10510.                    x[er0.size()] = '\0';
  10511.                    throw x;delete[] x; }           }
  10512.            catch (const char* x) {
  10513.                writelog(x);}}}
  10514. };
  10515.  
  10516.  
  10517. int main(int argc, char *argv[]) {
  10518.    lua_State *L = luaL_newstate();
  10519.    luaL_openlibs(L);//открыть все стандартные библиотеки lua.
  10520.    search(L);
  10521.    lua_close(L);// закрыть состояние
  10522. //  cin.get();//ожидает ввода символа программа завершается.
  10523.    return 0;
  10524.  
  10525. void checklua(lua_State *L, char *file) {
  10526.     int status = luaL_loadfile(L, file);// проверка есть ли ошибки.
  10527.         try {
  10528.         if (status == 0) {// если нет ошибки в файле.
  10529.             luaL_dofile(L, file);// запуск файла, в которым все происходит.
  10530.             string s1(file);
  10531.             string load = "loaded ";
  10532.             string er0 = load + s1;
  10533.                 char * x = new char[er0.size() + 1];
  10534.                     copy(er0.begin(), er0.end(), x);
  10535.                     x[er0.size()] = '\0';
  10536.                     writelog(x);}//.
  10537.                 else {
  10538.                     string er1 = lua_tostring(L, -1);
  10539.                     string er = "could not load ";
  10540.                     string er0 = er + er1;
  10541.                     char * x = new char[er0.size() + 1];
  10542.                     copy(er0.begin(), er0.end(), x);
  10543.                     x[er0.size()] = '\0';
  10544.                     throw x;    }           }
  10545.             catch (const char* x) {
  10546.                 writelog(x);}
  10547. };
  10548.  
  10549.  
  10550. lua memory allocation
  10551.  
  10552.  
  10553.  
  10554. int main(){
  10555.     struct luamem
  10556.     {
  10557.         static void *l_alloc(void *ud, void *ptr, size_t osize, size_t nsize) {
  10558.             (void)ud; (void)osize;  /* not used */
  10559.             if (nsize == 0) {
  10560.                 free(ptr);
  10561.                 return NULL;
  10562.             }
  10563.             else
  10564.                 return realloc(ptr, nsize);
  10565.         }
  10566.     };
  10567.     void* ud = nullptr;
  10568.     lua_State* L = lua_newstate(luamem::l_alloc, ud);
  10569.     lua_close(L);
  10570. }
  10571.  
  10572. struct GlobalAllocator
  10573. {
  10574.     void* Allocate(size_t sizeBytes)
  10575.     {
  10576.         return ::operator new(sizeBytes);
  10577.     }
  10578.  
  10579.     void DeAllocate(void* ptr, size_t /*osize*/)
  10580.     {
  10581.         assert(ptr != nullptr);     //can't decallocate null!!!
  10582.         ::operator delete(ptr);
  10583.     }
  10584.  
  10585.     void* ReAllocate(void* ptr, size_t osize, size_t nsize)
  10586.     {
  10587.         size_t bytesToCopy = osize;
  10588.         if (nsize < bytesToCopy)
  10589.         {
  10590.             bytesToCopy = nsize;
  10591.         }
  10592.         void* newPtr = Allocate(nsize);
  10593.         memcpy(newPtr, ptr, bytesToCopy);
  10594.         DeAllocate(ptr, osize);
  10595.         return newPtr;
  10596.     }
  10597.  
  10598.     static void *l_alloc(void *ud, void *ptr, size_t osize, size_t nsize) {
  10599.         GlobalAllocator * pool = static_cast<GlobalAllocator *>(ud);
  10600.         if (nsize == 0)
  10601.         {
  10602.             if (ptr != nullptr)
  10603.             {
  10604.                 pool->DeAllocate(ptr, osize);
  10605.             }
  10606.             return NULL;
  10607.         }
  10608.         else
  10609.         {
  10610.             if (ptr == nullptr)
  10611.             {
  10612.                 return pool->Allocate(nsize);
  10613.             }
  10614.             else
  10615.             {
  10616.                 return pool->ReAllocate(ptr, osize, nsize);
  10617.             }
  10618.         }
  10619.     }
  10620. };
  10621.  
  10622. /*! \brief Allocates from a fixed pool.
  10623. *   Aligns all memory to 8 bytes
  10624. *   Has a min allocation of 64 bytes
  10625. *   Puts all free'd blocks on a free list.
  10626. *   Falls back to GlobalAllocator when out of memory. */
  10627. struct ArenaAllocator
  10628. {
  10629.     void* m_begin;
  10630.     void* m_end;
  10631.     char* m_curr;
  10632.  
  10633.     static constexpr int ALIGNMENT = 8;
  10634.     static constexpr int MIN_BLOCK_SIZE = ALIGNMENT * 8;
  10635.  
  10636.     struct FreeList
  10637.     {
  10638.         FreeList* m_next;
  10639.     };
  10640.  
  10641.     FreeList* m_freeListHead;
  10642.     GlobalAllocator m_globalAllocator;
  10643.  
  10644.     ArenaAllocator(void* begin, void* end) :
  10645.         m_begin(begin),
  10646.         m_end(end)
  10647.     {
  10648.         Reset();
  10649.     }
  10650.  
  10651.     void Reset()
  10652.     {
  10653.         m_freeListHead = nullptr;
  10654.         m_curr = static_cast<char*>(m_begin);
  10655.     }
  10656.  
  10657.     size_t SizeToAllocate(size_t size)
  10658.     {
  10659.         size_t allocatedSize = size;
  10660.         if (allocatedSize < MIN_BLOCK_SIZE)
  10661.         {
  10662.             allocatedSize = MIN_BLOCK_SIZE;
  10663.         }
  10664.         return allocatedSize;
  10665.     }
  10666.  
  10667.     void* Allocate(size_t sizeBytes)
  10668.     {
  10669.         size_t allocatedBytes = SizeToAllocate(sizeBytes);
  10670.         if (allocatedBytes <= MIN_BLOCK_SIZE && m_freeListHead)
  10671.         {
  10672.             //printf("-- allocated from the freelist --\n");
  10673.             void* ptr = m_freeListHead;
  10674.             m_freeListHead = m_freeListHead->m_next;
  10675.             return ptr;
  10676.         }
  10677.         else
  10678.         {
  10679.             m_curr = (char*)((uintptr_t)m_curr + (ALIGNMENT - 1) & ~(ALIGNMENT - 1));
  10680.             if (m_curr + allocatedBytes <= m_end)
  10681.             {
  10682.                 printf("Allocated %d bytes\n", (int)allocatedBytes);
  10683.                 void* ptr = m_curr;
  10684.                 m_curr += allocatedBytes;
  10685.                 return ptr;
  10686.             }
  10687.             else
  10688.             {
  10689.                 return m_globalAllocator.Allocate(sizeBytes);
  10690.             }
  10691.         }
  10692.     }
  10693.  
  10694.     void DeAllocate(void* ptr, size_t osize)
  10695.     {
  10696.         assert(ptr != nullptr);     //can't decallocate null!!!
  10697.         if (ptr >= m_begin && ptr <= m_end)
  10698.         {
  10699.             size_t allocatedBytes = SizeToAllocate(osize);
  10700.             printf("DeAllocated %d bytes\n", (int)allocatedBytes);
  10701.             if (allocatedBytes >= MIN_BLOCK_SIZE)
  10702.             {
  10703.                 printf("-- deallocated to the freelist --\n");
  10704.                 FreeList* newHead = static_cast<FreeList*>(ptr);
  10705.                 newHead->m_next = m_freeListHead;
  10706.                 m_freeListHead = newHead;
  10707.             }
  10708.         }
  10709.         else
  10710.         {
  10711.             m_globalAllocator.DeAllocate(ptr, osize);
  10712.         }
  10713.     }
  10714.  
  10715.     void* ReAllocate(void* ptr, size_t osize, size_t nsize)
  10716.     {
  10717.         printf("ReAllocated %d bytes\n", (int)nsize);
  10718.         size_t bytesToCopy = osize;
  10719.         if (nsize < bytesToCopy)
  10720.         {
  10721.             bytesToCopy = nsize;
  10722.         }
  10723.         void* newPtr = Allocate(nsize);
  10724.         memcpy(newPtr, ptr, bytesToCopy);
  10725.         DeAllocate(ptr, osize);
  10726.         return newPtr;
  10727.     }
  10728.  
  10729.     static void *l_alloc(void *ud, void *ptr, size_t osize, size_t nsize) {
  10730.         ArenaAllocator * pool = static_cast<ArenaAllocator *>(ud);
  10731.         if (nsize == 0)
  10732.         {
  10733.             if (ptr != nullptr)
  10734.             {
  10735.                 pool->DeAllocate(ptr, osize);
  10736.             }
  10737.             return NULL;
  10738.         }
  10739.         else
  10740.         {
  10741.             if (ptr == nullptr)
  10742.             {
  10743.                 return pool->Allocate(nsize);
  10744.             }
  10745.             else
  10746.             {
  10747.                 return pool->ReAllocate(ptr, osize, nsize);
  10748.             }
  10749.         }
  10750.     }
  10751. };
  10752. int main() {
  10753.     constexpr int pool_size = 1024 * 10;
  10754.     char memory[pool_size];
  10755.     ArenaAllocator pool(memory, &memory[pool_size-1]);
  10756.  
  10757.     lua_State *L = lua_newstate(ArenaAllocator::l_alloc, &memory);
  10758.     //luaL_openlibs(L);
  10759.     lua_assert(L != nullptr);
  10760.     lua_close(L);
  10761.     //cin.get();//ожидает ввода символа программа завершается.
  10762.     return 0;
  10763. }
  10764.  
  10765. pragma once
  10766. #include <assert.h>
  10767. #include <cstdio>
  10768. #include <string.h>
  10769.  
  10770. /*! \brief Allocates from global memory (NOTE: does not currently align memory) */
  10771. struct GlobalAllocator
  10772. {
  10773.     void* Allocate(size_t sizeBytes)
  10774.     {
  10775.         return ::operator new(sizeBytes);
  10776.     }
  10777.  
  10778.     void DeAllocate(void* ptr, size_t /*osize*/)
  10779.     {
  10780.         assert(ptr != nullptr);     //can't decallocate null!!!
  10781.         ::operator delete(ptr);
  10782.     }
  10783.  
  10784.     void* ReAllocate(void* ptr, size_t osize, size_t nsize)
  10785.     {
  10786.         size_t bytesToCopy = osize;
  10787.         if (nsize < bytesToCopy)
  10788.         {
  10789.             bytesToCopy = nsize;
  10790.         }
  10791.         void* newPtr = Allocate(nsize);
  10792.         memcpy(newPtr, ptr, bytesToCopy);
  10793.         DeAllocate(ptr, osize);
  10794.         return newPtr;
  10795.     }
  10796.  
  10797.     static void *l_alloc(void *ud, void *ptr, size_t osize, size_t nsize) {
  10798.         GlobalAllocator * pool = static_cast<GlobalAllocator *>(ud);
  10799.         if (nsize == 0)
  10800.         {
  10801.             if (ptr != nullptr)
  10802.             {
  10803.                 pool->DeAllocate(ptr, osize);
  10804.             }
  10805.             return NULL;
  10806.         }
  10807.         else
  10808.         {
  10809.             if (ptr == nullptr)
  10810.             {
  10811.                 return pool->Allocate(nsize);
  10812.             }
  10813.             else
  10814.             {
  10815.                 return pool->ReAllocate(ptr, osize, nsize);
  10816.             }
  10817.         }
  10818.     }
  10819. };
  10820.  
  10821. /*! \brief Allocates from a fixed pool.
  10822. *   Aligns all memory to 8 bytes
  10823. *   Has a min allocation of 64 bytes
  10824. *   Puts all free'd blocks on a free list.
  10825. *   Falls back to GlobalAllocator when out of memory. */
  10826. struct ArenaAllocator
  10827. {
  10828.     void* m_begin;
  10829.     void* m_end;
  10830.     char* m_curr;
  10831.  
  10832.     static constexpr int ALIGNMENT = 8;
  10833.     static constexpr int MIN_BLOCK_SIZE = ALIGNMENT * 8;
  10834.  
  10835.     struct FreeList
  10836.     {
  10837.         FreeList* m_next;
  10838.     };
  10839.  
  10840.     FreeList* m_freeListHead;
  10841.     GlobalAllocator m_globalAllocator;
  10842.  
  10843.     ArenaAllocator(void* begin, void* end) :
  10844.         m_begin(begin),
  10845.         m_end(end)
  10846.     {
  10847.         Reset();
  10848.     }
  10849.  
  10850.     void Reset()
  10851.     {
  10852.         m_freeListHead = nullptr;
  10853.         m_curr = static_cast<char*>(m_begin);
  10854.     }
  10855.  
  10856.     size_t SizeToAllocate(size_t size)
  10857.     {
  10858.         size_t allocatedSize = size;
  10859.         if (allocatedSize < MIN_BLOCK_SIZE)
  10860.         {
  10861.             allocatedSize = MIN_BLOCK_SIZE;
  10862.         }
  10863.         return allocatedSize;
  10864.     }
  10865.  
  10866.     void* Allocate(size_t sizeBytes)
  10867.     {
  10868.         size_t allocatedBytes = SizeToAllocate(sizeBytes);
  10869.         if (allocatedBytes <= MIN_BLOCK_SIZE && m_freeListHead)
  10870.         {
  10871.             //printf("-- allocated from the freelist --\n");
  10872.             void* ptr = m_freeListHead;
  10873.             m_freeListHead = m_freeListHead->m_next;
  10874.             return ptr;
  10875.         }
  10876.         else
  10877.         {
  10878.             m_curr = (char*)((uintptr_t)m_curr + (ALIGNMENT - 1) & ~(ALIGNMENT - 1));
  10879.             if (m_curr + allocatedBytes <= m_end)
  10880.             {
  10881.                 //printf("Allocated %d bytes\n", (int)allocatedBytes);
  10882.                 void* ptr = m_curr;
  10883.                 m_curr += allocatedBytes;
  10884.                 return ptr;
  10885.             }
  10886.             else
  10887.             {
  10888.                 return m_globalAllocator.Allocate(sizeBytes);
  10889.             }
  10890.         }
  10891.     }
  10892.  
  10893.     void DeAllocate(void* ptr, size_t osize)
  10894.     {
  10895.         assert(ptr != nullptr);     //can't decallocate null!!!
  10896.         if (ptr >= m_begin && ptr <= m_end)
  10897.         {
  10898.             size_t allocatedBytes = SizeToAllocate(osize);
  10899.             //printf("DeAllocated %d bytes\n", (int)allocatedBytes);
  10900.             if (allocatedBytes >= MIN_BLOCK_SIZE)
  10901.             {
  10902.                 //printf("-- deallocated to the freelist --\n");
  10903.                 FreeList* newHead = static_cast<FreeList*>(ptr);
  10904.                 newHead->m_next = m_freeListHead;
  10905.                 m_freeListHead = newHead;
  10906.             }
  10907.         }
  10908.         else
  10909.         {
  10910.             m_globalAllocator.DeAllocate(ptr, osize);
  10911.         }
  10912.     }
  10913.  
  10914.     void* ReAllocate(void* ptr, size_t osize, size_t nsize)
  10915.     {
  10916.         //printf("ReAllocated %d bytes\n", (int)nsize);
  10917.         size_t bytesToCopy = osize;
  10918.         if (nsize < bytesToCopy)
  10919.         {
  10920.             bytesToCopy = nsize;
  10921.         }
  10922.         void* newPtr = Allocate(nsize);
  10923.         memcpy(newPtr, ptr, bytesToCopy);
  10924.         DeAllocate(ptr, osize);
  10925.         return newPtr;
  10926.     }
  10927.  
  10928.     static void *l_alloc(void *ud, void *ptr, size_t osize, size_t nsize) {
  10929.         ArenaAllocator * pool = static_cast<ArenaAllocator *>(ud);
  10930.         if (nsize == 0)
  10931.         {
  10932.             if (ptr != nullptr)
  10933.             {
  10934.                 pool->DeAllocate(ptr, osize);
  10935.             }
  10936.             return NULL;
  10937.         }
  10938.         else
  10939.         {
  10940.             if (ptr == nullptr)
  10941.             {
  10942.                 return pool->Allocate(nsize);
  10943.             }
  10944.             else
  10945.             {
  10946.                 return pool->ReAllocate(ptr, osize, nsize);
  10947.             }
  10948.         }
  10949.     }
  10950. };
  10951.  
  10952.  
  10953.  
  10954. Понимание стека Lua
  10955. ________________________________________
  10956. Я не буду пытаться познакомить вас с языком Lua, в Интернете есть много хороших учебных пособий. Здесь я кратко представлю основную структуру API-интерфейса Lua C, чтобы установить основу для понимания остальной части руководства.
  10957.  
  10958. Приятной особенностью языка Lua является то, что интерпретатор не использует глобальные переменные вообще. Это означает, что у вас может быть несколько сред Lua, работающих в разных потоках без каких-либо конфликтов. Это также одна из основных причин того, что встраивание Lua настолько просто, что вам действительно нужно отслеживать только одну переменную для каждой среды выполнения: lua_State.
  10959.  
  10960. Я избавлю вас от технических деталей, в основном потому, что я их не знаю, но по сути каждый lua_State поддерживает стек переменных lua. Переменные Lua бывают следующих (в основном) самоочевидных типов: nil, логическое значение, число, строка, функция, пользовательские данные, поток и таблица. Я вернусь к деталям позже, просто помните, что lua_State содержит стек таких переменных, и единственный способ взаимодействия с Lua - через этот стек. Давайте создадим lua_State и поиграем с его стеком, чтобы мы понимали, что происходит.
  10961. Код:
  10962. lua_State * ls = lua_newstate ( 0 , 0 );
  10963.  
  10964. lua_pushinteger (ls, 0 );
  10965. lua_pushstring (ls, «это строка, оканчивающаяся нулем.» )
  10966. lua_pushboolean (ls, true );
  10967.  
  10968. // Теперь стек выглядит следующим образом:
  10969. // 3. true
  10970. // 2. «это строка с нулевым окончанием».
  10971. // 1. 0
  10972.  
  10973. Любой, кто раньше использовал стек, скажет вам, что чаще всего ссылаются на вершину стека. В этом случае вершиной стека является элемент 3. Если вам нравится, вы можете обратиться к нему, вызвав lua_gettop, который возвращает количество элементов в стеке, но есть гораздо более простой способ. Вы можете ссылаться на элементы сверху вниз, используя отрицательные индексы. Таким образом, верхний элемент может быть проиндексирован с -1, второй сверху с -2 и так далее. Как вы увидите, вы будете ссылаться на элементы стека с отрицательными индексами довольно часто.
  10974. Код:
  10975. bool boolval = lua_toboolean (ls, - 1 ); // true
  10976. const char * stringval = lua_tostring (ls, - 2 ); // "это строка с нулевым окончанием."
  10977. int intval = lua_tointeger (ls, - 3 ); // 0
  10978.  
  10979. // Стоит отметить, что только nil переводит в ложное значение, число 0 переводит
  10980. // в true, что может удивить большинство программистов на Си.
  10981. boolval = lua_toboolean (ls, - 3 ); // правда
  10982.  
  10983. Итак, у нас есть несколько элементов стека, мы можем получить к ним доступ, что еще мы можем сделать?
  10984. Код:
  10985. lua_pop (ls, 1 ); //
  10986. вставляем верхний элемент lua_insert (ls, 1 ); // переместить верхний элемент в нижнюю часть стека
  10987. lua_pushvalue (ls, - 1 ); // выдвигает копию верхнего элемента
  10988.  
  10989. // Теперь стек выглядит следующим образом:
  10990. // 3. 0
  10991. // 2. 0
  10992. // 1. «Это строка с нулем в конце».
  10993.  
  10994. lua_settop (ls, 0 ); // удаляет все элементы из стека
  10995.  
  10996. Итак, вот основная суть стека. Пожалуйста, обратитесь к вашему дружелюбному руководству Neghborhood Lua для получения более подробной информации, и, конечно, есть намного больше деталей.
  10997.  
  10998. функции
  10999. ________________________________________
  11000. Нажатие и выталкивание строк и целых чисел - это весело и хорошо, но что, если вы действительно хотите сделать что-то полезное? Самое распространенное, что хочет сделать разработчик, - это представить функцию C / C ++ или класс C ++ сценарию Lua. Чтобы понять, как выставлять классы, мы должны начать с функций, поэтому давайте погрузимся прямо в.
  11001. Код:
  11002. // Все функции, доступные для Lua, должны иметь следующую структуру:
  11003. int some_lua_function ( lua_State * ls)
  11004. { // Do work ... return number_of_return_values; }
  11005.  
  11006.  
  11007.  
  11008.  
  11009. Мы взаимодействуем с Lua исключительно со стеком. В приведенной выше функции стек будет начинаться с параметров, которые были переданы, и вы несете ответственность за передачу возвращаемых значений в стек и указание Lua, сколько их существует. Вот более конкретный пример:
  11010. Код:
  11011. int move_player (lua_Stack * ls)
  11012. { const int xoffset = lua_tointeger (ls, 1 ); const int yoffset = lua_tointeger (ls, 2 ); const Point p = player-> move (xoffset, yoffset); lua_pushinteger (ls, px); lua_pushinteger (ls, py); возврат 2 ; }
  11013.  
  11014.  
  11015.  
  11016.  
  11017.  
  11018.  
  11019.  
  11020.  
  11021.  
  11022.  
  11023. Хорошо, у нас много чего происходит, поэтому давайте сделаем это медленно. Первое, на что нужно обратить внимание, это то, что всякий раз, когда Lua вызывает вашу функцию, она будет давать вам стек, содержащий только параметры функции. Первая часть функции превращает параметры в C / C ++, который мы можем использовать (позже я покажу вам, как быть в безопасности, вызвав luaL_checktype). Вторая часть функции - это работа, выполняемая вашим двигателем. Я оставлю это вашему воображению. Третья часть функции показывает, как мы возвращаем значения в Lua с помощью универсального стека. Последняя строка функции указывает Lua, сколько возвращаемых значений получить.
  11024.  
  11025. Теперь, когда мы определили функцию, вот как Lua распознает ее:
  11026. Код:
  11027. lua_register (ls, "MovePlayer" , move_player);
  11028.  
  11029. Хм ... это было легко. Теперь я могу вызывать MovePlayer в моих скриптах Lua! Теперь вы знаете достаточно, чтобы представить свой движок сценариям Lua, но, пожалуйста, следите за обновлениями, я покажу вам, как проверять параметры, обрабатывать ошибки и выставлять классы.
  11030.  
  11031. Краткое примечание об API Lua C
  11032. ________________________________________
  11033. Некоторые люди могут чесать голову, задаваясь вопросом, почему в 7 адах кто-то захочет вручную управлять стеком Lua. Это выглядит сложным, это выглядит подверженным ошибкам, почему бы не использовать библиотеку оболочки? Конечно, давай. Если вы хотите использовать библиотеку и находите библиотеку, подходящую для ваших нужд, то обязательно используйте ее. Просто прочитайте следующие несколько строк, прежде чем принять решение.
  11034.  
  11035. Управление стеками поддается инкапсуляции, поэтому большую часть сложности можно сделать невидимой. Ручное управление стеками очень быстрое, и Lua - очень быстрый язык, идеальный выбор. Ручное управление стеками не требует никаких дополнительных библиотек или API. Наконец, управление стеками не так уж сложно или сложно. Да, вам нужно потратить некоторое время на API, вам нужно приложить немного усилий, но вам все равно придется приложить усилия для изучения библиотеки-оболочки. В итоге у вас будет невероятно быстрый двигатель, который легко программировать и полностью под вашим контролем. Помимо всего этого, я покажу вам крутой трюк, который значительно упростит управление стеками. Просто
  11036. продолжай читать.
  11037.  
  11038.    
  11039.  
  11040. таблицы
  11041. ________________________________________
  11042. Столы! Столы! Столы! Если вы не понимаете таблицы, прочитайте документацию по Lua и вернитесь. Столы это все. Нет Луа без таблиц. Вот краткое введение в то, как взаимодействовать с таблицами Lua, используя C API.
  11043.  
  11044. Код:
  11045. lua_newtable (LS); //
  11046. создаем пустую таблицу поверх стека lua_pushstring (ls, "tablekey" ); //
  11047. помещает в стек значение, которое мы будем использовать
  11048. в качестве ключа таблицы lua_pushinteger (ls, 1337 ); // это будет значение, индексированное указанным ключом
  11049.  
  11050. // Теперь стек выглядит так:
  11051. // -1. 1337
  11052. // -2. "tablekey"
  11053. // -3. <table>
  11054.  
  11055. // При этом используется верхний элемент в -1 для значения, используется элемент в -2 для ключа и
  11056. выполняется запись в // таблицу в указанной позиции, в данном случае в -3. И значение, и ключ
  11057. // извлекаются из стека, оставляя новую таблицу сверху.
  11058. lua_settable (ls, - 3 );
  11059.  
  11060. // Код Lua, эквивалентный приведенному выше C-коду:
  11061. // {} ["tablekey"] = 1337
  11062.  
  11063. Код достаточно понятен для всех, кто знаком с таблицами Lua, поэтому я быстро перейду к следующему важному вопросу. Где пустая таблица, которую мы создали? У него нет имени, оно существует только в стеке. Чтобы сохранить таблицу, мы должны создать постоянную ссылку на нее, но как? Вот идет вкусный соус Lua. Почти все в Lua - это стол, даже глобальная среда! Таким образом, чтобы превратить нашу новую таблицу в глобальную переменную, мы просто помещаем ее в глобальную таблицу так же, как мы помещаем «1337» в новую таблицу! Итак, продолжаем, где мы остановились:
  11064.  
  11065. Код:
  11066. lua_pushstring (ls, "mynewtable" );
  11067.  
  11068. // Теперь стек выглядит так:
  11069. // -1. "mynewtable"
  11070. // -2. <table>
  11071.  
  11072. // Если вы посмотрите на фрагмент кода выше, вы заметите, что значение должно быть в верхней части
  11073. // стека, с ключом под ним, поэтому давайте немного перетасуем стек.
  11074. lua_insert (ls, - 2 ); // перемещаем верхний элемент в -2, смещая предыдущий -2 в верхний
  11075.  
  11076. // Теперь стек выглядит так:
  11077. // -1. <таблица>
  11078. // -2. "mynewtable"
  11079.  
  11080. // Теперь делаем то же самое, что мы делали выше, но обращаемся к глобальной таблице с помощью специального псевдоиндекса.
  11081. lua_settable (ls, LUA_GLOBALSINDEX);
  11082.  
  11083. Ta-Da! Мы создали новую глобальную переменную! Таблицы Lua могут использовать что угодно в качестве ключей, включая другие таблицы, но вы чаще всего будете использовать строки в качестве ключей. Lua C API имеет удобные функции для упрощения получения и установки «полей» таблицы, соответственно названных lua_getfield и lua_setfield. С помощью этих полезных функций 2 приведенных выше фрагмента кода можно сжать до:
  11084.  
  11085. Код:
  11086. lua_newtable (ls);
  11087. lua_pushinteger (ls, 1337);
  11088. lua_setfield (ls, -2, "tablekey" );
  11089. lua_setfield (ls, LUA_GLOBALSINDEX, "mynewtable" );
  11090.  
  11091. Давайте рассмотрим скорость и покажем вам очень практический пример того, как выставить синглтон двигателя Lua. В этом примере мы покажем синглтон приложения, который показывает панель предупреждений с текстом.
  11092.  
  11093. Код:
  11094. // Так или иначе мы устанавливаем этот класс C ++.
  11095. AlertPanel * alert = ...;
  11096.  
  11097. int alert_show ( lua_State * ls)
  11098. { строковое сообщение; // C ++ строка if (lua_gettop (ls)> 0 && lua_isstring (ls, - 1 )) {
  11099. message = lua_tostring (ls, 1 ); } else { // Давайте попробуем получить сообщение по умолчанию. lua_getfield
  11100. (ls, LUA_GLOBALSINDEX, "Alert" );
  11101. luaL_checktype (ls, - 1 , LUA_TTABLE);
  11102. lua_getfield (ls, - 1 , «по умолчанию» ); if (lua_isstring (ls, -1 ))
  11103. message = lua_tostring (ls, - 1 ); }
  11104. if (! message.empty ()) { alert-> setMessage (message); alert-> показать (); }
  11105. return 0 ; }
  11106.  
  11107. int alert_hide ( lua_State * ls) { alert-> hide (); вернуть 0 ; } // Инициализация интерфейса Lua в некоторой функции ... lua_newtable (ls); lua_pushcfuntion (ls, alert_show); lua_setfield (ls, - 2 , «показать» ); lua_pushcfuntion (ls, alert_hide); lua_setfield (ls, - 2 , «скрыть» );
  11108.  
  11109.  
  11110.  
  11111.  
  11112.  
  11113.  
  11114.  
  11115.  
  11116.  
  11117.  
  11118.  
  11119.  
  11120.  
  11121.  
  11122.  
  11123.  
  11124.  
  11125.  
  11126.  
  11127.  
  11128.  
  11129.  
  11130.  
  11131.  
  11132.  
  11133.  
  11134. lua_pushstring (ls, "Alert" );
  11135. lua_insert (ls, - 2 );
  11136. lua_settable (ls, LUA_GLOBALSINDEX);
  11137.  
  11138. Прежде чем вы уйдете с отвращением, позвольте мне заверить вас, что есть гораздо более простой и удобный способ сделать это, но я хочу убедиться, что вы понимаете основной механизм. Итак, что мы сделали? Посмотрите на следующий код Lua, чтобы увидеть, как мы будем использовать Alert:
  11139.  
  11140. Код:
  11141. - Настройка одноплодного оповещения с более по умолчанию сообщения.
  11142. Предупреждение. default = "Произошла неизвестная ошибка!"
  11143.  
  11144. - В случае с ошибкой пользователь должен знать о , предупредить их!
  11145. локальный результат, err = pcall (some_function, some_parameters),
  11146. если не результат, то
  11147.  Alert.show (err)
  11148. end
  11149.  
  11150. Это очень похоже на класс. На самом деле для многих движков может быть достаточно просто показать группу синглетонов, созданных таким образом. Но чтобы устранить любые опасения по поводу сложного управления таблицами в приведенном выше коде, позвольте мне показать вам гораздо более простой способ сделать то же самое:
  11151.  
  11152. Код:
  11153. // После объявления функций Alert C ...
  11154. static const luaL_reg Alert_funcs [] =
  11155. {
  11156.    { "show" , alert_show},
  11157.    { "hide" , alert_hide},
  11158.    { 0 , 0 }
  11159. };
  11160.  
  11161. // Инициализировать интерфейс Lua в некоторой функции ...
  11162. luaL_openlib (ls, "Alert" , Alert_funcs, 0 );
  11163. lua_pop (ls, 1 );
  11164.  
  11165. Намного проще, нет? Теперь вы знаете, что происходит под капотом, как вы можете создать изящную таблицу с функциями и переменными, и как сделать это быстро и безболезненно. Что-то еще, что вы можете сделать со своими новыми знаниями, - это изменить существующие таблицы Lua. Например, вы можете добавить несколько функций в довольно спартанскую библиотеку «io», возможно, «create_dir» и «destroy_dir». Помните, что вы не модифицируете библиотеку, а расширяете встроенную функцию своего игрового движка (Аргументы счетчика в 3 ... 2 ... 1 ...).
  11166.  
  11167. Пользовательские данные, метатаблицы и классы
  11168. ________________________________________
  11169. У Луа нет встроенного понятия о классах. Однако с помощью нескольких невероятно мощных механизмов Lua вы можете создать систему первого класса. Зайдите на lua.org, чтобы найти замечательный выбор учебников о том, как поддерживать классы и наследование. Со своей стороны, я собираюсь показать вам, как представить классы C ++ для Lua так, чтобы деструкторы могли хорошо играть с сборкой мусора Lua.
  11170.  
  11171. Чтобы представить класс C ++, который будет собирать мусор Lua, мы будем использовать тип userdata, который в Lua C API представлен указателем void. Вместо того, чтобы пытаться объяснить это, вот полный пример для анализа:
  11172.  
  11173. Код:
  11174. int monster_create (lua_State * ls)
  11175. { // Monster - это определенный где-то класс C ++ ... Monster * monster = new (lua_newuserdata (ls, sizeof (Monster)) Monster;luaL_getmetatable (ls, "MetaMonster" );    lua_setmetatable (ls, - 2 ); return 1 ;} int monster_destroy (lua_State * ls) {luaL_checktype (ls, 1 , LUA_TUSERDATA);Monster * monster = reinterpret_cast <Monster *> (lua_touserdata (ls, 1 ));монстр-> ~ Monster () ; вернуть 0
  11176.  
  11177.  
  11178.  
  11179.  
  11180.    
  11181.  
  11182.  
  11183.  
  11184.  
  11185.  
  11186.  
  11187.  
  11188.  
  11189.  
  11190.  ;
  11191. }
  11192.  
  11193. int monster_rawr (lua_State * ls)
  11194. {
  11195. luaL_checktype (ls, 1 , LUA_TUSERDATA);
  11196. Monster * monster = reinterpret_cast <Monster *> (lua_touserdata (ls, 1 ));
  11197. monster-> Rawr (); // печатает угрожающее "rawr! Я пистолет eet u!" возврат сообщения 0 ; } static const luaL_reg Monster_funcs [] = {     { "create" , monster_create},     { 0 , 0 } }; статический Const luaL_reg Monster_methods [] = { { "__gc"
  11198.  
  11199.  
  11200.  
  11201.  
  11202.  
  11203.  
  11204.  
  11205.  
  11206.  
  11207.  
  11208.  
  11209.  
  11210. , monster_destroy},
  11211. { "rawr" , monster_rawr},
  11212.    { 0 , 0 }
  11213. };
  11214.  
  11215. // Инициализировать интерфейс Lua в некоторой функции ...
  11216. luaL_newmetatable (ls, "MetaMonster" );
  11217. lua_pushstring (ls, "__index" );
  11218. lua_pushvalue (ls, - 2 );
  11219. lua_settable (ls, - 3 );
  11220.  
  11221. luaL_openlib (ls, 0 , Monster_methods, 0 );
  11222. luaL_openlib (ls, "Monster" , Monster_funcs, 0 );
  11223.  
  11224. Это достаточно много для понимания, но прежде чем мы проанализируем это, взглянем на то, как наш класс будет использоваться в скрипте Lua:
  11225.  
  11226. Код:
  11227. местный плохой парень = Monster.create ()
  11228.  
  11229. - О нет! Вы расстроили плохого парня!
  11230. Badguy: Rawr ()
  11231.  
  11232. Там у вас есть класс C ++, появляющийся в скрипте Lua. Теперь давайте посмотрим, как мы попали сюда, шаг за шагом, начиная с monster_create.
  11233.  
  11234. Первое, что мы делаем, это создаем экземпляр класса C ++, используя оператор размещения new. Если вы не знакомы с размещением new, то в основном он создает экземпляр класса в памяти, данной ему. В этом случае мы передаем память, которую мы получили от интерпретатора Lua. Это оставляет новый экземпляр пользовательских данных поверх стека. Следующие две строки - это место, где происходит волшебство. Я не буду пытаться объяснить вам метатаблицы, поэтому придется сделать следующее грубое искажение. Я в основном устанавливаю таблицу виртуальных функций экземпляра класса или список функций, которые он поддерживает. Я использую метатабель под названием «MetaMonster», который я создаю далее по фрагменту кода. Наконец, я возвращаю 1, чтобы указать Lua, что пользовательские данные в стеке должны быть возвращены вызывающей стороне monster_create.
  11235.  
  11236. Следующая функция, которую мы определили, это monster_destroy. Эта функция будет автоматически вызываться Lua после того, как будет выпущена последняя ссылка на экземпляр монстра. Убедившись, что параметр имеет смысл, мы приводим данные пользователя к нашему типу класса C ++ и вызываем его деструктор. Не вызывайте оператор удаления, Lua будет обрабатывать необработанную память. Вы можете обнулить память, если это заставляет вас чувствовать себя лучше.
  11237.  
  11238. Функция monster_rawr - это место, где мы представляем функцию-член Lua. В этом случае это супер-пугающая функция rawr, которая не принимает параметров и не возвращает результатов. При представлении функции-члена первым параметром всегда будут сами пользовательские данные, которые мы создали как экземпляр класса C ++ в monster_create. Для поддержки дополнительных параметров или возвращаемых значений, просто имейте в виду, что параметры будут начинаться с индекса стека 2, например:
  11239.  
  11240. Код:
  11241. int monster_jump (lua_State * ls)
  11242. {
  11243. luaL_checktype (ls, 1 , LUA_TUSERDATA);
  11244. Monster * monster = reinterpret_cast <Monster *> (lua_touserdata (ls, 1 )); // Параметры функции-члена начинаются с индекса стека 2 ... luaL_checktype (ls, 2 , LUA_TNUMBER); const int howhigh = lua_tointeger (ls, 2 ); const bool result = monster-> jump (howhigh); lua_settop (ls, 0 ); lua_pushboolean (ls, результат); возврат 1 ; }
  11245.  
  11246.  
  11247.  
  11248.  
  11249.  
  11250.  
  11251.  
  11252.  
  11253.  
  11254.  
  11255.  
  11256. Класс C ++ теперь можно использовать из Lua! Но есть что-то немного странное, что-то не совсем правильное в использовании пользовательских данных в Lua Scipt. Что произойдет, если вы захотите добавить поле в свой класс? Вы должны будете сделать это через C ++ и открыть новое поле с помощью другой функции Lua. Это может быть немного грязно, и, кажется, побеждать цель использования хорошего гибкого языка, такого как Lua. Итак, я собираюсь показать вам, как перейти на следующий уровень и представить класс C ++ в виде таблицы Lua, в которую вы можете добавлять функции и переменные. Ключ к достижению этого - метатаблицы. У нас уже есть монстр, доступный для мета с поддерживаемыми функциями-членами, теперь нам нужно просто поиграть с битами, чтобы при вызове одной из этих функций у нас был доступ к таблице и объекту C ++. Прежде всего, давайте вернемся к созданию монстров,
  11257.  
  11258. Код:
  11259. int monster_create (lua_State * ls)
  11260. { // Создать таблицу и установить ее метатизируемость. lua_newtable (LS); luaL_getmetatable (ls, "MetaMonster" ); lua_setmetatable (ls, - 2 ); // Monster - это класс C ++, определенный где-то ... Monster * monster = new (lua_newuserdata (ls, sizeof (Monster)) Monster;luaL_getmetatable (ls, "MetaMonster" );lua_setmetatable (ls, - 2 ); // Теперь стек выглядит следующим образом: // 2. <userdata> (наш экземпляр класса C ++) // 1. <table> (с метатабельным MetaMonster)     lua_setfield (ls, - 2
  11261.  
  11262.  
  11263.  
  11264.  
  11265.  
  11266.  
  11267.  
  11268.  
  11269.  
  11270.  
  11271.  
  11272.  
  11273.  
  11274.    
  11275. , "core_" ); возврат 1 ; }
  11276.  
  11277.  
  11278.  
  11279. Разница здесь в том, что мы начинаем с создания таблицы и установки ее метатизируемой перед созданием пользовательских данных. Затем мы даем userdata такой же метатабельный и помещаем его в новый экземпляр таблицы как поле core_. Можете ли вы увидеть, где это происходит? Теперь наши функции-члены будут принимать таблицу Lua в качестве первого параметра, извлекать поле core_, чтобы получить экземпляр класса C ++, и использовать два в тандеме для создания магии.
  11280.  
  11281. Небольшая заметка о метатабле. Мы назначаем метатаблицу дважды, один раз для таблицы и один раз для пользовательских данных. Мы будем использовать функции-члены через таблицу, но только объекты пользовательских данных будут иметь метаметод __gc, когда они готовы к смерти. Поэтому вместо того, чтобы использовать две отдельные метатаблицы, одну для функций-членов и одну для деструктора, я просто собрал их вместе.
  11282.  
  11283. Теперь взгляните на новые функции уничтожения и перехода, чтобы увидеть, что произошло.
  11284.  
  11285. Код:
  11286. // Метаметод __gc будет вызываться только для пользовательских данных.
  11287. int monster_destroy (lua_State * ls)
  11288. {
  11289. luaL_checktype (ls, 1 , LUA_TUSERDATA); Monster * monster = reinterpret_cast <Monster *> (lua_touserdata (ls, 1 )); monster-> ~ монстр (); вернуть 0 ; } int monster_jump (lua_State * ls) { luaL_checktype (ls, 1 , LUA_TTABLE); lua_getfield (ls, 1 , "core_" ); luaL_checktype (ls, - 1 , LUA_TUSERDATA); Monster * monster = reinterpret_cast
  11290.  
  11291.  
  11292.  
  11293.  
  11294.  
  11295.  
  11296.  
  11297.  
  11298.  
  11299.  
  11300.  
  11301.  
  11302. <Monster *> (lua_touserdata (ls, - 1 )); // Параметры функции-члена начинаются с индекса стека 2 ... luaL_checktype (ls, 2 , LUA_TNUMBER); const int howhigh = lua_tointeger (ls, 2 ); // Мы можем включить таблицу Lua в эту бессмысленную функцию ... int jumpbonus = 0 ; lua_getfield (ls, 1 , "jumpbonus" ); if (lua_isnumber (ls, - 1 )) jumpbonus = lua_tointeger (ls, - 1 ); const int result = monster-> jump (howhigh + jumpbonus); lua_pushboolean (ls, результат);
  11303.  
  11304.  
  11305.  
  11306.  
  11307.  
  11308.  
  11309.  
  11310.  
  11311.  
  11312.  
  11313.  
  11314.  
  11315.  
  11316. возврат 1 ; }
  11317.  
  11318.  
  11319. Первое, что делает наша функция-член, это проверяет, что ее первый параметр является таблицей. Затем он извлекает поле core_ и преобразует его в соответствующий экземпляр класса C ++. На данный момент я хотел бы отметить, что мы всегда можем использовать больше проверки ошибок, особенно на этапах отладки проекта. Это было бы провальным логическим провалом, если бы вы как-то заменили core_ другим экземпляром userdata или другим глупым дерьмом. Возможно, вы захотите избежать конфликтов имен, переименовывая core_ во что-то более уникальное, например, core_CANTTOUCHTHIS или, что еще лучше, core_nameofcppclass.
  11320.  
  11321. Двигаемся дальше. Наша функция-член теперь имеет стек с таблицей внизу и указатель на экземпляр класса C ++ сверху. Не стесняйтесь сходить с ума. На практике я немного опасаюсь доступа к членам Lua из функций-членов C ++, потому что это создает те же проблемы, что и использование прямых пользовательских данных в качестве экземпляров классов, требует изменения исходного кода C / C ++ и перекомпиляции. Тем не менее, у вас есть возможность, и есть разумные способы, которыми вы можете смешать их.
  11322.  
  11323. Мое личное мнение состоит в том, что C ++ должен сосредоточиться на тех функциях, которые он предоставляет, и Lua должен использовать эти функции для достижения ваших целей. Используйте C ++ для строительных блоков, используйте Lua для дизайна.
  11324.  
  11325. Код:
  11326. badguy = Monster.create ()
  11327.  
  11328. - badguy получает специальную атаку ...
  11329. badguy.pounce = function (self, howhigh)
  11330. self . jumpbonus = howhigh или 2 self : jump () self : rawr () end  
  11331.  
  11332.  
  11333. Рекомендации
  11334. ________________________________________
  11335. До сих пор я работал с позиции, что объекты создаются в Lua и хранятся там. Однако легко предвидеть времена, когда вы захотите, чтобы ваш движок управлял объектами Lua. В этих случаях вам нужно иметь какую-то ссылку, которую вы можете использовать, чтобы поместить объект Lua в стек. Хотя создать собственную справочную систему не так уж сложно (я оставлю это в качестве упражнения для читателя ... Я всегда хотел написать это!), Lua предлагает очень хороший предварительно протестированный вариант.
  11336. Код:
  11337. // Учитывая, что мы хотим сохранить ссылку на объект Lua поверх стека ...
  11338. const int objectRef = luaL_ref (ls, indexofatable);
  11339.  
  11340. // ... что-то происходит, может быть, следующий код находится в другой функции ...
  11341.  
  11342. // Поместить объект на вершину стека.
  11343. lua_rawgeti (ls, indexofatable, objectRef);
  11344.  
  11345. // ... опять же, следующий код может быть где угодно ...
  11346. luaL_unref (ls, indexofatable, objectRef);
  11347.  
  11348. // Теперь ссылка освобождена, не используйте ее снова.
  11349.  
  11350. Что ...!? Что это за индексный бизнес? Ну, ссылки Lua должны где-то жить, поэтому вам нужно указать, в какую таблицу поместить ссылку. Если у вас есть куча экземпляров 'Monster', которые вы хотите сохранить под рукой, то вы можете создать таблицу 'MonsterRef' в глобальном пространстве имен для отслеживания экземпляров 'Monster'. Да ... Я знаю ... это отстойно. Я думал, что ссылки должны были быть легкими и быстрыми. Ну, Луа накрыл это специальным столом; реестр.
  11351. Код:
  11352. const int objectRef = luaL_ref (ls, LUA_REGISTRYINDEX);
  11353.  
  11354. Доступ к реестру осуществляется с помощью специального псевдоиндекса стека, который служит хорошим опрятным местом для хранения ваших ссылок. Он также имеет преимущество в том, что доступ к нему осуществляется очень быстро, поскольку поиск имени для поиска таблицы не требуется. Говоря об этой теме, позвольте мне заверить вас, что у вас нет абсолютно никаких причин беспокоиться о производительности эталонной системы. Когда я только начинал работать с Lua, меня очень беспокоило снижение производительности при поиске ссылок каждый раз, когда к объектам Lua обращались из C ++. Мои опасения были абсолютно необоснованными. Поиск ссылок действительно быстрый, в основном это просто доступ к массиву.
  11355.  
  11356. Это подводит меня к общему мнению о производительности Lua: это очень хорошо. Как программист C ++, привыкший к кодированию медиа-конвейеров реального времени, я, естественно, был обеспокоен использованием этого необычного непрозрачного стекового интерфейса. Я думал, что если я хочу получить доступ к объекту Lua, мне нужно просто дать указатель и интерфейс. Хотя я нашел способы подтолкнуть Lua к пределам производительности (в процедурной генерации мира и AI, двух тяжелых процессорных задачах), профилирование показало, что мой чрезвычайно сложный игровой цикл Lua тратит только 2% своего времени на обработку вызовов Lua. Так что дерзайте и используйте справочную систему столько, сколько хотите. Это вряд ли повлияет на производительность.
  11357.  
  11358. Хорошие вещи, вот пример того, как мы можем использовать ссылки в нашей игре.
  11359. Код:
  11360. int world_insert ( lua_State * ls)
  11361. { // Получить параметр self, экземпляр класса C ++ "World" luaL_checktype (ls, 1 , LUA_TTABLE); lua_getfield (ls, 1 , "core_" ); luaL_checktype (ls, - 1 , LUA_TUSERDATA); Мир * мир = reinterpret_cast <Мир *> (lua_touserdata (ls, - 1 )); lua_pop (ls, 1 ); // Получить параметр монстра. luaL_checktype (ls, 2 , LUA_TTABLE); lua_getfield (ls, 2 , "core_" ); luaL_checktype (ls, - 1
  11362.  
  11363.  
  11364.  
  11365.  
  11366.  
  11367.  
  11368.  
  11369.  
  11370.  
  11371.  
  11372.  
  11373. , LUA_TUSERDATA); Monster * monster = reinterpret_cast <Monster *> (lua_touserdata (ls, - 1 )); lua_pop (ls, 1 ); // Получить координаты X и Y. luaL_checktype (ls, 3 , LUA_TNUMBER); luaL_checktype (ls, 4 , LUA_TNUMBER); const Vec2i loc ( lua_tointeger (ls, 3) , lua_tointeger (ls, 4) ) ; const bool result = world-> insert (monster, loc); // Нам нужно хранить ссылку где-нибудь, в этом примере мы // сохраним ее в фактическом экземпляре monster, в целочисленном свойстве
  11374.  
  11375.  
  11376.  
  11377.  
  11378.  
  11379.  
  11380.  
  11381.  
  11382.  
  11383.  
  11384.  
  11385.  
  11386.  
  11387.  
  11388.  
  11389. // с именем 'ref'. if (result && monster-> ref () == LUA_NOREF) { // Мы успешно вставили монстра, давайте сохраним ссылку на него //, так что даже если скрипт Lua отпускает его дескриптор, мы можем / / по-прежнему доступ к нему через наш экземпляр класса "World". // Нам нужен объект, на который мы хотим сослаться сверху стека, // поэтому мы просто вытолкнем все сверху нашего экземпляра монстра, // который находится в позиции стека 2. lua_settop (ls, 2 ); const int ref = luaL_ref (ls, LUA_REGISTRYINDEX); monster-> setRef (ссылка); } lua_pushboolean (ls, результат); возврат 1 ;
  11390.  
  11391.  
  11392.  
  11393.  
  11394.  
  11395.  
  11396.  
  11397.  
  11398.  
  11399.  
  11400.  
  11401.  
  11402.  
  11403.  
  11404.  
  11405.  
  11406.  
  11407.  
  11408.  
  11409. world_remove ( lua_State * ls)
  11410. {
  11411. luaL_checktype (ls, 1 , LUA_TTABLE);
  11412. lua_getfield (ls, 1 , "core_" );
  11413. luaL_checktype (ls, - 1 , LUA_TUSERDATA); Мир * мир = reinterpret_cast <Мир *> (lua_touserdata (ls, - 1 ));
  11414. lua_pop (ls, 1 );
  11415. luaL_checktype (ls, 2 , LUA_TTABLE); lua_getfield (ls, 2 , "core_" );
  11416. luaL_checktype (ls, - 1 , LUA_TUSERDATA); Monster * monster = reinterpret_cast <Monster *> (lua_touserdata (ls, - 1)
  11417.  
  11418.  
  11419.  
  11420.  
  11421.  
  11422.  
  11423.  
  11424.  
  11425. ));
  11426. lua_pop (ls, 1 ); монстр = мир-> удалить (монстр); if (monster) { luaL_unref (ls, LUA_REGISTRYINDEX, monster-> ref ()); monster-> setRef (LUA_NOREF); } return 0 ; }
  11427.  
  11428.  
  11429.  
  11430.  
  11431.  
  11432.  
  11433.  
  11434.  
  11435.  
  11436.  
  11437. Здесь происходит немало Мы работаем с гипотетическим классом C ++ под названием «Мир». Мировые объекты хранят монстров и отображают их в цикле рендеринга. Где-то в реализации World он держит указатель Monster, который мы даем ему в вызове insert, но для того, чтобы удерживать таблицу Lua и предотвратить ее уничтожение сборщиком мусора, нам нужно где-то сохранить ссылку. Я бы предпочел полностью исключить Lua из моих реализаций классов C ++, поэтому я собираюсь обрабатывать ссылки прямо здесь, на уровне привязки C ++ / Lua. К сожалению, мне все еще нужно где-то хранить дескриптор Lua, поэтому я решил оставить его в самом экземпляре класса C ++. Ссылки на Lua - это просто старые целые, поэтому мне не нужно импортировать Lua в файл класса, нужно только сделать публичное свойство int с именем ref.
  11438. Код:
  11439. Monster * monster = new (lua_newuserdata (ls, sizeof (Monster)) Monster; // Мы еще не создали ссылку. Monster-> setRef (LUA_NOREF);
  11440.  
  11441.  
  11442.  
  11443.  
  11444. Когда я хочу сохранить экземпляр монстра где-нибудь в своем коде C ++, я создам ссылку на него, а когда экземпляр больше не нужен моему движку, я освобождаю ссылку. Обратите внимание, что нет необходимости освобождать ссылку в метаметоде __gc, потому что этот метод никогда не будет вызываться, пока существует ссылка.
  11445.  
  11446. Работа со ссылками может быть подвержена ошибкам, особенно если вы выполняете это во многих различных функциях, поэтому вы можете захотеть написать класс RAII C ++, который будет обрабатывать его для вас. Я храню ссылки только на один вид объектов в моей игре, и на эти объекты ссылаются и не ссылаются в двух четко определенных функциях. Я считаю, что это лучшая стратегия управления ресурсами.
  11447.  
  11448. PS. Lua также поддерживает слабые ссылки. Обратитесь к документации Lua для деталей.
  11449.  
  11450.       Записан
  11451.  
  11452.  
  11453.  
  11454.  
  11455. Большая часть вашей личности без сознания.
  11456.  
  11457.  
  11458.  
  11459.  
  11460. Re: Встраивание Lua в C ++
  11461. « Ответ # 6: 28 октября 2011 г., 23:43:01»  
  11462. ________________________________________
  11463. Делать это аккуратно
  11464. ________________________________________
  11465. Позвольте мне предварить этот раздел заявлением об отказе от ответственности, что в этом нет необходимости, и многие люди могут найти его с дурным вкусом. На этом учебное пособие по Lua C API заканчивается, и если вы довольны необработанным C API, то будьте на моем пути с моим благословением. Ниже приведено несколько специализаций шаблонов и плохо названных макросов препроцессора, сшитых вместе, чтобы сделать немного слишком умный мини-язык для связывания C ++ и Lua. Я повторю то, что я сказал в начале: это хорошо работает для меня, ваш пробег может отличаться.
  11466.  
  11467. В программировании есть трюизм, который гласит, что многократное написание утомительного кода увеличит количество ошибок. Возможно, вы заметили много утомительного кода в приведенных выше фрагментах, и вот где я собираюсь это исправить, используя самый ненавистный из всех средств C / C ++, препроцессор.
  11468.  
  11469. Препроцессор получил действительно плохой рэп. Как и goto, он изображается как анафема для хорошей разработки программного обеспечения. Я понимаю необходимость информировать людей об опасностях, но абсолютам не место в реальности, и я действительно видел несколько хорошо использованных гото в моей жизни. Зная об опасностях инструмента, мы гораздо лучше подготовлены к безопасному обращению с ним. Так что в следующем разделе учтите, что столкновение имен макросов УБИТ ЩЕНКОВ. Имена макросов, которые я использую, никак не конфликтуют с моим кодом, но могут конфликтовать с вашим.
  11470.  
  11471. Я не собираюсь объяснять все тонкости того, что происходит под капотом, потому что мы уже изучали Lua C API в разделах выше. Без лишних слов, вот основной набросок макро-языка макросов для связывания кода C ++ с Lua.
  11472.  
  11473. Вот первый компонент языка, как объявлять функции.
  11474. Код:
  11475. # define Lfunc (NAME) \ int NAME (lua_State * ls) {\ int _stackpos = 1 ; ( Пустоты ) _stackpos; \ bool _opts = true ; ( void ) _opts; \ try {
  11476.  
  11477.  
  11478.  
  11479.  
  11480.  
  11481. Обратите внимание на две переменные: _stackpos и _opts. Мы будем использовать их для извлечения параметров функций из стека. Следующее, что вы заметите, это то, что мы открываем блок try. Если вы хотите, чтобы Lua хорошо работал с разматыванием стека C ++ и обработкой исключений, то вам нужно включить исключения C ++ в luaconf.h и скомпилировать исходники Lua в виде кода C ++. Пока вы это делаете, внимательно посмотрите на luaconf.h, потому что он очень хорошо задокументирован, и вы можете найти там несколько интересных вещей.
  11482.  
  11483. Для передачи данных туда и обратно мы будем использовать удивительную мощь шаблонов. Компилятор определит тип параметров и возвращаемых значений для нас.
  11484. Код:
  11485. шаблон < typename T>
  11486. T parm_get ( lua_State *, int &) ;
  11487.  
  11488. шаблон < typename T>
  11489. T opts_get ( lua_State *, int &, T const &, bool &) ;
  11490.  
  11491. template < typename T>
  11492. int ret_push ( lua_State *, T const &) ;
  11493.  
  11494. //
  11495. // например, bool
  11496. //
  11497. typedef bool Lparm_Lbool;
  11498. шаблон <> bool parm_get ( lua_State * ls,int & stackpos)
  11499. {
  11500. luaL_checktype (ls, stackpos, LUA_TBOOLEAN); вернутьlua_toboolean (ls, stackpos ++); }template<> bool opts_get ( lua_State * ls, int & stackpos, bool const & defaultval, bool & look) {if(look && lua_isboolean (ls, stackpos))вернутьlua_toboolean (ls, stackpos ++); смотреть =ложь; вернутьdefaultval; }template<> int ret_push ( lua_State * ls, bool const & b) {
  11501.  
  11502.  
  11503.  
  11504.  
  11505.  
  11506.  
  11507.  
  11508.  
  11509.  
  11510.  
  11511.  
  11512.  
  11513. lua_pushboolean (ls, b); возврат 1 ; }
  11514.  
  11515.  
  11516.  
  11517. Благодаря специализации шаблонов для вышеуказанных типов, мы можем добавить поддержку любых данных, которые могут быть переведены в значения Lua и из них.
  11518. Код:
  11519. typedef Vec2i Lparm_LVec2i;
  11520. template <> Vec2i parm_get ( lua_State * ls, int & stackpos)
  11521. {
  11522. luaL_checktype (ls, stackpos, LUA_TNUMBER);
  11523. luaL_checktype (ls, stackpos + 1 , LUA_TNUMBER); return
  11524. Vec2i ( lua_tonumber (ls, stackpos ++), lua_tonumber (ls, stackpos ++)); } template <> Vec2i opts_get ( lua_State * ls, int & stackpos, Vec2i const & defaultval, bool & look) { if (look && lua_isnumber (ls, stackpos) && lua_isnumber (ls, stackpos + 1
  11525.  
  11526.  
  11527.  
  11528.  
  11529.  
  11530.  
  11531.  
  11532. )) Возвращают Vec2i ( static_cast < INT > (lua_tointeger (LS, stackpos ++), static_cast < INT > (lua_tointeger (LS, stackpos ++)), смотрите = ложь ; возвращать defaultval; } // ... больше типов здесь ...
  11533.  
  11534.  
  11535.  
  11536.  
  11537.  
  11538.  
  11539.  
  11540.  
  11541.  
  11542. В приведенном выше примере мы берем два целых числа и превращаем их в Vec2i. Мы также можем взять таблицу Lua, содержащую поле core_, и превратить ее в экземпляр класса C ++. Просто будьте осторожны, чтобы параметр stackpos указывал на следующий неиспользуемый элемент стека.
  11543.  
  11544. Мы также предоставляем поддержку необязательных параметров со значениями по умолчанию. Подойдет любой способный к копированию тип C ++, просто обязательно установите для «look» значение false, если параметр отсутствует, чтобы мы прекратили искать дополнительные параметры, которых там нет.
  11545.  
  11546. Теперь посмотрим, как мы используем то, что мы создали, для автоматизации извлечения параметров и возврата значений.
  11547. Код:
  11548. #define Lparm (ТИП, ИМЯ) \
  11549.  Lparm ## _ ## ИМЯ ТИПА = parm_get <Lparm ## _ ## TYPE> (ls, _stackpos); #define Lopts (TYPE, NAME, DEFVAL) \ Lparm ## _ ## TYPE NAME = opts_get <TYPE> (ls, _stackpos, DEFVAL, _opts); #define Lcatch \ } catch (std :: exception const & err) {\ std :: cerr << err.what () << std :: endl; \ } catch (...) {\ std :: cerr << "неизвестное исключение." << endl; \ } #define Lret0 \ Lcatch \ lua_settop (ls, 0 ); \ return 0 ;
  11550.  
  11551.  
  11552.  
  11553.  
  11554.  
  11555.  
  11556.  
  11557.  
  11558.  
  11559.  
  11560.  
  11561.  
  11562.  
  11563.  
  11564.  
  11565.  
  11566.  
  11567.  
  11568.  
  11569. 0 ); \ return ret_push (RET); \ }
  11570.  
  11571.  
  11572.  
  11573. Используя описанные выше typedefs, мы можем безопасно и легко извлечь все нужные параметры и вернуть все, что захотим, без какого-либо явного управления стеками Lua. Просто посмотрите на пример:
  11574. Код:
  11575. Lfunc (MovePointer)
  11576. Lparm (Vec2i, distance)
  11577. Lopts (Lfloat, speed, 1.0 ) const Vec2i pos = Game :: movePointer (distance, speed); Lretv (позы)
  11578.  
  11579.  
  11580.  
  11581.  
  11582.  
  11583. Довольно аккуратно! Мы можем легко получить доступ к переменным расстояния и скорости в нашем теле функции. Используя еще немного магии препроцессора, мы можем расширить наш маленький мини-язык для поддержки классов. Вместо того, чтобы переходить к скучным деталям, я покажу вам, как это выглядит, и, если вам нравится то, что вы видите, вы можете скопировать и вставить реализацию ниже.
  11584. Код:
  11585. Lfunc (Entity_new)
  11586. Linst (Entity)
  11587. Lret1 // Да, есть три (3) подчеркивания Lfunc (Entity ___ gc) luaL_checktype (ls, 1 , LUA_TUSERDATA); Entity * self = (Entity *) lua_touserdata (ls, 1 ); self -> ~ Entity (); Lret0 Lmeth (Entity, get_location) Lretv ( self -> location ()) Lmeth (Entity, move) Lparm (LVec2i, dist) const Vec2i pos = self -> move (dist); Lretv (pos) // Эта функция показывает, как вы можете вручную анализировать таблицу Lua Lmeth (Entity, load_sprite) Lparm (Lstring, идент) if (
  11588.  
  11589.  
  11590.  
  11591.  
  11592.  
  11593.  
  11594.  
  11595.  
  11596.  
  11597.  
  11598.  
  11599.  
  11600.  
  11601.  
  11602.  
  11603.  
  11604.  
  11605.  
  11606.  
  11607.  
  11608. self -> sprite (идент))
  11609. { cerr << "Невозможно загрузить спрайт" " << идентификатор << ", спрайт уже использует этот идентификатор. " << endl; } else { // Извлечение параметра таблицы вручную. luaL_checktype (ls, _stackpos, LUA_TTABLE); векторные <string> текстуры; textures.reserve (lua_objlen (ls, _stackpos)); lua_pushnil (LS); while (lua_next (ls, _stackpos)) { // ключ имеет значение -2, val имеет значение -1 textures.push_back (lua_tostring (ls, - 1 )); lua_pop (ls, 1 ); } auto_ptr <Sprite>
  11610.  
  11611.    
  11612.  
  11613.  
  11614.  
  11615.  
  11616.  
  11617.  
  11618.  
  11619.  
  11620.  
  11621.  
  11622.  
  11623.    
  11624.    
  11625.    
  11626.  
  11627.  
  11628.  
  11629.   for (vector <string> :: iterator i = textures.begin (); i! = textures.end (); ++ i) {
  11630.  sprite-> addFrame (* i); }
  11631. if ( self -> insertSprite (идент. sprite.get ())) sprite.release (); }
  11632. Lret0 Lmeth (Entity, set_sprite) Lparm (Lstring, идент) self -> activSprite (идент ); Lret0 // Определяем интерфейс для Entity Linterface_start (Entity) Linterface (Entity, __gc) Linterface (Entity, move) Linterface (Entity, get_location) Linterface (Entity, load_sprite) Linterface (Entity, set_sprite) Linterface_end void LuaExtate l ( ls) {
  11633.    
  11634.  
  11635.    }int main() {
  11636.  
  11637.     lua_State *L = luaL_newstate();
  11638.     luaL_openlibs(L);
  11639.  
  11640.     /* chunk A */
  11641.     luaL_dostring(L, "local vec2 = {x=3, y=4}\n"
  11642.         "function setup()\n"
  11643.         "return vec2\n"
  11644.         "end\n");
  11645.     /* chunk B */
  11646.     luaL_dostring(L, "function test(p)\n"
  11647.         "print(p.x)\n"
  11648.         "end\n");
  11649.  
  11650.     /* call setup function */
  11651.     int top = lua_gettop(L);
  11652.     lua_getglobal(L, "setup");
  11653.  
  11654.     if (lua_pcall(L, 0, LUA_MULTRET, 0))
  11655.     {
  11656.         std::cout << lua_tostring(L, -1) << '\n';
  11657.         lua_pop(L, 1);
  11658.  
  11659.         exit(EXIT_FAILURE); // simpy fail for demo
  11660.     }
  11661.  
  11662.     /* check the return value */
  11663.     if (lua_gettop(L) - top)
  11664.     {
  11665.         // the top now contains the value returned from setup()
  11666.  
  11667.         /* call test function */
  11668.         lua_getglobal(L, "test");
  11669.  
  11670.         // copy the original value as argument
  11671.         lua_pushvalue(L, -2);
  11672.  
  11673.         if (lua_pcall(L, 1, 0, 0))
  11674.         {
  11675.             std::cout << lua_tostring(L, -1) << '\n';
  11676.             lua_pop(L, 1);
  11677.             exit(EXIT_FAILURE);
  11678.         }
  11679.  
  11680.         // drop the original value
  11681.         lua_pop(L, 1);
  11682.  
  11683.     }
  11684.     else
  11685.     {
  11686.         // nothing is returned, nothing to do
  11687.     }
  11688.     lua_close(L);// закрыть состояние
  11689.     cin.get();//ожидает ввода символа программа завершается.
  11690.  
  11691.     return 0;
  11692. }
  11693.  
  11694.  
  11695. class Foo
  11696. {
  11697. public:
  11698.     Foo(const std::string & name) : name(name)
  11699.     {
  11700.         std::cout << "Foo is born" << std::endl;
  11701.     }
  11702.  
  11703. //  std::string Add(int a, int b)
  11704.     //{
  11705.         //std::stringstream ss;
  11706.         //.ss << name << ": " << a << " + " << b << " = " << (a + b);
  11707.         //return ss.str();
  11708. //  }
  11709.  
  11710.     ~Foo()
  11711.     {
  11712.         std::cout << "Foo is gone" << std::endl;
  11713.     }
  11714.  
  11715. private:
  11716.     std::string name;
  11717. };
  11718.  
  11719. // The general pattern to binding C++ class to Lua is to write a Lua
  11720. // thunk for every method for the class, so here we go:
  11721.  
  11722. int l_Foo_constructor(lua_State * L)
  11723. {
  11724.     const char * name = luaL_checkstring(L, 1);
  11725.  
  11726.     // We could actually allocate Foo itself as a user data but
  11727.     // since user data can be GC'ed and we gain unity by using CRT's heap
  11728.     // all along.
  11729.     Foo ** udata = (Foo **)lua_newuserdata(L, sizeof(Foo *));
  11730.     *udata = new Foo(name);
  11731.  
  11732.     // Usually, we'll just use "Foo" as the second parameter, but I
  11733.     // say luaL_Foo here to distinguish the difference:
  11734.     //
  11735.     // This 2nd parameter here is an _internal label_ for luaL, it is
  11736.     // _not_ exposed to Lua by default.
  11737.     //
  11738.     // Effectively, this metatable is not accessible by Lua by default.
  11739.     luaL_getmetatable(L, "luaL_Foo");
  11740.  
  11741.     // The Lua stack at this point looks like this:
  11742.     //    
  11743.     //     3| metatable "luaL_foo"   |-1
  11744.     //     2| userdata               |-2
  11745.     //     1| string parameter       |-3
  11746.     //
  11747.     // So the following line sets the metatable for the user data to the luaL_Foo
  11748.     // metatable
  11749.     //
  11750.     // We must set the metatable here because Lua prohibits setting
  11751.     // the metatable of a userdata in Lua. The only way to set a metatable
  11752.     // of a userdata is to do it in C.
  11753.     lua_setmetatable(L, -2);
  11754.  
  11755.     // The Lua stack at this point looks like this:
  11756.     //    
  11757.     //     2| userdata               |-1
  11758.     //     1| string parameter       |-2
  11759.     //
  11760.     // We return 1 so Lua callsite will get the user data and
  11761.     // Lua will clean the stack after that.
  11762.  
  11763.     return 1;
  11764. }
  11765.  
  11766. Foo * l_CheckFoo(lua_State * L, int n)
  11767. {
  11768.     // This checks that the argument is a userdata
  11769.     // with the metatable "luaL_Foo"
  11770.     return *(Foo **)luaL_checkudata(L, n, "luaL_Foo");
  11771. }
  11772.  
  11773. int l_Foo_add(lua_State * L)
  11774. {
  11775.     Foo * foo = l_CheckFoo(L, 1);
  11776.     int a = (int)luaL_checknumber(L, 2);
  11777.     int b = (int)luaL_checknumber(L, 3);
  11778.  
  11779.     //std::string s = foo->Add(a, b);
  11780.     //lua_pushstring(L, s.c_str());
  11781.  
  11782.     // The Lua stack at this point looks like this:
  11783.     //    
  11784.     //     4| result string          |-1
  11785.     //     3| metatable "luaL_foo"   |-2
  11786.     //     2| userdata               |-3
  11787.     //     1| string parameter       |-4
  11788.     //
  11789.     // Return 1 to return the result string to Lua callsite.
  11790.  
  11791.     return 1;
  11792. }
  11793.  
  11794. int l_Foo_destructor(lua_State * L)
  11795. {
  11796.     Foo * foo = l_CheckFoo(L, 1);
  11797.     delete foo;
  11798.  
  11799.     return 0;
  11800. }
  11801.  
  11802. void RegisterFoo(lua_State * L)
  11803. {
  11804.     luaL_Reg sFooRegs[] =
  11805.     {
  11806.         { "new", l_Foo_constructor },
  11807.         { "add", l_Foo_add },
  11808.         { "__gc", l_Foo_destructor },
  11809.         { NULL, NULL }
  11810.     };
  11811.  
  11812.     // Create a luaL metatable. This metatable is not
  11813.     // exposed to Lua. The "luaL_Foo" label is used by luaL
  11814.     // internally to identity things.
  11815.     luaL_newmetatable(L, "luaL_Foo");
  11816.  
  11817.     // Register the C functions _into_ the metatable we just created.
  11818.     luaL_setfuncs(L, sFooRegs, 0);
  11819.  
  11820.     // The Lua stack at this point looks like this:
  11821.     //    
  11822.     //     1| metatable "luaL_Foo"   |-1
  11823.     lua_pushvalue(L, -1);
  11824.  
  11825.     // The Lua stack at this point looks like this:
  11826.     //    
  11827.     //     2| metatable "luaL_Foo"   |-1
  11828.     //     1| metatable "luaL_Foo"   |-2
  11829.  
  11830.     // Set the "__index" field of the metatable to point to itself
  11831.     // This pops the stack
  11832.     lua_setfield(L, -1, "__index");
  11833.  
  11834.     // The Lua stack at this point looks like this:
  11835.     //    
  11836.     //     1| metatable "luaL_Foo"   |-1
  11837.  
  11838.     // The luaL_Foo metatable now has the following fields
  11839.     //     - __gc
  11840.     //     - __index
  11841.     //     - add
  11842.     //     - new
  11843.  
  11844.     // Now we use setglobal to officially expose the luaL_Foo metatable
  11845.     // to Lua. And we use the name "Foo".
  11846.     //
  11847.     // This allows Lua scripts to _override_ the metatable of Foo.
  11848.     // For high security code this may not be called for but
  11849.     // we'll do this to get greater flexibility.
  11850.     lua_setglobal(L, "Foo");
  11851. }
  11852. int main(int argc, char *argv[]) {
  11853.     const char* LUA = R"(
  11854. -- to Foo
  11855. function Foo:speak()
  11856.    print("Hello, I am a Foo")
  11857. end
  11858.  
  11859. local foo = Foo.new("fred")
  11860. --local m = foo:add(3, 4)
  11861.  
  11862. -- "fred: 3 + 4 = 7"
  11863. print(m)
  11864.  
  11865. -- "Hello, I am a Foo"
  11866. foo:speak()
  11867.  
  11868. -- Let's rig the original metatable
  11869. Foo.add_ = Foo.add
  11870. --//function Foo:add(a, b)
  11871.  --  return "here comes the magic: " .. self:add_(a, b)
  11872. --end
  11873.  
  11874. --m = foo:add(9, 8)
  11875.  
  11876. -- "here comes the magic: fred: 9 + 8 = 17"
  11877. --print(m)
  11878.   )";
  11879.  
  11880.     lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  11881.     luaL_openlibs(L);
  11882.     RegisterFoo(L);
  11883.     checkerror(L, LUA);
  11884.  
  11885.     lua_pcall(L, 0, 0, 0);// вызвать функцию.
  11886.  
  11887.     lua_close(L);
  11888.  
  11889.     cin.get();//ожидает ввода символа программа завершается.
  11890.     return 0;
  11891. }
  11892.  
  11893.  
  11894. class Foo
  11895. {
  11896. public:
  11897.     Foo(const std::string & name) : name(name)  {
  11898.         std::cout << "Foo create" << std::endl;
  11899.     }
  11900.  
  11901.     ~Foo(){
  11902.         std::cout << "Foo destory" << std::endl;
  11903.     }
  11904.  
  11905. private:
  11906.     std::string name;
  11907. };
  11908.  
  11909. int l_Foo_constructor(lua_State * L){
  11910.     const char * name = luaL_checkstring(L, 1);
  11911.     Foo ** udata = (Foo **)lua_newuserdata(L, sizeof(Foo *));
  11912.     *udata = new Foo(name);
  11913.     luaL_getmetatable(L, "luaL_Foo");
  11914.     lua_setmetatable(L, -2);
  11915.     return 1;
  11916. }
  11917.  
  11918. Foo * l_CheckFoo(lua_State * L, int n){
  11919.     return *(Foo **)luaL_checkudata(L, n, "luaL_Foo");
  11920. }
  11921.  
  11922. int l_Foo_add(lua_State * L){
  11923.     Foo * foo = l_CheckFoo(L, 1);
  11924.     int a = (int)luaL_checknumber(L, 2);
  11925.     int b = (int)luaL_checknumber(L, 3);
  11926.     return 1;
  11927. }
  11928.  
  11929. int l_Foo_destructor(lua_State * L){
  11930.     Foo * foo = l_CheckFoo(L, 1);
  11931.     delete foo;
  11932.     return 0;
  11933. }
  11934.  
  11935. void RegisterFoo(lua_State * L){
  11936.     luaL_Reg sFooRegs[] =
  11937.     {
  11938.         { "new", l_Foo_constructor },
  11939.         { "add", l_Foo_add },
  11940.         { "__gc", l_Foo_destructor },
  11941.         { NULL, NULL }
  11942.     };
  11943.  
  11944.     luaL_newmetatable(L, "luaL_Foo");
  11945.  
  11946.     // Register the C functions _into_ the metatable we just created.
  11947.     luaL_setfuncs(L, sFooRegs, 0);/*    void luaL_setfuncs(lua_State * L, const luaL_Reg * l, int nup);
  11948.     Регистрирует все функции в массиве l(см.luaL_Reg) В таблице на вершине стека(ниже необязательных
  11949.     значений повышений).Когда nupне ноль, все функции создаются с nup общими значениями повышения, которые
  11950.     должны быть предварительно помещены в стек поверх таблицы библиотеки. Эти значения выталкиваются
  11951.     из стека после регистрации.*/
  11952.    
  11953.     lua_pushvalue(L, -1);
  11954.     lua_setfield(L, -1, "__index");
  11955.  
  11956.     lua_setglobal(L, "Foo");
  11957. }
  11958. int main(int argc, char *argv[]) {
  11959.     const char* LUA = R"(
  11960. function Foo:speak()
  11961.    print("Hello, I am a Foo")
  11962. end
  11963.  
  11964. local foo = Foo.new("fred")
  11965. foo:speak()
  11966.   )";
  11967.  
  11968.     lua_State *L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  11969.     luaL_openlibs(L);
  11970.     RegisterFoo(L);
  11971.     checkerror(L, LUA);
  11972.  
  11973.     lua_pcall(L, 0, 0, 0);// вызвать функцию.
  11974.  
  11975.     lua_close(L);
  11976.  
  11977.     cin.get();//ожидает ввода символа программа завершается.
  11978.     return 0;
  11979. }
  11980.  
  11981.  
  11982.  
  11983. void search(string res, vector<lua_State*>&luastate) {
  11984.     lua_State* L = luaL_newstate();/*Функция создает новое Lua состояние. Она вызывает lua_newstate с функцией-*/
  11985.     luaL_openlibs(L);
  11986.  
  11987.     cout << "adres " << L << endl; //||!!!тут вы брали адрес указателя, поэтому он был всегда одинаковым
  11988.     luastate.push_back(L);// !!! вот так
  11989.     int status = luaL_loadfile(L, res.c_str());// проверка есть ли ошибки.
  11990.     if (status == 0) {// если нет ошибки в файле.
  11991.         //luaL_dofile(L, res.c_str());// запуск файла.
  11992.         lua_pcall(L, 0, 0, 0);
  11993.         lua_getglobal(L, "main");// получаем из lua функцию pri.
  11994.         lua_pcall(L, 0, 0, 0);
  11995.         string load = "loaded ";
  11996.         string er0 = load + res;
  11997.         writelog(er0.c_str());
  11998.     }//.
  11999.     else {
  12000.         string er1 = lua_tostring(L, -1);
  12001.         string er = "could not load ";
  12002.         string er0 = er + er1;
  12003.         writelog(er0.c_str()); //!!! writelog должен быть объявлен принимающим const char * (если вдруг он у вас просто char *)
  12004.     }
  12005. };
  12006. int main(int argc, char* argv[]) {
  12007.  
  12008.  vector<lua_State*>luastate;
  12009.   vector<thread>t;
  12010.     for (auto const& de : fs::recursive_directory_iterator{ fs::current_path() / "lualoader" }) { // папка для поиска
  12011.  
  12012.         if (de.path().extension() == ".lua" || de.path().extension() == ".LUA") {
  12013.             string res = de.path().string();// имя в файла в строку
  12014.             t.push_back(move((std::thread(search, res, std::ref(luastate)))));
  12015.         }
  12016.     };    
  12017.     for (auto& i : t)
  12018.     {
  12019.         i.detach();
  12020.  
  12021.     };
  12022.     cin.get();
  12023. for (auto L : luastate) {
  12024.         cout << &L << endl;
  12025. lua_close(L);
  12026.     }
  12027.     return 0;
  12028.    
  12029.  
  12030. };
  12031.  
  12032.  
  12033. Записать элемента стек в файл.
  12034.  
  12035. void showstack1(lua_State* L) {
  12036.     int i = lua_gettop(L);/* получаем количество элементов в стеке.*/
  12037.     string path = "stack.txt";
  12038.     fstream f1; {f1.open(path, fstream::in | fstream::out | fstream::app);
  12039.     int j = (i) * -1 - 1;
  12040.     i = -1;
  12041.     for (i; i > j; i--) {
  12042.         int t = lua_type(L, i);
  12043.         if (LUA_TSTRING == t) {
  12044.             f1 << "str ";
  12045.              f1 << i; f1 << "\n";
  12046.         }
  12047.         if (LUA_TNUMBER == t) {
  12048.             f1 << "number ";
  12049.             f1 << i; f1 << "\n";        }
  12050.        
  12051.         if (LUA_TBOOLEAN == t) {
  12052.             f1 << "LUA_TBOOLEAN ";
  12053.             f1 << i; f1 << "\n";    }
  12054.         if (LUA_TLIGHTUSERDATA == t) {
  12055.             f1 << "LIGHTUSERDATA ";
  12056.             f1 << i; f1 << "\n";
  12057.         }
  12058.         if (LUA_TTABLE == t) { 
  12059.         f1 << "LUA_TTABLE ";
  12060.         f1 << i; f1 << "\n";
  12061.         }
  12062.         if (LUA_TFUNCTION == t) {
  12063.  
  12064.             f1 << "funs ";
  12065.             f1 << i; f1 << "\n";
  12066.         }
  12067.         if (LUA_TUSERDATA == t) {
  12068.             f1 << "user ";
  12069.             f1 << i; f1 << "\n";
  12070.         }
  12071.         if (LUA_TTHREAD == t) {
  12072.             cout << "LUA_TTHREAD " << endl;
  12073.         }
  12074.         if (LUA_TNIL == t) {
  12075.             cout << "LUA_TNIL " << endl;
  12076.         }
  12077.     }
  12078.     f1.close(); }
  12079. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement