├── .gitignore ├── LICENSE ├── README.md ├── build.lua ├── dep ├── .gitignore ├── README.md └── dkjson │ └── dkjson.lua ├── doc ├── .gitignore ├── Doxyfile ├── build.sh ├── design │ └── kvs_syntax.txt └── pages │ └── index.dox ├── lib ├── core │ ├── build.lua │ ├── include_order │ ├── src │ │ └── togo │ │ │ └── core │ │ │ ├── .dox │ │ │ ├── algorithm │ │ │ ├── .dox │ │ │ └── sort.hpp │ │ │ ├── collection │ │ │ ├── .dox │ │ │ ├── array.hpp │ │ │ ├── fixed_array.hpp │ │ │ ├── hash_map.hpp │ │ │ ├── npod.hpp │ │ │ ├── priority_queue.hpp │ │ │ ├── queue.hpp │ │ │ └── types.hpp │ │ │ ├── config.hpp │ │ │ ├── error │ │ │ ├── .dox │ │ │ ├── assert.cpp │ │ │ └── assert.hpp │ │ │ ├── external │ │ │ ├── dlmalloc.cpp │ │ │ ├── dlmalloc.hpp │ │ │ └── dlmalloc_import.hpp │ │ │ ├── filesystem │ │ │ ├── .dox │ │ │ ├── directory_reader.cpp │ │ │ ├── directory_reader.hpp │ │ │ ├── directory_reader │ │ │ │ ├── posix.hpp │ │ │ │ ├── posix.ipp │ │ │ │ └── private.hpp │ │ │ ├── filesystem.cpp │ │ │ ├── filesystem.hpp │ │ │ ├── filesystem.lua │ │ │ ├── filesystem │ │ │ │ ├── linux.ipp │ │ │ │ ├── private.hpp │ │ │ │ └── private.ipp │ │ │ ├── filesystem_li.cpp │ │ │ └── types.hpp │ │ │ ├── hash │ │ │ ├── .dox │ │ │ ├── hash.hpp │ │ │ └── types.hpp │ │ │ ├── io │ │ │ ├── .dox │ │ │ ├── file_stream.cpp │ │ │ ├── file_stream.hpp │ │ │ ├── file_stream │ │ │ │ ├── posix.hpp │ │ │ │ └── posix.ipp │ │ │ ├── io.hpp │ │ │ ├── io.lua │ │ │ ├── io_li.cpp │ │ │ ├── memory_stream.cpp │ │ │ ├── memory_stream.hpp │ │ │ ├── object_buffer.hpp │ │ │ ├── object_buffer_type.hpp │ │ │ ├── proto.hpp │ │ │ └── types.hpp │ │ │ ├── kvs │ │ │ ├── .dox │ │ │ ├── io │ │ │ │ ├── binary.ipp │ │ │ │ ├── parser.ipp │ │ │ │ └── parser_new.ipp │ │ │ ├── io_binary.cpp │ │ │ ├── io_text.cpp │ │ │ ├── io_text_new.cpp │ │ │ ├── kvs.cpp │ │ │ ├── kvs.hpp │ │ │ └── types.hpp │ │ │ ├── log │ │ │ ├── .dox │ │ │ ├── log.cpp │ │ │ ├── log.hpp │ │ │ ├── test.hpp │ │ │ └── test_unconfigure.hpp │ │ │ ├── lua │ │ │ ├── .dox │ │ │ ├── lua.cpp │ │ │ ├── lua.hpp │ │ │ └── types.hpp │ │ │ ├── math │ │ │ ├── .dox │ │ │ ├── interpolation.hpp │ │ │ ├── matrix.hpp │ │ │ ├── matrix │ │ │ │ ├── .dox │ │ │ │ ├── 2x2.hpp │ │ │ │ ├── 2x2_type.hpp │ │ │ │ ├── 2x3.hpp │ │ │ │ ├── 2x3_type.hpp │ │ │ │ ├── 2x4.hpp │ │ │ │ ├── 2x4_type.hpp │ │ │ │ ├── 3x2.hpp │ │ │ │ ├── 3x2_type.hpp │ │ │ │ ├── 3x3.hpp │ │ │ │ ├── 3x3_type.hpp │ │ │ │ ├── 3x4.hpp │ │ │ │ ├── 3x4_type.hpp │ │ │ │ ├── 4x2.hpp │ │ │ │ ├── 4x2_type.hpp │ │ │ │ ├── 4x3.hpp │ │ │ │ ├── 4x3_type.hpp │ │ │ │ ├── 4x4.hpp │ │ │ │ └── 4x4_type.hpp │ │ │ ├── traits.hpp │ │ │ ├── types.hpp │ │ │ ├── vector.hpp │ │ │ └── vector │ │ │ │ ├── .dox │ │ │ │ ├── 1.hpp │ │ │ │ ├── 1_type.hpp │ │ │ │ ├── 2.hpp │ │ │ │ ├── 2_type.hpp │ │ │ │ ├── 3.hpp │ │ │ │ ├── 3_type.hpp │ │ │ │ ├── 4.hpp │ │ │ │ └── 4_type.hpp │ │ │ ├── memory │ │ │ ├── .dox │ │ │ ├── assert_allocator.hpp │ │ │ ├── fixed_allocator.cpp │ │ │ ├── fixed_allocator.hpp │ │ │ ├── jump_block_allocator.cpp │ │ │ ├── jump_block_allocator.hpp │ │ │ ├── memory.cpp │ │ │ ├── memory.hpp │ │ │ ├── temp_allocator.hpp │ │ │ └── types.hpp │ │ │ ├── parser │ │ │ ├── .dox │ │ │ ├── debug.hpp │ │ │ ├── parse_state.cpp │ │ │ ├── parse_state.hpp │ │ │ ├── parser.cpp │ │ │ ├── parser.hpp │ │ │ └── types.hpp │ │ │ ├── random │ │ │ ├── .dox │ │ │ ├── random.cpp │ │ │ ├── random.hpp │ │ │ └── types.hpp │ │ │ ├── serialization │ │ │ ├── .dox │ │ │ ├── array.hpp │ │ │ ├── binary_serializer.hpp │ │ │ ├── fixed_array.hpp │ │ │ ├── serializer.hpp │ │ │ ├── string.hpp │ │ │ ├── support.hpp │ │ │ ├── types.hpp │ │ │ └── vector.hpp │ │ │ ├── string │ │ │ ├── .dox │ │ │ ├── string.cpp │ │ │ ├── string.hpp │ │ │ └── types.hpp │ │ │ ├── system │ │ │ ├── .dox │ │ │ ├── system.cpp │ │ │ ├── system.hpp │ │ │ ├── system.lua │ │ │ ├── system │ │ │ │ └── linux.ipp │ │ │ └── system_li.cpp │ │ │ ├── threading │ │ │ ├── .dox │ │ │ ├── condvar.cpp │ │ │ ├── condvar.hpp │ │ │ ├── condvar │ │ │ │ ├── posix.hpp │ │ │ │ └── posix.ipp │ │ │ ├── mutex.cpp │ │ │ ├── mutex.hpp │ │ │ ├── mutex │ │ │ │ ├── posix.hpp │ │ │ │ └── posix.ipp │ │ │ ├── task_manager.cpp │ │ │ ├── task_manager.hpp │ │ │ ├── thread.cpp │ │ │ ├── thread.hpp │ │ │ ├── thread │ │ │ │ └── posix.ipp │ │ │ └── types.hpp │ │ │ ├── tool │ │ │ ├── .dox │ │ │ ├── Tool.lua │ │ │ ├── tool.cpp │ │ │ ├── tool.hpp │ │ │ ├── tool_li.cpp │ │ │ └── types.hpp │ │ │ ├── types.hpp │ │ │ └── utility │ │ │ ├── .dox │ │ │ ├── args.cpp │ │ │ ├── args.hpp │ │ │ ├── constraints.hpp │ │ │ ├── endian.hpp │ │ │ ├── traits.hpp │ │ │ ├── types.hpp │ │ │ ├── utility.hpp │ │ │ ├── utility.lua │ │ │ └── utility_li.cpp │ └── test │ │ ├── algorithm │ │ └── sort.cpp │ │ ├── build.lua │ │ ├── collection │ │ ├── array.cpp │ │ ├── fixed_array.cpp │ │ ├── hash_map.cpp │ │ ├── npod.cpp │ │ ├── priority_queue.cpp │ │ └── queue.cpp │ │ ├── data │ │ └── .gitignore │ │ ├── filesystem │ │ ├── directory_reader.cpp │ │ └── general.cpp │ │ ├── general │ │ └── headers.cpp │ │ ├── hash │ │ └── literal.cpp │ │ ├── io │ │ ├── common.hpp │ │ ├── file_stream.cpp │ │ ├── memory_stream.cpp │ │ └── object_buffer.cpp │ │ ├── kvs │ │ ├── echo.cpp │ │ ├── general.cpp │ │ └── io.cpp │ │ ├── lua │ │ ├── filesystem.lua │ │ ├── general.cpp │ │ ├── io.lua │ │ └── utility.lua │ │ ├── memory │ │ ├── assert_allocator_f1.cpp │ │ ├── assert_allocator_f2.cpp │ │ ├── fixed_allocator.cpp │ │ ├── fixed_allocator_f1.cpp │ │ ├── fixed_allocator_f2.cpp │ │ ├── init.cpp │ │ └── temp_allocator.cpp │ │ ├── parser │ │ ├── common.hpp │ │ ├── general.cpp │ │ └── pdef.cpp │ │ ├── random │ │ └── rng.cpp │ │ ├── serialization │ │ └── general.cpp │ │ ├── string │ │ └── general.cpp │ │ ├── system │ │ └── general.cpp │ │ ├── threading │ │ ├── condvar.cpp │ │ ├── mutex.cpp │ │ ├── task_manager.cpp │ │ └── thread.cpp │ │ └── utility │ │ ├── args.cpp │ │ ├── endian.cpp │ │ └── general.cpp ├── game │ ├── build.lua │ ├── include_order │ ├── src │ │ └── togo │ │ │ └── game │ │ │ ├── .dox │ │ │ ├── app │ │ │ ├── .dox │ │ │ ├── app.cpp │ │ │ ├── app.hpp │ │ │ └── types.hpp │ │ │ ├── config.hpp │ │ │ ├── entity │ │ │ ├── .dox │ │ │ ├── entity_manager.cpp │ │ │ ├── entity_manager.hpp │ │ │ └── types.hpp │ │ │ ├── gfx │ │ │ ├── .dox │ │ │ ├── command.hpp │ │ │ ├── generator.hpp │ │ │ ├── generator │ │ │ │ ├── gen_clear.cpp │ │ │ │ └── gen_fullscreen_pass.cpp │ │ │ ├── gfx.hpp │ │ │ ├── render_node.cpp │ │ │ ├── render_node.hpp │ │ │ ├── renderer.cpp │ │ │ ├── renderer.hpp │ │ │ ├── renderer │ │ │ │ ├── opengl.hpp │ │ │ │ ├── opengl.ipp │ │ │ │ ├── private.hpp │ │ │ │ ├── private.ipp │ │ │ │ └── types.hpp │ │ │ ├── shader_def.hpp │ │ │ └── types.hpp │ │ │ ├── resource │ │ │ ├── .dox │ │ │ ├── resource.cpp │ │ │ ├── resource.hpp │ │ │ ├── resource_handler.hpp │ │ │ ├── resource_handler │ │ │ │ ├── render_config.cpp │ │ │ │ ├── shader.cpp │ │ │ │ ├── shader_prelude.cpp │ │ │ │ └── test_resource.cpp │ │ │ ├── resource_manager.cpp │ │ │ ├── resource_manager.hpp │ │ │ ├── resource_package.cpp │ │ │ ├── resource_package.hpp │ │ │ └── types.hpp │ │ │ ├── serialization │ │ │ ├── .dox │ │ │ ├── gfx │ │ │ │ ├── render_config.hpp │ │ │ │ └── shader_def.hpp │ │ │ └── resource │ │ │ │ ├── resource.hpp │ │ │ │ └── test_resource.hpp │ │ │ └── world │ │ │ ├── .dox │ │ │ ├── types.hpp │ │ │ ├── world_manager.cpp │ │ │ └── world_manager.hpp │ └── test │ │ ├── app │ │ └── general.cpp │ │ ├── build.lua │ │ ├── data │ │ ├── .gitignore │ │ ├── pkg │ │ │ ├── test1.package │ │ │ └── test2.package │ │ └── project │ │ │ ├── .project │ │ │ └── packages │ │ │ └── package │ │ │ ├── test1 │ │ │ ├── .package │ │ │ │ ├── compiler_metadata │ │ │ │ ├── manifest │ │ │ │ └── properties │ │ │ ├── 1.test │ │ │ └── subdir │ │ │ │ └── 2.test │ │ │ ├── test2 │ │ │ ├── .package │ │ │ │ ├── compiler_metadata │ │ │ │ ├── manifest │ │ │ │ └── properties │ │ │ ├── 1.test │ │ │ └── 3.test │ │ │ └── test_data │ │ │ ├── .package │ │ │ ├── compiler_metadata │ │ │ ├── manifest │ │ │ └── properties │ │ │ ├── test │ │ │ └── gfx │ │ │ │ ├── generic.shader │ │ │ │ ├── pipeline.render_config │ │ │ │ └── simple-oscillate.shader │ │ │ └── togo │ │ │ └── gfx │ │ │ └── shader-config.shader_prelude │ │ ├── general │ │ └── headers.cpp │ │ ├── gfx │ │ ├── renderer_pipeline.cpp │ │ └── renderer_triangle.cpp │ │ └── resource │ │ ├── general.cpp │ │ └── manager.cpp ├── image │ ├── build.lua │ ├── include_order │ ├── src │ │ └── togo │ │ │ └── image │ │ │ ├── .dox │ │ │ ├── config.hpp │ │ │ ├── pixmap │ │ │ ├── .dox │ │ │ ├── impl │ │ │ │ ├── private.hpp │ │ │ │ └── private.ipp │ │ │ ├── pixmap.cpp │ │ │ ├── pixmap.hpp │ │ │ └── types.hpp │ │ │ └── types.hpp │ └── test │ │ ├── build.lua │ │ ├── general │ │ └── headers.cpp │ │ └── pixmap │ │ └── general.cpp ├── platform │ ├── build.lua │ ├── include_order │ ├── src │ │ └── togo │ │ │ └── platform │ │ │ ├── .dox │ │ │ ├── config.hpp │ │ │ ├── notification │ │ │ ├── .dox │ │ │ ├── internal.hpp │ │ │ ├── notification.cpp │ │ │ ├── notification.hpp │ │ │ ├── notification.lua │ │ │ ├── notification │ │ │ │ ├── linux.hpp │ │ │ │ ├── linux.ipp │ │ │ │ ├── private.hpp │ │ │ │ ├── private.ipp │ │ │ │ └── types.hpp │ │ │ ├── notification_li.cpp │ │ │ └── types.hpp │ │ │ └── types.hpp │ └── test │ │ ├── build.lua │ │ ├── general │ │ └── headers.cpp │ │ └── notification │ │ └── notification.cpp └── window │ ├── build.lua │ ├── include_order │ ├── src │ └── togo │ │ └── window │ │ ├── .dox │ │ ├── config.hpp │ │ ├── input │ │ ├── .dox │ │ ├── input.cpp │ │ ├── input.hpp │ │ ├── input_buffer.cpp │ │ ├── input_buffer.hpp │ │ └── types.hpp │ │ ├── opengl.hpp │ │ └── window │ │ ├── .dox │ │ ├── impl │ │ ├── glfw.hpp │ │ ├── glfw.ipp │ │ ├── opengl.ipp │ │ ├── private.hpp │ │ ├── sdl.hpp │ │ ├── sdl.ipp │ │ └── types.hpp │ │ ├── types.hpp │ │ ├── window.cpp │ │ └── window.hpp │ └── test │ ├── build.lua │ ├── general │ └── headers.cpp │ └── window │ ├── opengl.cpp │ └── raster.cpp ├── premake4.lua ├── scripts ├── common.lua ├── glad-extensions.txt ├── glad-generate.sh ├── igen_interface.template ├── include_order ├── include_sort ├── include_sort.config ├── precore_import.lua ├── premake ├── run_igen.py ├── run_tests.lua └── tests.make ├── support └── togo │ └── support │ ├── .dox │ └── test.hpp ├── togo.sublime-project └── tool ├── res_build ├── build.lua ├── include_order └── src │ └── togo │ └── tool_res_build │ ├── .dox │ ├── compiler_manager.cpp │ ├── compiler_manager.hpp │ ├── config.hpp │ ├── generator_compiler.cpp │ ├── generator_compiler.hpp │ ├── generator_compiler │ ├── gc_clear.cpp │ ├── gc_fullscreen_pass.cpp │ ├── gc_test_proxy.cpp │ └── support.hpp │ ├── gfx_compiler.cpp │ ├── gfx_compiler.hpp │ ├── interface.cpp │ ├── interface.hpp │ ├── interface │ ├── command_compact.ipp │ ├── command_compile.ipp │ ├── command_create.ipp │ ├── command_help.ipp │ ├── command_list.ipp │ ├── command_pack.ipp │ └── command_sync.ipp │ ├── main.cpp │ ├── package_compiler.cpp │ ├── package_compiler.hpp │ ├── resource_compiler.cpp │ ├── resource_compiler.hpp │ ├── resource_compiler │ ├── render_config.cpp │ ├── shader_def.cpp │ └── test_resource.cpp │ └── types.hpp └── script_host ├── build.lua ├── include_order └── src └── togo └── tool_script_host ├── .dox ├── config.hpp ├── main.cpp └── types.hpp /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | togo.sublime-workspace 3 | 4 | *.make 5 | Makefile 6 | build/ 7 | tmp/ 8 | 9 | *.exe 10 | *.elf 11 | 12 | *.gen_interface 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2017 Coranna Howard 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /dep/.gitignore: -------------------------------------------------------------------------------- 1 | glad 2 | sdl 3 | glfw 4 | lua 5 | -------------------------------------------------------------------------------- /dep/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## Dependencies! 3 | 4 | Symlink/clone/download the following libraries (take care they go into the 5 | proper directories). 6 | 7 | ### lib/core 8 | 9 | 1. [Lua](https://www.lua.org/download.html) == **5.3.5** into `lua/` 10 | 11 | ### lib/image 12 | 13 | `lib/image` has no manual dependencies. 14 | 15 | ### lib/platform 16 | 17 | `lib/platform` has no manual dependencies. 18 | 19 | ### lib/window 20 | 21 | 1. [glad](https://github.com/Dav1dde/glad) (HEAD): 22 | 23 | ``` 24 | git clone git@github.com:Dav1dde/glad.git glad/ 25 | ../scripts/glad-generate.sh # default options (can be run anywhere) 26 | ``` 27 | 28 | 2. Backend (one of): 29 | 1. [SDL](http://libsdl.org/download-2.0.php) >= **2.0.3** into `sdl/` 30 | 2. [GLFW](http://www.glfw.org/download.html) >= **3.2** into `glfw/` 31 | 32 | ### lib/game 33 | 34 | `lib/game` has no manual dependencies. 35 | -------------------------------------------------------------------------------- /doc/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | html/ 3 | gen_interface/ 4 | -------------------------------------------------------------------------------- /doc/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | doxygen ./Doxyfile 4 | -------------------------------------------------------------------------------- /doc/design/kvs_syntax.txt: -------------------------------------------------------------------------------- 1 | 2 | // name 3 | name = 1 4 | "name" = 2 5 | ```name``` = 3 6 | 7 | // constant 8 | null 9 | false 10 | true 11 | 12 | // number 13 | 42 14 | 3.141592 15 | 2.0e4 16 | 17 | // string 18 | str 19 | "str" 20 | ```str 21 | ing``` 22 | 23 | // vector (1-dimensional to 4-dimensional) 24 | (42.0 3.141592) 25 | (0.0 1.0, 1.0e-3; -42e+1) 26 | 27 | // array 28 | [x y] 29 | 30 | // node 31 | {x = y, y = z} 32 | 33 | // basic composition 34 | 35 | SingleLineComment = "//" .* 36 | BlockComment = "/\*" .* "\*/" 37 | Comment = SingleLineComment | BlockComment 38 | 39 | Terminator = \s | \n | "," | ";" | Comment 40 | 41 | Identifier = [a-zA-Z_\.][a-zA-Z0-9_\-\.]* 42 | Integer = [\-+]? [0-9]+ 43 | DecimalNumber = [\-+]? [0-9]* \.? [0-9]+ 44 | DecimalNumberWithExponent = DecimalNumber ([eE][\-+]? [0-9]* \.? [0-9]+)? 45 | Null = "null" 46 | Boolean = "false" | "true" 47 | 48 | ValueConstant = Null | Boolean 49 | ValueNumber = Integer | DecimalNumberWithExponent 50 | ValueString = Identifier | "\"" .* "\"" | "```" [.\n]* "```" 51 | ValueVec1 = "(" ValueNumber ")" 52 | ValueVec2 = "(" ValueNumber ValueNumber ")" 53 | ValueVec3 = "(" ValueNumber ValueNumber ValueNumber ")" 54 | ValueVec4 = "(" ValueNumber ValueNumber ValueNumber ValueNumber ")" 55 | ValueVector = ValueVec1 | ValueVec2 | ValueVec3 | ValueVec4 56 | ValueArray = "[" NamelessObject* "]" 57 | ValueNode = "{" Object* "}" 58 | Value = ValueConstant | ValueNumber | ValueString | ValueVector | ValueArray | ValueNode 59 | 60 | Name = ValueString "=" 61 | Object = Name Value 62 | NamelessObject = Value 63 | -------------------------------------------------------------------------------- /doc/pages/index.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @mainpage 5 | @section README 6 | 7 | @section License 8 | 9 | togo carries the MIT license, which can be found both below and in the 10 | `LICENSE` file. 11 | 12 | @verbatim 13 | Copyright (c) 2014-2016 Coranna Howard 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy 16 | of this software and associated documentation files (the "Software"), to deal 17 | in the Software without restriction, including without limitation the rights 18 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the Software is 20 | furnished to do so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in 23 | all copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | THE SOFTWARE. 32 | @endverbatim 33 | 34 | */ 35 | -------------------------------------------------------------------------------- /lib/core/build.lua: -------------------------------------------------------------------------------- 1 | 2 | local S, G, R = precore.helpers() 3 | 4 | precore.make_config("togo.lib.core.lua.dep", nil, { 5 | {project = function(p) 6 | configuration {} 7 | includedirs { 8 | G"${DEP_PATH}/lua/include/", 9 | } 10 | 11 | if not precore.env_project()["NO_LINK"] then 12 | libdirs { 13 | G"${DEP_PATH}/lua/lib/", 14 | } 15 | linkoptions { 16 | "-Wl,-E -l:liblua.a", 17 | } 18 | end 19 | end}}) 20 | 21 | precore.make_config("togo.lib.core.dep", { 22 | reverse = true, 23 | }, { 24 | "togo.base", 25 | "togo.lib.core.lua.dep", 26 | {project = function(p) 27 | togo.library_config("core") 28 | 29 | configuration {"togo-test"} 30 | defines { 31 | "TOGO_TEST_PRIORITY_QUEUE", 32 | "TOGO_TEST_TASK_MANAGER", 33 | "TOGO_TEST_ALGORITHM", 34 | } 35 | end}}) 36 | 37 | precore.append_config_scoped("togo.projects", { 38 | {global = function(_) 39 | togo.make_library("core", { 40 | "togo.lib.core.dep", 41 | }) 42 | end}}) 43 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_core Library: core 5 | @details 6 | 7 | */ 8 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/algorithm/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_core_algorithm Algorithms 5 | @ingroup lib_core 6 | @details 7 | 8 | As opposed to sort_radix_generic(), sort_radix_k32() and 9 | sort_radix_k64() will copy the contents of the swap into the 10 | destination array if the result is swapped. 11 | 12 | */ 13 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/collection/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_core_collection Collections 5 | @ingroup lib_core 6 | @details 7 | 8 | Array is currently the only collection that supports the 9 | enable_collection_construction_and_destruction trait. Others will incur a copy 10 | at best, and fail compilation at worst (due to missing ctors or assignment 11 | operators). Other dynamic collections use Array underneath, so any operations 12 | directly using Array will use the appropriate state management. 13 | 14 | @warning None of these types are thread-safe. 15 | 16 | */ 17 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/error/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_core_error Error 5 | @ingroup lib_core 6 | @details 7 | 8 | */ 9 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/error/assert.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/error/assert.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace togo { 14 | 15 | void error_abort(unsigned line, char const* file, char const* msg, ...) { 16 | std::fprintf(stderr, "%s @ %4d: fatal error: ", file, line); 17 | va_list va; 18 | va_start(va, msg); 19 | std::vfprintf(stderr, msg, va); 20 | va_end(va); 21 | std::fflush(stderr); 22 | std::abort(); 23 | } 24 | 25 | } // namespace togo 26 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/external/dlmalloc_import.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 3 | 4 | @file 5 | @brief dlmalloc configuration and import. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | /** @cond INTERNAL */ 16 | 17 | // dlmalloc configuration 18 | #define USE_LOCKS 1 19 | #define ONLY_MSPACES 1 20 | #define MSPACES 1 21 | #define MALLINFO_FIELD_TYPE std::size_t 22 | #define ABORT (::togo::error_abort(__LINE__, __FILE__, "dlmalloc: invalid operation")) 23 | 24 | extern "C" { 25 | // Yanked from dlmalloc to shut clang up. 26 | #define _STRUCT_MALLINFO 27 | #define STRUCT_MALLINFO_DECLARED 1 28 | struct mallinfo { 29 | MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ 30 | MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ 31 | MALLINFO_FIELD_TYPE smblks; /* always 0 */ 32 | MALLINFO_FIELD_TYPE hblks; /* always 0 */ 33 | MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ 34 | MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ 35 | MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ 36 | MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ 37 | MALLINFO_FIELD_TYPE fordblks; /* total free space */ 38 | MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ 39 | }; 40 | } // extern "C" 41 | 42 | #include 43 | 44 | /** @endcond */ // INTERNAL 45 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/filesystem/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_core_filesystem Filesystem 5 | @ingroup lib_core 6 | @details 7 | 8 | All returned/assigned paths are NUL-terminated, excepting the path-part 9 | functions, which return views into the given path. 10 | 11 | Paths need not be NUL-terminated, but will incur a copy if not NUL-terminated 12 | where the underlying API requires it. 13 | 14 | */ 15 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/filesystem/directory_reader.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/filesystem/directory_reader.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #if defined(TOGO_PLATFORM_IS_POSIX) 11 | #include 12 | #else 13 | #error "missing DirectoryReader implementation for target platform" 14 | #endif 15 | 16 | namespace togo { 17 | 18 | TOGO_LUA_MARK_USERDATA_ANCHOR(DirectoryReader); 19 | 20 | DirectoryReader::DirectoryReader() 21 | : _options(0) 22 | , _impl() 23 | {} 24 | 25 | DirectoryReader::~DirectoryReader() { 26 | directory_reader::close(*this); 27 | } 28 | 29 | } // namespace togo 30 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/filesystem/directory_reader.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/filesystem/directory_reader.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief DirectoryReader interface. 7 | @ingroup lib_core_filesystem 8 | @ingroup lib_core_filesystem_directory_reader 9 | 10 | @defgroup lib_core_filesystem_directory_reader DirectoryReader 11 | @ingroup lib_core_filesystem 12 | @details 13 | */ 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | namespace togo { 23 | namespace directory_reader { 24 | 25 | /** 26 | @addtogroup lib_core_filesystem_directory_reader 27 | @{ 28 | */ 29 | 30 | /// Open directory. 31 | /// 32 | /// If prepend_path is true, read entries will include the directory path. 33 | /// 34 | /// An assertion will fail if the directory reader is already open. 35 | /// ignore_dotfiles will ignore regular directories and files that 36 | /// start with ".". 37 | bool open( 38 | DirectoryReader& reader, 39 | StringRef const& path, 40 | bool prepend_path, 41 | bool recursive, 42 | bool ignore_dotfiles 43 | ); 44 | 45 | /// Close directory. 46 | void close(DirectoryReader& reader); 47 | 48 | /// Read next entry. 49 | /// 50 | /// Directory entries will always end with a slash. 51 | /// "." and ".." entries are always ignored. 52 | bool read( 53 | DirectoryReader& reader, 54 | DirectoryEntry& entry, 55 | DirectoryEntry::Type type_mask 56 | ); 57 | 58 | /** @} */ // end of doc-group lib_core_filesystem_directory_reader 59 | 60 | } // namespace directory_reader 61 | } // namespace togo 62 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/filesystem/directory_reader/posix.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/filesystem/directory_reader/posix.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | namespace togo { 15 | 16 | struct PosixDirectoryReaderImpl { 17 | struct Node { 18 | DIR* handle; 19 | u32 size; 20 | }; 21 | 22 | u32 base_size; 23 | u32 current_size; 24 | FixedArray nodes; 25 | FixedArray path; 26 | 27 | PosixDirectoryReaderImpl(); 28 | }; 29 | 30 | using DirectoryReaderImpl = PosixDirectoryReaderImpl; 31 | 32 | } // namespace togo 33 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/filesystem/directory_reader/private.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/filesystem/directory_reader/private.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace togo { 13 | namespace directory_reader { 14 | 15 | namespace { 16 | enum : u32 { 17 | OPT_NONE = 0, 18 | OPT_PREPEND_PATH = 1 << 0, 19 | OPT_RECURSIVE = 1 << 1, 20 | OPT_IGNORE_DOTFILES = 1 << 2, 21 | }; 22 | } // anonymous namespace 23 | 24 | inline void set_options( 25 | DirectoryReader& reader, 26 | bool const prepend_path, 27 | bool const recursive, 28 | bool const ignore_dotfiles 29 | ) { 30 | reader._options 31 | = (prepend_path ? OPT_PREPEND_PATH : OPT_NONE) 32 | | (recursive ? OPT_RECURSIVE : OPT_NONE) 33 | | (ignore_dotfiles ? OPT_IGNORE_DOTFILES : OPT_NONE) 34 | ; 35 | } 36 | 37 | inline bool option_prepend_path(DirectoryReader const& reader) { 38 | return reader._options & OPT_PREPEND_PATH; 39 | } 40 | 41 | inline bool option_recursive(DirectoryReader const& reader) { 42 | return reader._options & OPT_RECURSIVE; 43 | } 44 | 45 | inline bool option_ignore_dotfiles(DirectoryReader const& reader) { 46 | return reader._options & OPT_IGNORE_DOTFILES; 47 | } 48 | 49 | } // namespace directory_reader 50 | } // namespace togo 51 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/filesystem/filesystem.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/filesystem/filesystem.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #if defined(TOGO_PLATFORM_LINUX) 12 | #include 13 | #include 14 | #else 15 | #error "unimplemented for target platform" 16 | #endif 17 | 18 | namespace togo { 19 | 20 | /// Create a directory and all of its parents. 21 | /// 22 | /// Returns false if the path could not be created in its entirety. 23 | bool filesystem::create_directory_whole(StringRef const path) { 24 | if (path.empty()) { 25 | return false; 26 | } 27 | 28 | // NB: should be proofed against Windows UNC paths 29 | bool exists = false; 30 | unsigned depth = 0; 31 | unsigned last_size = 0; 32 | StringRef sub{path}; 33 | for (; 34 | last_size != sub.size && sub.any() && !string::path_is_root(sub); 35 | sub = string::path_dir(sub) 36 | ) { 37 | last_size = sub.size; 38 | ++depth; 39 | if ((exists = filesystem::is_directory(sub))) { 40 | break; 41 | } 42 | } 43 | 44 | if (depth == 0) { 45 | // root always exists 46 | return true; 47 | } 48 | 49 | // subtle: string::path_dir() could return a different string (e.g., "") 50 | sub.data = path.data; 51 | sub.size = last_size; 52 | auto p = end(sub); 53 | auto e = end(path); 54 | while (p <= e) { 55 | if (!filesystem::create_directory(sub, true)) { 56 | return false; 57 | } 58 | for (++p; p < e && !(*p == '/' || *p == '\\'); ++p); 59 | sub.size = p - begin(sub); 60 | } 61 | return true; 62 | } 63 | 64 | } // namespace togo 65 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/filesystem/filesystem.lua: -------------------------------------------------------------------------------- 1 | u8R""__RAW_STRING__( 2 | 3 | local U = require "togo.utility" 4 | local M = U.module(...) 5 | 6 | M.debug = false 7 | 8 | function M.working_dir_scope(path, f) 9 | U.type_assert(path, "string") 10 | U.type_assert(f, "function") 11 | 12 | local previous_path = M.working_dir() 13 | U.assert(previous_path ~= "") 14 | U.assert(M.set_working_dir(path)) 15 | f(previous_path, path) 16 | U.assert(M.set_working_dir(previous_path)) 17 | end 18 | 19 | return M 20 | 21 | )"__RAW_STRING__" -------------------------------------------------------------------------------- /lib/core/src/togo/core/filesystem/filesystem/private.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/filesystem/filesystem/private.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #if defined(TOGO_PLATFORM_LINUX) 13 | #include 14 | #define TOGO_PATH_MAX PATH_MAX 15 | #endif 16 | 17 | namespace togo { 18 | namespace filesystem { 19 | 20 | StringRef to_cstring(StringRef path, FixedArray* buffer = nullptr); 21 | 22 | } // namespace filesystem 23 | } // namespace togo 24 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/filesystem/filesystem/private.ipp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/filesystem/filesystem/private.ipp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | namespace togo { 15 | 16 | namespace { 17 | static thread_local FixedArray _cstring_copy{}; 18 | } // anonymous namespace 19 | 20 | StringRef filesystem::to_cstring(StringRef path, FixedArray* buffer) { 21 | if (!buffer) { 22 | buffer = &_cstring_copy; 23 | } 24 | if (path.empty()) { 25 | path = ""; 26 | 27 | // FIXME: If data was allocated to path.size, this is OOB. 28 | // Undesireable, but sorta not actually a violation? Ho hum. 29 | } else if (path.data[path.size] != '\0') { 30 | string::copy(*buffer, path); 31 | path = *buffer; 32 | } 33 | return path; 34 | } 35 | 36 | } // namespace togo 37 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/hash/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_core_hash Hash 5 | @ingroup lib_core 6 | @details 7 | 8 | @note Although the togo implementations are under the MIT license, 9 | the FNV algorithms themselves are in the public domain. No copyright is 10 | claimed on them. 11 | 12 | */ 13 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/io/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_core_io IO 5 | @ingroup lib_core 6 | @details 7 | 8 | If a read operation reaches the end of the stream without reading all 9 | of the requested size, the stream status will have the EOF flag, 10 | indicating only a failure to satisfy the request. 11 | 12 | Both read and write operations may set the fail flag on the stream's 13 | status, which indicates an internal failure. Every operation and query 14 | apart from io::status() may clear the status of the stream upon entry. 15 | 16 | If a read operation fails (through the EOF or fail flags), the state 17 | of the destination buffer may be indeterminate (specifically, with 18 | system-based streams). 19 | 20 | @warning Streams are not thread-safe. 21 | 22 | */ 23 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/io/file_stream.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/io/file_stream.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | #if defined(TOGO_PLATFORM_IS_POSIX) 10 | #include 11 | #else 12 | #error "missing file_io implementation for target platform" 13 | #endif 14 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/io/file_stream/posix.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/io/file_stream/posix.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace togo { 13 | 14 | struct PosixFileStreamData { 15 | std::FILE* handle{nullptr}; 16 | IOStatus status{IOStatus::flag_none}; 17 | }; 18 | 19 | using FileStreamData = PosixFileStreamData; 20 | 21 | } // namespace togo 22 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/io/io.lua: -------------------------------------------------------------------------------- 1 | u8R""__RAW_STRING__( 2 | 3 | local U = require "togo.utility" 4 | local M = U.module(...) 5 | 6 | M.debug = false 7 | 8 | return M 9 | 10 | )"__RAW_STRING__" -------------------------------------------------------------------------------- /lib/core/src/togo/core/io/io_li.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/io/io_li.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | namespace togo { 15 | 16 | namespace io { 17 | 18 | // Read a file into a string. 19 | TOGO_LI_FUNC_DEF(read_file) { 20 | auto path = lua::get_string(L, 1); 21 | 22 | FileReader stream; 23 | if (!stream.open(path)) { 24 | lua::push_value(L, null_tag{}); 25 | return 1; 26 | } 27 | u64 remaining = filesystem::file_size(path); 28 | Array data{memory::scratch_allocator()}; 29 | array::resize(data, remaining); 30 | auto p = begin(data); 31 | unsigned read_size; 32 | while (remaining) { 33 | if (!io::read(stream, p, remaining, &read_size)) { 34 | stream.close(); 35 | lua::push_value(L, null_tag{}); 36 | return 1; 37 | } 38 | remaining -= read_size; 39 | p += read_size; 40 | } 41 | stream.close(); 42 | 43 | lua::push_value(L, StringRef{data}); 44 | return 1; 45 | } 46 | 47 | // Write a string to a file. 48 | TOGO_LI_FUNC_DEF(write_file) { 49 | auto path = lua::get_string(L, 1); 50 | auto data = lua::get_string(L, 2); 51 | 52 | bool success = false; 53 | FileWriter stream; 54 | if (!stream.open(path, false)) { 55 | goto l_exit; 56 | } 57 | if (!io::write(stream, data.data, data.size)) { 58 | goto l_exit; 59 | } 60 | success = true; 61 | 62 | l_exit: 63 | stream.close(); 64 | lua::push_value(L, success); 65 | return 1; 66 | } 67 | 68 | } // namespace io 69 | 70 | static LuaModuleFunctionArray const li_funcs{ 71 | TOGO_LI_FUNC_REF(io, read_file) 72 | TOGO_LI_FUNC_REF(io, write_file) 73 | }; 74 | 75 | static LuaModuleRef const li_module{ 76 | "togo.io", 77 | "togo/core/io/io.lua", 78 | li_funcs, 79 | #include 80 | }; 81 | 82 | /// Register the Lua interface. 83 | void io::register_lua_interface(lua_State* L) { 84 | lua::preload_module(L, li_module); 85 | } 86 | 87 | } // namespace togo 88 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/io/object_buffer_type.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/io/object_buffer_type.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Object buffer type. 7 | @ingroup lib_core_types 8 | @ingroup lib_core_io 9 | @ingroup lib_core_io_object_buffer 10 | */ 11 | 12 | #pragma once 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | namespace togo { 20 | 21 | /** 22 | @addtogroup lib_core_io_object_buffer 23 | @{ 24 | */ 25 | 26 | /// Object buffer. 27 | /// 28 | /// @tparam T Integral type to use for object types. 29 | /// @tparam S Integral type to use for object sizes. 30 | template 31 | struct ObjectBuffer { 32 | TOGO_CONSTRAIN_INTEGRAL(T); 33 | TOGO_CONSTRAIN_INTEGRAL(S); 34 | 35 | MemoryStream _stream; 36 | unsigned _num_objects; 37 | bool _consume_mode; 38 | 39 | ObjectBuffer() = delete; 40 | ObjectBuffer(ObjectBuffer const&) = delete; 41 | ObjectBuffer(ObjectBuffer&&) = delete; 42 | ObjectBuffer& operator=(ObjectBuffer const&) = delete; 43 | ObjectBuffer& operator=(ObjectBuffer&&) = delete; 44 | 45 | ~ObjectBuffer() = default; 46 | 47 | ObjectBuffer(Allocator& allocator, u32 const init_capacity); 48 | }; 49 | 50 | /** @} */ // end of doc-group lib_core_io_object_buffer 51 | 52 | } // namespace togo 53 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/io/types.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/io/types.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief IO types. 7 | @ingroup lib_core_types 8 | @ingroup lib_core_io 9 | */ 10 | 11 | #pragma once 12 | 13 | #include 14 | 15 | namespace togo { 16 | 17 | /** 18 | @addtogroup lib_core_io 19 | @{ 20 | */ 21 | 22 | // Forward declarations 23 | class IStreamBase; 24 | class IStreamSeekable; 25 | class IReader; 26 | class IWriter; 27 | 28 | /// IO stream status. 29 | struct IOStatus { 30 | enum : unsigned { 31 | /// No flags. 32 | flag_none = 0, 33 | /// Fail flag. 34 | flag_fail = 1 << 0, 35 | /// End-of-stream flag. 36 | flag_eof = 1 << 1, 37 | }; 38 | 39 | unsigned _value; 40 | 41 | /// Set status and return self. 42 | IOStatus& assign(bool const fail, bool const eof) { 43 | _value 44 | = fail ? flag_fail : flag_none 45 | | eof ? flag_eof : flag_none 46 | ; 47 | return *this; 48 | } 49 | 50 | /// Clear status and return self. 51 | IOStatus& clear() { 52 | _value = flag_none; 53 | return *this; 54 | } 55 | 56 | /// Whether there are no errors. 57 | constexpr bool ok() const noexcept { 58 | return !_value; 59 | } 60 | 61 | /// Whether an operation failed. 62 | constexpr bool fail() const noexcept { 63 | return _value & flag_fail; 64 | } 65 | 66 | /// Whether an operation failed and reached the end of the stream. 67 | /// 68 | /// Writers that have a bound stream size (i.e., non-growing) may 69 | /// set this flag. 70 | constexpr bool eof() const noexcept { 71 | return _value & flag_eof; 72 | } 73 | 74 | /// Whether there are no errors. 75 | constexpr operator bool() const noexcept { 76 | return ok(); 77 | } 78 | }; 79 | 80 | /** @} */ // end of doc-group lib_core_io 81 | 82 | } // namespace togo 83 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/kvs/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_core_kvs KVS 5 | @ingroup lib_core 6 | @details 7 | 8 | @note The kvs::find() functions short-circuit if name_hash is the hash identity or if name is empty. 9 | 10 | @warning An assertion will fail when requesting the value of a type when the KVS is of a different type. 11 | 12 | */ 13 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/kvs/io_text_new.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/kvs/io_text_new.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | namespace togo { 25 | 26 | /// Read text-format KVS from stream. 27 | /// 28 | /// Returns false if a parse error occurred. 29 | bool kvs::read_text_new(KVS& root, ArrayRef data, ParseError* error IGEN_DEFAULT(nullptr)) { 30 | TempAllocator<4096> allocator{}; 31 | KVSParseState ud{0}; 32 | ParseState state{ 33 | allocator, 34 | &ud 35 | }; 36 | array::reserve(state.results, (4096 / sizeof(ParseResult)) - sizeof(void*)); 37 | kvs::set_type(root, KVSType::node); 38 | kvs::clear(root); 39 | set_data_array(state, data); 40 | push(state, {rtype_kvs, &root}); 41 | bool success = parser::parse(p_root, state, error); 42 | return success; 43 | } 44 | 45 | } // namespace togo 46 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/log/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_core_log Logging 5 | @ingroup lib_core 6 | @details 7 | 8 | These operations are thread-safe. The TOGO_LOG_DEBUG() macros are 9 | defined only when TOGO_DEBUG is defined. 10 | 11 | */ 12 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/log/log.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/log/log.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | // TODO: Print into buffer, then flush buffer to streams 15 | 16 | namespace togo { 17 | 18 | namespace { 19 | static Mutex _log_mutex{}; 20 | } // anonymous namespace 21 | 22 | void log::printf(char const* const msg, ...) { 23 | MutexLock l{_log_mutex}; 24 | va_list va; 25 | va_start(va, msg); 26 | std::vprintf(msg, va); 27 | va_end(va); 28 | } 29 | 30 | } // namespace togo 31 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/log/log.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/log/log.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Logging. 7 | @ingroup lib_core_log 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | 15 | namespace togo { 16 | namespace log { 17 | 18 | /** 19 | @addtogroup lib_core_log 20 | @{ 21 | */ 22 | 23 | TOGO_VALIDATE_FORMAT_PARAM(1, 2) 24 | void printf(char const* const msg, ...); 25 | 26 | /// Log message. 27 | #define TOGO_LOG(msg) \ 28 | ::togo::log::printf(msg) 29 | 30 | /// Log formatted message. 31 | #define TOGO_LOGF(msg, ...) \ 32 | ::togo::log::printf(msg, __VA_ARGS__) 33 | 34 | /// Log message (traced). 35 | #define TOGO_LOG_TRACED(msg) \ 36 | TOGO_LOGF("%s @ %4d: " msg, __FILE__, __LINE__) 37 | 38 | /// Log formatted message (traced). 39 | #define TOGO_LOGF_TRACED(msg, ...) \ 40 | TOGO_LOGF("%s @ %4d: " msg, __FILE__, __LINE__, __VA_ARGS__) 41 | 42 | /// Log error message. 43 | #define TOGO_LOG_ERROR(msg) \ 44 | TOGO_LOG_TRACED("error: " msg) 45 | 46 | /// Log formatted error message. 47 | #define TOGO_LOG_ERRORF(msg, ...) \ 48 | TOGO_LOGF_TRACED("error: " msg, __VA_ARGS__) 49 | 50 | #if defined(TOGO_DEBUG) 51 | #define TOGO_LOG_DEBUG(msg) \ 52 | TOGO_LOG_TRACED("debug: " msg) 53 | 54 | #define TOGO_LOG_DEBUGF(msg, ...) \ 55 | TOGO_LOGF_TRACED("debug: " msg, __VA_ARGS__) 56 | #else 57 | /// Log debug message. 58 | #define TOGO_LOG_DEBUG(msg) (void(0)) 59 | 60 | /// Log formatted debug message. 61 | #define TOGO_LOG_DEBUGF(msg, ...) (void(0)) 62 | #endif 63 | 64 | /** @} */ // end of doc-group lib_core_log 65 | 66 | } // namespace log 67 | } // namespace togo 68 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/log/test.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/log/test.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Test logging. 7 | @ingroup lib_core_log 8 | */ 9 | 10 | #include 11 | #include 12 | 13 | namespace togo { 14 | namespace log { 15 | 16 | /** 17 | @addtogroup lib_core_log 18 | @{ 19 | */ 20 | 21 | #include 22 | 23 | #if defined(TOGO_TEST_LOG_ENABLE) 24 | #define TOGO_TEST_LOG(msg) TOGO_LOG(msg) 25 | #define TOGO_TEST_LOGF(msg, ...) TOGO_LOGF(msg, __VA_ARGS__) 26 | #define TOGO_TEST_LOG_ERROR(msg) TOGO_LOG_ERROR(msg) 27 | #define TOGO_TEST_LOG_ERRORF(msg, ...) TOGO_LOG_ERRORF(msg, __VA_ARGS__) 28 | #else 29 | /// Log message (test). 30 | #define TOGO_TEST_LOG(msg) (void(0)) 31 | 32 | /// Log formatted message (test). 33 | #define TOGO_TEST_LOGF(msg, ...) (void(0)) 34 | 35 | /// Log error message (test). 36 | #define TOGO_TEST_LOG_ERROR(msg) (void(0)) 37 | 38 | /// Log formatted error message (test). 39 | #define TOGO_TEST_LOG_ERRORF(msg, ...) (void(0)) 40 | #endif 41 | 42 | #if defined(TOGO_TEST_LOG_ENABLE) && defined(TOGO_DEBUG) 43 | #define TOGO_TEST_LOG_DEBUG(msg) TOGO_LOG_DEBUG(msg) 44 | #define TOGO_TEST_LOG_DEBUGF(msg, ...) TOGO_LOG_DEBUGF(msg, __VA_ARGS__) 45 | #else 46 | /// Log debug message (test). 47 | #define TOGO_TEST_LOG_DEBUG(msg) (void(0)) 48 | 49 | /// Log formatted debug message (test). 50 | #define TOGO_TEST_LOG_DEBUGF(msg, ...) (void(0)) 51 | #endif 52 | 53 | #undef TOGO_TEST_LOG_ENABLE 54 | 55 | /** @} */ // end of doc-group lib_core_log 56 | 57 | } // namespace log 58 | } // namespace togo 59 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/log/test_unconfigure.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/log/test_unconfigure.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Undefine all test logging macros. 7 | @ingroup lib_core_log 8 | */ 9 | 10 | namespace togo { 11 | namespace log { 12 | 13 | #undef TOGO_TEST_LOG 14 | #undef TOGO_TEST_LOGF 15 | #undef TOGO_TEST_LOG_ERROR 16 | #undef TOGO_TEST_LOG_ERRORF 17 | #undef TOGO_TEST_LOG_DEBUG 18 | #undef TOGO_TEST_LOG_DEBUGF 19 | 20 | } // namespace log 21 | } // namespace togo 22 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/lua/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_core_lua Lua scripting 5 | @ingroup lib_core 6 | @details 7 | 8 | */ 9 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/math/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_core_math Math 5 | @ingroup lib_core 6 | @details 7 | 8 | */ 9 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/math/matrix.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/math/matrix.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Matrix interface. 7 | @ingroup lib_core_math 8 | @ingroup lib_core_math_matrix 9 | */ 10 | 11 | #pragma once 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | namespace togo { 18 | namespace math { 19 | 20 | /** 21 | @addtogroup lib_core_math_matrix 22 | @{ 23 | */ 24 | 25 | /// Transpose a matrix. 26 | template 27 | inline typename C::transpose_type transpose(C const& m) { 28 | static_assert(math::is_matrix::value, ""); 29 | return C::operations::transpose(m); 30 | } 31 | 32 | /// Calculate the determinant of a (square) matrix. 33 | template 34 | inline math::value_type determinant(C const& m) { 35 | static_assert(math::is_square_matrix::value, ""); 36 | return C::operations::determinant(m); 37 | } 38 | 39 | /// Calculate the inverse of a (square) matrix. 40 | /// 41 | /// @warning The values in the resultant matrix are undefined if m is singular. 42 | template 43 | inline C inverse(C const& m) { 44 | static_assert(math::is_square_matrix::value, ""); 45 | return C::operations::inverse(m); 46 | } 47 | 48 | /** @} */ // end of doc-group lib_core_math_matrix 49 | 50 | } // namespace math 51 | } // namespace togo 52 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/math/matrix/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_core_math_matrix Matrix 5 | @ingroup lib_core_math 6 | @details 7 | 8 | */ 9 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/math/vector/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_core_math_vector Vector 5 | @ingroup lib_core_math 6 | @details 7 | 8 | */ 9 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/memory/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_core_memory Memory 5 | @ingroup lib_core 6 | @details 7 | 8 | */ 9 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/memory/assert_allocator.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/memory/assert_allocator.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief AssertAllocator class. 7 | @ingroup lib_core_memory 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | namespace togo { 19 | 20 | /** 21 | @addtogroup lib_core_memory 22 | @{ 23 | */ 24 | 25 | /// Allocator that always fails. 26 | class AssertAllocator 27 | : public Allocator 28 | { 29 | public: 30 | /// This operation is not supported. 31 | unsigned num_allocations() const override { 32 | return 0; 33 | } 34 | 35 | /// This operation is not supported. 36 | unsigned total_size() const override { 37 | return SIZE_NOT_TRACKED; 38 | } 39 | 40 | /// This operation is not supported. 41 | unsigned allocation_size(void const* const) const override { 42 | return SIZE_NOT_TRACKED; 43 | } 44 | 45 | /// Fails with an assertion. 46 | [[noreturn]] 47 | void* allocate(unsigned const, unsigned const = DEFAULT_ALIGNMENT) override { 48 | TOGO_ASSERTE(false); 49 | } 50 | 51 | /// Fails with an assertion if p != nullptr. 52 | void deallocate(void const* const p) override { 53 | TOGO_ASSERTE(!p); 54 | } 55 | }; 56 | 57 | /** @} */ // end of doc-group lib_core_memory 58 | 59 | } // namespace togo 60 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/memory/fixed_allocator.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/memory/fixed_allocator.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace togo { 13 | 14 | void* memory::fixed_allocator_allocate( 15 | u8** put_pointer, u8* buffer_end, 16 | unsigned const size, unsigned const align 17 | ) { 18 | TOGO_DEBUG_ASSERTE(size != 0); 19 | u8* p = pointer_align(*put_pointer, align); 20 | TOGO_ASSERT((p + size) <= buffer_end, "allocator buffer overflow"); 21 | *put_pointer = p + size; 22 | return p; 23 | } 24 | 25 | } // namespace togo 26 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/memory/jump_block_allocator.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/memory/jump_block_allocator.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace togo { 13 | 14 | namespace { 15 | static constexpr unsigned const 16 | BLOCK_SIZE_MIN = 4 * 1024; // 4KB 17 | } 18 | 19 | #define BLOCK_NEXT_PTR(block) \ 20 | *reinterpret_cast(block) 21 | 22 | JumpBlockAllocator::~JumpBlockAllocator() { 23 | void* p = BLOCK_NEXT_PTR(_base_block); 24 | while (p) { 25 | TOGO_LOG_DEBUGF("JumpBlockAllocator: destroying block: %p\n", p); 26 | void* const next = BLOCK_NEXT_PTR(p); 27 | _fallback_allocator.deallocate(p); 28 | p = next; 29 | } 30 | } 31 | 32 | JumpBlockAllocator::JumpBlockAllocator( 33 | char* const base_block_begin, 34 | char* const base_block_end, 35 | Allocator& fallback_allocator 36 | ) 37 | : _base_block(base_block_begin) 38 | , _block_begin(base_block_begin) 39 | , _block_end(base_block_end) 40 | , _put(_base_block + sizeof(void*)) 41 | , _fallback_allocator(fallback_allocator) 42 | { 43 | BLOCK_NEXT_PTR(_block_begin) = nullptr; 44 | } 45 | 46 | void* JumpBlockAllocator::allocate(unsigned const size, unsigned const align) { 47 | TOGO_ASSERTE(size != 0); 48 | _put = pointer_align(_put, align); 49 | if (signed_cast(size) > _block_end - _put) { 50 | unsigned const block_size = max( 51 | unsigned{sizeof(void*)} + size + align, 52 | BLOCK_SIZE_MIN 53 | ); 54 | _put = static_cast(_fallback_allocator.allocate(block_size)); 55 | TOGO_LOG_DEBUGF("JumpBlockAllocator: new block: %u @ %p\n", block_size, _put); 56 | BLOCK_NEXT_PTR(_block_begin) = _put; 57 | _block_begin = _put; 58 | BLOCK_NEXT_PTR(_block_begin) = nullptr; 59 | _block_end = _block_begin + block_size; 60 | _put += sizeof(void*); 61 | _put = pointer_align(_put, align); 62 | } 63 | void* const p = _put; 64 | _put += size; 65 | return p; 66 | } 67 | 68 | } // namespace togo 69 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/memory/temp_allocator.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/memory/temp_allocator.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief TempAllocator class. 7 | @ingroup lib_core_memory 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | namespace togo { 19 | 20 | /** 21 | @addtogroup lib_core_memory 22 | @{ 23 | */ 24 | 25 | /// Temporary stack-buffered, allocator-backed allocator. 26 | /// 27 | /// This allocator is backed by a JumpBlockAllocator with an internal 28 | /// char[S] buffer as the base block. This allocator is not 29 | /// thread-safe. 30 | /// 31 | /// S is the number of bytes in the buffer. S must be a power of 2 at least 32 | /// twice the size of a pointer. 33 | template 34 | class TempAllocator 35 | : public JumpBlockAllocator 36 | { 37 | public: 38 | static constexpr unsigned const 39 | BUFFER_SIZE = S; 40 | 41 | static_assert( 42 | (BUFFER_SIZE & (BUFFER_SIZE - 1)) == 0 && 43 | BUFFER_SIZE >= 2 * sizeof(void*), 44 | "S must be a power of 2 at least twice the size of a pointer" 45 | ); 46 | 47 | char _buffer[BUFFER_SIZE]; 48 | 49 | TempAllocator(TempAllocator&&) = delete; 50 | TempAllocator(TempAllocator const&) = delete; 51 | TempAllocator& operator=(TempAllocator&&) = delete; 52 | TempAllocator& operator=(TempAllocator const&) = delete; 53 | 54 | ~TempAllocator() = default; 55 | 56 | /// Construct with fallback allocator. 57 | TempAllocator(Allocator& fallback_allocator = memory::scratch_allocator()) 58 | : JumpBlockAllocator( 59 | _buffer, 60 | _buffer + BUFFER_SIZE, 61 | fallback_allocator 62 | ) 63 | {} 64 | }; 65 | 66 | /** @} */ // end of doc-group lib_core_memory 67 | 68 | } // namespace togo 69 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/memory/types.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/memory/types.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Memory types. 7 | @ingroup lib_core_types 8 | @ingroup lib_core_memory 9 | */ 10 | 11 | #pragma once 12 | 13 | #include 14 | 15 | namespace togo { 16 | 17 | /** 18 | @addtogroup lib_core_memory 19 | @{ 20 | */ 21 | 22 | // Forward declarations 23 | class Allocator; 24 | class AssertAllocator; 25 | template 26 | class FixedAllocator; 27 | class JumpBlockAllocator; 28 | template 29 | class TempAllocator; 30 | 31 | /// Memory constants. 32 | enum : unsigned { 33 | /// Minimum scratch size (8K). 34 | SCRATCH_ALLOCATOR_SIZE_MINIMUM = 8 * 1024, 35 | /// Default scratch size (4MB). 36 | SCRATCH_ALLOCATOR_SIZE_DEFAULT = 4 * 1024 * 1024 37 | }; 38 | 39 | /** @} */ // end of doc-group lib_core_memory 40 | 41 | } // namespace togo 42 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/parser/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_core_parser Parser 5 | @ingroup lib_core 6 | @details 7 | 8 | Combinator-based recursive descent parser. 9 | 10 | All allocations on Parser construction aren't released, so you'll need a 11 | lenient allocator (such as FixedAllocator) to avoid errors. 12 | 13 | */ 14 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/parser/debug.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/parser/debug.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Parser debug variables. 7 | @ingroup lib_core_parser 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | 15 | namespace togo { 16 | namespace parser { 17 | 18 | #if defined(TOGO_DEBUG) 19 | extern thread_local unsigned s_debug_trace_depth; 20 | extern thread_local unsigned s_debug_error_gen; 21 | extern thread_local unsigned s_debug_error_last; 22 | extern thread_local bool s_debug_error_show; 23 | #endif 24 | 25 | } // namespace parser 26 | } // namespace togo 27 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/random/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_core_random Random 5 | @ingroup lib_core 6 | @details 7 | 8 | The RNGs have the following properties: 9 | 10 | - xorshift64*: 2^64 - 1 period, 64 bits of state 11 | - xorshift128+: 2^128 - 1 period, 128 bits of state 12 | - xorshift1024*: 2^1024 - 1 period, 1024 bits of state 13 | 14 | xorshift128+ is the fastest xorshift RNG with nearly as few BitCrush 15 | failures as xorshift1024*. 16 | 17 | xorshift64* has the smallest state, but is much lower in quality 18 | compared to the other two. It is used to seed xorshift128+ and 19 | xorshift1024* from a 64-bit seed. 20 | 21 | */ 22 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/random/random.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/random/random.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace togo { 14 | 15 | enum : u64 { 16 | XS64M_MULTIPLIER = 0x2545F4914F6CDD1Dull, 17 | XS1024M_MULTIPLIER = 0x106689D45497FDB5ull, 18 | }; 19 | 20 | /// Seed xorshift64* RNG. 21 | inline void random::seed(XS64M& s, u64 const seed) { 22 | TOGO_DEBUG_ASSERT(seed != 0, "seed value must be non-zero"); 23 | s._v = seed; 24 | } 25 | 26 | /// Iterate xorshift64* RNG. 27 | inline u64 random::next(XS64M& s) { 28 | s._v ^= s._v >> 12; // a 29 | s._v ^= s._v << 25; // b 30 | s._v ^= s._v >> 27; // c 31 | return s._v * XS64M_MULTIPLIER; 32 | } 33 | 34 | /// Seed xorshift128+ RNG. 35 | void random::seed(XS128A& s, u64 seed) { 36 | TOGO_DEBUG_ASSERT(seed != 0, "seed value must be non-zero"); 37 | XS64M seed_rng{seed}; 38 | s._v[0] = random::next(seed_rng); 39 | s._v[1] = random::next(seed_rng); 40 | } 41 | 42 | /// Iterate xorshift128+ RNG. 43 | u64 random::next(XS128A& s) { 44 | u64 s1 = s._v[0]; 45 | u64 const s0 = s._v[1]; 46 | s._v[0] = s0; 47 | s1 ^= s1 << 23; // a 48 | return (s._v[1] = s1 ^ s0 ^ (s1 >> 17) ^ (s0 >> 26)) + s0; // b, c 49 | } 50 | 51 | /// Seed xorshift1024* RNG. 52 | void random::seed(XS1024M& s, u64 const seed) { 53 | TOGO_DEBUG_ASSERT(seed != 0, "seed value must be non-zero"); 54 | XS64M seed_rng{seed}; 55 | s._i = 0; 56 | for (unsigned i = 0; i < array_extent(s._v); ++i) { 57 | s._v[i] = random::next(seed_rng); 58 | } 59 | } 60 | 61 | /// Iterate xorshift1024* RNG. 62 | u64 random::next(XS1024M& s) { 63 | u64 s0 = s._v[s._i]; 64 | u64 s1 = s._v[s._i = (s._i + 1) & 15]; 65 | s1 ^= s1 << 31; // a 66 | s1 ^= s1 >> 11; // b 67 | s0 ^= s0 >> 30; // c 68 | return (s._v[s._i] = s0 ^ s1) * XS1024M_MULTIPLIER; 69 | } 70 | 71 | } // namespace togo 72 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/serialization/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_core_serialization Serialization 5 | @ingroup lib_core 6 | @details 7 | 8 | */ 9 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/serialization/array.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/serialization/array.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Array serialization. 7 | @ingroup lib_core_serialization 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | namespace togo { 20 | 21 | /** 22 | @addtogroup lib_core_serialization 23 | @{ 24 | */ 25 | 26 | /** @cond INTERNAL */ 27 | 28 | template 29 | inline void 30 | read(serializer_tag, Ser& ser, SerCollection>&& value) { 31 | auto& collection = value.ref; 32 | S size{}; 33 | ser % size; 34 | 35 | array::resize(collection, size); 36 | ser % make_ser_sequence( 37 | array::begin(collection), 38 | array::size(collection) 39 | ); 40 | } 41 | 42 | template 43 | inline void 44 | write(serializer_tag, Ser& ser, SerCollection, C> const& value) { 45 | auto const& collection = value.ref; 46 | auto const size = array::size(collection); 47 | TOGO_DEBUG_ASSERTE(std::numeric_limits::max() >= size); 48 | ser 49 | % static_cast(size) 50 | % make_ser_sequence( 51 | array::begin(collection), 52 | size 53 | ) 54 | ; 55 | } 56 | 57 | /** @endcond */ // INTERNAL 58 | 59 | /** @} */ // end of doc-group lib_core_serialization 60 | 61 | } // namespace togo 62 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/serialization/fixed_array.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/serialization/fixed_array.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief FixedArray serialization. 7 | @ingroup lib_core_serialization 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | namespace togo { 20 | 21 | /** 22 | @addtogroup lib_core_serialization 23 | @{ 24 | */ 25 | 26 | /** @cond INTERNAL */ 27 | 28 | template 29 | inline void 30 | read(serializer_tag, Ser& ser, SerCollection>&& value) { 31 | static_assert( 32 | std::numeric_limits::max() >= N, 33 | "S is smaller than the fixed capacity of this collection" 34 | ); 35 | 36 | auto& collection = value.ref; 37 | S size{}; 38 | ser % size; 39 | 40 | // NB: Assertion in resize() will cover invalid sizes 41 | fixed_array::resize(collection, size); 42 | ser % make_ser_sequence( 43 | fixed_array::begin(collection), 44 | fixed_array::size(collection) 45 | ); 46 | } 47 | 48 | template 49 | inline void 50 | write(serializer_tag, Ser& ser, SerCollection, C> const& value) { 51 | static_assert( 52 | std::numeric_limits::max() >= N, 53 | "S is smaller than the fixed capacity of this collection" 54 | ); 55 | 56 | auto const& collection = value.ref; 57 | auto const size = fixed_array::size(collection); 58 | TOGO_DEBUG_ASSERTE(std::numeric_limits::max() >= size); 59 | ser 60 | % static_cast(size) 61 | % make_ser_sequence( 62 | fixed_array::begin(collection), 63 | size 64 | ) 65 | ; 66 | } 67 | 68 | /** @endcond */ // INTERNAL 69 | 70 | /** @} */ // end of doc-group lib_core_serialization 71 | 72 | } // namespace togo 73 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/serialization/vector.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/serialization/array.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Array serialization. 7 | @ingroup lib_core_serialization 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | namespace togo { 19 | 20 | /** 21 | @addtogroup lib_core_serialization 22 | @{ 23 | */ 24 | 25 | /** @cond INTERNAL */ 26 | 27 | namespace { 28 | template struct is_md_vector : false_type {}; 29 | template<> struct is_md_vector : true_type {}; 30 | template<> struct is_md_vector : true_type {}; 31 | template<> struct is_md_vector : true_type {}; 32 | } // anonymous namespace 33 | 34 | template 35 | inline enable_if, Vec1>::value, void> 36 | serialize(serializer_tag, Ser& ser, T& value_unsafe) { 37 | auto& value = serializer_cast_safe(value_unsafe); 38 | ser % value.x; 39 | } 40 | 41 | template 42 | inline enable_if::value, void> 43 | serialize(serializer_tag, Ser& ser, T& value_unsafe) { 44 | auto& value = serializer_cast_safe(value_unsafe); 45 | ser % make_ser_sequence(&value.x, T::size()); 46 | } 47 | 48 | /** @endcond */ // INTERNAL 49 | 50 | /** @} */ // end of doc-group lib_core_serialization 51 | 52 | } // namespace togo 53 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/string/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_core_string String 5 | @ingroup lib_core 6 | @details 7 | 8 | String manipulation (including string::copy()) functions ensure data 9 | is NUL-terminated. string::size() should always be used to obtain the 10 | logical size (especially for fixed-capacity arrays, where the size is 11 | string::size(array) + 1 due to the terminator). 12 | 13 | */ 14 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/string/types.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/string/types.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief String types. 7 | @ingroup lib_core_types 8 | @ingroup lib_core_string 9 | */ 10 | 11 | #pragma once 12 | 13 | #include 14 | #include 15 | 16 | namespace togo { 17 | 18 | // Forward declarations 19 | namespace fixed_array { 20 | template 21 | struct FixedArray; // external 22 | } // namespace fixed_array 23 | 24 | namespace array { 25 | template 26 | struct Array; // external 27 | } // namespace array 28 | 29 | /** 30 | @addtogroup lib_core_string 31 | @{ 32 | */ 33 | 34 | /// Constant string reference. 35 | struct StringRef { 36 | /// String data. 37 | char const* data; 38 | /// String size (not including terminating NUL if there is one). 39 | unsigned size; 40 | 41 | StringRef(StringRef const&) = default; 42 | StringRef(StringRef&&) = default; 43 | StringRef& operator=(StringRef const&) = default; 44 | StringRef& operator=(StringRef&&) = default; 45 | 46 | StringRef(); 47 | StringRef(char const* const cstr, cstr_tag); 48 | StringRef(char const* const data, char const* const end); 49 | constexpr StringRef(char const* const data, unsigned const size); 50 | template 51 | constexpr StringRef(char const (&data)[N]); 52 | template 53 | StringRef(fixed_array::FixedArray const& array); 54 | StringRef(array::Array const& array); 55 | StringRef(ArrayRef const& array); 56 | StringRef(ArrayRef const& array); 57 | 58 | bool valid() const; 59 | bool any() const; 60 | bool empty() const; 61 | 62 | char operator[](unsigned const i) const; 63 | }; 64 | 65 | /** @} */ // end of doc-group lib_core_string 66 | 67 | } // namespace togo 68 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/system/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_core_system System 5 | @ingroup lib_core 6 | @details 7 | 8 | */ 9 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/system/system.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/system/system.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #if defined(TOGO_PLATFORM_LINUX) 12 | #include 13 | #else 14 | #error "unimplemented for target platform" 15 | #endif 16 | 17 | #include 18 | 19 | namespace togo { 20 | 21 | /// System time in seconds since the POSIX epoch. 22 | u64 system::secs_since_epoch() { 23 | auto const s = std::time(nullptr); 24 | TOGO_ASSERT(s != static_cast(-1), "std::time() failed"); 25 | return static_cast(s); 26 | } 27 | 28 | } // namespace togo 29 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/system/system.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/system/system.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief OS interface. 7 | @ingroup lib_core_system 8 | */ 9 | 10 | #pragma once 11 | 12 | // igen-source: system/system_li.cpp 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | namespace togo { 23 | namespace system { 24 | 25 | /** 26 | @addtogroup lib_core_system 27 | @{ 28 | */ 29 | 30 | /// Process ID. 31 | unsigned pid(); 32 | 33 | /// Number of CPU cores. 34 | unsigned num_cores(); 35 | 36 | /// Hostname. 37 | StringRef hostname(); 38 | 39 | /// Sleep the current thread for a duration in milliseconds. 40 | void sleep_ms(unsigned duration_ms); 41 | 42 | /// Time in seconds from monotonic system clock. 43 | /// 44 | /// The return value should have a precision of milliseconds or 45 | /// better (typically nanoseconds). 46 | f64 time_monotonic(); 47 | 48 | /// Get environment variable value. 49 | /// 50 | /// name must be NUL-terminated. 51 | /// If the return value will be stored & reused, it should be copied 52 | /// to another value. 53 | /// If the variable is modified, the return value will not reflect 54 | /// the value at the point of call. 55 | /// If the variable is removed, the return value will be invalid. 56 | StringRef environment_variable(StringRef const& name); 57 | 58 | /// Set environment variable value. 59 | /// 60 | /// name must be NUL-terminated. 61 | /// value must be NUL-terminated. 62 | bool set_environment_variable( 63 | StringRef const& name, 64 | StringRef const& value 65 | ); 66 | 67 | /// Remove environment variable. 68 | bool remove_environment_variable(StringRef const& name); 69 | 70 | /** @} */ // end of doc-group lib_core_system 71 | 72 | } // namespace system 73 | } // namespace togo 74 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/system/system.lua: -------------------------------------------------------------------------------- 1 | u8R""__RAW_STRING__( 2 | 3 | local U = require "togo.utility" 4 | local M = U.module(...) 5 | 6 | M.debug = false 7 | 8 | return M 9 | 10 | )"__RAW_STRING__" -------------------------------------------------------------------------------- /lib/core/src/togo/core/threading/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_core_threading Threading 5 | @ingroup lib_core 6 | @details 7 | 8 | */ 9 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/threading/condvar.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/threading/condvar.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #if defined(TOGO_PLATFORM_IS_POSIX) 11 | #include 12 | #else 13 | #error "missing CondVar implementation for target platform" 14 | #endif 15 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/threading/condvar.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/threading/condvar.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief CondVar interface. 7 | @ingroup lib_core_threading 8 | @ingroup lib_core_condvar 9 | 10 | @defgroup lib_core_condvar CondVar 11 | @ingroup lib_core_threading 12 | @details 13 | */ 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | 20 | namespace togo { 21 | 22 | namespace condvar { 23 | 24 | /** 25 | @addtogroup lib_core_condvar 26 | @{ 27 | */ 28 | 29 | /// Signal a single thread waiting on the condition variable. 30 | /// 31 | /// This makes no actual constraint, but the mutex must already be 32 | /// locked. 33 | void signal(CondVar& cv, Mutex& m); 34 | 35 | /// Signal a single thread waiting on the condition variable. 36 | inline void signal(CondVar& cv, MutexLock& l) { 37 | signal(cv, l._mutex); 38 | } 39 | 40 | /// Signal all threads waiting on the condition variable. 41 | /// 42 | /// This makes no actual constraint, but the mutex must already be 43 | /// locked. 44 | void signal_all(CondVar& cv, Mutex& m); 45 | 46 | /// Signal all threads waiting on the condition variable. 47 | inline void signal_all(CondVar& cv, MutexLock& l) { 48 | signal_all(cv, l._mutex); 49 | } 50 | 51 | /// Wait for a condition variable to be signaled. 52 | /// 53 | /// This makes no actual constraint, but the mutex must already be 54 | /// locked. The mutex will be atomically unlocked before suspending 55 | /// thread execution and locked again before returning (when 56 | /// signaled). 57 | void wait(CondVar& cv, Mutex& m); 58 | 59 | /// Wait for a condition variable to be signaled. 60 | /// 61 | /// The mutex lock will be atomically released before suspending 62 | /// thread execution and acquired again before returning (when 63 | /// signaled). 64 | inline void wait(CondVar& cv, MutexLock& l) { 65 | wait(cv, l._mutex); 66 | } 67 | 68 | /** @} */ // end of doc-group lib_core_condvar 69 | 70 | } // namespace condvar 71 | 72 | /// Construct condition variable. 73 | inline CondVar::CondVar() 74 | : _impl(*this) 75 | {} 76 | 77 | } // namespace togo 78 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/threading/condvar/posix.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/threading/condvar/posix.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace togo { 13 | 14 | // Forward declarations 15 | struct CondVar; 16 | 17 | struct PosixCondVarImpl { 18 | pthread_cond_t handle; 19 | 20 | PosixCondVarImpl(CondVar&) 21 | : handle(PTHREAD_COND_INITIALIZER) 22 | {} 23 | ~PosixCondVarImpl(); 24 | }; 25 | 26 | using CondVarImpl = PosixCondVarImpl; 27 | 28 | } // namespace togo 29 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/threading/condvar/posix.ipp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/threading/mutex/posix.ipp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | namespace togo { 18 | 19 | #define POSIX_CHECK(f) \ 20 | if (((err) = (f))) { goto posix_error; } 21 | 22 | PosixCondVarImpl::~PosixCondVarImpl() { 23 | if (pthread_cond_destroy(&handle) == EBUSY) { 24 | TOGO_ASSERT(false, "cannot destroy in-use condvar"); 25 | } 26 | } 27 | 28 | // condvar interface implementation 29 | 30 | void condvar::signal(CondVar& cv, Mutex& /*m*/) { 31 | signed err = 0; 32 | POSIX_CHECK(pthread_cond_signal(&cv._impl.handle)); 33 | return; 34 | 35 | posix_error: 36 | TOGO_ASSERTF(false, "error signaling condvar: %d, %s", err, std::strerror(err)); 37 | } 38 | 39 | void condvar::signal_all(CondVar& cv, Mutex& /*m*/) { 40 | signed err = 0; 41 | POSIX_CHECK(pthread_cond_broadcast(&cv._impl.handle)); 42 | return; 43 | 44 | posix_error: 45 | TOGO_ASSERTF(false, "error signaling condvar: %d, %s", err, std::strerror(err)); 46 | } 47 | 48 | void condvar::wait(CondVar& cv, Mutex& m) { 49 | signed err = 0; 50 | POSIX_CHECK(pthread_cond_wait(&cv._impl.handle, &m._impl.handle)); 51 | return; 52 | 53 | posix_error: 54 | TOGO_ASSERTF(false, "error waiting on condvar: %d, %s", err, std::strerror(err)); 55 | } 56 | 57 | } // namespace togo 58 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/threading/mutex.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/threading/mutex.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #if defined(TOGO_PLATFORM_IS_POSIX) 11 | #include 12 | #else 13 | #error "missing Mutex implementation for target platform" 14 | #endif 15 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/threading/mutex.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/threading/mutex.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Mutex interface. 7 | @ingroup lib_core_threading 8 | @ingroup lib_core_mutex 9 | 10 | @defgroup lib_core_mutex Mutex 11 | @ingroup lib_core_threading 12 | @details 13 | */ 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | 20 | namespace togo { 21 | 22 | namespace mutex { 23 | 24 | /** 25 | @addtogroup lib_core_mutex 26 | @{ 27 | */ 28 | 29 | /// Attempt to lock a mutex. 30 | /// 31 | /// Returns true if the lock attempt succeeded; returns false if the 32 | /// normal mutex was already locked on any thread. 33 | /// With a recursive mutex, this behaves as lock(). 34 | bool try_lock(Mutex& m); 35 | 36 | /// Lock a mutex directly. 37 | /// 38 | /// This will block until the lock can be acquired from another 39 | /// thread. If the mutex is already locked on the current thread, it 40 | /// can fail in debug mode, but may silently fail in non-debug mode. 41 | /// If the mutex is recursive, a locked mutex can only be locked again 42 | /// by the thread on which it was first locked. 43 | void lock(Mutex& m); 44 | 45 | /// Unlock a mutex directly. 46 | /// 47 | /// This will fail if the mutex is not locked or if the current thread 48 | /// is not the same as the thread that locked the thread. 49 | /// Recursive mutexes require the same number of locks as unlocks. 50 | /// A recursive mutex is only unlocked once each lock operation has 51 | /// been undone. 52 | void unlock(Mutex& m); 53 | 54 | /** @} */ // end of doc-group lib_core_mutex 55 | 56 | } // namespace mutex 57 | 58 | /// Construct typed mutex. 59 | inline Mutex::Mutex(MutexType const type) 60 | : _type(type) 61 | , _impl(*this) 62 | {} 63 | 64 | /// Destroy lock. 65 | /// 66 | /// This will unlock the mutex. 67 | inline MutexLock::~MutexLock() { 68 | mutex::unlock(_mutex); 69 | } 70 | 71 | /// Construct lock. 72 | /// 73 | /// This will immediately lock the mutex. 74 | inline MutexLock::MutexLock(Mutex& m) 75 | : _mutex(m) 76 | { 77 | mutex::lock(_mutex); 78 | } 79 | 80 | } // namespace togo 81 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/threading/mutex/posix.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/threading/mutex/posix.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace togo { 13 | 14 | // Forward declarations 15 | struct Mutex; 16 | 17 | struct PosixMutexImpl { 18 | pthread_mutex_t handle; 19 | 20 | PosixMutexImpl(Mutex& m); 21 | ~PosixMutexImpl(); 22 | }; 23 | 24 | using MutexImpl = PosixMutexImpl; 25 | 26 | } // namespace togo 27 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/threading/mutex/posix.ipp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/threading/mutex/posix.ipp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | namespace togo { 18 | 19 | #define POSIX_CHECK(f) \ 20 | if (((err) = (f))) { goto posix_error; } 21 | 22 | PosixMutexImpl::PosixMutexImpl(Mutex& m) 23 | : handle( 24 | #if defined(TOGO_DEBUG) 25 | PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP 26 | #else 27 | PTHREAD_MUTEX_INITIALIZER 28 | #endif 29 | ) 30 | { 31 | if (m._type == MutexType::recursive) { 32 | handle = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; 33 | } 34 | } 35 | 36 | PosixMutexImpl::~PosixMutexImpl() { 37 | if (pthread_mutex_destroy(&handle) == EBUSY) { 38 | TOGO_ASSERT(false, "cannot destroy locked mutex"); 39 | } 40 | } 41 | 42 | // mutex interface implementation 43 | 44 | bool mutex::try_lock(Mutex& m) { 45 | signed err = pthread_mutex_trylock(&m._impl.handle); 46 | if (err == EBUSY) { 47 | return false; 48 | } else if (err) { 49 | goto posix_error; 50 | } 51 | return true; 52 | 53 | posix_error: 54 | TOGO_ASSERTF(false, "error try-locking mutex: %d, %s", err, std::strerror(err)); 55 | } 56 | 57 | void mutex::lock(Mutex& m) { 58 | signed err = 0; 59 | POSIX_CHECK(pthread_mutex_lock(&m._impl.handle)); 60 | return; 61 | 62 | posix_error: 63 | TOGO_ASSERTF(false, "error locking mutex: %d, %s", err, std::strerror(err)); 64 | } 65 | 66 | void mutex::unlock(Mutex& m) { 67 | signed err = 0; 68 | POSIX_CHECK(pthread_mutex_unlock(&m._impl.handle)); 69 | return; 70 | 71 | posix_error: 72 | TOGO_ASSERTF(false, "error unlocking mutex: %d, %s", err, std::strerror(err)); 73 | } 74 | 75 | } // namespace togo 76 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/threading/task_manager.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/threading/task_manager.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief TaskManager interface. 7 | @ingroup lib_core_threading 8 | @ingroup lib_core_task_manager 9 | 10 | @defgroup lib_core_task_manager TaskManager 11 | @ingroup lib_core_threading 12 | @details 13 | 14 | TaskManager has a limit of 128 active tasks. An assertion will fail if any 15 | are added when there are no free slots. 16 | 17 | If TaskWork has a null func, its task is considered "empty" and no 18 | execution is done for it. Empty tasks can be used to collate sub-tasks and 19 | build task dependencies without incurring extra calls and synchronization 20 | tear down/setup. 21 | 22 | If workers are available, they will execute either the next available task 23 | or the next task to be added. As a result, "priority" may not be fully 24 | honored if tasks aren't added in a descending priority order. To ensure the 25 | highest priority tasks are executed first, either setup a hierarchy with 26 | task_manager::add_hold() or add them in descending priority. Furthermore, 27 | lower-priority tasks may be executed before higher-priority tasks due to 28 | preemption. 29 | */ 30 | 31 | #pragma once 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | namespace togo { 39 | namespace task_manager { 40 | 41 | /** 42 | @addtogroup lib_core_task_manager 43 | @{ 44 | */ 45 | 46 | /// Construct an empty TaskWork. 47 | inline TaskWork task_work_empty() { 48 | return {nullptr, nullptr}; 49 | } 50 | 51 | /// Add an empty task with a hold on its completion. 52 | inline TaskID add_hold_empty(TaskManager& tm, u16 priority = 0) { 53 | return add_hold(tm, task_work_empty(), priority); 54 | } 55 | 56 | /** @} */ // end of doc-group lib_core_task_manager 57 | 58 | } // namespace task_manager 59 | } // namespace togo 60 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/threading/thread.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/threading/thread.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace togo { 16 | 17 | enum : u32 { 18 | THREAD_DATA_NAME_SIZE = 32 19 | }; 20 | 21 | struct ThreadData { 22 | void* call_data; 23 | void* (*func)(void* call_data); 24 | Allocator* allocator; 25 | char name[THREAD_DATA_NAME_SIZE]; 26 | }; 27 | 28 | inline void thread_data_init( 29 | ThreadData& data, 30 | char const* name, 31 | void* call_data, 32 | void* (*func)(void* call_data), 33 | Allocator& allocator 34 | ) { 35 | TOGO_DEBUG_ASSERTE(name); 36 | TOGO_DEBUG_ASSERTE(func); 37 | std::strncpy(data.name, name, THREAD_DATA_NAME_SIZE - 1); 38 | data.name[THREAD_DATA_NAME_SIZE - 1] = '\0'; 39 | data.call_data = call_data; 40 | data.func = func; 41 | data.allocator = &allocator; 42 | } 43 | 44 | namespace { 45 | struct ThreadLocalRef { 46 | char const* name; 47 | }; 48 | 49 | thread_local ThreadLocalRef 50 | _tls_thread_ref{ 51 | nullptr 52 | }; 53 | } // anonymous namespace 54 | 55 | inline void* thread_runner(ThreadData& data) { 56 | _tls_thread_ref.name = data.name; 57 | void* exit_value = data.func(data.call_data); 58 | _tls_thread_ref.name = nullptr; 59 | return exit_value; 60 | } 61 | 62 | /// Name of the current thread. 63 | char const* thread::name() { 64 | if (thread::is_main()) { 65 | return "main"; 66 | } else if (!_tls_thread_ref.name) { 67 | return "uninitialized-thread"; 68 | } else { 69 | return _tls_thread_ref.name; 70 | } 71 | } 72 | 73 | } // namespace togo 74 | 75 | #if defined(TOGO_PLATFORM_IS_POSIX) 76 | #include 77 | #else 78 | #error "missing thread implementation for target platform" 79 | #endif 80 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/threading/thread.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/threading/thread.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Thread interface. 7 | @ingroup lib_core_threading 8 | @ingroup lib_core_thread 9 | 10 | @defgroup lib_core_thread Thread 11 | @ingroup lib_core_threading 12 | @details 13 | */ 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | namespace togo { 23 | namespace thread { 24 | 25 | /** 26 | @addtogroup lib_core_thread 27 | @{ 28 | */ 29 | 30 | // implementation 31 | 32 | /// Name. 33 | char const* name(Thread* t); 34 | 35 | /// Whether the current thread is the main thread. 36 | bool is_main(); 37 | 38 | /// Yield to the processor on the current thread. 39 | void yield(); 40 | 41 | /// Create thread. 42 | /// 43 | /// Execution will begin as soon as the system allots time to the 44 | /// thread. 45 | /// An assertion will fail if a thread could not be created. 46 | /// name will be copied and truncated to 32 characters. 47 | /// func takes the specified call_data. 48 | /// allocator will be used to construct and destroy the thread 49 | /// object, so its lifetime must be longer than the thread's. 50 | Thread* create( 51 | char const* name, 52 | void* call_data, 53 | void* (*func)(void* call_data), 54 | Allocator& allocator = memory::default_allocator() 55 | ); 56 | 57 | /// Join thread. 58 | /// 59 | /// The thread object will be invalid after this call. The return 60 | /// value is the return value of the function passed to 61 | /// thread::create(). This blocks until the thread completes its 62 | /// execution. 63 | void* join(Thread* t); 64 | 65 | /** @} */ // end of doc-group lib_core_thread 66 | 67 | } // namespace thread 68 | } // namespace togo 69 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/tool/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_core_tool Tool 5 | @ingroup lib_core 6 | @details 7 | 8 | */ 9 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/tool/tool.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/tool/tool.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace togo { 14 | 15 | /// Run tool. 16 | /// 17 | /// Uses Tool.run_tool() with the top of the stack (tool_supplied) or Tool.base_tool. 18 | /// 19 | /// args should include argv[0] (i.e., use the whole array). 20 | bool tool::run( 21 | lua_State* L, 22 | ArrayRef args, 23 | bool tool_supplied 24 | ) { 25 | lua::push_value(L, lua::pcall_error_message_handler); 26 | lua::load_module(L, "togo.Tool", true); 27 | lua::table_get_raw(L, "run_tool"); 28 | 29 | if (tool_supplied) { 30 | // move supplied tool 31 | lua_pushvalue(L, -4); 32 | lua_remove(L, -5); 33 | } else { 34 | lua::table_get_raw(L, -3, "base_tool"); 35 | } 36 | lua_remove(L, -3); // togo.Tool 37 | 38 | lua_createtable(L, 0, args.size()); 39 | for (unsigned i = 0; i < args.size(); ++i) { 40 | lua::table_set_index_raw(L, i + 1, StringRef{args[i], cstr_tag{}}); 41 | } 42 | 43 | bool r = true; 44 | if (lua_pcall(L, 2, 1, -4)) { 45 | auto error = lua::get_string(L, -1); 46 | TOGO_LOGF("error: %.*s\n", error.size, error.data); 47 | r = false; 48 | } else if (lua_isboolean(L, -1)) { 49 | r = lua::get_boolean(L, -1); 50 | } 51 | lua_pop(L, 2); 52 | 53 | return r; 54 | } 55 | 56 | } // namespace togo 57 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/tool/tool.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/tool/tool.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Tool interface. 7 | @ingroup lib_core_tool 8 | */ 9 | 10 | #pragma once 11 | 12 | // igen-source: tool/tool_li.cpp 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | namespace togo { 23 | namespace tool { 24 | 25 | /** 26 | @addtogroup lib_core_tool 27 | @{ 28 | */ 29 | 30 | /** @} */ // end of doc-group lib_core_tool 31 | 32 | } // namespace tool 33 | } // namespace togo 34 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/tool/tool_li.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/tool/tool_li.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace togo { 13 | 14 | namespace tool { 15 | 16 | static LuaModuleRef const li_module{ 17 | "togo.Tool", 18 | "togo/core/tool/Tool.lua", 19 | null_ref_tag{}, 20 | #include 21 | }; 22 | 23 | } // namespace tool 24 | 25 | /// Register the Lua interface. 26 | void tool::register_lua_interface(lua_State* L) { 27 | lua::preload_module(L, tool::li_module); 28 | } 29 | 30 | } // namespace togo 31 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/tool/types.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/tool/types.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Tool types. 7 | @ingroup lib_core_types 8 | @ingroup lib_core_tool 9 | */ 10 | 11 | #pragma once 12 | 13 | #include 14 | #include 15 | 16 | namespace togo { 17 | namespace tool { 18 | 19 | /** 20 | @addtogroup lib_core_tool 21 | @{ 22 | */ 23 | 24 | /** @} */ // end of doc-group lib_core_tool 25 | 26 | } // namespace tool 27 | } // namespace togo 28 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/types.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/types.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Core types. 7 | @ingroup lib_core_types 8 | 9 | @defgroup lib_core_types Types 10 | @ingroup lib_core 11 | @details 12 | */ 13 | 14 | #pragma once 15 | 16 | #include 17 | 18 | #include 19 | #include 20 | 21 | namespace togo { 22 | 23 | /** 24 | @addtogroup lib_core_types 25 | @{ 26 | */ 27 | 28 | namespace basic_types { 29 | 30 | /** @name Signed integral types */ /// @{ 31 | /// Fixed-width signed integral. 32 | using s8 = std::int8_t; 33 | using s16 = std::int16_t; 34 | using s32 = std::int32_t; 35 | using s32_fast = std::int_fast32_t; 36 | using s64 = std::int64_t; 37 | using s64_fast = std::int_fast64_t; 38 | /// @} 39 | 40 | /** @name Unsigned integral types */ /// @{ 41 | /// Fixed-width unsigned integral. 42 | using u8 = std::uint8_t; 43 | using u16 = std::uint16_t; 44 | using u32 = std::uint32_t; 45 | using u32_fast = std::uint_fast32_t; 46 | using u64 = std::uint64_t; 47 | using u64_fast = std::uint_fast64_t; 48 | /// @} 49 | 50 | /** @name Floating-point types */ /// @{ 51 | /// Fixed-width floating-point. 52 | using f32 = float; 53 | using f64 = double; 54 | /// @} 55 | 56 | /** @name Hash types */ /// @{ 57 | /// 32-bit hash. 58 | using hash32 = u32; 59 | /// 64-bit hash. 60 | using hash64 = u64; 61 | /// @} 62 | 63 | } // namespace basic_types 64 | 65 | using namespace basic_types; 66 | 67 | /** @} */ // end of doc-group lib_core_types 68 | 69 | } // namespace togo 70 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/utility/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_core_utility Utilities 5 | @ingroup lib_core 6 | @details 7 | 8 | */ 9 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/utility/args.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/utility/args.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Argument parsing. 7 | @ingroup lib_core_utility 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace togo { 18 | 19 | /** 20 | @addtogroup lib_core_utility 21 | @{ 22 | */ 23 | 24 | 25 | 26 | /** @} */ // end of doc-group lib_core_utility 27 | 28 | } // namespace togo 29 | -------------------------------------------------------------------------------- /lib/core/src/togo/core/utility/types.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/utility/types.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Utility types. 7 | @ingroup lib_core_utility 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | namespace togo { 15 | 16 | /** 17 | @addtogroup lib_core_utility 18 | @{ 19 | */ 20 | 21 | /** @name Variation/placeholder tags */ /// @{ 22 | 23 | /// No-initialize constructor tag. 24 | enum class no_init_tag {}; 25 | 26 | /// Null value tag. 27 | enum class null_tag {}; 28 | 29 | /// Null reference tag. 30 | enum class null_ref_tag {}; 31 | 32 | /// NUL-terminated string tag. 33 | enum class cstr_tag {}; 34 | 35 | /// Boolean value tag. 36 | enum class bool_tag {}; 37 | 38 | /// @} 39 | 40 | /// Endianness. 41 | enum class Endian : unsigned { 42 | /// Little endian. 43 | little = TOGO_ENDIAN_LITTLE, 44 | /// Big endian. 45 | big = TOGO_ENDIAN_BIG, 46 | /// System endian. 47 | system = TOGO_ENDIAN_SYSTEM, 48 | }; 49 | 50 | /// Array reference. 51 | template 52 | struct ArrayRef { 53 | T* _begin; 54 | T* _end; 55 | 56 | ArrayRef(null_ref_tag const) 57 | : _begin(nullptr) 58 | , _end(nullptr) 59 | {} 60 | 61 | ArrayRef(T* const begin, T* const end) 62 | : _begin(begin) 63 | , _end(end) 64 | {} 65 | 66 | ArrayRef(T* const data, unsigned const size) 67 | : ArrayRef(data, data + size) 68 | {} 69 | 70 | template 71 | ArrayRef(T (&data)[N]) 72 | : ArrayRef(data, data + N) 73 | {} 74 | 75 | template::value>*/> 76 | ArrayRef(ArrayRef const& other) 77 | : _begin(other._begin) 78 | , _end(other._end) 79 | {} 80 | 81 | /// Number of items. 82 | unsigned size() const { 83 | return _end - _begin; 84 | } 85 | 86 | /// Get value by index. 87 | T& operator[](unsigned const i); 88 | 89 | /// Get value by index. 90 | T const& operator[](unsigned const i) const; 91 | }; 92 | 93 | /** @} */ // end of doc-group lib_core_utility 94 | 95 | } // namespace togo 96 | -------------------------------------------------------------------------------- /lib/core/test/data/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | file_stream.bin 3 | directory_reader/ 4 | lua_io -------------------------------------------------------------------------------- /lib/core/test/hash/literal.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace togo; 7 | 8 | static constexpr hash32 const 9 | h32_identity = ""_hash32, 10 | h32_test = "test"_hash32; 11 | 12 | static constexpr hash64 const 13 | h64_identity = ""_hash64, 14 | h64_test = "test"_hash64; 15 | 16 | signed main() { 17 | TOGO_ASSERTE(hash::IDENTITY32 == h32_identity); 18 | TOGO_ASSERTE(hash::calc32("test", 4) == h32_test); 19 | TOGO_LOGF( 20 | "32: identity = 0x%08x, \"test\" = 0x%08x\n", 21 | h32_identity, h32_test 22 | ); 23 | 24 | TOGO_ASSERTE(hash::IDENTITY64 == h64_identity); 25 | TOGO_ASSERTE(hash::calc64("test", 4) == h64_test); 26 | TOGO_LOGF( 27 | "64: identity = 0x%016lx, \"test\" = 0x%016lx\n", 28 | h64_identity, h64_test 29 | ); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /lib/core/test/io/file_stream.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #include "./common.hpp" 6 | 7 | using namespace togo; 8 | 9 | signed main() { 10 | static constexpr StringRef const path{"data/file_stream.bin"}; 11 | { 12 | FileWriter writer; 13 | TOGO_ASSERTE(!writer.is_open()); 14 | TOGO_ASSERTE(writer.open(path, false)); 15 | TOGO_ASSERTE(writer.is_open()); 16 | test_writer(writer, true); 17 | writer.close(); 18 | } 19 | { 20 | FileReader reader; 21 | TOGO_ASSERTE(!reader.is_open()); 22 | TOGO_ASSERTE(reader.open(path)); 23 | TOGO_ASSERTE(reader.is_open()); 24 | test_reader(reader, true); 25 | reader.close(); 26 | } 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /lib/core/test/io/memory_stream.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include "./common.hpp" 10 | 11 | using namespace togo; 12 | 13 | signed main() { 14 | memory_init(); 15 | 16 | MemoryStream stream{memory::default_allocator(), 0}; 17 | test_writer(stream, true); 18 | TOGO_ASSERTE(io::seek_to(stream, 0) == 0); 19 | test_reader(stream, true); 20 | 21 | MemoryReader stream_const{array::begin(stream.data()), stream.size()}; 22 | test_reader(stream_const, true); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /lib/core/test/kvs/echo.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | using namespace togo; 16 | 17 | void echo(KVS& root, StringRef const& path, bool const binary) { 18 | TOGO_LOGF("#### reading file: '%.*s'\n", path.size, path.data); 19 | if ( 20 | binary 21 | ? kvs::read_binary_file(root, path) 22 | : kvs::read_text_file(root, path) 23 | ) { 24 | MemoryStream out_stream{memory::default_allocator(), 4096}; 25 | TOGO_ASSERTE(kvs::write_text(root, out_stream)); 26 | unsigned const size = static_cast(out_stream.size()); 27 | TOGO_LOGF( 28 | "#### rewritten (%u): <%.*s>\n", 29 | size, size, array::begin(out_stream.data()) 30 | ); 31 | } else { 32 | TOGO_LOG_ERROR("#### failed to read file\n"); 33 | } 34 | TOGO_LOG("\n"); 35 | } 36 | 37 | signed main(signed argc, char* argv[]) { 38 | memory_init(); 39 | KVS root; 40 | StringRef ref; 41 | bool binary = false; 42 | for (signed i = 1; i < argc; ++i) { 43 | ref = {argv[i], cstr_tag{}}; 44 | if (string::compare_equal(ref, "-b")) { 45 | binary = true; 46 | } else if (string::compare_equal(ref, "-t")) { 47 | binary = false; 48 | } else { 49 | echo(root, ref, binary); 50 | } 51 | } 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /lib/core/test/lua/filesystem.lua: -------------------------------------------------------------------------------- 1 | 2 | local U = require "togo.utility" 3 | local FS = require "togo.filesystem" 4 | 5 | U.print("%d", FS.EntryType.file) 6 | U.print("%d", FS.EntryType.dir) 7 | U.print("%d", FS.EntryType.all) 8 | 9 | local entry_type_name = { 10 | [FS.EntryType.file] = "file", 11 | [FS.EntryType.dir] = "dir", 12 | [FS.EntryType.all] = "all", 13 | } 14 | 15 | for path, entry_type in FS.iterate_dir(".", FS.EntryType.all, false, true, true) do 16 | U.print("%-4s %s", entry_type_name[entry_type], path) 17 | end 18 | -------------------------------------------------------------------------------- /lib/core/test/lua/general.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | using namespace togo; 13 | 14 | signed main(signed argc, char* argv[]) { 15 | memory_init(); 16 | if (argc == 1) { 17 | TOGO_LOG("usage: general.elf script [...]"); 18 | return 1; 19 | } 20 | 21 | lua_State* L = lua::new_state(); 22 | TOGO_ASSERTE(L); 23 | luaL_openlibs(L); 24 | lua::register_core(L); 25 | filesystem::register_lua_interface(L); 26 | io::register_lua_interface(L); 27 | 28 | lua::push_value(L, lua::pcall_error_message_handler); 29 | for (signed i = 1; i < argc; ++i) { 30 | StringRef path{argv[i], cstr_tag{}}; 31 | TOGO_ASSERTF( 32 | filesystem::is_file(path), 33 | "path is either not a file or does not exist: %.*s\n", 34 | path.size, path.data 35 | ); 36 | 37 | if (luaL_loadfile(L, path.data)) { 38 | auto error = lua::get_string(L, -1); 39 | TOGO_LOGF("failed to load script: %.*s\n", error.size, error.data); 40 | lua_pop(L, 1); 41 | continue; 42 | } 43 | if (lua_pcall(L, 0, 0, -2)) { 44 | auto error = lua::get_string(L, -1); 45 | TOGO_LOGF("script error: %.*s\n", error.size, error.data); 46 | lua_pop(L, 1); 47 | continue; 48 | } 49 | } 50 | lua_pop(L, 1); 51 | lua_close(L); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /lib/core/test/lua/io.lua: -------------------------------------------------------------------------------- 1 | 2 | local U = require "togo.utility" 3 | local IO = require "togo.io" 4 | 5 | do 6 | local inaccessible_path = "inaccessible/path" 7 | local test_path = "data/lua_io" 8 | local test_data = [[test]] 9 | 10 | U.assert(IO.write_file(inaccessible_path, test_data) == false) 11 | U.assert(IO.read_file(inaccessible_path) == nil) 12 | 13 | U.assert(IO.write_file(test_path, test_data) == true) 14 | U.assert(IO.read_file(test_path) == test_data) 15 | end 16 | -------------------------------------------------------------------------------- /lib/core/test/lua/utility.lua: -------------------------------------------------------------------------------- 1 | 2 | function print_preload() 3 | print("preload:") 4 | for k, v in pairs(package.preload) do 5 | print(" " .. k .. " = " .. type(v)) 6 | end 7 | end 8 | 9 | print_preload() 10 | 11 | local U = require "togo.utility" 12 | 13 | U.log("util test") 14 | 15 | print_preload() 16 | 17 | do 18 | local t = { 19 | {"/x/", "x"}, 20 | {"/x", "x"}, 21 | {"x", "x"}, 22 | } 23 | for _, p in pairs(t) do 24 | local r = U.trim_slashes(p[1]) 25 | U.print("%s -> %s", p[1], r) 26 | U.assert(r == p[2]) 27 | end 28 | end 29 | 30 | do 31 | local command_parsed, opt, cmd_opt, cmd = U.parse_args({ 32 | "exec", 33 | "-a", 34 | "--b=c", 35 | 36 | "x", 37 | "-y", 38 | "1", 39 | "2", 40 | "-z", 41 | "3", 42 | }) 43 | U.assert(command_parsed) 44 | 45 | local t, i 46 | local function check(name, value) 47 | local p = t[i] 48 | U.assert(p.name == name and p.value == value) 49 | i = i + 1 50 | end 51 | 52 | t = opt; i = 1 53 | U.assert(t.name == "exec") 54 | check("-a", true) 55 | check("--b", "c") 56 | 57 | t = cmd_opt; i = 1 58 | U.assert(t.name == "") 59 | check("-y", true) 60 | 61 | t = cmd; i = 1 62 | U.assert(t.name == "x") 63 | check("", "1") 64 | check("", "2") 65 | check("-z", true) 66 | check("", "3") 67 | end 68 | -------------------------------------------------------------------------------- /lib/core/test/memory/assert_allocator_f1.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | using namespace togo; 8 | 9 | signed main() { 10 | AssertAllocator a; 11 | TOGO_TEST_SHOULD_FAIL(a.allocate(1, 0)); 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /lib/core/test/memory/assert_allocator_f2.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | using namespace togo; 8 | 9 | signed main() { 10 | AssertAllocator a; 11 | TOGO_TEST_SHOULD_FAIL(a.deallocate(&a)); 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /lib/core/test/memory/fixed_allocator.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | using namespace togo; 9 | 10 | signed main() { 11 | // NB: FixedAllocator doesn't need the memory system to be initialized 12 | { 13 | FixedAllocator<1024> a; 14 | TOGO_ASSERTE(a._buffer == a._put); 15 | TOGO_ASSERTE(a.BUFFER_SIZE == 1024); 16 | } 17 | 18 | { 19 | FixedAllocator<1> a; 20 | a.allocate(1, 0); 21 | TOGO_ASSERTE((a._buffer + a.BUFFER_SIZE) == a._put); 22 | } 23 | 24 | { 25 | FixedAllocator<10> a; 26 | a.allocate(1, 0); 27 | TOGO_ASSERTE((a._buffer + 1) == a._put); 28 | a.allocate(4, 0); 29 | TOGO_ASSERTE((a._buffer + 5) == a._put); 30 | a.allocate(4, 0); 31 | TOGO_ASSERTE((a._buffer + 9) == a._put); 32 | a.allocate(1, 0); 33 | TOGO_ASSERTE((a._buffer + 10) == a._put); 34 | } 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /lib/core/test/memory/fixed_allocator_f1.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | using namespace togo; 8 | 9 | signed main() { 10 | FixedAllocator<1> a; 11 | a.allocate(1, 0); 12 | TOGO_TEST_SHOULD_FAIL(a.allocate(1, 0)); 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /lib/core/test/memory/fixed_allocator_f2.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | using namespace togo; 8 | 9 | signed main() { 10 | FixedAllocator<1> a; 11 | TOGO_TEST_SHOULD_FAIL(a.allocate(10, 0)); 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /lib/core/test/memory/init.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | using namespace togo; 5 | 6 | signed main() { 7 | memory::init(); 8 | memory::shutdown(); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /lib/core/test/memory/temp_allocator.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | using namespace togo; 9 | 10 | void f() { 11 | { 12 | TempAllocator<16> a; 13 | } 14 | 15 | TOGO_LOG("\n"); 16 | { 17 | TempAllocator<32> a; 18 | void* p = a.allocate(24); 19 | p = a.allocate(1); 20 | } 21 | 22 | TOGO_LOG("\n"); 23 | { 24 | TempAllocator<16> a; 25 | a.allocate(8); 26 | a.allocate(4087, 1); 27 | a.allocate(4087, 1); 28 | a.allocate(4087, 1); 29 | a.allocate(4087, 1); 30 | a.allocate(4087, 1); 31 | } 32 | } 33 | 34 | signed main() { 35 | memory_init(); 36 | f(); 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /lib/core/test/parser/common.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #if defined(TOGO_DEBUG) 5 | 6 | #define DEBUG_PRINT_PARSER(p_) do { \ 7 | TOGO_LOGF("\n%s @ %4d:\n", __FILE__, __LINE__); \ 8 | parser::debug_print_tree(p_); \ 9 | TOGO_LOG("\n"); \ 10 | } while (false) 11 | 12 | #else 13 | #define DEBUG_PRINT_PARSER(p_) (void(0)) 14 | #endif 15 | 16 | #define PARSE(p_, s_) parser::parse(p_, s_, &error, nullptr) 17 | #define PARSE_S(p_, s_) do { \ 18 | parse_state::init(state); \ 19 | parse_state::set_data(state, s_); \ 20 | parser::parse(p_, state, &error); \ 21 | } while (false) 22 | 23 | #define TEST(p_, s_) parser::test(p_, s_, &error, nullptr) 24 | #define TEST_WHOLE(p_, s_) parser::test_whole(p_, s_, &error, nullptr) 25 | -------------------------------------------------------------------------------- /lib/core/test/system/general.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace togo; 8 | 9 | signed main() { 10 | TOGO_LOGF("pid = %u, num_cores = %u\n", system::pid(), system::num_cores()); 11 | 12 | StringRef const hostname = system::hostname(); 13 | TOGO_LOGF("hostname = %.*s\n", hostname.size, hostname.data); 14 | 15 | TOGO_ASSERTE(system::secs_since_epoch() > 1407135980u); 16 | 17 | // Environment variables 18 | StringRef const env_path = system::environment_variable("PATH"); 19 | TOGO_LOGF("PATH = '%.*s'\n", env_path.size, env_path.data); 20 | 21 | StringRef const env_test_name = "__TOGO_TEST"; 22 | 23 | // Base state of unassigned variable 24 | StringRef env_test_value = system::environment_variable(env_test_name); 25 | TOGO_ASSERTE(!env_test_value.valid()); 26 | 27 | // Assignment 28 | TOGO_ASSERTE(system::set_environment_variable(env_test_name, "test")); 29 | env_test_value = system::environment_variable(env_test_name); 30 | TOGO_ASSERTE(string::compare_equal(env_test_value, "test")); 31 | 32 | // Removal (return to unassigned state) 33 | TOGO_ASSERTE(system::remove_environment_variable(env_test_name)); 34 | env_test_value = system::environment_variable(env_test_name); 35 | TOGO_ASSERTE(!env_test_value.valid()); 36 | 37 | // Timers 38 | TOGO_LOG("\n"); 39 | f64 const start = system::time_monotonic(); 40 | system::sleep_ms(1000u); 41 | f64 const d_1000ms = system::time_monotonic() - start; 42 | system::sleep_ms(100u); 43 | f64 const d_100ms = system::time_monotonic() - start; 44 | system::sleep_ms(10u); 45 | f64 const d_10ms = system::time_monotonic() - start; 46 | system::sleep_ms(1u); 47 | f64 const d_1ms = system::time_monotonic() - start; 48 | 49 | TOGO_LOGF("start : time_monotonic() = %.6f\n", start); 50 | TOGO_LOGF("1000ms delay: time_monotonic() = %.6f\n", d_1000ms); 51 | TOGO_LOGF("100ms delay : time_monotonic() = %.6f\n", d_100ms); 52 | TOGO_LOGF("10ms delay : time_monotonic() = %.6f\n", d_10ms); 53 | TOGO_LOGF("1ms delay : time_monotonic() = %.6f\n", d_1ms); 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /lib/core/test/threading/condvar.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | using namespace togo; 14 | 15 | static Mutex hive_mutex{}; 16 | static CondVar drone_cv{}; 17 | static CondVar queen_cv{}; 18 | static unsigned signal_value = 0; 19 | 20 | struct Drone { 21 | Thread* thread; 22 | }; 23 | 24 | void* drone_func(void*) { 25 | { 26 | MutexLock lock{hive_mutex}; 27 | while (signal_value == 0) { 28 | condvar::wait(drone_cv, lock); 29 | } 30 | TOGO_LOGF("%s: signaled with %u\n", thread::name(), signal_value); 31 | signal_value = 0; 32 | condvar::signal(queen_cv, lock); 33 | } 34 | return nullptr; 35 | } 36 | 37 | void* queen_func(void*) { 38 | static constexpr unsigned const DRONE_COUNT = 20; 39 | Drone drones[DRONE_COUNT]; 40 | 41 | char name[10]; 42 | unsigned index = 1; 43 | for (auto& drone : drones) { 44 | std::snprintf(name, sizeof(name), "drone-%u", index); 45 | drone.thread = thread::create(name, nullptr, drone_func); 46 | ++index; 47 | } 48 | 49 | for (unsigned value = 1; value <= DRONE_COUNT; ++value) { 50 | { 51 | MutexLock lock{hive_mutex}; 52 | signal_value = value; 53 | condvar::signal(drone_cv, lock); 54 | while (signal_value != 0) { 55 | condvar::wait(queen_cv, lock); 56 | } 57 | TOGO_LOGF("%s: received return signal\n", thread::name()); 58 | } 59 | } 60 | for (auto const& drone : drones) { 61 | TOGO_LOGF("joining %s\n", thread::name(drone.thread)); 62 | thread::join(drone.thread); 63 | } 64 | return nullptr; 65 | } 66 | 67 | signed main() { 68 | memory_init(); 69 | 70 | Thread* queen = thread::create("queen", nullptr, queen_func); 71 | thread::join(queen); 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /lib/core/test/threading/mutex.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | using namespace togo; 6 | 7 | signed main() { 8 | Mutex m1{}; 9 | mutex::lock(m1); 10 | TOGO_ASSERTE(!mutex::try_lock(m1)); 11 | mutex::unlock(m1); 12 | 13 | { 14 | MutexLock m1_lock{m1}; 15 | TOGO_ASSERTE(!mutex::try_lock(m1)); 16 | } 17 | 18 | TOGO_ASSERTE(mutex::try_lock(m1)); 19 | mutex::unlock(m1); 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /lib/core/test/threading/task_manager.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | using namespace togo; 13 | 14 | static Mutex counter_mutex{}; 15 | static unsigned counter = 0; 16 | 17 | struct WorkNum { 18 | unsigned value; 19 | }; 20 | 21 | void task_func(TaskID const task_id, void* const data) { 22 | WorkNum const* const wnum = static_cast(data); 23 | TOGO_LOGF( 24 | "task: %08x on %-32s: wnum: %u\n", 25 | task_id._value, 26 | thread::name(), 27 | wnum->value 28 | ); 29 | MutexLock l{counter_mutex}; 30 | ++counter; 31 | } 32 | 33 | TaskWork task_work_num(WorkNum& wnum) { 34 | return {&wnum, task_func}; 35 | } 36 | 37 | signed main() { 38 | WorkNum wnum_list[]{ 39 | {10}, {9}, {8}, {7}, {6}, 40 | { 5}, {4}, {3}, {2}, {1} 41 | }; 42 | memory_init(); 43 | 44 | { 45 | TaskManager tm{5, memory::default_allocator()}; 46 | unsigned count = 10; 47 | while (count--) { 48 | TaskID const finish_id = task_manager::add_hold_empty(tm); 49 | TOGO_LOGF("finish_id: %08x\n", finish_id._value); 50 | for (auto& wnum : wnum_list) { 51 | TaskID const work_id = task_manager::add( 52 | tm, task_work_num(wnum), static_cast(wnum.value) 53 | ); 54 | task_manager::set_parent(tm, work_id, finish_id); 55 | } 56 | task_manager::end_hold(tm, finish_id); 57 | task_manager::wait(tm, finish_id); 58 | TOGO_LOG("finished\n\n"); 59 | TOGO_ASSERTE(counter == 10); 60 | counter = 0; 61 | } 62 | } 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /lib/core/test/threading/thread.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | using namespace togo; 9 | 10 | static int static_rv_check = 0; 11 | 12 | void* thread_func(void* i_void) { 13 | int const* const value = static_cast(i_void); 14 | TOGO_LOGF("thread_func: '%s', %d\n", thread::name(), *value); 15 | static_rv_check = *value; 16 | return &static_rv_check; 17 | } 18 | 19 | signed main() { 20 | memory_init(); 21 | 22 | TOGO_LOGF("main thread: '%s'\n", thread::name()); 23 | 24 | int call_data = 42; 25 | Thread* t = thread::create("thread-1", &call_data, thread_func); 26 | TOGO_ASSERTE(t); 27 | TOGO_LOGF("new thread: '%s'\n", thread::name(t)); 28 | 29 | void* exit_value = thread::join(t); 30 | TOGO_ASSERTE(exit_value == &static_rv_check && static_rv_check == call_data); 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /lib/core/test/utility/args.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | using namespace togo; 13 | 14 | signed main(signed argc, char* argv[]) { 15 | memory_init(); 16 | 17 | KVS k_options; 18 | KVS k_command_options; 19 | KVS k_command; 20 | if (!parse_args(k_options, k_command_options, k_command, argc, argv)) { 21 | TOGO_LOG("#### no command\n"); 22 | } 23 | 24 | { 25 | MemoryStream out_stream{memory::default_allocator(), 1024}; 26 | TOGO_ASSERTE(kvs::write_text(k_options, out_stream)); 27 | TOGO_LOGF( 28 | "#### options (%u): `%.*s`: <%.*s>\n", 29 | static_cast(out_stream.size()), 30 | kvs::name_size(k_options), kvs::name(k_options), 31 | static_cast(out_stream.size()), 32 | array::begin(out_stream.data()) 33 | ); 34 | out_stream.clear(); 35 | 36 | TOGO_ASSERTE(kvs::write_text(k_command_options, out_stream)); 37 | TOGO_LOGF( 38 | "#### command options (%u): `%.*s` <%.*s>\n", 39 | static_cast(out_stream.size()), 40 | kvs::name_size(k_command_options), kvs::name(k_command_options), 41 | static_cast(out_stream.size()), 42 | array::begin(out_stream.data()) 43 | ); 44 | out_stream.clear(); 45 | 46 | TOGO_ASSERTE(kvs::write_text(k_command, out_stream)); 47 | TOGO_LOGF( 48 | "#### command (%u): `%.*s` <%.*s>\n", 49 | static_cast(out_stream.size()), 50 | kvs::name_size(k_command), kvs::name(k_command), 51 | static_cast(out_stream.size()), 52 | array::begin(out_stream.data()) 53 | ); 54 | out_stream.clear(); 55 | } 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /lib/game/build.lua: -------------------------------------------------------------------------------- 1 | 2 | local S, G, R = precore.helpers() 3 | 4 | precore.make_config("togo.lib.game.dep", { 5 | reverse = true, 6 | }, { 7 | "togo.base", 8 | "togo.lib.core.dep", 9 | "togo.dep.opengl", 10 | "togo.lib.window.dep", 11 | {project = function(p) 12 | togo.library_config("game") 13 | 14 | configuration {"togo-test"} 15 | defines { 16 | -- "TOGO_TEST_", 17 | } 18 | end}}) 19 | 20 | precore.append_config_scoped("togo.projects", { 21 | {global = function(_) 22 | togo.make_library("game", { 23 | "togo.lib.game.dep", 24 | }) 25 | end}}) 26 | -------------------------------------------------------------------------------- /lib/game/include_order: -------------------------------------------------------------------------------- 1 | 2 | return { 3 | M("entity", { 4 | N("entity_manager"), 5 | }), 6 | M("world", { 7 | N("world_manager"), 8 | }), 9 | M("gfx", { 10 | N("gfx"), 11 | N("command"), 12 | N("generator"), 13 | N("render_node"), 14 | N("shader_def"), 15 | N("renderer", { 16 | I("renderer", { 17 | N("opengl"), 18 | }), 19 | }), 20 | }), 21 | M("resource", { 22 | N("resource_handler"), 23 | N("resource_package"), 24 | N("resource_manager"), 25 | }), 26 | M("serialization", { 27 | N("gfx", { 28 | N("shader_def"), 29 | N("render_config"), 30 | }), 31 | N("resource", { 32 | N("resource"), 33 | N("test_resource"), 34 | }), 35 | }), 36 | M("app", {}), 37 | } 38 | -------------------------------------------------------------------------------- /lib/game/src/togo/game/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_game Library: game 5 | @details 6 | 7 | */ 8 | 9 | /** 10 | 11 | @defgroup lib_game_types Types 12 | @ingroup lib_game 13 | @details 14 | 15 | */ 16 | -------------------------------------------------------------------------------- /lib/game/src/togo/game/app/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_game_app Application 5 | @ingroup lib_game 6 | @details 7 | 8 | */ 9 | -------------------------------------------------------------------------------- /lib/game/src/togo/game/config.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/game/config.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Game library configuration. 7 | @ingroup lib_game_config 8 | 9 | @defgroup lib_game_config Configuration 10 | @ingroup lib_game 11 | @details 12 | */ 13 | 14 | #pragma once 15 | 16 | #include 17 | #include 18 | 19 | namespace togo { 20 | namespace game { 21 | 22 | /** 23 | @addtogroup lib_game_config 24 | @{ 25 | */ 26 | 27 | /** @name Graphics configuration */ /// @{ 28 | 29 | /// OpenGL renderer. 30 | #define TOGO_RENDERER_OPENGL 0x00000001 31 | 32 | #if defined(DOXYGEN_CONSISTS_SOLELY_OF_UNICORNS_AND_CONFETTI) 33 | /// Configure the renderer to use. 34 | /// 35 | /// Options: 36 | /// 37 | /// - #TOGO_RENDERER_OPENGL (default) 38 | #define TOGO_CONFIG_RENDERER 39 | #else 40 | #if !defined(TOGO_CONFIG_RENDERER) 41 | #define TOGO_CONFIG_RENDERER TOGO_RENDERER_OPENGL 42 | #endif 43 | 44 | #if (TOGO_CONFIG_RENDERER != TOGO_RENDERER_OPENGL) 45 | #error "TOGO_CONFIG_RENDERER has an invalid value" 46 | #endif 47 | #endif // defined(DOXYGEN_CONSISTS_SOLELY_OF_UNICORNS_AND_CONFETTI) 48 | 49 | /// @} // end of name-group Graphics configuration 50 | 51 | /** @} */ // end of doc-group lib_game_config 52 | 53 | } // namespace game 54 | } // namespace togo 55 | -------------------------------------------------------------------------------- /lib/game/src/togo/game/entity/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_game_entity Entity 5 | @ingroup lib_game 6 | @details 7 | 8 | */ 9 | -------------------------------------------------------------------------------- /lib/game/src/togo/game/entity/entity_manager.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/game/entity/entity_manager.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief EntityManager interface. 7 | @ingroup lib_game_entity 8 | @ingroup lib_game_entity_manager 9 | 10 | @defgroup lib_game_entity_manager EntityManager 11 | @ingroup lib_game_entity 12 | @details 13 | */ 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | namespace togo { 22 | namespace game { 23 | namespace entity_manager { 24 | 25 | /** 26 | @addtogroup lib_game_entity_manager 27 | @{ 28 | */ 29 | 30 | 31 | 32 | /** @} */ // end of doc-group lib_game_entity_manager 33 | 34 | } // namespace entity_manager 35 | } // namespace game 36 | } // namespace togo 37 | -------------------------------------------------------------------------------- /lib/game/src/togo/game/entity/types.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/game/entity/types.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Entity types. 7 | @ingroup lib_game_types 8 | @ingroup lib_game_entity 9 | */ 10 | 11 | #pragma once 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | namespace togo { 20 | namespace game { 21 | 22 | /** 23 | @addtogroup lib_game_entity 24 | @{ 25 | */ 26 | 27 | /// Entity ID. 28 | struct EntityID { 29 | using value_type = u32; 30 | 31 | enum : unsigned { 32 | INDEX_BITS = 24, 33 | INDEX_MASK = (1 << INDEX_BITS) - 1, 34 | 35 | GENERATION_BITS = 8, 36 | GENERATION_MASK = (1 << GENERATION_BITS) - 1, 37 | }; 38 | 39 | // layout: [generation] [index] 40 | value_type value; 41 | 42 | /// Index. 43 | unsigned index() const { 44 | return value & INDEX_MASK; 45 | } 46 | 47 | /// Generation. 48 | unsigned generation() const { 49 | return (value >> INDEX_BITS) & GENERATION_MASK; 50 | } 51 | }; 52 | 53 | /// Entity manager. 54 | struct EntityManager { 55 | unsigned _num_alive; 56 | Array _generation; 57 | Queue _free_indices; 58 | 59 | EntityManager() = delete; 60 | EntityManager(EntityManager const&) = delete; 61 | EntityManager& operator=(EntityManager const&) = delete; 62 | 63 | ~EntityManager() = default; 64 | EntityManager(EntityManager&&) = default; 65 | EntityManager& operator=(EntityManager&&) = default; 66 | 67 | EntityManager( 68 | Allocator& allocator 69 | ); 70 | }; 71 | 72 | /** @} */ // end of doc-group lib_game_entity 73 | 74 | } // namespace game 75 | } // namespace togo 76 | -------------------------------------------------------------------------------- /lib/game/src/togo/game/gfx/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_game_gfx Graphics 5 | @ingroup lib_game 6 | @details 7 | 8 | */ 9 | -------------------------------------------------------------------------------- /lib/game/src/togo/game/gfx/generator.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/game/gfx/generator.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Generator definitions. 7 | @ingroup lib_game_types 8 | @ingroup lib_game_gfx 9 | @ingroup lib_game_gfx_generator 10 | 11 | @defgroup lib_game_gfx_generator Generator 12 | @ingroup lib_game_gfx 13 | @details 14 | */ 15 | 16 | #pragma once 17 | 18 | #include 19 | #include 20 | 21 | namespace togo { 22 | namespace game { 23 | namespace gfx { 24 | namespace generator { 25 | 26 | /** 27 | @addtogroup lib_game_gfx_generator 28 | @{ 29 | */ 30 | 31 | extern gfx::GeneratorDef const clear; 32 | extern gfx::GeneratorDef const fullscreen_pass; 33 | 34 | /** @} */ // end of doc-group lib_game_gfx_generator 35 | 36 | } // namespace generator 37 | } // namespace gfx 38 | } // namespace game 39 | } // namespace togo 40 | -------------------------------------------------------------------------------- /lib/game/src/togo/game/gfx/generator/gen_clear.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/game/gfx/generator/gen_clear.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace togo { 18 | namespace game { 19 | namespace gfx { 20 | 21 | namespace generator { 22 | namespace gen_clear { 23 | 24 | static void read( 25 | gfx::GeneratorDef const& /*def*/, 26 | gfx::Renderer* /*renderer*/, 27 | BinaryInputSerializer& ser, 28 | gfx::GeneratorUnit& unit 29 | ) { 30 | u32 rt_index; 31 | ser % rt_index; 32 | unit.data_index = rt_index; 33 | unit.data = nullptr; 34 | } 35 | 36 | static void exec( 37 | gfx::GeneratorUnit const& unit, 38 | gfx::RenderNode& node, 39 | gfx::RenderObject const* const /*objects_begin*/, 40 | gfx::RenderObject const* const /*objects_end*/ 41 | ) { 42 | // TODO: Command for clearing any RT instead? 43 | // TODO: Clear all RTs in layer? 44 | u32 rt_index = unit.data_index; 45 | if (rt_index == ~u32{0}) { 46 | gfx::render_node::push(node, 0, gfx::CmdClearBackbuffer{}); 47 | } else { 48 | TOGO_ASSERT(false, "clearing other than the back-buffer is not implemented"); 49 | } 50 | } 51 | 52 | } // namespace gen_clear 53 | } // namespace generator 54 | 55 | gfx::GeneratorDef const generator::clear{ 56 | "clear"_generator_name, 57 | nullptr, 58 | nullptr, 59 | nullptr, 60 | generator::gen_clear::read, 61 | generator::gen_clear::exec 62 | }; 63 | 64 | } // namespace gfx 65 | } // namespace game 66 | } // namespace togo 67 | -------------------------------------------------------------------------------- /lib/game/src/togo/game/gfx/gfx.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/game/gfx/gfx.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Graphics interface. 7 | @ingroup lib_game_gfx 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace togo { 18 | namespace game { 19 | namespace gfx { 20 | 21 | /** 22 | @addtogroup lib_game_gfx 23 | @{ 24 | */ 25 | 26 | /// Calculate hash of parameter block name. 27 | inline gfx::ParamBlockNameHash hash_param_block_name(StringRef const& name) { 28 | return hash::calc32(name); 29 | } 30 | 31 | /// Calculate hash of generator name. 32 | inline gfx::GeneratorNameHash hash_generator_name(StringRef const& name) { 33 | return hash::calc32(name); 34 | } 35 | 36 | /// Calculate hash of viewport name. 37 | inline gfx::GeneratorNameHash hash_viewport_name(StringRef const& name) { 38 | return hash::calc32(name); 39 | } 40 | 41 | /// Test if a primitive is integral. 42 | inline bool is_primitive_integral(gfx::Primitive p) { 43 | return p <= gfx::Primitive::u32; 44 | } 45 | 46 | /// Test if a primitive is floating-point. 47 | inline bool is_primitive_fp(gfx::Primitive p) { 48 | return p == gfx::Primitive::f32 || p == gfx::Primitive::f64; 49 | } 50 | 51 | /** @} */ // end of doc-group lib_game_gfx 52 | 53 | } // namespace gfx 54 | } // namespace game 55 | } // namespace togo 56 | -------------------------------------------------------------------------------- /lib/game/src/togo/game/gfx/render_node.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/game/gfx/render_node.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | namespace togo { 17 | namespace game { 18 | namespace gfx { 19 | 20 | /// Push command. 21 | /// 22 | /// data is copied to the node's internal buffer. 23 | /// 24 | /// An assertion will fail if the node does not have space for another 25 | /// command. 26 | /// An assertion will fail if key_user is not contained within the 27 | /// user key bit space. 28 | void render_node::push( 29 | gfx::RenderNode& node, 30 | u64 const key_user, 31 | gfx::CmdType const type, 32 | unsigned const data_size, 33 | void const* const data 34 | ) { 35 | TOGO_ASSERTE( 36 | TOGO_GFX_NODE_NUM_COMMANDS > node.num_commands && 37 | (key_user & ~TOGO_GFX_KEY_USER_MASK) == 0 38 | ); 39 | unsigned const next_buffer_size = node.buffer_size + sizeof(gfx::CmdType) + data_size; 40 | TOGO_ASSERTE(TOGO_GFX_NODE_BUFFER_SIZE >= next_buffer_size); 41 | 42 | auto* put = static_cast(node.buffer + node.buffer_size); 43 | auto& cmd_key = node.keys[node.num_commands]; 44 | cmd_key.key = (node.sequence << TOGO_GFX_KEY_USER_BITS) | key_user; 45 | cmd_key.data = put; 46 | 47 | *static_cast(put) = type; 48 | if (data_size > 0) { 49 | put = pointer_add(put, sizeof(gfx::CmdType)); 50 | std::memcpy(put, data, data_size); 51 | } 52 | 53 | node.buffer_size = next_buffer_size; 54 | ++node.num_commands; 55 | } 56 | 57 | } // namespace gfx 58 | } // namespace game 59 | } // namespace togo 60 | -------------------------------------------------------------------------------- /lib/game/src/togo/game/gfx/render_node.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/game/gfx/render_node.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief RenderNode interface. 7 | @ingroup lib_game_gfx 8 | @ingroup lib_game_gfx_render_node 9 | 10 | @defgroup lib_game_gfx_render_node RenderNode 11 | @ingroup lib_game_gfx 12 | @details 13 | */ 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | namespace togo { 24 | namespace game { 25 | namespace gfx { 26 | namespace render_node { 27 | 28 | /** 29 | @addtogroup lib_game_gfx_render_node 30 | @{ 31 | */ 32 | 33 | /// Push command (generic helper). 34 | template 35 | inline void push( 36 | gfx::RenderNode& node, 37 | u64 const key_user, 38 | T const& data 39 | ) { 40 | render_node::push( 41 | node, 42 | key_user, 43 | CmdTypeProperties::type, 44 | sizeof_empty(), &data 45 | ); 46 | } 47 | 48 | /** @} */ // end of doc-group lib_game_gfx_render_node 49 | 50 | } // namespace render_node 51 | } // namespace gfx 52 | } // namespace game 53 | } // namespace togo 54 | -------------------------------------------------------------------------------- /lib/game/src/togo/game/resource/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_game_resource Resource 5 | @ingroup lib_game 6 | @details 7 | 8 | */ 9 | -------------------------------------------------------------------------------- /lib/game/src/togo/game/resource/resource_handler/test_resource.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/game/resource/resource_handler/test_resource.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace togo { 17 | namespace game { 18 | 19 | namespace resource_handler { 20 | namespace test_resource { 21 | 22 | static ResourceValue load( 23 | void* const type_data, 24 | ResourceManager& /*manager*/, 25 | ResourcePackage& package, 26 | Resource const& resource 27 | ) { 28 | TOGO_DEBUG_ASSERTE(type_data == nullptr); 29 | TestResource* const test_resource = TOGO_CONSTRUCT( 30 | memory::default_allocator(), TestResource, {0} 31 | ); 32 | 33 | {// Deserialize resource 34 | ResourceStreamLock lock{package, resource.metadata.id}; 35 | BinaryInputSerializer ser{lock.stream()}; 36 | ser % *test_resource; 37 | } 38 | return test_resource; 39 | } 40 | 41 | static void unload( 42 | void* const type_data, 43 | ResourceManager& /*manager*/, 44 | Resource const& resource 45 | ) { 46 | TOGO_DEBUG_ASSERTE(type_data == nullptr); 47 | auto const* test_resource = static_cast(resource.value.pointer); 48 | TOGO_DESTROY(memory::default_allocator(), test_resource); 49 | } 50 | 51 | } // namespace test_resource 52 | } // namespace resource_handler 53 | 54 | /// Register test (TestResource) resource handler. 55 | void resource_handler::register_test( 56 | ResourceManager& rm 57 | ) { 58 | ResourceHandler const handler{ 59 | RES_TYPE_TEST, 60 | SER_FORMAT_VERSION_TEST_RESOURCE, 61 | nullptr, 62 | resource_handler::test_resource::load, 63 | resource_handler::test_resource::unload 64 | }; 65 | resource_manager::register_handler(rm, handler); 66 | } 67 | 68 | } // namespace game 69 | } // namespace togo 70 | -------------------------------------------------------------------------------- /lib/game/src/togo/game/resource/resource_manager.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/game/resource/resource_manager.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief ResourceManager interface. 7 | @ingroup lib_game_resource 8 | @ingroup lib_game_resource_manager 9 | 10 | @defgroup lib_game_resource_manager ResourceManager 11 | @ingroup lib_game_resource 12 | @details 13 | */ 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | namespace togo { 23 | namespace game { 24 | namespace resource_manager { 25 | 26 | /** 27 | @addtogroup lib_game_resource_manager 28 | @{ 29 | */ 30 | 31 | /// Base path. 32 | inline StringRef base_path( 33 | ResourceManager const& rm 34 | ) { 35 | return rm._base_path; 36 | } 37 | 38 | /// Package collection. 39 | inline Array const& packages( 40 | ResourceManager const& rm 41 | ) { 42 | return rm._packages; 43 | } 44 | 45 | /** @} */ // end of doc-group lib_game_resource_manager 46 | 47 | } // namespace resource_manager 48 | } // namespace game 49 | } // namespace togo 50 | -------------------------------------------------------------------------------- /lib/game/src/togo/game/resource/resource_package.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/game/resource/resource_package.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief ResourcePackage interface. 7 | @ingroup lib_game_resource 8 | @ingroup lib_game_resource_package 9 | 10 | @defgroup lib_game_resource_package ResourcePackage 11 | @ingroup lib_game_resource 12 | @details 13 | */ 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | namespace togo { 23 | namespace game { 24 | namespace resource_package { 25 | 26 | /** 27 | @addtogroup lib_game_resource_package 28 | @{ 29 | */ 30 | 31 | /// Name hash. 32 | inline ResourcePackageNameHash name_hash(ResourcePackage const& pkg) { 33 | return pkg._name_hash; 34 | } 35 | 36 | /// Name. 37 | inline StringRef name(ResourcePackage const& pkg) { 38 | return pkg._name; 39 | } 40 | 41 | /// Path. 42 | inline StringRef path(ResourcePackage const& pkg) { 43 | return pkg._path; 44 | } 45 | 46 | /** @} */ // end of doc-group lib_game_resource_package 47 | 48 | } // namespace resource_package 49 | } // namespace game 50 | } // namespace togo 51 | -------------------------------------------------------------------------------- /lib/game/src/togo/game/serialization/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_game_serialization Serialization 5 | @ingroup lib_game 6 | @details 7 | 8 | */ 9 | -------------------------------------------------------------------------------- /lib/game/src/togo/game/serialization/gfx/shader_def.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/game/serialization/gfx/shader_def.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief gfx::ShaderDef serialization. 7 | @ingroup lib_game_serialization 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | namespace togo { 19 | namespace game { 20 | 21 | /** 22 | @addtogroup lib_game_serialization 23 | @{ 24 | */ 25 | 26 | /** @cond INTERNAL */ 27 | 28 | enum : u32 { 29 | SER_FORMAT_VERSION_SHADER_DEF = 2, 30 | }; 31 | 32 | namespace gfx { 33 | 34 | template 35 | inline void 36 | serialize(serializer_tag, Ser& ser, gfx::ParamBlockDef& value_unsafe) { 37 | auto& value = serializer_cast_safe(value_unsafe); 38 | ser 39 | % value.index 40 | % value.name_hash 41 | ; 42 | } 43 | 44 | template 45 | inline void 46 | serialize(serializer_tag, Ser& ser, gfx::ShaderDef& value_unsafe) { 47 | auto& value = serializer_cast_safe(value_unsafe); 48 | ser 49 | % value.properties 50 | // Clearer binary form when data comes last 51 | % make_ser_collection(value.prelude) 52 | % make_ser_collection(value.data_offsets) 53 | % make_ser_collection(value.fixed_param_blocks) 54 | % make_ser_collection(value.draw_param_blocks) 55 | % make_ser_collection(value.data) 56 | ; 57 | } 58 | 59 | } // namespace gfx 60 | 61 | /** @endcond */ // INTERNAL 62 | 63 | /** @} */ // end of doc-group lib_game_serialization 64 | 65 | } // namespace game 66 | } // namespace togo 67 | -------------------------------------------------------------------------------- /lib/game/src/togo/game/serialization/resource/resource.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/game/serialization/resource/resource.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief ResourceMetadata serialization. 7 | @ingroup lib_game_serialization 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | namespace togo { 17 | namespace game { 18 | 19 | /** 20 | @addtogroup lib_game_serialization 21 | @{ 22 | */ 23 | 24 | /** @cond INTERNAL */ 25 | 26 | template 27 | inline void 28 | serialize(serializer_tag, Ser& ser, ResourceMetadata& value_unsafe) { 29 | auto& value = serializer_cast_safe(value_unsafe); 30 | ser 31 | % value.name_hash 32 | % value.tag_glob_hash 33 | % value.type 34 | % value.data_format_version 35 | % value.data_offset 36 | % value.data_size 37 | ; 38 | } 39 | 40 | template 41 | inline void 42 | serialize(serializer_tag, Ser& ser, Resource& value_unsafe) { 43 | auto& value = serializer_cast_safe(value_unsafe); 44 | ser 45 | % value.metadata 46 | ; 47 | } 48 | 49 | /** @endcond */ // INTERNAL 50 | 51 | /** @} */ // end of doc-group lib_game_serialization 52 | 53 | } // namespace game 54 | } // namespace togo 55 | -------------------------------------------------------------------------------- /lib/game/src/togo/game/serialization/resource/test_resource.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/game/serialization/resource/test_resource.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief TestResource serialization. 7 | @ingroup lib_game_serialization 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | namespace togo { 17 | namespace game { 18 | 19 | /** 20 | @addtogroup lib_game_serialization 21 | @{ 22 | */ 23 | 24 | /** @cond INTERNAL */ 25 | 26 | enum : u32 { 27 | SER_FORMAT_VERSION_TEST_RESOURCE = 1, 28 | }; 29 | 30 | template 31 | inline void 32 | serialize(serializer_tag, Ser& ser, TestResource& value_unsafe) { 33 | auto& value = serializer_cast_safe(value_unsafe); 34 | ser % value.x; 35 | } 36 | 37 | /** @endcond */ // INTERNAL 38 | 39 | /** @} */ // end of doc-group lib_game_serialization 40 | 41 | } // namespace game 42 | } // namespace togo 43 | -------------------------------------------------------------------------------- /lib/game/src/togo/game/world/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_game_world World 5 | @ingroup lib_game 6 | @details 7 | 8 | */ 9 | -------------------------------------------------------------------------------- /lib/game/src/togo/game/world/world_manager.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/game/world/world_manager.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief WorldManager interface. 7 | @ingroup lib_game_world 8 | @ingroup lib_game_world_manager 9 | 10 | @defgroup lib_game_world_manager WorldManager 11 | @ingroup lib_game_world 12 | @details 13 | */ 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | namespace togo { 22 | namespace game { 23 | namespace world_manager { 24 | 25 | /** 26 | @addtogroup lib_game_world_manager 27 | @{ 28 | */ 29 | 30 | 31 | 32 | /** @} */ // end of doc-group lib_game_world_manager 33 | 34 | } // namespace world_manager 35 | } // namespace game 36 | } // namespace togo 37 | -------------------------------------------------------------------------------- /lib/game/test/app/general.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | using namespace togo; 12 | using namespace togo::game; 13 | 14 | struct TestAppData { 15 | unsigned x{42}; 16 | 17 | ~TestAppData() { 18 | TOGO_LOG("~TestAppData()\n"); 19 | } 20 | }; 21 | 22 | using TestApp = App; 23 | using TestAppModel = AppModel; 24 | 25 | template<> 26 | void TestAppModel::init(TestApp& app) { 27 | TOGO_LOG("init()\n"); 28 | TOGO_ASSERTE(app.data.x == 42); 29 | } 30 | 31 | template<> 32 | void TestAppModel::shutdown(TestApp& app) { 33 | TOGO_LOG("shutdown()\n"); 34 | TOGO_ASSERTE(app.data.x == 42); 35 | } 36 | 37 | template<> 38 | void TestAppModel::update(TestApp& app, float /*dt*/) { 39 | //TOGO_LOG("update()\n"); 40 | if (input::key_released(app.window, KeyCode::escape)) { 41 | app::quit(); 42 | } 43 | } 44 | 45 | template<> 46 | void TestAppModel::render(TestApp& /*app*/) { 47 | //TOGO_LOG("render()\n"); 48 | } 49 | 50 | signed main(signed argc, char* argv[]) { 51 | memory_init(); 52 | 53 | app::init( 54 | memory::default_allocator(), 55 | array_ref(argv, unsigned_cast(argc)), 56 | "data/project/package/", 57 | 1.0f / 30.0f 58 | ); 59 | app::run(); 60 | app::shutdown(); 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /lib/game/test/build.lua: -------------------------------------------------------------------------------- 1 | 2 | local S, G, R = precore.helpers() 3 | 4 | local configs = { 5 | "togo.lib.game.dep", 6 | } 7 | 8 | togo.make_tests("app", { 9 | ["general"] = {nil, configs}, 10 | }) 11 | 12 | togo.make_tests("general", { 13 | ["headers"] = {nil, configs}, 14 | }) 15 | 16 | togo.make_tests("gfx", { 17 | ["renderer_triangle"] = {nil, configs}, 18 | ["renderer_pipeline"] = {nil, configs}, 19 | }) 20 | 21 | togo.make_tests("resource", { 22 | ["general"] = {nil, configs}, 23 | ["manager"] = {nil, configs}, 24 | }) 25 | -------------------------------------------------------------------------------- /lib/game/test/data/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | project/package/*.package 3 | project/package/*/.compiled/ 4 | # project/package/*/.package/compiler_metadata 5 | # project/package/*/.package/manifest 6 | -------------------------------------------------------------------------------- /lib/game/test/data/pkg/test1.package: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/komiga/togo/7a366fc02e87c8480f008aa110516e4b04f8d73b/lib/game/test/data/pkg/test1.package -------------------------------------------------------------------------------- /lib/game/test/data/pkg/test2.package: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/komiga/togo/7a366fc02e87c8480f008aa110516e4b04f8d73b/lib/game/test/data/pkg/test2.package -------------------------------------------------------------------------------- /lib/game/test/data/project/.project/packages: -------------------------------------------------------------------------------- 1 | packages = [ 2 | test1 3 | test2 4 | test_data 5 | ] 6 | -------------------------------------------------------------------------------- /lib/game/test/data/project/package/test1/.package/compiler_metadata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/komiga/togo/7a366fc02e87c8480f008aa110516e4b04f8d73b/lib/game/test/data/project/package/test1/.package/compiler_metadata -------------------------------------------------------------------------------- /lib/game/test/data/project/package/test1/.package/manifest: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/komiga/togo/7a366fc02e87c8480f008aa110516e4b04f8d73b/lib/game/test/data/project/package/test1/.package/manifest -------------------------------------------------------------------------------- /lib/game/test/data/project/package/test1/.package/properties: -------------------------------------------------------------------------------- 1 | name = test1 2 | build_parity = true 3 | -------------------------------------------------------------------------------- /lib/game/test/data/project/package/test1/1.test: -------------------------------------------------------------------------------- 1 | x = 1 -------------------------------------------------------------------------------- /lib/game/test/data/project/package/test1/subdir/2.test: -------------------------------------------------------------------------------- 1 | x = 2 -------------------------------------------------------------------------------- /lib/game/test/data/project/package/test2/.package/compiler_metadata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/komiga/togo/7a366fc02e87c8480f008aa110516e4b04f8d73b/lib/game/test/data/project/package/test2/.package/compiler_metadata -------------------------------------------------------------------------------- /lib/game/test/data/project/package/test2/.package/manifest: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/komiga/togo/7a366fc02e87c8480f008aa110516e4b04f8d73b/lib/game/test/data/project/package/test2/.package/manifest -------------------------------------------------------------------------------- /lib/game/test/data/project/package/test2/.package/properties: -------------------------------------------------------------------------------- 1 | name = test2 2 | build_parity = true 3 | -------------------------------------------------------------------------------- /lib/game/test/data/project/package/test2/1.test: -------------------------------------------------------------------------------- 1 | x = 42 -------------------------------------------------------------------------------- /lib/game/test/data/project/package/test2/3.test: -------------------------------------------------------------------------------- 1 | x = 3 -------------------------------------------------------------------------------- /lib/game/test/data/project/package/test_data/.package/compiler_metadata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/komiga/togo/7a366fc02e87c8480f008aa110516e4b04f8d73b/lib/game/test/data/project/package/test_data/.package/compiler_metadata -------------------------------------------------------------------------------- /lib/game/test/data/project/package/test_data/.package/manifest: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/komiga/togo/7a366fc02e87c8480f008aa110516e4b04f8d73b/lib/game/test/data/project/package/test_data/.package/manifest -------------------------------------------------------------------------------- /lib/game/test/data/project/package/test_data/.package/properties: -------------------------------------------------------------------------------- 1 | name = test_data 2 | build_parity = false 3 | -------------------------------------------------------------------------------- /lib/game/test/data/project/package/test_data/test/gfx/generic.shader: -------------------------------------------------------------------------------- 1 | 2 | type = glsl 3 | prelude = [] 4 | 5 | fixed_param_blocks = [] 6 | 7 | draw_param_blocks = [] 8 | 9 | shared_source = ``` 10 | FRAG_ATTR Vec4 frag_color; 11 | ``` 12 | 13 | vertex_source = ``` 14 | VERT_ATTR(0) Vec2 a_pos; 15 | VERT_ATTR(1) Vec3 a_color; 16 | 17 | MAIN { 18 | frag_color = Vec4(a_color, 1.0); 19 | RESULT = Vec4(a_pos, 0.0, 1.0); 20 | } 21 | ``` 22 | 23 | fragment_source = ``` 24 | FRAG_RESULT(0) Vec4 RESULT0; 25 | 26 | MAIN { 27 | RESULT0 = frag_color; 28 | } 29 | ``` 30 | -------------------------------------------------------------------------------- /lib/game/test/data/project/package/test_data/test/gfx/pipeline.render_config: -------------------------------------------------------------------------------- 1 | 2 | shared_resources = { 3 | /*"ds_buffer" = { 4 | type = render_target 5 | scale_relative = "back_buffer" 6 | scale = (1 1) 7 | format = DS 8 | clear = true 9 | }*/ 10 | } 11 | 12 | pipes = { 13 | "default" = { 14 | layers = { 15 | "test" = { 16 | rts = ["back_buffer"] 17 | dst = null //"ds_buffer" 18 | order = front_back 19 | layout = { 20 | generators = [ 21 | { unit = "clear" render_target = "back_buffer" } 22 | { unit = "test_proxy" } 23 | ] 24 | } 25 | } 26 | } 27 | } 28 | } 29 | 30 | viewports = { 31 | "default" = { 32 | pipe = "default" 33 | output_rt = "back_buffer" 34 | output_dst = null //"ds_buffer" 35 | resources = [] 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /lib/game/test/data/project/package/test_data/test/gfx/simple-oscillate.shader: -------------------------------------------------------------------------------- 1 | 2 | type = glsl 3 | prelude = [] 4 | 5 | fixed_param_blocks = [ 6 | {name = "ColorFactors" index = 0} 7 | ] 8 | 9 | draw_param_blocks = [ 10 | {name = "Oscillator"} 11 | ] 12 | 13 | shared_source = ``` 14 | f32 sinu(f32 x) { 15 | return abs(sin(x)); 16 | } 17 | 18 | PARAM_BLOCK_FIXED(ColorFactors, 0) { 19 | Vec2 rg_gb; 20 | } p_color_factors; 21 | 22 | PARAM_BLOCK_DRAW(Oscillator) { 23 | f32 time; 24 | } p_osc; 25 | 26 | FRAG_ATTR Vec3 frag_color; 27 | ``` 28 | 29 | vertex_source = ``` 30 | VERT_ATTR(0) Vec2 a_pos; 31 | VERT_ATTR(1) Vec3 a_color; 32 | 33 | MAIN { 34 | // frag_color = a_color; 35 | frag_color = Vec3( 36 | a_color.r * p_color_factors.rg_gb.x, 37 | a_color.g * (0.5 * p_color_factors.rg_gb.x + 0.5 * p_color_factors.rg_gb.y), 38 | a_color.b * p_color_factors.rg_gb.y 39 | ); 40 | RESULT = Vec4(a_pos * sinu(0.60 * p_osc.time), 0.0, 1.0); 41 | // RESULT = Vec4(a_pos, 0.0, 1.0); 42 | } 43 | ``` 44 | 45 | fragment_source = ``` 46 | FRAG_RESULT(0) Vec4 RESULT0; 47 | 48 | MAIN { 49 | Vec3 c = 1.0 - frag_color; 50 | RESULT0 = Vec4(c * sinu(0.60 * p_osc.time), 1.0); 51 | // RESULT0 = Vec4(c, 1.0); 52 | } 53 | ``` 54 | -------------------------------------------------------------------------------- /lib/game/test/data/project/package/test_data/togo/gfx/shader-config.shader_prelude: -------------------------------------------------------------------------------- 1 | 2 | type = glsl 3 | prelude = [] 4 | 5 | /* 6 | Parameter block definitions: 7 | 8 | PARAM_BLOCK_DRAW(name) 9 | PARAM_BLOCK_FIXED(name, index) 10 | 11 | There can only be 16 definitions of each type (to total 32). 12 | Fixed param blocks can be indexed non-sequentially in [0, 15]. 13 | The renderer pre-defines fixed param blocks in [14, 15]. 14 | */ 15 | shared_source = ``` 16 | #extension GL_ARB_shading_language_420pack : require 17 | 18 | precision highp int; 19 | precision highp float; 20 | layout(std140, column_major) uniform; 21 | 22 | #define s32 int 23 | #define u32 uint 24 | #define f32 float 25 | #define f64 double 26 | #define Vec1 vec1 27 | #define Vec2 vec2 28 | #define Vec3 vec3 29 | #define Vec4 vec4 30 | 31 | #define MC_PI 3.1415926535897932384626f 32 | #define MC_TAU 6.2831853071795864769252f 33 | #define MAIN void main() 34 | 35 | #if (__VERSION__ >= 420) || defined(GL_ARB_shading_language_420pack) 36 | #define PARAM_BLOCK_FIXED(_a_name, _a_buffer_index) layout(binding = _a_buffer_index) uniform _a_name 37 | #else 38 | #define PARAM_BLOCK_FIXED(_a_name, _a_buffer_index) uniform _a_name 39 | #endif 40 | #define PARAM_BLOCK_DRAW(_a_name) uniform _a_name 41 | ``` 42 | 43 | /* 44 | Location of vertex attributes must be sequential from 0, following 45 | the data format in the vertex attribute buffer. 46 | */ 47 | vertex_source = ``` 48 | #define VERT_ATTR(_a_loc) layout(location = _a_loc) in 49 | #define FRAG_ATTR out 50 | #define RESULT gl_Position 51 | ``` 52 | 53 | /* 54 | Location of fragment results must be sequential from 0, following 55 | the target buffers. 56 | */ 57 | fragment_source = ``` 58 | #define FRAG_ATTR in 59 | #define FRAG_RESULT(_a_loc) layout(location = _a_loc) out 60 | ``` 61 | -------------------------------------------------------------------------------- /lib/game/test/general/headers.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | signed main() { 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /lib/image/build.lua: -------------------------------------------------------------------------------- 1 | 2 | local S, G, R = precore.helpers() 3 | 4 | precore.make_config("togo.lib.image.dep", { 5 | reverse = true, 6 | }, { 7 | "togo.base", 8 | "togo.lib.core.dep", 9 | {project = function(p) 10 | togo.library_config("image") 11 | 12 | configuration {"togo-test"} 13 | defines { 14 | -- "TOGO_TEST_", 15 | } 16 | end}}) 17 | 18 | precore.append_config_scoped("togo.projects", { 19 | {global = function(_) 20 | togo.make_library("image", { 21 | "togo.lib.image.dep", 22 | }) 23 | end}}) 24 | -------------------------------------------------------------------------------- /lib/image/include_order: -------------------------------------------------------------------------------- 1 | 2 | return { 3 | M("pixmap", { 4 | I("impl"), 5 | }), 6 | } 7 | -------------------------------------------------------------------------------- /lib/image/src/togo/image/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_image Library: image 5 | @details 6 | 7 | UVec4 is named by its use. If it is a "rect", the 3rd and 4th components are the 8 | width and height of a rectangle. If it is a "quad", they are x2 and y2. 9 | 10 | */ 11 | -------------------------------------------------------------------------------- /lib/image/src/togo/image/config.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/image/config.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Image library configuration. 7 | @ingroup lib_image_config 8 | 9 | @defgroup lib_image_config Configuration 10 | @ingroup lib_image 11 | @details 12 | */ 13 | 14 | #pragma once 15 | 16 | #include 17 | 18 | namespace togo { 19 | 20 | /** 21 | @addtogroup lib_image_config 22 | @{ 23 | */ 24 | /** @} */ // end of doc-group lib_image_config 25 | 26 | } // namespace togo 27 | -------------------------------------------------------------------------------- /lib/image/src/togo/image/pixmap/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_image_pixmap Pixmap 5 | @ingroup lib_image 6 | @details 7 | 8 | Pixmap storage is y-major, starting with the top-left pixel. 9 | 10 | Pixel layout names correspond to byte order. For example, PixelLayout::argb 11 | corresponds to: 12 | 13 | @code 14 | FF 00 00 00 // A mask 15 | 00 FF 00 00 // R mask 16 | 00 00 FF 00 // G mask 17 | 00 00 00 FF // B mask 18 | @endcode 19 | 20 | PixelLayout::rgb with PixelDataType::p32 has the same order as above, with 21 | the MSB being empty (unused): 22 | 23 | @code 24 | 00 00 00 00 // X mask 25 | 00 FF 00 00 // R mask 26 | 00 00 FF 00 // G mask 27 | 00 00 00 FF // B mask 28 | @endcode 29 | 30 | Pixmaps use the default allocator. 31 | 32 | */ 33 | -------------------------------------------------------------------------------- /lib/image/src/togo/image/pixmap/impl/private.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/image/pixmap/impl/private.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace togo { 13 | namespace pixmap { 14 | 15 | void fill_rgb(Pixmap& p, Color& color, UVec4& rect); 16 | void fill_packed(Pixmap& p, Color& color, UVec4& rect); 17 | 18 | void blit_unscaled_copy( 19 | PixelFormat const& format, 20 | u8* dst, 21 | unsigned dst_width, 22 | UVec2 dst_pos, 23 | u8 const* src, 24 | unsigned src_width, 25 | UVec4 src_rect 26 | ); 27 | 28 | void blit_unscaled_choose( 29 | PixelFormat const& dst_format, 30 | u8* dst, 31 | unsigned dst_width, 32 | UVec2 dst_pos, 33 | PixelFormat const& src_format, 34 | u8 const* src, 35 | unsigned src_width, 36 | UVec4 src_rect 37 | ); 38 | 39 | } // namespace pixmap 40 | } // namespace togo 41 | -------------------------------------------------------------------------------- /lib/image/src/togo/image/types.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/image/types.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Image types. 7 | @ingroup lib_image_types 8 | 9 | @defgroup lib_image_types Types 10 | @ingroup lib_image 11 | @details 12 | */ 13 | 14 | #pragma once 15 | 16 | #include 17 | #include 18 | 19 | namespace togo { 20 | 21 | /** 22 | @addtogroup lib_image_types 23 | @{ 24 | */ 25 | 26 | /// Color. 27 | struct Color { 28 | /// Components. 29 | u8 r, g, b, a; 30 | 31 | /// Construct from components. 32 | Color(u8 r, u8 g, u8 b, u8 a = 255) 33 | : r(r) 34 | , g(g) 35 | , b(b) 36 | , a(a) 37 | {} 38 | }; 39 | 40 | /** @} */ // end of doc-group lib_image_types 41 | 42 | } // namespace togo 43 | -------------------------------------------------------------------------------- /lib/image/test/build.lua: -------------------------------------------------------------------------------- 1 | 2 | local S, G, R = precore.helpers() 3 | 4 | local configs = { 5 | "togo.lib.image.dep", 6 | } 7 | 8 | togo.make_tests("general", { 9 | ["headers"] = {nil, configs}, 10 | }) 11 | 12 | togo.make_tests("pixmap", { 13 | ["general"] = {nil, configs}, 14 | }) 15 | -------------------------------------------------------------------------------- /lib/image/test/general/headers.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | signed main() { 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /lib/image/test/pixmap/general.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | using namespace togo; 12 | 13 | signed main() { 14 | memory_init(); 15 | 16 | PixelFormat format{PixelFormatID::rgba}; 17 | auto ps = pixel_format::pixel_size(format); 18 | Color c_init{0x01, 0x02, 0x03, 0x04}; 19 | Color c_fill1{0xAA, 0xBB, 0xCC, 0xDD}; 20 | Color c_fill2{0xDD, 0xCC, 0xBB, 0xAA}; 21 | auto cp_init = pixel_format::pack(format, c_init); 22 | auto cp_fill1 = pixel_format::pack(format, c_fill1); 23 | // auto cp_fill2 = pixel_format::pack(format, c_fill2); 24 | 25 | Pixmap p{format}; 26 | pixmap::resize(p, UVec2{1, 1}, c_init); 27 | TOGO_ASSERTE(p.data && p.data_size == p.data_capacity && p.data_size == 1*1 * ps); 28 | auto data = reinterpret_cast(p.data); 29 | TOGO_ASSERTE(data[0] == cp_init); 30 | 31 | pixmap::resize(p, UVec2{4, 4}, c_fill1); 32 | TOGO_ASSERTE(p.data && p.data_size == p.data_capacity && p.data_size == 4*4 * ps); 33 | data = reinterpret_cast(p.data); 34 | TOGO_ASSERTE(data[0] == cp_init); 35 | {auto end = pointer_add(data, p.data_size); 36 | for (auto check = data + 1; check != end; ++check) { 37 | TOGO_ASSERTE(*check == cp_fill1); 38 | }} 39 | 40 | {Pixmap copy{PixelFormatID::xrgb}; 41 | pixmap::copy(copy, p); 42 | TOGO_ASSERTE( 43 | copy.data_size == p.data_size && 44 | std::memcmp(copy.data, p.data, p.data_size) == 0 45 | );} 46 | 47 | {Pixmap blit{format}; 48 | pixmap::resize(blit, UVec2{4, 4}, c_fill2); 49 | pixmap::blit(blit, p, UVec2{0, 0}); 50 | TOGO_ASSERTE( 51 | blit.data_size == p.data_size && 52 | std::memcmp(blit.data, p.data, p.data_size) == 0 53 | );} 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /lib/platform/build.lua: -------------------------------------------------------------------------------- 1 | 2 | local S, G, R = precore.helpers() 3 | 4 | precore.make_config("togo.lib.platform.linux.dep", nil, { 5 | {project = function(p) 6 | if not precore.env_project()["NO_LINK"] then 7 | configuration {"linux"} 8 | linkoptions { 9 | "`pkg-config --libs" .. 10 | " libnotify" .. 11 | "`" 12 | } 13 | end 14 | configuration {"linux"} 15 | buildoptions { 16 | "`pkg-config --cflags-only-I" .. 17 | " libnotify" .. 18 | "`" 19 | } 20 | end}}) 21 | 22 | precore.make_config("togo.lib.platform.dep", { 23 | reverse = true, 24 | }, { 25 | "togo.base", 26 | "togo.lib.core.dep", 27 | "togo.lib.platform.linux.dep", 28 | {project = function(p) 29 | togo.library_config("platform") 30 | 31 | configuration {"togo-test"} 32 | defines { 33 | -- "TOGO_TEST_", 34 | } 35 | end}}) 36 | 37 | precore.append_config_scoped("togo.projects", { 38 | {global = function(_) 39 | togo.make_library("platform", { 40 | "togo.lib.platform.dep", 41 | }) 42 | end}}) 43 | -------------------------------------------------------------------------------- /lib/platform/include_order: -------------------------------------------------------------------------------- 1 | 2 | return { 3 | M("notification", { 4 | I("notification", { 5 | N("linux"), 6 | }), 7 | }), 8 | } 9 | -------------------------------------------------------------------------------- /lib/platform/src/togo/platform/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_platform Library: platform 5 | @details 6 | 7 | */ 8 | -------------------------------------------------------------------------------- /lib/platform/src/togo/platform/config.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/platform/config.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Image library configuration. 7 | @ingroup lib_platform_config 8 | 9 | @defgroup lib_platform_config Configuration 10 | @ingroup lib_platform 11 | @details 12 | */ 13 | 14 | #pragma once 15 | 16 | #include 17 | 18 | namespace togo { 19 | 20 | /** 21 | @addtogroup lib_platform_config 22 | @{ 23 | */ 24 | /** @} */ // end of doc-group lib_platform_config 25 | 26 | } // namespace togo 27 | -------------------------------------------------------------------------------- /lib/platform/src/togo/platform/notification/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_platform_notification Notification 5 | @ingroup lib_platform 6 | @details 7 | 8 | A Notification object can be modified without affecting what the user sees, as 9 | its state is only used when notification::post() is called. 10 | 11 | notification::init() must be called before creating any notifications or using 12 | any other part of the notification interface. 13 | 14 | notification::poll() must be called for callbacks to be processed and 15 | notification::is_active() to be valid. 16 | 17 | Some backends don't support all of the features of the interface. They are as 18 | follows: 19 | 20 | @par libnotify (Linux) 21 | 22 | libnotify is particularly poorly implemented by notification servers, but it is 23 | the only widespread system for Linux. 24 | 25 | - The @c NotificationClosed signal may be under- or un-implemented, which makes 26 | notification::is_active() nearly useless for determining status. e.g., 27 | 28 | - AwesomeWM (@<4.x) 29 | - NotifyOSD (only on notification::dismiss()) 30 | 31 | - When @c lifetime is @c 0, notification may not be treated as a notification. 32 | e.g., 33 | 34 | - NotifyOSD (opens a prompt) 35 | 36 | - Lifetime is otherwise ignored. e.g., 37 | 38 | - NotifyOSD (uses its own lifetime) 39 | 40 | */ 41 | -------------------------------------------------------------------------------- /lib/platform/src/togo/platform/notification/internal.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/platform/notification/internal.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Notification internals. 7 | @ingroup lib_platform_types 8 | @ingroup lib_platform_notification 9 | */ 10 | 11 | #pragma once 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | namespace togo { 19 | namespace notification { 20 | 21 | namespace { 22 | 23 | enum : unsigned { 24 | DEFAULT_LIFETIME_FALLBACK = 15000, 25 | }; 26 | 27 | enum : unsigned { 28 | S_TYPE = 0, 29 | B_TYPE = bits_to_store(unsigned_cast(notification::c_num_type) - 1), 30 | M_TYPE = fill_n_bits(B_TYPE), 31 | 32 | S_PRIORITY = S_TYPE + B_TYPE, 33 | B_PRIORITY = bits_to_store(unsigned_cast(notification::c_num_priority) - 1), 34 | M_PRIORITY = fill_n_bits(B_PRIORITY), 35 | 36 | S_MODIFIED = S_PRIORITY + B_PRIORITY, 37 | B_MODIFIED = 1, 38 | M_MODIFIED = 1, 39 | 40 | S_POSTED = S_MODIFIED + B_MODIFIED, 41 | B_POSTED = 1, 42 | M_POSTED = 1, 43 | 44 | S_LIFETIME = S_POSTED + B_POSTED, 45 | B_LIFETIME = bits_to_store(unsigned_cast(notification::MAX_LIFETIME)), 46 | M_LIFETIME = fill_n_bits(B_LIFETIME), 47 | 48 | S_LIFETIME_SIGN = S_LIFETIME + B_LIFETIME, 49 | B_LIFETIME_SIGN = 1, 50 | M_LIFETIME_SIGN = 1, 51 | }; 52 | static_assert( 53 | S_LIFETIME_SIGN < (sizeof(Notification::_properties) << 3), 54 | "properties exceed limit of value type" 55 | ); 56 | 57 | } // anonymous namespace 58 | 59 | namespace internal { 60 | 61 | inline unsigned get_property(Notification const& notification, unsigned mask, unsigned shift) { 62 | return (notification._properties & mask) >> shift; 63 | } 64 | 65 | inline void set_property(Notification& notification, unsigned mask, unsigned shift, unsigned value) { 66 | notification._properties = (notification._properties & ~mask) | (value << shift); 67 | } 68 | 69 | } // namespace internal 70 | 71 | } // namespace notification 72 | } // namespace togo 73 | -------------------------------------------------------------------------------- /lib/platform/src/togo/platform/notification/notification.lua: -------------------------------------------------------------------------------- 1 | u8R""__RAW_STRING__( 2 | 3 | local U = require "togo.utility" 4 | local M = U.module(...) 5 | 6 | --function M.__module_init__() 7 | U.set_functable(M, function(_, ...) 8 | return M.__mm_ctor(...) 9 | end) 10 | --end 11 | 12 | return M 13 | 14 | )"__RAW_STRING__" -------------------------------------------------------------------------------- /lib/platform/src/togo/platform/notification/notification/linux.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/platform/notification/notification/private.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace togo { 13 | namespace notification { 14 | 15 | // Forward declarations 16 | struct Notification; 17 | 18 | struct NotificationImpl { 19 | NotifyNotification* handle; 20 | 21 | NotificationImpl( 22 | Notification& notification, 23 | StringRef title, 24 | StringRef body 25 | ); 26 | }; 27 | 28 | } // namespace notification 29 | } // namespace togo 30 | -------------------------------------------------------------------------------- /lib/platform/src/togo/platform/notification/notification/private.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/platform/notification/notification/private.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace togo { 17 | namespace notification { 18 | 19 | bool init_impl(StringRef app_name); 20 | void shutdown_impl(); 21 | bool poll_impl(bool wait); 22 | 23 | void destroy_impl(Notification& notification); 24 | 25 | inline void set_modified(Notification& notification, bool modified) { 26 | return internal::set_property(notification, S_MODIFIED, M_MODIFIED, modified); 27 | } 28 | 29 | inline bool is_modified(Notification const& notification) { 30 | return internal::get_property(notification, S_MODIFIED, M_MODIFIED); 31 | } 32 | 33 | inline void set_posted(Notification& notification, bool posted) { 34 | return internal::set_property(notification, S_POSTED, M_POSTED, posted); 35 | } 36 | 37 | inline bool was_posted(Notification const& notification) { 38 | return internal::get_property(notification, S_POSTED, M_POSTED); 39 | } 40 | 41 | } // namespace notification 42 | } // namespace togo 43 | -------------------------------------------------------------------------------- /lib/platform/src/togo/platform/notification/notification/private.ipp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/platform/notification/notification/private.ipp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace togo { 11 | 12 | } // namespace togo 13 | -------------------------------------------------------------------------------- /lib/platform/src/togo/platform/notification/notification/types.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/platform/notification/notification/private.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #if defined(TOGO_PLATFORM_LINUX) 13 | #include 14 | #else 15 | #error "missing Notification implementation for target platform" 16 | #endif 17 | 18 | namespace togo { 19 | namespace notification { 20 | 21 | struct Globals { 22 | bool initialized; 23 | signed default_lifetime; 24 | }; 25 | 26 | extern Globals _globals; 27 | 28 | } // namespace notification 29 | } // namespace togo 30 | -------------------------------------------------------------------------------- /lib/platform/src/togo/platform/types.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/core/types.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Platform types. 7 | @ingroup lib_platform_types 8 | 9 | @defgroup lib_platform_types Types 10 | @ingroup lib_platform 11 | @details 12 | */ 13 | 14 | #pragma once 15 | 16 | #include 17 | #include 18 | 19 | namespace togo { 20 | 21 | /** 22 | @addtogroup lib_platform_types 23 | @{ 24 | */ 25 | 26 | 27 | 28 | /** @} */ // end of doc-group lib_platform_types 29 | 30 | } // namespace togo 31 | -------------------------------------------------------------------------------- /lib/platform/test/build.lua: -------------------------------------------------------------------------------- 1 | 2 | local S, G, R = precore.helpers() 3 | 4 | local configs = { 5 | "togo.lib.platform.dep", 6 | } 7 | 8 | togo.make_tests("general", { 9 | ["headers"] = {nil, configs}, 10 | }) 11 | 12 | togo.make_tests("notification", { 13 | ["notification"] = {nil, configs}, 14 | }) 15 | -------------------------------------------------------------------------------- /lib/platform/test/general/headers.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | signed main() { 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /lib/platform/test/notification/notification.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | using namespace togo; 11 | 12 | #define POLL \ 13 | notification::poll(); 14 | 15 | signed main() { 16 | memory_init(); 17 | TOGO_ASSERTE(notification::init("togo/platform/test/notfication/notification")); 18 | 19 | { 20 | Notification notification{ 21 | "111 Title 111", 22 | "111 Body 111", 23 | 2000 24 | }; 25 | TOGO_ASSERTE(notification::lifetime(notification) == 2000); 26 | TOGO_ASSERTE(notification::type(notification) == notification::Type::generic); 27 | TOGO_ASSERTE(notification::priority(notification) == notification::Priority::normal); 28 | POLL; (void)!notification::is_active(notification); 29 | TOGO_ASSERTE(notification::post(notification)); 30 | POLL; (void)notification::is_active(notification); 31 | system::sleep_ms(1000); 32 | POLL; (void)notification::is_active(notification); 33 | system::sleep_ms(1200); 34 | POLL; (void)!notification::is_active(notification); 35 | 36 | notification::set_title(notification, "222 Title 222"); 37 | notification::set_body(notification, "222 Body 222"); 38 | TOGO_ASSERTE(notification::post(notification)); 39 | POLL; (void)notification::is_active(notification); 40 | system::sleep_ms(3000); 41 | POLL; (void)!notification::is_active(notification); 42 | 43 | notification::set_lifetime(notification, 0); 44 | notification::set_title(notification, "333 Title 333"); 45 | notification::set_body(notification, "333 Body 333"); 46 | TOGO_ASSERTE(notification::post(notification)); 47 | system::sleep_ms(2000); 48 | POLL; notification::dismiss(notification); 49 | POLL; (void)!notification::is_active(notification); 50 | system::sleep_ms(1000); 51 | } 52 | 53 | notification::shutdown(); 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /lib/window/include_order: -------------------------------------------------------------------------------- 1 | 2 | return { 3 | N("opengl"), 4 | M("window", { 5 | I("impl", { 6 | N("sdl"), 7 | N("glfw"), 8 | N("opengl"), 9 | }), 10 | }), 11 | M("input", { 12 | N("input_buffer"), 13 | }), 14 | } 15 | -------------------------------------------------------------------------------- /lib/window/src/togo/window/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_window Library: window 5 | @details 6 | 7 | */ 8 | 9 | /** 10 | 11 | @defgroup lib_window_types Types 12 | @ingroup lib_window 13 | @details 14 | 15 | */ 16 | -------------------------------------------------------------------------------- /lib/window/src/togo/window/config.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/window/config.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Window library configuration. 7 | @ingroup lib_window_config 8 | 9 | @defgroup lib_window_config Configuration 10 | @ingroup lib_window 11 | @details 12 | */ 13 | 14 | #pragma once 15 | 16 | #include 17 | 18 | namespace togo { 19 | 20 | /** 21 | @addtogroup lib_window_config 22 | @{ 23 | */ 24 | 25 | /** @name Window configuration */ /// @{ 26 | 27 | /// SDL window backend. 28 | #define TOGO_WINDOW_BACKEND_SDL 1 29 | 30 | /// GLFW window backend. 31 | #define TOGO_WINDOW_BACKEND_GLFW 2 32 | 33 | #if defined(DOXYGEN_CONSISTS_SOLELY_OF_UNICORNS_AND_CONFETTI) 34 | /// Set the window backend. 35 | /// 36 | /// Options: 37 | /// 38 | /// - #TOGO_WINDOW_BACKEND_SDL (OpenGL, raster) 39 | /// - #TOGO_WINDOW_BACKEND_GLFW (OpenGL) 40 | #define TOGO_CONFIG_WINDOW_BACKEND 41 | 42 | /// Defined if OpenGL windows are supported by the backend. 43 | #define TOGO_WINDOW_BACKEND_SUPPORTS_OPENGL 44 | 45 | /// Defined if raster windows are supported by the backend. 46 | #define TOGO_WINDOW_BACKEND_SUPPORTS_RASTER 47 | #else 48 | #if !defined(TOGO_CONFIG_WINDOW_BACKEND) 49 | #error "window backend has not been selected" 50 | #endif 51 | 52 | #if (TOGO_CONFIG_WINDOW_BACKEND == TOGO_WINDOW_BACKEND_SDL) || \ 53 | (TOGO_CONFIG_WINDOW_BACKEND == TOGO_WINDOW_BACKEND_GLFW) 54 | #define TOGO_WINDOW_BACKEND_SUPPORTS_OPENGL 55 | #endif 56 | #if (TOGO_CONFIG_WINDOW_BACKEND == TOGO_WINDOW_BACKEND_SDL) 57 | #define TOGO_WINDOW_BACKEND_SUPPORTS_RASTER 58 | #endif 59 | #endif // defined(DOXYGEN_CONSISTS_SOLELY_OF_UNICORNS_AND_CONFETTI) 60 | 61 | /// @} // end of name-group Window configuration 62 | 63 | /** @} */ // end of doc-group lib_window_config 64 | 65 | } // namespace togo 66 | -------------------------------------------------------------------------------- /lib/window/src/togo/window/input/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_window_input Input 5 | @ingroup lib_window 6 | @details 7 | 8 | Due to the behavior of some backends, there should only be 9 | one InputBuffer in use. Events for windows that have not been added 10 | to the window system will be discarded. 11 | 12 | The SDL backend may report events to the wrong window due to 13 | SDL implementation quirks. Keyboard events that do not have a valid 14 | windowID will be reported as having come from the first window in the 15 | input buffer (hopefully the primary window). 16 | 17 | */ 18 | -------------------------------------------------------------------------------- /lib/window/src/togo/window/input/input.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/window/input/input.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace togo { 12 | 13 | /// Whether key has been pressed for window. 14 | bool input::key_pressed(Window* window, KeyCode const code) { 15 | return window->_key_states[static_cast(code)]; 16 | } 17 | 18 | /// Whether key has been released for window. 19 | bool input::key_released(Window* window, KeyCode const code) { 20 | return window->_key_states[ 21 | static_cast(code) 22 | ] & (1 << static_cast(KeyAction::release)); 23 | } 24 | 25 | /// Whether button has been pressed for window. 26 | bool input::mouse_button_pressed(Window* window, MouseButton const button) { 27 | return window->_mouse_button_states[static_cast(button)]; 28 | } 29 | 30 | /// Whether button has been released for window. 31 | bool input::mouse_button_released(Window* window, MouseButton const button) { 32 | return window->_mouse_button_states[ 33 | static_cast(button) 34 | ] & (1 << static_cast(MouseButtonAction::release)); 35 | } 36 | 37 | /// Mouse position in window. 38 | Vec2 input::mouse_position(Window* window) { 39 | return Vec2{ 40 | static_cast(window->_mouse_x), 41 | static_cast(window->_mouse_y) 42 | }; 43 | } 44 | 45 | } // namespace togo 46 | -------------------------------------------------------------------------------- /lib/window/src/togo/window/input/input.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/window/input/input.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Input interface. 7 | @ingroup lib_window_input 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace togo { 18 | namespace input { 19 | 20 | /** 21 | @addtogroup lib_window_input 22 | @{ 23 | */ 24 | 25 | 26 | 27 | /** @} */ // end of doc-group lib_window_input 28 | 29 | } // namespace input 30 | } // namespace togo 31 | -------------------------------------------------------------------------------- /lib/window/src/togo/window/input/input_buffer.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/window/input/input_buffer.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief InputBuffer interface. 7 | @ingroup lib_window_input 8 | @ingroup lib_window_input_buffer 9 | 10 | @defgroup lib_window_input_buffer InputBuffer 11 | @ingroup lib_window_input 12 | @details 13 | */ 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | namespace togo { 24 | 25 | /// Construct with allocator for storage. 26 | inline InputBuffer::InputBuffer( 27 | Allocator& allocator, 28 | u32 const init_capacity 29 | ) 30 | : _num_windows(0) 31 | , _windows() 32 | , _buffer(allocator, init_capacity) 33 | {} 34 | 35 | namespace input_buffer { 36 | 37 | /** 38 | @addtogroup lib_window_input_buffer 39 | @{ 40 | */ 41 | 42 | /// Number of windows. 43 | inline unsigned num_windows(InputBuffer& ib) { 44 | return ib._num_windows; 45 | } 46 | 47 | /** @} */ // end of doc-group lib_window_input_buffer 48 | 49 | } // namespace input_buffer 50 | 51 | } // namespace togo 52 | -------------------------------------------------------------------------------- /lib/window/src/togo/window/opengl.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/window/opengl.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief OpenGL includes. 7 | */ 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #if !defined(TOGO_WINDOW_BACKEND_SUPPORTS_OPENGL) 14 | #error "OpenGL is not supported by the lib/window backend" 15 | #endif 16 | 17 | #include 18 | 19 | namespace togo { 20 | namespace window { 21 | 22 | char const* gl_get_error(); 23 | 24 | #define TOGO_GLCE_LOG() \ 25 | do { while (char const* gl_error__ = window::gl_get_error()) { \ 26 | TOGO_LOG_ERRORF("OpenGL error: %s\n", gl_error__); \ 27 | } } while (false) 28 | 29 | #define TOGO_GLCE(expr_) do { (expr_); TOGO_GLCE_LOG(); } while (false) 30 | 31 | void init_opengl(); 32 | 33 | bool set_opengl_debug_mode(bool active); 34 | 35 | } // namespace window 36 | } // namespace togo 37 | -------------------------------------------------------------------------------- /lib/window/src/togo/window/window/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup lib_window_window Window 5 | @ingroup lib_window 6 | @details 7 | 8 | */ 9 | -------------------------------------------------------------------------------- /lib/window/src/togo/window/window/impl/glfw.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/window/window/impl/glfw.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace togo { 13 | 14 | struct GLFWWindowImpl { 15 | GLFWwindow* handle; 16 | }; 17 | 18 | using WindowImpl = GLFWWindowImpl; 19 | 20 | #define TOGO_GLFW_CHECK(expr) \ 21 | if (!(expr)) { goto glfw_error; } 22 | 23 | } // namespace togo 24 | -------------------------------------------------------------------------------- /lib/window/src/togo/window/window/impl/private.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/window/window/impl/private.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace togo { 13 | namespace window { 14 | 15 | void init_impl(); 16 | void shutdown_impl(); 17 | 18 | bool is_attached_to_input_buffer(Window const* window); 19 | void attach_to_input_buffer(Window* window, InputBuffer& ib); 20 | void detach_from_input_buffer(Window* window); 21 | 22 | // Backend 23 | void attach_to_input_buffer_impl(Window* window); 24 | void detach_from_input_buffer_impl(Window* window); 25 | void process_events(InputBuffer& ib); 26 | 27 | } // namespace window 28 | } // namespace togo 29 | -------------------------------------------------------------------------------- /lib/window/src/togo/window/window/impl/sdl.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/window/window/impl/sdl.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | namespace togo { 14 | 15 | struct SDLWindowImpl { 16 | SDL_Window* handle; 17 | SDL_GLContext context; 18 | Pixmap backbuffer; 19 | }; 20 | 21 | using WindowImpl = SDLWindowImpl; 22 | 23 | #define TOGO_SDL_CHECK(expr) \ 24 | if ((expr)) { goto sdl_error; } 25 | 26 | } // namespace togo 27 | -------------------------------------------------------------------------------- /lib/window/test/build.lua: -------------------------------------------------------------------------------- 1 | 2 | local S, G, R = precore.helpers() 3 | 4 | local configs = { 5 | "togo.lib.window.dep", 6 | } 7 | 8 | togo.make_tests("general", { 9 | ["headers"] = {nil, configs}, 10 | }) 11 | 12 | togo.make_tests("window", { 13 | ["raster"] = {nil, configs}, 14 | ["opengl"] = {nil, configs}, 15 | }) 16 | -------------------------------------------------------------------------------- /lib/window/test/general/headers.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | signed main() { 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /lib/window/test/window/opengl.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | using namespace togo; 13 | 14 | signed main() { 15 | memory_init(); 16 | 17 | #if defined(TOGO_WINDOW_BACKEND_SUPPORTS_OPENGL) 18 | window::init(3, 3); 19 | 20 | WindowOpenGLConfig config{}; 21 | config.color_bits = {8, 8, 8, 0}; 22 | config.depth_bits = 16; 23 | config.stencil_bits = 0; 24 | config.msaa_num_buffers = 0; 25 | config.msaa_num_samples = 0; 26 | config.flags = WindowOpenGLConfig::Flags::double_buffered; 27 | 28 | Window* const window = window::create_opengl( 29 | "togo window", 30 | UVec2{1024, 768}, 31 | WindowFlags::borderless | 32 | WindowFlags::resizable, 33 | config 34 | ); 35 | InputBuffer ib{memory::default_allocator()}; 36 | input_buffer::add_window(ib, window); 37 | 38 | bool quit = false; 39 | bool mouse_lock = false; 40 | window::set_mouse_lock(window, mouse_lock); 41 | 42 | InputEventType event_type{}; 43 | InputEvent const* event = nullptr; 44 | while (!quit) { 45 | input_buffer::update(ib); 46 | while (input_buffer::poll(ib, event_type, event)) { 47 | TOGO_ASSERTE(event->window == window); 48 | if (event_type == InputEventType::window_close_request) { 49 | quit = true; 50 | } 51 | } 52 | if (input::key_released(window, KeyCode::escape)) { 53 | quit = true; 54 | } 55 | if (input::key_released(window, KeyCode::f1)) { 56 | mouse_lock = !mouse_lock; 57 | window::set_mouse_lock(window, mouse_lock); 58 | TOGO_LOG("mouse lock toggled\n"); 59 | } 60 | window::swap_buffers(window); 61 | system::sleep_ms(50); 62 | } 63 | input_buffer::remove_window(ib, window); 64 | window::destroy(window); 65 | window::shutdown(); 66 | #else 67 | TOGO_LOG("OpenGL windows are not supported by backend\n"); 68 | #endif 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /premake4.lua: -------------------------------------------------------------------------------- 1 | 2 | dofile("scripts/precore_import.lua") 3 | 4 | local _, G, R = precore.helpers() 5 | 6 | precore.init( 7 | nil, 8 | { 9 | "precore.clang-opts", 10 | "precore.c++11-core", 11 | } 12 | ) 13 | 14 | precore.import(".") 15 | precore.apply_global("togo.projects") 16 | 17 | -- precore.print_debug() 18 | 19 | if _ACTION == "clean" then 20 | os.rmdir(G"${BUILD_PATH}") 21 | 22 | local sol = precore.state.solutions["togo"] 23 | assert(sol) 24 | for _, proj in pairs(sol.projects) do 25 | if proj.env["TOGO_LIBRARY"] then 26 | os.rmdir(proj.obj.basedir .. "/test/build") 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /scripts/common.lua: -------------------------------------------------------------------------------- 1 | 2 | function togo_libraries() 3 | return { 4 | "core", 5 | "image", 6 | "platform", 7 | "window", 8 | "game", 9 | } 10 | end 11 | 12 | function togo_tools() 13 | return { 14 | "script_host", 15 | "res_build", 16 | } 17 | end 18 | 19 | function table_last(t) 20 | return t[#t] 21 | end 22 | 23 | function split_path(path) 24 | local name, extension = string.match(path, "^(%.?%.?.*)%.([^%.\\/]*)$") 25 | return (name or path), extension 26 | end 27 | 28 | function dirname(path) 29 | path = trim_trailing_slash(path) 30 | local dir, _ = string.match(path, "^(.+)/([^/]*)$") 31 | return dir or path 32 | end 33 | 34 | function trim_trailing_slash(path) 35 | if string.sub(path, -1) == "/" then 36 | path = string.sub(path, 1, -2) 37 | end 38 | return path 39 | end 40 | 41 | function make_inverse_table(t, value) 42 | local it = {} 43 | for k, v in pairs(t) do 44 | it[v] = value or k 45 | end 46 | return it 47 | end 48 | 49 | function printf(msg, ...) 50 | print(string.format(msg, ...)) 51 | end 52 | 53 | function iterate_dir(dir, select_only, max_depth) 54 | require("lfs") 55 | assert(dir and dir ~= "", "directory parameter is missing or empty") 56 | dir = trim_trailing_slash(dir) 57 | max_depth = max_depth or math.huge 58 | 59 | local function yield_tree(base, path, depth) 60 | if depth > max_depth then 61 | return 62 | end 63 | for entry in lfs.dir(base .. path) do 64 | if entry ~= "." and entry ~= ".." then 65 | entry = path .. "/" .. entry 66 | local attr = lfs.attributes(base .. entry) 67 | if select_only == nil or attr.mode == select_only then 68 | coroutine.yield(string.sub(entry, 2), attr) 69 | end 70 | if attr.mode == "directory" then 71 | yield_tree(base, entry, depth + 1) 72 | end 73 | end 74 | end 75 | end 76 | 77 | return coroutine.wrap( 78 | function() 79 | yield_tree(dir, "", 1) 80 | end 81 | ) 82 | end 83 | -------------------------------------------------------------------------------- /scripts/glad-extensions.txt: -------------------------------------------------------------------------------- 1 | GL_KHR_debug 2 | GL_ARB_texture_non_power_of_two 3 | GL_ARB_shading_language_420pack -------------------------------------------------------------------------------- /scripts/glad-generate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pushd "$(dirname "$(readlink -f "$0")")/../dep/glad" > /dev/null 4 | 5 | python -m glad \ 6 | --local-files \ 7 | --omit-khrplatform \ 8 | --generator c \ 9 | --profile core \ 10 | --spec gl \ 11 | --api gl=3.3 \ 12 | --extensions "../../scripts/glad-extensions.txt" \ 13 | --out-path "./src/glad/" 14 | 15 | popd > /dev/null 16 | -------------------------------------------------------------------------------- /scripts/igen_interface.template: -------------------------------------------------------------------------------- 1 | /** 2 | @file 3 | @brief GENERATED 4 | @note This file was created by igen. 5 | */ 6 | 7 | #pragma once 8 | 9 | #if !defined(IGEN_RUNNING) 10 | 11 | %for ns in group.funcs_by_namespace.values(): 12 | ${ns.open_string()} 13 | /** 14 | @addtogroup ${interface.doc_group} 15 | @{ 16 | */ 17 | 18 | %for f in ns.funcs: 19 | %if f.anno_private: 20 | /// @cond INTERNAL 21 | %elif f.cursor.raw_comment: 22 | ${f.cursor.raw_comment} 23 | %endif 24 | ${f.signature(named_args = True)}; 25 | %if f.anno_private: 26 | /// @endcond 27 | %endif 28 | 29 | %endfor 30 | /** @} */ 31 | ${ns.close_string()} 32 | %endfor 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /scripts/include_order: -------------------------------------------------------------------------------- 1 | 2 | local function find_name(name, children) 3 | for _, node in pairs(children) do 4 | if node.name == name then 5 | return true 6 | end 7 | end 8 | return false 9 | end 10 | 11 | return function(config) 12 | M = function(name, children) 13 | children = children or {} 14 | table.insert(children, 1, N("types")) 15 | if not find_name(name, children) then 16 | table.insert(children, 2, N(name)) 17 | end 18 | return N(name, children) 19 | end 20 | I = function(name, children) 21 | children = children or {} 22 | table.insert(children, 1, N("types")) 23 | table.insert(children, 2, N("private")) 24 | return N(name, children) 25 | end 26 | 27 | local nodes = {} 28 | local function do_group(root, prefix, name) 29 | local dir = string.format("%s/%s", root, name) 30 | local children = dofile(dir .. "/include_order") or {} 31 | table.insert(children, 1, N("config")) 32 | table.insert(children, 2, N("types")) 33 | table.insert(nodes, N(prefix .. name, children)) 34 | if config then 35 | table.insert(config.paths, dir .. "/src") 36 | if root == "lib" then 37 | table.insert(config.paths, dir .. "/test") 38 | end 39 | end 40 | end 41 | 42 | for _, name in pairs(togo_libraries()) do 43 | do_group("lib", "", name) 44 | end 45 | for _, name in pairs(togo_tools()) do 46 | do_group("tool", "tool_", name) 47 | end 48 | M, I = nil, nil 49 | 50 | return R( 51 | "togo", nodes, 52 | -- extension order 53 | {"hpp", "ipp", "gen_interface"}, 54 | -- path values 55 | {}, 56 | -- value filter 57 | function(_, path, extension, value) 58 | if string.match(path, "^togo/[^/]+/config$") then 59 | value.path = 1 60 | elseif string.match(path, "^togo/[^/]+/types$") then 61 | value.path = 2 62 | elseif extension == "gen_interface" then 63 | -- Force to the bottom of the include block 64 | value.path = -1 65 | end 66 | end 67 | ) 68 | end 69 | -------------------------------------------------------------------------------- /scripts/include_sort: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | include_sort scripts/include_sort.config $@ 4 | -------------------------------------------------------------------------------- /scripts/include_sort.config: -------------------------------------------------------------------------------- 1 | 2 | dofile("scripts/common.lua") 3 | 4 | local config = new_config() 5 | config.print_ok = false 6 | 7 | config.exclusions = make_inverse_table({ 8 | "togo/core/external/dlmalloc.hpp", 9 | "togo/core/external/dlmalloc.cpp", 10 | }) 11 | config.extension_filter = make_inverse_table({ 12 | "hpp", "ipp", "cpp", "cxx" 13 | }) 14 | 15 | config.order_tree = make_order_tree({ 16 | dofile("scripts/include_order")(config) 17 | }) 18 | 19 | return config 20 | -------------------------------------------------------------------------------- /scripts/precore_import.lua: -------------------------------------------------------------------------------- 1 | 2 | local function import_precore() 3 | local root_path = os.getenv("PRECORE_ROOT") 4 | if root_path == nil or #root_path == 0 then 5 | error( 6 | "Environment variable 'PRECORE_ROOT' is not defined" .. 7 | " or is blank; assign it to precore's root directory" 8 | ) 9 | end 10 | dofile(path.join(root_path, "precore.lua")) 11 | end 12 | 13 | import_precore() 14 | -------------------------------------------------------------------------------- /scripts/premake: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | premake4 $@ 4 | 5 | if [[ -f Makefile ]]; then 6 | sed -i \ 7 | -e 's/lib_core:/& | igen/' \ 8 | -e 's/lib_image:/& | lib_core/' \ 9 | -e 's/lib_window:/& | lib_image/' \ 10 | -e 's/lib_platform:/& | lib_core/' \ 11 | -e 's/lib_game:/& | lib_window/' \ 12 | -e 's/tool_script_host_lib:/& | lib_core/' \ 13 | -e 's/tool_script_host:/& | tool_script_host_lib/' \ 14 | -e 's|\-f tool_script_host\.make$|& -W src/togo/tool_script_host/main.cpp|' \ 15 | -e 's/tool_res_build_lib:/& | lib_game/' \ 16 | -e 's/tool_res_build:/& | tool_res_build_lib/' \ 17 | -e 's|\-f tool_res_build\.make$|& -W src/togo/tool_res_build/main.cpp|' \ 18 | -e 's/clean:/&:/' \ 19 | -e '$a include scripts/tests.make' \ 20 | Makefile 21 | fi 22 | -------------------------------------------------------------------------------- /scripts/run_igen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2 2 | 3 | print("run_igen") 4 | 5 | import os 6 | import sys 7 | 8 | IGEN_ROOT = os.environ["IGEN_ROOT"] 9 | assert IGEN_ROOT, "IGEN_ROOT not set" 10 | 11 | sys.path.append(os.path.join(IGEN_ROOT, "src")) 12 | 13 | from igen import interface 14 | 15 | interface.configure(IGEN_ROOT, "togo", "tmp", "scripts/igen_interface.template") 16 | 17 | c = interface.Collector() 18 | c.add_groups("lib", "") 19 | c.add_groups("tool", "tool_") 20 | c.collect() 21 | c.write() 22 | 23 | interface.build(sys.argv) 24 | -------------------------------------------------------------------------------- /scripts/tests.make: -------------------------------------------------------------------------------- 1 | 2 | TEST_ONLY_RECIPES := \ 3 | lib_core_tests_only \ 4 | lib_image_tests_only \ 5 | lib_window_tests_only \ 6 | lib_platform_tests_only \ 7 | lib_game_tests_only 8 | 9 | TEST_RECIPES := \ 10 | lib_core_tests \ 11 | lib_image_tests \ 12 | lib_window_tests \ 13 | lib_platform_tests \ 14 | lib_game_tests 15 | 16 | .PHONY: $(TEST_ONLY_RECIPES) tests_only $(TEST_RECIPES) tests clean_tests 17 | 18 | lib_core_tests_only: 19 | @${MAKE} --no-print-directory -C lib/core/test -f Makefile 20 | 21 | lib_image_tests_only: 22 | @${MAKE} --no-print-directory -C lib/image/test -f Makefile 23 | 24 | lib_window_tests_only: 25 | @${MAKE} --no-print-directory -C lib/window/test -f Makefile 26 | 27 | lib_platform_tests_only: 28 | @${MAKE} --no-print-directory -C lib/platform/test -f Makefile 29 | 30 | lib_game_tests_only: 31 | @${MAKE} --no-print-directory -C lib/game/test -f Makefile 32 | 33 | tests_only: $(TEST_ONLY_RECIPES) 34 | 35 | lib_core_tests: | lib_core 36 | @${MAKE} --no-print-directory -C lib/core/test -f Makefile 37 | 38 | lib_image_tests: | lib_image 39 | @${MAKE} --no-print-directory -C lib/image/test -f Makefile 40 | 41 | lib_window_tests: | lib_window 42 | @${MAKE} --no-print-directory -C lib/window/test -f Makefile 43 | 44 | lib_platform_tests: | lib_platform 45 | @${MAKE} --no-print-directory -C lib/platform/test -f Makefile 46 | 47 | lib_game_tests: | lib_game 48 | @${MAKE} --no-print-directory -C lib/game/test -f Makefile 49 | 50 | tests: $(TEST_RECIPES) 51 | 52 | clean_tests: 53 | @${MAKE} --no-print-directory -C lib/core/test -f Makefile clean 54 | @${MAKE} --no-print-directory -C lib/image/test -f Makefile clean 55 | @${MAKE} --no-print-directory -C lib/window/test -f Makefile clean 56 | @${MAKE} --no-print-directory -C lib/platform/test -f Makefile clean 57 | @${MAKE} --no-print-directory -C lib/game/test -f Makefile clean 58 | 59 | clean:: clean_tests 60 | -------------------------------------------------------------------------------- /support/togo/support/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup support Support 5 | @details 6 | 7 | */ 8 | -------------------------------------------------------------------------------- /support/togo/support/test.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/support/test.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Test support. 7 | @ingroup support_test 8 | 9 | @defgroup support_test Test 10 | @ingroup support 11 | @details 12 | */ 13 | 14 | #pragma once 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | /** 21 | @addtogroup support_test 22 | @{ 23 | */ 24 | 25 | #if defined(DOXYGEN_CONSISTS_SOLELY_OF_UNICORNS_AND_CONFETTI) 26 | /// The scratch size to init with. 27 | /// 28 | /// Defaults to togo::SCRATCH_ALLOCATOR_SIZE_DEFAULT. 29 | #define TOGO_SUPPORT_MEMINIT_SCRATCH_SIZE 30 | #elif !defined(TOGO_SUPPORT_MEMINIT_SCRATCH_SIZE) 31 | #define TOGO_SUPPORT_MEMINIT_SCRATCH_SIZE togo::SCRATCH_ALLOCATOR_SIZE_DEFAULT 32 | #endif 33 | 34 | /// Memory system initializer. 35 | /// 36 | /// Calls togo::memory::init() on construction and togo::memory::shutdown() 37 | /// on destruction. 38 | struct MemoryInitializer { 39 | MemoryInitializer(MemoryInitializer const&) = delete; 40 | MemoryInitializer& operator=(MemoryInitializer const&) = delete; 41 | MemoryInitializer(MemoryInitializer&&) = delete; 42 | MemoryInitializer& operator=(MemoryInitializer&&) = delete; 43 | 44 | MemoryInitializer() { 45 | togo::memory::init(TOGO_SUPPORT_MEMINIT_SCRATCH_SIZE); 46 | } 47 | 48 | ~MemoryInitializer() { 49 | togo::memory::shutdown(); 50 | } 51 | }; 52 | 53 | /// Ensure initialization of a static MemoryInitializer. 54 | void memory_init() { 55 | static MemoryInitializer const _ci{}; 56 | } 57 | 58 | /// Assert if an expression does not abort. 59 | #define TOGO_TEST_SHOULD_FAIL(expr_) do { \ 60 | TOGO_LOG_DEBUG("TOGO_TEST_SHOULD_FAIL: `" #expr_ "`\n"); \ 61 | (expr_); \ 62 | TOGO_ASSERT(false, "statement that should've failed did not"); \ 63 | } while (false) 64 | 65 | /** @} */ // end of doc-group support_test 66 | -------------------------------------------------------------------------------- /tool/res_build/build.lua: -------------------------------------------------------------------------------- 1 | 2 | local S, G, R = precore.helpers() 3 | 4 | precore.make_config("togo.tool.res_build.dep", { 5 | reverse = true, 6 | }, { 7 | "togo.base", 8 | "togo.lib.core.dep", 9 | "togo.lib.game.dep", 10 | {project = function(_) 11 | togo.tool_config("res_build") 12 | end}}) 13 | 14 | precore.append_config_scoped("togo.projects", { 15 | {global = function(_) 16 | togo.make_tool("res_build", { 17 | "togo.tool.res_build.dep", 18 | }) 19 | end}}) 20 | -------------------------------------------------------------------------------- /tool/res_build/include_order: -------------------------------------------------------------------------------- 1 | 2 | return { 3 | N("resource_compiler"), 4 | N("package_compiler"), 5 | N("compiler_manager"), 6 | N("generator_compiler"), 7 | N("gfx_compiler"), 8 | N("interface", { 9 | N("command_help"), 10 | N("command_list"), 11 | N("command_create"), 12 | N("command_sync"), 13 | N("command_compile"), 14 | N("command_pack"), 15 | N("command_compact"), 16 | }), 17 | } 18 | -------------------------------------------------------------------------------- /tool/res_build/src/togo/tool_res_build/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup tool_res_build Tool: res_build 5 | @details 6 | 7 | */ 8 | -------------------------------------------------------------------------------- /tool/res_build/src/togo/tool_res_build/compiler_manager.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/tool_res_build/compiler_manager.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief CompilerManager interface. 7 | @ingroup tool_res_build_compiler_manager 8 | 9 | @defgroup tool_res_build_compiler_manager CompilerManager 10 | @ingroup tool_res_build 11 | @details 12 | */ 13 | 14 | #pragma once 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | namespace togo { 23 | namespace tool_res_build { 24 | namespace compiler_manager { 25 | 26 | /** 27 | @addtogroup tool_res_build_compiler_manager 28 | @{ 29 | */ 30 | 31 | /// Package collection. 32 | inline Array const& packages( 33 | CompilerManager const& cm 34 | ) { 35 | return cm._packages; 36 | } 37 | 38 | /** @} */ // end of doc-group tool_res_build_compiler_manager 39 | 40 | } // namespace compiler_manager 41 | } // namespace tool_res_build 42 | } // namespace togo 43 | -------------------------------------------------------------------------------- /tool/res_build/src/togo/tool_res_build/config.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/tool_res_build/config.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Core configuration. 7 | @ingroup tool_res_build_config 8 | 9 | @defgroup tool_res_build_config Configuration 10 | @ingroup tool_res_build 11 | @details 12 | */ 13 | 14 | #pragma once 15 | 16 | #include 17 | 18 | namespace togo { 19 | namespace tool_res_build { 20 | 21 | /** 22 | @addtogroup tool_res_build_config 23 | @{ 24 | */ 25 | 26 | using namespace togo::game; 27 | 28 | /// tool_res_build information text. 29 | #define TOGO_TOOL_RES_BUILD_INFO_TEXT \ 30 | "togo res_build 0.00" 31 | 32 | /// tool_res_build usage text. 33 | #define TOGO_TOOL_RES_BUILD_USAGE_TEXT \ 34 | "usage: build [options] [command_arguments]" 35 | 36 | /** @} */ // end of doc-group tool_res_build_config 37 | 38 | } // namespace tool_res_build 39 | } // namespace togo 40 | -------------------------------------------------------------------------------- /tool/res_build/src/togo/tool_res_build/generator_compiler.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/tool_res_build/generator_compiler.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace togo { 12 | namespace tool_res_build { 13 | 14 | /// Register standard generator compilers. 15 | void generator_compiler::register_standard( 16 | GfxCompiler& gfx_compiler 17 | ) { 18 | gfx_compiler::register_generator_compiler(gfx_compiler, generator_compiler::test_proxy); 19 | gfx_compiler::register_generator_compiler(gfx_compiler, generator_compiler::clear); 20 | gfx_compiler::register_generator_compiler(gfx_compiler, generator_compiler::fullscreen_pass); 21 | } 22 | 23 | } // namespace tool_res_build 24 | } // namespace togo 25 | -------------------------------------------------------------------------------- /tool/res_build/src/togo/tool_res_build/generator_compiler.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/tool_res_build/generator_compiler.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief GeneratorCompiler interface. 7 | @ingroup tool_res_build_generator_compiler 8 | 9 | @defgroup tool_res_build_generator_compiler GeneratorCompiler 10 | @ingroup tool_res_build 11 | @details 12 | */ 13 | 14 | #pragma once 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | namespace togo { 21 | namespace tool_res_build { 22 | namespace generator_compiler { 23 | 24 | /** 25 | @addtogroup tool_res_build_generator_compiler 26 | @{ 27 | */ 28 | 29 | /// test_proxy generator compiler. 30 | extern GeneratorCompiler const test_proxy; 31 | 32 | /// clear generator compiler. 33 | extern GeneratorCompiler const clear; 34 | 35 | /// fullscreen_pass generator compiler. 36 | extern GeneratorCompiler const fullscreen_pass; 37 | 38 | /** @} */ // end of doc-group tool_res_build_generator_compiler 39 | 40 | } // namespace generator_compiler 41 | } // namespace tool_res_build 42 | } // namespace togo 43 | -------------------------------------------------------------------------------- /tool/res_build/src/togo/tool_res_build/generator_compiler/gc_test_proxy.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/tool_res_build/generator_compiler/gc_test_proxy.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace togo { 12 | namespace tool_res_build { 13 | 14 | namespace generator_compiler { 15 | namespace gc_test_proxy { 16 | 17 | static bool write( 18 | GeneratorCompiler& /*gen_compiler*/, 19 | BinaryOutputSerializer& /*ser*/, 20 | gfx::RenderConfig const& /*render_config*/, 21 | gfx::GeneratorUnit const& /*unit*/ 22 | ) { 23 | // Nothing to do! 24 | return true; 25 | } 26 | 27 | } // namespace gc_test_proxy 28 | } // namespace generator_compiler 29 | 30 | GeneratorCompiler const generator_compiler::test_proxy{ 31 | gfx::hash_generator_name("test_proxy"), 32 | generator_compiler::gc_test_proxy::write 33 | }; 34 | 35 | } // namespace tool_res_build 36 | } // namespace togo 37 | -------------------------------------------------------------------------------- /tool/res_build/src/togo/tool_res_build/generator_compiler/support.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/tool_res_build/generator_compiler/support.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace togo { 16 | namespace tool_res_build { 17 | 18 | inline bool rc_find_shared_resource( 19 | gfx::RenderConfig const& render_config, 20 | u32 const type, 21 | hash32 const name_hash, 22 | u32& index 23 | ) { 24 | index = 0; 25 | for (auto const& resource : render_config.shared_resources) { 26 | if (resource.name_hash == name_hash) { 27 | return resource.type() == type; 28 | } else if (resource.type() == type) { 29 | ++index; 30 | } 31 | } 32 | index = ~u32{0}; 33 | return false; 34 | } 35 | 36 | inline bool rc_get_render_target( 37 | StringRef const context, 38 | gfx::RenderConfig const& render_config, 39 | KVS const& k_var, 40 | u32& index 41 | ) { 42 | StringRef const name = kvs::string_ref(k_var); 43 | hash32 const name_hash = hash::calc32(name); 44 | if (rc_find_shared_resource( 45 | render_config, gfx::RenderConfigResource::TYPE_RENDER_TARGET, name_hash, 46 | index 47 | )) { 48 | return true; 49 | } else if (index != ~u32{0}) { 50 | TOGO_LOG_ERRORF( 51 | "malformed generator: %.*s: " 52 | "%.*s '%.*s' is not a render target\n", 53 | context.size, context.data, 54 | kvs::name_size(k_var), kvs::name(k_var), 55 | name.size, name.data 56 | ); 57 | return false; 58 | } else { 59 | TOGO_LOG_ERRORF( 60 | "malformed generator: %.*s: " 61 | "%.*s '%.*s' not found\n", 62 | context.size, context.data, 63 | kvs::name_size(k_var), kvs::name(k_var), 64 | name.size, name.data 65 | ); 66 | return false; 67 | } 68 | } 69 | 70 | } // namespace tool_res_build 71 | } // namespace togo 72 | -------------------------------------------------------------------------------- /tool/res_build/src/togo/tool_res_build/gfx_compiler.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/tool_res_build/gfx_compiler.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace togo { 14 | namespace tool_res_build { 15 | 16 | GfxCompiler::GfxCompiler(Allocator& allocator) 17 | : _gen_compilers(allocator) 18 | { 19 | hash_map::reserve(_gen_compilers, 16); 20 | } 21 | 22 | /// Register a generator compiler. 23 | void gfx_compiler::register_generator_compiler( 24 | GfxCompiler& gfx_compiler, 25 | GeneratorCompiler const& gen_compiler 26 | ) { 27 | TOGO_ASSERT( 28 | gen_compiler.func_write, 29 | "func_write must be assigned in generator compiler" 30 | ); 31 | TOGO_ASSERTF( 32 | !hash_map::has(gfx_compiler._gen_compilers, gen_compiler.name_hash), 33 | "generator %08x has already been registered", 34 | gen_compiler.name_hash 35 | ); 36 | hash_map::push(gfx_compiler._gen_compilers, gen_compiler.name_hash, gen_compiler); 37 | } 38 | 39 | /// Find a generator compiler by name. 40 | GeneratorCompiler* gfx_compiler::find_generator_compiler( 41 | GfxCompiler& gfx_compiler, 42 | gfx::GeneratorNameHash name_hash 43 | ) { 44 | return hash_map::find(gfx_compiler._gen_compilers, name_hash); 45 | } 46 | 47 | } // namespace tool_res_build 48 | } // namespace togo 49 | -------------------------------------------------------------------------------- /tool/res_build/src/togo/tool_res_build/gfx_compiler.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/tool_res_build/gfx_compiler.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief GfxCompiler interface. 7 | @ingroup tool_res_build_gfx_compiler 8 | 9 | @defgroup tool_res_build_gfx_compiler GfxCompiler 10 | @ingroup tool_res_build 11 | @details 12 | */ 13 | 14 | #pragma once 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | namespace togo { 21 | namespace tool_res_build { 22 | namespace gfx_compiler { 23 | 24 | /** 25 | @addtogroup tool_res_build_gfx_compiler 26 | @{ 27 | */ 28 | 29 | 30 | 31 | /** @} */ // end of doc-group tool_res_build_gfx_compiler 32 | 33 | } // namespace gfx_compiler 34 | } // namespace tool_res_build 35 | } // namespace togo 36 | -------------------------------------------------------------------------------- /tool/res_build/src/togo/tool_res_build/interface.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/tool_res_build/interface.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief tool_res_build interface. 7 | @ingroup tool_res_build_interface 8 | 9 | @defgroup tool_res_build_interface Interface 10 | @ingroup tool_res_build 11 | @details 12 | */ 13 | 14 | #pragma once 15 | 16 | // igen-following-sources-included 17 | // igen-source-pattern: interface/.+ipp 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | namespace togo { 26 | namespace tool_res_build { 27 | namespace interface { 28 | 29 | /** 30 | @addtogroup tool_res_build_interface 31 | @{ 32 | */ 33 | 34 | /// Project path. 35 | inline StringRef project_path( 36 | Interface const& interface 37 | ) { 38 | return {interface._project_path}; 39 | } 40 | 41 | /** @} */ // end of doc-group tool_res_build_interface 42 | 43 | } // namespace interface 44 | } // namespace tool_res_build 45 | } // namespace togo 46 | -------------------------------------------------------------------------------- /tool/res_build/src/togo/tool_res_build/interface/command_create.ipp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/tool_res_build/interface/command_create.ipp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | namespace togo { 7 | namespace tool_res_build { 8 | 9 | /// Run create command. 10 | /// 11 | /// Creates package. 12 | bool interface::command_create( 13 | Interface& interface, 14 | StringRef const& name 15 | ) { 16 | interface::check_project_path(interface); 17 | if (name.empty()) { 18 | TOGO_LOG_ERROR("package name must not be empty\n"); 19 | return false; 20 | } 21 | ResourcePackageNameHash const name_hash = resource::hash_package_name(name); 22 | if (compiler_manager::has_package(interface._manager, name_hash)) { 23 | TOGO_LOG_ERRORF( 24 | "package '%.*s' already exists in the project\n", 25 | name.size, name.data 26 | ); 27 | return false; 28 | } 29 | 30 | FixedArray path{}; 31 | string::append(path, interface._project_path); 32 | string::append(path, "/package/"); 33 | string::append(path, name); 34 | if (!package_compiler::create_stub(path, name)) { 35 | return false; 36 | } 37 | compiler_manager::add_package(interface._manager, path); 38 | return true; 39 | } 40 | 41 | /// Run create command with KVS. 42 | /// 43 | /// Specification: 44 | /// @verbatim create @endverbatim 45 | bool interface::command_create( 46 | Interface& interface, 47 | KVS const& k_command_options, 48 | KVS const& k_command 49 | ) { 50 | if (kvs::any(k_command_options)) { 51 | TOGO_LOG("error: options unexpected\n"); 52 | return false; 53 | } else if (kvs::empty(k_command)) { 54 | TOGO_LOG("error: expected\n"); 55 | return false; 56 | } else if (kvs::size(k_command) > 1) { 57 | TOGO_LOG("error: too many arguments\n"); 58 | return false; 59 | } 60 | 61 | KVS const& k_name = k_command[0]; 62 | TOGO_ASSERTE(kvs::is_string(k_name)); 63 | return interface::command_create(interface, kvs::string_ref(k_name)); 64 | } 65 | 66 | } // namespace tool_res_build 67 | } // namespace togo 68 | -------------------------------------------------------------------------------- /tool/res_build/src/togo/tool_res_build/main.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/tool_res_build/main.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace togo; 14 | using namespace togo::tool_res_build; 15 | 16 | signed main(signed argc, char* argv[]) { 17 | signed ec = 0; 18 | memory::init(); 19 | 20 | { 21 | KVS k_options{}; 22 | KVS k_command_options{}; 23 | KVS k_command{}; 24 | parse_args(k_options, k_command_options, k_command, argc, argv); 25 | 26 | Interface interface{}; 27 | if (!interface::read_options(interface, k_options)) { 28 | ec = -1; 29 | goto l_exit; 30 | } 31 | interface::init(interface, "", true); 32 | interface::read_project(interface); 33 | 34 | if (!interface::run(interface, k_command_options, k_command)) { 35 | ec = -2; 36 | goto l_exit; 37 | } 38 | } 39 | 40 | l_exit: 41 | memory::shutdown(); 42 | return ec; 43 | } 44 | -------------------------------------------------------------------------------- /tool/res_build/src/togo/tool_res_build/resource_compiler.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/tool_res_build/resource_compiler.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace togo { 12 | namespace tool_res_build { 13 | 14 | /// Register standard resource compilers. 15 | void resource_compiler::register_standard( 16 | CompilerManager& cm, 17 | GfxCompiler& gfx_compiler 18 | ) { 19 | resource_compiler::register_test(cm); 20 | resource_compiler::register_shader_prelude(cm); 21 | resource_compiler::register_shader(cm); 22 | resource_compiler::register_render_config(cm, gfx_compiler); 23 | } 24 | 25 | } // namespace tool_res_build 26 | } // namespace togo 27 | -------------------------------------------------------------------------------- /tool/res_build/src/togo/tool_res_build/resource_compiler.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/tool_res_build/resource_compiler.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief ResourceCompiler interface. 7 | @ingroup tool_res_build_resource_compiler 8 | 9 | @defgroup tool_res_build_resource_compiler ResourceCompiler 10 | @ingroup tool_res_build 11 | @details 12 | */ 13 | 14 | #pragma once 15 | 16 | // igen-source-pattern: resource_compiler/.+cpp 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | namespace togo { 23 | namespace tool_res_build { 24 | namespace resource_compiler { 25 | 26 | /** 27 | @addtogroup tool_res_build_resource_compiler 28 | @{ 29 | */ 30 | 31 | 32 | 33 | /** @} */ // end of doc-group tool_res_build_resource_compiler 34 | 35 | } // namespace resource_compiler 36 | } // namespace tool_res_build 37 | } // namespace togo 38 | -------------------------------------------------------------------------------- /tool/script_host/build.lua: -------------------------------------------------------------------------------- 1 | 2 | local S, G, R = precore.helpers() 3 | 4 | precore.make_config("togo.tool.script_host.dep", { 5 | reverse = true, 6 | }, { 7 | "togo.base", 8 | "togo.lib.core.dep", 9 | {project = function(_) 10 | togo.tool_config("script_host") 11 | end}}) 12 | 13 | precore.append_config_scoped("togo.projects", { 14 | {global = function(_) 15 | togo.make_tool("script_host", { 16 | "togo.tool.script_host.dep", 17 | }) 18 | end}}) 19 | -------------------------------------------------------------------------------- /tool/script_host/include_order: -------------------------------------------------------------------------------- 1 | 2 | return { 3 | } 4 | -------------------------------------------------------------------------------- /tool/script_host/src/togo/tool_script_host/.dox: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | 4 | @defgroup tool_script_host Tool: script_host 5 | @details 6 | 7 | Simple host for scripts. 8 | 9 | */ 10 | -------------------------------------------------------------------------------- /tool/script_host/src/togo/tool_script_host/config.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/tool_script_host/config.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief Core configuration. 7 | @ingroup tool_script_host_config 8 | 9 | @defgroup tool_script_host_config Configuration 10 | @ingroup tool_script_host 11 | @details 12 | */ 13 | 14 | #pragma once 15 | 16 | #include 17 | 18 | namespace togo { 19 | namespace tool_script_host { 20 | 21 | /** 22 | @addtogroup tool_script_host_config 23 | @{ 24 | */ 25 | 26 | /** @} */ // end of doc-group tool_script_host_config 27 | 28 | } // namespace tool_script_host 29 | } // namespace togo 30 | -------------------------------------------------------------------------------- /tool/script_host/src/togo/tool_script_host/main.cpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/tool_script_host/main.cpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | using namespace togo; 18 | 19 | signed main(signed argc, char* argv[]) { 20 | if (argc == 1) { 21 | TOGO_LOG("error: expected script path\n"); 22 | return 1; 23 | } 24 | 25 | StringRef script_path{argv[1], cstr_tag{}}; 26 | if (!filesystem::is_file(script_path)) { 27 | TOGO_LOGF( 28 | "error: path is either not a file or does not exist: %.*s\n", 29 | script_path.size, script_path.data 30 | ); 31 | return 2; 32 | } 33 | 34 | signed ec = 0; 35 | memory::init(); 36 | 37 | lua_State* L = lua::new_state(); 38 | TOGO_ASSERTE(L); 39 | luaL_openlibs(L); 40 | 41 | lua::register_core(L); 42 | io::register_lua_interface(L); 43 | filesystem::register_lua_interface(L); 44 | 45 | lua::push_value(L, lua::pcall_error_message_handler); 46 | if (luaL_loadfile(L, script_path.data)) { 47 | auto error = lua::get_string(L, -1); 48 | TOGO_LOGF("failed to load script: %.*s\n", error.size, error.data); 49 | lua_pop(L, 1); 50 | ec = 3; 51 | } else { 52 | lua_createtable(L, 0, argc - 1); 53 | for (signed i = 1; i < argc; ++i) { 54 | lua::table_set_index_raw(L, i, StringRef{argv[i], cstr_tag{}}); 55 | } 56 | if (lua_pcall(L, 1, 1, -3)) { 57 | auto error = lua::get_string(L, -1); 58 | TOGO_LOGF("error: %.*s\n", error.size, error.data); 59 | ec = 4; 60 | } else { 61 | if (lua_isboolean(L, -1) && !lua::get_boolean(L, -1)) { 62 | ec = 5; 63 | } 64 | } 65 | lua_pop(L, 1); 66 | } 67 | lua_pop(L, 1); 68 | lua_close(L); 69 | 70 | memory::shutdown(); 71 | return ec; 72 | } 73 | -------------------------------------------------------------------------------- /tool/script_host/src/togo/tool_script_host/types.hpp: -------------------------------------------------------------------------------- 1 | #line 2 "togo/tool_script_host/types.hpp" 2 | /** 3 | @copyright MIT license; see @ref index or the accompanying LICENSE file. 4 | 5 | @file 6 | @brief tool_script_host types. 7 | @ingroup tool_script_host_types 8 | 9 | @defgroup tool_script_host_types Types 10 | @ingroup tool_script_host 11 | @details 12 | */ 13 | 14 | #pragma once 15 | 16 | #include 17 | #include 18 | 19 | namespace togo { 20 | namespace tool_script_host { 21 | 22 | } // namespace tool_script_host 23 | } // namespace togo 24 | --------------------------------------------------------------------------------