├── res ├── img │ └── img.jpg └── shaders │ ├── frag.shader │ ├── vert.shader │ └── compute.shader ├── 3rdlibs ├── sol │ ├── CMakeLists.txt │ └── sol │ │ └── config.hpp ├── glad │ └── CMakeLists.txt └── lua │ ├── CMakeLists.txt │ ├── include │ ├── lundump.h │ ├── lprefix.h │ ├── lualib.h │ ├── lapi.h │ ├── lopnames.h │ ├── lzio.h │ ├── lstring.h │ ├── lfunc.h │ ├── ljumptab.h │ ├── ldebug.h │ ├── ltable.h │ ├── lctype.h │ ├── llex.h │ ├── ldo.h │ ├── ltm.h │ ├── lmem.h │ ├── ltests.h │ ├── lcode.h │ ├── lvm.h │ ├── lparser.h │ └── lgc.h │ └── src │ ├── lzio.c │ ├── linit.c │ ├── onelua.c │ ├── lctype.c │ ├── lopcodes.c │ ├── lcorolib.c │ ├── ldump.c │ ├── lmem.c │ ├── lstring.c │ ├── lutf8lib.c │ └── ltm.c ├── .gitmodules ├── .gitignore ├── CMakeLists.txt ├── bins ├── log.cpp ├── sparse_sets.cpp ├── expected.cpp ├── cgmath_benchmark.cpp ├── net_echo_client.cpp ├── benchmark.cpp ├── tweeny.cpp ├── CMakeLists.txt ├── net_echo_server.cpp ├── renderer2d.cpp ├── fp.cpp ├── ecs.cpp ├── gogl_compute.cpp ├── luabind.cpp ├── gogl_triangle.cpp ├── refl.cpp ├── serialize.cpp └── cgmath_test.cpp ├── .github └── workflows │ └── cmake.yml ├── ppm.hpp ├── ReadMe.md ├── sparse_sets.hpp ├── tweeny.hpp ├── log.hpp ├── benchmark.hpp ├── serialize.hpp ├── luabind.hpp └── expected.hpp /res/img/img.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VisualGMQ/gmq_header/HEAD/res/img/img.jpg -------------------------------------------------------------------------------- /3rdlibs/sol/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(sol2 INTERFACE) 2 | target_include_directories(sol2 INTERFACE ./) -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "3rdlibs/glfw"] 2 | path = 3rdlibs/glfw 3 | url = https://github.com/glfw/glfw.git -------------------------------------------------------------------------------- /3rdlibs/glad/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(glad STATIC "./src/glad.c") 2 | target_include_directories(glad PUBLIC "./include") -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | cmake-build 3 | .vscode 4 | compile_flags.txt 5 | clang-build 6 | .cache 7 | .clang-format 8 | compile_commands.json -------------------------------------------------------------------------------- /res/shaders/frag.shader: -------------------------------------------------------------------------------- 1 | #version 410 core 2 | 3 | out vec4 FragColor; 4 | in vec2 outColor; 5 | in vec2 outTexcoord; 6 | 7 | uniform sampler2D image; 8 | 9 | void main() { 10 | FragColor = texture(image, outTexcoord) * vec4(outColor, 0, 1); 11 | } -------------------------------------------------------------------------------- /res/shaders/vert.shader: -------------------------------------------------------------------------------- 1 | #version 410 core 2 | 3 | layout (location = 0) in vec3 aPos; 4 | layout (location = 1) in vec2 aColor; 5 | layout (location = 2) in vec2 aTexcoord; 6 | 7 | out vec2 outColor; 8 | out vec2 outTexcoord; 9 | 10 | void main() { 11 | outColor = aColor; 12 | outTexcoord = aTexcoord; 13 | gl_Position = vec4(aPos, 1.0); 14 | } 15 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.20) 2 | 3 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 4 | 5 | project( 6 | GMQ-Headers 7 | LANGUAGES CXX 8 | ) 9 | 10 | add_subdirectory(3rdlibs/sol) 11 | add_subdirectory(3rdlibs/lua) 12 | 13 | 14 | enable_testing() 15 | add_subdirectory(3rdlibs/glfw) 16 | add_subdirectory(3rdlibs/glad) 17 | add_subdirectory(bins) 18 | -------------------------------------------------------------------------------- /res/shaders/compute.shader: -------------------------------------------------------------------------------- 1 | #version 430 2 | 3 | layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; 4 | 5 | layout(std430, binding = 0) buffer InputBufferA { 6 | float A[]; 7 | }; 8 | 9 | layout(std430, binding = 1) buffer InputBufferB { 10 | float B[]; 11 | }; 12 | 13 | layout(std430, binding = 2) buffer OutputBuffer { 14 | float C[]; 15 | }; 16 | 17 | void main() { 18 | uint index = gl_GlobalInvocationID.x; 19 | if (index < 256) { 20 | C[index] = A[index] + B[index]; 21 | } 22 | } -------------------------------------------------------------------------------- /bins/log.cpp: -------------------------------------------------------------------------------- 1 | #include "log.hpp" 2 | 3 | int main() { 4 | // a quick way to log 5 | LOGI("hello ", "world", " this is logi ", 123); 6 | 7 | // create your own logger and log 8 | auto& log = logger::LoggerMgr::Instance().GetDefault(); 9 | LOGI("info"); 10 | LOGI("trace"); 11 | 12 | log.SetLevel(logger::Debug); 13 | // this will not output 14 | LOGI("info after set level to debug"); 15 | // this will output 16 | LOGD("debug after set level to debug"); 17 | LOGW("warning after set level to debug"); 18 | 19 | return 0; 20 | } -------------------------------------------------------------------------------- /bins/sparse_sets.cpp: -------------------------------------------------------------------------------- 1 | #include "sparse_sets.hpp" 2 | 3 | int main() { 4 | SparseSets set; 5 | 6 | set.Add(1); 7 | set.Add(6); 8 | set.Add(9); 9 | set.Add(2); 10 | set.Add(13); 11 | 12 | assert(set.Contain(1)); 13 | assert(set.Contain(6)); 14 | assert(set.Contain(9)); 15 | assert(set.Contain(2)); 16 | assert(set.Contain(13)); 17 | assert(!set.Contain(0)); 18 | assert(!set.Contain(15)); 19 | assert(!set.Contain(10)); 20 | assert(!set.Contain(7)); 21 | 22 | set.Remove(2); 23 | set.Remove(0); 24 | set.Remove(9); 25 | assert(!set.Contain(2)); 26 | assert(!set.Contain(9)); 27 | 28 | set.Remove(13); 29 | assert(!set.Contain(13)); 30 | } -------------------------------------------------------------------------------- /bins/expected.cpp: -------------------------------------------------------------------------------- 1 | #include "expected.hpp" 2 | 3 | #define CATCH_CONFIG_MAIN 4 | #include "3rdlibs/catch.hpp" 5 | 6 | #include 7 | 8 | gmq::expected doSomethingFailed() { 9 | return gmq::unexpected(-1); 10 | } 11 | 12 | gmq::expected doSomethingOk() { 13 | return gmq::expected(); 14 | } 15 | 16 | 17 | TEST_CASE("expected test", "[expected]") { 18 | gmq::unexpected e(123); 19 | REQUIRE(e.error() == 123); 20 | 21 | auto expected = doSomethingFailed(); 22 | REQUIRE_FALSE(expected.has_value()); 23 | REQUIRE(expected.error() == -1); 24 | 25 | expected = doSomethingOk(); 26 | REQUIRE(expected.has_value()); 27 | 28 | gmq::expected e2(123); 29 | REQUIRE(e2); 30 | REQUIRE(e2.value() == 123); 31 | 32 | e2 = gmq::unexpected(456.0f); 33 | REQUIRE(!e2); 34 | REQUIRE(e2.error() == 456.0f); 35 | } 36 | -------------------------------------------------------------------------------- /3rdlibs/lua/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(lua 2 | VERSION 5.4.4) 3 | 4 | set(LUA_LIB_SRC 5 | src/lapi.c 6 | src/lcode.c 7 | src/lctype.c 8 | src/ldebug.c 9 | src/ldo.c 10 | src/ldump.c 11 | src/lfunc.c 12 | src/lgc.c 13 | src/llex.c 14 | src/lmem.c 15 | src/lobject.c 16 | src/lopcodes.c 17 | src/lparser.c 18 | src/lstate.c 19 | src/lstring.c 20 | src/ltable.c 21 | src/ltm.c 22 | src/lundump.c 23 | src/lvm.c 24 | src/lzio.c 25 | src/ltests.c 26 | src/lauxlib.c 27 | src/lbaselib.c 28 | src/ldblib.c 29 | src/liolib.c 30 | src/lmathlib.c 31 | src/loslib.c 32 | src/ltablib.c 33 | src/lstrlib.c 34 | src/lutf8lib.c 35 | src/loadlib.c 36 | src/lcorolib.c 37 | src/linit.c 38 | ) 39 | 40 | add_library(lua STATIC ${LUA_LIB_SRC}) 41 | target_compile_features(lua PRIVATE c_std_99) 42 | target_include_directories(lua PUBLIC include) -------------------------------------------------------------------------------- /bins/cgmath_benchmark.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 VisualGMQ 2 | #include 3 | 4 | #define CGMATH_NUMERIC_TYPE double 5 | #include "cgmath.hpp" 6 | 7 | #define BENCHMARK_REPEAT_NUM 10000000 8 | #include "benchmark.hpp" 9 | 10 | void SimpleAdd(benchmark::Measure measure) { 11 | cgmath::Vec4 vec1{1, 2, 3, 4}; 12 | cgmath::Vec4 vec2{5, 6, 7, 8}; 13 | 14 | measure([&](){ 15 | auto v = vec1 + vec2; 16 | }); 17 | } 18 | 19 | void SimpleDot(benchmark::Measure measure) { 20 | cgmath::Vec4 vec1{1, 2, 3, 4}; 21 | cgmath::Vec4 vec2{5, 6, 7, 8}; 22 | 23 | measure([&](){ 24 | auto v = vec1.Dot(vec2); 25 | }); 26 | } 27 | 28 | BENCHMARK_MAIN { 29 | BENCHMARK_GROUP("add benchmark") { 30 | BENCHMARK_ADD("simple", SimpleAdd); 31 | } 32 | 33 | BENCHMARK_GROUP("dot benchmark") { 34 | BENCHMARK_ADD("simple", SimpleDot); 35 | } 36 | 37 | BENCHMARK_RUN(); 38 | } 39 | -------------------------------------------------------------------------------- /3rdlibs/lua/include/lundump.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.h $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lundump_h 8 | #define lundump_h 9 | 10 | #include "llimits.h" 11 | #include "lobject.h" 12 | #include "lzio.h" 13 | 14 | 15 | /* data to catch conversion errors */ 16 | #define LUAC_DATA "\x19\x93\r\n\x1a\n" 17 | 18 | #define LUAC_INT 0x5678 19 | #define LUAC_NUM cast_num(370.5) 20 | 21 | /* 22 | ** Encode major-minor version in one byte, one nibble for each 23 | */ 24 | #define MYINT(s) (s[0]-'0') /* assume one-digit numerals */ 25 | #define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)) 26 | 27 | #define LUAC_FORMAT 0 /* this is the official format */ 28 | 29 | /* load one chunk; from lundump.c */ 30 | LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name); 31 | 32 | /* dump one chunk; from ldump.c */ 33 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, 34 | void* data, int strip); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /bins/net_echo_client.cpp: -------------------------------------------------------------------------------- 1 | #define NET_IMPLEMENTATION 2 | #include "net.hpp" 3 | 4 | constexpr uint16_t PORT = 8080; 5 | 6 | int main() { 7 | auto netInstance = net::Init(); 8 | auto result = net::AddrInfoBuilder::CreateTCP("localhost", PORT).Build(); 9 | if (result.result != 0) { 10 | std::cerr << "create TCP addrinfo failed: " << net::GetLastError() << std::endl; 11 | } 12 | 13 | auto socket = netInstance->CreateSocket(result.value); 14 | socket->Bind(); 15 | 16 | std::cout << "connecting..." << std::endl; 17 | socket->Connect(); 18 | 19 | std::cout << "connected, send 'quit' to close connect" << std::endl; 20 | 21 | int iResult = 0; 22 | char buf[1024] = {0}; 23 | do { 24 | std::cin >> buf; 25 | iResult = socket->Send(buf, strlen(buf) + 1); 26 | std::cout << "send: " << iResult << std::endl; 27 | if (iResult == 0) { 28 | std::cout << "server closed" << std::endl; 29 | } 30 | } while (iResult > 0); 31 | 32 | return 0; 33 | } -------------------------------------------------------------------------------- /3rdlibs/lua/include/lprefix.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lprefix.h $ 3 | ** Definitions for Lua code that must come before any other header file 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lprefix_h 8 | #define lprefix_h 9 | 10 | 11 | /* 12 | ** Allows POSIX/XSI stuff 13 | */ 14 | #if !defined(LUA_USE_C89) /* { */ 15 | 16 | #if !defined(_XOPEN_SOURCE) 17 | #define _XOPEN_SOURCE 600 18 | #elif _XOPEN_SOURCE == 0 19 | #undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */ 20 | #endif 21 | 22 | /* 23 | ** Allows manipulation of large files in gcc and some other compilers 24 | */ 25 | #if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS) 26 | #define _LARGEFILE_SOURCE 1 27 | #define _FILE_OFFSET_BITS 64 28 | #endif 29 | 30 | #endif /* } */ 31 | 32 | 33 | /* 34 | ** Windows stuff 35 | */ 36 | #if defined(_WIN32) /* { */ 37 | 38 | #if !defined(_CRT_SECURE_NO_WARNINGS) 39 | #define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ 40 | #endif 41 | 42 | #endif /* } */ 43 | 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /bins/benchmark.cpp: -------------------------------------------------------------------------------- 1 | #define BENCHMARK_REPEAT_NUM 1 2 | #include "benchmark.hpp" 3 | #include 4 | 5 | void Delay2s() { 6 | std::this_thread::sleep_for(std::chrono::seconds(2)); 7 | } 8 | 9 | void Delay1s() { 10 | std::this_thread::sleep_for(std::chrono::seconds(1)); 11 | } 12 | 13 | void use_measure(benchmark::Measure measure) { 14 | // some prepare 15 | measure([]{ 16 | // your func 17 | }); 18 | // some end 19 | } 20 | 21 | BENCHMARK_MAIN { 22 | BENCHMARK_GROUP("group1") { 23 | BENCHMARK_ADD("Delay1s", Delay1s); 24 | BENCHMARK_ADD("Delay2s", Delay2s); 25 | } 26 | BENCHMARK_GROUP("group2") { 27 | BENCHMARK_ADD("use_measure", use_measure); 28 | } 29 | 30 | /* 31 | run some groups: 32 | BENCHMARK_RUN_GROUPS("group1", "group2"); 33 | */ 34 | /* 35 | run all groups(you can't point out which group in cmd parameter): 36 | BENCHMARK_RUN_ALL(); 37 | */ 38 | /* 39 | run groups, you can send group names in cmdline. Eg: 40 | ./benchmark group1 41 | */ 42 | BENCHMARK_RUN(); 43 | } -------------------------------------------------------------------------------- /bins/tweeny.cpp: -------------------------------------------------------------------------------- 1 | #include "tweeny.hpp" 2 | 3 | #define CATCH_CONFIG_MAIN 4 | #include "3rdlibs/catch.hpp" 5 | 6 | TEST_CASE("tweeny", "[tweeny]") { 7 | tweeny::Tween tween = tweeny::Tween::From(0).To(100).During(4) 8 | .To(300).During(2); 9 | REQUIRE(tween.Direction() == tweeny::TweenyDirection::Forward); 10 | REQUIRE(tween.CurTick() == 0.0); 11 | REQUIRE(tween.CurValue() == 0.0); 12 | tween.Step(1); 13 | REQUIRE(tween.CurTick() == 1.0); 14 | REQUIRE(tween.CurValue() == 25.0); 15 | tween.Step(1); 16 | REQUIRE(tween.CurTick() == 2.0); 17 | REQUIRE(tween.CurValue() == 50.0); 18 | tween.Step(1); 19 | REQUIRE(tween.CurTick() == 3.0); 20 | REQUIRE(tween.CurValue() == 75.0); 21 | tween.Step(1); 22 | REQUIRE(tween.CurTick() == 4.0); 23 | REQUIRE(tween.CurValue() == 100.0); 24 | tween.Step(1); 25 | REQUIRE(tween.CurTick() == 5.0); 26 | REQUIRE(tween.CurValue() == 200.0); 27 | tween.Step(1); 28 | REQUIRE(tween.CurTick() == 6.0); 29 | REQUIRE(tween.CurValue() == 300.0); 30 | tween.Step(1); 31 | REQUIRE(tween.CurTick() == 6.0); 32 | REQUIRE(tween.CurValue() == 300.0); 33 | } 34 | 35 | 36 | -------------------------------------------------------------------------------- /bins/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | macro(AddExample NAME) 2 | add_executable(${NAME} ${NAME}.cpp) 3 | target_include_directories(${NAME} PRIVATE ../) 4 | target_compile_features(${NAME} PRIVATE cxx_std_17) 5 | endmacro(AddExample) 6 | 7 | macro(AddTest NAME) 8 | add_executable(${NAME} ${NAME}.cpp) 9 | target_include_directories(${NAME} PRIVATE ../) 10 | target_compile_features(${NAME} PRIVATE cxx_std_17) 11 | add_test(NAME "${NAME}_test" 12 | COMMAND $) 13 | endmacro() 14 | 15 | AddExample(benchmark) 16 | AddExample(log) 17 | AddTest(cgmath_test) 18 | AddExample(cgmath_benchmark) 19 | AddExample(expected) 20 | AddExample(ecs) 21 | AddExample(sparse_sets) 22 | AddTest(fp) 23 | AddTest(refl) 24 | AddTest(luabind) 25 | AddTest(serialize) 26 | AddTest(tweeny) 27 | target_link_libraries(luabind PRIVATE sol2 lua) 28 | target_link_libraries(serialize PRIVATE sol2 lua) 29 | 30 | if (WIN32) 31 | AddExample(net_echo_client) 32 | AddExample(net_echo_server) 33 | endif() 34 | 35 | AddExample(gogl_triangle) 36 | target_link_libraries(gogl_triangle PRIVATE glad glfw) 37 | 38 | AddExample(gogl_compute) 39 | target_link_libraries(gogl_compute PRIVATE glad glfw) 40 | 41 | AddExample(renderer2d) 42 | target_link_libraries(renderer2d PRIVATE glad glfw) -------------------------------------------------------------------------------- /3rdlibs/lua/include/lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lualib.h $ 3 | ** Lua standard libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lualib_h 9 | #define lualib_h 10 | 11 | #include "lua.h" 12 | 13 | 14 | /* version suffix for environment variable names */ 15 | #define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR 16 | 17 | 18 | LUAMOD_API int (luaopen_base) (lua_State *L); 19 | 20 | #define LUA_COLIBNAME "coroutine" 21 | LUAMOD_API int (luaopen_coroutine) (lua_State *L); 22 | 23 | #define LUA_TABLIBNAME "table" 24 | LUAMOD_API int (luaopen_table) (lua_State *L); 25 | 26 | #define LUA_IOLIBNAME "io" 27 | LUAMOD_API int (luaopen_io) (lua_State *L); 28 | 29 | #define LUA_OSLIBNAME "os" 30 | LUAMOD_API int (luaopen_os) (lua_State *L); 31 | 32 | #define LUA_STRLIBNAME "string" 33 | LUAMOD_API int (luaopen_string) (lua_State *L); 34 | 35 | #define LUA_UTF8LIBNAME "utf8" 36 | LUAMOD_API int (luaopen_utf8) (lua_State *L); 37 | 38 | #define LUA_MATHLIBNAME "math" 39 | LUAMOD_API int (luaopen_math) (lua_State *L); 40 | 41 | #define LUA_DBLIBNAME "debug" 42 | LUAMOD_API int (luaopen_debug) (lua_State *L); 43 | 44 | #define LUA_LOADLIBNAME "package" 45 | LUAMOD_API int (luaopen_package) (lua_State *L); 46 | 47 | 48 | /* open all previous libraries */ 49 | LUALIB_API void (luaL_openlibs) (lua_State *L); 50 | 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /bins/net_echo_server.cpp: -------------------------------------------------------------------------------- 1 | #define NET_IMPLEMENTATION 2 | #include "net.hpp" 3 | 4 | constexpr uint16_t PORT = 8080; 5 | 6 | int main() { 7 | auto netInstance = net::Init(); 8 | auto result = net::AddrInfoBuilder::CreateTCP("localhost", PORT).Build(); 9 | if (result.result != 0) { 10 | std::cerr << "create TCP addrinfo failed: " << net::GetLastError() << std::endl; 11 | } 12 | 13 | auto socket = netInstance->CreateSocket(result.value); 14 | socket->Bind(); 15 | socket->Listen(SOMAXCONN); 16 | std::cout << "listening..." << std::endl; 17 | 18 | int iResult = 0; 19 | char buf[1024] = {0}; 20 | net::Result> acceptResult = socket->Accept(); 21 | if (acceptResult.result != 0) { 22 | iResult = -1; 23 | } 24 | 25 | std::cout << "accepted" << std::endl; 26 | 27 | do { 28 | auto& clientSocket = acceptResult.value; 29 | 30 | iResult = clientSocket->Recv(buf, sizeof(buf)); 31 | std::cout << "recived: " << iResult << std::endl; 32 | if (iResult == 0) { 33 | std::cout << "client closed" << std::endl; 34 | } else if (iResult > 0) { 35 | std::cout << "recived: " << buf << std::endl; 36 | if (strcmp(buf, "quit") == 0) { 37 | iResult = -1; 38 | } 39 | } 40 | } while (iResult > 0); 41 | 42 | return 0; 43 | } -------------------------------------------------------------------------------- /.github/workflows/cmake.yml: -------------------------------------------------------------------------------- 1 | name: CMake 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | env: 10 | # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) 11 | BUILD_TYPE: Release 12 | 13 | jobs: 14 | build: 15 | # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. 16 | # You can convert this to a matrix build if you need cross-platform coverage. 17 | # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix 18 | runs-on: ubuntu-latest 19 | 20 | steps: 21 | - uses: actions/checkout@v3 22 | 23 | - name: Upate Apt 24 | run: sudo apt update 25 | 26 | - name: Upgrade Apt 27 | run: sudo apt upgrade 28 | 29 | - name: Install CMake 30 | run: sudo apt install cmake git 31 | 32 | - name: Depedency Install 33 | run: sudo apt install xorg-dev 34 | 35 | - name: Pull submodules recursively 36 | run: git submodule update --init --recursive 37 | 38 | - name: Configure CMake 39 | run: cmake -S ${{github.workspace}} -B ${{github.workspace}}/cmake-build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} 40 | 41 | - name: Build 42 | # Build your program with the given configuration 43 | run: cmake --build ${{github.workspace}}/cmake-build --config ${{env.BUILD_TYPE}} 44 | 45 | - name: Test 46 | working-directory: ${{github.workspace}}/cmake-build 47 | run: ctest -C ${{env.BUILD_TYPE}} 48 | 49 | -------------------------------------------------------------------------------- /ppm.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | struct Color final { 10 | float r, g, b; 11 | }; 12 | 13 | class PPM final { 14 | public: 15 | PPM(unsigned int w, unsigned int h): w_(w), h_(h) { 16 | data_.resize(w * h, Color{0, 0, 0}); 17 | } 18 | 19 | void Set(const Color& c, int x, int y) { 20 | assert(x >= 0 && y >= 0); 21 | data_.at(x + y * w_) = c; 22 | } 23 | 24 | auto W() const { 25 | return w_; 26 | } 27 | 28 | auto H() const { 29 | return h_; 30 | } 31 | 32 | void Fill(const Color& color) { 33 | data_.assign(w_ * h_, color); 34 | } 35 | 36 | void Save(std::string_view filename) { 37 | std::ofstream file(filename.data()); 38 | if (file.fail()) { 39 | throw std::runtime_error("open file failed"); 40 | } 41 | 42 | file << "P3" << std::endl 43 | << W() << " " << H() << std::endl 44 | << "255" << std::endl; 45 | 46 | for (int y = 0; y < H(); y++) { 47 | for (int x = 0; x < W(); x++) { 48 | auto& color = data_.at(x + y * W()); 49 | file << int(color.r * 255) << " " << int(color.g * 255) << " " << int(color.b * 255) << " "; 50 | } 51 | file << std::endl; 52 | } 53 | } 54 | 55 | private: 56 | std::vector data_; 57 | unsigned int w_; 58 | unsigned int h_; 59 | }; 60 | -------------------------------------------------------------------------------- /3rdlibs/lua/include/lapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lapi.h $ 3 | ** Auxiliary functions from Lua API 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lapi_h 8 | #define lapi_h 9 | 10 | 11 | #include "llimits.h" 12 | #include "lstate.h" 13 | 14 | 15 | /* Increments 'L->top', checking for stack overflows */ 16 | #define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ 17 | "stack overflow");} 18 | 19 | 20 | /* 21 | ** If a call returns too many multiple returns, the callee may not have 22 | ** stack space to accommodate all results. In this case, this macro 23 | ** increases its stack space ('L->ci->top'). 24 | */ 25 | #define adjustresults(L,nres) \ 26 | { if ((nres) <= LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } 27 | 28 | 29 | /* Ensure the stack has at least 'n' elements */ 30 | #define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ 31 | "not enough elements in the stack") 32 | 33 | 34 | /* 35 | ** To reduce the overhead of returning from C functions, the presence of 36 | ** to-be-closed variables in these functions is coded in the CallInfo's 37 | ** field 'nresults', in a way that functions with no to-be-closed variables 38 | ** with zero, one, or "all" wanted results have no overhead. Functions 39 | ** with other number of wanted results, as well as functions with 40 | ** variables to be closed, have an extra check. 41 | */ 42 | 43 | #define hastocloseCfunc(n) ((n) < LUA_MULTRET) 44 | 45 | /* Map [-1, inf) (range of 'nresults') into (-inf, -2] */ 46 | #define codeNresults(n) (-(n) - 3) 47 | #define decodeNresults(n) (-(n) - 3) 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /3rdlibs/lua/src/lzio.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.c $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lzio_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "llimits.h" 18 | #include "lmem.h" 19 | #include "lstate.h" 20 | #include "lzio.h" 21 | 22 | 23 | int luaZ_fill (ZIO *z) { 24 | size_t size; 25 | lua_State *L = z->L; 26 | const char *buff; 27 | lua_unlock(L); 28 | buff = z->reader(L, z->data, &size); 29 | lua_lock(L); 30 | if (buff == NULL || size == 0) 31 | return EOZ; 32 | z->n = size - 1; /* discount char being returned */ 33 | z->p = buff; 34 | return cast_uchar(*(z->p++)); 35 | } 36 | 37 | 38 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { 39 | z->L = L; 40 | z->reader = reader; 41 | z->data = data; 42 | z->n = 0; 43 | z->p = NULL; 44 | } 45 | 46 | 47 | /* --------------------------------------------------------------- read --- */ 48 | size_t luaZ_read (ZIO *z, void *b, size_t n) { 49 | while (n) { 50 | size_t m; 51 | if (z->n == 0) { /* no bytes in buffer? */ 52 | if (luaZ_fill(z) == EOZ) /* try to read more */ 53 | return n; /* no more input; return number of missing bytes */ 54 | else { 55 | z->n++; /* luaZ_fill consumed first byte; put it back */ 56 | z->p--; 57 | } 58 | } 59 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ 60 | memcpy(b, z->p, m); 61 | z->n -= m; 62 | z->p += m; 63 | b = (char *)b + m; 64 | n -= m; 65 | } 66 | return 0; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /3rdlibs/lua/include/lopnames.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopnames.h $ 3 | ** Opcode names 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #if !defined(lopnames_h) 8 | #define lopnames_h 9 | 10 | #include 11 | 12 | 13 | /* ORDER OP */ 14 | 15 | static const char *const opnames[] = { 16 | "MOVE", 17 | "LOADI", 18 | "LOADF", 19 | "LOADK", 20 | "LOADKX", 21 | "LOADFALSE", 22 | "LFALSESKIP", 23 | "LOADTRUE", 24 | "LOADNIL", 25 | "GETUPVAL", 26 | "SETUPVAL", 27 | "GETTABUP", 28 | "GETTABLE", 29 | "GETI", 30 | "GETFIELD", 31 | "SETTABUP", 32 | "SETTABLE", 33 | "SETI", 34 | "SETFIELD", 35 | "NEWTABLE", 36 | "SELF", 37 | "ADDI", 38 | "ADDK", 39 | "SUBK", 40 | "MULK", 41 | "MODK", 42 | "POWK", 43 | "DIVK", 44 | "IDIVK", 45 | "BANDK", 46 | "BORK", 47 | "BXORK", 48 | "SHRI", 49 | "SHLI", 50 | "ADD", 51 | "SUB", 52 | "MUL", 53 | "MOD", 54 | "POW", 55 | "DIV", 56 | "IDIV", 57 | "BAND", 58 | "BOR", 59 | "BXOR", 60 | "SHL", 61 | "SHR", 62 | "MMBIN", 63 | "MMBINI", 64 | "MMBINK", 65 | "UNM", 66 | "BNOT", 67 | "NOT", 68 | "LEN", 69 | "CONCAT", 70 | "CLOSE", 71 | "TBC", 72 | "JMP", 73 | "EQ", 74 | "LT", 75 | "LE", 76 | "EQK", 77 | "EQI", 78 | "LTI", 79 | "LEI", 80 | "GTI", 81 | "GEI", 82 | "TEST", 83 | "TESTSET", 84 | "CALL", 85 | "TAILCALL", 86 | "RETURN", 87 | "RETURN0", 88 | "RETURN1", 89 | "FORLOOP", 90 | "FORPREP", 91 | "TFORPREP", 92 | "TFORCALL", 93 | "TFORLOOP", 94 | "SETLIST", 95 | "CLOSURE", 96 | "VARARG", 97 | "VARARGPREP", 98 | "EXTRAARG", 99 | NULL 100 | }; 101 | 102 | #endif 103 | 104 | -------------------------------------------------------------------------------- /3rdlibs/lua/include/lzio.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.h $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lzio_h 9 | #define lzio_h 10 | 11 | #include "lua.h" 12 | 13 | #include "lmem.h" 14 | 15 | 16 | #define EOZ (-1) /* end of stream */ 17 | 18 | typedef struct Zio ZIO; 19 | 20 | #define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z)) 21 | 22 | 23 | typedef struct Mbuffer { 24 | char *buffer; 25 | size_t n; 26 | size_t buffsize; 27 | } Mbuffer; 28 | 29 | #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) 30 | 31 | #define luaZ_buffer(buff) ((buff)->buffer) 32 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) 33 | #define luaZ_bufflen(buff) ((buff)->n) 34 | 35 | #define luaZ_buffremove(buff,i) ((buff)->n -= (i)) 36 | #define luaZ_resetbuffer(buff) ((buff)->n = 0) 37 | 38 | 39 | #define luaZ_resizebuffer(L, buff, size) \ 40 | ((buff)->buffer = luaM_reallocvchar(L, (buff)->buffer, \ 41 | (buff)->buffsize, size), \ 42 | (buff)->buffsize = size) 43 | 44 | #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) 45 | 46 | 47 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, 48 | void *data); 49 | LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */ 50 | 51 | 52 | 53 | /* --------- Private Part ------------------ */ 54 | 55 | struct Zio { 56 | size_t n; /* bytes still unread */ 57 | const char *p; /* current position in buffer */ 58 | lua_Reader reader; /* reader function */ 59 | void *data; /* additional data */ 60 | lua_State *L; /* Lua state (for reader) */ 61 | }; 62 | 63 | 64 | LUAI_FUNC int luaZ_fill (ZIO *z); 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /3rdlibs/lua/include/lstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.h $ 3 | ** String table (keep all strings handled by Lua) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lstring_h 8 | #define lstring_h 9 | 10 | #include "lgc.h" 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | 14 | 15 | /* 16 | ** Memory-allocation error message must be preallocated (it cannot 17 | ** be created after memory is exhausted) 18 | */ 19 | #define MEMERRMSG "not enough memory" 20 | 21 | 22 | /* 23 | ** Size of a TString: Size of the header plus space for the string 24 | ** itself (including final '\0'). 25 | */ 26 | #define sizelstring(l) (offsetof(TString, contents) + ((l) + 1) * sizeof(char)) 27 | 28 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ 29 | (sizeof(s)/sizeof(char))-1)) 30 | 31 | 32 | /* 33 | ** test whether a string is a reserved word 34 | */ 35 | #define isreserved(s) ((s)->tt == LUA_VSHRSTR && (s)->extra > 0) 36 | 37 | 38 | /* 39 | ** equality for short strings, which are always internalized 40 | */ 41 | #define eqshrstr(a,b) check_exp((a)->tt == LUA_VSHRSTR, (a) == (b)) 42 | 43 | 44 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); 45 | LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts); 46 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); 47 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 48 | LUAI_FUNC void luaS_clearcache (global_State *g); 49 | LUAI_FUNC void luaS_init (lua_State *L); 50 | LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); 51 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue); 52 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 53 | LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); 54 | LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l); 55 | 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /3rdlibs/lua/src/linit.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: linit.c $ 3 | ** Initialization of libraries for lua.c and other clients 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #define linit_c 9 | #define LUA_LIB 10 | 11 | /* 12 | ** If you embed Lua in your program and need to open the standard 13 | ** libraries, call luaL_openlibs in your program. If you need a 14 | ** different set of libraries, copy this file to your project and edit 15 | ** it to suit your needs. 16 | ** 17 | ** You can also *preload* libraries, so that a later 'require' can 18 | ** open the library, which is already linked to the application. 19 | ** For that, do the following code: 20 | ** 21 | ** luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); 22 | ** lua_pushcfunction(L, luaopen_modname); 23 | ** lua_setfield(L, -2, modname); 24 | ** lua_pop(L, 1); // remove PRELOAD table 25 | */ 26 | 27 | #include "lprefix.h" 28 | 29 | 30 | #include 31 | 32 | #include "lua.h" 33 | 34 | #include "lualib.h" 35 | #include "lauxlib.h" 36 | 37 | 38 | /* 39 | ** these libs are loaded by lua.c and are readily available to any Lua 40 | ** program 41 | */ 42 | static const luaL_Reg loadedlibs[] = { 43 | {LUA_GNAME, luaopen_base}, 44 | {LUA_LOADLIBNAME, luaopen_package}, 45 | {LUA_COLIBNAME, luaopen_coroutine}, 46 | {LUA_TABLIBNAME, luaopen_table}, 47 | {LUA_IOLIBNAME, luaopen_io}, 48 | {LUA_OSLIBNAME, luaopen_os}, 49 | {LUA_STRLIBNAME, luaopen_string}, 50 | {LUA_MATHLIBNAME, luaopen_math}, 51 | {LUA_UTF8LIBNAME, luaopen_utf8}, 52 | {LUA_DBLIBNAME, luaopen_debug}, 53 | {NULL, NULL} 54 | }; 55 | 56 | 57 | LUALIB_API void luaL_openlibs (lua_State *L) { 58 | const luaL_Reg *lib; 59 | /* "require" functions from 'loadedlibs' and set results to global table */ 60 | for (lib = loadedlibs; lib->func; lib++) { 61 | luaL_requiref(L, lib->name, lib->func, 1); 62 | lua_pop(L, 1); /* remove lib */ 63 | } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /3rdlibs/lua/include/lfunc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.h $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lfunc_h 8 | #define lfunc_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | #define sizeCclosure(n) (cast_int(offsetof(CClosure, upvalue)) + \ 15 | cast_int(sizeof(TValue)) * (n)) 16 | 17 | #define sizeLclosure(n) (cast_int(offsetof(LClosure, upvals)) + \ 18 | cast_int(sizeof(TValue *)) * (n)) 19 | 20 | 21 | /* test whether thread is in 'twups' list */ 22 | #define isintwups(L) (L->twups != L) 23 | 24 | 25 | /* 26 | ** maximum number of upvalues in a closure (both C and Lua). (Value 27 | ** must fit in a VM register.) 28 | */ 29 | #define MAXUPVAL 255 30 | 31 | 32 | #define upisopen(up) ((up)->v != &(up)->u.value) 33 | 34 | 35 | #define uplevel(up) check_exp(upisopen(up), cast(StkId, (up)->v)) 36 | 37 | 38 | /* 39 | ** maximum number of misses before giving up the cache of closures 40 | ** in prototypes 41 | */ 42 | #define MAXMISS 10 43 | 44 | 45 | 46 | /* special status to close upvalues preserving the top of the stack */ 47 | #define CLOSEKTOP (-1) 48 | 49 | 50 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); 51 | LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nupvals); 52 | LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nupvals); 53 | LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); 54 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); 55 | LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level); 56 | LUAI_FUNC void luaF_closeupval (lua_State *L, StkId level); 57 | LUAI_FUNC void luaF_close (lua_State *L, StkId level, int status, int yy); 58 | LUAI_FUNC void luaF_unlinkupval (UpVal *uv); 59 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); 60 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, 61 | int pc); 62 | 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | # GMQ-Headers 2 | 3 | There are some useful header-only files for C++17. 4 | 5 | Use CMake to compile examples(or unittest): 6 | 7 | ```bash 8 | cmake -S . -B build 9 | cmake --build build 10 | ``` 11 | 12 | 13 | |module|description|deps|support| 14 | |--|--|--|--| 15 | |benchmark.hpp|a small, eazy to use benchmark framework for C++|None|| 16 | |log.hpp|a small log system|None|| 17 | |cgmath.hpp|a math library for computer graphics and computational geomentry|None, but test dependent on 3rdlibs/catch2.hpp and benchmark depends on benchmark.hpp|| 18 | |expect.hpp|a implementation of std::expect(C++23) in C++17|None, but test dependent on 3rdlibs/catch2.hpp|deprecated, maybe use C++23 after few years| 19 | |ecs.hpp|an ECS framework referenced bevy's ECS|sparse_sets.hpp|deprecated, new version is [gecs](https://github.com/VisualGMQ/gecs)| 20 | |sparse_sets.hpp|a sparse_set data-structure implement, [reference](https://manenko.com/2021/05/23/sparse-sets.html)|None|new version in [gecs](https://github.com/VisualGMQ/gecs)| 21 | |net.hpp|a thin layer for Win32 Socket|None| 22 | |fp.hpp|a functional programming library referenced Haskell & Lisp.Aimed to do compile time algorithm/reflection easier.Has two implementations: pure template and constexpr function|None|new version in [mirrow](https://github.com/VisualGMQ/mirrow)| 23 | |refl.hpp|static reflection in compile-time|None|deprecated, new version is [mirrow](https://github.com/VisualGMQ/mirrow)| 24 | |serialize.hpp|a serialize/deserialize library for convert class to/from lua|refl.hpp & sol2(under `3rdlibs/`) & log.hpp|deprecated, new version is [mirrow](https://github.com/VisualGMQ/mirrow)| 25 | |luabind|use static reflection and sol2 to auto-bind C++ code to lua|lua, sol and refl.hpp|| 26 | |gogl.hpp|a thin layer for OpenGL 4.3|log.hpp & cgmath.hpp & any opengl loader(glew, glad). Test dependents on glad and glfw(in `3rdlibs/`)|| 27 | |tweeny.hpp|a eazy to use tween library for game and GUI interaction|None|| 28 | |renderer2d.hpp|a 2D renderer in OpenGL for quickly embed in OpenGL Context|gogl.hpp, cgmath.hpp|| 29 | -------------------------------------------------------------------------------- /sparse_sets.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | template >> 11 | class SparseSets final { 12 | public: 13 | void Add(T t) { 14 | density_.push_back(t); 15 | assure(t); 16 | index(t) = density_.size() - 1; 17 | } 18 | 19 | void Remove(T t) { 20 | if (!Contain(t)) return; 21 | 22 | auto& idx = index(t); 23 | if (idx == density_.size() - 1) { 24 | idx = null; 25 | density_.pop_back(); 26 | } else { 27 | auto last = density_.back(); 28 | index(last) = idx; 29 | std::swap(density_[idx], density_.back()); 30 | idx = null; 31 | density_.pop_back(); 32 | } 33 | } 34 | 35 | bool Contain(T t) const { 36 | assert(t != null); 37 | 38 | auto p = page(t); 39 | auto o = offset(t); 40 | 41 | return p < sparse_.size() && sparse_[p]->at(o) != null; 42 | } 43 | 44 | void Clear() { 45 | density_.clear(); 46 | sparse_.clear(); 47 | } 48 | 49 | auto begin() { return density_.begin(); } 50 | auto end() { return density_.end(); } 51 | 52 | private: 53 | std::vector density_; 54 | std::vector>> sparse_; 55 | static constexpr T null = std::numeric_limits::max(); 56 | 57 | size_t page(T t) const { 58 | return t / PageSize; 59 | } 60 | 61 | T index(T t) const { 62 | return sparse_[page(t)]->at(offset(t)); 63 | } 64 | 65 | T& index(T t) { 66 | return sparse_[page(t)]->at(offset(t)); 67 | } 68 | 69 | size_t offset(T t) const { 70 | return t % PageSize; 71 | } 72 | 73 | void assure(T t) { 74 | auto p = page(t); 75 | if (p >= sparse_.size()) { 76 | for (size_t i = sparse_.size(); i <= p; i++) { 77 | sparse_.emplace_back(std::make_unique>()); 78 | sparse_[i]->fill(null); 79 | } 80 | } 81 | } 82 | }; -------------------------------------------------------------------------------- /3rdlibs/sol/sol/config.hpp: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | 3 | // Copyright (c) 2013-2020 Rapptz, ThePhD and contributors 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | // this software and associated documentation files (the "Software"), to deal in 7 | // the Software without restriction, including without limitation the rights to 8 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | // the Software, and to permit persons to whom the Software is furnished to do so, 10 | // subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | // This file was generated with a script. 23 | // Generated 2022-06-25 08:14:19.336233 UTC 24 | // This header was generated with sol v3.3.0 (revision eba86625) 25 | // https://github.com/ThePhD/sol2 26 | 27 | #ifndef SOL_SINGLE_CONFIG_HPP 28 | #define SOL_SINGLE_CONFIG_HPP 29 | 30 | // beginning of sol/config.hpp 31 | 32 | /* Base, empty configuration file! 33 | 34 | To override, place a file in your include paths of the form: 35 | 36 | . (your include path here) 37 | | sol (directory, or equivalent) 38 | | config.hpp (your config.hpp file) 39 | 40 | So that when sol2 includes the file 41 | 42 | #include 43 | 44 | it gives you the configuration values you desire. Configuration values can be 45 | seen in the safety.rst of the doc/src, or at 46 | https://sol2.readthedocs.io/en/latest/safety.html ! You can also pass them through 47 | the build system, or the command line options of your compiler. 48 | 49 | */ 50 | 51 | // end of sol/config.hpp 52 | 53 | #endif // SOL_SINGLE_CONFIG_HPP 54 | -------------------------------------------------------------------------------- /3rdlibs/lua/include/ljumptab.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ljumptab.h $ 3 | ** Jump Table for the Lua interpreter 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #undef vmdispatch 9 | #undef vmcase 10 | #undef vmbreak 11 | 12 | #define vmdispatch(x) goto *disptab[x]; 13 | 14 | #define vmcase(l) L_##l: 15 | 16 | #define vmbreak vmfetch(); vmdispatch(GET_OPCODE(i)); 17 | 18 | 19 | static const void *const disptab[NUM_OPCODES] = { 20 | 21 | #if 0 22 | ** you can update the following list with this command: 23 | ** 24 | ** sed -n '/^OP_/\!d; s/OP_/\&\&L_OP_/ ; s/,.*/,/ ; s/\/.*// ; p' lopcodes.h 25 | ** 26 | #endif 27 | 28 | &&L_OP_MOVE, 29 | &&L_OP_LOADI, 30 | &&L_OP_LOADF, 31 | &&L_OP_LOADK, 32 | &&L_OP_LOADKX, 33 | &&L_OP_LOADFALSE, 34 | &&L_OP_LFALSESKIP, 35 | &&L_OP_LOADTRUE, 36 | &&L_OP_LOADNIL, 37 | &&L_OP_GETUPVAL, 38 | &&L_OP_SETUPVAL, 39 | &&L_OP_GETTABUP, 40 | &&L_OP_GETTABLE, 41 | &&L_OP_GETI, 42 | &&L_OP_GETFIELD, 43 | &&L_OP_SETTABUP, 44 | &&L_OP_SETTABLE, 45 | &&L_OP_SETI, 46 | &&L_OP_SETFIELD, 47 | &&L_OP_NEWTABLE, 48 | &&L_OP_SELF, 49 | &&L_OP_ADDI, 50 | &&L_OP_ADDK, 51 | &&L_OP_SUBK, 52 | &&L_OP_MULK, 53 | &&L_OP_MODK, 54 | &&L_OP_POWK, 55 | &&L_OP_DIVK, 56 | &&L_OP_IDIVK, 57 | &&L_OP_BANDK, 58 | &&L_OP_BORK, 59 | &&L_OP_BXORK, 60 | &&L_OP_SHRI, 61 | &&L_OP_SHLI, 62 | &&L_OP_ADD, 63 | &&L_OP_SUB, 64 | &&L_OP_MUL, 65 | &&L_OP_MOD, 66 | &&L_OP_POW, 67 | &&L_OP_DIV, 68 | &&L_OP_IDIV, 69 | &&L_OP_BAND, 70 | &&L_OP_BOR, 71 | &&L_OP_BXOR, 72 | &&L_OP_SHL, 73 | &&L_OP_SHR, 74 | &&L_OP_MMBIN, 75 | &&L_OP_MMBINI, 76 | &&L_OP_MMBINK, 77 | &&L_OP_UNM, 78 | &&L_OP_BNOT, 79 | &&L_OP_NOT, 80 | &&L_OP_LEN, 81 | &&L_OP_CONCAT, 82 | &&L_OP_CLOSE, 83 | &&L_OP_TBC, 84 | &&L_OP_JMP, 85 | &&L_OP_EQ, 86 | &&L_OP_LT, 87 | &&L_OP_LE, 88 | &&L_OP_EQK, 89 | &&L_OP_EQI, 90 | &&L_OP_LTI, 91 | &&L_OP_LEI, 92 | &&L_OP_GTI, 93 | &&L_OP_GEI, 94 | &&L_OP_TEST, 95 | &&L_OP_TESTSET, 96 | &&L_OP_CALL, 97 | &&L_OP_TAILCALL, 98 | &&L_OP_RETURN, 99 | &&L_OP_RETURN0, 100 | &&L_OP_RETURN1, 101 | &&L_OP_FORLOOP, 102 | &&L_OP_FORPREP, 103 | &&L_OP_TFORPREP, 104 | &&L_OP_TFORCALL, 105 | &&L_OP_TFORLOOP, 106 | &&L_OP_SETLIST, 107 | &&L_OP_CLOSURE, 108 | &&L_OP_VARARG, 109 | &&L_OP_VARARGPREP, 110 | &&L_OP_EXTRAARG 111 | 112 | }; 113 | -------------------------------------------------------------------------------- /3rdlibs/lua/include/ldebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldebug.h $ 3 | ** Auxiliary functions from Debug Interface module 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldebug_h 8 | #define ldebug_h 9 | 10 | 11 | #include "lstate.h" 12 | 13 | 14 | #define pcRel(pc, p) (cast_int((pc) - (p)->code) - 1) 15 | 16 | 17 | /* Active Lua function (given call info) */ 18 | #define ci_func(ci) (clLvalue(s2v((ci)->func))) 19 | 20 | 21 | #define resethookcount(L) (L->hookcount = L->basehookcount) 22 | 23 | /* 24 | ** mark for entries in 'lineinfo' array that has absolute information in 25 | ** 'abslineinfo' array 26 | */ 27 | #define ABSLINEINFO (-0x80) 28 | 29 | 30 | /* 31 | ** MAXimum number of successive Instructions WiTHout ABSolute line 32 | ** information. (A power of two allows fast divisions.) 33 | */ 34 | #if !defined(MAXIWTHABS) 35 | #define MAXIWTHABS 128 36 | #endif 37 | 38 | 39 | LUAI_FUNC int luaG_getfuncline (const Proto *f, int pc); 40 | LUAI_FUNC const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, 41 | StkId *pos); 42 | LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, 43 | const char *opname); 44 | LUAI_FUNC l_noret luaG_callerror (lua_State *L, const TValue *o); 45 | LUAI_FUNC l_noret luaG_forerror (lua_State *L, const TValue *o, 46 | const char *what); 47 | LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, 48 | const TValue *p2); 49 | LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1, 50 | const TValue *p2, 51 | const char *msg); 52 | LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1, 53 | const TValue *p2); 54 | LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, 55 | const TValue *p2); 56 | LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); 57 | LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg, 58 | TString *src, int line); 59 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L); 60 | LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc); 61 | 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /3rdlibs/lua/include/ltable.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltable.h $ 3 | ** Lua tables (hash) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltable_h 8 | #define ltable_h 9 | 10 | #include "lobject.h" 11 | 12 | 13 | #define gnode(t,i) (&(t)->node[i]) 14 | #define gval(n) (&(n)->i_val) 15 | #define gnext(n) ((n)->u.next) 16 | 17 | 18 | /* 19 | ** Clear all bits of fast-access metamethods, which means that the table 20 | ** may have any of these metamethods. (First access that fails after the 21 | ** clearing will set the bit again.) 22 | */ 23 | #define invalidateTMcache(t) ((t)->flags &= ~maskflags) 24 | 25 | 26 | /* true when 't' is using 'dummynode' as its hash part */ 27 | #define isdummy(t) ((t)->lastfree == NULL) 28 | 29 | 30 | /* allocated size for hash nodes */ 31 | #define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t)) 32 | 33 | 34 | /* returns the Node, given the value of a table entry */ 35 | #define nodefromval(v) cast(Node *, (v)) 36 | 37 | 38 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); 39 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, 40 | TValue *value); 41 | LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); 42 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); 43 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); 44 | LUAI_FUNC void luaH_newkey (lua_State *L, Table *t, const TValue *key, 45 | TValue *value); 46 | LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key, 47 | TValue *value); 48 | LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key, 49 | const TValue *slot, TValue *value); 50 | LUAI_FUNC Table *luaH_new (lua_State *L); 51 | LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, 52 | unsigned int nhsize); 53 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); 54 | LUAI_FUNC void luaH_free (lua_State *L, Table *t); 55 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); 56 | LUAI_FUNC lua_Unsigned luaH_getn (Table *t); 57 | LUAI_FUNC unsigned int luaH_realasize (const Table *t); 58 | 59 | 60 | #if defined(LUA_DEBUG) 61 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); 62 | LUAI_FUNC int luaH_isdummy (const Table *t); 63 | #endif 64 | 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /bins/renderer2d.cpp: -------------------------------------------------------------------------------- 1 | #include "renderer2d.hpp" 2 | #include "GLFW/glfw3.h" 3 | #define STB_IMAGE_IMPLEMENTATION 4 | #include "3rdlibs/stb_image.h" 5 | 6 | constexpr int WindowWidth = 1024; 7 | constexpr int WindowHeight = 720; 8 | 9 | int main() { 10 | if (!glfwInit()) { 11 | LOGF("[APP]: glfw init failed"); 12 | return 1; 13 | } 14 | 15 | glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); 16 | glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 17 | glfwWindowHint(GLFW_SAMPLES, 8); 18 | GLFWwindow* window = glfwCreateWindow(WindowWidth, WindowHeight, "renderer2d", NULL, NULL); 19 | if (!window) { 20 | LOGE("[GLFW]: create window failed"); 21 | } 22 | 23 | glfwMakeContextCurrent(window); 24 | glfwSwapInterval(1); // Enable vsync 25 | if (gladLoadGL() == 0) { 26 | LOGF("[GLAD]: glad init failed!"); 27 | return 2; 28 | } 29 | 30 | auto renderer = std::make_unique(); 31 | renderer->SetViewport({0, 0}, {WindowWidth, WindowHeight}); 32 | renderer->SetClearColor({0.2, 0.2, 0.2, 1.0}); 33 | 34 | int w, h; 35 | void* datas = stbi_load("res/img/img.jpg", &w, &h, nullptr, 4); 36 | std::unique_ptr texture = std::make_unique( 37 | gogl::Texture::Type::Dimension2, datas, w, h, 38 | gogl::Sampler::CreateLinearRepeat(), gogl::Format::RGBA, 39 | gogl::Format::RGBA); 40 | 41 | while (!glfwWindowShouldClose(window)) { 42 | glfwPollEvents(); 43 | 44 | renderer->Clear(); 45 | 46 | renderer->DrawLine({0, 0}, {WindowWidth, WindowHeight}, {1, 0, 0, 1}); 47 | renderer->DrawRect(cgmath::Rect{100, 200, 50, 100}, {0, 1, 0, 1}, 48 | cgmath::CreateZRotation(cgmath::Deg2Rad(15.0f))); 49 | 50 | renderer->FillRect(cgmath::Rect{400, 200, 50, 100}, {0, 1, 0, 1}, 51 | cgmath::CreateZRotation(cgmath::Deg2Rad(15.0f)), 52 | renderer2d::RectSampler{texture.get()}); 53 | renderer->DrawArc(cgmath::Vec2{400, 400}, 100.0, 30.0, 90.0, {0, 0, 1, 1}); 54 | renderer->FillCircle(cgmath::Vec2{400, 400}, 100.0, {0, 0, 1, 1}, renderer2d::CircleSampler{texture.get()}); 55 | renderer->FillFan(cgmath::Vec2{400, 400}, 100.0, 30.0, 90.0, {1, 0, 1, 1}); 56 | 57 | glfwSwapBuffers(window); 58 | } 59 | 60 | texture.reset(); 61 | renderer.reset(); 62 | 63 | glfwDestroyWindow(window); 64 | glfwTerminate(); 65 | return 0; 66 | 67 | 68 | return 0; 69 | } -------------------------------------------------------------------------------- /3rdlibs/lua/src/onelua.c: -------------------------------------------------------------------------------- 1 | /* 2 | * one.c -- Lua core, libraries, and interpreter in a single file 3 | */ 4 | 5 | /* default is to build the full interpreter */ 6 | #ifndef MAKE_LIB 7 | #ifndef MAKE_LUAC 8 | #ifndef MAKE_LUA 9 | #define MAKE_LUA 10 | #endif 11 | #endif 12 | #endif 13 | 14 | /* choose suitable platform-specific features */ 15 | /* some of these may need extra libraries such as -ldl -lreadline -lncurses */ 16 | #if 0 17 | #define LUA_USE_LINUX 18 | #define LUA_USE_MACOSX 19 | #define LUA_USE_POSIX 20 | #define LUA_ANSI 21 | #endif 22 | 23 | /* no need to change anything below this line ----------------------------- */ 24 | 25 | #include "lprefix.h" 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | 44 | /* setup for luaconf.h */ 45 | #define LUA_CORE 46 | #define LUA_LIB 47 | #define ltable_c 48 | #define lvm_c 49 | #include "luaconf.h" 50 | 51 | /* do not export internal symbols */ 52 | #undef LUAI_FUNC 53 | #undef LUAI_DDEC 54 | #undef LUAI_DDEF 55 | #define LUAI_FUNC static 56 | #define LUAI_DDEC(def) /* empty */ 57 | #define LUAI_DDEF static 58 | 59 | /* core -- used by all */ 60 | #include "lzio.c" 61 | #include "lctype.c" 62 | #include "lopcodes.c" 63 | #include "lmem.c" 64 | #include "lundump.c" 65 | #include "ldump.c" 66 | #include "lstate.c" 67 | #include "lgc.c" 68 | #include "llex.c" 69 | #include "lcode.c" 70 | #include "lparser.c" 71 | #include "ldebug.c" 72 | #include "lfunc.c" 73 | #include "lobject.c" 74 | #include "ltm.c" 75 | #include "lstring.c" 76 | #include "ltable.c" 77 | #include "ldo.c" 78 | #include "lvm.c" 79 | #include "lapi.c" 80 | 81 | /* auxiliary library -- used by all */ 82 | #include "lauxlib.c" 83 | 84 | /* standard library -- not used by luac */ 85 | #ifndef MAKE_LUAC 86 | #include "lbaselib.c" 87 | #include "lcorolib.c" 88 | #include "ldblib.c" 89 | #include "liolib.c" 90 | #include "lmathlib.c" 91 | #include "loadlib.c" 92 | #include "loslib.c" 93 | #include "lstrlib.c" 94 | #include "ltablib.c" 95 | #include "lutf8lib.c" 96 | #include "linit.c" 97 | #endif 98 | 99 | /* lua */ 100 | #ifdef MAKE_LUA 101 | #include "lua.c" 102 | #endif 103 | 104 | /* luac */ 105 | #ifdef MAKE_LUAC 106 | #include "luac.c" 107 | #endif 108 | -------------------------------------------------------------------------------- /3rdlibs/lua/include/lctype.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.h $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lctype_h 8 | #define lctype_h 9 | 10 | #include "lua.h" 11 | 12 | 13 | /* 14 | ** WARNING: the functions defined here do not necessarily correspond 15 | ** to the similar functions in the standard C ctype.h. They are 16 | ** optimized for the specific needs of Lua. 17 | */ 18 | 19 | #if !defined(LUA_USE_CTYPE) 20 | 21 | #if 'A' == 65 && '0' == 48 22 | /* ASCII case: can use its own tables; faster and fixed */ 23 | #define LUA_USE_CTYPE 0 24 | #else 25 | /* must use standard C ctype */ 26 | #define LUA_USE_CTYPE 1 27 | #endif 28 | 29 | #endif 30 | 31 | 32 | #if !LUA_USE_CTYPE /* { */ 33 | 34 | #include 35 | 36 | #include "llimits.h" 37 | 38 | 39 | #define ALPHABIT 0 40 | #define DIGITBIT 1 41 | #define PRINTBIT 2 42 | #define SPACEBIT 3 43 | #define XDIGITBIT 4 44 | 45 | 46 | #define MASK(B) (1 << (B)) 47 | 48 | 49 | /* 50 | ** add 1 to char to allow index -1 (EOZ) 51 | */ 52 | #define testprop(c,p) (luai_ctype_[(c)+1] & (p)) 53 | 54 | /* 55 | ** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_' 56 | */ 57 | #define lislalpha(c) testprop(c, MASK(ALPHABIT)) 58 | #define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT))) 59 | #define lisdigit(c) testprop(c, MASK(DIGITBIT)) 60 | #define lisspace(c) testprop(c, MASK(SPACEBIT)) 61 | #define lisprint(c) testprop(c, MASK(PRINTBIT)) 62 | #define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) 63 | 64 | 65 | /* 66 | ** In ASCII, this 'ltolower' is correct for alphabetic characters and 67 | ** for '.'. That is enough for Lua needs. ('check_exp' ensures that 68 | ** the character either is an upper-case letter or is unchanged by 69 | ** the transformation, which holds for lower-case letters and '.'.) 70 | */ 71 | #define ltolower(c) \ 72 | check_exp(('A' <= (c) && (c) <= 'Z') || (c) == ((c) | ('A' ^ 'a')), \ 73 | (c) | ('A' ^ 'a')) 74 | 75 | 76 | /* one entry for each character and for -1 (EOZ) */ 77 | LUAI_DDEC(const lu_byte luai_ctype_[UCHAR_MAX + 2];) 78 | 79 | 80 | #else /* }{ */ 81 | 82 | /* 83 | ** use standard C ctypes 84 | */ 85 | 86 | #include 87 | 88 | 89 | #define lislalpha(c) (isalpha(c) || (c) == '_') 90 | #define lislalnum(c) (isalnum(c) || (c) == '_') 91 | #define lisdigit(c) (isdigit(c)) 92 | #define lisspace(c) (isspace(c)) 93 | #define lisprint(c) (isprint(c)) 94 | #define lisxdigit(c) (isxdigit(c)) 95 | 96 | #define ltolower(c) (tolower(c)) 97 | 98 | #endif /* } */ 99 | 100 | #endif 101 | 102 | -------------------------------------------------------------------------------- /3rdlibs/lua/src/lctype.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.c $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lctype_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include "lctype.h" 14 | 15 | #if !LUA_USE_CTYPE /* { */ 16 | 17 | #include 18 | 19 | 20 | #if defined (LUA_UCID) /* accept UniCode IDentifiers? */ 21 | /* consider all non-ascii codepoints to be alphabetic */ 22 | #define NONA 0x01 23 | #else 24 | #define NONA 0x00 /* default */ 25 | #endif 26 | 27 | 28 | LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { 29 | 0x00, /* EOZ */ 30 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */ 31 | 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 32 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */ 33 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 34 | 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */ 35 | 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 36 | 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */ 37 | 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 38 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */ 39 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 40 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */ 41 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05, 42 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */ 43 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 44 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */ 45 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, 46 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* 8. */ 47 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 48 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* 9. */ 49 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 50 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* a. */ 51 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 52 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* b. */ 53 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 54 | 0x00, 0x00, NONA, NONA, NONA, NONA, NONA, NONA, /* c. */ 55 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 56 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* d. */ 57 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 58 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, /* e. */ 59 | NONA, NONA, NONA, NONA, NONA, NONA, NONA, NONA, 60 | NONA, NONA, NONA, NONA, NONA, 0x00, 0x00, 0x00, /* f. */ 61 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 62 | }; 63 | 64 | #endif /* } */ 65 | -------------------------------------------------------------------------------- /3rdlibs/lua/include/llex.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llex.h $ 3 | ** Lexical Analyzer 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef llex_h 8 | #define llex_h 9 | 10 | #include 11 | 12 | #include "lobject.h" 13 | #include "lzio.h" 14 | 15 | 16 | /* 17 | ** Single-char tokens (terminal symbols) are represented by their own 18 | ** numeric code. Other tokens start at the following value. 19 | */ 20 | #define FIRST_RESERVED (UCHAR_MAX + 1) 21 | 22 | 23 | #if !defined(LUA_ENV) 24 | #define LUA_ENV "_ENV" 25 | #endif 26 | 27 | 28 | /* 29 | * WARNING: if you change the order of this enumeration, 30 | * grep "ORDER RESERVED" 31 | */ 32 | enum RESERVED { 33 | /* terminal symbols denoted by reserved words */ 34 | TK_AND = FIRST_RESERVED, TK_BREAK, 35 | TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, 36 | TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, 37 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, 38 | /* other terminal symbols */ 39 | TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, 40 | TK_SHL, TK_SHR, 41 | TK_DBCOLON, TK_EOS, 42 | TK_FLT, TK_INT, TK_NAME, TK_STRING 43 | }; 44 | 45 | /* number of reserved words */ 46 | #define NUM_RESERVED (cast_int(TK_WHILE-FIRST_RESERVED + 1)) 47 | 48 | 49 | typedef union { 50 | lua_Number r; 51 | lua_Integer i; 52 | TString *ts; 53 | } SemInfo; /* semantics information */ 54 | 55 | 56 | typedef struct Token { 57 | int token; 58 | SemInfo seminfo; 59 | } Token; 60 | 61 | 62 | /* state of the lexer plus state of the parser when shared by all 63 | functions */ 64 | typedef struct LexState { 65 | int current; /* current character (charint) */ 66 | int linenumber; /* input line counter */ 67 | int lastline; /* line of last token 'consumed' */ 68 | Token t; /* current token */ 69 | Token lookahead; /* look ahead token */ 70 | struct FuncState *fs; /* current function (parser) */ 71 | struct lua_State *L; 72 | ZIO *z; /* input stream */ 73 | Mbuffer *buff; /* buffer for tokens */ 74 | Table *h; /* to avoid collection/reuse strings */ 75 | struct Dyndata *dyd; /* dynamic structures used by the parser */ 76 | TString *source; /* current source name */ 77 | TString *envn; /* environment variable name */ 78 | } LexState; 79 | 80 | 81 | LUAI_FUNC void luaX_init (lua_State *L); 82 | LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, 83 | TString *source, int firstchar); 84 | LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); 85 | LUAI_FUNC void luaX_next (LexState *ls); 86 | LUAI_FUNC int luaX_lookahead (LexState *ls); 87 | LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s); 88 | LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); 89 | 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /bins/fp.cpp: -------------------------------------------------------------------------------- 1 | #include "fp.hpp" 2 | 3 | #define CATCH_CONFIG_MAIN 4 | #include "3rdlibs/catch.hpp" 5 | 6 | using l = GList(1, 2, 3, 4); 7 | 8 | TEST_CASE("list operations") { 9 | SECTION("template implementation") { 10 | using listT = GList(1, 2, 3, 4); 11 | 12 | constexpr int head = tmpl::Head; 13 | constexpr int snd = tmpl::Head>; 14 | constexpr int last = tmpl::Last; 15 | using tail = tmpl::Tail; 16 | using init = tmpl::Init; 17 | using concatedList = tmpl::Concat; 18 | 19 | static_assert(tmpl::Eq>); 20 | static_assert(head == 1); 21 | static_assert(snd == 2); 22 | static_assert(last == 4); 23 | static_assert(tmpl::Eq); 24 | static_assert(tmpl::Eq); 25 | static_assert(tmpl::Eq); 26 | static_assert(tmpl::Nth<0, listT> == 1); 27 | static_assert(tmpl::Nth<1, listT> == 2); 28 | static_assert(tmpl::Nth<2, listT> == 3); 29 | static_assert(tmpl::Nth<3, listT> == 4); 30 | static_assert(tmpl::Null>); 31 | static_assert(tmpl::Eq, GList(1, 1, 1)>); 32 | static_assert(tmpl::Eq, GList(1, 2, 3, 4, 5, 6)>); 33 | static_assert(tmpl::Eq::type, GList(1, 2, 3)>); 34 | static_assert(tmpl::Sum == 6); 35 | static_assert(tmpl::Maxmimum == 9); 36 | static_assert(tmpl::Elem); 37 | static_assert(tmpl::Elem); 38 | static_assert(!tmpl::Elem); 39 | static_assert(tmpl::Fst> == 1); 40 | static_assert(tmpl::Snd> == 2); 41 | static_assert(tmpl::Eq, GList(2, 3, 4, 5)>); 42 | static_assert(tmpl::Eq, GList(1, 3)>); 43 | } 44 | 45 | SECTION("compile-time function implementations") { 46 | constexpr auto list = List{}; 47 | 48 | constexpr int headF = func::Head(list); 49 | constexpr int sndF = func::Head(func::Tail(list)); 50 | constexpr int lastF = func::Last(list); 51 | constexpr auto concatedListF = func::Concat(std::integral_constant{}, list); 52 | constexpr auto initF = func::Init(list); 53 | REQUIRE(func::Eq(list, List{})); 54 | static_assert(headF == 1); 55 | static_assert(sndF == 2); 56 | static_assert(lastF == 4); 57 | REQUIRE(func::Eq(initF, List{})); 58 | } 59 | } -------------------------------------------------------------------------------- /bins/ecs.cpp: -------------------------------------------------------------------------------- 1 | #include "ecs.hpp" 2 | #include 3 | #include 4 | 5 | using namespace ecs; 6 | 7 | struct Name { 8 | std::string name; 9 | }; 10 | 11 | struct ID { 12 | int id; 13 | }; 14 | 15 | struct Timer { 16 | int t; 17 | }; 18 | 19 | void StartUpSystem(Commands& command, Resources) { 20 | command.Spawn(Name{ "person1" }) 21 | .Spawn(Name{"person2"}, ID{1}) 22 | .Spawn(ID{2}); 23 | } 24 | 25 | void EchoNameSystem(Commands& command, Querier query, Resources resources, Events& e) { 26 | std::cout << "echo name system" << std::endl; 27 | std::vector entities = query.Query(); 28 | for (auto entity : entities) { 29 | std::cout << query.Get(entity).name << std::endl; 30 | } 31 | 32 | auto reader = e.Reader(); 33 | if (reader.Has()) { 34 | std::cout << reader.Read() << std::endl; 35 | } 36 | } 37 | 38 | void EchoNameAndIDSystem(Commands& command, Querier query, Resources resources, Events& e) { 39 | std::cout << "echo name and id system" << std::endl; 40 | std::vector entities = query.Query>(); 41 | for (auto entity : entities) { 42 | std::cout << query.Get(entity).name << ", " << query.Get(entity).id << std::endl; 43 | } 44 | 45 | auto reader = e.Reader(); 46 | if (reader.Has()) { 47 | std::cout << reader.Read() << std::endl; 48 | } 49 | } 50 | 51 | bool canWrite = true; 52 | 53 | void EchoIDSystem(Commands& command, Querier query, Resources resources, Events& e) { 54 | std::cout << "echo id system" << std::endl; 55 | std::vector entities = query.Query(); 56 | for (auto entity : entities) { 57 | std::cout << query.Get(entity).id << std::endl; 58 | } 59 | 60 | if (canWrite) { 61 | e.Writer().Write("hello, I'm EchoIDSystem"); 62 | canWrite = false; 63 | } 64 | } 65 | 66 | void EchoTimeSystem(Commands& command, Querier query, Resources resources, Events& e) { 67 | std::cout << "echo time system" << std::endl; 68 | std::cout << resources.Get().t << std::endl; 69 | 70 | auto reader = e.Reader(); 71 | if (reader.Has()) { 72 | std::cout << reader.Read() << std::endl; 73 | } 74 | } 75 | 76 | int main() { 77 | World world; 78 | world.AddStartupSystem(StartUpSystem) 79 | .SetResource(Timer{123}) 80 | .AddSystem(EchoNameSystem) 81 | .AddSystem(EchoNameAndIDSystem) 82 | .AddSystem(EchoIDSystem) 83 | .AddSystem(EchoTimeSystem); 84 | 85 | world.Startup(); 86 | 87 | world.Update(); 88 | std::cout << "==================" << std::endl; 89 | world.Update(); 90 | std::cout << "==================" << std::endl; 91 | world.Update(); 92 | 93 | world.Shutdown(); 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /bins/gogl_compute.cpp: -------------------------------------------------------------------------------- 1 | #include "gogl.hpp" 2 | #include "GLFW/glfw3.h" 3 | 4 | using namespace gogl; 5 | 6 | struct Context final { 7 | std::unique_ptr bufmgr; 8 | std::unique_ptr texmgr; 9 | std::unique_ptr shadermgr; 10 | std::unique_ptr attrmgr; 11 | 12 | Context() 13 | : bufmgr(std::make_unique()), 14 | texmgr(std::make_unique()), 15 | shadermgr(std::make_unique()), 16 | attrmgr(std::make_unique()) { } 17 | }; 18 | 19 | int main() { 20 | if (!glfwInit()) { 21 | LOGF("[APP]: glfw init failed"); 22 | return 1; 23 | } 24 | 25 | glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); 26 | glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 27 | GLFWwindow* window = glfwCreateWindow(200, 200, "VisualDebugger", NULL, NULL); 28 | if (!window) { 29 | LOGE("[GLFW]: create window failed"); 30 | } 31 | 32 | glfwMakeContextCurrent(window); 33 | 34 | 35 | if (gladLoadGL() == 0) { 36 | LOGF("[GLAD]: glad init failed!"); 37 | return 2; 38 | } 39 | PhysicDevice phyDev; 40 | auto size = phyDev.GetComputeWorkGroupMaxSize(); 41 | std::cout << "max compute work group size:" << size[0] << ", " << size[1] << ", " << size[2] << std::endl; 42 | std::cout << "max compute work invoke count:" << phyDev.GetComputeGroupInvocationMaxCount() << std::endl; 43 | 44 | std::unique_ptr ctx = std::make_unique(); 45 | 46 | std::ifstream shader_file("./res/shaders/compute.shader"); 47 | std::string shader_source(std::istreambuf_iterator(shader_file), (std::istreambuf_iterator())); 48 | auto& shader = ctx->shadermgr->Create("compute", ShaderModule::CreateComputeShader(shader_source)); 49 | 50 | float buf[256] = {0}; 51 | auto& inputBufferA = ctx->bufmgr->Create("input1", BufferType::ShaderStorage); 52 | auto& inputBufferB = ctx->bufmgr->Create("input2", BufferType::ShaderStorage); 53 | auto& outputBuffer = ctx->bufmgr->Create("output", BufferType::ShaderStorage); 54 | 55 | for (int i = 0; i < 256; i++) { 56 | buf[i] = i; 57 | } 58 | inputBufferA.SetData(buf, sizeof(buf)); 59 | inputBufferA.Bind2Base(0); 60 | 61 | for (int i = 0; i < 256; i++) { 62 | buf[i] = i + 1; 63 | } 64 | inputBufferB.SetData(buf, sizeof(buf)); 65 | inputBufferB.Bind2Base(1); 66 | 67 | outputBuffer.ExtendSize(sizeof(buf)); 68 | outputBuffer.Bind2Base(2); 69 | 70 | shader.Use(); 71 | shader.DispatchCompute(256, 1, 1); 72 | shader.WaitMemoryBarrier(BarrierType::ShaderStorage); 73 | 74 | float data[256] = {0}; 75 | outputBuffer.GetSubData(data, 0, sizeof(data)); 76 | for (int i = 0; i < 256; i++) { 77 | std::cout << (int)data[i] << std::endl; 78 | } 79 | 80 | ctx.reset(); 81 | 82 | glfwDestroyWindow(window); 83 | glfwTerminate(); 84 | return 0; 85 | } -------------------------------------------------------------------------------- /3rdlibs/lua/include/ldo.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldo.h $ 3 | ** Stack and Call structure of Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldo_h 8 | #define ldo_h 9 | 10 | 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | #include "lzio.h" 14 | 15 | 16 | /* 17 | ** Macro to check stack size and grow stack if needed. Parameters 18 | ** 'pre'/'pos' allow the macro to preserve a pointer into the 19 | ** stack across reallocations, doing the work only when needed. 20 | ** It also allows the running of one GC step when the stack is 21 | ** reallocated. 22 | ** 'condmovestack' is used in heavy tests to force a stack reallocation 23 | ** at every check. 24 | */ 25 | #define luaD_checkstackaux(L,n,pre,pos) \ 26 | if (l_unlikely(L->stack_last - L->top <= (n))) \ 27 | { pre; luaD_growstack(L, n, 1); pos; } \ 28 | else { condmovestack(L,pre,pos); } 29 | 30 | /* In general, 'pre'/'pos' are empty (nothing to save) */ 31 | #define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0) 32 | 33 | 34 | 35 | #define savestack(L,p) ((char *)(p) - (char *)L->stack) 36 | #define restorestack(L,n) ((StkId)((char *)L->stack + (n))) 37 | 38 | 39 | /* macro to check stack size, preserving 'p' */ 40 | #define checkstackGCp(L,n,p) \ 41 | luaD_checkstackaux(L, n, \ 42 | ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \ 43 | luaC_checkGC(L), /* stack grow uses memory */ \ 44 | p = restorestack(L, t__)) /* 'pos' part: restore 'p' */ 45 | 46 | 47 | /* macro to check stack size and GC */ 48 | #define checkstackGC(L,fsize) \ 49 | luaD_checkstackaux(L, (fsize), luaC_checkGC(L), (void)0) 50 | 51 | 52 | /* type of protected functions, to be ran by 'runprotected' */ 53 | typedef void (*Pfunc) (lua_State *L, void *ud); 54 | 55 | LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); 56 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, 57 | const char *mode); 58 | LUAI_FUNC void luaD_hook (lua_State *L, int event, int line, 59 | int fTransfer, int nTransfer); 60 | LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci); 61 | LUAI_FUNC int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1, int delta); 62 | LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults); 63 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); 64 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); 65 | LUAI_FUNC StkId luaD_tryfuncTM (lua_State *L, StkId func); 66 | LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status); 67 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, 68 | ptrdiff_t oldtop, ptrdiff_t ef); 69 | LUAI_FUNC void luaD_poscall (lua_State *L, CallInfo *ci, int nres); 70 | LUAI_FUNC int luaD_reallocstack (lua_State *L, int newsize, int raiseerror); 71 | LUAI_FUNC int luaD_growstack (lua_State *L, int n, int raiseerror); 72 | LUAI_FUNC void luaD_shrinkstack (lua_State *L); 73 | LUAI_FUNC void luaD_inctop (lua_State *L); 74 | 75 | LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); 76 | LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); 77 | 78 | #endif 79 | 80 | -------------------------------------------------------------------------------- /3rdlibs/lua/include/ltm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltm.h $ 3 | ** Tag methods 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltm_h 8 | #define ltm_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | /* 15 | * WARNING: if you change the order of this enumeration, 16 | * grep "ORDER TM" and "ORDER OP" 17 | */ 18 | typedef enum { 19 | TM_INDEX, 20 | TM_NEWINDEX, 21 | TM_GC, 22 | TM_MODE, 23 | TM_LEN, 24 | TM_EQ, /* last tag method with fast access */ 25 | TM_ADD, 26 | TM_SUB, 27 | TM_MUL, 28 | TM_MOD, 29 | TM_POW, 30 | TM_DIV, 31 | TM_IDIV, 32 | TM_BAND, 33 | TM_BOR, 34 | TM_BXOR, 35 | TM_SHL, 36 | TM_SHR, 37 | TM_UNM, 38 | TM_BNOT, 39 | TM_LT, 40 | TM_LE, 41 | TM_CONCAT, 42 | TM_CALL, 43 | TM_CLOSE, 44 | TM_N /* number of elements in the enum */ 45 | } TMS; 46 | 47 | 48 | /* 49 | ** Mask with 1 in all fast-access methods. A 1 in any of these bits 50 | ** in the flag of a (meta)table means the metatable does not have the 51 | ** corresponding metamethod field. (Bit 7 of the flag is used for 52 | ** 'isrealasize'.) 53 | */ 54 | #define maskflags (~(~0u << (TM_EQ + 1))) 55 | 56 | 57 | /* 58 | ** Test whether there is no tagmethod. 59 | ** (Because tagmethods use raw accesses, the result may be an "empty" nil.) 60 | */ 61 | #define notm(tm) ttisnil(tm) 62 | 63 | 64 | #define gfasttm(g,et,e) ((et) == NULL ? NULL : \ 65 | ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) 66 | 67 | #define fasttm(l,et,e) gfasttm(G(l), et, e) 68 | 69 | #define ttypename(x) luaT_typenames_[(x) + 1] 70 | 71 | LUAI_DDEC(const char *const luaT_typenames_[LUA_TOTALTYPES];) 72 | 73 | 74 | LUAI_FUNC const char *luaT_objtypename (lua_State *L, const TValue *o); 75 | 76 | LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); 77 | LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, 78 | TMS event); 79 | LUAI_FUNC void luaT_init (lua_State *L); 80 | 81 | LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, 82 | const TValue *p2, const TValue *p3); 83 | LUAI_FUNC void luaT_callTMres (lua_State *L, const TValue *f, 84 | const TValue *p1, const TValue *p2, StkId p3); 85 | LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, 86 | StkId res, TMS event); 87 | LUAI_FUNC void luaT_tryconcatTM (lua_State *L); 88 | LUAI_FUNC void luaT_trybinassocTM (lua_State *L, const TValue *p1, 89 | const TValue *p2, int inv, StkId res, TMS event); 90 | LUAI_FUNC void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, 91 | int inv, StkId res, TMS event); 92 | LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, 93 | const TValue *p2, TMS event); 94 | LUAI_FUNC int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, 95 | int inv, int isfloat, TMS event); 96 | 97 | LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams, 98 | struct CallInfo *ci, const Proto *p); 99 | LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci, 100 | StkId where, int wanted); 101 | 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /3rdlibs/lua/include/lmem.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.h $ 3 | ** Interface to Memory Manager 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lmem_h 8 | #define lmem_h 9 | 10 | 11 | #include 12 | 13 | #include "llimits.h" 14 | #include "lua.h" 15 | 16 | 17 | #define luaM_error(L) luaD_throw(L, LUA_ERRMEM) 18 | 19 | 20 | /* 21 | ** This macro tests whether it is safe to multiply 'n' by the size of 22 | ** type 't' without overflows. Because 'e' is always constant, it avoids 23 | ** the runtime division MAX_SIZET/(e). 24 | ** (The macro is somewhat complex to avoid warnings: The 'sizeof' 25 | ** comparison avoids a runtime comparison when overflow cannot occur. 26 | ** The compiler should be able to optimize the real test by itself, but 27 | ** when it does it, it may give a warning about "comparison is always 28 | ** false due to limited range of data type"; the +1 tricks the compiler, 29 | ** avoiding this warning but also this optimization.) 30 | */ 31 | #define luaM_testsize(n,e) \ 32 | (sizeof(n) >= sizeof(size_t) && cast_sizet((n)) + 1 > MAX_SIZET/(e)) 33 | 34 | #define luaM_checksize(L,n,e) \ 35 | (luaM_testsize(n,e) ? luaM_toobig(L) : cast_void(0)) 36 | 37 | 38 | /* 39 | ** Computes the minimum between 'n' and 'MAX_SIZET/sizeof(t)', so that 40 | ** the result is not larger than 'n' and cannot overflow a 'size_t' 41 | ** when multiplied by the size of type 't'. (Assumes that 'n' is an 42 | ** 'int' or 'unsigned int' and that 'int' is not larger than 'size_t'.) 43 | */ 44 | #define luaM_limitN(n,t) \ 45 | ((cast_sizet(n) <= MAX_SIZET/sizeof(t)) ? (n) : \ 46 | cast_uint((MAX_SIZET/sizeof(t)))) 47 | 48 | 49 | /* 50 | ** Arrays of chars do not need any test 51 | */ 52 | #define luaM_reallocvchar(L,b,on,n) \ 53 | cast_charp(luaM_saferealloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char))) 54 | 55 | #define luaM_freemem(L, b, s) luaM_free_(L, (b), (s)) 56 | #define luaM_free(L, b) luaM_free_(L, (b), sizeof(*(b))) 57 | #define luaM_freearray(L, b, n) luaM_free_(L, (b), (n)*sizeof(*(b))) 58 | 59 | #define luaM_new(L,t) cast(t*, luaM_malloc_(L, sizeof(t), 0)) 60 | #define luaM_newvector(L,n,t) cast(t*, luaM_malloc_(L, (n)*sizeof(t), 0)) 61 | #define luaM_newvectorchecked(L,n,t) \ 62 | (luaM_checksize(L,n,sizeof(t)), luaM_newvector(L,n,t)) 63 | 64 | #define luaM_newobject(L,tag,s) luaM_malloc_(L, (s), tag) 65 | 66 | #define luaM_growvector(L,v,nelems,size,t,limit,e) \ 67 | ((v)=cast(t *, luaM_growaux_(L,v,nelems,&(size),sizeof(t), \ 68 | luaM_limitN(limit,t),e))) 69 | 70 | #define luaM_reallocvector(L, v,oldn,n,t) \ 71 | (cast(t *, luaM_realloc_(L, v, cast_sizet(oldn) * sizeof(t), \ 72 | cast_sizet(n) * sizeof(t)))) 73 | 74 | #define luaM_shrinkvector(L,v,size,fs,t) \ 75 | ((v)=cast(t *, luaM_shrinkvector_(L, v, &(size), fs, sizeof(t)))) 76 | 77 | LUAI_FUNC l_noret luaM_toobig (lua_State *L); 78 | 79 | /* not to be called directly */ 80 | LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, 81 | size_t size); 82 | LUAI_FUNC void *luaM_saferealloc_ (lua_State *L, void *block, size_t oldsize, 83 | size_t size); 84 | LUAI_FUNC void luaM_free_ (lua_State *L, void *block, size_t osize); 85 | LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int nelems, 86 | int *size, int size_elem, int limit, 87 | const char *what); 88 | LUAI_FUNC void *luaM_shrinkvector_ (lua_State *L, void *block, int *nelem, 89 | int final_n, int size_elem); 90 | LUAI_FUNC void *luaM_malloc_ (lua_State *L, size_t size, int tag); 91 | 92 | #endif 93 | 94 | -------------------------------------------------------------------------------- /3rdlibs/lua/include/ltests.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltests.h $ 3 | ** Internal Header for Debugging of the Lua Implementation 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltests_h 8 | #define ltests_h 9 | 10 | 11 | #include 12 | #include 13 | 14 | /* test Lua with compatibility code */ 15 | #define LUA_COMPAT_MATHLIB 16 | #define LUA_COMPAT_LT_LE 17 | 18 | 19 | #define LUA_DEBUG 20 | 21 | 22 | /* turn on assertions */ 23 | #define LUAI_ASSERT 24 | 25 | 26 | /* to avoid warnings, and to make sure value is really unused */ 27 | #define UNUSED(x) (x=0, (void)(x)) 28 | 29 | 30 | /* test for sizes in 'l_sprintf' (make sure whole buffer is available) */ 31 | #undef l_sprintf 32 | #if !defined(LUA_USE_C89) 33 | #define l_sprintf(s,sz,f,i) (memset(s,0xAB,sz), snprintf(s,sz,f,i)) 34 | #else 35 | #define l_sprintf(s,sz,f,i) (memset(s,0xAB,sz), sprintf(s,f,i)) 36 | #endif 37 | 38 | 39 | /* get a chance to test code without jump tables */ 40 | #define LUA_USE_JUMPTABLE 0 41 | 42 | 43 | /* use 32-bit integers in random generator */ 44 | #define LUA_RAND32 45 | 46 | 47 | /* memory-allocator control variables */ 48 | typedef struct Memcontrol { 49 | int failnext; 50 | unsigned long numblocks; 51 | unsigned long total; 52 | unsigned long maxmem; 53 | unsigned long memlimit; 54 | unsigned long countlimit; 55 | unsigned long objcount[LUA_NUMTYPES]; 56 | } Memcontrol; 57 | 58 | LUA_API Memcontrol l_memcontrol; 59 | 60 | 61 | /* 62 | ** generic variable for debug tricks 63 | */ 64 | extern void *l_Trick; 65 | 66 | 67 | 68 | /* 69 | ** Function to traverse and check all memory used by Lua 70 | */ 71 | LUAI_FUNC int lua_checkmemory (lua_State *L); 72 | 73 | /* 74 | ** Function to print an object GC-friendly 75 | */ 76 | struct GCObject; 77 | LUAI_FUNC void lua_printobj (lua_State *L, struct GCObject *o); 78 | 79 | 80 | /* test for lock/unlock */ 81 | 82 | struct L_EXTRA { int lock; int *plock; }; 83 | #undef LUA_EXTRASPACE 84 | #define LUA_EXTRASPACE sizeof(struct L_EXTRA) 85 | #define getlock(l) cast(struct L_EXTRA*, lua_getextraspace(l)) 86 | #define luai_userstateopen(l) \ 87 | (getlock(l)->lock = 0, getlock(l)->plock = &(getlock(l)->lock)) 88 | #define luai_userstateclose(l) \ 89 | lua_assert(getlock(l)->lock == 1 && getlock(l)->plock == &(getlock(l)->lock)) 90 | #define luai_userstatethread(l,l1) \ 91 | lua_assert(getlock(l1)->plock == getlock(l)->plock) 92 | #define luai_userstatefree(l,l1) \ 93 | lua_assert(getlock(l)->plock == getlock(l1)->plock) 94 | #define lua_lock(l) lua_assert((*getlock(l)->plock)++ == 0) 95 | #define lua_unlock(l) lua_assert(--(*getlock(l)->plock) == 0) 96 | 97 | 98 | 99 | LUA_API int luaB_opentests (lua_State *L); 100 | 101 | LUA_API void *debug_realloc (void *ud, void *block, 102 | size_t osize, size_t nsize); 103 | 104 | #if defined(lua_c) 105 | #define luaL_newstate() lua_newstate(debug_realloc, &l_memcontrol) 106 | #define luaL_openlibs(L) \ 107 | { (luaL_openlibs)(L); \ 108 | luaL_requiref(L, "T", luaB_opentests, 1); \ 109 | lua_pop(L, 1); } 110 | #endif 111 | 112 | 113 | 114 | /* change some sizes to give some bugs a chance */ 115 | 116 | #undef LUAL_BUFFERSIZE 117 | #define LUAL_BUFFERSIZE 23 118 | #define MINSTRTABSIZE 2 119 | #define MAXIWTHABS 3 120 | 121 | #define STRCACHE_N 23 122 | #define STRCACHE_M 5 123 | 124 | #undef LUAI_USER_ALIGNMENT_T 125 | #define LUAI_USER_ALIGNMENT_T union { char b[sizeof(void*) * 8]; } 126 | 127 | 128 | /* make stack-overflow tests run faster */ 129 | #undef LUAI_MAXSTACK 130 | #define LUAI_MAXSTACK 50000 131 | 132 | 133 | /* test mode uses more stack space */ 134 | #undef LUAI_MAXCCALLS 135 | #define LUAI_MAXCCALLS 180 136 | 137 | 138 | /* force Lua to use its own implementations */ 139 | #undef lua_strx2number 140 | #undef lua_number2strx 141 | 142 | 143 | #endif 144 | 145 | -------------------------------------------------------------------------------- /bins/luabind.cpp: -------------------------------------------------------------------------------- 1 | #include "refl.hpp" 2 | #include "luabind.hpp" 3 | 4 | struct Person { 5 | Person(const std::string& name): name(name) {} 6 | std::string name; 7 | }; 8 | 9 | struct TestClass final { 10 | TestClass(int a): value(a) {} 11 | TestClass(Person&& p): person(std::move(p)) {} 12 | 13 | int GetValue() const { return value; } 14 | 15 | void SetValue(int v) { 16 | value = std::move(v); 17 | } 18 | 19 | void SetPerson(Person&& p) { 20 | person = std::move(p); 21 | } 22 | 23 | void InvalidFunction() { 24 | std::cout << "Invalid function" << std::endl; 25 | } 26 | 27 | void PrintType(const std::string&) const { 28 | std::cout << "string" << std::endl; 29 | } 30 | void PrintType(float) const { 31 | std::cout << "number" << std::endl; 32 | } 33 | void PrintType(Person&& p) const { 34 | std::cout << "person" << std::endl; 35 | } 36 | 37 | void ChangeNameFunc() { 38 | std::cout << "my real name is ChangeNameFunc" << std::endl; 39 | } 40 | 41 | TestClass operator+(float value) const { 42 | std::cout << "plused " << value << std::endl; 43 | return *this; 44 | } 45 | 46 | int value; 47 | 48 | Person person{"no-name"}; 49 | }; 50 | 51 | ReflClass(Person) { 52 | Constructors(Person(const std::string&)) 53 | Fields() 54 | }; 55 | 56 | enum MyEnum { 57 | Value1 = 123, 58 | Value2 = 45, 59 | }; 60 | 61 | ReflClass(TestClass) { 62 | Constructors(TestClass(int), TestClass(Person&&)) 63 | Fields( 64 | Field("value", &TestClass::value), 65 | Field("GetValue", &TestClass::GetValue), 66 | Field("SetValue", &TestClass::SetValue), 67 | Field("SetPerson", &TestClass::SetPerson), 68 | Field("operator+", &TestClass::operator+), 69 | Overload("PrintType", 70 | static_cast(&TestClass::PrintType), 71 | static_cast(&TestClass::PrintType), 72 | static_cast(&TestClass::PrintType)), 73 | AttrField(Attrs(luabind::LuaBindName), "ChangeNameFunc", &TestClass::ChangeNameFunc), 74 | AttrField(Attrs(luabind::LuaNoBind), "InvalidFunction", &TestClass::InvalidFunction), 75 | ) 76 | }; 77 | 78 | ReflEnum(MyEnum, int) { 79 | EnumValues( 80 | EnumValue("Value1", MyEnum::Value1), 81 | EnumValue("Value2", MyEnum::Value2), 82 | ) 83 | }; 84 | 85 | 86 | struct Name { 87 | Name(Name&&) = default; 88 | void SetValue(int&& value) { this->value = value; } 89 | int value; 90 | }; 91 | 92 | ReflClass(Name) { 93 | Constructors(Name(Name&&)) 94 | Fields( 95 | Overload("SetValue", static_cast(&Name::SetValue)) 96 | ) 97 | }; 98 | 99 | int main() { 100 | sol::state lua; 101 | lua.open_libraries(sol::lib::base); 102 | luabind::BindClass(lua, "TestClass"); 103 | luabind::BindEnum(lua, "MyEnum"); 104 | luabind::BindClass(lua, "Name"); 105 | lua.script(R"( 106 | function Test() 107 | local a = TestClass.new(123) 108 | print(a:GetValue()) 109 | print(a.value) 110 | a = a + 5.0 111 | a:SetValue(234) 112 | print(a.value) 113 | a:PrintType("haha") 114 | a:PrintType(123) 115 | if a.InvalidFunction then 116 | a:InvalidFunction() 117 | end 118 | if a.foo then 119 | a:foo() 120 | end 121 | print(MyEnum.Value1) 122 | print(MyEnum.Value2) 123 | end 124 | )"); 125 | 126 | sol::protected_function f(lua["Test"]); 127 | sol::protected_function_result result = f(); 128 | if (!result.valid()) { 129 | sol::error err = result; 130 | std::string what = err.what(); 131 | std::cout << "call failed, sol::error::what() is:" << std::endl << what << std::endl; 132 | } 133 | 134 | 135 | return 0; 136 | } -------------------------------------------------------------------------------- /tweeny.hpp: -------------------------------------------------------------------------------- 1 | //! @file tweeny.hpp 2 | //! @brief a small tween lib for game and gui interaction 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace tweeny { 12 | 13 | enum class TweenyDirection { 14 | Forward = 1, 15 | Backward = -1, 16 | }; 17 | 18 | template 19 | using TweenFunc = std::function; 20 | 21 | template 22 | struct Easing { 23 | inline static TweenFunc Linear = [](float t, T a, T b) { return a + (b - a) * t; }; 24 | }; 25 | 26 | template 27 | class Tween final { 28 | public: 29 | 30 | static Tween From(T from) { 31 | Tween tweeny; 32 | tweeny.keyPoints_.push_back({from, 0}); 33 | return tweeny; 34 | } 35 | 36 | Tween& To(T value) { 37 | keyPoints_.push_back({value, 0}); 38 | return *this; 39 | } 40 | 41 | Tween& Via(TweenFunc func) { 42 | func_ = func; 43 | return *this; 44 | } 45 | 46 | Tween& Loop(int loop) { 47 | loop_ = loop; 48 | return *this; 49 | } 50 | 51 | Tween& Timing(float time) { 52 | if (!keyPoints_.empty()) { 53 | keyPoints_.back().time = time; 54 | } 55 | return *this; 56 | } 57 | 58 | Tween& During(float during) { 59 | if (keyPoints_.size() >= 2) { 60 | keyPoints_.back().time = keyPoints_[keyPoints_.size() - 2].time + during; 61 | } 62 | return *this; 63 | } 64 | 65 | auto Direction() const { 66 | return direction_; 67 | } 68 | 69 | Tween& Forward() { 70 | direction_ = TweenyDirection::Forward; 71 | return *this; 72 | } 73 | 74 | Tween& Backward() { 75 | direction_ = TweenyDirection::Backward; 76 | return *this; 77 | } 78 | 79 | void Step(T step) { 80 | if (keyPoints_.size() < 2) { 81 | return; 82 | } 83 | 84 | curDur_ += static_cast(direction_) * step; 85 | const auto& from = keyPoints_[curPoint_]; 86 | const auto& to = keyPoints_[curPoint_ + 1]; 87 | if (curDur_ < from.time) { 88 | curPoint_ --; 89 | } else if (curDur_ > to.time) { 90 | curPoint_ ++; 91 | } 92 | 93 | if (curPoint_ < 0) { 94 | curPoint_ = 0; 95 | curDur_ = keyPoints_[curPoint_].time; 96 | if (loop_ != 0) { 97 | curPoint_ = keyPoints_.size() - 2; 98 | curDur_ = keyPoints_.back().time; 99 | loop_ -= loop_ < 0 ? 0 : 1; 100 | } 101 | } else if (curPoint_ + 2 >= keyPoints_.size() && curDur_ >= to.time) { 102 | curPoint_ = keyPoints_.size() - 2; 103 | curDur_ = keyPoints_.back().time; 104 | if (loop_ != 0) { 105 | curPoint_ = 0; 106 | curDur_ = 0; 107 | loop_ -= loop_ < 0 ? 0 : 1; 108 | } 109 | } 110 | } 111 | 112 | T CurValue() const { 113 | if (keyPoints_.size() < 2) { 114 | if (keyPoints_.size() == 1) { 115 | return keyPoints_.back().value; 116 | } else { 117 | return T{}; 118 | } 119 | } 120 | 121 | if (curPoint_ >= keyPoints_.size() - 1) { 122 | return keyPoints_.back().value; 123 | } 124 | 125 | const auto& from = keyPoints_[curPoint_]; 126 | const auto& to = keyPoints_[curPoint_ + 1]; 127 | return func_(static_cast(curDur_ - from.time) / (to.time - from.time), 128 | from.value, to.value); 129 | } 130 | 131 | T CurTick() const { 132 | return curDur_; 133 | } 134 | 135 | private: 136 | struct KeyPoint { 137 | T value; 138 | float time; 139 | }; 140 | 141 | TweenFunc func_ = Easing::Linear; 142 | std::vector keyPoints_; 143 | int loop_ = 0; 144 | TweenyDirection direction_ = TweenyDirection::Forward; 145 | T curDur_ = 0; 146 | size_t curPoint_ = 0; 147 | }; 148 | 149 | } -------------------------------------------------------------------------------- /3rdlibs/lua/include/lcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcode.h $ 3 | ** Code generator for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lcode_h 8 | #define lcode_h 9 | 10 | #include "llex.h" 11 | #include "lobject.h" 12 | #include "lopcodes.h" 13 | #include "lparser.h" 14 | 15 | 16 | /* 17 | ** Marks the end of a patch list. It is an invalid value both as an absolute 18 | ** address, and as a list link (would link an element to itself). 19 | */ 20 | #define NO_JUMP (-1) 21 | 22 | 23 | /* 24 | ** grep "ORDER OPR" if you change these enums (ORDER OP) 25 | */ 26 | typedef enum BinOpr { 27 | /* arithmetic operators */ 28 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW, 29 | OPR_DIV, OPR_IDIV, 30 | /* bitwise operators */ 31 | OPR_BAND, OPR_BOR, OPR_BXOR, 32 | OPR_SHL, OPR_SHR, 33 | /* string operator */ 34 | OPR_CONCAT, 35 | /* comparison operators */ 36 | OPR_EQ, OPR_LT, OPR_LE, 37 | OPR_NE, OPR_GT, OPR_GE, 38 | /* logical operators */ 39 | OPR_AND, OPR_OR, 40 | OPR_NOBINOPR 41 | } BinOpr; 42 | 43 | 44 | /* true if operation is foldable (that is, it is arithmetic or bitwise) */ 45 | #define foldbinop(op) ((op) <= OPR_SHR) 46 | 47 | 48 | #define luaK_codeABC(fs,o,a,b,c) luaK_codeABCk(fs,o,a,b,c,0) 49 | 50 | 51 | typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; 52 | 53 | 54 | /* get (pointer to) instruction of given 'expdesc' */ 55 | #define getinstruction(fs,e) ((fs)->f->code[(e)->u.info]) 56 | 57 | 58 | #define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) 59 | 60 | #define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) 61 | 62 | LUAI_FUNC int luaK_code (FuncState *fs, Instruction i); 63 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); 64 | LUAI_FUNC int luaK_codeAsBx (FuncState *fs, OpCode o, int A, int Bx); 65 | LUAI_FUNC int luaK_codeABCk (FuncState *fs, OpCode o, int A, 66 | int B, int C, int k); 67 | LUAI_FUNC int luaK_isKint (expdesc *e); 68 | LUAI_FUNC int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v); 69 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); 70 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); 71 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); 72 | LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); 73 | LUAI_FUNC void luaK_int (FuncState *fs, int reg, lua_Integer n); 74 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); 75 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); 76 | LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); 77 | LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); 78 | LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); 79 | LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); 80 | LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); 81 | LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); 82 | LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); 83 | LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e); 84 | LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); 85 | LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); 86 | LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); 87 | LUAI_FUNC int luaK_jump (FuncState *fs); 88 | LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); 89 | LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); 90 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); 91 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); 92 | LUAI_FUNC int luaK_getlabel (FuncState *fs); 93 | LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); 94 | LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); 95 | LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, 96 | expdesc *v2, int line); 97 | LUAI_FUNC void luaK_settablesize (FuncState *fs, int pc, 98 | int ra, int asize, int hsize); 99 | LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); 100 | LUAI_FUNC void luaK_finish (FuncState *fs); 101 | LUAI_FUNC l_noret luaK_semerror (LexState *ls, const char *msg); 102 | 103 | 104 | #endif 105 | -------------------------------------------------------------------------------- /bins/gogl_triangle.cpp: -------------------------------------------------------------------------------- 1 | #include "gogl.hpp" 2 | #include "GLFW/glfw3.h" 3 | #include "log.hpp" 4 | 5 | #define STB_IMAGE_IMPLEMENTATION 6 | #include "3rdlibs/stb_image.h" 7 | 8 | #include 9 | #include 10 | 11 | using namespace gogl; 12 | 13 | struct Context final { 14 | std::unique_ptr bufmgr; 15 | std::unique_ptr texmgr; 16 | std::unique_ptr shadermgr; 17 | std::unique_ptr attrmgr; 18 | 19 | Context() 20 | : bufmgr(std::make_unique()), 21 | texmgr(std::make_unique()), 22 | shadermgr(std::make_unique()), 23 | attrmgr(std::make_unique()) { } 24 | }; 25 | 26 | void ErrorCallback(int error, const char* description) { 27 | LOGE("[GLFW]: ", error, " - ", description); 28 | } 29 | 30 | constexpr int WindowWidth = 1024; 31 | constexpr int WindowHeight = 720; 32 | 33 | int main() { 34 | if (!glfwInit()) { 35 | LOGF("[APP]: glfw init failed"); 36 | return 1; 37 | } 38 | 39 | glfwSetErrorCallback(ErrorCallback); 40 | 41 | glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); 42 | glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 43 | GLFWwindow* window = glfwCreateWindow(WindowWidth, WindowHeight, "VisualDebugger", NULL, NULL); 44 | if (!window) { 45 | LOGE("[GLFW]: create window failed"); 46 | } 47 | 48 | glfwMakeContextCurrent(window); 49 | glfwSwapInterval(1); // Enable vsync 50 | if (gladLoadGL() == 0) { 51 | LOGF("[GLAD]: glad init failed!"); 52 | return 2; 53 | } 54 | 55 | // create context 56 | std::unique_ptr ctx = std::make_unique(); 57 | 58 | // load shader 59 | std::ifstream vertex_file("./res/shaders/vert.shader"), 60 | fragment_file("./res/shaders/frag.shader"); 61 | std::string vertex_source(std::istreambuf_iterator(vertex_file), (std::istreambuf_iterator())), 62 | fragment_source(std::istreambuf_iterator(fragment_file), (std::istreambuf_iterator())); 63 | ShaderModule vertex = ShaderModule::CreateVertexShader(vertex_source); 64 | ShaderModule fragment = ShaderModule::CreateFragmentShader(fragment_source); 65 | auto& shader = ctx->shadermgr->Create("shader", vertex, fragment); 66 | 67 | // prepare data 68 | float vertices[] = { 69 | // vec3 position, vec2 color, texcoord 70 | -0.5, -0.5, 0, 1.0, 0.0, 0.0, 0.0, 71 | 0.5, -0.5, 0, 0.0, 1.0, 1.0, 0.0, 72 | 0, 0.5, 0, 0.0, 0.0, 0.5, 1.0, 73 | }; 74 | 75 | // create buffer 76 | auto& buffer = ctx->bufmgr->Create("buffer", BufferType::Array); 77 | buffer.Bind(); 78 | buffer.SetData(vertices, sizeof(vertices)); 79 | 80 | // create attribute pointer 81 | auto& pointer = ctx->attrmgr->Create("attr", BufferLayout::CreateFromTypes({ 82 | Attribute::Type::Vec3, 83 | Attribute::Type::Vec2, 84 | Attribute::Type::Vec2, 85 | })); 86 | pointer.Bind(); 87 | 88 | // create texture 89 | int w, h; 90 | stbi_set_flip_vertically_on_load(1); 91 | void* pixels = stbi_load("./res/img/img.jpg", &w, &h, nullptr, 3); 92 | auto &texture = ctx->texmgr->Create("image", 93 | Texture::Type::Dimension2, 94 | pixels, 95 | w, h, 96 | Sampler::CreateLinearRepeat(), 97 | Format::RGB, Format::RGB); 98 | 99 | GL_CALL(glViewport(0, 0, WindowWidth, WindowHeight)); 100 | 101 | shader.SetInt("image", 0); 102 | 103 | while (!glfwWindowShouldClose(window)) { 104 | glfwPollEvents(); 105 | 106 | GL_CALL(glClearColor(0.2, 0.2, 0.2, 1.0)); 107 | GL_CALL(glClear(GL_COLOR_BUFFER_BIT)); 108 | pointer.Bind(); 109 | shader.Use(); 110 | texture.Bind(); 111 | 112 | shader.DrawArray(PrimitiveType::Triangles, 0, 3); 113 | 114 | glfwSwapBuffers(window); 115 | } 116 | 117 | ctx.reset(); 118 | 119 | glfwDestroyWindow(window); 120 | glfwTerminate(); 121 | return 0; 122 | } -------------------------------------------------------------------------------- /bins/refl.cpp: -------------------------------------------------------------------------------- 1 | #include "refl.hpp" 2 | 3 | #define CATCH_CONFIG_MAIN 4 | #include "3rdlibs/catch.hpp" 5 | 6 | struct TestClass final { 7 | float fvalue; 8 | double dvalue; 9 | 10 | static int StaticFunc(float, double) { return 123; } 11 | std::string MemberFunc(double&, char&&) { return ""; } 12 | 13 | void OverloadFunc(int) {} 14 | void OverloadFunc(double) {} 15 | 16 | TestClass(float) {} 17 | TestClass(double) {} 18 | }; 19 | 20 | 21 | ReflClass(TestClass) { 22 | Constructors(TestClass(float), TestClass(double)) 23 | Fields( 24 | Field("fvalue", &TestClass::fvalue), 25 | Field("dvalue", &TestClass::dvalue), 26 | Field("StaticFunc", TestClass::StaticFunc), 27 | Field("MemberFunc", &TestClass::MemberFunc), 28 | Overload("OverloadFunc", 29 | static_cast(&TestClass::OverloadFunc), 30 | static_cast(&TestClass::OverloadFunc)), 31 | ) 32 | }; 33 | 34 | enum MyEnum { 35 | Value1 = 123, 36 | Value2 = 277, 37 | Value3 = 45, 38 | }; 39 | 40 | ReflEnum(MyEnum, int) { 41 | EnumValues( 42 | EnumValue("Value1", MyEnum::Value1), 43 | EnumValue("Value2", MyEnum::Value2), 44 | EnumValue("Value3", MyEnum::Value3) 45 | ) 46 | }; 47 | 48 | TEST_CASE("reflection") { 49 | constexpr auto info = refl::TypeInfo(); 50 | static_assert(std::is_same_v); 51 | 52 | SECTION("member1") { 53 | constexpr auto& member = std::get<0>(info.fields); 54 | using type = std::remove_const_t(info.fields))>>; 55 | static_assert(member.isStatic == false); 56 | static_assert(std::is_same_v); 57 | static_assert(member.name == "fvalue"); 58 | static_assert(member.pointer == &TestClass::fvalue); 59 | } 60 | 61 | SECTION("member2") { 62 | constexpr auto& member = std::get<1>(info.fields); 63 | using type = std::remove_const_t(info.fields))>>; 64 | static_assert(member.isStatic == false); 65 | static_assert(member.name == "dvalue"); 66 | static_assert(std::is_same_v); 67 | static_assert(member.pointer == &TestClass::dvalue); 68 | } 69 | 70 | SECTION("static function") { 71 | constexpr auto& member = std::get<2>(info.fields); 72 | using type = std::remove_const_t(info.fields))>>; 73 | static_assert(member.isStatic == true); 74 | static_assert(member.name == "StaticFunc"); 75 | static_assert(std::is_same_v); 76 | static_assert(std::is_same_v>); 77 | static_assert(member.pointer == &TestClass::StaticFunc); 78 | } 79 | 80 | SECTION("member function") { 81 | constexpr auto member = std::get<3>(info.fields); 82 | using type = std::remove_const_t(info.fields))>>; 83 | static_assert(member.isStatic == false); 84 | static_assert(member.name == "MemberFunc"); 85 | static_assert(std::is_same_v); 86 | static_assert(std::is_same_v>); 87 | static_assert(member.pointer == &TestClass::MemberFunc); 88 | static_assert(!refl::IsOverloadFunctions>::value); 89 | 90 | constexpr auto overload = std::get<4>(info.fields); 91 | static_assert(refl::IsOverloadFunctions>::value); 92 | } 93 | 94 | SECTION("enum refl") { 95 | static_assert(refl::EnumInfo::values.size() == 3); 96 | static_assert(refl::EnumInfo::values[0].name == "Value1"); 97 | static_assert(refl::EnumInfo::values[0].value == MyEnum::Value1); 98 | static_assert(refl::EnumInfo::values[1].name == "Value2"); 99 | static_assert(refl::EnumInfo::values[1].value == MyEnum::Value2); 100 | static_assert(refl::EnumInfo::values[2].name == "Value3"); 101 | static_assert(refl::EnumInfo::values[2].value == MyEnum::Value3); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /3rdlibs/lua/src/lopcodes.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopcodes.c $ 3 | ** Opcodes for Lua virtual machine 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lopcodes_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include "lopcodes.h" 14 | 15 | 16 | /* ORDER OP */ 17 | 18 | LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { 19 | /* MM OT IT T A mode opcode */ 20 | opmode(0, 0, 0, 0, 1, iABC) /* OP_MOVE */ 21 | ,opmode(0, 0, 0, 0, 1, iAsBx) /* OP_LOADI */ 22 | ,opmode(0, 0, 0, 0, 1, iAsBx) /* OP_LOADF */ 23 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_LOADK */ 24 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_LOADKX */ 25 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADFALSE */ 26 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LFALSESKIP */ 27 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADTRUE */ 28 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LOADNIL */ 29 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETUPVAL */ 30 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETUPVAL */ 31 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETTABUP */ 32 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETTABLE */ 33 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETI */ 34 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_GETFIELD */ 35 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETTABUP */ 36 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETTABLE */ 37 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETI */ 38 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETFIELD */ 39 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_NEWTABLE */ 40 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SELF */ 41 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADDI */ 42 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADDK */ 43 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SUBK */ 44 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MULK */ 45 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MODK */ 46 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_POWK */ 47 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_DIVK */ 48 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_IDIVK */ 49 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BANDK */ 50 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BORK */ 51 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BXORK */ 52 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHRI */ 53 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHLI */ 54 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADD */ 55 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SUB */ 56 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MUL */ 57 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_MOD */ 58 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_POW */ 59 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_DIV */ 60 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_IDIV */ 61 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BAND */ 62 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BOR */ 63 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BXOR */ 64 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHL */ 65 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SHR */ 66 | ,opmode(1, 0, 0, 0, 0, iABC) /* OP_MMBIN */ 67 | ,opmode(1, 0, 0, 0, 0, iABC) /* OP_MMBINI*/ 68 | ,opmode(1, 0, 0, 0, 0, iABC) /* OP_MMBINK*/ 69 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_UNM */ 70 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_BNOT */ 71 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_NOT */ 72 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_LEN */ 73 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_CONCAT */ 74 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_CLOSE */ 75 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_TBC */ 76 | ,opmode(0, 0, 0, 0, 0, isJ) /* OP_JMP */ 77 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_EQ */ 78 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LT */ 79 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LE */ 80 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_EQK */ 81 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_EQI */ 82 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LTI */ 83 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_LEI */ 84 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_GTI */ 85 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_GEI */ 86 | ,opmode(0, 0, 0, 1, 0, iABC) /* OP_TEST */ 87 | ,opmode(0, 0, 0, 1, 1, iABC) /* OP_TESTSET */ 88 | ,opmode(0, 1, 1, 0, 1, iABC) /* OP_CALL */ 89 | ,opmode(0, 1, 1, 0, 1, iABC) /* OP_TAILCALL */ 90 | ,opmode(0, 0, 1, 0, 0, iABC) /* OP_RETURN */ 91 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_RETURN0 */ 92 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_RETURN1 */ 93 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_FORLOOP */ 94 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_FORPREP */ 95 | ,opmode(0, 0, 0, 0, 0, iABx) /* OP_TFORPREP */ 96 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_TFORCALL */ 97 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_TFORLOOP */ 98 | ,opmode(0, 0, 1, 0, 0, iABC) /* OP_SETLIST */ 99 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_CLOSURE */ 100 | ,opmode(0, 1, 0, 0, 1, iABC) /* OP_VARARG */ 101 | ,opmode(0, 0, 1, 0, 1, iABC) /* OP_VARARGPREP */ 102 | ,opmode(0, 0, 0, 0, 0, iAx) /* OP_EXTRAARG */ 103 | }; 104 | 105 | -------------------------------------------------------------------------------- /bins/serialize.cpp: -------------------------------------------------------------------------------- 1 | #include "serialize.hpp" 2 | 3 | #define CATCH_CONFIG_MAIN 4 | #include "3rdlibs/catch.hpp" 5 | 6 | struct PersonConfig { 7 | std::string name; 8 | float height; 9 | bool female; 10 | }; 11 | 12 | struct FamilyConfig { 13 | PersonConfig mother, father; 14 | std::vector children; 15 | std::string name; 16 | std::array ids; 17 | }; 18 | 19 | struct IDNameMap{ 20 | std::unordered_map data; 21 | }; 22 | 23 | ReflClass(PersonConfig) { 24 | Constructors() 25 | Fields( 26 | Field("name", &PersonConfig::name), 27 | Field("height", &PersonConfig::height), 28 | Field("female", &PersonConfig::female), 29 | ) 30 | }; 31 | 32 | ReflClass(FamilyConfig) { 33 | Constructors() 34 | Fields( 35 | Field("mother", &FamilyConfig::mother), 36 | Field("father", &FamilyConfig::father), 37 | Field("children", &FamilyConfig::children), 38 | Field("name", &FamilyConfig::name), 39 | Field("ids", &FamilyConfig::ids), 40 | ) 41 | }; 42 | 43 | ReflClass(IDNameMap) { 44 | Constructors() 45 | Fields( 46 | Field("data", &IDNameMap::data) 47 | ) 48 | }; 49 | 50 | TEST_CASE("deserialize", "[serialize]") { 51 | sol::state lua; 52 | lua.open_libraries(sol::lib::base); 53 | 54 | SECTION("deserialize plain data") { 55 | lua.do_string(R"( 56 | Config = { 57 | name = "VisualGMQ", 58 | height = 175.0, 59 | female = false, 60 | } 61 | )"); 62 | sol::table table = lua["Config"]; 63 | sol::object obj = table; 64 | std::optional config = serialize::DeserializeFromLua(table); 65 | REQUIRE(config.has_value()); 66 | REQUIRE(config->name == "VisualGMQ"); 67 | REQUIRE(config->height == 175.0); 68 | REQUIRE(config->female == false); 69 | } 70 | 71 | SECTION("deserialize class member") { 72 | lua.do_string(R"( 73 | Config = { 74 | mother = { 75 | name = "mother", 76 | height = 160.3, 77 | female = true, 78 | }, 79 | father = { 80 | name = "father", 81 | height = 175.2, 82 | female = false, 83 | }, 84 | children = { 85 | { 86 | name = "child1", 87 | height = 40.9, 88 | female = false, 89 | }, 90 | { 91 | name = "child2", 92 | height = 55.18, 93 | female = true, 94 | }, 95 | }, 96 | name = "happy family", 97 | ids = { 1, 2, 3, 4 }, 98 | } 99 | )"); 100 | sol::table table = lua["Config"]; 101 | std::optional family = serialize::DeserializeFromLua(table); 102 | REQUIRE(family.has_value()); 103 | REQUIRE(family->mother.name == "mother"); 104 | REQUIRE(family->mother.height == 160.3f); 105 | REQUIRE(family->mother.female == true); 106 | 107 | REQUIRE(family->father.name == "father"); 108 | REQUIRE(family->father.height == 175.2f); 109 | REQUIRE(family->father.female == false); 110 | 111 | REQUIRE(family->children.size() == 2); 112 | 113 | REQUIRE(family->children[0].name == "child1"); 114 | REQUIRE(family->children[0].height == 40.9f); 115 | REQUIRE(family->children[0].female == false); 116 | 117 | REQUIRE(family->children[1].name == "child2"); 118 | REQUIRE(family->children[1].height == 55.18f); 119 | REQUIRE(family->children[1].female == true); 120 | 121 | REQUIRE(family->name == "happy family"); 122 | REQUIRE(family->ids[0] == 1); 123 | REQUIRE(family->ids[1] == 2); 124 | REQUIRE(family->ids[2] == 3); 125 | REQUIRE(family->ids[3] == 4); 126 | } 127 | 128 | SECTION("deserialize unordered_map member") { 129 | lua.do_string(R"( 130 | Config = { 131 | data = { 132 | [3] = "elem3", 133 | [4] = "elem4", 134 | [6] = "elem6", 135 | } 136 | } 137 | )"); 138 | sol::table table = lua["Config"]; 139 | std::optional m = serialize::DeserializeFromLua(table); 140 | REQUIRE(m.has_value()); 141 | REQUIRE(m.value().data[3] == "elem3"); 142 | REQUIRE(m.value().data[4] == "elem4"); 143 | REQUIRE(m.value().data[6] == "elem6"); 144 | } 145 | } -------------------------------------------------------------------------------- /3rdlibs/lua/include/lvm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lvm.h $ 3 | ** Lua virtual machine 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lvm_h 8 | #define lvm_h 9 | 10 | 11 | #include "ldo.h" 12 | #include "lobject.h" 13 | #include "ltm.h" 14 | 15 | 16 | #if !defined(LUA_NOCVTN2S) 17 | #define cvt2str(o) ttisnumber(o) 18 | #else 19 | #define cvt2str(o) 0 /* no conversion from numbers to strings */ 20 | #endif 21 | 22 | 23 | #if !defined(LUA_NOCVTS2N) 24 | #define cvt2num(o) ttisstring(o) 25 | #else 26 | #define cvt2num(o) 0 /* no conversion from strings to numbers */ 27 | #endif 28 | 29 | 30 | /* 31 | ** You can define LUA_FLOORN2I if you want to convert floats to integers 32 | ** by flooring them (instead of raising an error if they are not 33 | ** integral values) 34 | */ 35 | #if !defined(LUA_FLOORN2I) 36 | #define LUA_FLOORN2I F2Ieq 37 | #endif 38 | 39 | 40 | /* 41 | ** Rounding modes for float->integer coercion 42 | */ 43 | typedef enum { 44 | F2Ieq, /* no rounding; accepts only integral values */ 45 | F2Ifloor, /* takes the floor of the number */ 46 | F2Iceil /* takes the ceil of the number */ 47 | } F2Imod; 48 | 49 | 50 | /* convert an object to a float (including string coercion) */ 51 | #define tonumber(o,n) \ 52 | (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n)) 53 | 54 | 55 | /* convert an object to a float (without string coercion) */ 56 | #define tonumberns(o,n) \ 57 | (ttisfloat(o) ? ((n) = fltvalue(o), 1) : \ 58 | (ttisinteger(o) ? ((n) = cast_num(ivalue(o)), 1) : 0)) 59 | 60 | 61 | /* convert an object to an integer (including string coercion) */ 62 | #define tointeger(o,i) \ 63 | (l_likely(ttisinteger(o)) ? (*(i) = ivalue(o), 1) \ 64 | : luaV_tointeger(o,i,LUA_FLOORN2I)) 65 | 66 | 67 | /* convert an object to an integer (without string coercion) */ 68 | #define tointegerns(o,i) \ 69 | (l_likely(ttisinteger(o)) ? (*(i) = ivalue(o), 1) \ 70 | : luaV_tointegerns(o,i,LUA_FLOORN2I)) 71 | 72 | 73 | #define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2)) 74 | 75 | #define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2) 76 | 77 | 78 | /* 79 | ** fast track for 'gettable': if 't' is a table and 't[k]' is present, 80 | ** return 1 with 'slot' pointing to 't[k]' (position of final result). 81 | ** Otherwise, return 0 (meaning it will have to check metamethod) 82 | ** with 'slot' pointing to an empty 't[k]' (if 't' is a table) or NULL 83 | ** (otherwise). 'f' is the raw get function to use. 84 | */ 85 | #define luaV_fastget(L,t,k,slot,f) \ 86 | (!ttistable(t) \ 87 | ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \ 88 | : (slot = f(hvalue(t), k), /* else, do raw access */ \ 89 | !isempty(slot))) /* result not empty? */ 90 | 91 | 92 | /* 93 | ** Special case of 'luaV_fastget' for integers, inlining the fast case 94 | ** of 'luaH_getint'. 95 | */ 96 | #define luaV_fastgeti(L,t,k,slot) \ 97 | (!ttistable(t) \ 98 | ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \ 99 | : (slot = (l_castS2U(k) - 1u < hvalue(t)->alimit) \ 100 | ? &hvalue(t)->array[k - 1] : luaH_getint(hvalue(t), k), \ 101 | !isempty(slot))) /* result not empty? */ 102 | 103 | 104 | /* 105 | ** Finish a fast set operation (when fast get succeeds). In that case, 106 | ** 'slot' points to the place to put the value. 107 | */ 108 | #define luaV_finishfastset(L,t,slot,v) \ 109 | { setobj2t(L, cast(TValue *,slot), v); \ 110 | luaC_barrierback(L, gcvalue(t), v); } 111 | 112 | 113 | 114 | 115 | LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2); 116 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); 117 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); 118 | LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); 119 | LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, F2Imod mode); 120 | LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p, 121 | F2Imod mode); 122 | LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode); 123 | LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, 124 | StkId val, const TValue *slot); 125 | LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, 126 | TValue *val, const TValue *slot); 127 | LUAI_FUNC void luaV_finishOp (lua_State *L); 128 | LUAI_FUNC void luaV_execute (lua_State *L, CallInfo *ci); 129 | LUAI_FUNC void luaV_concat (lua_State *L, int total); 130 | LUAI_FUNC lua_Integer luaV_idiv (lua_State *L, lua_Integer x, lua_Integer y); 131 | LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y); 132 | LUAI_FUNC lua_Number luaV_modf (lua_State *L, lua_Number x, lua_Number y); 133 | LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y); 134 | LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); 135 | 136 | #endif 137 | -------------------------------------------------------------------------------- /log.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 VisualGMQ 2 | #pragma once 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace logger { 14 | 15 | enum Level { 16 | Trace = 0, 17 | Debug, 18 | Info, 19 | Warning, 20 | Error, 21 | FatalError, 22 | All, 23 | }; 24 | 25 | class Logger final { 26 | public: 27 | Logger(std::ostream& o): stream_(o), level_(All) {} 28 | 29 | template 30 | void Trace(std::string_view funcName, std::string_view filename, unsigned int line, Args&&... args) { 31 | log(Level::Trace, funcName, filename, line, std::forward(args)...); 32 | } 33 | 34 | template 35 | void Debug(std::string_view funcName, std::string_view filename, unsigned int line, Args&&... args) { 36 | log(Level::Debug, funcName, filename, line, std::forward(args)...); 37 | } 38 | 39 | template 40 | void Info(std::string_view funcName, std::string_view filename, unsigned int line, Args&&... args) { 41 | log(Level::Info, funcName, filename, line, std::forward(args)...); 42 | } 43 | 44 | template 45 | void Warning(std::string_view funcName, std::string_view filename, unsigned int line, Args&&... args) { 46 | log(Level::Warning, funcName, filename, line, std::forward(args)...); 47 | } 48 | 49 | template 50 | void Error(std::string_view funcName, std::string_view filename, unsigned int line, Args&&... args) { 51 | log(Level::Error, funcName, filename, line, std::forward(args)...); 52 | } 53 | 54 | template 55 | void FatalError(std::string_view funcName, std::string_view filename, unsigned int line, Args&&... args) { 56 | log(Level::FatalError, funcName, filename, line, std::forward(args)...); 57 | } 58 | 59 | void SetLevel(Level level) { level_ = level; } 60 | 61 | private: 62 | std::ostream& stream_; 63 | Level level_; 64 | 65 | template 66 | void log(Level level, std::string_view funcName, std::string_view filename, unsigned int line, Args&&... args) { 67 | if (level <= level_) { 68 | printf("[%s][%s][%s][%u]", Level2Str(level).data(), filename.data(), funcName.data(), line); 69 | doLog(std::forward(args)...); 70 | stream_ << std::endl; 71 | } 72 | } 73 | 74 | template 75 | void doLog(ParamT&& param, Params&&... params) { 76 | stream_ << param; 77 | doLog(std::forward(params)...); 78 | } 79 | 80 | template 81 | void doLog(ParamT&& param) { 82 | stream_ << param; 83 | } 84 | 85 | std::string_view Level2Str(Level level) { 86 | #define CASE(level) case Level::level: return #level; 87 | switch (level) { 88 | CASE(Trace) 89 | CASE(Debug) 90 | CASE(Info) 91 | CASE(Warning) 92 | CASE(Error) 93 | CASE(FatalError) 94 | default: 95 | return ""; 96 | } 97 | #undef CASE 98 | } 99 | }; 100 | 101 | class LoggerMgr final { 102 | public: 103 | static LoggerMgr& Instance() { 104 | static std::unique_ptr instance; 105 | if (!instance) { 106 | instance.reset(new LoggerMgr()); 107 | } 108 | return *instance; 109 | } 110 | 111 | static Logger& CreateFromFile(const std::string& name, const std::string& filename, bool append = false) { 112 | auto& instance = Instance(); 113 | instance.files_.emplace_back(filename, append ? std::ios::app : std::ios::trunc); 114 | return instance.loggers_.emplace(name, Logger(instance.files_.back())).first->second; 115 | } 116 | 117 | static Logger& CreateFromOstream(const std::string& name, std::ostream& o) { 118 | auto& instance = Instance(); 119 | return instance.loggers_.emplace(name, o).first->second; 120 | } 121 | 122 | Logger& GetDefault() { return *defaultLogger_; } 123 | 124 | private: 125 | std::vector files_; 126 | std::map loggers_; 127 | std::unique_ptr defaultLogger_; 128 | 129 | LoggerMgr() { 130 | defaultLogger_.reset(new Logger(std::cout)); 131 | } 132 | }; 133 | 134 | #define LOGT(...) logger::LoggerMgr::Instance().GetDefault().Trace(__FUNCTION__, __FILE__, __LINE__, ## __VA_ARGS__) 135 | #define LOGD(...) logger::LoggerMgr::Instance().GetDefault().Debug(__FUNCTION__, __FILE__, __LINE__, ## __VA_ARGS__) 136 | #define LOGI(...) logger::LoggerMgr::Instance().GetDefault().Info(__FUNCTION__, __FILE__, __LINE__, ## __VA_ARGS__) 137 | #define LOGW(...) logger::LoggerMgr::Instance().GetDefault().Warning(__FUNCTION__, __FILE__, __LINE__, ## __VA_ARGS__) 138 | #define LOGE(...) logger::LoggerMgr::Instance().GetDefault().Error(__FUNCTION__, __FILE__, __LINE__, ## __VA_ARGS__) 139 | #define LOGF(...) logger::LoggerMgr::Instance().GetDefault().FatalError(__FUNCTION__, __FILE__, __LINE__, ## __VA_ARGS__) 140 | 141 | } // namespace logger 142 | -------------------------------------------------------------------------------- /3rdlibs/lua/src/lcorolib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcorolib.c $ 3 | ** Coroutine Library 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lcorolib_c 8 | #define LUA_LIB 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "lauxlib.h" 18 | #include "lualib.h" 19 | 20 | 21 | static lua_State *getco (lua_State *L) { 22 | lua_State *co = lua_tothread(L, 1); 23 | luaL_argexpected(L, co, 1, "thread"); 24 | return co; 25 | } 26 | 27 | 28 | /* 29 | ** Resumes a coroutine. Returns the number of results for non-error 30 | ** cases or -1 for errors. 31 | */ 32 | static int auxresume (lua_State *L, lua_State *co, int narg) { 33 | int status, nres; 34 | if (l_unlikely(!lua_checkstack(co, narg))) { 35 | lua_pushliteral(L, "too many arguments to resume"); 36 | return -1; /* error flag */ 37 | } 38 | lua_xmove(L, co, narg); 39 | status = lua_resume(co, L, narg, &nres); 40 | if (l_likely(status == LUA_OK || status == LUA_YIELD)) { 41 | if (l_unlikely(!lua_checkstack(L, nres + 1))) { 42 | lua_pop(co, nres); /* remove results anyway */ 43 | lua_pushliteral(L, "too many results to resume"); 44 | return -1; /* error flag */ 45 | } 46 | lua_xmove(co, L, nres); /* move yielded values */ 47 | return nres; 48 | } 49 | else { 50 | lua_xmove(co, L, 1); /* move error message */ 51 | return -1; /* error flag */ 52 | } 53 | } 54 | 55 | 56 | static int luaB_coresume (lua_State *L) { 57 | lua_State *co = getco(L); 58 | int r; 59 | r = auxresume(L, co, lua_gettop(L) - 1); 60 | if (l_unlikely(r < 0)) { 61 | lua_pushboolean(L, 0); 62 | lua_insert(L, -2); 63 | return 2; /* return false + error message */ 64 | } 65 | else { 66 | lua_pushboolean(L, 1); 67 | lua_insert(L, -(r + 1)); 68 | return r + 1; /* return true + 'resume' returns */ 69 | } 70 | } 71 | 72 | 73 | static int luaB_auxwrap (lua_State *L) { 74 | lua_State *co = lua_tothread(L, lua_upvalueindex(1)); 75 | int r = auxresume(L, co, lua_gettop(L)); 76 | if (l_unlikely(r < 0)) { /* error? */ 77 | int stat = lua_status(co); 78 | if (stat != LUA_OK && stat != LUA_YIELD) { /* error in the coroutine? */ 79 | stat = lua_resetthread(co); /* close its tbc variables */ 80 | lua_assert(stat != LUA_OK); 81 | lua_xmove(co, L, 1); /* move error message to the caller */ 82 | } 83 | if (stat != LUA_ERRMEM && /* not a memory error and ... */ 84 | lua_type(L, -1) == LUA_TSTRING) { /* ... error object is a string? */ 85 | luaL_where(L, 1); /* add extra info, if available */ 86 | lua_insert(L, -2); 87 | lua_concat(L, 2); 88 | } 89 | return lua_error(L); /* propagate error */ 90 | } 91 | return r; 92 | } 93 | 94 | 95 | static int luaB_cocreate (lua_State *L) { 96 | lua_State *NL; 97 | luaL_checktype(L, 1, LUA_TFUNCTION); 98 | NL = lua_newthread(L); 99 | lua_pushvalue(L, 1); /* move function to top */ 100 | lua_xmove(L, NL, 1); /* move function from L to NL */ 101 | return 1; 102 | } 103 | 104 | 105 | static int luaB_cowrap (lua_State *L) { 106 | luaB_cocreate(L); 107 | lua_pushcclosure(L, luaB_auxwrap, 1); 108 | return 1; 109 | } 110 | 111 | 112 | static int luaB_yield (lua_State *L) { 113 | return lua_yield(L, lua_gettop(L)); 114 | } 115 | 116 | 117 | #define COS_RUN 0 118 | #define COS_DEAD 1 119 | #define COS_YIELD 2 120 | #define COS_NORM 3 121 | 122 | 123 | static const char *const statname[] = 124 | {"running", "dead", "suspended", "normal"}; 125 | 126 | 127 | static int auxstatus (lua_State *L, lua_State *co) { 128 | if (L == co) return COS_RUN; 129 | else { 130 | switch (lua_status(co)) { 131 | case LUA_YIELD: 132 | return COS_YIELD; 133 | case LUA_OK: { 134 | lua_Debug ar; 135 | if (lua_getstack(co, 0, &ar)) /* does it have frames? */ 136 | return COS_NORM; /* it is running */ 137 | else if (lua_gettop(co) == 0) 138 | return COS_DEAD; 139 | else 140 | return COS_YIELD; /* initial state */ 141 | } 142 | default: /* some error occurred */ 143 | return COS_DEAD; 144 | } 145 | } 146 | } 147 | 148 | 149 | static int luaB_costatus (lua_State *L) { 150 | lua_State *co = getco(L); 151 | lua_pushstring(L, statname[auxstatus(L, co)]); 152 | return 1; 153 | } 154 | 155 | 156 | static int luaB_yieldable (lua_State *L) { 157 | lua_State *co = lua_isnone(L, 1) ? L : getco(L); 158 | lua_pushboolean(L, lua_isyieldable(co)); 159 | return 1; 160 | } 161 | 162 | 163 | static int luaB_corunning (lua_State *L) { 164 | int ismain = lua_pushthread(L); 165 | lua_pushboolean(L, ismain); 166 | return 2; 167 | } 168 | 169 | 170 | static int luaB_close (lua_State *L) { 171 | lua_State *co = getco(L); 172 | int status = auxstatus(L, co); 173 | switch (status) { 174 | case COS_DEAD: case COS_YIELD: { 175 | status = lua_resetthread(co); 176 | if (status == LUA_OK) { 177 | lua_pushboolean(L, 1); 178 | return 1; 179 | } 180 | else { 181 | lua_pushboolean(L, 0); 182 | lua_xmove(co, L, 1); /* move error message */ 183 | return 2; 184 | } 185 | } 186 | default: /* normal or running coroutine */ 187 | return luaL_error(L, "cannot close a %s coroutine", statname[status]); 188 | } 189 | } 190 | 191 | 192 | static const luaL_Reg co_funcs[] = { 193 | {"create", luaB_cocreate}, 194 | {"resume", luaB_coresume}, 195 | {"running", luaB_corunning}, 196 | {"status", luaB_costatus}, 197 | {"wrap", luaB_cowrap}, 198 | {"yield", luaB_yield}, 199 | {"isyieldable", luaB_yieldable}, 200 | {"close", luaB_close}, 201 | {NULL, NULL} 202 | }; 203 | 204 | 205 | 206 | LUAMOD_API int luaopen_coroutine (lua_State *L) { 207 | luaL_newlib(L, co_funcs); 208 | return 1; 209 | } 210 | 211 | -------------------------------------------------------------------------------- /3rdlibs/lua/src/ldump.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldump.c $ 3 | ** save precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define ldump_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "lobject.h" 18 | #include "lstate.h" 19 | #include "lundump.h" 20 | 21 | 22 | typedef struct { 23 | lua_State *L; 24 | lua_Writer writer; 25 | void *data; 26 | int strip; 27 | int status; 28 | } DumpState; 29 | 30 | 31 | /* 32 | ** All high-level dumps go through dumpVector; you can change it to 33 | ** change the endianness of the result 34 | */ 35 | #define dumpVector(D,v,n) dumpBlock(D,v,(n)*sizeof((v)[0])) 36 | 37 | #define dumpLiteral(D, s) dumpBlock(D,s,sizeof(s) - sizeof(char)) 38 | 39 | 40 | static void dumpBlock (DumpState *D, const void *b, size_t size) { 41 | if (D->status == 0 && size > 0) { 42 | lua_unlock(D->L); 43 | D->status = (*D->writer)(D->L, b, size, D->data); 44 | lua_lock(D->L); 45 | } 46 | } 47 | 48 | 49 | #define dumpVar(D,x) dumpVector(D,&x,1) 50 | 51 | 52 | static void dumpByte (DumpState *D, int y) { 53 | lu_byte x = (lu_byte)y; 54 | dumpVar(D, x); 55 | } 56 | 57 | 58 | /* dumpInt Buff Size */ 59 | #define DIBS ((sizeof(size_t) * 8 / 7) + 1) 60 | 61 | static void dumpSize (DumpState *D, size_t x) { 62 | lu_byte buff[DIBS]; 63 | int n = 0; 64 | do { 65 | buff[DIBS - (++n)] = x & 0x7f; /* fill buffer in reverse order */ 66 | x >>= 7; 67 | } while (x != 0); 68 | buff[DIBS - 1] |= 0x80; /* mark last byte */ 69 | dumpVector(D, buff + DIBS - n, n); 70 | } 71 | 72 | 73 | static void dumpInt (DumpState *D, int x) { 74 | dumpSize(D, x); 75 | } 76 | 77 | 78 | static void dumpNumber (DumpState *D, lua_Number x) { 79 | dumpVar(D, x); 80 | } 81 | 82 | 83 | static void dumpInteger (DumpState *D, lua_Integer x) { 84 | dumpVar(D, x); 85 | } 86 | 87 | 88 | static void dumpString (DumpState *D, const TString *s) { 89 | if (s == NULL) 90 | dumpSize(D, 0); 91 | else { 92 | size_t size = tsslen(s); 93 | const char *str = getstr(s); 94 | dumpSize(D, size + 1); 95 | dumpVector(D, str, size); 96 | } 97 | } 98 | 99 | 100 | static void dumpCode (DumpState *D, const Proto *f) { 101 | dumpInt(D, f->sizecode); 102 | dumpVector(D, f->code, f->sizecode); 103 | } 104 | 105 | 106 | static void dumpFunction(DumpState *D, const Proto *f, TString *psource); 107 | 108 | static void dumpConstants (DumpState *D, const Proto *f) { 109 | int i; 110 | int n = f->sizek; 111 | dumpInt(D, n); 112 | for (i = 0; i < n; i++) { 113 | const TValue *o = &f->k[i]; 114 | int tt = ttypetag(o); 115 | dumpByte(D, tt); 116 | switch (tt) { 117 | case LUA_VNUMFLT: 118 | dumpNumber(D, fltvalue(o)); 119 | break; 120 | case LUA_VNUMINT: 121 | dumpInteger(D, ivalue(o)); 122 | break; 123 | case LUA_VSHRSTR: 124 | case LUA_VLNGSTR: 125 | dumpString(D, tsvalue(o)); 126 | break; 127 | default: 128 | lua_assert(tt == LUA_VNIL || tt == LUA_VFALSE || tt == LUA_VTRUE); 129 | } 130 | } 131 | } 132 | 133 | 134 | static void dumpProtos (DumpState *D, const Proto *f) { 135 | int i; 136 | int n = f->sizep; 137 | dumpInt(D, n); 138 | for (i = 0; i < n; i++) 139 | dumpFunction(D, f->p[i], f->source); 140 | } 141 | 142 | 143 | static void dumpUpvalues (DumpState *D, const Proto *f) { 144 | int i, n = f->sizeupvalues; 145 | dumpInt(D, n); 146 | for (i = 0; i < n; i++) { 147 | dumpByte(D, f->upvalues[i].instack); 148 | dumpByte(D, f->upvalues[i].idx); 149 | dumpByte(D, f->upvalues[i].kind); 150 | } 151 | } 152 | 153 | 154 | static void dumpDebug (DumpState *D, const Proto *f) { 155 | int i, n; 156 | n = (D->strip) ? 0 : f->sizelineinfo; 157 | dumpInt(D, n); 158 | dumpVector(D, f->lineinfo, n); 159 | n = (D->strip) ? 0 : f->sizeabslineinfo; 160 | dumpInt(D, n); 161 | for (i = 0; i < n; i++) { 162 | dumpInt(D, f->abslineinfo[i].pc); 163 | dumpInt(D, f->abslineinfo[i].line); 164 | } 165 | n = (D->strip) ? 0 : f->sizelocvars; 166 | dumpInt(D, n); 167 | for (i = 0; i < n; i++) { 168 | dumpString(D, f->locvars[i].varname); 169 | dumpInt(D, f->locvars[i].startpc); 170 | dumpInt(D, f->locvars[i].endpc); 171 | } 172 | n = (D->strip) ? 0 : f->sizeupvalues; 173 | dumpInt(D, n); 174 | for (i = 0; i < n; i++) 175 | dumpString(D, f->upvalues[i].name); 176 | } 177 | 178 | 179 | static void dumpFunction (DumpState *D, const Proto *f, TString *psource) { 180 | if (D->strip || f->source == psource) 181 | dumpString(D, NULL); /* no debug info or same source as its parent */ 182 | else 183 | dumpString(D, f->source); 184 | dumpInt(D, f->linedefined); 185 | dumpInt(D, f->lastlinedefined); 186 | dumpByte(D, f->numparams); 187 | dumpByte(D, f->is_vararg); 188 | dumpByte(D, f->maxstacksize); 189 | dumpCode(D, f); 190 | dumpConstants(D, f); 191 | dumpUpvalues(D, f); 192 | dumpProtos(D, f); 193 | dumpDebug(D, f); 194 | } 195 | 196 | 197 | static void dumpHeader (DumpState *D) { 198 | dumpLiteral(D, LUA_SIGNATURE); 199 | dumpByte(D, LUAC_VERSION); 200 | dumpByte(D, LUAC_FORMAT); 201 | dumpLiteral(D, LUAC_DATA); 202 | dumpByte(D, sizeof(Instruction)); 203 | dumpByte(D, sizeof(lua_Integer)); 204 | dumpByte(D, sizeof(lua_Number)); 205 | dumpInteger(D, LUAC_INT); 206 | dumpNumber(D, LUAC_NUM); 207 | } 208 | 209 | 210 | /* 211 | ** dump Lua function as precompiled chunk 212 | */ 213 | int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, 214 | int strip) { 215 | DumpState D; 216 | D.L = L; 217 | D.writer = w; 218 | D.data = data; 219 | D.strip = strip; 220 | D.status = 0; 221 | dumpHeader(&D); 222 | dumpByte(&D, f->sizeupvalues); 223 | dumpFunction(&D, f, NULL); 224 | return D.status; 225 | } 226 | 227 | -------------------------------------------------------------------------------- /3rdlibs/lua/include/lparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lparser.h $ 3 | ** Lua Parser 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lparser_h 8 | #define lparser_h 9 | 10 | #include "llimits.h" 11 | #include "lobject.h" 12 | #include "lzio.h" 13 | 14 | 15 | /* 16 | ** Expression and variable descriptor. 17 | ** Code generation for variables and expressions can be delayed to allow 18 | ** optimizations; An 'expdesc' structure describes a potentially-delayed 19 | ** variable/expression. It has a description of its "main" value plus a 20 | ** list of conditional jumps that can also produce its value (generated 21 | ** by short-circuit operators 'and'/'or'). 22 | */ 23 | 24 | /* kinds of variables/expressions */ 25 | typedef enum { 26 | VVOID, /* when 'expdesc' describes the last expression of a list, 27 | this kind means an empty list (so, no expression) */ 28 | VNIL, /* constant nil */ 29 | VTRUE, /* constant true */ 30 | VFALSE, /* constant false */ 31 | VK, /* constant in 'k'; info = index of constant in 'k' */ 32 | VKFLT, /* floating constant; nval = numerical float value */ 33 | VKINT, /* integer constant; ival = numerical integer value */ 34 | VKSTR, /* string constant; strval = TString address; 35 | (string is fixed by the lexer) */ 36 | VNONRELOC, /* expression has its value in a fixed register; 37 | info = result register */ 38 | VLOCAL, /* local variable; var.ridx = register index; 39 | var.vidx = relative index in 'actvar.arr' */ 40 | VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */ 41 | VCONST, /* compile-time variable; 42 | info = absolute index in 'actvar.arr' */ 43 | VINDEXED, /* indexed variable; 44 | ind.t = table register; 45 | ind.idx = key's R index */ 46 | VINDEXUP, /* indexed upvalue; 47 | ind.t = table upvalue; 48 | ind.idx = key's K index */ 49 | VINDEXI, /* indexed variable with constant integer; 50 | ind.t = table register; 51 | ind.idx = key's value */ 52 | VINDEXSTR, /* indexed variable with literal string; 53 | ind.t = table register; 54 | ind.idx = key's K index */ 55 | VJMP, /* expression is a test/comparison; 56 | info = pc of corresponding jump instruction */ 57 | VRELOC, /* expression can put result in any register; 58 | info = instruction pc */ 59 | VCALL, /* expression is a function call; info = instruction pc */ 60 | VVARARG /* vararg expression; info = instruction pc */ 61 | } expkind; 62 | 63 | 64 | #define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXSTR) 65 | #define vkisindexed(k) (VINDEXED <= (k) && (k) <= VINDEXSTR) 66 | 67 | 68 | typedef struct expdesc { 69 | expkind k; 70 | union { 71 | lua_Integer ival; /* for VKINT */ 72 | lua_Number nval; /* for VKFLT */ 73 | TString *strval; /* for VKSTR */ 74 | int info; /* for generic use */ 75 | struct { /* for indexed variables */ 76 | short idx; /* index (R or "long" K) */ 77 | lu_byte t; /* table (register or upvalue) */ 78 | } ind; 79 | struct { /* for local variables */ 80 | lu_byte ridx; /* register holding the variable */ 81 | unsigned short vidx; /* compiler index (in 'actvar.arr') */ 82 | } var; 83 | } u; 84 | int t; /* patch list of 'exit when true' */ 85 | int f; /* patch list of 'exit when false' */ 86 | } expdesc; 87 | 88 | 89 | /* kinds of variables */ 90 | #define VDKREG 0 /* regular */ 91 | #define RDKCONST 1 /* constant */ 92 | #define RDKTOCLOSE 2 /* to-be-closed */ 93 | #define RDKCTC 3 /* compile-time constant */ 94 | 95 | /* description of an active local variable */ 96 | typedef union Vardesc { 97 | struct { 98 | TValuefields; /* constant value (if it is a compile-time constant) */ 99 | lu_byte kind; 100 | lu_byte ridx; /* register holding the variable */ 101 | short pidx; /* index of the variable in the Proto's 'locvars' array */ 102 | TString *name; /* variable name */ 103 | } vd; 104 | TValue k; /* constant value (if any) */ 105 | } Vardesc; 106 | 107 | 108 | 109 | /* description of pending goto statements and label statements */ 110 | typedef struct Labeldesc { 111 | TString *name; /* label identifier */ 112 | int pc; /* position in code */ 113 | int line; /* line where it appeared */ 114 | lu_byte nactvar; /* number of active variables in that position */ 115 | lu_byte close; /* goto that escapes upvalues */ 116 | } Labeldesc; 117 | 118 | 119 | /* list of labels or gotos */ 120 | typedef struct Labellist { 121 | Labeldesc *arr; /* array */ 122 | int n; /* number of entries in use */ 123 | int size; /* array size */ 124 | } Labellist; 125 | 126 | 127 | /* dynamic structures used by the parser */ 128 | typedef struct Dyndata { 129 | struct { /* list of all active local variables */ 130 | Vardesc *arr; 131 | int n; 132 | int size; 133 | } actvar; 134 | Labellist gt; /* list of pending gotos */ 135 | Labellist label; /* list of active labels */ 136 | } Dyndata; 137 | 138 | 139 | /* control of blocks */ 140 | struct BlockCnt; /* defined in lparser.c */ 141 | 142 | 143 | /* state needed to generate code for a given function */ 144 | typedef struct FuncState { 145 | Proto *f; /* current function header */ 146 | struct FuncState *prev; /* enclosing function */ 147 | struct LexState *ls; /* lexical state */ 148 | struct BlockCnt *bl; /* chain of current blocks */ 149 | int pc; /* next position to code (equivalent to 'ncode') */ 150 | int lasttarget; /* 'label' of last 'jump label' */ 151 | int previousline; /* last line that was saved in 'lineinfo' */ 152 | int nk; /* number of elements in 'k' */ 153 | int np; /* number of elements in 'p' */ 154 | int nabslineinfo; /* number of elements in 'abslineinfo' */ 155 | int firstlocal; /* index of first local var (in Dyndata array) */ 156 | int firstlabel; /* index of first label (in 'dyd->label->arr') */ 157 | short ndebugvars; /* number of elements in 'f->locvars' */ 158 | lu_byte nactvar; /* number of active local variables */ 159 | lu_byte nups; /* number of upvalues */ 160 | lu_byte freereg; /* first free register */ 161 | lu_byte iwthabs; /* instructions issued since last absolute line info */ 162 | lu_byte needclose; /* function needs to close upvalues when returning */ 163 | } FuncState; 164 | 165 | 166 | LUAI_FUNC int luaY_nvarstack (FuncState *fs); 167 | LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, 168 | Dyndata *dyd, const char *name, int firstchar); 169 | 170 | 171 | #endif 172 | -------------------------------------------------------------------------------- /3rdlibs/lua/src/lmem.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.c $ 3 | ** Interface to Memory Manager 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lmem_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lgc.h" 20 | #include "lmem.h" 21 | #include "lobject.h" 22 | #include "lstate.h" 23 | 24 | 25 | #if defined(EMERGENCYGCTESTS) 26 | /* 27 | ** First allocation will fail whenever not building initial state. 28 | ** (This fail will trigger 'tryagain' and a full GC cycle at every 29 | ** allocation.) 30 | */ 31 | static void *firsttry (global_State *g, void *block, size_t os, size_t ns) { 32 | if (completestate(g) && ns > 0) /* frees never fail */ 33 | return NULL; /* fail */ 34 | else /* normal allocation */ 35 | return (*g->frealloc)(g->ud, block, os, ns); 36 | } 37 | #else 38 | #define firsttry(g,block,os,ns) ((*g->frealloc)(g->ud, block, os, ns)) 39 | #endif 40 | 41 | 42 | 43 | 44 | 45 | /* 46 | ** About the realloc function: 47 | ** void *frealloc (void *ud, void *ptr, size_t osize, size_t nsize); 48 | ** ('osize' is the old size, 'nsize' is the new size) 49 | ** 50 | ** - frealloc(ud, p, x, 0) frees the block 'p' and returns NULL. 51 | ** Particularly, frealloc(ud, NULL, 0, 0) does nothing, 52 | ** which is equivalent to free(NULL) in ISO C. 53 | ** 54 | ** - frealloc(ud, NULL, x, s) creates a new block of size 's' 55 | ** (no matter 'x'). Returns NULL if it cannot create the new block. 56 | ** 57 | ** - otherwise, frealloc(ud, b, x, y) reallocates the block 'b' from 58 | ** size 'x' to size 'y'. Returns NULL if it cannot reallocate the 59 | ** block to the new size. 60 | */ 61 | 62 | 63 | 64 | 65 | /* 66 | ** {================================================================== 67 | ** Functions to allocate/deallocate arrays for the Parser 68 | ** =================================================================== 69 | */ 70 | 71 | /* 72 | ** Minimum size for arrays during parsing, to avoid overhead of 73 | ** reallocating to size 1, then 2, and then 4. All these arrays 74 | ** will be reallocated to exact sizes or erased when parsing ends. 75 | */ 76 | #define MINSIZEARRAY 4 77 | 78 | 79 | void *luaM_growaux_ (lua_State *L, void *block, int nelems, int *psize, 80 | int size_elems, int limit, const char *what) { 81 | void *newblock; 82 | int size = *psize; 83 | if (nelems + 1 <= size) /* does one extra element still fit? */ 84 | return block; /* nothing to be done */ 85 | if (size >= limit / 2) { /* cannot double it? */ 86 | if (l_unlikely(size >= limit)) /* cannot grow even a little? */ 87 | luaG_runerror(L, "too many %s (limit is %d)", what, limit); 88 | size = limit; /* still have at least one free place */ 89 | } 90 | else { 91 | size *= 2; 92 | if (size < MINSIZEARRAY) 93 | size = MINSIZEARRAY; /* minimum size */ 94 | } 95 | lua_assert(nelems + 1 <= size && size <= limit); 96 | /* 'limit' ensures that multiplication will not overflow */ 97 | newblock = luaM_saferealloc_(L, block, cast_sizet(*psize) * size_elems, 98 | cast_sizet(size) * size_elems); 99 | *psize = size; /* update only when everything else is OK */ 100 | return newblock; 101 | } 102 | 103 | 104 | /* 105 | ** In prototypes, the size of the array is also its number of 106 | ** elements (to save memory). So, if it cannot shrink an array 107 | ** to its number of elements, the only option is to raise an 108 | ** error. 109 | */ 110 | void *luaM_shrinkvector_ (lua_State *L, void *block, int *size, 111 | int final_n, int size_elem) { 112 | void *newblock; 113 | size_t oldsize = cast_sizet((*size) * size_elem); 114 | size_t newsize = cast_sizet(final_n * size_elem); 115 | lua_assert(newsize <= oldsize); 116 | newblock = luaM_saferealloc_(L, block, oldsize, newsize); 117 | *size = final_n; 118 | return newblock; 119 | } 120 | 121 | /* }================================================================== */ 122 | 123 | 124 | l_noret luaM_toobig (lua_State *L) { 125 | luaG_runerror(L, "memory allocation error: block too big"); 126 | } 127 | 128 | 129 | /* 130 | ** Free memory 131 | */ 132 | void luaM_free_ (lua_State *L, void *block, size_t osize) { 133 | global_State *g = G(L); 134 | lua_assert((osize == 0) == (block == NULL)); 135 | (*g->frealloc)(g->ud, block, osize, 0); 136 | g->GCdebt -= osize; 137 | } 138 | 139 | 140 | /* 141 | ** In case of allocation fail, this function will do an emergency 142 | ** collection to free some memory and then try the allocation again. 143 | ** The GC should not be called while state is not fully built, as the 144 | ** collector is not yet fully initialized. Also, it should not be called 145 | ** when 'gcstopem' is true, because then the interpreter is in the 146 | ** middle of a collection step. 147 | */ 148 | static void *tryagain (lua_State *L, void *block, 149 | size_t osize, size_t nsize) { 150 | global_State *g = G(L); 151 | if (completestate(g) && !g->gcstopem) { 152 | luaC_fullgc(L, 1); /* try to free some memory... */ 153 | return (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ 154 | } 155 | else return NULL; /* cannot free any memory without a full state */ 156 | } 157 | 158 | 159 | /* 160 | ** Generic allocation routine. 161 | */ 162 | void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { 163 | void *newblock; 164 | global_State *g = G(L); 165 | lua_assert((osize == 0) == (block == NULL)); 166 | newblock = firsttry(g, block, osize, nsize); 167 | if (l_unlikely(newblock == NULL && nsize > 0)) { 168 | newblock = tryagain(L, block, osize, nsize); 169 | if (newblock == NULL) /* still no memory? */ 170 | return NULL; /* do not update 'GCdebt' */ 171 | } 172 | lua_assert((nsize == 0) == (newblock == NULL)); 173 | g->GCdebt = (g->GCdebt + nsize) - osize; 174 | return newblock; 175 | } 176 | 177 | 178 | void *luaM_saferealloc_ (lua_State *L, void *block, size_t osize, 179 | size_t nsize) { 180 | void *newblock = luaM_realloc_(L, block, osize, nsize); 181 | if (l_unlikely(newblock == NULL && nsize > 0)) /* allocation failed? */ 182 | luaM_error(L); 183 | return newblock; 184 | } 185 | 186 | 187 | void *luaM_malloc_ (lua_State *L, size_t size, int tag) { 188 | if (size == 0) 189 | return NULL; /* that's all */ 190 | else { 191 | global_State *g = G(L); 192 | void *newblock = firsttry(g, NULL, tag, size); 193 | if (l_unlikely(newblock == NULL)) { 194 | newblock = tryagain(L, NULL, tag, size); 195 | if (newblock == NULL) 196 | luaM_error(L); 197 | } 198 | g->GCdebt += size; 199 | return newblock; 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /benchmark.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 VisualGMQ 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #ifndef BENCHMARK_REPEAT_NUM 16 | #define BENCHMARK_REPEAT_NUM 1000 17 | #endif 18 | 19 | namespace benchmark { 20 | 21 | class Measure; 22 | 23 | using BenchmarkFunc = std::function; 24 | using BenchmarkFuncWithOp = std::function; 25 | 26 | struct Unit final { 27 | Unit(std::string_view name, BenchmarkFunc func) 28 | : name(name), func(func), time(0) {} 29 | Unit(std::string_view name, BenchmarkFuncWithOp func) 30 | : name(name), funcWithOp(func), time(0) {} 31 | 32 | std::string_view name; 33 | BenchmarkFunc func; 34 | BenchmarkFuncWithOp funcWithOp; 35 | uint64_t time; 36 | }; 37 | 38 | class Measure final { 39 | public: 40 | explicit Measure(Unit& unit) : unit_(unit) {} 41 | 42 | void operator()(BenchmarkFunc func) const { 43 | auto begin = std::chrono::steady_clock::now(); 44 | if (func) { 45 | for (uint64_t i = 0; i < BENCHMARK_REPEAT_NUM; i++) { 46 | (void)func(); 47 | } 48 | } 49 | unit_.time = std::chrono::duration_cast( 50 | std::chrono::steady_clock::now() - begin) 51 | .count(); 52 | } 53 | 54 | private: 55 | Unit& unit_; 56 | }; 57 | 58 | class Group final { 59 | public: 60 | friend class BenchmarkMgr; 61 | 62 | explicit Group(std::string_view name) : name_(name) {} 63 | 64 | void Add(const Unit& unit) { units_.push_back(unit); } 65 | 66 | void DoBenchmark() { 67 | std::cout << "running group " << name_ << std::endl; 68 | for (auto& unit : units_) { 69 | std::cout << "measuring " << unit.name << " ..."; 70 | if (unit.func) { 71 | measureOneUnit(unit); 72 | } else { 73 | measureOneUnitWithExtraOp(unit); 74 | } 75 | std::cout << std::endl; 76 | } 77 | } 78 | 79 | void ShowResult() { 80 | for (auto& unit : units_) { 81 | std::cout << unit.name << ":" << std::endl; 82 | std::cout << "\ttotle time: " << unit.time << "ms" << std::endl; 83 | std::cout << "\taverage time: " 84 | << unit.time / static_cast(BENCHMARK_REPEAT_NUM) 85 | << "ms" << std::endl; 86 | std::cout << std::endl; 87 | } 88 | } 89 | 90 | private: 91 | std::vector units_; 92 | std::string_view name_; 93 | 94 | void measureOneUnit(Unit& unit) const { 95 | if (unit.func) { 96 | Measure measure(unit); 97 | measure(unit.func); 98 | } 99 | } 100 | 101 | void measureOneUnitWithExtraOp(Unit& unit) const { 102 | if (unit.funcWithOp) { 103 | unit.funcWithOp(Measure{unit}); 104 | } 105 | } 106 | }; 107 | 108 | class BenchmarkMgr final { 109 | public: 110 | static BenchmarkMgr& Instance() { 111 | static std::unique_ptr instance; 112 | 113 | if (!instance) { 114 | instance = std::make_unique(); 115 | } 116 | 117 | return *instance; 118 | } 119 | 120 | void RunAll() { 121 | for (auto it = groups_.begin(); it != groups_.end(); it++) { 122 | doBenchmarkInGroup(it->second); 123 | drawGroupSplitLine(); 124 | } 125 | } 126 | 127 | void RunByCmd(int argc, char** argv) { 128 | if (argc == 1) { 129 | RunAll(); 130 | } else { 131 | for (int i = 1; i < argc; i++) { 132 | auto it = groups_.find(argv[i]); 133 | if (it != groups_.end()) { 134 | doBenchmarkInGroup(it->second); 135 | drawGroupSplitLine(); 136 | } 137 | } 138 | } 139 | } 140 | 141 | template 142 | void Run(Names... names) { 143 | doRun(names...); 144 | } 145 | 146 | void BeginGroup(std::string_view name) { group_ = Group(name); } 147 | 148 | void PushCurrentGroup() { 149 | if (group_) { 150 | groups_.emplace(group_->name_, group_.value()); 151 | } 152 | } 153 | 154 | void AddUnit2CurrentGroup(const Unit& unit) { 155 | if (group_) { 156 | group_->Add(unit); 157 | } 158 | } 159 | 160 | private: 161 | std::map groups_; 162 | std::optional group_; 163 | 164 | template 165 | void doRun(Name name, Names... names) { 166 | auto it = groups_.find(name); 167 | if (it != groups_.end()) { 168 | doBenchmarkInGroup(it->second); 169 | drawGroupSplitLine(); 170 | } 171 | doRun(names...); 172 | } 173 | 174 | void doRun(std::string_view name) { 175 | auto it = groups_.find(name); 176 | if (it != groups_.end()) { 177 | doBenchmarkInGroup(it->second); 178 | } 179 | } 180 | 181 | void doRun(const char* name) { 182 | auto it = groups_.find(name); 183 | if (it != groups_.end()) { 184 | doBenchmarkInGroup(it->second); 185 | } 186 | } 187 | 188 | void doBenchmarkInGroup(Group& group) const { 189 | group.DoBenchmark(); 190 | std::cout << std::endl; 191 | group.ShowResult(); 192 | } 193 | 194 | void drawGroupSplitLine() { 195 | std::cout << "--------------------------------" << std::endl; 196 | } 197 | }; 198 | 199 | } // namespace benchmark 200 | 201 | #define BENCHMARK_MAIN int main(int argc, char** argv) 202 | #define BENCHMARK_GROUP(name) \ 203 | benchmark::BenchmarkMgr::Instance().PushCurrentGroup(); \ 204 | benchmark::BenchmarkMgr::Instance().BeginGroup(name); 205 | #define BENCHMARK_ADD(name, func) \ 206 | benchmark::BenchmarkMgr::Instance().AddUnit2CurrentGroup( \ 207 | benchmark::Unit(name, func)); 208 | #define BENCHMARK_RUN_GROUPS(...) \ 209 | benchmark::BenchmarkMgr::Instance().PushCurrentGroup(); \ 210 | benchmark::BenchmarkMgr::Instance().Run(__VA_ARGS__); 211 | #define BENCHMARK_RUN_ALL() \ 212 | benchmark::BenchmarkMgr::Instance().PushCurrentGroup(); \ 213 | benchmark::BenchmarkMgr::Instance().RunAll(); 214 | #define BENCHMARK_RUN() \ 215 | benchmark::BenchmarkMgr::Instance().PushCurrentGroup(); \ 216 | benchmark::BenchmarkMgr::Instance().RunByCmd(argc, argv); 217 | -------------------------------------------------------------------------------- /bins/cgmath_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023 VisualGMQ 2 | // a simple math library for computer graphics and computational geomentry 3 | 4 | #include 5 | 6 | #define CGMATH_NUMERIC_TYPE double 7 | #include "cgmath.hpp" 8 | 9 | #define CATCH_CONFIG_MAIN 10 | #include "3rdlibs/catch.hpp" 11 | 12 | #define FLT_EQ(a, b) (std::abs(a - b) <= std::numeric_limits::epsilon()) 13 | 14 | TEST_CASE("vectors can be add, sub, mul and divide", "[vector]") { 15 | cgmath::Vec2 v1{1, 2}; 16 | cgmath::Vec2 v2{2, 3}; 17 | 18 | SECTION("vector add") { 19 | auto result = v1 + v2; 20 | REQUIRE(result.x == 3); 21 | REQUIRE(result.y == 5); 22 | } 23 | 24 | SECTION("vector sub") { 25 | auto result = v1 - v2; 26 | REQUIRE(result.x == -1); 27 | REQUIRE(result.y == -1); 28 | } 29 | 30 | SECTION("vector mul") { 31 | auto result = v1 * v2; 32 | REQUIRE(result.x == 2); 33 | REQUIRE(result.y == 6); 34 | } 35 | 36 | SECTION("vector div") { 37 | auto result = v1 / v2; 38 | REQUIRE(result.x == 0.5); 39 | REQUIRE(result.y == 2.0 / 3.0); 40 | } 41 | 42 | SECTION("vector mul scalar") { 43 | auto result = v1 * 0.5; 44 | REQUIRE(result.x == 0.5); 45 | REQUIRE(result.y == 1); 46 | result = 0.5 * v1; 47 | REQUIRE(result.x == 0.5); 48 | REQUIRE(result.y == 1); 49 | } 50 | } 51 | 52 | TEST_CASE("vectors can be dot", "[vector]") { 53 | SECTION("vector dot") { 54 | auto result = cgmath::Vec2{1, 2}.Dot(cgmath::Vec2{2, 3}); 55 | REQUIRE(result == 8); 56 | } 57 | } 58 | 59 | TEST_CASE("Vec2 and Vec3 can be cross", "[vector]") { 60 | SECTION("Vec2 cross") { 61 | auto result = cgmath::Vec2{1, 2}.Cross(cgmath::Vec2{2, 3}); 62 | REQUIRE(result == -1); 63 | } 64 | 65 | SECTION("Vec3 cross") { 66 | auto result = cgmath::Vec3{1, 2, 3}.Cross(cgmath::Vec3{4, 5, 6}); 67 | REQUIRE(result.x == -3); 68 | REQUIRE(result.y == 6); 69 | REQUIRE(result.z == -3); 70 | } 71 | } 72 | 73 | TEST_CASE("vectors can get length and normalize", "[vector]") { 74 | SECTION("vector length") { 75 | cgmath::Vec2 v1{1, 2}; 76 | cgmath::Vec2 v2{2, 3}; 77 | REQUIRE(v1.LengthSquare() == 5); 78 | REQUIRE(v2.LengthSquare() == 13); 79 | REQUIRE(FLT_EQ(v1.Length(), std::sqrt(5))); 80 | REQUIRE(FLT_EQ(v2.Length(), std::sqrt(13))); 81 | } 82 | 83 | SECTION("vector normalize") { 84 | cgmath::Vec2 v1{1, 2}; 85 | double len = v1.Length(); 86 | v1.Normalize(); 87 | REQUIRE(v1.x == 1 / len); 88 | REQUIRE(v1.y == 2 / len); 89 | 90 | auto v2 = cgmath::Normalize(cgmath::Vec2{1, 2}); 91 | REQUIRE(v2.x == 1 / len); 92 | REQUIRE(v2.y == 2 / len); 93 | } 94 | } 95 | 96 | TEST_CASE("vectors can be assigned", "[vector]") { 97 | cgmath::Vec2 v1{1, 2}; 98 | cgmath::Vec2 v2 = v1; 99 | v1.x = 3; 100 | REQUIRE(v1.x == 3); 101 | REQUIRE(v2.x == 1); 102 | v2 = v1; 103 | v1.x = 6; 104 | REQUIRE(v2.x == 3); 105 | REQUIRE(v1.x == 6); 106 | } 107 | 108 | TEST_CASE("matrix can be add, sub, multiply and divide", "[matrix]") { 109 | /* 110 | [1, 2] 111 | [3, 4] 112 | */ 113 | cgmath::Mat22 m1 = cgmath::Mat22::FromRow({1, 2, 114 | 3, 4}); 115 | /* 116 | [5, 6] 117 | [7, 8] 118 | */ 119 | cgmath::Mat22 m2 = cgmath::Mat22::FromCol({cgmath::Vec2{5, 7}, 120 | cgmath::Vec2{6, 8}}); 121 | 122 | SECTION("matrix init") { 123 | REQUIRE(m1.Get(0, 0) == 1); 124 | REQUIRE(m1.Get(1, 0) == 2); 125 | REQUIRE(m1.Get(0, 1) == 3); 126 | REQUIRE(m1.Get(1, 1) == 4); 127 | 128 | REQUIRE(m2.Get(0, 0) == 5); 129 | REQUIRE(m2.Get(1, 0) == 6); 130 | REQUIRE(m2.Get(0, 1) == 7); 131 | REQUIRE(m2.Get(1, 1) == 8); 132 | } 133 | 134 | SECTION("matrix add") { 135 | auto m = m1 + m2; 136 | REQUIRE(m.Get(0, 0) == 6); 137 | REQUIRE(m.Get(1, 0) == 8); 138 | REQUIRE(m.Get(0, 1) == 10); 139 | REQUIRE(m.Get(1, 1) == 12); 140 | } 141 | 142 | SECTION("matrix sub") { 143 | auto m = m1 - m2; 144 | REQUIRE(m.Get(0, 0) == -4); 145 | REQUIRE(m.Get(1, 0) == -4); 146 | REQUIRE(m.Get(0, 1) == -4); 147 | REQUIRE(m.Get(1, 1) == -4); 148 | } 149 | 150 | SECTION("matrix mul") { 151 | auto m = MulEach(m1, m2); 152 | REQUIRE(m.Get(0, 0) == 5); 153 | REQUIRE(m.Get(1, 0) == 12); 154 | REQUIRE(m.Get(0, 1) == 21); 155 | REQUIRE(m.Get(1, 1) == 32); 156 | } 157 | 158 | SECTION("matrix div") { 159 | auto m = DivEach(m1, m2); 160 | REQUIRE(m.Get(0, 0) == 1.0 / 5.0); 161 | REQUIRE(m.Get(1, 0) == 2.0 / 6.0); 162 | REQUIRE(m.Get(0, 1) == 3.0 / 7.0); 163 | REQUIRE(m.Get(1, 1) == 4.0 / 8.0); 164 | } 165 | 166 | SECTION("matrix mul scalar") { 167 | auto m = m1 * 2.0; 168 | REQUIRE(m.Get(0, 0) == 2); 169 | REQUIRE(m.Get(1, 0) == 4); 170 | REQUIRE(m.Get(0, 1) == 6); 171 | REQUIRE(m.Get(1, 1) == 8); 172 | 173 | m = 2.0 * m1; 174 | REQUIRE(m.Get(0, 0) == 2); 175 | REQUIRE(m.Get(1, 0) == 4); 176 | REQUIRE(m.Get(0, 1) == 6); 177 | REQUIRE(m.Get(1, 1) == 8); 178 | } 179 | 180 | SECTION("matrix multiply matrix") { 181 | auto m = m1 * m2; 182 | REQUIRE(m.Get(0, 0) == 19); 183 | REQUIRE(m.Get(1, 0) == 22); 184 | REQUIRE(m.Get(0, 1) == 43); 185 | REQUIRE(m.Get(1, 1) == 50); 186 | 187 | auto m3 = cgmath::Mat::FromRow({ 188 | 1, 2, 189 | 3, 4, 190 | 5, 6, 191 | }); 192 | 193 | auto m4 = cgmath::Mat::FromRow({ 194 | 1, 2, 3, 195 | 4, 5, 6, 196 | }); 197 | 198 | auto result = m3 * m4; 199 | REQUIRE(result.W() == 3); 200 | REQUIRE(result.H() == 3); 201 | REQUIRE(result.Get(0, 0) == 9); 202 | REQUIRE(result.Get(1, 0) == 12); 203 | REQUIRE(result.Get(2, 0) == 15); 204 | REQUIRE(result.Get(0, 1) == 19); 205 | REQUIRE(result.Get(1, 1) == 26); 206 | REQUIRE(result.Get(2, 1) == 33); 207 | REQUIRE(result.Get(0, 2) == 29); 208 | REQUIRE(result.Get(1, 2) == 40); 209 | REQUIRE(result.Get(2, 2) == 51); 210 | } 211 | 212 | SECTION("matrix multiple vector") { 213 | auto m = cgmath::Mat22::FromRow({1, 2, 214 | 3, 4}); 215 | cgmath::Vec2 v{6, 7}; 216 | auto result = m * v; 217 | 218 | REQUIRE(result.x == 20); 219 | REQUIRE(result.y == 46); 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /3rdlibs/lua/include/lgc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lgc.h $ 3 | ** Garbage Collector 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lgc_h 8 | #define lgc_h 9 | 10 | 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | 14 | /* 15 | ** Collectable objects may have one of three colors: white, which means 16 | ** the object is not marked; gray, which means the object is marked, but 17 | ** its references may be not marked; and black, which means that the 18 | ** object and all its references are marked. The main invariant of the 19 | ** garbage collector, while marking objects, is that a black object can 20 | ** never point to a white one. Moreover, any gray object must be in a 21 | ** "gray list" (gray, grayagain, weak, allweak, ephemeron) so that it 22 | ** can be visited again before finishing the collection cycle. (Open 23 | ** upvalues are an exception to this rule.) These lists have no meaning 24 | ** when the invariant is not being enforced (e.g., sweep phase). 25 | */ 26 | 27 | 28 | /* 29 | ** Possible states of the Garbage Collector 30 | */ 31 | #define GCSpropagate 0 32 | #define GCSenteratomic 1 33 | #define GCSatomic 2 34 | #define GCSswpallgc 3 35 | #define GCSswpfinobj 4 36 | #define GCSswptobefnz 5 37 | #define GCSswpend 6 38 | #define GCScallfin 7 39 | #define GCSpause 8 40 | 41 | 42 | #define issweepphase(g) \ 43 | (GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend) 44 | 45 | 46 | /* 47 | ** macro to tell when main invariant (white objects cannot point to black 48 | ** ones) must be kept. During a collection, the sweep 49 | ** phase may break the invariant, as objects turned white may point to 50 | ** still-black objects. The invariant is restored when sweep ends and 51 | ** all objects are white again. 52 | */ 53 | 54 | #define keepinvariant(g) ((g)->gcstate <= GCSatomic) 55 | 56 | 57 | /* 58 | ** some useful bit tricks 59 | */ 60 | #define resetbits(x,m) ((x) &= cast_byte(~(m))) 61 | #define setbits(x,m) ((x) |= (m)) 62 | #define testbits(x,m) ((x) & (m)) 63 | #define bitmask(b) (1<<(b)) 64 | #define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) 65 | #define l_setbit(x,b) setbits(x, bitmask(b)) 66 | #define resetbit(x,b) resetbits(x, bitmask(b)) 67 | #define testbit(x,b) testbits(x, bitmask(b)) 68 | 69 | 70 | /* 71 | ** Layout for bit use in 'marked' field. First three bits are 72 | ** used for object "age" in generational mode. Last bit is used 73 | ** by tests. 74 | */ 75 | #define WHITE0BIT 3 /* object is white (type 0) */ 76 | #define WHITE1BIT 4 /* object is white (type 1) */ 77 | #define BLACKBIT 5 /* object is black */ 78 | #define FINALIZEDBIT 6 /* object has been marked for finalization */ 79 | 80 | #define TESTBIT 7 81 | 82 | 83 | 84 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) 85 | 86 | 87 | #define iswhite(x) testbits((x)->marked, WHITEBITS) 88 | #define isblack(x) testbit((x)->marked, BLACKBIT) 89 | #define isgray(x) /* neither white nor black */ \ 90 | (!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT))) 91 | 92 | #define tofinalize(x) testbit((x)->marked, FINALIZEDBIT) 93 | 94 | #define otherwhite(g) ((g)->currentwhite ^ WHITEBITS) 95 | #define isdeadm(ow,m) ((m) & (ow)) 96 | #define isdead(g,v) isdeadm(otherwhite(g), (v)->marked) 97 | 98 | #define changewhite(x) ((x)->marked ^= WHITEBITS) 99 | #define nw2black(x) \ 100 | check_exp(!iswhite(x), l_setbit((x)->marked, BLACKBIT)) 101 | 102 | #define luaC_white(g) cast_byte((g)->currentwhite & WHITEBITS) 103 | 104 | 105 | /* object age in generational mode */ 106 | #define G_NEW 0 /* created in current cycle */ 107 | #define G_SURVIVAL 1 /* created in previous cycle */ 108 | #define G_OLD0 2 /* marked old by frw. barrier in this cycle */ 109 | #define G_OLD1 3 /* first full cycle as old */ 110 | #define G_OLD 4 /* really old object (not to be visited) */ 111 | #define G_TOUCHED1 5 /* old object touched this cycle */ 112 | #define G_TOUCHED2 6 /* old object touched in previous cycle */ 113 | 114 | #define AGEBITS 7 /* all age bits (111) */ 115 | 116 | #define getage(o) ((o)->marked & AGEBITS) 117 | #define setage(o,a) ((o)->marked = cast_byte(((o)->marked & (~AGEBITS)) | a)) 118 | #define isold(o) (getage(o) > G_SURVIVAL) 119 | 120 | #define changeage(o,f,t) \ 121 | check_exp(getage(o) == (f), (o)->marked ^= ((f)^(t))) 122 | 123 | 124 | /* Default Values for GC parameters */ 125 | #define LUAI_GENMAJORMUL 100 126 | #define LUAI_GENMINORMUL 20 127 | 128 | /* wait memory to double before starting new cycle */ 129 | #define LUAI_GCPAUSE 200 130 | 131 | /* 132 | ** some gc parameters are stored divided by 4 to allow a maximum value 133 | ** up to 1023 in a 'lu_byte'. 134 | */ 135 | #define getgcparam(p) ((p) * 4) 136 | #define setgcparam(p,v) ((p) = (v) / 4) 137 | 138 | #define LUAI_GCMUL 100 139 | 140 | /* how much to allocate before next GC step (log2) */ 141 | #define LUAI_GCSTEPSIZE 13 /* 8 KB */ 142 | 143 | 144 | /* 145 | ** Check whether the declared GC mode is generational. While in 146 | ** generational mode, the collector can go temporarily to incremental 147 | ** mode to improve performance. This is signaled by 'g->lastatomic != 0'. 148 | */ 149 | #define isdecGCmodegen(g) (g->gckind == KGC_GEN || g->lastatomic != 0) 150 | 151 | 152 | /* 153 | ** Control when GC is running: 154 | */ 155 | #define GCSTPUSR 1 /* bit true when GC stopped by user */ 156 | #define GCSTPGC 2 /* bit true when GC stopped by itself */ 157 | #define GCSTPCLS 4 /* bit true when closing Lua state */ 158 | #define gcrunning(g) ((g)->gcstp == 0) 159 | 160 | 161 | /* 162 | ** Does one step of collection when debt becomes positive. 'pre'/'pos' 163 | ** allows some adjustments to be done only when needed. macro 164 | ** 'condchangemem' is used only for heavy tests (forcing a full 165 | ** GC cycle on every opportunity) 166 | */ 167 | #define luaC_condGC(L,pre,pos) \ 168 | { if (G(L)->GCdebt > 0) { pre; luaC_step(L); pos;}; \ 169 | condchangemem(L,pre,pos); } 170 | 171 | /* more often than not, 'pre'/'pos' are empty */ 172 | #define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0) 173 | 174 | 175 | #define luaC_barrier(L,p,v) ( \ 176 | (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \ 177 | luaC_barrier_(L,obj2gco(p),gcvalue(v)) : cast_void(0)) 178 | 179 | #define luaC_barrierback(L,p,v) ( \ 180 | (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \ 181 | luaC_barrierback_(L,p) : cast_void(0)) 182 | 183 | #define luaC_objbarrier(L,p,o) ( \ 184 | (isblack(p) && iswhite(o)) ? \ 185 | luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0)) 186 | 187 | LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o); 188 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); 189 | LUAI_FUNC void luaC_step (lua_State *L); 190 | LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); 191 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); 192 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz); 193 | LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); 194 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); 195 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); 196 | LUAI_FUNC void luaC_changemode (lua_State *L, int newmode); 197 | 198 | 199 | #endif 200 | -------------------------------------------------------------------------------- /serialize.hpp: -------------------------------------------------------------------------------- 1 | 2 | #include "refl.hpp" 3 | #define SOL_ALL_SAFETIES_ON 1 4 | #include "sol/sol.hpp" 5 | #include "log.hpp" 6 | 7 | namespace serialize { 8 | 9 | struct DeserialPath { 10 | std::vector path; 11 | 12 | std::string ToString() const { 13 | std::string str; 14 | for (const auto& p : path) { 15 | str += "->" + p; 16 | } 17 | return str; 18 | } 19 | }; 20 | 21 | //! @brief attribute for field, the field is optional 22 | struct SerialOption {}; 23 | 24 | //! @brief attribute for field, the field will not serial/deserial 25 | struct NoSerial {}; 26 | 27 | //! @brief serialize class to lua 28 | //! @tparam T the class you want to serialize 29 | //! @return the serialized lua code, please write then into lua file 30 | template 31 | std::vector SerializeToLua() { 32 | // TODO: not finish 33 | return {}; 34 | } 35 | 36 | //! @brief descrialize class from lua file 37 | //! @tparam T the class you want to deserialize 38 | //! @param lua 39 | //! @return the class instance, failed will return std::nullopt 40 | template 41 | std::optional DeserializeFromLua(sol::object& lua) { 42 | DeserialPath path; 43 | return _deserializeFromLua(lua, path); 44 | } 45 | 46 | template 47 | std::optional _deserializeFromLua(sol::object& lua, DeserialPath& path) { 48 | if constexpr (std::is_class_v && !_isSerialDirectly()) { 49 | using typeinfo = refl::TypeInfo; 50 | if (lua.get_type() == sol::type::table) { 51 | T value; 52 | _deserializeField<0>(value, lua.as(), typeinfo::fields, path); 53 | return value; 54 | } else { 55 | LOGW("[Lua Config Parser]: try to parse a non-table lua node to a class. Path: ", path.ToString()); 56 | return std::nullopt; 57 | } 58 | } else { 59 | if constexpr (_isVector::value) { 60 | using inner_type = _isVector::value_type; 61 | std::vector values; 62 | sol::table table = lua.as(); 63 | for (auto& elem : table) { 64 | auto elem_value = _deserializeFromLua(elem.second, path); 65 | if (elem_value.has_value()) { 66 | values.push_back(elem_value.value()); 67 | } else { 68 | LOGW("[Lua Config Parser]: parse std::vector failed. Path: ", path.ToString()); 69 | return std::nullopt; 70 | } 71 | } 72 | return values; 73 | } else if constexpr (_isArray::value) { 74 | using inner_type = _isArray::value_type; 75 | constexpr size_t require_size = _isArray::size; 76 | sol::table table = lua.as(); 77 | if (table.size() datas; 82 | int i = 0; 83 | for (auto& elem : table) { 84 | auto elem_value = _deserializeFromLua(elem.second, path); 85 | if (elem_value.has_value()) { 86 | datas[i++] = elem_value.value(); 87 | } else { 88 | LOGW("[Lua Config Parser]: parse std::array element failed. Path: ", path.ToString()); 89 | return std::nullopt; 90 | } 91 | } 92 | return datas; 93 | } 94 | } else if constexpr (_isUnorderedMap::value) { 95 | using key = _isUnorderedMap::key; 96 | using type = _isUnorderedMap::type; 97 | std::unordered_map result; 98 | sol::table table = lua.as(); 99 | for (auto& elem : table) { 100 | auto first = _deserializeFromLua(elem.first, path); 101 | if (!first) { 102 | LOGW("[Lua Config Parser]: parse std::unordered_map key element failed. Path: ", path.ToString()); 103 | return std::nullopt; 104 | } 105 | auto second = _deserializeFromLua(elem.second, path); 106 | if (!second) { 107 | LOGW("[Lua Config Parser]: parse std::unordered_map value element failed. Path: ", path.ToString()); 108 | return std::nullopt; 109 | } 110 | result[first.value()] = second.value(); 111 | } 112 | return result; 113 | } else { 114 | return lua.as(); 115 | } 116 | } 117 | } 118 | 119 | inline bool _canSerialDirectly(const sol::object& lua) { 120 | auto type = lua.get_type(); 121 | return type == sol::type::boolean || 122 | type == sol::type::number || 123 | type == sol::type::string || 124 | type == sol::type::function || 125 | type == sol::type::nil || 126 | type == sol::type::lua_nil; 127 | } 128 | 129 | template 130 | struct _isVector { 131 | static constexpr bool value = false; 132 | }; 133 | 134 | template 135 | struct _isVector> { 136 | static constexpr bool value = true; 137 | using value_type = T; 138 | }; 139 | 140 | template 141 | struct _isArray { 142 | static constexpr bool value = false; 143 | }; 144 | 145 | template 146 | struct _isArray> { 147 | static constexpr bool value = true; 148 | using value_type = T; 149 | static constexpr size_t size = N; 150 | }; 151 | 152 | template 153 | struct _isUnorderedMap { 154 | static constexpr bool value = false; 155 | }; 156 | 157 | template 158 | struct _isUnorderedMap> { 159 | static constexpr bool value = true; 160 | using key = Key; 161 | using type = T; 162 | }; 163 | 164 | 165 | template 166 | constexpr bool _isSerialDirectly() { 167 | return std::is_arithmetic_v || 168 | std::is_same_v || 169 | _isVector::value || 170 | _isUnorderedMap::value || 171 | _isArray::value; 172 | } 173 | 174 | template 175 | void _deserializeField(T& value, sol::table& lua, std::tuple fields, DeserialPath& path) { 176 | auto field = std::get(fields); 177 | using field_info = std::tuple_element_t>; 178 | 179 | path.path.push_back(std::string(field.name.data())); 180 | auto lua_field = lua[field.name]; 181 | if (lua_field.valid()) { 182 | if constexpr (_isSerialDirectly()) { 183 | auto field_value = _deserializeFromLua(lua_field.get(), path); 184 | if (field_value) { 185 | value.*field.pointer = field_value.value(); 186 | } else { 187 | LOGW("[Lua Config Parser]: parsing failed, no exists field. Path: ", path.ToString()); 188 | return; 189 | } 190 | } else { 191 | if (lua_field.get_type() == sol::type::table) { 192 | auto field_value = _deserializeFromLua(lua_field.get(), path); 193 | if (field_value) { 194 | value.*field.pointer = field_value.value(); 195 | } else { 196 | LOGW("[Lua Config Parser]: parsing failed, no exists field. Path: ", path.ToString()); 197 | return; 198 | } 199 | } 200 | } 201 | } 202 | 203 | if constexpr (Idx < sizeof...(Types) - 1) { 204 | _deserializeField(value, lua, fields, path); 205 | } 206 | } 207 | 208 | } -------------------------------------------------------------------------------- /luabind.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #define SOL_ALL_SAFETIES_ON 1 3 | #include "sol/sol.hpp" 4 | #include "refl.hpp" 5 | #include 6 | 7 | namespace luabind { 8 | 9 | //! @brief an attribute struct hint to don't bind to lua 10 | struct LuaNoBind final {}; 11 | 12 | //! @brief an attribute struct hint to bind field to a point name 13 | template 14 | struct LuaBindName final { 15 | struct Helper { 16 | static constexpr char name[] = {chars..., 0}; 17 | }; 18 | 19 | static constexpr std::string_view name = Helper::name; 20 | }; 21 | 22 | 23 | template 24 | struct _CtorBindHelper; 25 | 26 | //! @brief a help struct to detect whether parameters is rvalue-reference 27 | template 28 | struct _HasRValueRefParam; 29 | 30 | template 31 | struct _HasRValueRefParam> { 32 | static constexpr bool value = std::is_rvalue_reference_v || _HasRValueRefParam>::value; 33 | }; 34 | 35 | template <> 36 | struct _HasRValueRefParam> { 37 | static constexpr bool value = false; 38 | }; 39 | 40 | template 41 | struct _HasNoRValueRefParamInFunc { 42 | static constexpr bool value = !_HasRValueRefParam::params>::value; 43 | }; 44 | 45 | template 46 | constexpr auto TuplePushfront(T value, std::tuple tpl) { 47 | return std::tuple_cat(std::make_tuple(value), tpl); 48 | } 49 | 50 | template 51 | constexpr auto FirstOfTuple(std::tuple t) { 52 | return std::get<0>(t); 53 | } 54 | 55 | template 56 | constexpr auto FilterNoRValueRefFunc(std::tuple t) { 57 | if constexpr (idx == sizeof...(Types)) { 58 | return std::make_tuple(); 59 | } else { 60 | if constexpr (_HasRValueRefParam< 61 | typename refl::FuncInfoBase>>::params>::value) { 63 | return FilterNoRValueRefFunc(t); 64 | } else { 65 | return TuplePushfront(std::get(t), FilterNoRValueRefFunc(t)); 66 | } 67 | } 68 | } 69 | 70 | enum _AttrType: uint8_t { 71 | Bind = 0, 72 | ChangeName, 73 | NoBind, 74 | }; 75 | 76 | template 77 | struct _GetAttrType { 78 | static constexpr uint8_t value = _AttrType::Bind; 79 | }; 80 | 81 | template <> 82 | struct _GetAttrType { 83 | static constexpr _AttrType value = _AttrType::NoBind; 84 | }; 85 | 86 | template 87 | struct _GetAttrType> { 88 | static constexpr _AttrType value = _AttrType::ChangeName; 89 | }; 90 | 91 | 92 | template 93 | struct _GetHighLevelAttr; 94 | 95 | template 96 | struct _GetHighLevelAttr> { 97 | static constexpr uint8_t _value1 = _GetAttrType::value; 98 | using _later_attr_info = _GetHighLevelAttr; 99 | static constexpr uint8_t _value2 = _later_attr_info::value; 100 | 101 | static constexpr _AttrType value = static_cast<_AttrType>(_value1 > _value2 ? _value1 : _value2); 102 | using type = std::conditional_t<(_value1 > _value2), T, typename _later_attr_info::type>; 103 | }; 104 | 105 | template 106 | struct _GetHighLevelAttr> { 107 | static constexpr uint8_t value = _GetAttrType::value; 108 | using type = T; 109 | }; 110 | 111 | template 112 | struct _CtorBindHelper> { 113 | static auto BindAndCreate(std::string_view name, sol::state& lua){ 114 | return lua.new_usertype(name, sol::constructors()); 115 | } 116 | }; 117 | 118 | template 119 | void _bindOverloadFuncs(sol::usertype& usertype, const std::tuple& funcs, std::string_view name) { 120 | if constexpr (std::tuple_size_v> > 0) { 121 | usertype[name] = sol::overload(std::get(funcs)...); 122 | } 123 | } 124 | 125 | // @brief a helper function to convert C++ operator overload to lua method 126 | inline std::optional _getOperatorLuaName(std::string_view name, bool hasParams) { 127 | if (name == "operator+") { 128 | return "__add"; 129 | } 130 | if (name == "operator-" && hasParams) { 131 | return "__sub"; 132 | } 133 | if (name == "operator-" && !hasParams) { 134 | return "__unm"; 135 | } 136 | if (name == "operator*") { 137 | return "__mul"; 138 | } 139 | if (name == "operator/") { 140 | return "__div"; 141 | } 142 | if (name == "operator<") { 143 | return "__lt"; 144 | } 145 | if (name == "operator==") { 146 | return "__eq"; 147 | } 148 | if (name == "operator()") { 149 | return "__call"; 150 | } 151 | return std::nullopt; 152 | } 153 | 154 | template 155 | void _bindOneField(sol::usertype& usertype, const std::tuple& fields) { 156 | auto field = std::get(fields); 157 | using type = std::tuple_element_t>; 158 | using high_attr = _GetHighLevelAttr; 159 | constexpr auto attr = high_attr::value; 160 | if constexpr (attr != _AttrType::NoBind) { 161 | // detect convertable name 162 | std::string_view name = field.name; 163 | auto operatorName = _getOperatorLuaName(name, 1 /*, params::size != 0*/); 164 | if (operatorName.has_value()) { 165 | name = operatorName.value(); 166 | } 167 | if constexpr (!refl::IsOverloadFunctions::value) { 168 | if constexpr (std::is_member_function_pointer_v) { 169 | using params = typename type::params; 170 | if constexpr (!_HasRValueRefParam::value) { 171 | } 172 | } 173 | } 174 | 175 | if constexpr (refl::IsOverloadFunctions::value) { 176 | _bindOverloadFuncs(usertype, FilterNoRValueRefFunc<0>(field.funcs), name); 177 | } else { 178 | if constexpr (attr == _AttrType::ChangeName) { 179 | usertype[high_attr::type::name] = field.pointer; 180 | } else { 181 | if constexpr (std::is_member_function_pointer_v) { 182 | if constexpr (!_HasRValueRefParam::value) { 183 | usertype[name] = field.pointer; 184 | } 185 | } else { 186 | usertype[name] = field.pointer; 187 | } 188 | } 189 | } 190 | } 191 | 192 | if constexpr (Idx + 1 < sizeof...(Fields)) { 193 | _bindOneField(usertype, fields); 194 | } 195 | } 196 | 197 | template 198 | void _bindFields(sol::usertype& usertype) { 199 | if constexpr (std::tuple_size_v) { 200 | _bindOneField(usertype, ClassInfo::fields); 201 | } 202 | } 203 | 204 | template 205 | void BindClass(sol::state& lua, std::string_view name) { 206 | sol::usertype usertype; 207 | using ClassInfo = refl::TypeInfo; 208 | using filted_constructors = typename refl::Filter<_HasNoRValueRefParamInFunc, typename ClassInfo::constructors>::type; 209 | if constexpr(filted_constructors::size > 0) { 210 | usertype = std::move(_CtorBindHelper::BindAndCreate(name, lua)); 211 | } else { 212 | usertype = std::move(lua.new_usertype(name)); 213 | } 214 | _bindFields(usertype); 215 | } 216 | 217 | template 218 | void _bindEnum(sol::state& lua, std::string_view name, T values, std::index_sequence) { 219 | lua.new_enum(name, {std::pair(values[Idx].name, values[Idx].value)...}); 220 | } 221 | 222 | template 223 | void BindEnum(sol::state& lua, std::string_view name) { 224 | using type = refl::EnumInfo; 225 | constexpr auto values = type::values; 226 | _bindEnum(lua, name, values, std::make_index_sequence()); 227 | } 228 | 229 | 230 | } -------------------------------------------------------------------------------- /expected.hpp: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 VisualGMQ 2 | * this is a C++17 implementation for std::unexpected and std::expected(C++23) 3 | * [reference](https://en.cppreference.com/w/cpp/utility/expected) */ 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | namespace gmq { 15 | 16 | template 17 | class bad_expected_access; 18 | 19 | template <> 20 | class bad_expected_access : public std::exception { 21 | void error() {} 22 | }; 23 | 24 | template 25 | class bad_expected_access : bad_expected_access { 26 | public: 27 | explicit bad_expected_access(const E& error) : error_(error) {} 28 | 29 | const E& error() const& noexcept { return error_; } 30 | E& error() & noexcept { return error_; } 31 | const E&& error() const&& noexcept { return std::move(error_); } 32 | E&& error() && noexcept { return std::move(error_); } 33 | 34 | private: 35 | E error_; 36 | }; 37 | 38 | template 39 | class unexpected final { 40 | public: 41 | constexpr unexpected(const unexpected&) = default; 42 | constexpr unexpected(unexpected&&) = default; 43 | 44 | template 45 | constexpr explicit unexpected( 46 | std::enable_if_t, Err>&& e) 47 | : error_(std::forward(e)) {} 48 | 49 | template 50 | constexpr explicit unexpected( 51 | const std::enable_if_t, Err>& e) 52 | : error_(e) {} 53 | 54 | /* 55 | template 56 | constexpr explicit unexpected(std::in_place_t, Args&&... args) { 57 | // TOOD 58 | } 59 | 60 | template 61 | constexpr explicit unexpected(std::in_place_t, std::initializer_list il, 62 | Args&&... args) { 63 | // TODO 64 | } 65 | */ 66 | 67 | constexpr const E& error() const& noexcept { return error_; } 68 | constexpr E& error() & noexcept { return error_; } 69 | constexpr const E&& error() const&& noexcept { return std::move(error_); } 70 | constexpr E&& error() && noexcept { return std::move(error_); } 71 | 72 | constexpr void swap(unexpected& e) noexcept( 73 | std::is_nothrow_swappable_v) { 74 | std::swap(e, error_); 75 | } 76 | 77 | constexpr bool operator==(const unexpected& o) const { 78 | return o.error() == error(); 79 | } 80 | 81 | private: 82 | E error_; 83 | }; 84 | 85 | template 86 | class expected { 87 | public: 88 | using value_type = std::enable_if_t && 89 | std::is_copy_constructible_v && 90 | std::is_move_constructible_v, 91 | T>; 92 | using error_type = E; 93 | 94 | template 95 | using rebind = expected; 96 | 97 | constexpr explicit expected(const T& value) : data_(value) {} 98 | constexpr explicit expected(T&& value) : data_(std::move(value)) {} 99 | constexpr explicit expected(const unexpected& error) 100 | : data_(error.error()) {} 101 | constexpr explicit expected(unexpected&& err) 102 | : data_(std::move(err.error())) {} 103 | 104 | constexpr const value_type& value() const& { 105 | auto value = std::get_if(data_); 106 | if (value) { 107 | return *value; 108 | } else { 109 | throw bad_expected_access(std::get(data_)); 110 | } 111 | } 112 | 113 | constexpr value_type& value() & { 114 | auto value = std::get_if(&data_); 115 | if (value) { 116 | return *value; 117 | } else { 118 | throw bad_expected_access(std::get(data_)); 119 | } 120 | } 121 | 122 | constexpr const value_type&& value() const&& { 123 | auto value = std::get_if(&data_); 124 | if (value) { 125 | return std::move(*value); 126 | } else { 127 | throw bad_expected_access(std::get(data_)); 128 | } 129 | } 130 | 131 | constexpr value_type&& value() && { 132 | auto value = std::get_if(&data_); 133 | if (value) { 134 | return std::move(*value); 135 | } else { 136 | throw bad_expected_access(std::get(data_)); 137 | } 138 | } 139 | 140 | constexpr const error_type& error() const& noexcept { 141 | return std::get(data_); 142 | } 143 | 144 | constexpr error_type& error() & noexcept { 145 | return std::get(data_); 146 | } 147 | 148 | constexpr const error_type&& error() const&& noexcept { 149 | return std::move(std::get(data_)); 150 | } 151 | 152 | constexpr error_type&& error() && noexcept { 153 | return std::move(std::get(data_)); 154 | } 155 | 156 | operator bool() const { return has_value(); } 157 | 158 | bool has_value() const { return std::get_if(&data_); } 159 | 160 | template 161 | constexpr T value_or(U&& default_value) const& { 162 | return static_cast(*this) ? **this : 163 | static_cast(std::forward(default_value)); 164 | } 165 | 166 | template 167 | constexpr T value_or(U&& default_value) && { 168 | return static_cast(*this) ? std::move(**this) : 169 | static_cast(std::forward(default_value)); 170 | } 171 | 172 | expected& operator=(const expected&) = default; 173 | expected& operator=(const unexpected& error) { 174 | data_ = error.error(); 175 | return *this; 176 | } 177 | 178 | expected& operator=(unexpected&& error) { 179 | data_ = std::move(error.error()); 180 | return *this; 181 | } 182 | 183 | private: 184 | std::variant data_; 185 | }; 186 | 187 | template 188 | class expected { 189 | public: 190 | using value_type = void; 191 | using error_type = E; 192 | 193 | template 194 | using rebind = expected; 195 | 196 | constexpr expected() = default; 197 | constexpr explicit expected(const E& e): error_(e) {} 198 | 199 | template 200 | constexpr expected( 201 | const std::enable_if_t>& e) 202 | : error_(e) {} 203 | 204 | constexpr expected(const unexpected& err) : error_(err.error()) {} 205 | constexpr expected(unexpected&& err) : error_(std::move(err.error())) {} 206 | 207 | constexpr value_type value() const { return; } 208 | constexpr value_type value() { return; } 209 | 210 | operator bool() const { return has_value(); } 211 | 212 | bool has_value() const { return !error_.has_value(); } 213 | 214 | template 215 | constexpr U value_or(U&& default_value) const& { 216 | return std::forward(default_value); 217 | } 218 | 219 | template 220 | constexpr U value_or(U&& default_value) && { 221 | return std::forward(default_value); 222 | } 223 | 224 | constexpr const error_type& error() const& noexcept { 225 | return error_.value(); 226 | } 227 | 228 | constexpr error_type& error() & noexcept { return error_.value(); } 229 | 230 | constexpr const error_type&& error() const&& noexcept { 231 | return std::move(error_.value()); 232 | } 233 | 234 | constexpr error_type&& error() && noexcept { 235 | return std::move(error_.value()); 236 | } 237 | 238 | expected& operator=(const expected&) = default; 239 | expected& operator=(const unexpected& error) { 240 | error_ = error.error(); 241 | return *this; 242 | } 243 | 244 | expected& operator=(unexpected&& error) { 245 | error_ = std::move(error.error()); 246 | return *this; 247 | } 248 | 249 | private: 250 | std::optional error_; 251 | }; 252 | 253 | } // namespace gmq 254 | -------------------------------------------------------------------------------- /3rdlibs/lua/src/lstring.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.c $ 3 | ** String table (keeps all strings handled by Lua) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lstring_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lmem.h" 20 | #include "lobject.h" 21 | #include "lstate.h" 22 | #include "lstring.h" 23 | 24 | 25 | /* 26 | ** Maximum size for string table. 27 | */ 28 | #define MAXSTRTB cast_int(luaM_limitN(MAX_INT, TString*)) 29 | 30 | 31 | /* 32 | ** equality for long strings 33 | */ 34 | int luaS_eqlngstr (TString *a, TString *b) { 35 | size_t len = a->u.lnglen; 36 | lua_assert(a->tt == LUA_VLNGSTR && b->tt == LUA_VLNGSTR); 37 | return (a == b) || /* same instance or... */ 38 | ((len == b->u.lnglen) && /* equal length and ... */ 39 | (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ 40 | } 41 | 42 | 43 | unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { 44 | unsigned int h = seed ^ cast_uint(l); 45 | for (; l > 0; l--) 46 | h ^= ((h<<5) + (h>>2) + cast_byte(str[l - 1])); 47 | return h; 48 | } 49 | 50 | 51 | unsigned int luaS_hashlongstr (TString *ts) { 52 | lua_assert(ts->tt == LUA_VLNGSTR); 53 | if (ts->extra == 0) { /* no hash? */ 54 | size_t len = ts->u.lnglen; 55 | ts->hash = luaS_hash(getstr(ts), len, ts->hash); 56 | ts->extra = 1; /* now it has its hash */ 57 | } 58 | return ts->hash; 59 | } 60 | 61 | 62 | static void tablerehash (TString **vect, int osize, int nsize) { 63 | int i; 64 | for (i = osize; i < nsize; i++) /* clear new elements */ 65 | vect[i] = NULL; 66 | for (i = 0; i < osize; i++) { /* rehash old part of the array */ 67 | TString *p = vect[i]; 68 | vect[i] = NULL; 69 | while (p) { /* for each string in the list */ 70 | TString *hnext = p->u.hnext; /* save next */ 71 | unsigned int h = lmod(p->hash, nsize); /* new position */ 72 | p->u.hnext = vect[h]; /* chain it into array */ 73 | vect[h] = p; 74 | p = hnext; 75 | } 76 | } 77 | } 78 | 79 | 80 | /* 81 | ** Resize the string table. If allocation fails, keep the current size. 82 | ** (This can degrade performance, but any non-zero size should work 83 | ** correctly.) 84 | */ 85 | void luaS_resize (lua_State *L, int nsize) { 86 | stringtable *tb = &G(L)->strt; 87 | int osize = tb->size; 88 | TString **newvect; 89 | if (nsize < osize) /* shrinking table? */ 90 | tablerehash(tb->hash, osize, nsize); /* depopulate shrinking part */ 91 | newvect = luaM_reallocvector(L, tb->hash, osize, nsize, TString*); 92 | if (l_unlikely(newvect == NULL)) { /* reallocation failed? */ 93 | if (nsize < osize) /* was it shrinking table? */ 94 | tablerehash(tb->hash, nsize, osize); /* restore to original size */ 95 | /* leave table as it was */ 96 | } 97 | else { /* allocation succeeded */ 98 | tb->hash = newvect; 99 | tb->size = nsize; 100 | if (nsize > osize) 101 | tablerehash(newvect, osize, nsize); /* rehash for new size */ 102 | } 103 | } 104 | 105 | 106 | /* 107 | ** Clear API string cache. (Entries cannot be empty, so fill them with 108 | ** a non-collectable string.) 109 | */ 110 | void luaS_clearcache (global_State *g) { 111 | int i, j; 112 | for (i = 0; i < STRCACHE_N; i++) 113 | for (j = 0; j < STRCACHE_M; j++) { 114 | if (iswhite(g->strcache[i][j])) /* will entry be collected? */ 115 | g->strcache[i][j] = g->memerrmsg; /* replace it with something fixed */ 116 | } 117 | } 118 | 119 | 120 | /* 121 | ** Initialize the string table and the string cache 122 | */ 123 | void luaS_init (lua_State *L) { 124 | global_State *g = G(L); 125 | int i, j; 126 | stringtable *tb = &G(L)->strt; 127 | tb->hash = luaM_newvector(L, MINSTRTABSIZE, TString*); 128 | tablerehash(tb->hash, 0, MINSTRTABSIZE); /* clear array */ 129 | tb->size = MINSTRTABSIZE; 130 | /* pre-create memory-error message */ 131 | g->memerrmsg = luaS_newliteral(L, MEMERRMSG); 132 | luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */ 133 | for (i = 0; i < STRCACHE_N; i++) /* fill cache with valid strings */ 134 | for (j = 0; j < STRCACHE_M; j++) 135 | g->strcache[i][j] = g->memerrmsg; 136 | } 137 | 138 | 139 | 140 | /* 141 | ** creates a new string object 142 | */ 143 | static TString *createstrobj (lua_State *L, size_t l, int tag, unsigned int h) { 144 | TString *ts; 145 | GCObject *o; 146 | size_t totalsize; /* total size of TString object */ 147 | totalsize = sizelstring(l); 148 | o = luaC_newobj(L, tag, totalsize); 149 | ts = gco2ts(o); 150 | ts->hash = h; 151 | ts->extra = 0; 152 | getstr(ts)[l] = '\0'; /* ending 0 */ 153 | return ts; 154 | } 155 | 156 | 157 | TString *luaS_createlngstrobj (lua_State *L, size_t l) { 158 | TString *ts = createstrobj(L, l, LUA_VLNGSTR, G(L)->seed); 159 | ts->u.lnglen = l; 160 | return ts; 161 | } 162 | 163 | 164 | void luaS_remove (lua_State *L, TString *ts) { 165 | stringtable *tb = &G(L)->strt; 166 | TString **p = &tb->hash[lmod(ts->hash, tb->size)]; 167 | while (*p != ts) /* find previous element */ 168 | p = &(*p)->u.hnext; 169 | *p = (*p)->u.hnext; /* remove element from its list */ 170 | tb->nuse--; 171 | } 172 | 173 | 174 | static void growstrtab (lua_State *L, stringtable *tb) { 175 | if (l_unlikely(tb->nuse == MAX_INT)) { /* too many strings? */ 176 | luaC_fullgc(L, 1); /* try to free some... */ 177 | if (tb->nuse == MAX_INT) /* still too many? */ 178 | luaM_error(L); /* cannot even create a message... */ 179 | } 180 | if (tb->size <= MAXSTRTB / 2) /* can grow string table? */ 181 | luaS_resize(L, tb->size * 2); 182 | } 183 | 184 | 185 | /* 186 | ** Checks whether short string exists and reuses it or creates a new one. 187 | */ 188 | static TString *internshrstr (lua_State *L, const char *str, size_t l) { 189 | TString *ts; 190 | global_State *g = G(L); 191 | stringtable *tb = &g->strt; 192 | unsigned int h = luaS_hash(str, l, g->seed); 193 | TString **list = &tb->hash[lmod(h, tb->size)]; 194 | lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */ 195 | for (ts = *list; ts != NULL; ts = ts->u.hnext) { 196 | if (l == ts->shrlen && (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { 197 | /* found! */ 198 | if (isdead(g, ts)) /* dead (but not collected yet)? */ 199 | changewhite(ts); /* resurrect it */ 200 | return ts; 201 | } 202 | } 203 | /* else must create a new string */ 204 | if (tb->nuse >= tb->size) { /* need to grow string table? */ 205 | growstrtab(L, tb); 206 | list = &tb->hash[lmod(h, tb->size)]; /* rehash with new size */ 207 | } 208 | ts = createstrobj(L, l, LUA_VSHRSTR, h); 209 | memcpy(getstr(ts), str, l * sizeof(char)); 210 | ts->shrlen = cast_byte(l); 211 | ts->u.hnext = *list; 212 | *list = ts; 213 | tb->nuse++; 214 | return ts; 215 | } 216 | 217 | 218 | /* 219 | ** new string (with explicit length) 220 | */ 221 | TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { 222 | if (l <= LUAI_MAXSHORTLEN) /* short string? */ 223 | return internshrstr(L, str, l); 224 | else { 225 | TString *ts; 226 | if (l_unlikely(l >= (MAX_SIZE - sizeof(TString))/sizeof(char))) 227 | luaM_toobig(L); 228 | ts = luaS_createlngstrobj(L, l); 229 | memcpy(getstr(ts), str, l * sizeof(char)); 230 | return ts; 231 | } 232 | } 233 | 234 | 235 | /* 236 | ** Create or reuse a zero-terminated string, first checking in the 237 | ** cache (using the string address as a key). The cache can contain 238 | ** only zero-terminated strings, so it is safe to use 'strcmp' to 239 | ** check hits. 240 | */ 241 | TString *luaS_new (lua_State *L, const char *str) { 242 | unsigned int i = point2uint(str) % STRCACHE_N; /* hash */ 243 | int j; 244 | TString **p = G(L)->strcache[i]; 245 | for (j = 0; j < STRCACHE_M; j++) { 246 | if (strcmp(str, getstr(p[j])) == 0) /* hit? */ 247 | return p[j]; /* that is it */ 248 | } 249 | /* normal route */ 250 | for (j = STRCACHE_M - 1; j > 0; j--) 251 | p[j] = p[j - 1]; /* move out last element */ 252 | /* new element is first in the list */ 253 | p[0] = luaS_newlstr(L, str, strlen(str)); 254 | return p[0]; 255 | } 256 | 257 | 258 | Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue) { 259 | Udata *u; 260 | int i; 261 | GCObject *o; 262 | if (l_unlikely(s > MAX_SIZE - udatamemoffset(nuvalue))) 263 | luaM_toobig(L); 264 | o = luaC_newobj(L, LUA_VUSERDATA, sizeudata(nuvalue, s)); 265 | u = gco2u(o); 266 | u->len = s; 267 | u->nuvalue = nuvalue; 268 | u->metatable = NULL; 269 | for (i = 0; i < nuvalue; i++) 270 | setnilvalue(&u->uv[i].uv); 271 | return u; 272 | } 273 | 274 | -------------------------------------------------------------------------------- /3rdlibs/lua/src/lutf8lib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lutf8lib.c $ 3 | ** Standard library for UTF-8 manipulation 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lutf8lib_c 8 | #define LUA_LIB 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "lua.h" 19 | 20 | #include "lauxlib.h" 21 | #include "lualib.h" 22 | 23 | 24 | #define MAXUNICODE 0x10FFFFu 25 | 26 | #define MAXUTF 0x7FFFFFFFu 27 | 28 | /* 29 | ** Integer type for decoded UTF-8 values; MAXUTF needs 31 bits. 30 | */ 31 | #if (UINT_MAX >> 30) >= 1 32 | typedef unsigned int utfint; 33 | #else 34 | typedef unsigned long utfint; 35 | #endif 36 | 37 | 38 | #define iscont(p) ((*(p) & 0xC0) == 0x80) 39 | 40 | 41 | /* from strlib */ 42 | /* translate a relative string position: negative means back from end */ 43 | static lua_Integer u_posrelat (lua_Integer pos, size_t len) { 44 | if (pos >= 0) return pos; 45 | else if (0u - (size_t)pos > len) return 0; 46 | else return (lua_Integer)len + pos + 1; 47 | } 48 | 49 | 50 | /* 51 | ** Decode one UTF-8 sequence, returning NULL if byte sequence is 52 | ** invalid. The array 'limits' stores the minimum value for each 53 | ** sequence length, to check for overlong representations. Its first 54 | ** entry forces an error for non-ascii bytes with no continuation 55 | ** bytes (count == 0). 56 | */ 57 | static const char *utf8_decode (const char *s, utfint *val, int strict) { 58 | static const utfint limits[] = 59 | {~(utfint)0, 0x80, 0x800, 0x10000u, 0x200000u, 0x4000000u}; 60 | unsigned int c = (unsigned char)s[0]; 61 | utfint res = 0; /* final result */ 62 | if (c < 0x80) /* ascii? */ 63 | res = c; 64 | else { 65 | int count = 0; /* to count number of continuation bytes */ 66 | for (; c & 0x40; c <<= 1) { /* while it needs continuation bytes... */ 67 | unsigned int cc = (unsigned char)s[++count]; /* read next byte */ 68 | if ((cc & 0xC0) != 0x80) /* not a continuation byte? */ 69 | return NULL; /* invalid byte sequence */ 70 | res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ 71 | } 72 | res |= ((utfint)(c & 0x7F) << (count * 5)); /* add first byte */ 73 | if (count > 5 || res > MAXUTF || res < limits[count]) 74 | return NULL; /* invalid byte sequence */ 75 | s += count; /* skip continuation bytes read */ 76 | } 77 | if (strict) { 78 | /* check for invalid code points; too large or surrogates */ 79 | if (res > MAXUNICODE || (0xD800u <= res && res <= 0xDFFFu)) 80 | return NULL; 81 | } 82 | if (val) *val = res; 83 | return s + 1; /* +1 to include first byte */ 84 | } 85 | 86 | 87 | /* 88 | ** utf8len(s [, i [, j [, lax]]]) --> number of characters that 89 | ** start in the range [i,j], or nil + current position if 's' is not 90 | ** well formed in that interval 91 | */ 92 | static int utflen (lua_State *L) { 93 | lua_Integer n = 0; /* counter for the number of characters */ 94 | size_t len; /* string length in bytes */ 95 | const char *s = luaL_checklstring(L, 1, &len); 96 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); 97 | lua_Integer posj = u_posrelat(luaL_optinteger(L, 3, -1), len); 98 | int lax = lua_toboolean(L, 4); 99 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 2, 100 | "initial position out of bounds"); 101 | luaL_argcheck(L, --posj < (lua_Integer)len, 3, 102 | "final position out of bounds"); 103 | while (posi <= posj) { 104 | const char *s1 = utf8_decode(s + posi, NULL, !lax); 105 | if (s1 == NULL) { /* conversion error? */ 106 | luaL_pushfail(L); /* return fail ... */ 107 | lua_pushinteger(L, posi + 1); /* ... and current position */ 108 | return 2; 109 | } 110 | posi = s1 - s; 111 | n++; 112 | } 113 | lua_pushinteger(L, n); 114 | return 1; 115 | } 116 | 117 | 118 | /* 119 | ** codepoint(s, [i, [j [, lax]]]) -> returns codepoints for all 120 | ** characters that start in the range [i,j] 121 | */ 122 | static int codepoint (lua_State *L) { 123 | size_t len; 124 | const char *s = luaL_checklstring(L, 1, &len); 125 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); 126 | lua_Integer pose = u_posrelat(luaL_optinteger(L, 3, posi), len); 127 | int lax = lua_toboolean(L, 4); 128 | int n; 129 | const char *se; 130 | luaL_argcheck(L, posi >= 1, 2, "out of bounds"); 131 | luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of bounds"); 132 | if (posi > pose) return 0; /* empty interval; return no values */ 133 | if (pose - posi >= INT_MAX) /* (lua_Integer -> int) overflow? */ 134 | return luaL_error(L, "string slice too long"); 135 | n = (int)(pose - posi) + 1; /* upper bound for number of returns */ 136 | luaL_checkstack(L, n, "string slice too long"); 137 | n = 0; /* count the number of returns */ 138 | se = s + pose; /* string end */ 139 | for (s += posi - 1; s < se;) { 140 | utfint code; 141 | s = utf8_decode(s, &code, !lax); 142 | if (s == NULL) 143 | return luaL_error(L, "invalid UTF-8 code"); 144 | lua_pushinteger(L, code); 145 | n++; 146 | } 147 | return n; 148 | } 149 | 150 | 151 | static void pushutfchar (lua_State *L, int arg) { 152 | lua_Unsigned code = (lua_Unsigned)luaL_checkinteger(L, arg); 153 | luaL_argcheck(L, code <= MAXUTF, arg, "value out of range"); 154 | lua_pushfstring(L, "%U", (long)code); 155 | } 156 | 157 | 158 | /* 159 | ** utfchar(n1, n2, ...) -> char(n1)..char(n2)... 160 | */ 161 | static int utfchar (lua_State *L) { 162 | int n = lua_gettop(L); /* number of arguments */ 163 | if (n == 1) /* optimize common case of single char */ 164 | pushutfchar(L, 1); 165 | else { 166 | int i; 167 | luaL_Buffer b; 168 | luaL_buffinit(L, &b); 169 | for (i = 1; i <= n; i++) { 170 | pushutfchar(L, i); 171 | luaL_addvalue(&b); 172 | } 173 | luaL_pushresult(&b); 174 | } 175 | return 1; 176 | } 177 | 178 | 179 | /* 180 | ** offset(s, n, [i]) -> index where n-th character counting from 181 | ** position 'i' starts; 0 means character at 'i'. 182 | */ 183 | static int byteoffset (lua_State *L) { 184 | size_t len; 185 | const char *s = luaL_checklstring(L, 1, &len); 186 | lua_Integer n = luaL_checkinteger(L, 2); 187 | lua_Integer posi = (n >= 0) ? 1 : len + 1; 188 | posi = u_posrelat(luaL_optinteger(L, 3, posi), len); 189 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3, 190 | "position out of bounds"); 191 | if (n == 0) { 192 | /* find beginning of current byte sequence */ 193 | while (posi > 0 && iscont(s + posi)) posi--; 194 | } 195 | else { 196 | if (iscont(s + posi)) 197 | return luaL_error(L, "initial position is a continuation byte"); 198 | if (n < 0) { 199 | while (n < 0 && posi > 0) { /* move back */ 200 | do { /* find beginning of previous character */ 201 | posi--; 202 | } while (posi > 0 && iscont(s + posi)); 203 | n++; 204 | } 205 | } 206 | else { 207 | n--; /* do not move for 1st character */ 208 | while (n > 0 && posi < (lua_Integer)len) { 209 | do { /* find beginning of next character */ 210 | posi++; 211 | } while (iscont(s + posi)); /* (cannot pass final '\0') */ 212 | n--; 213 | } 214 | } 215 | } 216 | if (n == 0) /* did it find given character? */ 217 | lua_pushinteger(L, posi + 1); 218 | else /* no such character */ 219 | luaL_pushfail(L); 220 | return 1; 221 | } 222 | 223 | 224 | static int iter_aux (lua_State *L, int strict) { 225 | size_t len; 226 | const char *s = luaL_checklstring(L, 1, &len); 227 | lua_Unsigned n = (lua_Unsigned)lua_tointeger(L, 2); 228 | if (n < len) { 229 | while (iscont(s + n)) n++; /* skip continuation bytes */ 230 | } 231 | if (n >= len) /* (also handles original 'n' being negative) */ 232 | return 0; /* no more codepoints */ 233 | else { 234 | utfint code; 235 | const char *next = utf8_decode(s + n, &code, strict); 236 | if (next == NULL) 237 | return luaL_error(L, "invalid UTF-8 code"); 238 | lua_pushinteger(L, n + 1); 239 | lua_pushinteger(L, code); 240 | return 2; 241 | } 242 | } 243 | 244 | 245 | static int iter_auxstrict (lua_State *L) { 246 | return iter_aux(L, 1); 247 | } 248 | 249 | static int iter_auxlax (lua_State *L) { 250 | return iter_aux(L, 0); 251 | } 252 | 253 | 254 | static int iter_codes (lua_State *L) { 255 | int lax = lua_toboolean(L, 2); 256 | luaL_checkstring(L, 1); 257 | lua_pushcfunction(L, lax ? iter_auxlax : iter_auxstrict); 258 | lua_pushvalue(L, 1); 259 | lua_pushinteger(L, 0); 260 | return 3; 261 | } 262 | 263 | 264 | /* pattern to match a single UTF-8 character */ 265 | #define UTF8PATT "[\0-\x7F\xC2-\xFD][\x80-\xBF]*" 266 | 267 | 268 | static const luaL_Reg funcs[] = { 269 | {"offset", byteoffset}, 270 | {"codepoint", codepoint}, 271 | {"char", utfchar}, 272 | {"len", utflen}, 273 | {"codes", iter_codes}, 274 | /* placeholders */ 275 | {"charpattern", NULL}, 276 | {NULL, NULL} 277 | }; 278 | 279 | 280 | LUAMOD_API int luaopen_utf8 (lua_State *L) { 281 | luaL_newlib(L, funcs); 282 | lua_pushlstring(L, UTF8PATT, sizeof(UTF8PATT)/sizeof(char) - 1); 283 | lua_setfield(L, -2, "charpattern"); 284 | return 1; 285 | } 286 | 287 | -------------------------------------------------------------------------------- /3rdlibs/lua/src/ltm.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltm.c $ 3 | ** Tag methods 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define ltm_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lgc.h" 20 | #include "lobject.h" 21 | #include "lstate.h" 22 | #include "lstring.h" 23 | #include "ltable.h" 24 | #include "ltm.h" 25 | #include "lvm.h" 26 | 27 | 28 | static const char udatatypename[] = "userdata"; 29 | 30 | LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTYPES] = { 31 | "no value", 32 | "nil", "boolean", udatatypename, "number", 33 | "string", "table", "function", udatatypename, "thread", 34 | "upvalue", "proto" /* these last cases are used for tests only */ 35 | }; 36 | 37 | 38 | void luaT_init (lua_State *L) { 39 | static const char *const luaT_eventname[] = { /* ORDER TM */ 40 | "__index", "__newindex", 41 | "__gc", "__mode", "__len", "__eq", 42 | "__add", "__sub", "__mul", "__mod", "__pow", 43 | "__div", "__idiv", 44 | "__band", "__bor", "__bxor", "__shl", "__shr", 45 | "__unm", "__bnot", "__lt", "__le", 46 | "__concat", "__call", "__close" 47 | }; 48 | int i; 49 | for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); 51 | luaC_fix(L, obj2gco(G(L)->tmname[i])); /* never collect these names */ 52 | } 53 | } 54 | 55 | 56 | /* 57 | ** function to be used with macro "fasttm": optimized for absence of 58 | ** tag methods 59 | */ 60 | const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { 61 | const TValue *tm = luaH_getshortstr(events, ename); 62 | lua_assert(event <= TM_EQ); 63 | if (notm(tm)) { /* no tag method? */ 64 | events->flags |= cast_byte(1u<metatable; 76 | break; 77 | case LUA_TUSERDATA: 78 | mt = uvalue(o)->metatable; 79 | break; 80 | default: 81 | mt = G(L)->mt[ttype(o)]; 82 | } 83 | return (mt ? luaH_getshortstr(mt, G(L)->tmname[event]) : &G(L)->nilvalue); 84 | } 85 | 86 | 87 | /* 88 | ** Return the name of the type of an object. For tables and userdata 89 | ** with metatable, use their '__name' metafield, if present. 90 | */ 91 | const char *luaT_objtypename (lua_State *L, const TValue *o) { 92 | Table *mt; 93 | if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) || 94 | (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) { 95 | const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name")); 96 | if (ttisstring(name)) /* is '__name' a string? */ 97 | return getstr(tsvalue(name)); /* use it as type name */ 98 | } 99 | return ttypename(ttype(o)); /* else use standard type name */ 100 | } 101 | 102 | 103 | void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, 104 | const TValue *p2, const TValue *p3) { 105 | StkId func = L->top; 106 | setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ 107 | setobj2s(L, func + 1, p1); /* 1st argument */ 108 | setobj2s(L, func + 2, p2); /* 2nd argument */ 109 | setobj2s(L, func + 3, p3); /* 3rd argument */ 110 | L->top = func + 4; 111 | /* metamethod may yield only when called from Lua code */ 112 | if (isLuacode(L->ci)) 113 | luaD_call(L, func, 0); 114 | else 115 | luaD_callnoyield(L, func, 0); 116 | } 117 | 118 | 119 | void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1, 120 | const TValue *p2, StkId res) { 121 | ptrdiff_t result = savestack(L, res); 122 | StkId func = L->top; 123 | setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ 124 | setobj2s(L, func + 1, p1); /* 1st argument */ 125 | setobj2s(L, func + 2, p2); /* 2nd argument */ 126 | L->top += 3; 127 | /* metamethod may yield only when called from Lua code */ 128 | if (isLuacode(L->ci)) 129 | luaD_call(L, func, 1); 130 | else 131 | luaD_callnoyield(L, func, 1); 132 | res = restorestack(L, result); 133 | setobjs2s(L, res, --L->top); /* move result to its place */ 134 | } 135 | 136 | 137 | static int callbinTM (lua_State *L, const TValue *p1, const TValue *p2, 138 | StkId res, TMS event) { 139 | const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ 140 | if (notm(tm)) 141 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ 142 | if (notm(tm)) return 0; 143 | luaT_callTMres(L, tm, p1, p2, res); 144 | return 1; 145 | } 146 | 147 | 148 | void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, 149 | StkId res, TMS event) { 150 | if (l_unlikely(!callbinTM(L, p1, p2, res, event))) { 151 | switch (event) { 152 | case TM_BAND: case TM_BOR: case TM_BXOR: 153 | case TM_SHL: case TM_SHR: case TM_BNOT: { 154 | if (ttisnumber(p1) && ttisnumber(p2)) 155 | luaG_tointerror(L, p1, p2); 156 | else 157 | luaG_opinterror(L, p1, p2, "perform bitwise operation on"); 158 | } 159 | /* calls never return, but to avoid warnings: *//* FALLTHROUGH */ 160 | default: 161 | luaG_opinterror(L, p1, p2, "perform arithmetic on"); 162 | } 163 | } 164 | } 165 | 166 | 167 | void luaT_tryconcatTM (lua_State *L) { 168 | StkId top = L->top; 169 | if (l_unlikely(!callbinTM(L, s2v(top - 2), s2v(top - 1), top - 2, 170 | TM_CONCAT))) 171 | luaG_concaterror(L, s2v(top - 2), s2v(top - 1)); 172 | } 173 | 174 | 175 | void luaT_trybinassocTM (lua_State *L, const TValue *p1, const TValue *p2, 176 | int flip, StkId res, TMS event) { 177 | if (flip) 178 | luaT_trybinTM(L, p2, p1, res, event); 179 | else 180 | luaT_trybinTM(L, p1, p2, res, event); 181 | } 182 | 183 | 184 | void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, 185 | int flip, StkId res, TMS event) { 186 | TValue aux; 187 | setivalue(&aux, i2); 188 | luaT_trybinassocTM(L, p1, &aux, flip, res, event); 189 | } 190 | 191 | 192 | /* 193 | ** Calls an order tag method. 194 | ** For lessequal, LUA_COMPAT_LT_LE keeps compatibility with old 195 | ** behavior: if there is no '__le', try '__lt', based on l <= r iff 196 | ** !(r < l) (assuming a total order). If the metamethod yields during 197 | ** this substitution, the continuation has to know about it (to negate 198 | ** the result of rtop, event)) /* try original event */ 204 | return !l_isfalse(s2v(L->top)); 205 | #if defined(LUA_COMPAT_LT_LE) 206 | else if (event == TM_LE) { 207 | /* try '!(p2 < p1)' for '(p1 <= p2)' */ 208 | L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */ 209 | if (callbinTM(L, p2, p1, L->top, TM_LT)) { 210 | L->ci->callstatus ^= CIST_LEQ; /* clear mark */ 211 | return l_isfalse(s2v(L->top)); 212 | } 213 | /* else error will remove this 'ci'; no need to clear mark */ 214 | } 215 | #endif 216 | luaG_ordererror(L, p1, p2); /* no metamethod found */ 217 | return 0; /* to avoid warnings */ 218 | } 219 | 220 | 221 | int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, 222 | int flip, int isfloat, TMS event) { 223 | TValue aux; const TValue *p2; 224 | if (isfloat) { 225 | setfltvalue(&aux, cast_num(v2)); 226 | } 227 | else 228 | setivalue(&aux, v2); 229 | if (flip) { /* arguments were exchanged? */ 230 | p2 = p1; p1 = &aux; /* correct them */ 231 | } 232 | else 233 | p2 = &aux; 234 | return luaT_callorderTM(L, p1, p2, event); 235 | } 236 | 237 | 238 | void luaT_adjustvarargs (lua_State *L, int nfixparams, CallInfo *ci, 239 | const Proto *p) { 240 | int i; 241 | int actual = cast_int(L->top - ci->func) - 1; /* number of arguments */ 242 | int nextra = actual - nfixparams; /* number of extra arguments */ 243 | ci->u.l.nextraargs = nextra; 244 | luaD_checkstack(L, p->maxstacksize + 1); 245 | /* copy function to the top of the stack */ 246 | setobjs2s(L, L->top++, ci->func); 247 | /* move fixed parameters to the top of the stack */ 248 | for (i = 1; i <= nfixparams; i++) { 249 | setobjs2s(L, L->top++, ci->func + i); 250 | setnilvalue(s2v(ci->func + i)); /* erase original parameter (for GC) */ 251 | } 252 | ci->func += actual + 1; 253 | ci->top += actual + 1; 254 | lua_assert(L->top <= ci->top && ci->top <= L->stack_last); 255 | } 256 | 257 | 258 | void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted) { 259 | int i; 260 | int nextra = ci->u.l.nextraargs; 261 | if (wanted < 0) { 262 | wanted = nextra; /* get all extra arguments available */ 263 | checkstackGCp(L, nextra, where); /* ensure stack space */ 264 | L->top = where + nextra; /* next instruction will need top */ 265 | } 266 | for (i = 0; i < wanted && i < nextra; i++) 267 | setobjs2s(L, where + i, ci->func - nextra + i); 268 | for (; i < wanted; i++) /* complete required results with nil */ 269 | setnilvalue(s2v(where + i)); 270 | } 271 | 272 | --------------------------------------------------------------------------------