From 7ce6c2d71616cdd9dcd2b0a5b4e0e7c63a55a7a0 Mon Sep 17 00:00:00 2001 From: RiscadoA Date: Mon, 26 Feb 2024 22:37:48 +0000 Subject: [PATCH] =?UTF-8?q?Deploy=20preview=20for=20PR=201032=20?= =?UTF-8?q?=F0=9F=9B=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs-preview/pr-1032/CubosLogo.png | Bin 0 -> 18999 bytes docs-preview/pr-1032/aabb_8hpp.html | 136 + docs-preview/pr-1032/access_8hpp.html | 134 + .../pr-1032/accumulated__correction_8hpp.html | 132 + docs-preview/pr-1032/action_8hpp.html | 132 + docs-preview/pr-1032/annotated.html | 555 ++++ docs-preview/pr-1032/any__value_8hpp.html | 136 + docs-preview/pr-1032/any__vector_8hpp.html | 136 + docs-preview/pr-1032/archetype_8hpp.html | 134 + .../pr-1032/archetype__graph_8hpp.html | 134 + docs-preview/pr-1032/archetype__id_8hpp.html | 138 + docs-preview/pr-1032/archive_8hpp.html | 134 + docs-preview/pr-1032/array_8hpp.html | 134 + docs-preview/pr-1032/asset_8hpp.html | 141 + docs-preview/pr-1032/assets_2bridge_8hpp.html | 132 + docs-preview/pr-1032/assets_8hpp.html | 156 + docs-preview/pr-1032/audio__device_8hpp.html | 171 + docs-preview/pr-1032/axis_8hpp.html | 132 + docs-preview/pr-1032/binary_8hpp.html | 133 + docs-preview/pr-1032/bindings_8hpp.html | 132 + docs-preview/pr-1032/bloom_8hpp.html | 132 + docs-preview/pr-1032/blueprint_8hpp.html | 146 + docs-preview/pr-1032/buffer__stream_8hpp.html | 134 + docs-preview/pr-1032/camera_8hpp.html | 132 + docs-preview/pr-1032/child__of_8hpp.html | 132 + .../pr-1032/classcubos_1_1core_1_1Logger.html | 374 +++ .../classcubos_1_1core_1_1ThreadPool.html | 183 ++ ...asscubos_1_1core_1_1al_1_1AudioDevice.html | 292 ++ ...cubos_1_1core_1_1al_1_1impl_1_1Buffer.html | 161 + ...cubos_1_1core_1_1al_1_1impl_1_1Source.html | 379 +++ ...classcubos_1_1core_1_1data_1_1Archive.html | 398 +++ ...os_1_1core_1_1data_1_1DebugSerializer.html | 220 ++ ...cubos_1_1core_1_1data_1_1Deserializer.html | 355 ++ ...os_1_1core_1_1data_1_1EmbeddedArchive.html | 466 +++ .../classcubos_1_1core_1_1data_1_1File.html | 496 +++ ...sscubos_1_1core_1_1data_1_1FileStream.html | 352 ++ ...sscubos_1_1core_1_1data_1_1FileSystem.html | 361 ++ ...s_1_1core_1_1data_1_1JSONDeserializer.html | 204 ++ ...bos_1_1core_1_1data_1_1JSONSerializer.html | 200 ++ ...sscubos_1_1core_1_1data_1_1Serializer.html | 349 ++ ...os_1_1core_1_1data_1_1StandardArchive.html | 434 +++ ..._1_1data_1_1old_1_1BinaryDeserializer.html | 491 +++ ...re_1_1data_1_1old_1_1BinarySerializer.html | 574 ++++ ...bos_1_1core_1_1data_1_1old_1_1Context.html | 248 ++ ..._1core_1_1data_1_1old_1_1Deserializer.html | 557 ++++ ...re_1_1data_1_1old_1_1JSONDeserializer.html | 485 +++ ...core_1_1data_1_1old_1_1JSONSerializer.html | 574 ++++ ...bos_1_1core_1_1data_1_1old_1_1Package.html | 849 +++++ ...re_1_1data_1_1old_1_1SerializationMap.html | 377 +++ ..._1_1core_1_1data_1_1old_1_1Serializer.html | 652 ++++ ..._1_1core_1_1data_1_1old_1_1Unpackager.html | 485 +++ ...re_1_1data_1_1old_1_1impl_1_1Packager.html | 542 +++ ...ubos_1_1core_1_1ecs_1_1ArchetypeGraph.html | 334 ++ ...lasscubos_1_1core_1_1ecs_1_1Blueprint.html | 549 ++++ ...cubos_1_1core_1_1ecs_1_1CommandBuffer.html | 379 +++ ...classcubos_1_1core_1_1ecs_1_1Commands.html | 568 ++++ .../classcubos_1_1core_1_1ecs_1_1Cubos.html | 496 +++ ...asscubos_1_1core_1_1ecs_1_1DenseTable.html | 391 +++ ..._1_1core_1_1ecs_1_1DenseTableRegistry.html | 227 ++ ...asscubos_1_1core_1_1ecs_1_1Dispatcher.html | 455 +++ ...asscubos_1_1core_1_1ecs_1_1EntityPool.html | 296 ++ ...lasscubos_1_1core_1_1ecs_1_1EventPipe.html | 299 ++ ...sscubos_1_1core_1_1ecs_1_1EventReader.html | 249 ++ ...ore_1_1ecs_1_1EventReader_1_1Iterator.html | 103 + ...sscubos_1_1core_1_1ecs_1_1EventWriter.html | 195 ++ .../classcubos_1_1core_1_1ecs_1_1Opt.html | 304 ++ .../classcubos_1_1core_1_1ecs_1_1Query.html | 331 ++ ..._1_1core_1_1ecs_1_1QueryArchetypeNode.html | 268 ++ ...lasscubos_1_1core_1_1ecs_1_1QueryData.html | 307 ++ ...scubos_1_1core_1_1ecs_1_1QueryFetcher.html | 254 ++ ...sscubos_1_1core_1_1ecs_1_1QueryFilter.html | 222 ++ ...lasscubos_1_1core_1_1ecs_1_1QueryNode.html | 277 ++ ...os_1_1core_1_1ecs_1_1QueryRelatedNode.html | 267 ++ ...scubos_1_1core_1_1ecs_1_1ReadResource.html | 185 ++ ...bos_1_1core_1_1ecs_1_1ResourceManager.html | 224 ++ ...1_1core_1_1ecs_1_1SparseRelationTable.html | 827 +++++ ...1_1ecs_1_1SparseRelationTableRegistry.html | 419 +++ ...rseRelationTableRegistry_1_1TypeIndex.html | 197 ++ .../classcubos_1_1core_1_1ecs_1_1System.html | 258 ++ ...cubos_1_1core_1_1ecs_1_1SystemFetcher.html | 228 ++ .../classcubos_1_1core_1_1ecs_1_1Tables.html | 194 ++ ...asscubos_1_1core_1_1ecs_1_1TagBuilder.html | 310 ++ ...sscubos_1_1core_1_1ecs_1_1TypeBuilder.html | 296 ++ .../classcubos_1_1core_1_1ecs_1_1Types.html | 477 +++ .../classcubos_1_1core_1_1ecs_1_1World.html | 1208 +++++++ ...cubos_1_1core_1_1ecs_1_1WriteResource.html | 185 ++ .../classcubos_1_1core_1_1gl_1_1Debug.html | 375 +++ ...sscubos_1_1core_1_1gl_1_1RenderDevice.html | 1288 ++++++++ ...s_1_1core_1_1gl_1_1impl_1_1BlendState.html | 103 + ...1core_1_1gl_1_1impl_1_1ConstantBuffer.html | 144 + ...ubos_1_1core_1_1gl_1_1impl_1_1CubeMap.html | 183 ++ ...1_1core_1_1gl_1_1impl_1_1CubeMapArray.html | 189 ++ ...re_1_1gl_1_1impl_1_1DepthStencilState.html | 103 + ..._1_1core_1_1gl_1_1impl_1_1Framebuffer.html | 103 + ..._1_1core_1_1gl_1_1impl_1_1IndexBuffer.html | 144 + ..._1_1core_1_1gl_1_1impl_1_1RasterState.html | 103 + ...ubos_1_1core_1_1gl_1_1impl_1_1Sampler.html | 103 + ...e_1_1gl_1_1impl_1_1ShaderBindingPoint.html | 624 ++++ ...1core_1_1gl_1_1impl_1_1ShaderPipeline.html | 140 + ..._1_1core_1_1gl_1_1impl_1_1ShaderStage.html | 140 + ...os_1_1core_1_1gl_1_1impl_1_1Texture1D.html | 165 + ...os_1_1core_1_1gl_1_1impl_1_1Texture2D.html | 204 ++ ...1core_1_1gl_1_1impl_1_1Texture2DArray.html | 183 ++ ...os_1_1core_1_1gl_1_1impl_1_1Texture3D.html | 189 ++ ..._1_1core_1_1gl_1_1impl_1_1VertexArray.html | 103 + ...1_1core_1_1gl_1_1impl_1_1VertexBuffer.html | 144 + ...lasscubos_1_1core_1_1io_1_1BaseWindow.html | 534 +++ .../classcubos_1_1core_1_1io_1_1Cursor.html | 206 ++ ...sscubos_1_1core_1_1memory_1_1AnyValue.html | 370 +++ ...scubos_1_1core_1_1memory_1_1AnyVector.html | 529 +++ ...bos_1_1core_1_1memory_1_1BufferStream.html | 444 +++ ...ory_1_1Function_3_01R_07Ts_8_8_8_08_4.html | 311 ++ ...scubos_1_1core_1_1memory_1_1ReadGuard.html | 263 ++ ...s_1_1core_1_1memory_1_1StandardStream.html | 333 ++ ...lasscubos_1_1core_1_1memory_1_1Stream.html | 1012 ++++++ ...asscubos_1_1core_1_1memory_1_1TypeMap.html | 583 ++++ ...s_1_1core_1_1memory_1_1UnorderedBimap.html | 483 +++ ...cubos_1_1core_1_1memory_1_1WriteGuard.html | 326 ++ ...s_1_1core_1_1reflection_1_1ArrayTrait.html | 438 +++ ...e_1_1reflection_1_1ConstructibleTrait.html | 499 +++ ...tion_1_1ConstructibleTrait_1_1Builder.html | 238 ++ ...core_1_1reflection_1_1DictionaryTrait.html | 494 +++ ...os_1_1core_1_1reflection_1_1EnumTrait.html | 490 +++ ..._1_1core_1_1reflection_1_1FieldsTrait.html | 472 +++ ...ction_1_1FieldsTrait_1_1AddressOfImpl.html | 198 ++ ...os_1_1core_1_1reflection_1_1MaskTrait.html | 466 +++ ..._1core_1_1reflection_1_1NullableTrait.html | 218 ++ ..._1reflection_1_1StringConversionTrait.html | 230 ++ ...sscubos_1_1core_1_1reflection_1_1Type.html | 357 ++ ...1_1core_1_1reflection_1_1TypeRegistry.html | 351 ++ .../classcubos_1_1engine_1_1AnyAsset.html | 452 +++ .../classcubos_1_1engine_1_1Asset.html | 332 ++ .../classcubos_1_1engine_1_1AssetBridge.html | 246 ++ .../classcubos_1_1engine_1_1AssetMeta.html | 244 ++ .../classcubos_1_1engine_1_1Assets.html | 708 ++++ .../classcubos_1_1engine_1_1BaseRenderer.html | 433 +++ .../classcubos_1_1engine_1_1BinaryBridge.html | 259 ++ ...classcubos_1_1engine_1_1DataInspector.html | 257 ++ ...sscubos_1_1engine_1_1DeferredRenderer.html | 300 ++ .../classcubos_1_1engine_1_1FileBridge.html | 337 ++ .../classcubos_1_1engine_1_1Gizmos.html | 697 ++++ ...asscubos_1_1engine_1_1Gizmos_1_1Gizmo.html | 200 ++ .../classcubos_1_1engine_1_1Input.html | 560 ++++ .../classcubos_1_1engine_1_1InputAction.html | 313 ++ .../classcubos_1_1engine_1_1InputAxis.html | 313 ++ ...classcubos_1_1engine_1_1InputBindings.html | 195 ++ .../classcubos_1_1engine_1_1JSONBridge.html | 239 ++ ...ubos_1_1engine_1_1PostProcessingBloom.html | 393 +++ ...cubos_1_1engine_1_1PostProcessingCopy.html | 221 ++ ...os_1_1engine_1_1PostProcessingManager.html | 296 ++ ...cubos_1_1engine_1_1PostProcessingPass.html | 233 ++ ...classcubos_1_1engine_1_1RendererFrame.html | 416 +++ .../classcubos_1_1engine_1_1SceneBridge.html | 300 ++ .../classcubos_1_1engine_1_1ScreenPicker.html | 243 ++ .../classcubos_1_1engine_1_1Settings.html | 436 +++ .../classcubos_1_1engine_1_1VoxelGrid.html | 367 +++ .../classcubos_1_1engine_1_1VoxelPalette.html | 408 +++ ...1_1engine_1_1VoxelPalette_1_1Iterator.html | 103 + ...bos_1_1engine_1_1impl_1_1RendererGrid.html | 103 + ...scubos_1_1engine_1_1old_1_1JSONBridge.html | 260 ++ .../pr-1032/classtesseratos_1_1Toolbox.html | 248 ++ docs-preview/pr-1032/collider_8hpp.html | 132 + .../pr-1032/colliding__with_8hpp.html | 132 + .../pr-1032/collision__event_8hpp.html | 132 + docs-preview/pr-1032/column_8hpp.html | 134 + .../pr-1032/command__buffer_8hpp.html | 136 + docs-preview/pr-1032/commands_8hpp.html | 134 + docs-preview/pr-1032/comparison_8hpp.html | 136 + docs-preview/pr-1032/constructible_8hpp.html | 139 + .../pr-1032/constructible__utils_8hpp.html | 136 + docs-preview/pr-1032/contribution.html | 114 + docs-preview/pr-1032/controller_8hpp.html | 132 + docs-preview/pr-1032/copy__pass_8hpp.html | 132 + ...de_2cubos_2core_2data_2des_2json_8hpp.html | 134 + ...ude_2cubos_2core_2data_2fs_2file_8hpp.html | 134 + ...de_2cubos_2core_2data_2ser_2json_8hpp.html | 134 + ...os_2core_2ecs_2resource_2manager_8hpp.html | 144 + ...2include_2cubos_2core_2geom_2box_8hpp.html | 136 + ...lude_2cubos_2core_2geom_2capsule_8hpp.html | 136 + docs-preview/pr-1032/cstring_8hpp.html | 102 + docs-preview/pr-1032/cubos_8hpp.html | 150 + docs-preview/pr-1032/cursor_8hpp.html | 134 + docs-preview/pr-1032/damping_8hpp.html | 132 + .../pr-1032/data_2ser_2debug_8hpp.html | 134 + docs-preview/pr-1032/data_8hpp.html | 135 + .../pr-1032/data__inspector_8hpp.html | 132 + .../pr-1032/deferred__renderer_8hpp.html | 132 + .../pr-1032/dense_2registry_8hpp.html | 134 + docs-preview/pr-1032/dense_2table_8hpp.html | 134 + .../pr-1032/des_2deserializer_8hpp.html | 134 + docs-preview/pr-1032/dictionary_8hpp.html | 142 + .../dir_00300fcbde38ee57d1255bf5757a56e9.html | 120 + .../dir_043da9b7d60f46877cefd90a49e157c3.html | 120 + .../dir_0835e003fa277f66ce5cf543d578f6a2.html | 136 + .../dir_0b39c986537c7114081f36bbdae17547.html | 132 + .../dir_1849b6590c20a7c40f18c0337f505edf.html | 136 + .../dir_18699a5452817121af2ab0a7c7f1cc3e.html | 120 + .../dir_26a5878ebb5e9988b6ffa6f152301254.html | 128 + .../dir_2a25e2bce65ce0f842dba5b7b3a0e22d.html | 154 + .../dir_2a3f20446d92cb0b384d0cf4f4d26d60.html | 120 + .../dir_3504744c369d3ac8de67ffae1d44d2b4.html | 122 + .../dir_3764e76d8ec4e739fc24b5bb90adc3af.html | 128 + .../dir_38aac728ad33877355e223e23ac4ab7a.html | 124 + .../dir_38dc3202db19a8deaf7e1516278a105d.html | 120 + .../dir_38e9fb064544086d3594e70a41f6b257.html | 124 + .../dir_3e72b743a5c62924583b661b2c5525f9.html | 120 + .../dir_4149d46e02eca8eae23b140f2d5369cf.html | 123 + .../dir_459dda10180a6131eb62bc74e02d0b6e.html | 122 + .../dir_46c6a4a310169812045f09ba6135aa36.html | 122 + .../dir_56f03f6936f99956d731d9e98d524876.html | 120 + .../dir_57aff98960b24114775613a58ec786ad.html | 122 + .../dir_5f701044e65d6c264a6c1dc66b1052c2.html | 132 + .../dir_60b52edecd3c8caac6b76bd0bb2ba3ce.html | 120 + .../dir_64a2fed96ae76f57d94061df7c919db3.html | 102 + .../dir_672562f1eb3ea0be7f3aa3e89e72ecd2.html | 126 + .../dir_696376665c0dc3694e56f168acfac677.html | 120 + .../dir_69c88e5af9faf72eaf159ee3e83d9db2.html | 126 + .../dir_6c4c9e5f04768b915dbc2edba08d4f5c.html | 122 + .../dir_6c897dd97bedf3914ee8a4d9f7f6549c.html | 144 + .../dir_6e7fefd5d33489e77ed24a475a1b2d04.html | 122 + .../dir_7376bacbd9e6243f425bd4c56d48edd9.html | 126 + .../dir_73cd920be1d9b25db5feb4d2a202c641.html | 136 + .../dir_79f402fdd7bbb1d73f9fd1aa85f618da.html | 130 + .../dir_85f1b5bc6fb8e602e74068211760bfae.html | 136 + .../dir_8711f680e2d25dedddc79c2be2b1fda2.html | 122 + .../dir_87a7847ee77970235330560d79c37ce0.html | 148 + .../dir_8e5f84d20b1aa89c94160461e78e26c4.html | 128 + .../dir_95549d37735ad5b142799f042eef0d37.html | 124 + .../dir_983a8c8cc77436ec11afd1f0c4e2ef1f.html | 120 + .../dir_9b04cf786b414c0d644db09287f665e6.html | 126 + .../dir_9bdaf8f561be1ffd03f616379797b70b.html | 140 + .../dir_9f228de11f2fc2633236213a3ef5c992.html | 124 + .../dir_a1cc7ffab82768b4f8702a03c85b938c.html | 120 + .../dir_ae52c41efe1aaae7a392cb947b223e9f.html | 120 + .../dir_b6daa990b896c2c0c53126427e4d978d.html | 148 + .../dir_bafb7af0e03e95b24a45ff63060ab57b.html | 148 + .../dir_bc092de7c4be29a20e8c6c4d7f3164b3.html | 120 + .../dir_bd9be39c2ccf4132268583193b02b48c.html | 124 + .../dir_c1b5957eb0512b9978230dfb34d9655b.html | 122 + .../dir_c1deef5baf41393ad8a994c3fd53e62f.html | 126 + .../dir_c26f946019c5d6937d16d4e3329f697e.html | 120 + .../dir_c3ed6a1192e5b1b0ac8a4baf7bd6e376.html | 120 + .../dir_c4311188e9cc606330f5e3e0b9dd5059.html | 124 + .../dir_ce4a27e99b2102cfb79fc5b09181f4e6.html | 122 + .../dir_d28a4e16d9deb548c857866e71f89c35.html | 120 + .../dir_db86702e1371d7558db3699dd3786a14.html | 134 + .../dir_f4414684a5bb1e1b8e9ba236e8bdb594.html | 136 + .../dir_f6f65ff657bd34b22e5078310628f4e7.html | 120 + .../dir_fc8110eaf6ef50e82d21b749d50a1849.html | 122 + .../pr-1032/directional__light_8hpp.html | 132 + docs-preview/pr-1032/dispatcher_8hpp.html | 146 + .../pr-1032/embedded__archive_8hpp.html | 142 + docs-preview/pr-1032/endianness_8hpp.html | 159 + ...s_2engine_2assets_2bridges_2file_8hpp.html | 132 + ...s_2engine_2assets_2bridges_2json_8hpp.html | 133 + ...gine_2assets_2bridges_2old_2json_8hpp.html | 133 + ...e_2cubos_2engine_2assets_2plugin_8hpp.html | 132 + ...ubos_2engine_2collisions_2plugin_8hpp.html | 132 + ...2engine_2collisions_2shapes_2box_8hpp.html | 132 + ...ine_2collisions_2shapes_2capsule_8hpp.html | 132 + ...bos_2engine_2fixed__step_2plugin_8hpp.html | 132 + ...e_2cubos_2engine_2gizmos_2plugin_8hpp.html | 132 + ...de_2cubos_2engine_2imgui_2plugin_8hpp.html | 132 + ...de_2cubos_2engine_2input_2plugin_8hpp.html | 132 + ..._2cubos_2engine_2physics_2plugin_8hpp.html | 132 + ...2cubos_2engine_2renderer_2plugin_8hpp.html | 150 + ..._2engine_2renderer_2pps_2manager_8hpp.html | 144 + ...de_2cubos_2engine_2scene_2plugin_8hpp.html | 132 + ..._2engine_2screen__picker_2plugin_8hpp.html | 132 + ...2cubos_2engine_2settings_2plugin_8hpp.html | 132 + ...bos_2engine_2splitscreen_2plugin_8hpp.html | 132 + ...cubos_2engine_2transform_2plugin_8hpp.html | 132 + ...ine_2utils_2free__camera_2plugin_8hpp.html | 132 + ...e_2cubos_2engine_2voxels_2plugin_8hpp.html | 132 + ...e_2cubos_2engine_2window_2plugin_8hpp.html | 132 + docs-preview/pr-1032/entity_8hpp.html | 134 + docs-preview/pr-1032/enum_8hpp.html | 134 + docs-preview/pr-1032/environment_8hpp.html | 132 + .../examples-core-data-des-custom.html | 197 ++ .../pr-1032/examples-core-data-des.html | 106 + .../examples-core-data-ser-custom.html | 182 + .../pr-1032/examples-core-data-ser-json.html | 121 + .../pr-1032/examples-core-data-ser.html | 106 + docs-preview/pr-1032/examples-core-data.html | 105 + .../pr-1032/examples-core-logging.html | 116 + .../examples-core-reflection-basic.html | 138 + ...examples-core-reflection-traits-array.html | 145 + ...-core-reflection-traits-constructible.html | 133 + ...les-core-reflection-traits-dictionary.html | 154 + .../examples-core-reflection-traits-enum.html | 162 + ...xamples-core-reflection-traits-fields.html | 162 + .../examples-core-reflection-traits-mask.html | 174 + ...mples-core-reflection-traits-nullable.html | 156 + ...e-reflection-traits-string-conversion.html | 136 + .../pr-1032/examples-core-reflection.html | 105 + docs-preview/pr-1032/examples-core.html | 104 + .../examples-engine-assets-bridge.html | 143 + .../pr-1032/examples-engine-assets-json.html | 125 + .../examples-engine-assets-saving.html | 120 + .../pr-1032/examples-engine-assets.html | 105 + .../pr-1032/examples-engine-events.html | 161 + .../pr-1032/examples-engine-gizmos.html | 155 + .../pr-1032/examples-engine-hello-cubos.html | 138 + .../pr-1032/examples-engine-imgui.html | 192 ++ .../pr-1032/examples-engine-input.html | 316 ++ .../pr-1032/examples-engine-renderer.html | 150 + .../pr-1032/examples-engine-scene.html | 172 + .../pr-1032/examples-engine-settings.html | 116 + .../pr-1032/examples-engine-voxels.html | 119 + docs-preview/pr-1032/examples-engine.html | 104 + docs-preview/pr-1032/examples.html | 103 + docs-preview/pr-1032/favicon-dark.png | Bin 0 -> 380 bytes docs-preview/pr-1032/features-ecs.html | 184 ++ docs-preview/pr-1032/features-plugins.html | 138 + docs-preview/pr-1032/features-quadrados.html | 123 + docs-preview/pr-1032/features-queries.html | 194 ++ docs-preview/pr-1032/features.html | 102 + docs-preview/pr-1032/fields_8hpp.html | 147 + docs-preview/pr-1032/file__stream_8hpp.html | 135 + docs-preview/pr-1032/file__system_8hpp.html | 134 + docs-preview/pr-1032/files.html | 568 ++++ docs-preview/pr-1032/filter_8hpp.html | 138 + .../pr-1032/fixed__delta__time_8hpp.html | 132 + docs-preview/pr-1032/force_8hpp.html | 132 + docs-preview/pr-1032/frame_8hpp.html | 136 + docs-preview/pr-1032/function_8hpp.html | 135 + docs-preview/pr-1032/gamepad_8hpp.html | 193 ++ docs-preview/pr-1032/getting-started.html | 103 + docs-preview/pr-1032/gizmos_8hpp.html | 136 + docs-preview/pr-1032/gl_2debug_8hpp.html | 134 + docs-preview/pr-1032/glm_8hpp.html | 102 + docs-preview/pr-1032/grid_8hpp.html | 136 + .../pr-1032/group__assets-plugin.html | 303 ++ .../pr-1032/group__collisions-plugin.html | 192 ++ docs-preview/pr-1032/group__core-al.html | 153 + .../pr-1032/group__core-data-des.html | 137 + docs-preview/pr-1032/group__core-data-fs.html | 162 + .../pr-1032/group__core-data-ser.html | 139 + docs-preview/pr-1032/group__core-data.html | 124 + .../pr-1032/group__core-ecs-entity.html | 155 + .../pr-1032/group__core-ecs-query.html | 164 + .../pr-1032/group__core-ecs-resource.html | 141 + .../group__core-ecs-system-arguments.html | 164 + .../pr-1032/group__core-ecs-system.html | 165 + .../pr-1032/group__core-ecs-table.html | 161 + docs-preview/pr-1032/group__core-ecs.html | 193 ++ docs-preview/pr-1032/group__core-geom.html | 148 + docs-preview/pr-1032/group__core-gl.html | 1249 +++++++ docs-preview/pr-1032/group__core-io.html | 703 ++++ docs-preview/pr-1032/group__core-memory.html | 530 +++ .../pr-1032/group__core-reflection.html | 487 +++ docs-preview/pr-1032/group__core.html | 586 ++++ docs-preview/pr-1032/group__engine.html | 170 + .../pr-1032/group__fixed-step-plugin.html | 166 + .../pr-1032/group__free-camera-plugin.html | 153 + .../pr-1032/group__gizmos-plugin.html | 168 + docs-preview/pr-1032/group__imgui-plugin.html | 168 + docs-preview/pr-1032/group__input-plugin.html | 187 ++ .../group__physics-gravity-plugin.html | 176 + .../pr-1032/group__physics-plugin.html | 232 ++ .../pr-1032/group__physics-solver-plugin.html | 121 + .../pr-1032/group__renderer-plugin.html | 370 +++ docs-preview/pr-1032/group__scene-plugin.html | 172 + .../pr-1032/group__screen-picker-plugin.html | 168 + .../pr-1032/group__settings-plugin.html | 155 + .../pr-1032/group__splitscreen-plugin.html | 153 + ...oup__tesseratos-asset-explorer-plugin.html | 154 + ...up__tesseratos-collider-gizmos-plugin.html | 153 + ...group__tesseratos-debug-camera-plugin.html | 153 + ...oup__tesseratos-ecs-statistics-plugin.html | 153 + ...p__tesseratos-entity-inspector-plugin.html | 153 + ...up__tesseratos-entity-selector-plugin.html | 156 + ...roup__tesseratos-metrics-panel-plugin.html | 153 + .../group__tesseratos-play-pause-plugin.html | 153 + ...group__tesseratos-scene-editor-plugin.html | 153 + ..._tesseratos-settings-inspector-plugin.html | 153 + .../group__tesseratos-toolbox-plugin.html | 164 + ...up__tesseratos-transform-gizmo-plugin.html | 151 + ...esseratos-voxel-palette-editor-plugin.html | 153 + ...up__tesseratos-world-inspector-plugin.html | 153 + docs-preview/pr-1032/group__tesseratos.html | 185 ++ .../pr-1032/group__transform-plugin.html | 197 ++ .../pr-1032/group__voxels-plugin.html | 178 + .../pr-1032/group__window-plugin.html | 158 + docs-preview/pr-1032/guards_8hpp.html | 140 + docs-preview/pr-1032/hash_8hpp.html | 134 + docs-preview/pr-1032/id_8hpp.html | 140 + docs-preview/pr-1032/img1.png | Bin 0 -> 11833 bytes docs-preview/pr-1032/img2.png | Bin 0 -> 10174 bytes docs-preview/pr-1032/impulse_8hpp.html | 132 + docs-preview/pr-1032/index.html | 102 + docs-preview/pr-1032/input_8hpp.html | 132 + docs-preview/pr-1032/intersections_8hpp.html | 148 + docs-preview/pr-1032/keyboard_8hpp.html | 251 ++ .../pr-1032/local__to__parent_8hpp.html | 132 + .../pr-1032/local__to__world_8hpp.html | 132 + docs-preview/pr-1032/log_8hpp.html | 239 ++ .../pr-1032/m-dark+documentation.compiled.css | 2925 +++++++++++++++++ docs-preview/pr-1032/map_8hpp.html | 102 + docs-preview/pr-1032/mask_8hpp.html | 134 + docs-preview/pr-1032/mass_8hpp.html | 132 + docs-preview/pr-1032/material_8hpp.html | 136 + docs-preview/pr-1032/meta_8hpp.html | 136 + docs-preview/pr-1032/modules.html | 197 ++ docs-preview/pr-1032/move_8hpp.html | 161 + docs-preview/pr-1032/name_8hpp.html | 134 + docs-preview/pr-1032/namespacecubos.html | 122 + .../pr-1032/namespacecubos_1_1core.html | 148 + .../pr-1032/namespacecubos_1_1core_1_1al.html | 167 + .../namespacecubos_1_1core_1_1al_1_1impl.html | 126 + .../namespacecubos_1_1core_1_1data.html | 163 + ...ecubos_1_1core_1_1data_1_1old_1_1impl.html | 122 + .../namespacecubos_1_1core_1_1ecs.html | 430 +++ ...namespacecubos_1_1core_1_1ecs_1_1impl.html | 103 + .../namespacecubos_1_1core_1_1geom.html | 189 ++ .../pr-1032/namespacecubos_1_1core_1_1gl.html | 496 +++ .../namespacecubos_1_1core_1_1gl_1_1impl.html | 190 ++ .../pr-1032/namespacecubos_1_1core_1_1io.html | 384 +++ .../namespacecubos_1_1core_1_1memory.html | 275 ++ .../namespacecubos_1_1core_1_1reflection.html | 223 ++ .../pr-1032/namespacecubos_1_1engine.html | 660 ++++ .../namespacecubos_1_1engine_1_1impl.html | 122 + docs-preview/pr-1032/namespaces.html | 157 + docs-preview/pr-1032/namespacetesseratos.html | 298 ++ docs-preview/pr-1032/node_8hpp.html | 134 + docs-preview/pr-1032/nullable_8hpp.html | 134 + docs-preview/pr-1032/opt_8hpp.html | 135 + docs-preview/pr-1032/options_8hpp.html | 134 + docs-preview/pr-1032/pages.html | 193 ++ docs-preview/pr-1032/palette_8hpp.html | 140 + docs-preview/pr-1032/pass_8hpp.html | 132 + .../pr-1032/physics__bundle_8hpp.html | 132 + docs-preview/pr-1032/pipe_8hpp.html | 135 + .../pr-1032/plugins_2gravity_8hpp.html | 132 + docs-preview/pr-1032/point__light_8hpp.html | 132 + docs-preview/pr-1032/pool_8hpp.html | 134 + docs-preview/pr-1032/popup_8hpp.html | 140 + docs-preview/pr-1032/position_8hpp.html | 132 + .../pr-1032/previous__position_8hpp.html | 132 + docs-preview/pr-1032/primitives_8hpp.html | 102 + docs-preview/pr-1032/query_2fetcher_8hpp.html | 135 + docs-preview/pr-1032/query_8hpp.html | 135 + docs-preview/pr-1032/reader_8hpp.html | 139 + docs-preview/pr-1032/reflect_8hpp.html | 182 + docs-preview/pr-1032/reflection_8hpp.html | 147 + docs-preview/pr-1032/related_8hpp.html | 134 + docs-preview/pr-1032/render__device_8hpp.html | 596 ++++ docs-preview/pr-1032/renderer_8hpp.html | 156 + docs-preview/pr-1032/renderer_output.png | Bin 0 -> 118782 bytes .../pr-1032/resources_2gravity_8hpp.html | 132 + docs-preview/pr-1032/resources_8hpp.html | 124 + docs-preview/pr-1032/rotation_8hpp.html | 132 + docs-preview/pr-1032/scale_8hpp.html | 132 + docs-preview/pr-1032/scene_2bridge_8hpp.html | 132 + docs-preview/pr-1032/scene_8hpp.html | 132 + docs-preview/pr-1032/screen__picker_8hpp.html | 132 + docs-preview/pr-1032/search-v2.js | 897 +++++ docs-preview/pr-1032/searchdata-v2.js | 2 + .../pr-1032/ser_2serializer_8hpp.html | 134 + docs-preview/pr-1032/settings_8hpp.html | 132 + docs-preview/pr-1032/solver_8hpp.html | 132 + .../sparse__relation_2registry_8hpp.html | 138 + .../pr-1032/sparse__relation_2table_8hpp.html | 142 + docs-preview/pr-1032/spot__light_8hpp.html | 132 + .../pr-1032/standard__archive_8hpp.html | 134 + .../pr-1032/standard__stream_8hpp.html | 134 + docs-preview/pr-1032/stream_8hpp.html | 146 + docs-preview/pr-1032/string_8hpp.html | 102 + .../pr-1032/string__conversion_8hpp.html | 134 + docs-preview/pr-1032/string__view_8hpp.html | 102 + ...tructcubos_1_1core_1_1Logger_1_1Entry.html | 135 + ...ctcubos_1_1core_1_1Logger_1_1Location.html | 158 + ...tcubos_1_1core_1_1Logger_1_1Timestamp.html | 174 + ...re_1_1data_1_1EmbeddedArchive_1_1Data.html | 137 + ...a_1_1EmbeddedArchive_1_1Data_1_1Entry.html | 147 + ...ctcubos_1_1core_1_1ecs_1_1ArchetypeId.html | 173 + ...bos_1_1core_1_1ecs_1_1ArchetypeIdHash.html | 103 + ...ructcubos_1_1core_1_1ecs_1_1Arguments.html | 124 + ...tructcubos_1_1core_1_1ecs_1_1ColumnId.html | 271 ++ ...uctcubos_1_1core_1_1ecs_1_1DataTypeId.html | 169 + ...ubos_1_1core_1_1ecs_1_1DataTypeIdHash.html | 103 + ...ructcubos_1_1core_1_1ecs_1_1DeltaTime.html | 128 + ...re_1_1ecs_1_1Dispatcher_1_1Dependency.html | 103 + ..._1core_1_1ecs_1_1Dispatcher_1_1System.html | 103 + ..._1ecs_1_1Dispatcher_1_1SystemSettings.html | 103 + .../structcubos_1_1core_1_1ecs_1_1Entity.html | 315 ++ ...uctcubos_1_1core_1_1ecs_1_1EntityHash.html | 104 + ...ubos_1_1core_1_1ecs_1_1EphemeralTrait.html | 103 + .../structcubos_1_1core_1_1ecs_1_1Name.html | 123 + ...ryFilter_1_1View_1_1Iterator_1_1Match.html | 123 + ...ructcubos_1_1core_1_1ecs_1_1QueryTerm.html | 532 +++ ...core_1_1ecs_1_1QueryTerm_1_1Component.html | 131 + ...1_1core_1_1ecs_1_1QueryTerm_1_1Entity.html | 123 + ...1core_1_1ecs_1_1QueryTerm_1_1Relation.html | 131 + ...uctcubos_1_1core_1_1ecs_1_1ShouldQuit.html | 124 + ...1core_1_1ecs_1_1SparseRelationTableId.html | 198 ++ ...e_1_1ecs_1_1SparseRelationTableIdHash.html | 103 + ...seRelationTable_1_1Iterator_1_1Output.html | 131 + ...onTable_1_1View_1_1Iterator_1_1Output.html | 131 + ...ubos_1_1core_1_1ecs_1_1SymmetricTrait.html | 104 + ...tcubos_1_1core_1_1ecs_1_1SystemAccess.html | 164 + ...cubos_1_1core_1_1ecs_1_1SystemOptions.html | 123 + ...ructcubos_1_1core_1_1ecs_1_1TreeTrait.html | 104 + ..._1Components_1_1Iterator_1_1Component.html | 127 + ...stComponents_1_1Iterator_1_1Component.html | 127 + ...onstRelations_1_1Iterator_1_1Relation.html | 131 + ..._1_1Relations_1_1Iterator_1_1Relation.html | 131 + .../structcubos_1_1core_1_1geom_1_1AABB.html | 354 ++ .../structcubos_1_1core_1_1geom_1_1Box.html | 195 ++ ...tructcubos_1_1core_1_1geom_1_1Capsule.html | 205 ++ ...cubos_1_1core_1_1geom_1_1Intersection.html | 131 + ...cubos_1_1core_1_1gl_1_1BlendStateDesc.html | 167 + ..._1core_1_1gl_1_1ConstantBufferElement.html | 135 + ...core_1_1gl_1_1ConstantBufferStructure.html | 131 + ...bos_1_1core_1_1gl_1_1CubeMapArrayDesc.html | 147 + ...uctcubos_1_1core_1_1gl_1_1CubeMapDesc.html | 143 + ..._1core_1_1gl_1_1DepthStencilStateDesc.html | 141 + ...1gl_1_1DepthStencilStateDesc_1_1Depth.html | 139 + ...l_1_1DepthStencilStateDesc_1_1Stencil.html | 153 + ...thStencilStateDesc_1_1Stencil_1_1Face.html | 135 + ...ubos_1_1core_1_1gl_1_1FramebufferDesc.html | 164 + ...FramebufferDesc_1_1CubeMapArrayTarget.html | 123 + ...l_1_1FramebufferDesc_1_1CubeMapTarget.html | 127 + ...1FramebufferDesc_1_1FramebufferTarget.html | 123 + ...amebufferDesc_1_1Texture2DArrayTarget.html | 123 + ...1_1FramebufferDesc_1_1Texture2DTarget.html | 123 + ...ubos_1_1core_1_1gl_1_1RasterStateDesc.html | 139 + ...uctcubos_1_1core_1_1gl_1_1SamplerDesc.html | 151 + ...tcubos_1_1core_1_1gl_1_1Texture1DDesc.html | 139 + ...s_1_1core_1_1gl_1_1Texture2DArrayDesc.html | 147 + ...tcubos_1_1core_1_1gl_1_1Texture2DDesc.html | 143 + ...tcubos_1_1core_1_1gl_1_1Texture3DDesc.html | 147 + ...ubos_1_1core_1_1gl_1_1VertexArrayDesc.html | 135 + ...tcubos_1_1core_1_1gl_1_1VertexElement.html | 147 + ...1core_1_1io_1_1GamepadConnectionEvent.html | 127 + ...ctcubos_1_1core_1_1io_1_1GamepadState.html | 190 ++ ...structcubos_1_1core_1_1io_1_1KeyEvent.html | 127 + ...bos_1_1core_1_1io_1_1KeyWithModifiers.html | 103 + ...cubos_1_1core_1_1io_1_1ModifiersEvent.html | 123 + ...bos_1_1core_1_1io_1_1MouseButtonEvent.html | 127 + ...cubos_1_1core_1_1io_1_1MouseMoveEvent.html | 123 + ...bos_1_1core_1_1io_1_1MouseScrollEvent.html | 123 + ...uctcubos_1_1core_1_1io_1_1ResizeEvent.html | 123 + ...tructcubos_1_1core_1_1io_1_1TextEvent.html | 123 + ..._1core_1_1memory_1_1IsLValueReference.html | 115 + ..._1_1core_1_1memory_1_1RemoveReference.html | 136 + ...ait_1_1ConstView_1_1Iterator_1_1Entry.html | 127 + ...aryTrait_1_1View_1_1Iterator_1_1Entry.html | 127 + ...it_1_1ConstView_1_1Iterator_1_1Output.html | 127 + ...dsTrait_1_1View_1_1Iterator_1_1Output.html | 127 + ...ubos_1_1core_1_1reflection_1_1Reflect.html | 116 + ...os_1_1engine_1_1AccumulatedCorrection.html | 123 + ...tructcubos_1_1engine_1_1ActiveCameras.html | 133 + ...cubos_1_1engine_1_1ActiveVoxelPalette.html | 127 + ...bos_1_1engine_1_1AssetMeta_1_1Exclude.html | 123 + ...1_1engine_1_1BaseRenderer_1_1Viewport.html | 103 + ...tcubos_1_1engine_1_1BoxCollisionShape.html | 123 + .../structcubos_1_1engine_1_1Camera.html | 132 + ...os_1_1engine_1_1CapsuleCollisionShape.html | 123 + .../structcubos_1_1engine_1_1ChildOf.html | 103 + .../structcubos_1_1engine_1_1Collider.html | 149 + ...tructcubos_1_1engine_1_1CollidingWith.html | 135 + ...ructcubos_1_1engine_1_1CollisionEvent.html | 139 + .../structcubos_1_1engine_1_1Damping.html | 103 + ...ctcubos_1_1engine_1_1DirectionalLight.html | 128 + ...ructcubos_1_1engine_1_1FixedDeltaTime.html | 103 + .../structcubos_1_1engine_1_1Force.html | 104 + ...bos_1_1engine_1_1FreeCameraController.html | 151 + .../structcubos_1_1engine_1_1Gravity.html | 103 + .../structcubos_1_1engine_1_1Impulse.html | 104 + ...tructcubos_1_1engine_1_1LocalToParent.html | 124 + ...structcubos_1_1engine_1_1LocalToWorld.html | 124 + .../structcubos_1_1engine_1_1Mass.html | 103 + ...tructcubos_1_1engine_1_1PhysicsBundle.html | 103 + .../structcubos_1_1engine_1_1PointLight.html | 132 + .../structcubos_1_1engine_1_1Position.html | 124 + ...ctcubos_1_1engine_1_1PreviousPosition.html | 123 + ...ructcubos_1_1engine_1_1RenderableGrid.html | 132 + ...ubos_1_1engine_1_1RendererEnvironment.html | 127 + ...1_1engine_1_1RendererFrame_1_1DrawCmd.html | 131 + .../structcubos_1_1engine_1_1Rotation.html | 124 + .../structcubos_1_1engine_1_1Scale.html | 124 + .../structcubos_1_1engine_1_1Scene.html | 128 + .../structcubos_1_1engine_1_1SpotLight.html | 140 + .../structcubos_1_1engine_1_1Substeps.html | 103 + .../structcubos_1_1engine_1_1Velocity.html | 104 + .../structcubos_1_1engine_1_1Viewport.html | 104 + ...tructcubos_1_1engine_1_1VoxelMaterial.html | 170 + .../structcubos_1_1engine_1_1VoxelVertex.html | 131 + ...tructtesseratos_1_1AssetSelectedEvent.html | 123 + .../structtesseratos_1_1EntitySelector.html | 127 + docs-preview/pr-1032/substeps_8hpp.html | 132 + .../system_2arguments_2world_8hpp.html | 124 + .../pr-1032/system_2fetcher_8hpp.html | 135 + docs-preview/pr-1032/system_8hpp.html | 135 + docs-preview/pr-1032/tables_8hpp.html | 134 + docs-preview/pr-1032/term_8hpp.html | 158 + docs-preview/pr-1032/thread__pool_8hpp.html | 132 + ...seratos_2asset__explorer_2plugin_8hpp.html | 140 + ...eratos_2collider__gizmos_2plugin_8hpp.html | 130 + ...esseratos_2debug__camera_2plugin_8hpp.html | 130 + ...seratos_2ecs__statistics_2plugin_8hpp.html | 130 + ...ratos_2entity__inspector_2plugin_8hpp.html | 130 + ...eratos_2entity__selector_2plugin_8hpp.html | 140 + ...sseratos_2metrics__panel_2plugin_8hpp.html | 130 + ...2tesseratos_2play__pause_2plugin_8hpp.html | 130 + ...tos_2include_2tesseratos_2plugin_8hpp.html | 130 + ...esseratos_2scene__editor_2plugin_8hpp.html | 130 + ...tos_2settings__inspector_2plugin_8hpp.html | 130 + ...ude_2tesseratos_2toolbox_2plugin_8hpp.html | 140 + ...eratos_2transform__gizmo_2plugin_8hpp.html | 130 + ..._2voxel__palette__editor_2plugin_8hpp.html | 130 + ...eratos_2world__inspector_2plugin_8hpp.html | 130 + docs-preview/pr-1032/type_8hpp.html | 134 + docs-preview/pr-1032/type__map_8hpp.html | 135 + docs-preview/pr-1032/type__registry_8hpp.html | 134 + docs-preview/pr-1032/types_8hpp.html | 142 + .../pr-1032/unordered__bimap_8hpp.html | 135 + docs-preview/pr-1032/unordered__map_8hpp.html | 102 + docs-preview/pr-1032/util_8hpp.html | 136 + docs-preview/pr-1032/uuid_8hpp.html | 102 + docs-preview/pr-1032/vector_8hpp.html | 102 + docs-preview/pr-1032/velocity_8hpp.html | 132 + docs-preview/pr-1032/vertex_8hpp.html | 148 + docs-preview/pr-1032/viewport_8hpp.html | 132 + docs-preview/pr-1032/voxels_output.png | Bin 0 -> 6828 bytes docs-preview/pr-1032/window_8hpp.html | 228 ++ docs-preview/pr-1032/world_8hpp.html | 150 + docs-preview/pr-1032/writer_8hpp.html | 135 + 629 files changed, 124853 insertions(+) create mode 100644 docs-preview/pr-1032/CubosLogo.png create mode 100644 docs-preview/pr-1032/aabb_8hpp.html create mode 100644 docs-preview/pr-1032/access_8hpp.html create mode 100644 docs-preview/pr-1032/accumulated__correction_8hpp.html create mode 100644 docs-preview/pr-1032/action_8hpp.html create mode 100644 docs-preview/pr-1032/annotated.html create mode 100644 docs-preview/pr-1032/any__value_8hpp.html create mode 100644 docs-preview/pr-1032/any__vector_8hpp.html create mode 100644 docs-preview/pr-1032/archetype_8hpp.html create mode 100644 docs-preview/pr-1032/archetype__graph_8hpp.html create mode 100644 docs-preview/pr-1032/archetype__id_8hpp.html create mode 100644 docs-preview/pr-1032/archive_8hpp.html create mode 100644 docs-preview/pr-1032/array_8hpp.html create mode 100644 docs-preview/pr-1032/asset_8hpp.html create mode 100644 docs-preview/pr-1032/assets_2bridge_8hpp.html create mode 100644 docs-preview/pr-1032/assets_8hpp.html create mode 100644 docs-preview/pr-1032/audio__device_8hpp.html create mode 100644 docs-preview/pr-1032/axis_8hpp.html create mode 100644 docs-preview/pr-1032/binary_8hpp.html create mode 100644 docs-preview/pr-1032/bindings_8hpp.html create mode 100644 docs-preview/pr-1032/bloom_8hpp.html create mode 100644 docs-preview/pr-1032/blueprint_8hpp.html create mode 100644 docs-preview/pr-1032/buffer__stream_8hpp.html create mode 100644 docs-preview/pr-1032/camera_8hpp.html create mode 100644 docs-preview/pr-1032/child__of_8hpp.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1Logger.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ThreadPool.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1al_1_1AudioDevice.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1al_1_1impl_1_1Buffer.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1al_1_1impl_1_1Source.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1Archive.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1DebugSerializer.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1Deserializer.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1EmbeddedArchive.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1File.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1FileStream.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1FileSystem.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1JSONDeserializer.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1JSONSerializer.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1Serializer.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1StandardArchive.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1BinaryDeserializer.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1BinarySerializer.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1Context.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1Deserializer.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1JSONDeserializer.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1JSONSerializer.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1Package.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1SerializationMap.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1Serializer.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1Unpackager.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1impl_1_1Packager.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1ArchetypeGraph.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Blueprint.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1CommandBuffer.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Commands.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Cubos.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1DenseTable.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1DenseTableRegistry.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Dispatcher.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1EntityPool.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1EventPipe.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1EventReader.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1EventReader_1_1Iterator.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1EventWriter.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Opt.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Query.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryArchetypeNode.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryData.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryFetcher.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryFilter.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryNode.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryRelatedNode.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1ReadResource.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1ResourceManager.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1SparseRelationTable.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1SparseRelationTableRegistry.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1SparseRelationTableRegistry_1_1TypeIndex.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1System.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1SystemFetcher.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Tables.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1TagBuilder.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1TypeBuilder.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Types.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1World.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1WriteResource.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1Debug.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1RenderDevice.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1BlendState.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1ConstantBuffer.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1CubeMap.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1CubeMapArray.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1DepthStencilState.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Framebuffer.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1IndexBuffer.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1RasterState.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Sampler.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderBindingPoint.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderPipeline.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderStage.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Texture1D.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Texture2D.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Texture2DArray.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Texture3D.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1VertexArray.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1VertexBuffer.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1io_1_1BaseWindow.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1io_1_1Cursor.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1AnyValue.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1AnyVector.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1BufferStream.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1Function_3_01R_07Ts_8_8_8_08_4.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1ReadGuard.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1StandardStream.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1Stream.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1TypeMap.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1UnorderedBimap.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1WriteGuard.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1ArrayTrait.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1ConstructibleTrait.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1ConstructibleTrait_1_1Builder.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1DictionaryTrait.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1EnumTrait.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1FieldsTrait.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1FieldsTrait_1_1AddressOfImpl.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1MaskTrait.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1NullableTrait.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1StringConversionTrait.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1Type.html create mode 100644 docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1TypeRegistry.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1AnyAsset.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1Asset.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1AssetBridge.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1AssetMeta.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1Assets.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1BaseRenderer.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1BinaryBridge.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1DataInspector.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1DeferredRenderer.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1FileBridge.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1Gizmos.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1Gizmos_1_1Gizmo.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1Input.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1InputAction.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1InputAxis.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1InputBindings.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1JSONBridge.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1PostProcessingBloom.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1PostProcessingCopy.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1PostProcessingManager.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1PostProcessingPass.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1RendererFrame.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1SceneBridge.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1ScreenPicker.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1Settings.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1VoxelGrid.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1VoxelPalette.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1VoxelPalette_1_1Iterator.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1impl_1_1RendererGrid.html create mode 100644 docs-preview/pr-1032/classcubos_1_1engine_1_1old_1_1JSONBridge.html create mode 100644 docs-preview/pr-1032/classtesseratos_1_1Toolbox.html create mode 100644 docs-preview/pr-1032/collider_8hpp.html create mode 100644 docs-preview/pr-1032/colliding__with_8hpp.html create mode 100644 docs-preview/pr-1032/collision__event_8hpp.html create mode 100644 docs-preview/pr-1032/column_8hpp.html create mode 100644 docs-preview/pr-1032/command__buffer_8hpp.html create mode 100644 docs-preview/pr-1032/commands_8hpp.html create mode 100644 docs-preview/pr-1032/comparison_8hpp.html create mode 100644 docs-preview/pr-1032/constructible_8hpp.html create mode 100644 docs-preview/pr-1032/constructible__utils_8hpp.html create mode 100644 docs-preview/pr-1032/contribution.html create mode 100644 docs-preview/pr-1032/controller_8hpp.html create mode 100644 docs-preview/pr-1032/copy__pass_8hpp.html create mode 100644 docs-preview/pr-1032/core_2include_2cubos_2core_2data_2des_2json_8hpp.html create mode 100644 docs-preview/pr-1032/core_2include_2cubos_2core_2data_2fs_2file_8hpp.html create mode 100644 docs-preview/pr-1032/core_2include_2cubos_2core_2data_2ser_2json_8hpp.html create mode 100644 docs-preview/pr-1032/core_2include_2cubos_2core_2ecs_2resource_2manager_8hpp.html create mode 100644 docs-preview/pr-1032/core_2include_2cubos_2core_2geom_2box_8hpp.html create mode 100644 docs-preview/pr-1032/core_2include_2cubos_2core_2geom_2capsule_8hpp.html create mode 100644 docs-preview/pr-1032/cstring_8hpp.html create mode 100644 docs-preview/pr-1032/cubos_8hpp.html create mode 100644 docs-preview/pr-1032/cursor_8hpp.html create mode 100644 docs-preview/pr-1032/damping_8hpp.html create mode 100644 docs-preview/pr-1032/data_2ser_2debug_8hpp.html create mode 100644 docs-preview/pr-1032/data_8hpp.html create mode 100644 docs-preview/pr-1032/data__inspector_8hpp.html create mode 100644 docs-preview/pr-1032/deferred__renderer_8hpp.html create mode 100644 docs-preview/pr-1032/dense_2registry_8hpp.html create mode 100644 docs-preview/pr-1032/dense_2table_8hpp.html create mode 100644 docs-preview/pr-1032/des_2deserializer_8hpp.html create mode 100644 docs-preview/pr-1032/dictionary_8hpp.html create mode 100644 docs-preview/pr-1032/dir_00300fcbde38ee57d1255bf5757a56e9.html create mode 100644 docs-preview/pr-1032/dir_043da9b7d60f46877cefd90a49e157c3.html create mode 100644 docs-preview/pr-1032/dir_0835e003fa277f66ce5cf543d578f6a2.html create mode 100644 docs-preview/pr-1032/dir_0b39c986537c7114081f36bbdae17547.html create mode 100644 docs-preview/pr-1032/dir_1849b6590c20a7c40f18c0337f505edf.html create mode 100644 docs-preview/pr-1032/dir_18699a5452817121af2ab0a7c7f1cc3e.html create mode 100644 docs-preview/pr-1032/dir_26a5878ebb5e9988b6ffa6f152301254.html create mode 100644 docs-preview/pr-1032/dir_2a25e2bce65ce0f842dba5b7b3a0e22d.html create mode 100644 docs-preview/pr-1032/dir_2a3f20446d92cb0b384d0cf4f4d26d60.html create mode 100644 docs-preview/pr-1032/dir_3504744c369d3ac8de67ffae1d44d2b4.html create mode 100644 docs-preview/pr-1032/dir_3764e76d8ec4e739fc24b5bb90adc3af.html create mode 100644 docs-preview/pr-1032/dir_38aac728ad33877355e223e23ac4ab7a.html create mode 100644 docs-preview/pr-1032/dir_38dc3202db19a8deaf7e1516278a105d.html create mode 100644 docs-preview/pr-1032/dir_38e9fb064544086d3594e70a41f6b257.html create mode 100644 docs-preview/pr-1032/dir_3e72b743a5c62924583b661b2c5525f9.html create mode 100644 docs-preview/pr-1032/dir_4149d46e02eca8eae23b140f2d5369cf.html create mode 100644 docs-preview/pr-1032/dir_459dda10180a6131eb62bc74e02d0b6e.html create mode 100644 docs-preview/pr-1032/dir_46c6a4a310169812045f09ba6135aa36.html create mode 100644 docs-preview/pr-1032/dir_56f03f6936f99956d731d9e98d524876.html create mode 100644 docs-preview/pr-1032/dir_57aff98960b24114775613a58ec786ad.html create mode 100644 docs-preview/pr-1032/dir_5f701044e65d6c264a6c1dc66b1052c2.html create mode 100644 docs-preview/pr-1032/dir_60b52edecd3c8caac6b76bd0bb2ba3ce.html create mode 100644 docs-preview/pr-1032/dir_64a2fed96ae76f57d94061df7c919db3.html create mode 100644 docs-preview/pr-1032/dir_672562f1eb3ea0be7f3aa3e89e72ecd2.html create mode 100644 docs-preview/pr-1032/dir_696376665c0dc3694e56f168acfac677.html create mode 100644 docs-preview/pr-1032/dir_69c88e5af9faf72eaf159ee3e83d9db2.html create mode 100644 docs-preview/pr-1032/dir_6c4c9e5f04768b915dbc2edba08d4f5c.html create mode 100644 docs-preview/pr-1032/dir_6c897dd97bedf3914ee8a4d9f7f6549c.html create mode 100644 docs-preview/pr-1032/dir_6e7fefd5d33489e77ed24a475a1b2d04.html create mode 100644 docs-preview/pr-1032/dir_7376bacbd9e6243f425bd4c56d48edd9.html create mode 100644 docs-preview/pr-1032/dir_73cd920be1d9b25db5feb4d2a202c641.html create mode 100644 docs-preview/pr-1032/dir_79f402fdd7bbb1d73f9fd1aa85f618da.html create mode 100644 docs-preview/pr-1032/dir_85f1b5bc6fb8e602e74068211760bfae.html create mode 100644 docs-preview/pr-1032/dir_8711f680e2d25dedddc79c2be2b1fda2.html create mode 100644 docs-preview/pr-1032/dir_87a7847ee77970235330560d79c37ce0.html create mode 100644 docs-preview/pr-1032/dir_8e5f84d20b1aa89c94160461e78e26c4.html create mode 100644 docs-preview/pr-1032/dir_95549d37735ad5b142799f042eef0d37.html create mode 100644 docs-preview/pr-1032/dir_983a8c8cc77436ec11afd1f0c4e2ef1f.html create mode 100644 docs-preview/pr-1032/dir_9b04cf786b414c0d644db09287f665e6.html create mode 100644 docs-preview/pr-1032/dir_9bdaf8f561be1ffd03f616379797b70b.html create mode 100644 docs-preview/pr-1032/dir_9f228de11f2fc2633236213a3ef5c992.html create mode 100644 docs-preview/pr-1032/dir_a1cc7ffab82768b4f8702a03c85b938c.html create mode 100644 docs-preview/pr-1032/dir_ae52c41efe1aaae7a392cb947b223e9f.html create mode 100644 docs-preview/pr-1032/dir_b6daa990b896c2c0c53126427e4d978d.html create mode 100644 docs-preview/pr-1032/dir_bafb7af0e03e95b24a45ff63060ab57b.html create mode 100644 docs-preview/pr-1032/dir_bc092de7c4be29a20e8c6c4d7f3164b3.html create mode 100644 docs-preview/pr-1032/dir_bd9be39c2ccf4132268583193b02b48c.html create mode 100644 docs-preview/pr-1032/dir_c1b5957eb0512b9978230dfb34d9655b.html create mode 100644 docs-preview/pr-1032/dir_c1deef5baf41393ad8a994c3fd53e62f.html create mode 100644 docs-preview/pr-1032/dir_c26f946019c5d6937d16d4e3329f697e.html create mode 100644 docs-preview/pr-1032/dir_c3ed6a1192e5b1b0ac8a4baf7bd6e376.html create mode 100644 docs-preview/pr-1032/dir_c4311188e9cc606330f5e3e0b9dd5059.html create mode 100644 docs-preview/pr-1032/dir_ce4a27e99b2102cfb79fc5b09181f4e6.html create mode 100644 docs-preview/pr-1032/dir_d28a4e16d9deb548c857866e71f89c35.html create mode 100644 docs-preview/pr-1032/dir_db86702e1371d7558db3699dd3786a14.html create mode 100644 docs-preview/pr-1032/dir_f4414684a5bb1e1b8e9ba236e8bdb594.html create mode 100644 docs-preview/pr-1032/dir_f6f65ff657bd34b22e5078310628f4e7.html create mode 100644 docs-preview/pr-1032/dir_fc8110eaf6ef50e82d21b749d50a1849.html create mode 100644 docs-preview/pr-1032/directional__light_8hpp.html create mode 100644 docs-preview/pr-1032/dispatcher_8hpp.html create mode 100644 docs-preview/pr-1032/embedded__archive_8hpp.html create mode 100644 docs-preview/pr-1032/endianness_8hpp.html create mode 100644 docs-preview/pr-1032/engine_2include_2cubos_2engine_2assets_2bridges_2file_8hpp.html create mode 100644 docs-preview/pr-1032/engine_2include_2cubos_2engine_2assets_2bridges_2json_8hpp.html create mode 100644 docs-preview/pr-1032/engine_2include_2cubos_2engine_2assets_2bridges_2old_2json_8hpp.html create mode 100644 docs-preview/pr-1032/engine_2include_2cubos_2engine_2assets_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/engine_2include_2cubos_2engine_2collisions_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/engine_2include_2cubos_2engine_2collisions_2shapes_2box_8hpp.html create mode 100644 docs-preview/pr-1032/engine_2include_2cubos_2engine_2collisions_2shapes_2capsule_8hpp.html create mode 100644 docs-preview/pr-1032/engine_2include_2cubos_2engine_2fixed__step_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/engine_2include_2cubos_2engine_2gizmos_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/engine_2include_2cubos_2engine_2imgui_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/engine_2include_2cubos_2engine_2input_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/engine_2include_2cubos_2engine_2physics_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/engine_2include_2cubos_2engine_2renderer_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/engine_2include_2cubos_2engine_2renderer_2pps_2manager_8hpp.html create mode 100644 docs-preview/pr-1032/engine_2include_2cubos_2engine_2scene_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/engine_2include_2cubos_2engine_2screen__picker_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/engine_2include_2cubos_2engine_2settings_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/engine_2include_2cubos_2engine_2splitscreen_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/engine_2include_2cubos_2engine_2transform_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/engine_2include_2cubos_2engine_2utils_2free__camera_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/engine_2include_2cubos_2engine_2voxels_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/engine_2include_2cubos_2engine_2window_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/entity_8hpp.html create mode 100644 docs-preview/pr-1032/enum_8hpp.html create mode 100644 docs-preview/pr-1032/environment_8hpp.html create mode 100644 docs-preview/pr-1032/examples-core-data-des-custom.html create mode 100644 docs-preview/pr-1032/examples-core-data-des.html create mode 100644 docs-preview/pr-1032/examples-core-data-ser-custom.html create mode 100644 docs-preview/pr-1032/examples-core-data-ser-json.html create mode 100644 docs-preview/pr-1032/examples-core-data-ser.html create mode 100644 docs-preview/pr-1032/examples-core-data.html create mode 100644 docs-preview/pr-1032/examples-core-logging.html create mode 100644 docs-preview/pr-1032/examples-core-reflection-basic.html create mode 100644 docs-preview/pr-1032/examples-core-reflection-traits-array.html create mode 100644 docs-preview/pr-1032/examples-core-reflection-traits-constructible.html create mode 100644 docs-preview/pr-1032/examples-core-reflection-traits-dictionary.html create mode 100644 docs-preview/pr-1032/examples-core-reflection-traits-enum.html create mode 100644 docs-preview/pr-1032/examples-core-reflection-traits-fields.html create mode 100644 docs-preview/pr-1032/examples-core-reflection-traits-mask.html create mode 100644 docs-preview/pr-1032/examples-core-reflection-traits-nullable.html create mode 100644 docs-preview/pr-1032/examples-core-reflection-traits-string-conversion.html create mode 100644 docs-preview/pr-1032/examples-core-reflection.html create mode 100644 docs-preview/pr-1032/examples-core.html create mode 100644 docs-preview/pr-1032/examples-engine-assets-bridge.html create mode 100644 docs-preview/pr-1032/examples-engine-assets-json.html create mode 100644 docs-preview/pr-1032/examples-engine-assets-saving.html create mode 100644 docs-preview/pr-1032/examples-engine-assets.html create mode 100644 docs-preview/pr-1032/examples-engine-events.html create mode 100644 docs-preview/pr-1032/examples-engine-gizmos.html create mode 100644 docs-preview/pr-1032/examples-engine-hello-cubos.html create mode 100644 docs-preview/pr-1032/examples-engine-imgui.html create mode 100644 docs-preview/pr-1032/examples-engine-input.html create mode 100644 docs-preview/pr-1032/examples-engine-renderer.html create mode 100644 docs-preview/pr-1032/examples-engine-scene.html create mode 100644 docs-preview/pr-1032/examples-engine-settings.html create mode 100644 docs-preview/pr-1032/examples-engine-voxels.html create mode 100644 docs-preview/pr-1032/examples-engine.html create mode 100644 docs-preview/pr-1032/examples.html create mode 100644 docs-preview/pr-1032/favicon-dark.png create mode 100644 docs-preview/pr-1032/features-ecs.html create mode 100644 docs-preview/pr-1032/features-plugins.html create mode 100644 docs-preview/pr-1032/features-quadrados.html create mode 100644 docs-preview/pr-1032/features-queries.html create mode 100644 docs-preview/pr-1032/features.html create mode 100644 docs-preview/pr-1032/fields_8hpp.html create mode 100644 docs-preview/pr-1032/file__stream_8hpp.html create mode 100644 docs-preview/pr-1032/file__system_8hpp.html create mode 100644 docs-preview/pr-1032/files.html create mode 100644 docs-preview/pr-1032/filter_8hpp.html create mode 100644 docs-preview/pr-1032/fixed__delta__time_8hpp.html create mode 100644 docs-preview/pr-1032/force_8hpp.html create mode 100644 docs-preview/pr-1032/frame_8hpp.html create mode 100644 docs-preview/pr-1032/function_8hpp.html create mode 100644 docs-preview/pr-1032/gamepad_8hpp.html create mode 100644 docs-preview/pr-1032/getting-started.html create mode 100644 docs-preview/pr-1032/gizmos_8hpp.html create mode 100644 docs-preview/pr-1032/gl_2debug_8hpp.html create mode 100644 docs-preview/pr-1032/glm_8hpp.html create mode 100644 docs-preview/pr-1032/grid_8hpp.html create mode 100644 docs-preview/pr-1032/group__assets-plugin.html create mode 100644 docs-preview/pr-1032/group__collisions-plugin.html create mode 100644 docs-preview/pr-1032/group__core-al.html create mode 100644 docs-preview/pr-1032/group__core-data-des.html create mode 100644 docs-preview/pr-1032/group__core-data-fs.html create mode 100644 docs-preview/pr-1032/group__core-data-ser.html create mode 100644 docs-preview/pr-1032/group__core-data.html create mode 100644 docs-preview/pr-1032/group__core-ecs-entity.html create mode 100644 docs-preview/pr-1032/group__core-ecs-query.html create mode 100644 docs-preview/pr-1032/group__core-ecs-resource.html create mode 100644 docs-preview/pr-1032/group__core-ecs-system-arguments.html create mode 100644 docs-preview/pr-1032/group__core-ecs-system.html create mode 100644 docs-preview/pr-1032/group__core-ecs-table.html create mode 100644 docs-preview/pr-1032/group__core-ecs.html create mode 100644 docs-preview/pr-1032/group__core-geom.html create mode 100644 docs-preview/pr-1032/group__core-gl.html create mode 100644 docs-preview/pr-1032/group__core-io.html create mode 100644 docs-preview/pr-1032/group__core-memory.html create mode 100644 docs-preview/pr-1032/group__core-reflection.html create mode 100644 docs-preview/pr-1032/group__core.html create mode 100644 docs-preview/pr-1032/group__engine.html create mode 100644 docs-preview/pr-1032/group__fixed-step-plugin.html create mode 100644 docs-preview/pr-1032/group__free-camera-plugin.html create mode 100644 docs-preview/pr-1032/group__gizmos-plugin.html create mode 100644 docs-preview/pr-1032/group__imgui-plugin.html create mode 100644 docs-preview/pr-1032/group__input-plugin.html create mode 100644 docs-preview/pr-1032/group__physics-gravity-plugin.html create mode 100644 docs-preview/pr-1032/group__physics-plugin.html create mode 100644 docs-preview/pr-1032/group__physics-solver-plugin.html create mode 100644 docs-preview/pr-1032/group__renderer-plugin.html create mode 100644 docs-preview/pr-1032/group__scene-plugin.html create mode 100644 docs-preview/pr-1032/group__screen-picker-plugin.html create mode 100644 docs-preview/pr-1032/group__settings-plugin.html create mode 100644 docs-preview/pr-1032/group__splitscreen-plugin.html create mode 100644 docs-preview/pr-1032/group__tesseratos-asset-explorer-plugin.html create mode 100644 docs-preview/pr-1032/group__tesseratos-collider-gizmos-plugin.html create mode 100644 docs-preview/pr-1032/group__tesseratos-debug-camera-plugin.html create mode 100644 docs-preview/pr-1032/group__tesseratos-ecs-statistics-plugin.html create mode 100644 docs-preview/pr-1032/group__tesseratos-entity-inspector-plugin.html create mode 100644 docs-preview/pr-1032/group__tesseratos-entity-selector-plugin.html create mode 100644 docs-preview/pr-1032/group__tesseratos-metrics-panel-plugin.html create mode 100644 docs-preview/pr-1032/group__tesseratos-play-pause-plugin.html create mode 100644 docs-preview/pr-1032/group__tesseratos-scene-editor-plugin.html create mode 100644 docs-preview/pr-1032/group__tesseratos-settings-inspector-plugin.html create mode 100644 docs-preview/pr-1032/group__tesseratos-toolbox-plugin.html create mode 100644 docs-preview/pr-1032/group__tesseratos-transform-gizmo-plugin.html create mode 100644 docs-preview/pr-1032/group__tesseratos-voxel-palette-editor-plugin.html create mode 100644 docs-preview/pr-1032/group__tesseratos-world-inspector-plugin.html create mode 100644 docs-preview/pr-1032/group__tesseratos.html create mode 100644 docs-preview/pr-1032/group__transform-plugin.html create mode 100644 docs-preview/pr-1032/group__voxels-plugin.html create mode 100644 docs-preview/pr-1032/group__window-plugin.html create mode 100644 docs-preview/pr-1032/guards_8hpp.html create mode 100644 docs-preview/pr-1032/hash_8hpp.html create mode 100644 docs-preview/pr-1032/id_8hpp.html create mode 100644 docs-preview/pr-1032/img1.png create mode 100644 docs-preview/pr-1032/img2.png create mode 100644 docs-preview/pr-1032/impulse_8hpp.html create mode 100644 docs-preview/pr-1032/index.html create mode 100644 docs-preview/pr-1032/input_8hpp.html create mode 100644 docs-preview/pr-1032/intersections_8hpp.html create mode 100644 docs-preview/pr-1032/keyboard_8hpp.html create mode 100644 docs-preview/pr-1032/local__to__parent_8hpp.html create mode 100644 docs-preview/pr-1032/local__to__world_8hpp.html create mode 100644 docs-preview/pr-1032/log_8hpp.html create mode 100644 docs-preview/pr-1032/m-dark+documentation.compiled.css create mode 100644 docs-preview/pr-1032/map_8hpp.html create mode 100644 docs-preview/pr-1032/mask_8hpp.html create mode 100644 docs-preview/pr-1032/mass_8hpp.html create mode 100644 docs-preview/pr-1032/material_8hpp.html create mode 100644 docs-preview/pr-1032/meta_8hpp.html create mode 100644 docs-preview/pr-1032/modules.html create mode 100644 docs-preview/pr-1032/move_8hpp.html create mode 100644 docs-preview/pr-1032/name_8hpp.html create mode 100644 docs-preview/pr-1032/namespacecubos.html create mode 100644 docs-preview/pr-1032/namespacecubos_1_1core.html create mode 100644 docs-preview/pr-1032/namespacecubos_1_1core_1_1al.html create mode 100644 docs-preview/pr-1032/namespacecubos_1_1core_1_1al_1_1impl.html create mode 100644 docs-preview/pr-1032/namespacecubos_1_1core_1_1data.html create mode 100644 docs-preview/pr-1032/namespacecubos_1_1core_1_1data_1_1old_1_1impl.html create mode 100644 docs-preview/pr-1032/namespacecubos_1_1core_1_1ecs.html create mode 100644 docs-preview/pr-1032/namespacecubos_1_1core_1_1ecs_1_1impl.html create mode 100644 docs-preview/pr-1032/namespacecubos_1_1core_1_1geom.html create mode 100644 docs-preview/pr-1032/namespacecubos_1_1core_1_1gl.html create mode 100644 docs-preview/pr-1032/namespacecubos_1_1core_1_1gl_1_1impl.html create mode 100644 docs-preview/pr-1032/namespacecubos_1_1core_1_1io.html create mode 100644 docs-preview/pr-1032/namespacecubos_1_1core_1_1memory.html create mode 100644 docs-preview/pr-1032/namespacecubos_1_1core_1_1reflection.html create mode 100644 docs-preview/pr-1032/namespacecubos_1_1engine.html create mode 100644 docs-preview/pr-1032/namespacecubos_1_1engine_1_1impl.html create mode 100644 docs-preview/pr-1032/namespaces.html create mode 100644 docs-preview/pr-1032/namespacetesseratos.html create mode 100644 docs-preview/pr-1032/node_8hpp.html create mode 100644 docs-preview/pr-1032/nullable_8hpp.html create mode 100644 docs-preview/pr-1032/opt_8hpp.html create mode 100644 docs-preview/pr-1032/options_8hpp.html create mode 100644 docs-preview/pr-1032/pages.html create mode 100644 docs-preview/pr-1032/palette_8hpp.html create mode 100644 docs-preview/pr-1032/pass_8hpp.html create mode 100644 docs-preview/pr-1032/physics__bundle_8hpp.html create mode 100644 docs-preview/pr-1032/pipe_8hpp.html create mode 100644 docs-preview/pr-1032/plugins_2gravity_8hpp.html create mode 100644 docs-preview/pr-1032/point__light_8hpp.html create mode 100644 docs-preview/pr-1032/pool_8hpp.html create mode 100644 docs-preview/pr-1032/popup_8hpp.html create mode 100644 docs-preview/pr-1032/position_8hpp.html create mode 100644 docs-preview/pr-1032/previous__position_8hpp.html create mode 100644 docs-preview/pr-1032/primitives_8hpp.html create mode 100644 docs-preview/pr-1032/query_2fetcher_8hpp.html create mode 100644 docs-preview/pr-1032/query_8hpp.html create mode 100644 docs-preview/pr-1032/reader_8hpp.html create mode 100644 docs-preview/pr-1032/reflect_8hpp.html create mode 100644 docs-preview/pr-1032/reflection_8hpp.html create mode 100644 docs-preview/pr-1032/related_8hpp.html create mode 100644 docs-preview/pr-1032/render__device_8hpp.html create mode 100644 docs-preview/pr-1032/renderer_8hpp.html create mode 100644 docs-preview/pr-1032/renderer_output.png create mode 100644 docs-preview/pr-1032/resources_2gravity_8hpp.html create mode 100644 docs-preview/pr-1032/resources_8hpp.html create mode 100644 docs-preview/pr-1032/rotation_8hpp.html create mode 100644 docs-preview/pr-1032/scale_8hpp.html create mode 100644 docs-preview/pr-1032/scene_2bridge_8hpp.html create mode 100644 docs-preview/pr-1032/scene_8hpp.html create mode 100644 docs-preview/pr-1032/screen__picker_8hpp.html create mode 100644 docs-preview/pr-1032/search-v2.js create mode 100644 docs-preview/pr-1032/searchdata-v2.js create mode 100644 docs-preview/pr-1032/ser_2serializer_8hpp.html create mode 100644 docs-preview/pr-1032/settings_8hpp.html create mode 100644 docs-preview/pr-1032/solver_8hpp.html create mode 100644 docs-preview/pr-1032/sparse__relation_2registry_8hpp.html create mode 100644 docs-preview/pr-1032/sparse__relation_2table_8hpp.html create mode 100644 docs-preview/pr-1032/spot__light_8hpp.html create mode 100644 docs-preview/pr-1032/standard__archive_8hpp.html create mode 100644 docs-preview/pr-1032/standard__stream_8hpp.html create mode 100644 docs-preview/pr-1032/stream_8hpp.html create mode 100644 docs-preview/pr-1032/string_8hpp.html create mode 100644 docs-preview/pr-1032/string__conversion_8hpp.html create mode 100644 docs-preview/pr-1032/string__view_8hpp.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1Logger_1_1Entry.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1Logger_1_1Location.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1Logger_1_1Timestamp.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1data_1_1EmbeddedArchive_1_1Data.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1data_1_1EmbeddedArchive_1_1Data_1_1Entry.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1ArchetypeId.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1ArchetypeIdHash.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Arguments.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1ColumnId.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1DataTypeId.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1DataTypeIdHash.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1DeltaTime.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Dispatcher_1_1Dependency.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Dispatcher_1_1System.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Dispatcher_1_1SystemSettings.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Entity.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1EntityHash.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1EphemeralTrait.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Name.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1QueryFilter_1_1View_1_1Iterator_1_1Match.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1QueryTerm.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1QueryTerm_1_1Component.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1QueryTerm_1_1Entity.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1QueryTerm_1_1Relation.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1ShouldQuit.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SparseRelationTableId.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SparseRelationTableIdHash.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SparseRelationTable_1_1Iterator_1_1Output.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SparseRelationTable_1_1View_1_1Iterator_1_1Output.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SymmetricTrait.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SystemAccess.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SystemOptions.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1TreeTrait.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1World_1_1Components_1_1Iterator_1_1Component.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1World_1_1ConstComponents_1_1Iterator_1_1Component.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1World_1_1ConstRelations_1_1Iterator_1_1Relation.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1World_1_1Relations_1_1Iterator_1_1Relation.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1geom_1_1AABB.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1geom_1_1Box.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1geom_1_1Capsule.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1geom_1_1Intersection.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1BlendStateDesc.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1ConstantBufferElement.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1ConstantBufferStructure.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1CubeMapArrayDesc.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1CubeMapDesc.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Depth.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Stencil.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Stencil_1_1Face.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1CubeMapArrayTarget.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1CubeMapTarget.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1FramebufferTarget.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1Texture2DArrayTarget.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1Texture2DTarget.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1RasterStateDesc.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1SamplerDesc.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1Texture1DDesc.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1Texture2DArrayDesc.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1Texture2DDesc.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1Texture3DDesc.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1VertexArrayDesc.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1VertexElement.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1GamepadConnectionEvent.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1GamepadState.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1KeyEvent.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1KeyWithModifiers.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1ModifiersEvent.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1MouseButtonEvent.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1MouseMoveEvent.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1MouseScrollEvent.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1ResizeEvent.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1TextEvent.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1memory_1_1IsLValueReference.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1memory_1_1RemoveReference.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1reflection_1_1DictionaryTrait_1_1ConstView_1_1Iterator_1_1Entry.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1reflection_1_1DictionaryTrait_1_1View_1_1Iterator_1_1Entry.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1reflection_1_1FieldsTrait_1_1ConstView_1_1Iterator_1_1Output.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1reflection_1_1FieldsTrait_1_1View_1_1Iterator_1_1Output.html create mode 100644 docs-preview/pr-1032/structcubos_1_1core_1_1reflection_1_1Reflect.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1AccumulatedCorrection.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1ActiveCameras.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1ActiveVoxelPalette.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1AssetMeta_1_1Exclude.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1BaseRenderer_1_1Viewport.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1BoxCollisionShape.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1Camera.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1CapsuleCollisionShape.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1ChildOf.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1Collider.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1CollidingWith.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1CollisionEvent.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1Damping.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1DirectionalLight.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1FixedDeltaTime.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1Force.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1FreeCameraController.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1Gravity.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1Impulse.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1LocalToParent.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1LocalToWorld.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1Mass.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1PhysicsBundle.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1PointLight.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1Position.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1PreviousPosition.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1RenderableGrid.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1RendererEnvironment.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1RendererFrame_1_1DrawCmd.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1Rotation.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1Scale.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1Scene.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1SpotLight.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1Substeps.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1Velocity.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1Viewport.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1VoxelMaterial.html create mode 100644 docs-preview/pr-1032/structcubos_1_1engine_1_1VoxelVertex.html create mode 100644 docs-preview/pr-1032/structtesseratos_1_1AssetSelectedEvent.html create mode 100644 docs-preview/pr-1032/structtesseratos_1_1EntitySelector.html create mode 100644 docs-preview/pr-1032/substeps_8hpp.html create mode 100644 docs-preview/pr-1032/system_2arguments_2world_8hpp.html create mode 100644 docs-preview/pr-1032/system_2fetcher_8hpp.html create mode 100644 docs-preview/pr-1032/system_8hpp.html create mode 100644 docs-preview/pr-1032/tables_8hpp.html create mode 100644 docs-preview/pr-1032/term_8hpp.html create mode 100644 docs-preview/pr-1032/thread__pool_8hpp.html create mode 100644 docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2asset__explorer_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2collider__gizmos_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2debug__camera_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2ecs__statistics_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2entity__inspector_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2entity__selector_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2metrics__panel_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2play__pause_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2scene__editor_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2settings__inspector_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2toolbox_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2transform__gizmo_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2voxel__palette__editor_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2world__inspector_2plugin_8hpp.html create mode 100644 docs-preview/pr-1032/type_8hpp.html create mode 100644 docs-preview/pr-1032/type__map_8hpp.html create mode 100644 docs-preview/pr-1032/type__registry_8hpp.html create mode 100644 docs-preview/pr-1032/types_8hpp.html create mode 100644 docs-preview/pr-1032/unordered__bimap_8hpp.html create mode 100644 docs-preview/pr-1032/unordered__map_8hpp.html create mode 100644 docs-preview/pr-1032/util_8hpp.html create mode 100644 docs-preview/pr-1032/uuid_8hpp.html create mode 100644 docs-preview/pr-1032/vector_8hpp.html create mode 100644 docs-preview/pr-1032/velocity_8hpp.html create mode 100644 docs-preview/pr-1032/vertex_8hpp.html create mode 100644 docs-preview/pr-1032/viewport_8hpp.html create mode 100644 docs-preview/pr-1032/voxels_output.png create mode 100644 docs-preview/pr-1032/window_8hpp.html create mode 100644 docs-preview/pr-1032/world_8hpp.html create mode 100644 docs-preview/pr-1032/writer_8hpp.html diff --git a/docs-preview/pr-1032/CubosLogo.png b/docs-preview/pr-1032/CubosLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..fd0cc2a08280d6020b487d4f5824b72345a4f882 GIT binary patch literal 18999 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 Q4E{}@Hf!opf9aP02c=FaoB#j- literal 0 HcmV?d00001 diff --git a/docs-preview/pr-1032/aabb_8hpp.html b/docs-preview/pr-1032/aabb_8hpp.html new file mode 100644 index 000000000..6bd2aff28 --- /dev/null +++ b/docs-preview/pr-1032/aabb_8hpp.html @@ -0,0 +1,136 @@ + + + + + core/geom/aabb.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/access_8hpp.html b/docs-preview/pr-1032/access_8hpp.html new file mode 100644 index 000000000..e5db60758 --- /dev/null +++ b/docs-preview/pr-1032/access_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/ecs/system/access.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/accumulated__correction_8hpp.html b/docs-preview/pr-1032/accumulated__correction_8hpp.html new file mode 100644 index 000000000..ceeaf2ab7 --- /dev/null +++ b/docs-preview/pr-1032/accumulated__correction_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/physics/components/accumulated_correction.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/action_8hpp.html b/docs-preview/pr-1032/action_8hpp.html new file mode 100644 index 000000000..fceadbcea --- /dev/null +++ b/docs-preview/pr-1032/action_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/input/action.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/annotated.html b/docs-preview/pr-1032/annotated.html new file mode 100644 index 000000000..bdfadceee --- /dev/null +++ b/docs-preview/pr-1032/annotated.html @@ -0,0 +1,555 @@ + + + + + CUBOS. Docs + + + + + + + +
+
+
+
+
+

Classes

+
    +
  • + namespace cubos CUBOS. libraries namespace. +
      + + +
    +
  • +
  • + namespace tesseratos Tesseratos module. +
      +
    • struct AssetSelectedEvent Event sent when an asset is selected.
    • +
    • struct EntitySelector Resource which identifies the currently selected entity.
    • +
    • class Toolbox final Resource which manages other tools windows.
    • +
    +
  • +
+ +
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/any__value_8hpp.html b/docs-preview/pr-1032/any__value_8hpp.html new file mode 100644 index 000000000..9e838fd8a --- /dev/null +++ b/docs-preview/pr-1032/any__value_8hpp.html @@ -0,0 +1,136 @@ + + + + + core/memory/any_value.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/any__vector_8hpp.html b/docs-preview/pr-1032/any__vector_8hpp.html new file mode 100644 index 000000000..79ea9dc22 --- /dev/null +++ b/docs-preview/pr-1032/any__vector_8hpp.html @@ -0,0 +1,136 @@ + + + + + core/memory/any_vector.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/memory/any_vector.hpp file +

+

Class cubos::core::memory::AnyVector.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::reflection
+
Reflection module.
+
namespace cubos::core::memory
+
Memory module.
+
+
+
+

Classes

+
+
+ class cubos::core::memory::AnyVector +
+
Stores a dynamically sized array of blobs of a given reflected type.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/archetype_8hpp.html b/docs-preview/pr-1032/archetype_8hpp.html new file mode 100644 index 000000000..6661ae1b3 --- /dev/null +++ b/docs-preview/pr-1032/archetype_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/ecs/query/node/archetype.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/archetype__graph_8hpp.html b/docs-preview/pr-1032/archetype__graph_8hpp.html new file mode 100644 index 000000000..fe73a7b7b --- /dev/null +++ b/docs-preview/pr-1032/archetype__graph_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/ecs/entity/archetype_graph.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/archetype__id_8hpp.html b/docs-preview/pr-1032/archetype__id_8hpp.html new file mode 100644 index 000000000..838ba6f06 --- /dev/null +++ b/docs-preview/pr-1032/archetype__id_8hpp.html @@ -0,0 +1,138 @@ + + + + + core/ecs/entity/archetype_id.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/archive_8hpp.html b/docs-preview/pr-1032/archive_8hpp.html new file mode 100644 index 000000000..35c085d49 --- /dev/null +++ b/docs-preview/pr-1032/archive_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/data/fs/archive.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/array_8hpp.html b/docs-preview/pr-1032/array_8hpp.html new file mode 100644 index 000000000..e5d6858fc --- /dev/null +++ b/docs-preview/pr-1032/array_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/reflection/traits/array.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/asset_8hpp.html b/docs-preview/pr-1032/asset_8hpp.html new file mode 100644 index 000000000..815b20ca4 --- /dev/null +++ b/docs-preview/pr-1032/asset_8hpp.html @@ -0,0 +1,141 @@ + + + + + engine/assets/asset.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ engine/assets/asset.hpp file +

+

Classes cubos::engine::AnyAsset and cubos::engine::Asset.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::data
+
Data module.
+
namespace cubos::engine
+
Engine module.
+
+
+
+

Classes

+
+
+ class cubos::engine::AnyAsset +
+
Handle to an asset of any type. May either be weak or strong. Weak handles do not guarantee the asset is loaded, while strong handles do.
+
+
template<core::reflection::Reflectable T>
+ class cubos::engine::Asset +
+
Handle to an asset of a specific type.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/assets_2bridge_8hpp.html b/docs-preview/pr-1032/assets_2bridge_8hpp.html new file mode 100644 index 000000000..65fb1536e --- /dev/null +++ b/docs-preview/pr-1032/assets_2bridge_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/assets/bridge.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/assets_8hpp.html b/docs-preview/pr-1032/assets_8hpp.html new file mode 100644 index 000000000..d9f56bd9f --- /dev/null +++ b/docs-preview/pr-1032/assets_8hpp.html @@ -0,0 +1,156 @@ + + + + + engine/assets/assets.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ engine/assets/assets.hpp file +

+

Resource cubos::engine::Assets.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::engine
+
Engine module.
+
+
+
+

Classes

+
+
+ class cubos::engine::Assets +
+
Resource which manages all assets. Responsible for loading and unloading assets, storing them in memory, and providing access to them.
+
+
+
+

Typedefs

+
+
+ using AssetMetaRead = core::memory::ReadGuard<AssetMeta, std::shared_lock<std::shared_mutex>> +
+
Read-only guard for an asset's metadata.
+
+ using AssetMetaWrite = core::memory::WriteGuard<AssetMeta, std::unique_lock<std::shared_mutex>> +
+
Read-write guard for an asset's metadata.
+
+
template<typename T>
+ using AssetRead = core::memory::ReadGuard<T, std::shared_lock<std::shared_mutex>> +
+
Read-only guard for an asset's data.
+
+
template<typename T>
+ using AssetWrite = core::memory::WriteGuard<T, std::unique_lock<std::shared_mutex>> +
+
Read-write guard for an asset's data.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/audio__device_8hpp.html b/docs-preview/pr-1032/audio__device_8hpp.html new file mode 100644 index 000000000..bfee18b5d --- /dev/null +++ b/docs-preview/pr-1032/audio__device_8hpp.html @@ -0,0 +1,171 @@ + + + + + core/al/audio_device.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/al/audio_device.hpp file +

+

Class cubos::core::al::AudioDevice and related types.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::al
+
Audio module.
+
namespace cubos::core::al::impl
+
Namespace to store the abstract types implemented by the audio device implementations.
+
+
+
+

Classes

+
+
+ class cubos::core::al::AudioDevice +
+
Audio device interface used to wrap low-level audio rendering APIs.
+
+ class cubos::core::al::impl::Buffer +
+
Abstract audio buffer.
+
+ class cubos::core::al::impl::Source +
+
Abstract audio source.
+
+
+
+

Enums

+
+
+ enum class Format { Mono8, + Mono16, + Stereo8, + Stereo16 } +
+
Possible audio formats.
+
+
+
+

Typedefs

+
+
+ using Buffer = std::shared_ptr<impl::Buffer> +
+
Handle to an audio buffer.
+
+ using Source = std::shared_ptr<impl::Source> +
+
Handle to an audio source.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/axis_8hpp.html b/docs-preview/pr-1032/axis_8hpp.html new file mode 100644 index 000000000..d22178b45 --- /dev/null +++ b/docs-preview/pr-1032/axis_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/input/axis.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/binary_8hpp.html b/docs-preview/pr-1032/binary_8hpp.html new file mode 100644 index 000000000..ea73e642c --- /dev/null +++ b/docs-preview/pr-1032/binary_8hpp.html @@ -0,0 +1,133 @@ + + + + + engine/assets/bridges/binary.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/bindings_8hpp.html b/docs-preview/pr-1032/bindings_8hpp.html new file mode 100644 index 000000000..255130093 --- /dev/null +++ b/docs-preview/pr-1032/bindings_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/input/bindings.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/bloom_8hpp.html b/docs-preview/pr-1032/bloom_8hpp.html new file mode 100644 index 000000000..baf339259 --- /dev/null +++ b/docs-preview/pr-1032/bloom_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/renderer/pps/bloom.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/blueprint_8hpp.html b/docs-preview/pr-1032/blueprint_8hpp.html new file mode 100644 index 000000000..0e66dbe4a --- /dev/null +++ b/docs-preview/pr-1032/blueprint_8hpp.html @@ -0,0 +1,146 @@ + + + + + core/ecs/blueprint.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/ecs/blueprint.hpp file +

+

Class cubos::core::ecs::Blueprint.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::ecs
+
ECS module.
+
+
+
+

Classes

+
+
+ class cubos::core::ecs::Blueprint +
+
Collection of entities and their respective components and relations.
+
+
+
+

Functions

+
+
+ void convertEntities(const std::unordered_map<Entity, Entity, EntityHash>& map, + const reflection::Type& type, + void* value) +
+
Converts entities in a value to their respective new entities. If an entity is not found in the map, it is left unchanged.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/buffer__stream_8hpp.html b/docs-preview/pr-1032/buffer__stream_8hpp.html new file mode 100644 index 000000000..9683b4562 --- /dev/null +++ b/docs-preview/pr-1032/buffer__stream_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/memory/buffer_stream.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/camera_8hpp.html b/docs-preview/pr-1032/camera_8hpp.html new file mode 100644 index 000000000..7593bce2a --- /dev/null +++ b/docs-preview/pr-1032/camera_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/renderer/camera.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/child__of_8hpp.html b/docs-preview/pr-1032/child__of_8hpp.html new file mode 100644 index 000000000..bf2c4d79d --- /dev/null +++ b/docs-preview/pr-1032/child__of_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/transform/child_of.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1Logger.html b/docs-preview/pr-1032/classcubos_1_1core_1_1Logger.html new file mode 100644 index 000000000..0eb5b766a --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1Logger.html @@ -0,0 +1,374 @@ + + + + + cubos::core::Logger class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::Logger class final + +

+

Singleton which holds the logging state.

+ +
+

Public types

+
+
+ struct Entry +
+
Data created by a call to log.
+
+ struct Location +
+
Identifies a location in the code.
+
+ struct Timestamp +
+
A timestamp used to identify when a logging message was written.
+
+ enum class Level { Trace = CUBOS_LOG_LEVEL_TRACE, + Debug = CUBOS_LOG_LEVEL_DEBUG, + Info = CUBOS_LOG_LEVEL_INFO, + Warn = CUBOS_LOG_LEVEL_WARN, + Error = CUBOS_LOG_LEVEL_ERROR, + Critical = CUBOS_LOG_LEVEL_CRITICAL, + Off = CUBOS_LOG_LEVEL_OFF } +
+
Represents a logging level.
+
+
+
+

Public static functions

+
+
+ static void level(Level level) +
+
Sets the log level.
+
+ static auto level() -> Level +
+
Gets the current log level.
+
+ static void write(Level level, + Location location, + std::string message) +
+
Creates a new entry in the logs, as long as the log level is high enough.
+
+
template<reflection::Reflectable... TArgs>
+ static void writeFormat(Level level, + Location location, + const char* format, + TArgs... args) +
+
Wrapper for write() with message formatting.
+
+ static auto read(std::size_t& cursor, + Entry& entry) -> bool +
+
Reads a log entry, if there's a new one.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ Logger() deleted +
+
Deleted constructor.
+
+
+
+

Enum documentation

+
+

+ enum class cubos::core::Logger::Level +

+

Represents a logging level.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Enumerators
Trace +

Trace log level, lowest log level. Very verbose.

+
Debug +

Debug log level. Contains messages useful for debugging, but which are not necessary in release builds.

+
Info +

Information log level. Contains important events that are not errors.

+
Warn +

Warn log level. Contains events that are not errors, but which are unexpected and may be problematic.

+
Error +

Error log level. Contains errors which are recoverable from.

+
Critical +

Critical log level, highest log level. Contains errors which are unrecoverable from.

+
Off +

Off log level, disables all logging.

+
+
+
+
+

Function documentation

+
+

+ static void cubos::core::Logger::level(Level level) +

+

Sets the log level.

+ + + + + + + + + + +
Parameters
levelNew logging level.
+

If CUBOS_LOG_LEVEL is higher than the set level, entries below it are still not registered.

+
+
+

+ static Level cubos::core::Logger::level() +

+

Gets the current log level.

+ + + + + + + +
ReturnsLog level.
+
+
+

+ static void cubos::core::Logger::write(Level level, + Location location, + std::string message) +

+

Creates a new entry in the logs, as long as the log level is high enough.

+ + + + + + + + + + + + + + + + + + +
Parameters
levelLog level.
locationCode location.
messageLog message.
+
+
+

+
+ template<reflection::Reflectable... TArgs> +
+ static void cubos::core::Logger::writeFormat(Level level, + Location location, + const char* format, + TArgs... args) +

+

Wrapper for write() with message formatting.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TArgsMessage format argument types.
Parameters
levelLog level.
locationCode location.
formatMessage format string.
argsMessage format arguments.
+
+
+

+ static bool cubos::core::Logger::read(std::size_t& cursor, + Entry& entry) +

+

Reads a log entry, if there's a new one.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
cursor outIndex of the entry to be read. Automatically increased.
entry outEntry to read into.
ReturnsWhether an entry was red.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ThreadPool.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ThreadPool.html new file mode 100644 index 000000000..77dad879f --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ThreadPool.html @@ -0,0 +1,183 @@ + + + + + cubos::core::ThreadPool class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ThreadPool class final + +

+

Manages a pool of threads, to which tasks can be submitted.

+ + +
+

Constructors, destructors, conversion operators

+
+
+ ThreadPool(std::size_t numThreads) +
+
Constructs a pool with numThreads, starting them immediately.
+
+ ThreadPool(const ThreadPool&) deleted +
+
Forbid copy construction.
+
+ ThreadPool(ThreadPool&&) deleted +
+
Forbid move construction.
+
+
+
+

Public functions

+
+
+ void addTask(std::function<void()> task) +
+
Adds a task to the thread pool. Starts when a thread becomes available.
+
+ void wait() +
+
Blocks until all tasks finish.
+
+
+
+

Function documentation

+
+

+ cubos::core::ThreadPool::ThreadPool(std::size_t numThreads) +

+

Constructs a pool with numThreads, starting them immediately.

+ + + + + + + + + + +
Parameters
numThreadsNumber of threads to create.
+
+
+

+ void cubos::core::ThreadPool::addTask(std::function<void()> task) +

+

Adds a task to the thread pool. Starts when a thread becomes available.

+ + + + + + + + + + +
Parameters
taskTask to add.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1al_1_1AudioDevice.html b/docs-preview/pr-1032/classcubos_1_1core_1_1al_1_1AudioDevice.html new file mode 100644 index 000000000..e6d1d61df --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1al_1_1AudioDevice.html @@ -0,0 +1,292 @@ + + + + + cubos::core::al::AudioDevice class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::al::AudioDevice class + +

+

Audio device interface used to wrap low-level audio rendering APIs.

+ +
+

Public static functions

+
+
+ static auto create(const std::string& specifier = "") -> std::shared_ptr<AudioDevice> +
+
Creates an audio device from a given device specifier.
+
+ static void enumerateDevices(std::vector<std::string>& devices) +
+
Enumerates the available devices.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ AudioDevice(const AudioDevice&) deleted +
+
Forbid copy construction.
+
+
+
+

Public functions

+
+
+ auto createBuffer() -> Buffer pure virtual +
+
Creates a new audio buffer.
+
+ auto createSource() -> Source pure virtual +
+
Creates a new audio source.
+
+ void setListenerPosition(const glm::vec3& position) pure virtual +
+
Sets the position of the listener.
+
+ void setListenerOrientation(const glm::vec3& forward, + const glm::vec3& up) pure virtual +
+
Sets the orientation of the listener.
+
+ void setListenerVelocity(const glm::vec3& velocity) pure virtual +
+
Sets the velocity of the listener. Used to implement the doppler effect.
+
+
+
+

Function documentation

+
+

+ static std::shared_ptr<AudioDevice> cubos::core::al::AudioDevice::create(const std::string& specifier = "") +

+

Creates an audio device from a given device specifier.

+ + + + + + + + + + + + + + + + +
Parameters
specifierDevice specifier (empty for default).
ReturnsAudio device, or nullptr on failure.
+ +
+
+

+ static void cubos::core::al::AudioDevice::enumerateDevices(std::vector<std::string>& devices) +

+

Enumerates the available devices.

+ + + + + + + + + + +
Parameters
devices outVector to fill with the available devices.
+
+
+

+ Buffer cubos::core::al::AudioDevice::createBuffer() pure virtual +

+

Creates a new audio buffer.

+ + + + + + + +
ReturnsHandle of the new buffer.
+
+
+

+ Source cubos::core::al::AudioDevice::createSource() pure virtual +

+

Creates a new audio source.

+ + + + + + + +
ReturnsHandle of the new source.
+
+
+

+ void cubos::core::al::AudioDevice::setListenerPosition(const glm::vec3& position) pure virtual +

+

Sets the position of the listener.

+ + + + + + + + + + +
Parameters
positionPosition.
+
+
+

+ void cubos::core::al::AudioDevice::setListenerOrientation(const glm::vec3& forward, + const glm::vec3& up) pure virtual +

+

Sets the orientation of the listener.

+ + + + + + + + + + + + + + +
Parameters
forwardForward direction of the listener.
upUp direction of the listener.
+
+
+

+ void cubos::core::al::AudioDevice::setListenerVelocity(const glm::vec3& velocity) pure virtual +

+

Sets the velocity of the listener. Used to implement the doppler effect.

+ + + + + + + + + + +
Parameters
velocityVelocity of the listener.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1al_1_1impl_1_1Buffer.html b/docs-preview/pr-1032/classcubos_1_1core_1_1al_1_1impl_1_1Buffer.html new file mode 100644 index 000000000..5168ce031 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1al_1_1impl_1_1Buffer.html @@ -0,0 +1,161 @@ + + + + + cubos::core::al::impl::Buffer class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::al::impl::Buffer class + +

+

Abstract audio buffer.

+ +
+

Public functions

+
+
+ void fill(Format format, + std::size_t size, + const void* data, + std::size_t frequency) pure virtual +
+
Fills the buffer with data.
+
+
+
+

Function documentation

+
+

+ void cubos::core::al::impl::Buffer::fill(Format format, + std::size_t size, + const void* data, + std::size_t frequency) pure virtual +

+

Fills the buffer with data.

+ + + + + + + + + + + + + + + + + + + + + + +
Parameters
formatAudio format of the data.
sizeSize of the buffer in bytes.
dataBuffer data.
frequencyAudio frequency.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1al_1_1impl_1_1Source.html b/docs-preview/pr-1032/classcubos_1_1core_1_1al_1_1impl_1_1Source.html new file mode 100644 index 000000000..e059fec63 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1al_1_1impl_1_1Source.html @@ -0,0 +1,379 @@ + + + + + cubos::core::al::impl::Source class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::al::impl::Source class + +

+

Abstract audio source.

+ +
+

Public functions

+
+
+ void setBuffer(std::shared_ptr<Buffer> buffer) pure virtual +
+
Sets the buffer to be played by the source.
+
+ void setPosition(const glm::vec3& position) pure virtual +
+
Sets the position of the source, by default, in the world space.
+
+ void setVelocity(const glm::vec3& velocity) pure virtual +
+
Sets the velocity of the source, by default, in the world space.
+
+ void setGain(float gain) pure virtual +
+
Sets the gain of the source.
+
+ void setPitch(float pitch) pure virtual +
+
Sets the pitch of the source.
+
+ void setLooping(bool looping) pure virtual +
+
Sets whether the source plays in a loop.
+
+ void setRelative(bool relative) pure virtual +
+
Sets whether the source position and velocity is relative to the listener or not.
+
+ void setDistance(float maxDistance) pure virtual +
+
Sets the maximum distance at which the source is audible.
+
+ void setConeAngle(float coneAngle) pure virtual +
+
Sets the cone angle of the source, in degrees. By default, 360.
+
+ void setConeGain(float coneGain) pure virtual +
+
Sets the cone gain of the source.
+
+ void setConeDirection(const glm::vec3& direction) pure virtual +
+
Sets the cone direction of the source.
+
+ void setReferenceDistance(float referenceDistance) pure virtual +
+
Sets the distance under which the volume for the source would normally drop by half.
+
+ void play() pure virtual +
+
Plays the source.
+
+
+
+

Function documentation

+
+

+ void cubos::core::al::impl::Source::setBuffer(std::shared_ptr<Buffer> buffer) pure virtual +

+

Sets the buffer to be played by the source.

+ + + + + + + + + + +
Parameters
bufferBuffer.
+
+
+

+ void cubos::core::al::impl::Source::setPosition(const glm::vec3& position) pure virtual +

+

Sets the position of the source, by default, in the world space.

+ + + + + + + + + + +
Parameters
positionPosition.
+ +
+
+

+ void cubos::core::al::impl::Source::setVelocity(const glm::vec3& velocity) pure virtual +

+

Sets the velocity of the source, by default, in the world space.

+ + + + + + + + + + +
Parameters
velocityVelocity.
+
+
+

+ void cubos::core::al::impl::Source::setGain(float gain) pure virtual +

+

Sets the gain of the source.

+ + + + + + + + + + +
Parameters
gainGain.
+
+
+

+ void cubos::core::al::impl::Source::setPitch(float pitch) pure virtual +

+

Sets the pitch of the source.

+ + + + + + + + + + +
Parameters
pitchPitch.
+
+
+

+ void cubos::core::al::impl::Source::setLooping(bool looping) pure virtual +

+

Sets whether the source plays in a loop.

+ + + + + + + + + + +
Parameters
loopingLooping flag.
+
+
+

+ void cubos::core::al::impl::Source::setRelative(bool relative) pure virtual +

+

Sets whether the source position and velocity is relative to the listener or not.

+ + + + + + + + + + +
Parameters
relativeRelative flag.
+
+
+

+ void cubos::core::al::impl::Source::setDistance(float maxDistance) pure virtual +

+

Sets the maximum distance at which the source is audible.

+ + + + + + + + + + +
Parameters
maxDistanceMaximum distance.
+
+
+

+ void cubos::core::al::impl::Source::setConeAngle(float coneAngle) pure virtual +

+

Sets the cone angle of the source, in degrees. By default, 360.

+ + + + + + + + + + +
Parameters
coneAngleAngle, in degrees.
+
+
+

+ void cubos::core::al::impl::Source::setConeGain(float coneGain) pure virtual +

+

Sets the cone gain of the source.

+ + + + + + + + + + +
Parameters
coneGainGain.
+
+
+

+ void cubos::core::al::impl::Source::setConeDirection(const glm::vec3& direction) pure virtual +

+

Sets the cone direction of the source.

+ + + + + + + + + + +
Parameters
directionDirection.
+
+
+

+ void cubos::core::al::impl::Source::setReferenceDistance(float referenceDistance) pure virtual +

+

Sets the distance under which the volume for the source would normally drop by half.

+ + + + + + + + + + +
Parameters
referenceDistanceDistance.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1Archive.html b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1Archive.html new file mode 100644 index 000000000..c86737abc --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1Archive.html @@ -0,0 +1,398 @@ + + + + + cubos::core::data::Archive class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data::Archive class + +

+

Interface for a bridge between the CUBOS. virtual file system and the real world.

+ +

By real world, we mean something such as a file on the OS file system or a network connection. The archive is responsible for creating and destroying files, supplying streams for reading and writing, and retrieving information about existing files.

Each file in an archive is represented by a unique integer identifier. The identifier 0 is reserved for errors, and the identifier 1 is reserved for the root file of the archive.

The root file may be a directory or a regular file. If its a directory, when mounted, the archive will take the form of a directory, with the root file being placed on the mount point. If the root file is a regular file, then the mount point will be a regular file.

This class is not meant to be thread-safe - it is the responsibility of the File class to ensure that the same file is not accessed or modified by multiple threads at the same time.

Implementations should crash when called with invalid arguments - since they're only called by File, its okay to assume the arguments are correct (please do use asserts though).

+
+

Derived classes

+
+
+ class EmbeddedArchive +
+
Archive implementation which reads data embedded in the application. Meant to be used with the quadrados embed tool.
+
+ class StandardArchive +
+
Archive implementation which reads and writes from/into the OS file system using the standard library.
+
+
+
+

Public functions

+
+
+ auto create(std::size_t parent, + std::string_view name, + bool directory = false) -> std::size_t pure virtual +
+
Creates a new file in the archive.
+
+ auto destroy(std::size_t id) -> bool pure virtual +
+
Destroys a regular file or empty directory in the archive.
+
+ auto name(std::size_t id) const -> std::string pure virtual +
+
Gets the name of the file with the given id.
+
+ auto directory(std::size_t id) const -> bool pure virtual +
+
Checks whether the file with the given id is a directory.
+
+ auto readOnly() const -> bool pure virtual +
+
Checks whether the archive is read-only.
+
+ auto parent(std::size_t id) const -> std::size_t pure virtual +
+
Gets the identifier of the parent file of the file with the given id.
+
+ auto sibling(std::size_t id) const -> std::size_t pure virtual +
+
Gets the identifier of the sibling of the file with the given id.
+
+ auto child(std::size_t id) const -> std::size_t pure virtual +
+
Gets the identifier of the first child of the file with the given id.
+
+ auto open(std::size_t id, + File::Handle handle, + File::OpenMode mode) -> std::unique_ptr<memory::Stream> pure virtual +
+
Opens a file in the archive.
+
+
+
+

Function documentation

+
+

+ std::size_t cubos::core::data::Archive::create(std::size_t parent, + std::string_view name, + bool directory = false) pure virtual +

+

Creates a new file in the archive.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
parentParent directory of the new file.
nameName of the new file.
directoryWhether the new file is a directory or not.
ReturnsIdentifier of the file, or 0 if the file could not be created.
+

The first child of the parent will have its sibling set to the new file and then be replaced by the new file.

+
+
+

+ bool cubos::core::data::Archive::destroy(std::size_t id) pure virtual +

+

Destroys a regular file or empty directory in the archive.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the file.
ReturnsWhether the file was destroyed successfully.
+

Will be replaced in the tree by its sibling.

+
+
+

+ std::string cubos::core::data::Archive::name(std::size_t id) const pure virtual +

+

Gets the name of the file with the given id.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the file.
ReturnsName of the file.
+
+
+

+ bool cubos::core::data::Archive::directory(std::size_t id) const pure virtual +

+

Checks whether the file with the given id is a directory.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the file.
ReturnsWhether the file is a directory or not.
+
+
+

+ bool cubos::core::data::Archive::readOnly() const pure virtual +

+

Checks whether the archive is read-only.

+ + + + + + + +
ReturnsWhether the archive is read-only.
+
+
+

+ std::size_t cubos::core::data::Archive::parent(std::size_t id) const pure virtual +

+

Gets the identifier of the parent file of the file with the given id.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the file.
ReturnsIdentifier of the parent file, or 0 if the file is the root file.
+
+
+

+ std::size_t cubos::core::data::Archive::sibling(std::size_t id) const pure virtual +

+

Gets the identifier of the sibling of the file with the given id.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the file.
ReturnsIdentifier of the sibling, or 0 if there are no more files in the parent.
+
+
+

+ std::size_t cubos::core::data::Archive::child(std::size_t id) const pure virtual +

+

Gets the identifier of the first child of the file with the given id.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the file.
ReturnsIdentifier of the first child, or 0 if the file is not a directory or is empty.
+
+
+

+ std::unique_ptr<memory::Stream> cubos::core::data::Archive::open(std::size_t id, + File::Handle handle, + File::OpenMode mode) pure virtual +

+

Opens a file in the archive.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the file.
handleHandle to the file.
modeMode to open the file in.
ReturnsFile stream, or nullptr if the file could not be opened.
+

Although a bit hacky, the handle parameter is used to keep a reference to the respective File alive, preventing the file from being destroyed while the stream is open.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1DebugSerializer.html b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1DebugSerializer.html new file mode 100644 index 000000000..0b512497f --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1DebugSerializer.html @@ -0,0 +1,220 @@ + + + + + cubos::core::data::DebugSerializer class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data::DebugSerializer class + +

+

Serializer implementation which prints the given data to a stream in a human-readable format not meant to be parsed.

+ +
+

Base classes

+
+
+ class Serializer +
+
Base class for serializers, which defines the interface for serializing arbitrary data using its reflection metadata.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ DebugSerializer(memory::Stream& stream) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ void pretty(bool pretty) +
+
Sets whether to pretty-print the output.
+
+
+
+

Protected functions

+
+
+ auto decompose(const reflection::Type& type, + const void* value) -> bool override +
+
Called for each type with no hook defined.
+
+
+
+

Function documentation

+
+

+ cubos::core::data::DebugSerializer::DebugSerializer(memory::Stream& stream) +

+

Constructs.

+ + + + + + + + + + +
Parameters
streamStream to serialize to.
+
+
+

+ void cubos::core::data::DebugSerializer::pretty(bool pretty) +

+

Sets whether to pretty-print the output.

+ + + + + + + + + + +
Parameters
prettyWhether to pretty-print the output.
+
+
+

+ bool cubos::core::data::DebugSerializer::decompose(const reflection::Type& type, + const void* value) override protected +

+

Called for each type with no hook defined.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
typeType.
valueValue.
ReturnsWhether the value was successfully serialized.
+

Should recurse by calling write() again as appropriate.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1Deserializer.html b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1Deserializer.html new file mode 100644 index 000000000..e9471d86e --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1Deserializer.html @@ -0,0 +1,355 @@ + + + + + cubos::core::data::Deserializer class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data::Deserializer class + +

+

Base class for deserializers, which defines the interface for deserializing arbitrary data using its reflection metadata.

+ +

Deserializers are type visitors which allow overriding the default deserialization behaviour for each type using hooks. Hooks are functions which are called when the deserializer encounters a type, and can be used to customize the deserialization process.

If a type which can't be further decomposed is encountered for which no hook is defined, the deserializer will emit a warning and fail. Implementations should set default hooks for at least the primitive types.

+
+

Derived classes

+
+
+ class JSONDeserializer +
+
Deserializer implementation which allows reading data from a JSON object.
+
+
+
+

Public types

+
+
+ using Hook = memory::Function<bool(void*)> +
+
Function type for deserialization hooks.
+
+
template<typename T>
+ using TypedHook = memory::Function<bool(T&)> +
+
Function type for deserialization hooks.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ Deserializer() defaulted +
+
Constructs.
+
+
+
+

Public functions

+
+
+ auto read(const reflection::Type& type, + void* value) -> bool +
+
Deserialize the given value.
+
+
template<typename T>
+ auto read(T& value) -> bool +
+
Deserialize the given value.
+
+ void hook(const reflection::Type& type, + Hook hook) +
+
Sets the hook to be called on deserialization of the given type.
+
+
template<typename T>
+ void hook(TypedHook<T> hook) +
+
Sets the hook to be called on deserialization of the given type.
+
+
+
+

Protected functions

+
+
+ auto decompose(const reflection::Type& type, + void* value) -> bool pure virtual +
+
Called for each type with no hook defined.
+
+
+
+

Typedef documentation

+
+

+
+ template<typename T> +
+ using cubos::core::data::Deserializer::TypedHook = memory::Function<bool(T&)> +

+

Function type for deserialization hooks.

+ + + + + + + + + + +
Template parameters
TType.
+
+
+
+

Function documentation

+
+

+ bool cubos::core::data::Deserializer::read(const reflection::Type& type, + void* value) +

+

Deserialize the given value.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
typeType.
valueValue.
ReturnsWhether the value was successfully deserialized.
+
+
+

+
+ template<typename T> +
+ bool cubos::core::data::Deserializer::read(T& value) +

+

Deserialize the given value.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TType.
Parameters
valueValue.
ReturnsWhether the value was successfully deserialized.
+
+
+

+ void cubos::core::data::Deserializer::hook(const reflection::Type& type, + Hook hook) +

+

Sets the hook to be called on deserialization of the given type.

+ + + + + + + + + + + + + + +
Parameters
typeType.
hookHook.
+
+
+

+
+ template<typename T> +
+ void cubos::core::data::Deserializer::hook(TypedHook<T> hook) +

+

Sets the hook to be called on deserialization of the given type.

+ + + + + + + + + + + + + + + + + + + +
Template parameters
TType.
Parameters
hookHook.
+
+
+

+ bool cubos::core::data::Deserializer::decompose(const reflection::Type& type, + void* value) pure virtual protected +

+

Called for each type with no hook defined.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
typeType.
valueValue.
ReturnsWhether the value was successfully deserialized.
+

Should recurse by calling read() again as appropriate.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1EmbeddedArchive.html b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1EmbeddedArchive.html new file mode 100644 index 000000000..44d9c814f --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1EmbeddedArchive.html @@ -0,0 +1,466 @@ + + + + + cubos::core::data::EmbeddedArchive class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data::EmbeddedArchive class + +

+

Archive implementation which reads data embedded in the application. Meant to be used with the quadrados embed tool.

+ +

Can be used to create single-file applications, where all the data is embedded in the executable.

This archive accesses a global map of data, where embedded data can be registered with a given name. Then, to access that data, an instance of this archive is created pointing to that name.

The embed tool generates source files which define and register that data. By linking those files into your application, you're making the data available to be accessed through an instance of this archive.

+
+

Base classes

+
+
+ class Archive +
+
Interface for a bridge between the CUBOS. virtual file system and the real world.
+
+
+
+

Public types

+
+
+ struct Data +
+
Describes the structure of the embedded data.
+
+
+
+

Public static functions

+
+
+ static void registerData(const std::string& name, + const Data& data) +
+
Registers embedded archive data, which must remain valid for the lifetime of the application.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ EmbeddedArchive(const std::string& name) +
+
Constructs pointing to the data with the given name.
+
+
+
+

Public functions

+
+
+ auto create(std::size_t parent, + std::string_view name, + bool directory = false) -> std::size_t override +
+
Creates a new file in the archive.
+
+ auto destroy(std::size_t id) -> bool override +
+
Destroys a regular file or empty directory in the archive.
+
+ auto name(std::size_t id) const -> std::string override +
+
Gets the name of the file with the given id.
+
+ auto directory(std::size_t id) const -> bool override +
+
Checks whether the file with the given id is a directory.
+
+ auto readOnly() const -> bool override +
+
Checks whether the archive is read-only.
+
+ auto parent(std::size_t id) const -> std::size_t override +
+
Gets the identifier of the parent file of the file with the given id.
+
+ auto sibling(std::size_t id) const -> std::size_t override +
+
Gets the identifier of the sibling of the file with the given id.
+
+ auto child(std::size_t id) const -> std::size_t override +
+
Gets the identifier of the first child of the file with the given id.
+
+ auto open(std::size_t id, + File::Handle handle, + File::OpenMode mode) -> std::unique_ptr<memory::Stream> override +
+
Opens a file in the archive.
+
+
+
+

Function documentation

+
+

+ static void cubos::core::data::EmbeddedArchive::registerData(const std::string& name, + const Data& data) +

+

Registers embedded archive data, which must remain valid for the lifetime of the application.

+ + + + + + + + + + + + + + +
Parameters
nameName of the embedded archive data.
dataEmbedded archive data.
+

This function is called by the code generated by the embed tool.

+
+
+

+ cubos::core::data::EmbeddedArchive::EmbeddedArchive(const std::string& name) +

+

Constructs pointing to the data with the given name.

+ + + + + + + + + + +
Parameters
nameName of the data the embedded archive is going to access.
+

Aborts if no data with the given name was registered.

+
+
+

+ std::size_t cubos::core::data::EmbeddedArchive::create(std::size_t parent, + std::string_view name, + bool directory = false) override +

+

Creates a new file in the archive.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
parentParent directory of the new file.
nameName of the new file.
directoryWhether the new file is a directory or not.
ReturnsIdentifier of the file, or 0 if the file could not be created.
+

The first child of the parent will have its sibling set to the new file and then be replaced by the new file.

+
+
+

+ bool cubos::core::data::EmbeddedArchive::destroy(std::size_t id) override +

+

Destroys a regular file or empty directory in the archive.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the file.
ReturnsWhether the file was destroyed successfully.
+

Will be replaced in the tree by its sibling.

+
+
+

+ std::string cubos::core::data::EmbeddedArchive::name(std::size_t id) const override +

+

Gets the name of the file with the given id.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the file.
ReturnsName of the file.
+
+
+

+ bool cubos::core::data::EmbeddedArchive::directory(std::size_t id) const override +

+

Checks whether the file with the given id is a directory.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the file.
ReturnsWhether the file is a directory or not.
+
+
+

+ bool cubos::core::data::EmbeddedArchive::readOnly() const override +

+

Checks whether the archive is read-only.

+ + + + + + + +
ReturnsWhether the archive is read-only.
+
+
+

+ std::size_t cubos::core::data::EmbeddedArchive::parent(std::size_t id) const override +

+

Gets the identifier of the parent file of the file with the given id.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the file.
ReturnsIdentifier of the parent file, or 0 if the file is the root file.
+
+
+

+ std::size_t cubos::core::data::EmbeddedArchive::sibling(std::size_t id) const override +

+

Gets the identifier of the sibling of the file with the given id.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the file.
ReturnsIdentifier of the sibling, or 0 if there are no more files in the parent.
+
+
+

+ std::size_t cubos::core::data::EmbeddedArchive::child(std::size_t id) const override +

+

Gets the identifier of the first child of the file with the given id.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the file.
ReturnsIdentifier of the first child, or 0 if the file is not a directory or is empty.
+
+
+

+ std::unique_ptr<memory::Stream> cubos::core::data::EmbeddedArchive::open(std::size_t id, + File::Handle handle, + File::OpenMode mode) override +

+

Opens a file in the archive.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the file.
handleHandle to the file.
modeMode to open the file in.
ReturnsFile stream, or nullptr if the file could not be opened.
+

Although a bit hacky, the handle parameter is used to keep a reference to the respective File alive, preventing the file from being destroyed while the stream is open.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1File.html b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1File.html new file mode 100644 index 000000000..afb1c1ceb --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1File.html @@ -0,0 +1,496 @@ + + + + + cubos::core::data::File class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data::File class final + +

+

Represents a file in the virtual file system of the engine.

+ +

Instances of this class are always held through a File::Handle, which is just a smart shared pointer.

Files may either be regular files or directories. Directories can have children files, but no data. Regular files are only allowed inside mounted archives, since they must have data associated with them, while the directories are just a way to organize the files.

+
+

Public types

+
+
+ enum class OpenMode { Read, + Write, + ReadWrite } +
+
Possible modes to open files in.
+
+ using Handle = std::shared_ptr<File> +
+
Handle to a file in the CUBOS. virtual file system.
+
+
+
+

Public functions

+
+
+ auto mount(std::string_view path, + std::unique_ptr<Archive> archive) -> bool +
+
Mounts an archive to a path relative to this file.
+
+ auto unmount(std::string_view path) -> bool +
+
Unmounts an archive from a path relative to this file.
+
+ auto find(std::string_view path) -> Handle +
+
Gets a handle to a file relative to this file.
+
+ auto create(std::string_view path, + bool directory = false) -> Handle +
+
Creates a new file on a path relative to this file.
+
+ auto destroy() -> bool +
+
Marks this file for destruction.
+
+ auto open(OpenMode mode) -> std::unique_ptr<memory::Stream> +
+
Opens this file for reading or writing.
+
+ auto name() const -> std::string_view +
+
Gets the name of this file.
+
+ auto path() const -> std::string_view +
+
Gets the absolute path of this file.
+
+ auto directory() const -> bool +
+
Checks whether this file is a directory.
+
+ auto archive() const -> const std::shared_ptr<Archive>& +
+
Gets the archive this file is in.
+
+ auto id() const -> std::size_t +
+
Gets the identifier of this file on its archive.
+
+ auto parent() const -> Handle +
+
Gets the parent directory of this file.
+
+ auto sibling() const -> Handle +
+
Gets the next sibling of this file.
+
+ auto child() const -> Handle +
+
Gets the first child of this file.
+
+
+
+

Enum documentation

+
+

+ enum class cubos::core::data::File::OpenMode +

+

Possible modes to open files in.

+ + + + + + + + + + + + + + + + +
Enumerators
Read +

Open the file for reading.

+
Write +

Open the file for writing, overwriting any previous changes.

+
ReadWrite +

Open the file for reading or writing data.

+
+
+
+
+

Typedef documentation

+
+

+ using cubos::core::data::File::Handle = std::shared_ptr<File> +

+

Handle to a file in the CUBOS. virtual file system.

+

This is a smart shared pointer, so that files are not destroyed while being referenced.

+
+
+
+

Function documentation

+
+

+ bool cubos::core::data::File::mount(std::string_view path, + std::unique_ptr<Archive> archive) +

+

Mounts an archive to a path relative to this file.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
pathPath relative to this file to mount the archive on.
archiveArchive to mount.
ReturnsWhether the archive was successfully mounted.
+

Creates any parent directories that may be necessary, but the mount point itself must not already exist.

This method fails on the following conditions:

  • path is absolute or invalid.
  • a parent file in the path exists and is not a directory.
  • a parent directory in the path belongs to an archive.
  • a file already exists at the mount point.
+
+
+

+ bool cubos::core::data::File::unmount(std::string_view path) +

+

Unmounts an archive from a path relative to this file.

+ + + + + + + + + + + + + + + + +
Parameters
pathPath relative to this file to unmount the archive from.
ReturnsWhether the archive was successfully unmounted.
+

Removes all of the archive's files from the virtual file system.

This method fails on the following conditions:

  • path is absolute or invalid.
  • any of the files in the path do not exist.
  • the target path is not the mount point for an archive.
+
+
+

+ Handle cubos::core::data::File::find(std::string_view path) +

+

Gets a handle to a file relative to this file.

+ + + + + + + + + + + + + + + + +
Parameters
pathPath relative to this file to get the file from.
ReturnsHandle to the file, or nullptr on failure.
+

Fails if the file does not exist or if the path is absolute or invalid.

+
+
+

+ Handle cubos::core::data::File::create(std::string_view path, + bool directory = false) +

+

Creates a new file on a path relative to this file.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
pathRelative path to the file.
directoryWhether the new file should be a directory.
ReturnsHandle to the file, or nullptr on failure.
+

The destination location must be writeable - that is, it must be under a mounted writeable archive. If a file at the given path already exists, it is returned instead. Any parent directories that may be necessary are created.

This method fails on the following conditions:

  • path is absolute or invalid.
  • a parent directory in the path does not exist and cannot be created.
  • a parent directory in the path already exists as a regular file.
  • a file of a different type already exists at the destination.
+
+
+

+ bool cubos::core::data::File::destroy() +

+

Marks this file for destruction.

+ + + + + + + +
ReturnsWhether the file was successfully marked for destruction.
+

Although the file will only be deleted when no more references to it exist, it is immediately removed from the virtual file system and this method is called recursively on all its children.

This method fails on the following conditions:

  • this file is the mount point of an archive.
  • this file does not belong to an archive.
  • this file belongs to a read-only archive.
+
+
+

+ std::unique_ptr<memory::Stream> cubos::core::data::File::open(OpenMode mode) +

+

Opens this file for reading or writing.

+ + + + + + + + + + + + + + + + +
Parameters
modeMode to open the file in.
ReturnsHandle to a file stream, or nullptr on failure.
+

If the file is being written to, blocks until the other threads are done with the file.

This method fails on the following conditions:

  • this file is a directory.
  • this file belongs to a read-only archive and the mode is not OpenMode::Read.
+
+
+

+ std::string_view cubos::core::data::File::name() const +

+

Gets the name of this file.

+ + + + + + + +
ReturnsName of this file.
+
+
+

+ std::string_view cubos::core::data::File::path() const +

+

Gets the absolute path of this file.

+ + + + + + + +
ReturnsAbsolute path of this file.
+
+
+

+ bool cubos::core::data::File::directory() const +

+

Checks whether this file is a directory.

+ + + + + + + +
ReturnsWhether this file is a directory.
+
+
+

+ const std::shared_ptr<Archive>& cubos::core::data::File::archive() const +

+

Gets the archive this file is in.

+ + + + + + + +
ReturnsArchive this file is in, or nullptr if the file is not in an archive.
+
+
+

+ std::size_t cubos::core::data::File::id() const +

+

Gets the identifier of this file on its archive.

+ + + + + + + +
ReturnsIdentifier of this file on its archive, or 0 if it is not in an archive.
+
+
+

+ Handle cubos::core::data::File::parent() const +

+

Gets the parent directory of this file.

+ + + + + + + +
ReturnsFile's parent directory, or nullptr if there isn't one.
+
+
+

+ Handle cubos::core::data::File::sibling() const +

+

Gets the next sibling of this file.

+ + + + + + + +
ReturnsNext sibling, or nullptr if this file is the last child of its parent.
+
+
+

+ Handle cubos::core::data::File::child() const +

+

Gets the first child of this file.

+ + + + + + + +
ReturnsFirst child, or nullptr if this file is not a directory or if it is empty.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1FileStream.html b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1FileStream.html new file mode 100644 index 000000000..9acbdc068 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1FileStream.html @@ -0,0 +1,352 @@ + + + + + cubos::core::data::FileStream class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::data::FileStream class final +

+

Wrapper around an implementation-specific file stream which keeps the file alive and does some sanity checks.

+ + + + + + + + + + +
Template parameters
TInner implementation-specific stream type.
+ +

The file is kept alive by storing a handle to it, which prevents it from being destroyed as long as the stream is alive.

+
+

Base classes

+
+
+ class cubos::core::memory::Stream +
+
Interface class for memory streams. Abstracts away sources or destinations of data.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ FileStream(File::Handle file, + File::OpenMode mode, + T&& stream) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ auto read(void* data, + std::size_t size) -> std::size_t override +
+
Reads data from the stream.
+
+ auto write(const void* data, + std::size_t size) -> std::size_t override +
+
Writes data to the stream.
+
+ auto tell() const -> std::size_t override +
+
Gets the current position in the stream.
+
+ void seek(ptrdiff_t offset, + memory::SeekOrigin origin) override +
+
Seeks to a position in the stream.
+
+ auto eof() const -> bool override +
+
Checks if the stream still has content to read.
+
+ auto peek() const -> char override +
+
Peeks one byte from the stream.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ cubos::core::data::FileStream<T>::FileStream(File::Handle file, + File::OpenMode mode, + T&& stream) +

+

Constructs.

+ + + + + + + + + + + + + + + + + + +
Parameters
fileFile which the stream is reading/writing from/to.
modeMode to open the file in.
streamStream to read/write from/to.
+
+
+

+
+ template<typename T> +
+ std::size_t cubos::core::data::FileStream<T>::read(void* data, + std::size_t size) override +

+

Reads data from the stream.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
dataBuffer to read data into.
sizeSize of the buffer.
ReturnsNumber of bytes read.
+
+
+

+
+ template<typename T> +
+ std::size_t cubos::core::data::FileStream<T>::write(const void* data, + std::size_t size) override +

+

Writes data to the stream.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
dataBuffer to write data from.
sizeSize of the buffer.
ReturnsNumber of bytes written.
+
+
+

+
+ template<typename T> +
+ std::size_t cubos::core::data::FileStream<T>::tell() const override +

+

Gets the current position in the stream.

+ + + + + + + +
ReturnsCurrent position in the stream, or SIZE_MAX if the position is unknown.
+
+
+

+
+ template<typename T> +
+ void cubos::core::data::FileStream<T>::seek(ptrdiff_t offset, + memory::SeekOrigin origin) override +

+

Seeks to a position in the stream.

+ + + + + + + + + + + + + + +
Parameters
offsetOffset to seek to.
originOrigin of the offset.
+
+
+

+
+ template<typename T> +
+ bool cubos::core::data::FileStream<T>::eof() const override +

+

Checks if the stream still has content to read.

+ + + + + + + +
ReturnsWhether the stream has reached the end.
+
+
+

+
+ template<typename T> +
+ char cubos::core::data::FileStream<T>::peek() const override +

+

Peeks one byte from the stream.

+ + + + + + + +
ReturnsPeeked byte.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1FileSystem.html b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1FileSystem.html new file mode 100644 index 000000000..e00ac0acf --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1FileSystem.html @@ -0,0 +1,361 @@ + + + + + cubos::core::data::FileSystem class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data::FileSystem class final + +

+

Singleton which represents the virtual file system of the engine.

+ +

All filesystem operations in the engine should be done through this class or through a File obtained here.

+
+

Public static functions

+
+
+ static auto root() -> File::Handle +
+
Gets the root file of the virtual file system.
+
+ static auto mount(std::string_view path, + std::unique_ptr<Archive> archive) -> bool +
+
Mounts an archive to an absolute path.
+
+ static auto unmount(std::string_view path) -> bool +
+
Unmounts an archive from an absolute path.
+
+ static auto find(std::string_view path) -> File::Handle +
+
Gets a handle to a file.
+
+ static auto create(std::string_view path, + bool directory = false) -> File::Handle +
+
Creates a new file at the specified absolute path.
+
+ static auto destroy(std::string_view path) -> bool +
+
Marks a file for destruction.
+
+ static auto open(std::string_view path, + File::OpenMode mode) -> std::unique_ptr<memory::Stream> +
+
Opens a file in the virtual file system.
+
+ static auto copy(std::string_view sourcePath, + std::string_view destinationPath) -> bool +
+
Copies a file from the source path to the destination path.
+
+
+
+

Function documentation

+
+

+ static File::Handle cubos::core::data::FileSystem::root() +

+

Gets the root file of the virtual file system.

+ + + + + + + +
ReturnsFile handle.
+
+
+

+ static bool cubos::core::data::FileSystem::mount(std::string_view path, + std::unique_ptr<Archive> archive) +

+

Mounts an archive to an absolute path.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
pathAbsolute path to mount the archive on.
archiveArchive to mount.
ReturnsWhether the archive was successfully mounted.
+

Creates any parent directories that may be necessary, but the mount point itself must not already exist.

This method fails on the following conditions:

  • path is relative or invalid.
  • a parent file in the path exists and is not a directory.
  • a parent directory in the path belongs to an archive.
  • a file already exists at the mount point.
+
+
+

+ static bool cubos::core::data::FileSystem::unmount(std::string_view path) +

+

Unmounts an archive from an absolute path.

+ + + + + + + + + + + + + + + + +
Parameters
pathPath to unmount the archive from.
ReturnsWhether the archive was successfully unmounted.
+

Removes all of the archive's files from the virtual file system.

This method fails on the following conditions:

  • path is relative or invalid.
  • any of the files in the path do not exist.
  • the target path is not the mount point of an archive.
+
+
+

+ static File::Handle cubos::core::data::FileSystem::find(std::string_view path) +

+

Gets a handle to a file.

+ + + + + + + + + + + + + + + + +
Parameters
pathAbsolute path to the file.
ReturnsFile handle or nullptr on failure.
+

Fails if the file does not exist or the path is relative or invalid.

+
+
+

+ static File::Handle cubos::core::data::FileSystem::create(std::string_view path, + bool directory = false) +

+

Creates a new file at the specified absolute path.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
pathAbsolute path to the file.
directoryWhether the new file should be a directory.
ReturnsFile or nullptr on failure.
+

The destination location must be writeable - that is, it must be under a mounted writeable archive.

If a file at the specified path already exists, it is returned instead. Any parent directories that may be necessary are created.

This method fails on the following conditions:

  • path is relative or invalid.
  • a parent directory in the path does not exist and cannot be created.
  • a parent directory in the path already exists as a regular file.
  • a file of a different type already exists at the destination.
+
+
+

+ static bool cubos::core::data::FileSystem::destroy(std::string_view path) +

+

Marks a file for destruction.

+ + + + + + + + + + + + + + + + +
Parameters
pathAbsolute path of the file to destroy.
ReturnsWhether the file was successfully marked for destruction.
+

Although The file will only be deleted when no more references to it exist, it is immediately removed from the virtual file system.

All children of the file are also marked for destruction.

This method fails on the following conditions:

  • path is relative or invalid.
  • the file does not exist.
  • the file is the mount point of an archive.
  • the file does not belong to an archive.
  • the file belongs to a read-only archive.
+
+
+

+ static std::unique_ptr<memory::Stream> cubos::core::data::FileSystem::open(std::string_view path, + File::OpenMode mode) +

+

Opens a file in the virtual file system.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
pathAbsolute path of the file.
modeMode to open the file in.
ReturnsFile stream, or nullptr if an error occurred.
+

If the file is being written to, blocks until the other threads are done with the file.

This method fails on the following conditions:

  • FileSystem::find(path) fails.
  • file->open(mode) fails.
+
+
+

+ static bool cubos::core::data::FileSystem::copy(std::string_view sourcePath, + std::string_view destinationPath) +

+

Copies a file from the source path to the destination path.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
sourcePathAbsolute path of the source file.
destinationPathAbsolute path of the destination file.
ReturnsWhether the file was successfully copied.
+

This method opens the source file in binary mode, reads its contents, and writes them to the destination file. If the destination file already exists, it will be overwritten.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1JSONDeserializer.html b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1JSONDeserializer.html new file mode 100644 index 000000000..8f8561fb0 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1JSONDeserializer.html @@ -0,0 +1,204 @@ + + + + + cubos::core::data::JSONDeserializer class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data::JSONDeserializer class + +

+

Deserializer implementation which allows reading data from a JSON object.

+ +

Before deserializing any data, a JSON object must be fed to the deserializer.

+
+

Base classes

+
+
+ class Deserializer +
+
Base class for deserializers, which defines the interface for deserializing arbitrary data using its reflection metadata.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ JSONDeserializer() +
+
Constructs.
+
+
+
+

Public functions

+
+
+ void feed(nlohmann::json json) +
+
Feeds a JSON object to be deserialized.
+
+
+
+

Protected functions

+
+
+ auto decompose(const reflection::Type& type, + void* value) -> bool override +
+
Called for each type with no hook defined.
+
+
+
+

Function documentation

+
+

+ void cubos::core::data::JSONDeserializer::feed(nlohmann::json json) +

+

Feeds a JSON object to be deserialized.

+ + + + + + + + + + +
Parameters
jsonJSON object.
+
+
+

+ bool cubos::core::data::JSONDeserializer::decompose(const reflection::Type& type, + void* value) override protected +

+

Called for each type with no hook defined.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
typeType.
valueValue.
ReturnsWhether the value was successfully deserialized.
+

Should recurse by calling read() again as appropriate.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1JSONSerializer.html b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1JSONSerializer.html new file mode 100644 index 000000000..1d9006a1e --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1JSONSerializer.html @@ -0,0 +1,200 @@ + + + + + cubos::core::data::JSONSerializer class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data::JSONSerializer class + +

+

Implementation of the abstract Serializer class for serializing to JSON.

+ +
+

Base classes

+
+
+ class Serializer +
+
Base class for serializers, which defines the interface for serializing arbitrary data using its reflection metadata.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ JSONSerializer() +
+
Constructs.
+
+
+
+

Public functions

+
+
+ auto output() -> nlohmann::json +
+
Outputs the serialized JSON. write must be called before this.
+
+
+
+

Protected functions

+
+
+ auto decompose(const reflection::Type& type, + const void* value) -> bool override +
+
Called for each type with no hook defined.
+
+
+
+

Function documentation

+
+

+ nlohmann::json cubos::core::data::JSONSerializer::output() +

+

Outputs the serialized JSON. write must be called before this.

+ + + + + + + +
ReturnsJSON.
+
+
+

+ bool cubos::core::data::JSONSerializer::decompose(const reflection::Type& type, + const void* value) override protected +

+

Called for each type with no hook defined.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
typeType.
valueValue.
ReturnsWhether the value was successfully serialized.
+

Should recurse by calling write() again as appropriate.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1Serializer.html b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1Serializer.html new file mode 100644 index 000000000..49cccfa79 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1Serializer.html @@ -0,0 +1,349 @@ + + + + + cubos::core::data::Serializer class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data::Serializer class + +

+

Base class for serializers, which defines the interface for serializing arbitrary data using its reflection metadata.

+ +

Serializers are type visitors which allow overriding the default serialization behaviour for each type using hooks. Hooks are functions which are called when the serializer encounters a type, and can be used to customize the serialization process.

If a type which can't be further decomposed is encountered for which no hook is defined, the serializer will emit a warning and fail. Implementations should set default hooks for at least the primitive types.

+
+

Derived classes

+
+
+ class DebugSerializer +
+
Serializer implementation which prints the given data to a stream in a human-readable format not meant to be parsed.
+
+ class JSONSerializer +
+
Implementation of the abstract Serializer class for serializing to JSON.
+
+
+
+

Public types

+
+
+ using Hook = memory::Function<bool(const void*)> +
+
Function type for serialization hooks.
+
+
template<typename T>
+ using TypedHook = memory::Function<bool(const T&)> +
+
Function type for serialization hooks.
+
+
+
+

Public functions

+
+
+ auto write(const reflection::Type& type, + const void* value) -> bool +
+
Serialize the given value.
+
+
template<typename T>
+ auto write(const T& value) -> bool +
+
Serialize the given value.
+
+ void hook(const reflection::Type& type, + Hook hook) +
+
Sets the hook to be called on serialization of the given type.
+
+
template<typename T>
+ void hook(TypedHook<T> hook) +
+
Sets the hook to be called on serialization of the given type.
+
+
+
+

Protected functions

+
+
+ auto decompose(const reflection::Type& type, + const void* value) -> bool pure virtual +
+
Called for each type with no hook defined.
+
+
+
+

Typedef documentation

+
+

+
+ template<typename T> +
+ using cubos::core::data::Serializer::TypedHook = memory::Function<bool(const T&)> +

+

Function type for serialization hooks.

+ + + + + + + + + + +
Template parameters
TType.
+
+
+
+

Function documentation

+
+

+ bool cubos::core::data::Serializer::write(const reflection::Type& type, + const void* value) +

+

Serialize the given value.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
typeType.
valueValue.
ReturnsWhether the value was successfully serialized.
+
+
+

+
+ template<typename T> +
+ bool cubos::core::data::Serializer::write(const T& value) +

+

Serialize the given value.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TType.
Parameters
valueValue.
ReturnsWhether the value was successfully serialized.
+
+
+

+ void cubos::core::data::Serializer::hook(const reflection::Type& type, + Hook hook) +

+

Sets the hook to be called on serialization of the given type.

+ + + + + + + + + + + + + + +
Parameters
typeType.
hookHook.
+
+
+

+
+ template<typename T> +
+ void cubos::core::data::Serializer::hook(TypedHook<T> hook) +

+

Sets the hook to be called on serialization of the given type.

+ + + + + + + + + + + + + + + + + + + +
Template parameters
TType.
Parameters
hookHook.
+
+
+

+ bool cubos::core::data::Serializer::decompose(const reflection::Type& type, + const void* value) pure virtual protected +

+

Called for each type with no hook defined.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
typeType.
valueValue.
ReturnsWhether the value was successfully serialized.
+

Should recurse by calling write() again as appropriate.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1StandardArchive.html b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1StandardArchive.html new file mode 100644 index 000000000..fb98db5c2 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1StandardArchive.html @@ -0,0 +1,434 @@ + + + + + cubos::core::data::StandardArchive class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data::StandardArchive class + +

+

Archive implementation which reads and writes from/into the OS file system using the standard library.

+ +

Can represent both regular files and directories.

+
+

Base classes

+
+
+ class Archive +
+
Interface for a bridge between the CUBOS. virtual file system and the real world.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ StandardArchive(const std::filesystem::path& osPath, + bool isDirectory, + bool readOnly) +
+
Constructs pointing to the regular file or directory with the given osPath.
+
+
+
+

Public functions

+
+
+ auto create(std::size_t parent, + std::string_view name, + bool directory = false) -> std::size_t override +
+
Creates a new file in the archive.
+
+ auto destroy(std::size_t id) -> bool override +
+
Destroys a regular file or empty directory in the archive.
+
+ auto name(std::size_t id) const -> std::string override +
+
Gets the name of the file with the given id.
+
+ auto directory(std::size_t id) const -> bool override +
+
Checks whether the file with the given id is a directory.
+
+ auto readOnly() const -> bool override +
+
Checks whether the archive is read-only.
+
+ auto parent(std::size_t id) const -> std::size_t override +
+
Gets the identifier of the parent file of the file with the given id.
+
+ auto sibling(std::size_t id) const -> std::size_t override +
+
Gets the identifier of the sibling of the file with the given id.
+
+ auto child(std::size_t id) const -> std::size_t override +
+
Gets the identifier of the first child of the file with the given id.
+
+ auto open(std::size_t id, + File::Handle handle, + File::OpenMode mode) -> std::unique_ptr<memory::Stream> override +
+
Opens a file in the archive.
+
+
+
+

Function documentation

+
+

+ cubos::core::data::StandardArchive::StandardArchive(const std::filesystem::path& osPath, + bool isDirectory, + bool readOnly) +

+

Constructs pointing to the regular file or directory with the given osPath.

+ + + + + + + + + + + + + + + + + + +
Parameters
osPathThe path to the file/directory in the real file system.
isDirectoryWhether the path is a directory or a file.
readOnlyTrue if the archive is read-only, false otherwise.
+

If readOnly is false and there's no file or directory at osPath, then it is created.

+
+
+

+ std::size_t cubos::core::data::StandardArchive::create(std::size_t parent, + std::string_view name, + bool directory = false) override +

+

Creates a new file in the archive.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
parentParent directory of the new file.
nameName of the new file.
directoryWhether the new file is a directory or not.
ReturnsIdentifier of the file, or 0 if the file could not be created.
+

The first child of the parent will have its sibling set to the new file and then be replaced by the new file.

+
+
+

+ bool cubos::core::data::StandardArchive::destroy(std::size_t id) override +

+

Destroys a regular file or empty directory in the archive.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the file.
ReturnsWhether the file was destroyed successfully.
+

Will be replaced in the tree by its sibling.

+
+
+

+ std::string cubos::core::data::StandardArchive::name(std::size_t id) const override +

+

Gets the name of the file with the given id.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the file.
ReturnsName of the file.
+
+
+

+ bool cubos::core::data::StandardArchive::directory(std::size_t id) const override +

+

Checks whether the file with the given id is a directory.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the file.
ReturnsWhether the file is a directory or not.
+
+
+

+ bool cubos::core::data::StandardArchive::readOnly() const override +

+

Checks whether the archive is read-only.

+ + + + + + + +
ReturnsWhether the archive is read-only.
+
+
+

+ std::size_t cubos::core::data::StandardArchive::parent(std::size_t id) const override +

+

Gets the identifier of the parent file of the file with the given id.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the file.
ReturnsIdentifier of the parent file, or 0 if the file is the root file.
+
+
+

+ std::size_t cubos::core::data::StandardArchive::sibling(std::size_t id) const override +

+

Gets the identifier of the sibling of the file with the given id.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the file.
ReturnsIdentifier of the sibling, or 0 if there are no more files in the parent.
+
+
+

+ std::size_t cubos::core::data::StandardArchive::child(std::size_t id) const override +

+

Gets the identifier of the first child of the file with the given id.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the file.
ReturnsIdentifier of the first child, or 0 if the file is not a directory or is empty.
+
+
+

+ std::unique_ptr<memory::Stream> cubos::core::data::StandardArchive::open(std::size_t id, + File::Handle handle, + File::OpenMode mode) override +

+

Opens a file in the archive.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the file.
handleHandle to the file.
modeMode to open the file in.
ReturnsFile stream, or nullptr if the file could not be opened.
+

Although a bit hacky, the handle parameter is used to keep a reference to the respective File alive, preventing the file from being destroyed while the stream is open.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1BinaryDeserializer.html b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1BinaryDeserializer.html new file mode 100644 index 000000000..9f01e782d --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1BinaryDeserializer.html @@ -0,0 +1,491 @@ + + + + + cubos::core::data::old::BinaryDeserializer class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data::old::BinaryDeserializer class +

+ +

Implementation of the abstract Deserializer class for deserializing from raw binary data. This class allows data to be deserialized from both little and big endian formats.

+
+

Base classes

+
+
+ class Deserializer +
+
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ BinaryDeserializer(memory::Stream& stream, + bool readLittleEndian = true) +
+
+
+
+
+

Public functions

+
+
+ void readI8(int8_t& value) override +
+
+
+ void readI16(int16_t& value) override +
+
+
+ void readI32(int32_t& value) override +
+
+
+ void readI64(int64_t& value) override +
+
+
+ void readU8(uint8_t& value) override +
+
+
+ void readU16(uint16_t& value) override +
+
+
+ void readU32(uint32_t& value) override +
+
+
+ void readU64(uint64_t& value) override +
+
+
+ void readF32(float& value) override +
+
+
+ void readF64(double& value) override +
+
+
+ void readBool(bool& value) override +
+
+
+ void readString(std::string& value) override +
+
+
+ void beginObject() override +
+
+
+ void endObject() override +
+
+
+ auto beginArray() -> std::size_t override +
+
+
+ void endArray() override +
+
+
+ auto beginDictionary() -> std::size_t override +
+
+
+ void endDictionary() override +
+
+
+
+
+

Function documentation

+
+

+ cubos::core::data::old::BinaryDeserializer::BinaryDeserializer(memory::Stream& stream, + bool readLittleEndian = true) +

+ + + + + + + + + + + + + + +
Parameters
streamThe stream to deserialize from.
readLittleEndianIf true, the data will be read in little endian format (big endian otherwise).
+
+
+

+ void cubos::core::data::old::BinaryDeserializer::readI8(int8_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a signed 8 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::BinaryDeserializer::readI16(int16_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a signed 16 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::BinaryDeserializer::readI32(int32_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a signed 32 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::BinaryDeserializer::readI64(int64_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a signed 64 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::BinaryDeserializer::readU8(uint8_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes an unsigned 8 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::BinaryDeserializer::readU16(uint16_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes an unsigned 16 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::BinaryDeserializer::readU32(uint32_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes an unsigned 32 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::BinaryDeserializer::readU64(uint64_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes an unsigned 64 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::BinaryDeserializer::readF32(float& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a float. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::BinaryDeserializer::readF64(double& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a double. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::BinaryDeserializer::readBool(bool& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a boolean. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::BinaryDeserializer::readString(std::string& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a string. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::BinaryDeserializer::beginObject() override +

+

Indicates that a object is currently being deserialized. The fail bit is set on failure.

+
+
+

+ void cubos::core::data::old::BinaryDeserializer::endObject() override +

+

Indicates that a object is no longer being deserialized. The fail bit is set on failure.

+
+
+

+ std::size_t cubos::core::data::old::BinaryDeserializer::beginArray() override +

+ + + + + + + +
ReturnsThe length of the array.
+

Indicates that an array is currently being deserialized. The fail bit is set on failure.

+
+
+

+ void cubos::core::data::old::BinaryDeserializer::endArray() override +

+

Indicates that an array is no longer being deserialized. The fail bit is set on failure.

+
+
+

+ std::size_t cubos::core::data::old::BinaryDeserializer::beginDictionary() override +

+ + + + + + + +
ReturnsThe length of the dictionary (always 0 on failure).
+

Indicates that a dictionary is being deserialized. The fail bit is set on failure.

+
+
+

+ void cubos::core::data::old::BinaryDeserializer::endDictionary() override +

+

Indicates that a dictionary is no longer being deserialized. The fail bit is set on failure.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1BinarySerializer.html b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1BinarySerializer.html new file mode 100644 index 000000000..d98ecee95 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1BinarySerializer.html @@ -0,0 +1,574 @@ + + + + + cubos::core::data::old::BinarySerializer class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data::old::BinarySerializer class +

+ +

Implementation of the abstract Serializer class for serializing to binary data. This class allows data to be serialized in both little and big endian formats.

+
+

Base classes

+
+
+ class Serializer +
+
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ BinarySerializer(memory::Stream& stream, + bool writeLittleEndian = true) +
+
+
+
+
+

Public functions

+
+
+ void writeI8(int8_t value, + const char* name) override +
+
+
+ void writeI16(int16_t value, + const char* name) override +
+
+
+ void writeI32(int32_t value, + const char* name) override +
+
+
+ void writeI64(int64_t value, + const char* name) override +
+
+
+ void writeU8(uint8_t value, + const char* name) override +
+
+
+ void writeU16(uint16_t value, + const char* name) override +
+
+
+ void writeU32(uint32_t value, + const char* name) override +
+
+
+ void writeU64(uint64_t value, + const char* name) override +
+
+
+ void writeF32(float value, + const char* name) override +
+
+
+ void writeF64(double value, + const char* name) override +
+
+
+ void writeBool(bool value, + const char* name) override +
+
+
+ void writeString(const char* str, + const char* name) override +
+
+
+ void beginObject(const char* name) override +
+
+
+ void endObject() override +
+
Indicates that a object is no longer being serialized.
+
+ void beginArray(std::size_t length, + const char* name) override +
+
+
+ void endArray() override +
+
Indicates that a array is no longer being serialized.
+
+ void beginDictionary(std::size_t length, + const char* name) override +
+
+
+ void endDictionary() override +
+
Indicates that a dictionary is no longer being serialized.
+
+
+
+

Function documentation

+
+

+ cubos::core::data::old::BinarySerializer::BinarySerializer(memory::Stream& stream, + bool writeLittleEndian = true) +

+ + + + + + + + + + + + + + +
Parameters
streamThe stream to serialize to.
writeLittleEndianIf true, the data will be written in little endian format (big endian otherwise).
+
+
+

+ void cubos::core::data::old::BinarySerializer::writeI8(int8_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes a signed 8 bit integer.

+
+
+

+ void cubos::core::data::old::BinarySerializer::writeI16(int16_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an signed 16 bit integer.

+
+
+

+ void cubos::core::data::old::BinarySerializer::writeI32(int32_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an signed 32 bit integer.

+
+
+

+ void cubos::core::data::old::BinarySerializer::writeI64(int64_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an signed 64 bit integer.

+
+
+

+ void cubos::core::data::old::BinarySerializer::writeU8(uint8_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an unsigned 8 bit integer.

+
+
+

+ void cubos::core::data::old::BinarySerializer::writeU16(uint16_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an unsigned 16 bit integer.

+
+
+

+ void cubos::core::data::old::BinarySerializer::writeU32(uint32_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an unsigned 32 bit integer.

+
+
+

+ void cubos::core::data::old::BinarySerializer::writeU64(uint64_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an unsigned 64 bit integer.

+
+
+

+ void cubos::core::data::old::BinarySerializer::writeF32(float value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes a float.

+
+
+

+ void cubos::core::data::old::BinarySerializer::writeF64(double value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes a double.

+
+
+

+ void cubos::core::data::old::BinarySerializer::writeBool(bool value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes a boolean.

+
+
+

+ void cubos::core::data::old::BinarySerializer::writeString(const char* str, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
strThe string to serialize.
nameThe name of the value (optional).
+

Serializes a string.

+
+
+

+ void cubos::core::data::old::BinarySerializer::beginObject(const char* name) override +

+ + + + + + + + + + +
Parameters
nameThe name of the object (optional).
+

Indicates that a object is currently being serialized.

+
+
+

+ void cubos::core::data::old::BinarySerializer::beginArray(std::size_t length, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
lengthThe length of the array.
nameThe name of the array (optional).
+

Indicates that a array is currently being serialized.

+
+
+

+ void cubos::core::data::old::BinarySerializer::beginDictionary(std::size_t length, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
lengthThe length of the dictionary.
nameThe name of the dictionary (optional).
+

Indicates that a dictionary is currently being serialized.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1Context.html b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1Context.html new file mode 100644 index 000000000..ccecb364d --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1Context.html @@ -0,0 +1,248 @@ + + + + + cubos::core::data::old::Context class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data::old::Context class final +

+ +

Stores the context necessary to serialize or deserialize data. This is done through a type map, which stores an instance for each type added (akin to the ECS resources).

+
+

Public functions

+
+
+
template<typename T>
+ void push(T data) +
+
+
+ void pushSubContext(Context& context) +
+
+
+ void pop() +
+
+
+
template<typename T>
+ auto get() -> T& +
+
+
+
template<typename T>
+ auto has() const -> bool +
+
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ void cubos::core::data::old::Context::push(T data) +

+ + + + + + + + + + + + + + + + + + + +
Template parameters
TThe type of the data.
Parameters
dataThe data to push.
+

Pushes a new value to the stack.

+
+
+

+ void cubos::core::data::old::Context::pushSubContext(Context& context) +

+ + + + + + + + + + +
Parameters
contextThe context to push.
+

Pushes a new sub-context to the stack. The sub-context acts as a group of values associated with a single push. The reference must be valid until the sub-context is popped.

+
+
+

+ void cubos::core::data::old::Context::pop() +

+

Pops the top value or sub-context from the stack. This must be called once for each push.

+
+
+

+
+ template<typename T> +
+ T& cubos::core::data::old::Context::get() +

+ + + + + + + + + + + + + + + + +
Template parameters
TThe type of the data.
Returnsthe data associated with the given type.
+

Gets the data associated with the given type. If the type is present multiple times, the topmost one is returned. Aborts if the data is not present.

+
+
+

+
+ template<typename T> +
+ bool cubos::core::data::old::Context::has() const +

+ + + + + + + + + + + + + + + + +
Template parameters
TThe type of the data.
ReturnsTrue if the data is present, false otherwise.
+

Checks if there is data associated with the given type.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1Deserializer.html b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1Deserializer.html new file mode 100644 index 000000000..8d5f91734 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1Deserializer.html @@ -0,0 +1,557 @@ + + + + + cubos::core::data::old::Deserializer class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data::old::Deserializer class +

+ +

Abstract class for deserializing data in a format-agnostic way. Each deserializer implementation is responsible for implementing its own primitive deserialization methods: readI8, readString, etc.

More complex types can be deserialized by implementing a specialization of the cubos::core::data::old::deserialize function:

struct MyType
+{
+    int32_t a;
+};
+
+// In the corresponding .cpp file.
+void cubos::core::data::old::deserialize<MyType>(Deserializer& d, MyType& obj)
+{
+    d.read(obj.a, "a");
+}
+
+// Alternatively, the type can define a `deserialize` method.
+
+class MyType
+{
+public:
+    void deserialize(Deserializer& d);
+
+private:
+    int32_t a;
+}; 
+
+
+

Derived classes

+
+
+ class BinaryDeserializer +
+
+
+ class JSONDeserializer +
+
Implementation of the abstract Deserializer class for deserializing from JSON.
+
+ class Unpackager +
+
Responsible for deserializing packages into types.
+
+
+
+

Public functions

+
+
+ void readI8(int8_t& value) pure virtual +
+
+
+ void readI16(int16_t& value) pure virtual +
+
+
+ void readI32(int32_t& value) pure virtual +
+
+
+ void readI64(int64_t& value) pure virtual +
+
+
+ void readU8(uint8_t& value) pure virtual +
+
+
+ void readU16(uint16_t& value) pure virtual +
+
+
+ void readU32(uint32_t& value) pure virtual +
+
+
+ void readU64(uint64_t& value) pure virtual +
+
+
+ void readF32(float& value) pure virtual +
+
+
+ void readF64(double& value) pure virtual +
+
+
+ void readBool(bool& value) pure virtual +
+
+
+ void readString(std::string& value) pure virtual +
+
+
+
template<typename T>
+ void read(T& obj) +
+
+
+ void beginObject() pure virtual +
+
+
+ void endObject() pure virtual +
+
+
+ auto beginArray() -> std::size_t pure virtual +
+
+
+ void endArray() pure virtual +
+
+
+ auto beginDictionary() -> std::size_t pure virtual +
+
+
+ void endDictionary() pure virtual +
+
+
+ auto failed() const -> bool +
+
Checks if the deserializer has failed.
+
+ void fail() +
+
Sets the fail bit.
+
+ auto context() -> Context& +
+
+
+
+
+

Protected variables

+
+
+ bool mFailBit +
+
Indicates if the deserializer has failed.
+
+
+
+

Function documentation

+
+

+ void cubos::core::data::old::Deserializer::readI8(int8_t& value) pure virtual +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a signed 8 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Deserializer::readI16(int16_t& value) pure virtual +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a signed 16 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Deserializer::readI32(int32_t& value) pure virtual +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a signed 32 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Deserializer::readI64(int64_t& value) pure virtual +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a signed 64 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Deserializer::readU8(uint8_t& value) pure virtual +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes an unsigned 8 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Deserializer::readU16(uint16_t& value) pure virtual +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes an unsigned 16 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Deserializer::readU32(uint32_t& value) pure virtual +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes an unsigned 32 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Deserializer::readU64(uint64_t& value) pure virtual +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes an unsigned 64 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Deserializer::readF32(float& value) pure virtual +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a float. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Deserializer::readF64(double& value) pure virtual +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a double. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Deserializer::readBool(bool& value) pure virtual +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a boolean. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Deserializer::readString(std::string& value) pure virtual +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a string. The fail bit is set if the deserialization fails.

+
+
+

+
+ template<typename T> +
+ void cubos::core::data::old::Deserializer::read(T& obj) +

+ + + + + + + + + + + + + + + + + + + +
Template parameters
TThe type of the object.
Parameters
objThe object to deserialize.
+

Deserializes an object. The cubos::core::data::old::deserialize function must be implemented for the given type. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Deserializer::beginObject() pure virtual +

+

Indicates that a object is currently being deserialized. The fail bit is set on failure.

+
+
+

+ void cubos::core::data::old::Deserializer::endObject() pure virtual +

+

Indicates that a object is no longer being deserialized. The fail bit is set on failure.

+
+
+

+ std::size_t cubos::core::data::old::Deserializer::beginArray() pure virtual +

+ + + + + + + +
ReturnsThe length of the array.
+

Indicates that an array is currently being deserialized. The fail bit is set on failure.

+
+
+

+ void cubos::core::data::old::Deserializer::endArray() pure virtual +

+

Indicates that an array is no longer being deserialized. The fail bit is set on failure.

+
+
+

+ std::size_t cubos::core::data::old::Deserializer::beginDictionary() pure virtual +

+ + + + + + + +
ReturnsThe length of the dictionary (always 0 on failure).
+

Indicates that a dictionary is being deserialized. The fail bit is set on failure.

+
+
+

+ void cubos::core::data::old::Deserializer::endDictionary() pure virtual +

+

Indicates that a dictionary is no longer being deserialized. The fail bit is set on failure.

+
+
+

+ Context& cubos::core::data::old::Deserializer::context() +

+ + + + + + + +
ReturnsThe context of the serializer.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1JSONDeserializer.html b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1JSONDeserializer.html new file mode 100644 index 000000000..127906e8b --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1JSONDeserializer.html @@ -0,0 +1,485 @@ + + + + + cubos::core::data::old::JSONDeserializer class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data::old::JSONDeserializer class +

+

Implementation of the abstract Deserializer class for deserializing from JSON.

+ +
+

Base classes

+
+
+ class Deserializer +
+
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ JSONDeserializer(const std::string& src) +
+
+
+
+
+

Public functions

+
+
+ void readI8(int8_t& value) override +
+
+
+ void readI16(int16_t& value) override +
+
+
+ void readI32(int32_t& value) override +
+
+
+ void readI64(int64_t& value) override +
+
+
+ void readU8(uint8_t& value) override +
+
+
+ void readU16(uint16_t& value) override +
+
+
+ void readU32(uint32_t& value) override +
+
+
+ void readU64(uint64_t& value) override +
+
+
+ void readF32(float& value) override +
+
+
+ void readF64(double& value) override +
+
+
+ void readBool(bool& value) override +
+
+
+ void readString(std::string& value) override +
+
+
+ void beginObject() override +
+
+
+ void endObject() override +
+
+
+ auto beginArray() -> std::size_t override +
+
+
+ void endArray() override +
+
+
+ auto beginDictionary() -> std::size_t override +
+
+
+ void endDictionary() override +
+
+
+
+
+

Function documentation

+
+

+ cubos::core::data::old::JSONDeserializer::JSONDeserializer(const std::string& src) +

+ + + + + + + + + + +
Parameters
srcThe string to deserialize from. Must correspond to a JSON literal/object/array.
+
+
+

+ void cubos::core::data::old::JSONDeserializer::readI8(int8_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a signed 8 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::JSONDeserializer::readI16(int16_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a signed 16 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::JSONDeserializer::readI32(int32_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a signed 32 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::JSONDeserializer::readI64(int64_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a signed 64 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::JSONDeserializer::readU8(uint8_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes an unsigned 8 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::JSONDeserializer::readU16(uint16_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes an unsigned 16 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::JSONDeserializer::readU32(uint32_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes an unsigned 32 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::JSONDeserializer::readU64(uint64_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes an unsigned 64 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::JSONDeserializer::readF32(float& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a float. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::JSONDeserializer::readF64(double& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a double. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::JSONDeserializer::readBool(bool& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a boolean. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::JSONDeserializer::readString(std::string& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a string. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::JSONDeserializer::beginObject() override +

+

Indicates that a object is currently being deserialized. The fail bit is set on failure.

+
+
+

+ void cubos::core::data::old::JSONDeserializer::endObject() override +

+

Indicates that a object is no longer being deserialized. The fail bit is set on failure.

+
+
+

+ std::size_t cubos::core::data::old::JSONDeserializer::beginArray() override +

+ + + + + + + +
ReturnsThe length of the array.
+

Indicates that an array is currently being deserialized. The fail bit is set on failure.

+
+
+

+ void cubos::core::data::old::JSONDeserializer::endArray() override +

+

Indicates that an array is no longer being deserialized. The fail bit is set on failure.

+
+
+

+ std::size_t cubos::core::data::old::JSONDeserializer::beginDictionary() override +

+ + + + + + + +
ReturnsThe length of the dictionary (always 0 on failure).
+

Indicates that a dictionary is being deserialized. The fail bit is set on failure.

+
+
+

+ void cubos::core::data::old::JSONDeserializer::endDictionary() override +

+

Indicates that a dictionary is no longer being deserialized. The fail bit is set on failure.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1JSONSerializer.html b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1JSONSerializer.html new file mode 100644 index 000000000..3cda5c310 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1JSONSerializer.html @@ -0,0 +1,574 @@ + + + + + cubos::core::data::old::JSONSerializer class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data::old::JSONSerializer class +

+ +

Implementation of the abstract Serializer class for serializing to JSON. Each time a top-level primitive/object/array/dictionary is written, its JSON output is written to the underlying stream.

+
+

Base classes

+
+
+ class Serializer +
+
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ JSONSerializer(memory::Stream& stream, + int indent = -1) +
+
+
+
+
+

Public functions

+
+
+ void writeI8(int8_t value, + const char* name) override +
+
+
+ void writeI16(int16_t value, + const char* name) override +
+
+
+ void writeI32(int32_t value, + const char* name) override +
+
+
+ void writeI64(int64_t value, + const char* name) override +
+
+
+ void writeU8(uint8_t value, + const char* name) override +
+
+
+ void writeU16(uint16_t value, + const char* name) override +
+
+
+ void writeU32(uint32_t value, + const char* name) override +
+
+
+ void writeU64(uint64_t value, + const char* name) override +
+
+
+ void writeF32(float value, + const char* name) override +
+
+
+ void writeF64(double value, + const char* name) override +
+
+
+ void writeBool(bool value, + const char* name) override +
+
+
+ void writeString(const char* str, + const char* name) override +
+
+
+ void beginObject(const char* name) override +
+
+
+ void endObject() override +
+
Indicates that a object is no longer being serialized.
+
+ void beginArray(std::size_t length, + const char* name) override +
+
+
+ void endArray() override +
+
Indicates that a array is no longer being serialized.
+
+ void beginDictionary(std::size_t length, + const char* name) override +
+
+
+ void endDictionary() override +
+
Indicates that a dictionary is no longer being serialized.
+
+
+
+

Function documentation

+
+

+ cubos::core::data::old::JSONSerializer::JSONSerializer(memory::Stream& stream, + int indent = -1) +

+ + + + + + + + + + + + + + +
Parameters
streamThe stream to serialize to.
indentThe JSON output indentantion (-1 means no indentation).
+
+
+

+ void cubos::core::data::old::JSONSerializer::writeI8(int8_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes a signed 8 bit integer.

+
+
+

+ void cubos::core::data::old::JSONSerializer::writeI16(int16_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an signed 16 bit integer.

+
+
+

+ void cubos::core::data::old::JSONSerializer::writeI32(int32_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an signed 32 bit integer.

+
+
+

+ void cubos::core::data::old::JSONSerializer::writeI64(int64_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an signed 64 bit integer.

+
+
+

+ void cubos::core::data::old::JSONSerializer::writeU8(uint8_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an unsigned 8 bit integer.

+
+
+

+ void cubos::core::data::old::JSONSerializer::writeU16(uint16_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an unsigned 16 bit integer.

+
+
+

+ void cubos::core::data::old::JSONSerializer::writeU32(uint32_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an unsigned 32 bit integer.

+
+
+

+ void cubos::core::data::old::JSONSerializer::writeU64(uint64_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an unsigned 64 bit integer.

+
+
+

+ void cubos::core::data::old::JSONSerializer::writeF32(float value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes a float.

+
+
+

+ void cubos::core::data::old::JSONSerializer::writeF64(double value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes a double.

+
+
+

+ void cubos::core::data::old::JSONSerializer::writeBool(bool value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes a boolean.

+
+
+

+ void cubos::core::data::old::JSONSerializer::writeString(const char* str, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
strThe string to serialize.
nameThe name of the value (optional).
+

Serializes a string.

+
+
+

+ void cubos::core::data::old::JSONSerializer::beginObject(const char* name) override +

+ + + + + + + + + + +
Parameters
nameThe name of the object (optional).
+

Indicates that a object is currently being serialized.

+
+
+

+ void cubos::core::data::old::JSONSerializer::beginArray(std::size_t length, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
lengthThe length of the array.
nameThe name of the array (optional).
+

Indicates that a array is currently being serialized.

+
+
+

+ void cubos::core::data::old::JSONSerializer::beginDictionary(std::size_t length, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
lengthThe length of the dictionary.
nameThe name of the dictionary (optional).
+

Indicates that a dictionary is currently being serialized.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1Package.html b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1Package.html new file mode 100644 index 000000000..24b11eb6c --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1Package.html @@ -0,0 +1,849 @@ + + + + + cubos::core::data::old::Package class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data::old::Package class final +

+

A utility object which is capable of storing the data of any trivially serializable object. One way to understand this class is to think of it as if it were a JSON representation of an object.

+ +

While packages are serialiable, they are not deserializable. This is because there's no way to know what type the package was serialized from. If you know what type the package was serialized from, and want to deserialize it, you can use the type's deserialization function.

Usage example:

auto pkg = Package::from(mySerializableObject);
+pkg.field("position").field("x").set(1.0f);
+pkg.field("position").field("y").set(2.0f);
+pkg.field("position").field("z").set(3.0f);
+pkg.into(myDeserializableObject);
+// myDeserializableObject will hold the same data as
+// mySerilizableObject but with the position set to (1, 2, 3).
+
+
+

Public types

+
+
+ enum class Type { None, + I8, + I16, + I32, + I64, + U8, + U16, + U32, + U64, + F32, + F64, + Bool, + String, + Object, + Array, + Dictionary } +
+
Used to identify the type of the packaged data.
+
+ using Fields = std::vector<std::pair<std::string, Package>> +
+
Type alias for the map used to store the object fields.
+
+ using Elements = std::vector<Package> +
+
Type alias for the vector used to store the array elements.
+
+ using Dictionary = std::vector<std::pair<Package, Package>> +
+
Type alias for the vector used to store the dictionary pairs.
+
+ using Data = std::variant<std::monostate, int8_t, int16_t, int32_t, int64_t, uint8_t, uint16_t, uint32_t, uint64_t, float, double, bool, std::string, Fields, Elements, Dictionary> +
+
+
+
+
+

Public static functions

+
+
+
template<typename T>
+ static auto from(const T& data, + Context* context = nullptr) -> Package +
+
+
+ static auto typeToString(Type type) -> const char* +
+
+
+
+
+

Public functions

+
+
+
template<typename T>
+ void set(const T& data, + Context* context = nullptr) +
+
+
+ auto change(int64_t data) -> bool +
+
+
+ auto change(uint64_t data) -> bool +
+
+
+ auto change(double data) -> bool +
+
+
+ auto change(bool data) -> bool +
+
+
+ auto change(const std::string& data) -> bool +
+
+
+
template<typename T>
+ auto into(T& data, + Context* context = nullptr) const -> bool +
+
+
+
template<typename T>
+ auto get(Context* context = nullptr) const -> requires std::default_initializable<T> T +
+
+
+ auto type() const -> Type +
+
+
+ auto size() const -> std::size_t +
+
+
+ auto isStructured() const -> bool +
+
+
+ auto field(const std::string& name) -> Package& +
+
+
+ auto fields() -> Fields& +
+
+
+ auto fields() const -> const Fields& +
+
+
+ auto removeField(std::string_view name) -> Package +
+
+
+ auto element(std::size_t index) -> Package& +
+
+
+ auto elements() -> Elements& +
+
+
+ auto elements() const -> const Elements& +
+
+
+ auto dictionary() -> Dictionary& +
+
+
+ auto dictionary() const -> const Dictionary& +
+
+
+
+
+

Enum documentation

+
+

+ enum class cubos::core::data::old::Package::Type +

+

Used to identify the type of the packaged data.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Enumerators
None +

The package doesn't contain anything.

+
I8 +

The package contains a signed 8-bit integer.

+
I16 +

The package contains a signed 16-bit integer.

+
I32 +

The package contains a signed 32-bit integer.

+
I64 +

The package contains a signed 64-bit integer.

+
U8 +

The package contains an unsigned 8-bit integer.

+
U16 +

The package contains an unsigned 16-bit integer.

+
U32 +

The package contains an unsigned 32-bit integer.

+
U64 +

The package contains an unsigned 64-bit integer.

+
F32 +

The package contains a 32-bit floating point number.

+
F64 +

The package contains a 64-bit floating point number.

+
Bool +

The package contains a boolean value.

+
String +

The package contains a string.

+
Object +

The package contains an object with fields.

+
Array +

The package contains an array.

+
Dictionary +

The packages contains a dictionary.

+
+
+
+
+

Typedef documentation

+
+

+ using cubos::core::data::old::Package::Data = std::variant<std::monostate, int8_t, int16_t, int32_t, int64_t, uint8_t, uint16_t, uint32_t, uint64_t, float, double, bool, std::string, Fields, Elements, Dictionary> +

+

Type alias for the variant used to store the package's data. The types must be defined in the same order as the Type enum.

+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ static Package cubos::core::data::old::Package::from(const T& data, + Context* context = nullptr) +

+ + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TThe type of the data to package.
Parameters
dataThe data to package.
contextOptional context to use when packaging the data.
+

Packages serializable data and returns the result.

+
+
+

+ static const char* cubos::core::data::old::Package::typeToString(Type type) +

+ + + + + + + + + + + + + + + + +
Parameters
typeThe type to convert.
ReturnsThe string representation of the type.
+

Converts a package type into its string representation.

+
+
+

+
+ template<typename T> +
+ void cubos::core::data::old::Package::set(const T& data, + Context* context = nullptr) +

+ + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TThe type of the data to package.
Parameters
dataThe data to package.
contextOptional context to use when packaging the data.
+

Packages the specified data into this package. This will change the type of the package. This may be a problem in some cases. For example, if an uint8_t is packaged, then set to a uint16_t, and then binary serialized, it won't be deserializable back to an uint8_t (only to a uint16_t). One way to avoid this problem is to use Package::change instead.

+
+
+

+ bool cubos::core::data::old::Package::change(int64_t data) +

+ + + + + + + + + + + + + + + + +
Parameters
dataThe data to package.
ReturnsTrue on success, false on failure.
+

Packages the specified int64_t into this package, without changing the type of the package. If the types aren't compatible, this will fail. For example, 255 would be compatible with uint8_t, but -1 or 256 would not.

+
+
+

+ bool cubos::core::data::old::Package::change(uint64_t data) +

+ + + + + + + + + + + + + + + + +
Parameters
dataThe data to package.
ReturnsTrue on success, false on failure.
+

Packages the specified uint64_t into this package, without changing the type of the package. If the types aren't compatible, this will fail. For example, 255 would be compatible with uint8_t, but 256 would not.

+
+
+

+ bool cubos::core::data::old::Package::change(double data) +

+ + + + + + + + + + + + + + + + +
Parameters
dataThe data to package.
ReturnsTrue on success, false on failure.
+

Packages the specified double into this package, without changing the type of the package. If the types aren't compatible, this will fail. If the underlying type is a float, the precision will be lowered.

+
+
+

+ bool cubos::core::data::old::Package::change(bool data) +

+ + + + + + + + + + + + + + + + +
Parameters
dataThe data to package.
ReturnsTrue on success, false on failure.
+

Packages the specified bool into this package, without changing the type of the package. If the package isn't a bool, this will fail.

+
+
+

+ bool cubos::core::data::old::Package::change(const std::string& data) +

+ + + + + + + + + + + + + + + + +
Parameters
dataThe data to package.
ReturnsTrue on success, false on failure.
+

Packages the specified string into this package, without changing the type of the package. If the package isn't a string already, this will fail.

+
+
+

+
+ template<typename T> +
+ bool cubos::core::data::old::Package::into(T& data, + Context* context = nullptr) const +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TThe type of the data to unpackage.
Parameters
dataThe data to write to.
contextOptional context to use when unpackaging the data.
ReturnsTrue if the unpackaging succeeded, false otherwise.
+

Unpackages the package into data. If there is a field missing or there's a type mismatch, the unpackaging may fail. It is guaranteed that unpackaging a package created from a certain type to the same type never fails.

+
+
+

+
+ template<typename T> +
+ requires std::default_initializable<T> T cubos::core::data::old::Package::get(Context* context = nullptr) const +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TThe type of the data to unpackage.
Parameters
contextOptional context to use when unpackaging the data.
ReturnsThe data.
+

Alternative to Package::into for types which are default constructible. Unpackages the package and returns the data, and aborts if the type isn't the expected. Should only be used when you're sure the type is correct.

+
+
+

+ Type cubos::core::data::old::Package::type() const +

+ + + + + + + +
ReturnsThe type of the packaged data.
+
+
+

+ std::size_t cubos::core::data::old::Package::size() const +

+ + + + + + + +
ReturnsThe size of the packaged
+

Gets the size of the package. For empty packages, or scalars (including strings), this is always 0, or 1, respectively. For objects, arrays and dictionaries, this is, respectively, the field count, the element count and the key-value pair count.

+
+
+

+ bool cubos::core::data::old::Package::isStructured() const +

+ + + + + + + +
ReturnsTrue if the package is storing a structured data type, false otherwise.
+

Checks if the package is storing a structured data type (object, array or dictionary).

+
+
+

+ Package& cubos::core::data::old::Package::field(const std::string& name) +

+ + + + + + + + + + + + + + + + +
Parameters
nameThe name of the field.
ReturnsA reference to the field.
+

Gets a reference to a field of this package. If the package isn't storing an object or if the field doesn't exist, this method will abort.

+
+
+

+ Fields& cubos::core::data::old::Package::fields() +

+ + + + + + + +
ReturnsA map associating the field name to the field package.
+

Gets all of the fields in this package. If the package isn't storing an object, this method will abort.

+
+
+

+ const Fields& cubos::core::data::old::Package::fields() const +

+ + + + + + + +
ReturnsA map associating the field name to the field package.
+

Gets all of the fields in this package. If the package isn't storing an object, this method will abort.

+
+
+

+ Package cubos::core::data::old::Package::removeField(std::string_view name) +

+ + + + + + + + + + + + + + + + +
Parameters
nameThe name of the field.
ReturnsThe removed field, or an empty package if the field didn't exist.
+

Removes a field from this package. If the package isn't storing an object, this method will abort.

+
+
+

+ Package& cubos::core::data::old::Package::element(std::size_t index) +

+ + + + + + + + + + + + + + + + +
Parameters
indexThe index of the element in the array.
ReturnsA reference to the element.
+

Gets an element of the array stored in this package. If the package isn't an array, this method will abort. If the index is out of bounds, this method will abort.

+
+
+

+ Elements& cubos::core::data::old::Package::elements() +

+ + + + + + + +
ReturnsA vector of the packaged elements.
+

Gets the array stored in this package. If the package isn't an array, this method will abort.

+
+
+

+ const Elements& cubos::core::data::old::Package::elements() const +

+ + + + + + + +
ReturnsA vector of the packaged elements.
+

Gets the array stored in this package. If the package isn't an array, this method will abort.

+
+
+

+ Dictionary& cubos::core::data::old::Package::dictionary() +

+

Gets the dictionary stored in this package. The dictionary is returned as a vector of the packaged key-value pairs. If the package isn't a dictionary, this method will abort.

+
+
+

+ const Dictionary& cubos::core::data::old::Package::dictionary() const +

+

Gets the dictionary stored in this package. The dictionary is returned as a vector of the packaged key-value pairs. If the package isn't a dictionary, this method will abort.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1SerializationMap.html b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1SerializationMap.html new file mode 100644 index 000000000..a07763b47 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1SerializationMap.html @@ -0,0 +1,377 @@ + + + + + cubos::core::data::old::SerializationMap class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+
template<typename R, typename I, typename RH = std::hash<R>, typename IH = std::hash<I>>
+ cubos::core::data::old::SerializationMap class final +

+ + + + + + + + + + + + + + + + + + + + + + +
Template parameters
RReference type.
ISerialized identifier type.
RHReference hash type.
IHIdentifier hash type.
+ +

Class used to map between references and their serialized identifiers.

+
+

Constructors, destructors, conversion operators

+
+
+ SerializationMap(std::function<bool(const R&, I&)> serialize, + std::function<bool(R&, const I&)> deserialize) +
+
+
+
+
+

Public functions

+
+
+ void add(const R& reference, + const I& id) +
+
+
+ auto hasRef(const R& reference) const -> bool +
+
+
+ auto hasId(const I& id) const -> bool +
+
+
+ auto getRef(const I& id) const -> R +
+
+
+ auto getId(const R& reference) const -> I +
+
+
+ void clear() +
+
Clears the map.
+
+ auto size() const -> std::size_t +
+
+
+ auto getMap() const -> std::unordered_map<R, I, RH> +
+
Returns the internal map that maps references to IDs.
+
+
+
+

Function documentation

+
+

+
+ template<typename R, typename I, typename RH, typename IH> +
+ cubos::core::data::old::SerializationMap<R, I, RH, IH>::SerializationMap(std::function<bool(const R&, I&)> serialize, + std::function<bool(R&, const I&)> deserialize) +

+ + + + + + + + + + + + + + +
Parameters
serializeFunction used to serialize references.
deserializeFunction used to deserialize references.
+

Makes the serialization map use functions instead of keeping a map.

+
+
+

+
+ template<typename R, typename I, typename RH, typename IH> +
+ void cubos::core::data::old::SerializationMap<R, I, RH, IH>::add(const R& reference, + const I& id) +

+ + + + + + + + + + + + + + +
Parameters
referenceReference to add.
idSerialized identifier to add.
+

Adds a reference <-> serialized identifier pair.

+
+
+

+
+ template<typename R, typename I, typename RH, typename IH> +
+ bool cubos::core::data::old::SerializationMap<R, I, RH, IH>::hasRef(const R& reference) const +

+ + + + + + + + + + + + + + + + +
Parameters
referenceReference to check.
ReturnsTrue if the reference is in the map, false otherwise.
+

Checks if a reference is in the map.

+
+
+

+
+ template<typename R, typename I, typename RH, typename IH> +
+ bool cubos::core::data::old::SerializationMap<R, I, RH, IH>::hasId(const I& id) const +

+ + + + + + + + + + + + + + + + +
Parameters
idSerialized identifier to check.
ReturnsTrue if the serialized identifier is in the map, false otherwise.
+

Checks if a serialized identifier is in the map.

+
+
+

+
+ template<typename R, typename I, typename RH, typename IH> +
+ R cubos::core::data::old::SerializationMap<R, I, RH, IH>::getRef(const I& id) const +

+ + + + + + + + + + + + + + + + +
Parameters
idSerialized identifier to get the reference of.
ReturnsReference of the serialized identifier.
+

Gets the reference of a serialized identifier.

+
+
+

+
+ template<typename R, typename I, typename RH, typename IH> +
+ I cubos::core::data::old::SerializationMap<R, I, RH, IH>::getId(const R& reference) const +

+ + + + + + + + + + + + + + + + +
Parameters
referenceReference to get the serialized identifier of.
ReturnsSerialized identifier of the reference.
+

Gets the serialized identifier of a reference.

+
+
+

+
+ template<typename R, typename I, typename RH, typename IH> +
+ std::size_t cubos::core::data::old::SerializationMap<R, I, RH, IH>::size() const +

+ + + + + + + +
ReturnsNumber of mapped references.
+

Gets the number of mapped references.

+
+
+

+
+ template<typename R, typename I, typename RH, typename IH> +
+ std::unordered_map<R, I, RH> cubos::core::data::old::SerializationMap<R, I, RH, IH>::getMap() const +

+

Returns the internal map that maps references to IDs.

+ + + + + + + +
ReturnsMap of references and Ids.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1Serializer.html b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1Serializer.html new file mode 100644 index 000000000..f7f268775 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1Serializer.html @@ -0,0 +1,652 @@ + + + + + cubos::core::data::old::Serializer class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data::old::Serializer class +

+ +

Abstract class for serializing data in a format-agnostic way. Each serializer implementation is responsible for implementing its own primitive serialization methods: writeI8, writeString, etc.

More complex types can be serialized by implementing a specialization of the cubos::core::data::old::serialize function:

struct MyType
+{
+    int32_t a;
+};
+
+// In the corresponding .cpp file.
+void cubos::core::data::old::serialize<MyType>(Serializer& s, const MyType& obj, const char* name)
+{
+    s.write(obj.a, "a");
+}
+
+// Alternatively, the type can define a `serialize` method.
+
+class MyType
+{
+public:
+    void serialize(Serializer& s, const char* name);
+
+private:
+    int32_t a;
+}; 
+
+
+

Derived classes

+
+
+ class BinarySerializer +
+
+
+ class JSONSerializer +
+
+
+ class Packager +
+
+
+
+
+

Public functions

+
+
+ void flush() virtual +
+
+
+ void writeI8(int8_t value, + const char* name) pure virtual +
+
+
+ void writeI16(int16_t value, + const char* name) pure virtual +
+
+
+ void writeI32(int32_t value, + const char* name) pure virtual +
+
+
+ void writeI64(int64_t value, + const char* name) pure virtual +
+
+
+ void writeU8(uint8_t value, + const char* name) pure virtual +
+
+
+ void writeU16(uint16_t value, + const char* name) pure virtual +
+
+
+ void writeU32(uint32_t value, + const char* name) pure virtual +
+
+
+ void writeU64(uint64_t value, + const char* name) pure virtual +
+
+
+ void writeF32(float value, + const char* name) pure virtual +
+
+
+ void writeF64(double value, + const char* name) pure virtual +
+
+
+ void writeBool(bool value, + const char* name) pure virtual +
+
+
+ void writeString(const char* str, + const char* name) pure virtual +
+
+
+
template<typename T>
+ void write(const T& obj, + const char* name) +
+
+
+ void beginObject(const char* name) pure virtual +
+
+
+ void endObject() pure virtual +
+
Indicates that a object is no longer being serialized.
+
+ void beginArray(std::size_t length, + const char* name) pure virtual +
+
+
+ void endArray() pure virtual +
+
Indicates that a array is no longer being serialized.
+
+ void beginDictionary(std::size_t length, + const char* name) pure virtual +
+
+
+ void endDictionary() pure virtual +
+
Indicates that a dictionary is no longer being serialized.
+
+ auto failed() const -> bool +
+
Checks if the serializer has failed.
+
+ auto context() -> Context& +
+
+
+
+
+

Protected variables

+
+
+ bool mFailBit +
+
Indicates if the serializer failed.
+
+
+
+

Function documentation

+
+

+ void cubos::core::data::old::Serializer::flush() virtual +

+

Flushes the serializer, guaranteeing that all data has already been processed. This is automatically called when the serializer is destroyed.

+
+
+

+ void cubos::core::data::old::Serializer::writeI8(int8_t value, + const char* name) pure virtual +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes a signed 8 bit integer.

+
+
+

+ void cubos::core::data::old::Serializer::writeI16(int16_t value, + const char* name) pure virtual +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an signed 16 bit integer.

+
+
+

+ void cubos::core::data::old::Serializer::writeI32(int32_t value, + const char* name) pure virtual +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an signed 32 bit integer.

+
+
+

+ void cubos::core::data::old::Serializer::writeI64(int64_t value, + const char* name) pure virtual +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an signed 64 bit integer.

+
+
+

+ void cubos::core::data::old::Serializer::writeU8(uint8_t value, + const char* name) pure virtual +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an unsigned 8 bit integer.

+
+
+

+ void cubos::core::data::old::Serializer::writeU16(uint16_t value, + const char* name) pure virtual +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an unsigned 16 bit integer.

+
+
+

+ void cubos::core::data::old::Serializer::writeU32(uint32_t value, + const char* name) pure virtual +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an unsigned 32 bit integer.

+
+
+

+ void cubos::core::data::old::Serializer::writeU64(uint64_t value, + const char* name) pure virtual +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an unsigned 64 bit integer.

+
+
+

+ void cubos::core::data::old::Serializer::writeF32(float value, + const char* name) pure virtual +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes a float.

+
+
+

+ void cubos::core::data::old::Serializer::writeF64(double value, + const char* name) pure virtual +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes a double.

+
+
+

+ void cubos::core::data::old::Serializer::writeBool(bool value, + const char* name) pure virtual +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes a boolean.

+
+
+

+ void cubos::core::data::old::Serializer::writeString(const char* str, + const char* name) pure virtual +

+ + + + + + + + + + + + + + +
Parameters
strThe string to serialize.
nameThe name of the value (optional).
+

Serializes a string.

+
+
+

+
+ template<typename T> +
+ void cubos::core::data::old::Serializer::write(const T& obj, + const char* name) +

+ + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TThe type of the object.
Parameters
objThe object to serialize.
nameThe name of the object (optional).
+

Serializes an object. The cubos::core::data::old::serialize function must be implemented for the given type.

+
+
+

+ void cubos::core::data::old::Serializer::beginObject(const char* name) pure virtual +

+ + + + + + + + + + +
Parameters
nameThe name of the object (optional).
+

Indicates that a object is currently being serialized.

+
+
+

+ void cubos::core::data::old::Serializer::beginArray(std::size_t length, + const char* name) pure virtual +

+ + + + + + + + + + + + + + +
Parameters
lengthThe length of the array.
nameThe name of the array (optional).
+

Indicates that a array is currently being serialized.

+
+
+

+ void cubos::core::data::old::Serializer::beginDictionary(std::size_t length, + const char* name) pure virtual +

+ + + + + + + + + + + + + + +
Parameters
lengthThe length of the dictionary.
nameThe name of the dictionary (optional).
+

Indicates that a dictionary is currently being serialized.

+
+
+

+ Context& cubos::core::data::old::Serializer::context() +

+ + + + + + + +
ReturnsThe context of the serializer.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1Unpackager.html b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1Unpackager.html new file mode 100644 index 000000000..41003321b --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1Unpackager.html @@ -0,0 +1,485 @@ + + + + + cubos::core::data::old::Unpackager class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data::old::Unpackager class +

+

Responsible for deserializing packages into types.

+ +
+

Base classes

+
+
+ class Deserializer +
+
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ Unpackager(const Package& pkg) +
+
+
+
+
+

Public functions

+
+
+ void readI8(int8_t& value) override +
+
+
+ void readI16(int16_t& value) override +
+
+
+ void readI32(int32_t& value) override +
+
+
+ void readI64(int64_t& value) override +
+
+
+ void readU8(uint8_t& value) override +
+
+
+ void readU16(uint16_t& value) override +
+
+
+ void readU32(uint32_t& value) override +
+
+
+ void readU64(uint64_t& value) override +
+
+
+ void readF32(float& value) override +
+
+
+ void readF64(double& value) override +
+
+
+ void readBool(bool& value) override +
+
+
+ void readString(std::string& value) override +
+
+
+ void beginObject() override +
+
+
+ void endObject() override +
+
+
+ auto beginArray() -> std::size_t override +
+
+
+ void endArray() override +
+
+
+ auto beginDictionary() -> std::size_t override +
+
+
+ void endDictionary() override +
+
+
+
+
+

Function documentation

+
+

+ cubos::core::data::old::Unpackager::Unpackager(const Package& pkg) +

+ + + + + + + + + + +
Parameters
pkgThe package to read from.
+
+
+

+ void cubos::core::data::old::Unpackager::readI8(int8_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a signed 8 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Unpackager::readI16(int16_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a signed 16 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Unpackager::readI32(int32_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a signed 32 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Unpackager::readI64(int64_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a signed 64 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Unpackager::readU8(uint8_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes an unsigned 8 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Unpackager::readU16(uint16_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes an unsigned 16 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Unpackager::readU32(uint32_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes an unsigned 32 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Unpackager::readU64(uint64_t& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes an unsigned 64 bit integer. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Unpackager::readF32(float& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a float. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Unpackager::readF64(double& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a double. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Unpackager::readBool(bool& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a boolean. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Unpackager::readString(std::string& value) override +

+ + + + + + + + + + +
Parameters
valueThe value to deserialize.
+

Deserializes a string. The fail bit is set if the deserialization fails.

+
+
+

+ void cubos::core::data::old::Unpackager::beginObject() override +

+

Indicates that a object is currently being deserialized. The fail bit is set on failure.

+
+
+

+ void cubos::core::data::old::Unpackager::endObject() override +

+

Indicates that a object is no longer being deserialized. The fail bit is set on failure.

+
+
+

+ std::size_t cubos::core::data::old::Unpackager::beginArray() override +

+ + + + + + + +
ReturnsThe length of the array.
+

Indicates that an array is currently being deserialized. The fail bit is set on failure.

+
+
+

+ void cubos::core::data::old::Unpackager::endArray() override +

+

Indicates that an array is no longer being deserialized. The fail bit is set on failure.

+
+
+

+ std::size_t cubos::core::data::old::Unpackager::beginDictionary() override +

+ + + + + + + +
ReturnsThe length of the dictionary (always 0 on failure).
+

Indicates that a dictionary is being deserialized. The fail bit is set on failure.

+
+
+

+ void cubos::core::data::old::Unpackager::endDictionary() override +

+

Indicates that a dictionary is no longer being deserialized. The fail bit is set on failure.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1impl_1_1Packager.html b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1impl_1_1Packager.html new file mode 100644 index 000000000..b36011dfa --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1data_1_1old_1_1impl_1_1Packager.html @@ -0,0 +1,542 @@ + + + + + cubos::core::data::old::impl::Packager class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data::old::impl::Packager class +

+ +

Responsible for serializing types into packages. Should never be used directly.

+
+

Base classes

+
+
+ class cubos::core::data::old::Serializer +
+
+
+
+
+

Public functions

+
+
+ void writeI8(int8_t value, + const char* name) override +
+
+
+ void writeI16(int16_t value, + const char* name) override +
+
+
+ void writeI32(int32_t value, + const char* name) override +
+
+
+ void writeI64(int64_t value, + const char* name) override +
+
+
+ void writeU8(uint8_t value, + const char* name) override +
+
+
+ void writeU16(uint16_t value, + const char* name) override +
+
+
+ void writeU32(uint32_t value, + const char* name) override +
+
+
+ void writeU64(uint64_t value, + const char* name) override +
+
+
+ void writeF32(float value, + const char* name) override +
+
+
+ void writeF64(double value, + const char* name) override +
+
+
+ void writeBool(bool value, + const char* name) override +
+
+
+ void writeString(const char* str, + const char* name) override +
+
+
+ void beginObject(const char* name) override +
+
+
+ void endObject() override +
+
Indicates that a object is no longer being serialized.
+
+ void beginArray(std::size_t length, + const char* name) override +
+
+
+ void endArray() override +
+
Indicates that a array is no longer being serialized.
+
+ void beginDictionary(std::size_t length, + const char* name) override +
+
+
+ void endDictionary() override +
+
Indicates that a dictionary is no longer being serialized.
+
+
+
+

Function documentation

+
+

+ void cubos::core::data::old::impl::Packager::writeI8(int8_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes a signed 8 bit integer.

+
+
+

+ void cubos::core::data::old::impl::Packager::writeI16(int16_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an signed 16 bit integer.

+
+
+

+ void cubos::core::data::old::impl::Packager::writeI32(int32_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an signed 32 bit integer.

+
+
+

+ void cubos::core::data::old::impl::Packager::writeI64(int64_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an signed 64 bit integer.

+
+
+

+ void cubos::core::data::old::impl::Packager::writeU8(uint8_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an unsigned 8 bit integer.

+
+
+

+ void cubos::core::data::old::impl::Packager::writeU16(uint16_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an unsigned 16 bit integer.

+
+
+

+ void cubos::core::data::old::impl::Packager::writeU32(uint32_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an unsigned 32 bit integer.

+
+
+

+ void cubos::core::data::old::impl::Packager::writeU64(uint64_t value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes an unsigned 64 bit integer.

+
+
+

+ void cubos::core::data::old::impl::Packager::writeF32(float value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes a float.

+
+
+

+ void cubos::core::data::old::impl::Packager::writeF64(double value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes a double.

+
+
+

+ void cubos::core::data::old::impl::Packager::writeBool(bool value, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
valueThe value to serialize.
nameThe name of the value (optional).
+

Serializes a boolean.

+
+
+

+ void cubos::core::data::old::impl::Packager::writeString(const char* str, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
strThe string to serialize.
nameThe name of the value (optional).
+

Serializes a string.

+
+
+

+ void cubos::core::data::old::impl::Packager::beginObject(const char* name) override +

+ + + + + + + + + + +
Parameters
nameThe name of the object (optional).
+

Indicates that a object is currently being serialized.

+
+
+

+ void cubos::core::data::old::impl::Packager::beginArray(std::size_t length, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
lengthThe length of the array.
nameThe name of the array (optional).
+

Indicates that a array is currently being serialized.

+
+
+

+ void cubos::core::data::old::impl::Packager::beginDictionary(std::size_t length, + const char* name) override +

+ + + + + + + + + + + + + + +
Parameters
lengthThe length of the dictionary.
nameThe name of the dictionary (optional).
+

Indicates that a dictionary is currently being serialized.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1ArchetypeGraph.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1ArchetypeGraph.html new file mode 100644 index 000000000..f1bdce5a1 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1ArchetypeGraph.html @@ -0,0 +1,334 @@ + + + + + cubos::core::ecs::ArchetypeGraph class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::ArchetypeGraph class + +

+

Stores which column types each archetype holds and the edges which connect them.

+ +

These edges are bidirectional and indicate the addition or removal of column types, depending on the direction being taken. Neighboring archetypes (which have only one differing column type) are not always connected by an edge, as they are only generated the first time the traversal is done between those two archetypes.

In practice, this means that the first time a component is added to an entity of a given archetype, even if the target archetype already exists, a slow lookup must first be made. We cache the result of the lookup as a new edge, such that the next time the same component type is added, we just traverse the edge to find the target archetype's id.

+
+

Constructors, destructors, conversion operators

+
+
+ ArchetypeGraph() +
+
Constructs.
+
+
+
+

Public functions

+
+
+ auto contains(ArchetypeId archetype, + ColumnId id) const -> bool +
+
Checks if the given archetype contains the column type with the given id.
+
+ auto with(ArchetypeId source, + ColumnId id) -> ArchetypeId +
+
Returns an archetype with same identifiers as the given source archetype, but with an extra column type with the given id.
+
+ auto without(ArchetypeId source, + ColumnId id) -> ArchetypeId +
+
Returns an archetype with same identifiers as the given source archetype, except for the column type with the given id, which is excluded.
+
+ auto first(ArchetypeId archetype) const -> ColumnId +
+
Returns the first column type in the set of column types held by the given archetype.
+
+ auto next(ArchetypeId archetype, + ColumnId id) const -> ColumnId +
+
Returns the next column type in the set of column types held by the given archetype.
+
+ auto collect(ArchetypeId archetype, + std::vector<ArchetypeId>& supersets, + std::size_t seen = 0) const -> std::size_t +
+
Collects all of the archetypes which are supersets of the given archetype.
+
+
+
+

Function documentation

+
+

+ bool cubos::core::ecs::ArchetypeGraph::contains(ArchetypeId archetype, + ColumnId id) const +

+

Checks if the given archetype contains the column type with the given id.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
archetypeArchetype.
idColumn type identifier.
ReturnsWhether the archetype contains the column type.
+
+
+

+ ArchetypeId cubos::core::ecs::ArchetypeGraph::with(ArchetypeId source, + ColumnId id) +

+

Returns an archetype with same identifiers as the given source archetype, but with an extra column type with the given id.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
sourceSource archetype.
idExtra column type identifier.
ReturnsTarget archetype.
+

The column type with the given id must not already be present in source.

+
+
+

+ ArchetypeId cubos::core::ecs::ArchetypeGraph::without(ArchetypeId source, + ColumnId id) +

+

Returns an archetype with same identifiers as the given source archetype, except for the column type with the given id, which is excluded.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
sourceSource archetype.
idExcluded column type identifier.
ReturnsTarget archetype.
+

The given column type with the given id must be present in source.

+
+
+

+ ColumnId cubos::core::ecs::ArchetypeGraph::first(ArchetypeId archetype) const +

+

Returns the first column type in the set of column types held by the given archetype.

+ + + + + + + + + + + + + + + + +
Parameters
archetypeArchetype.
ReturnsFirst column type, or ColumnId::Invalid if the archetype is Empty.
+
+
+

+ ColumnId cubos::core::ecs::ArchetypeGraph::next(ArchetypeId archetype, + ColumnId id) const +

+

Returns the next column type in the set of column types held by the given archetype.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
archetypeArchetype.
idCurrent column type.
ReturnsNext column type, or ColumnId::Invalid if there is no next column type.
+
+
+

+ std::size_t cubos::core::ecs::ArchetypeGraph::collect(ArchetypeId archetype, + std::vector<ArchetypeId>& supersets, + std::size_t seen = 0) const +

+

Collects all of the archetypes which are supersets of the given archetype.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
archetypeBase archetype.
supersets outSet to insert new found archetypes into.
seenMaximum previously seen archetype. To be used after the first call to this.
ReturnsMaximum seen archetype.
+

Returns the largest identifier checked during the call, which can then be used to only check new archetypes in later calls.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Blueprint.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Blueprint.html new file mode 100644 index 000000000..85ddb1451 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Blueprint.html @@ -0,0 +1,549 @@ + + + + + cubos::core::ecs::Blueprint class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::Blueprint class final + +

+

Collection of entities and their respective components and relations.

+ +

Blueprints are in a way the 'Prefab' of CUBOS. They act as a tiny World which can then be spawned into an actual World, as many times as needed.

When a blueprint is spawned, all of its components and relations are scanned using the Reflection system for any references to other entities in the blueprint. These references are then replaced with the actual spawned entities. This has the side effect that if you do not expose an Entity field to the Reflection system, it will not be replaced and thus continue referencing the original entity in the blueprint.

+
+

Public types

+
+
+ using Create = Entity(*)(void*userData, std::string name) +
+
Function used by instantiate to create entities.
+
+ using Add = void(*)(void*userData, Entity entity, memory::AnyValue component) +
+
Function used by instantiate to add components to entities.
+
+ using Relate = void(*)(void*userData, Entity fromEntity, Entity toEntity, memory::AnyValue relation) +
+
Function used by instantiate to add relations to entities.
+
+
+
+

Public static functions

+
+
+ static auto validEntityName(const std::string& name) -> bool +
+
Checks if the given name is a valid entity name.
+
+
+
+

Public functions

+
+
+ auto create(std::string name) -> Entity +
+
Creates a new entity in the blueprint and returns it.
+
+ void add(Entity entity, + memory::AnyValue component) +
+
Adds a component to an entity. Overwrites the existing component, if there's any.
+
+
template<reflection::Reflectable... Ts>
+ void add(Entity entity, + Ts... components) +
+
Adds components to an entity. Overwrites the existing components, if there's any.
+
+ void relate(Entity fromEntity, + Entity toEntity, + memory::AnyValue relation) +
+
Adds a relation between two entities. Overwrites the existing relation, if there's any.
+
+
template<reflection::Reflectable T>
+ void relate(Entity fromEntity, + Entity toEntity, + T relation) +
+
Adds a relation between two entities. Overwrites the existing relation, if there's any.
+
+ void merge(const std::string& prefix, + const Blueprint& other) +
+
Merges another blueprint into this one.
+
+ void clear() +
+
Clears the blueprint.
+
+ auto bimap() const -> const memory::UnorderedBimap<Entity, std::string, EntityHash>& +
+
Returns a bimap which maps entities to their names.
+
+ void instantiate(void* userData, + Create create, + Add add, + Relate relate, + bool withName) const +
+
Instantiates the blueprint by calling the given functions.
+
+
template<typename C, typename A, typename R>
+ void instantiate(C create, + A add, + R relate, + bool withName) const +
+
Instantiates the blueprint by calling the given functors.
+
+ auto entities() const -> memory::UnorderedBimap<Entity, std::string, EntityHash> +
+
Gets the map relating entities to their name.
+
+ auto components() const -> memory::TypeMap<EntityMap<memory::AnyValue>> +
+
Gets the map relating types of components to maps of entities to the component values.
+
+ auto relations() const -> memory::TypeMap<EntityMap<EntityMap<memory::AnyValue>>> +
+
Gets the map relating types of relations to maps of entities to maps of entities to the component values.
+
+
+
+

Function documentation

+
+

+ static bool cubos::core::ecs::Blueprint::validEntityName(const std::string& name) +

+

Checks if the given name is a valid entity name.

+ + + + + + + +
ReturnsWhether the name is valid.
+

Entity names must contain only lowercase alphanumerical characters and hyphens.

+
+
+

+ Entity cubos::core::ecs::Blueprint::create(std::string name) +

+

Creates a new entity in the blueprint and returns it.

+ + + + + + + + + + + + + + + + +
Parameters
nameEntity name.
ReturnsEntity.
+

An entity with the same name must not exist. The name must be valid.

+
+
+

+ void cubos::core::ecs::Blueprint::add(Entity entity, + memory::AnyValue component) +

+

Adds a component to an entity. Overwrites the existing component, if there's any.

+ + + + + + + + + + + + + + +
Parameters
entityEntity.
componentComponent to move.
+
+
+

+
+ template<reflection::Reflectable... Ts> +
+ void cubos::core::ecs::Blueprint::add(Entity entity, + Ts... components) +

+

Adds components to an entity. Overwrites the existing components, if there's any.

+ + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TsComponent types.
Parameters
entityEntity.
componentsComponents to move.
+
+
+

+ void cubos::core::ecs::Blueprint::relate(Entity fromEntity, + Entity toEntity, + memory::AnyValue relation) +

+

Adds a relation between two entities. Overwrites the existing relation, if there's any.

+ + + + + + + + + + + + + + + + + + +
Parameters
fromEntityFrom entity.
toEntityTo entity.
relationRelation to move.
+
+
+

+
+ template<reflection::Reflectable T> +
+ void cubos::core::ecs::Blueprint::relate(Entity fromEntity, + Entity toEntity, + T relation) +

+

Adds a relation between two entities. Overwrites the existing relation, if there's any.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TRelation type.
Parameters
fromEntityFrom entity.
toEntityTo entity.
relationRelation to move.
+
+
+

+ void cubos::core::ecs::Blueprint::merge(const std::string& prefix, + const Blueprint& other) +

+

Merges another blueprint into this one.

+ + + + + + + + + + + + + + +
Parameters
prefixName to prefix with the merged blueprint.
otherBlueprint to merge.
+

Entities in the other blueprint will have their names prefixed with the specified string.

+
+
+

+ const memory::UnorderedBimap<Entity, std::string, EntityHash>& cubos::core::ecs::Blueprint::bimap() const +

+

Returns a bimap which maps entities to their names.

+ + + + + + + +
ReturnsBimap of entities to names.
+
+
+

+ void cubos::core::ecs::Blueprint::instantiate(void* userData, + Create create, + Add add, + Relate relate, + bool withName) const +

+

Instantiates the blueprint by calling the given functions.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
userDataUser data to pass into the functions.
createFunction used to create entities.
addFunction used to add components to entities.
relateFunction used to add relations to entities.
withNameWhether to add the 'Name' component to instantiated entities.
+
+
+

+
+ template<typename C, typename A, typename R> +
+ void cubos::core::ecs::Blueprint::instantiate(C create, + A add, + R relate, + bool withName) const +

+

Instantiates the blueprint by calling the given functors.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
CCreate functor type.
AAdd functor type.
RRelate functor type.
Parameters
createFunctor used to create entities.
addFunctor used to add components to entities.
relateFunctor used to add relations to entities.
withNameWhether to use the entity names from the blueprint.
+
+
+

+ memory::UnorderedBimap<Entity, std::string, EntityHash> cubos::core::ecs::Blueprint::entities() const +

+

Gets the map relating entities to their name.

+ + + + + + + +
ReturnsBimap relating entities and names
+
+
+

+ memory::TypeMap<EntityMap<memory::AnyValue>> cubos::core::ecs::Blueprint::components() const +

+

Gets the map relating types of components to maps of entities to the component values.

+ + + + + + + +
ReturnsTypeMap of an EntityMap to component values
+
+
+

+ memory::TypeMap<EntityMap<EntityMap<memory::AnyValue>>> cubos::core::ecs::Blueprint::relations() const +

+

Gets the map relating types of relations to maps of entities to maps of entities to the component values.

+ + + + + + + +
ReturnsTypeMap of an EntityMap to another EntityMap to component values
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1CommandBuffer.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1CommandBuffer.html new file mode 100644 index 000000000..e2997216d --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1CommandBuffer.html @@ -0,0 +1,379 @@ + + + + + cubos::core::ecs::CommandBuffer class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::CommandBuffer class final + +

+

Stores commands to execute them later.

+ +
+

Constructors, destructors, conversion operators

+
+
+ CommandBuffer(World& world) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ auto create() -> Entity +
+
Creates a new entity.
+
+ void destroy(Entity entity) +
+
Destroys an entity.
+
+ auto spawn(const Blueprint& blueprint, + bool withName = true) -> std::unordered_map<std::string, Entity> +
+
Spawns a blueprint into the world.
+
+ void add(Entity entity, + const reflection::Type& type, + void* value) +
+
Adds a component to an entity.
+
+ void remove(Entity entity, + const reflection::Type& type) +
+
Removes a component from an entity.
+
+ void relate(Entity from, + Entity to, + const reflection::Type& type, + void* value) +
+
Inserts a relation between the two given entities.
+
+ void unrelate(Entity from, + Entity to, + const reflection::Type& type) +
+
Removes the relation, if there's any, between the two given entities.
+
+ void push(memory::Function<void(World&)> command) +
+
Pushes a command.
+
+ void commit() +
+
Commits the commands to the world.
+
+
+
+

Function documentation

+
+

+ cubos::core::ecs::CommandBuffer::CommandBuffer(World& world) +

+

Constructs.

+ + + + + + + + + + +
Parameters
worldWorld to which the commands will be applied.
+
+
+

+ Entity cubos::core::ecs::CommandBuffer::create() +

+

Creates a new entity.

+ + + + + + + +
ReturnsEntity identifier.
+
+
+

+ void cubos::core::ecs::CommandBuffer::destroy(Entity entity) +

+

Destroys an entity.

+ + + + + + + + + + +
Parameters
entityEntity identifier.
+
+
+

+ std::unordered_map<std::string, Entity> cubos::core::ecs::CommandBuffer::spawn(const Blueprint& blueprint, + bool withName = true) +

+

Spawns a blueprint into the world.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
blueprintBlueprint to spawn.
withNameWhether to use the entity names from the blueprint.
ReturnsMap of entity names to their identifiers.
+
+
+

+ void cubos::core::ecs::CommandBuffer::add(Entity entity, + const reflection::Type& type, + void* value) +

+

Adds a component to an entity.

+ + + + + + + + + + + + + + + + + + +
Parameters
entityEntity identifier.
typeComponent type.
valueComponent value to be moved.
+
+
+

+ void cubos::core::ecs::CommandBuffer::remove(Entity entity, + const reflection::Type& type) +

+

Removes a component from an entity.

+ + + + + + + + + + + + + + +
Parameters
entityEntity identifier.
typeComponent type.
+
+
+

+ void cubos::core::ecs::CommandBuffer::relate(Entity from, + Entity to, + const reflection::Type& type, + void* value) +

+

Inserts a relation between the two given entities.

+ + + + + + + + + + + + + + + + + + + + + + +
Parameters
fromFrom entity.
toTo entity.
typeRelation type.
valueRelation value to move.
+

If the relation already exists, it is overwritten.

+
+
+

+ void cubos::core::ecs::CommandBuffer::unrelate(Entity from, + Entity to, + const reflection::Type& type) +

+

Removes the relation, if there's any, between the two given entities.

+ + + + + + + + + + + + + + + + + + +
Parameters
fromFrom entity.
toTo entity.
typeRelation type.
+
+
+

+ void cubos::core::ecs::CommandBuffer::push(memory::Function<void(World&)> command) +

+

Pushes a command.

+ + + + + + + + + + +
Parameters
commandCommand function.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Commands.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Commands.html new file mode 100644 index 000000000..464a088f9 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Commands.html @@ -0,0 +1,568 @@ + + + + + cubos::core::ecs::Commands class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::Commands class final + +

+

System argument used to write ECS commands and execute them at a later time.

+ +

Internally wraps a reference to a CommandBuffer object.

+
+

Constructors, destructors, conversion operators

+
+
+ Commands(CommandBuffer& buffer) +
+
Constructs.
+
+ Commands(Commands&&) defaulted +
+
Move constructor.
+
+
+
+

Public functions

+
+
+ auto create() -> EntityBuilder +
+
Creates a new entity.
+
+ void destroy(Entity entity) +
+
Destroys an entity.
+
+ auto spawn(const Blueprint& blueprint, + bool withName = true) -> BlueprintBuilder +
+
Spawns a blueprint into the world.
+
+ auto add(Entity entity, + const reflection::Type& type, + void* value) -> Commands& +
+
Adds a component to an entity.
+
+
template<reflection::Reflectable T>
+ auto add(Entity entity, + T value) -> Commands& +
+
Adds a component to an entity.
+
+ auto remove(Entity entity, + const reflection::Type& type) -> Commands& +
+
Removes a component from an entity.
+
+
template<reflection::Reflectable T>
+ auto remove(Entity entity) -> Commands& +
+
Removes a component from an entity.
+
+ auto relate(Entity from, + Entity to, + const reflection::Type& type, + void* value) -> Commands& +
+
Inserts a relation between the two given entities.
+
+
template<reflection::Reflectable T>
+ auto relate(Entity from, + Entity to, + T value) -> Commands& +
+
Inserts a relation between the two given entities.
+
+ auto unrelate(Entity from, + Entity to, + const reflection::Type& type) -> Commands& +
+
Removes the relation, if there's any, between the two given entities.
+
+
template<reflection::Reflectable T>
+ auto unrelate(Entity from, + Entity to) -> Commands& +
+
Removes the relation, if there's any, between the two given entities.
+
+
+
+

Function documentation

+
+

+ cubos::core::ecs::Commands::Commands(CommandBuffer& buffer) +

+

Constructs.

+ + + + + + + + + + +
Parameters
bufferCommand buffer to write to.
+
+
+

+ EntityBuilder cubos::core::ecs::Commands::create() +

+

Creates a new entity.

+ + + + + + + +
ReturnsBuilder which can be used to modify the created entity.
+
+
+

+ void cubos::core::ecs::Commands::destroy(Entity entity) +

+

Destroys an entity.

+ + + + + + + + + + +
Parameters
entityEntity identifier.
+
+
+

+ BlueprintBuilder cubos::core::ecs::Commands::spawn(const Blueprint& blueprint, + bool withName = true) +

+

Spawns a blueprint into the world.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
blueprintBlueprint to spawn.
withNameWhether to use the entity names from the blueprint.
ReturnsBlueprint builder.
+
+
+

+ Commands& cubos::core::ecs::Commands::add(Entity entity, + const reflection::Type& type, + void* value) +

+

Adds a component to an entity.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
entityEntity identifier.
typeComponent type.
valueComponent value.
ReturnsCommands.
+
+
+

+
+ template<reflection::Reflectable T> +
+ Commands& cubos::core::ecs::Commands::add(Entity entity, + T value) +

+

Adds a component to an entity.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TComponent type.
Parameters
entityEntity identifier.
valueComponent value.
ReturnsCommands.
+
+
+

+ Commands& cubos::core::ecs::Commands::remove(Entity entity, + const reflection::Type& type) +

+

Removes a component from an entity.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
entityEntity identifier.
typeComponent type.
ReturnsCommands.
+
+
+

+
+ template<reflection::Reflectable T> +
+ Commands& cubos::core::ecs::Commands::remove(Entity entity) +

+

Removes a component from an entity.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TComponent type.
Parameters
entityEntity identifier.
ReturnsCommands.
+
+
+

+ Commands& cubos::core::ecs::Commands::relate(Entity from, + Entity to, + const reflection::Type& type, + void* value) +

+

Inserts a relation between the two given entities.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
fromFrom entity.
toTo entity.
typeRelation type.
valueRelation value to move.
ReturnsCommands.
+

If the relation already exists, it is overwritten.

+
+
+

+
+ template<reflection::Reflectable T> +
+ Commands& cubos::core::ecs::Commands::relate(Entity from, + Entity to, + T value) +

+

Inserts a relation between the two given entities.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TRelation type.
Parameters
fromFrom entity.
toTo entity.
valueRelation value.
ReturnsCommands.
+

If the relation already exists, it is overwritten.

+
+
+

+ Commands& cubos::core::ecs::Commands::unrelate(Entity from, + Entity to, + const reflection::Type& type) +

+

Removes the relation, if there's any, between the two given entities.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
fromFrom entity.
toTo entity.
typeRelation type.
ReturnsCommands.
+
+
+

+
+ template<reflection::Reflectable T> +
+ Commands& cubos::core::ecs::Commands::unrelate(Entity from, + Entity to) +

+

Removes the relation, if there's any, between the two given entities.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TRelation type.
Parameters
fromFrom entity.
toTo entity.
ReturnsCommands.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Cubos.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Cubos.html new file mode 100644 index 000000000..a7b5f42a0 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Cubos.html @@ -0,0 +1,496 @@ + + + + + cubos::core::ecs::Cubos class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::Cubos class final + +

+

Represents the engine itself, and exposes the interface with which the game developer interacts with. Ties up all the different parts of the engine together.

+ +
+

Constructors, destructors, conversion operators

+
+
+ Cubos() +
+
Constructs an empty application without arguments.
+
+ Cubos(int argc, + char** argv) +
+
Constructs an empty application with arguments.
+
+
+
+

Public functions

+
+
+ auto addPlugin(void(*)(Cubos&) func) -> Cubos& +
+
Adds a new plugin to the engine. If the plugin had already been added, nothing happens. A plugin is just a function that operates on the Cubos object, further configuring it. It is useful for separating the code into modules.
+
+
template<typename R, typename... TArgs>
+ auto addResource(TArgs... args) -> Cubos& +
+
Adds a new resource to the engine.
+
+
template<typename C>
+ auto addComponent() -> Cubos& +
+
Adds a new component type to the engine.
+
+
template<typename R>
+ auto addRelation() -> Cubos& +
+
Adds a new relation type to the engine.
+
+
template<typename E>
+ auto addEvent() -> Cubos& +
+
Adds a new event type to the engine.
+
+ auto tag(const std::string& tag) -> TagBuilder +
+
Returns a TagBuilder to configure the systems with the given tag.
+
+ auto startupTag(const std::string& tag) -> TagBuilder +
+
Returns a TagBuilder to configure the systems with the given startup tag.
+
+ auto noTag(const std::string& tag) -> TagBuilder +
+
Returns a TagBuilder to configure the systems without the given tag.
+
+ auto noStartupTag(const std::string& tag) -> TagBuilder +
+
Returns a TagBuilder to configure the systems without the given startup tag.
+
+ auto system(std::string name) -> SystemBuilder +
+
Returns a new builder used to add a system to the engine.
+
+ auto startupSystem(std::string name) -> SystemBuilder +
+
Returns a new builder used to add a startup system to the engine.
+
+ void run() +
+
Runs the engine.
+
+
+
+

Function documentation

+
+

+ cubos::core::ecs::Cubos::Cubos(int argc, + char** argv) +

+

Constructs an empty application with arguments.

+ + + + + + + + + + + + + + +
Parameters
argcArgument count.
argvArgument array.
+
+
+

+ Cubos& cubos::core::ecs::Cubos::addPlugin(void(*)(Cubos&) func) +

+

Adds a new plugin to the engine. If the plugin had already been added, nothing happens. A plugin is just a function that operates on the Cubos object, further configuring it. It is useful for separating the code into modules.

+ + + + + + + + + + + + + + + + +
Parameters
funcEntry point of the plugin to add.
ReturnsReference to this object, for chaining.
+
+
+

+
+ template<typename R, typename... TArgs> +
+ Cubos& cubos::core::ecs::Cubos::addResource(TArgs... args) +

+

Adds a new resource to the engine.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
RType of the resource.
TArgsTypes of the arguments passed to the resource's constructor.
Parameters
argsArguments passed to the resource's constructor.
ReturnsReference to this object, for chaining.
+
+
+

+
+ template<typename C> +
+ Cubos& cubos::core::ecs::Cubos::addComponent() +

+

Adds a new component type to the engine.

+ + + + + + + + + + + + + + + + +
Template parameters
CType of the component.
ReturnsReference to this object, for chaining.
+
+
+

+
+ template<typename R> +
+ Cubos& cubos::core::ecs::Cubos::addRelation() +

+

Adds a new relation type to the engine.

+ + + + + + + + + + + + + + + + +
Template parameters
RType of the relation.
ReturnsReference to this object, for chaining.
+
+
+

+
+ template<typename E> +
+ Cubos& cubos::core::ecs::Cubos::addEvent() +

+

Adds a new event type to the engine.

+ + + + + + + + + + + + + + + + +
Template parameters
EType of the event.
ReturnsReference to this object, for chaining.
+
+
+

+ TagBuilder cubos::core::ecs::Cubos::tag(const std::string& tag) +

+

Returns a TagBuilder to configure the systems with the given tag.

+ + + + + + + + + + + + + + + + +
Parameters
tagTag.
ReturnsTagBuilder.
+
+
+

+ TagBuilder cubos::core::ecs::Cubos::startupTag(const std::string& tag) +

+

Returns a TagBuilder to configure the systems with the given startup tag.

+ + + + + + + + + + + + + + + + +
Parameters
tagTag.
ReturnsTagBuilder.
+
+
+

+ TagBuilder cubos::core::ecs::Cubos::noTag(const std::string& tag) +

+

Returns a TagBuilder to configure the systems without the given tag.

+ + + + + + + + + + + + + + + + +
Parameters
tagTag.
ReturnsTagBuilder.
+
+
+

+ TagBuilder cubos::core::ecs::Cubos::noStartupTag(const std::string& tag) +

+

Returns a TagBuilder to configure the systems without the given startup tag.

+ + + + + + + + + + + + + + + + +
Parameters
tagTag.
ReturnsTagBuilder.
+
+
+

+ SystemBuilder cubos::core::ecs::Cubos::system(std::string name) +

+

Returns a new builder used to add a system to the engine.

+ + + + + + + + + + + + + + + + +
Parameters
nameSystem debug name.
ReturnsBuilder used to configure the system.
+
+
+

+ SystemBuilder cubos::core::ecs::Cubos::startupSystem(std::string name) +

+

Returns a new builder used to add a startup system to the engine.

+ + + + + + + + + + + + + + + + +
Parameters
nameSystem debug name.
ReturnsBuilder used to configure the system.
+
+
+

+ void cubos::core::ecs::Cubos::run() +

+

Runs the engine.

+

Initially, dispatches all of the startup systems. Then, while ShouldQuit is false, dispatches all other systems.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1DenseTable.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1DenseTable.html new file mode 100644 index 000000000..d676bdf57 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1DenseTable.html @@ -0,0 +1,391 @@ + + + + + cubos::core::ecs::DenseTable class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::DenseTable class final + +

+

Stores the dense data associated to entities of a given archetype.

+ +
+

Constructors, destructors, conversion operators

+
+
+ DenseTable() defaulted +
+
Constructs a table without columns.
+
+ DenseTable(DenseTable&&) deleted noexcept +
+
Forbid move construction.
+
+
+
+

Public functions

+
+
+ void addColumn(ColumnId id, + const reflection::Type& type) +
+
Adds a new column to the table.
+
+ void pushBack(uint32_t index) +
+
Inserts a new entity to the end of the table.
+
+ void swapErase(uint32_t index) +
+
Removes an entity from the table.
+
+ void swapMove(uint32_t index, + DenseTable& other) +
+
Moves an entity from this table into another table, effectively calling pushBack() on the other table, and swapErase() on this one.
+
+ auto row(uint32_t index) const -> std::size_t +
+
Gets the row which contains the data for the given entity.
+
+ auto entity(std::size_t row) const -> uint32_t +
+
Gets the index of the entity which is stored in the given row.
+
+ auto size() const -> std::size_t +
+
Gets the number of rows in the table.
+
+ auto column(ColumnId id) -> memory::AnyVector& +
+
Gets a reference to the column with the given id.
+
+ auto column(ColumnId id) const -> const memory::AnyVector& +
+
Gets a reference to the column with the given id.
+
+ auto contains(ColumnId id) const -> bool +
+
Checks if the table has a column with the given id.
+
+
+
+

Function documentation

+
+

+ void cubos::core::ecs::DenseTable::addColumn(ColumnId id, + const reflection::Type& type) +

+

Adds a new column to the table.

+ + + + + + + + + + + + + + +
Parameters
idColumn type identifier.
typeColumn data type.
+

The table must still be empty, and the column must not already exist in the table.

+
+
+

+ void cubos::core::ecs::DenseTable::pushBack(uint32_t index) +

+

Inserts a new entity to the end of the table.

+ + + + + + + + + + +
Parameters
indexEntity index.
+ +
+
+

+ void cubos::core::ecs::DenseTable::swapErase(uint32_t index) +

+

Removes an entity from the table.

+ + + + + + + + + + +
Parameters
indexEntity index.
+

If the entity isn't the last one in the table, the last entity will be moved to the position of the removed entity. The data columns will be updated accordingly.

+
+
+

+ void cubos::core::ecs::DenseTable::swapMove(uint32_t index, + DenseTable& other) +

+

Moves an entity from this table into another table, effectively calling pushBack() on the other table, and swapErase() on this one.

+ + + + + + + + + + + + + + +
Parameters
indexEntity index.
otherDestination table.
+ +
+
+

+ std::size_t cubos::core::ecs::DenseTable::row(uint32_t index) const +

+

Gets the row which contains the data for the given entity.

+ + + + + + + + + + + + + + + + +
Parameters
indexEntity index.
ReturnsRow index.
+
+
+

+ uint32_t cubos::core::ecs::DenseTable::entity(std::size_t row) const +

+

Gets the index of the entity which is stored in the given row.

+ + + + + + + + + + + + + + + + +
Parameters
rowRow index.
ReturnsEntity index.
+
+
+

+ std::size_t cubos::core::ecs::DenseTable::size() const +

+

Gets the number of rows in the table.

+ + + + + + + +
ReturnsNumber of rows.
+
+
+

+ memory::AnyVector& cubos::core::ecs::DenseTable::column(ColumnId id) +

+

Gets a reference to the column with the given id.

+ + + + + + + + + + + + + + + + +
Parameters
idColumn identifier.
ReturnsColumn reference.
+

Aborts if the column does not exist in the table.

+
+
+

+ const memory::AnyVector& cubos::core::ecs::DenseTable::column(ColumnId id) const +

+

Gets a reference to the column with the given id.

+ + + + + + + + + + + + + + + + +
Parameters
idColumn identifier.
ReturnsColumn reference.
+

Aborts if the column does not exist in the table.

+
+
+

+ bool cubos::core::ecs::DenseTable::contains(ColumnId id) const +

+

Checks if the table has a column with the given id.

+ + + + + + + + + + + + + + + + +
Parameters
idColumn identifier.
ReturnsWhether the table contains the given column.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1DenseTableRegistry.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1DenseTableRegistry.html new file mode 100644 index 000000000..cd54ec9cd --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1DenseTableRegistry.html @@ -0,0 +1,227 @@ + + + + + cubos::core::ecs::DenseTableRegistry class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::DenseTableRegistry class final + +

+

Stores the dense tables of a given world.

+ +
+

Constructors, destructors, conversion operators

+
+
+ DenseTableRegistry() +
+
Constructs.
+
+
+
+

Public functions

+
+
+ auto contains(ArchetypeId archetype) const -> bool +
+
Checks if the given archetype has a dense table.
+
+ auto create(ArchetypeId archetype, + ArchetypeGraph& graph, + Types& types) -> DenseTable& +
+
Returns a reference to the dense table of the given archetype.
+
+ auto at(ArchetypeId archetype) -> DenseTable& +
+
Returns a reference to the dense table of the given archetype.
+
+
+
+

Function documentation

+
+

+ bool cubos::core::ecs::DenseTableRegistry::contains(ArchetypeId archetype) const +

+

Checks if the given archetype has a dense table.

+ + + + + + + + + + + + + + + + +
Parameters
archetypeArchetype identifier.
ReturnsWHether it contains a table or not.
+
+
+

+ DenseTable& cubos::core::ecs::DenseTableRegistry::create(ArchetypeId archetype, + ArchetypeGraph& graph, + Types& types) +

+

Returns a reference to the dense table of the given archetype.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
archetypeArchetype identifier.
graphArchetype graph used to initialize the table, if necessary.
typesType registry used to initialize the table, if necessary.
ReturnsReference to table.
+

Creates the table if it doesn't exist already.

+
+
+

+ DenseTable& cubos::core::ecs::DenseTableRegistry::at(ArchetypeId archetype) +

+

Returns a reference to the dense table of the given archetype.

+ + + + + + + + + + + + + + + + +
Parameters
archetypeArchetype identifier.
ReturnsReference to table.
+

Aborts if the table doesn't exist.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Dispatcher.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Dispatcher.html new file mode 100644 index 000000000..f39fea262 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Dispatcher.html @@ -0,0 +1,455 @@ + + + + + cubos::core::ecs::Dispatcher class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::Dispatcher class + +

+

Used to add systems and relations between them and then dispatch them all at once.

+ +
+

Public types

+
+
+ struct Dependency +
+
Internal class to specify system dependencies.
+
+ struct System +
+
Internal class to handle tag settings.
+
+ struct SystemSettings +
+
Internal class with settings pertaining to system/tag execution.
+
+
+
+

Public functions

+
+
+ void addTag(const std::string& tag) +
+
Adds a tag, and sets it as the current tag for further settings.
+
+ void addNegativeTag(const std::string& tag) +
+
Adds a tag, and sets it as the current negative tag for further settings.
+
+ void tagInheritTag(const std::string& tag) +
+
Makes the current tag inherit the settings of another tag.
+
+ void tagSetAfterTag(const std::string& tag) +
+
Makes the current tag run after the given tag.
+
+ void tagSetBeforeTag(const std::string& tag) +
+
Makes the current tag run before the given tag.
+
+ void tagAddCondition(ecs::System<bool> condition) +
+
Adds a condition to the current tag.
+
+ void tagRepeatWhile(ecs::System<bool> condition) +
+
Adds a repeat condition to the current tag.
+
+ void groupAddGroup() +
+
Adds a (sub)group to the current group.
+
+ void addSystem(std::string name, + ecs::System<void> system) +
+
Adds a system, and sets it as the current system for further configuration.
+
+ void systemAddTag(const std::string& tag) +
+
Sets the tag for the current system.
+
+ void systemAddGroup(const std::string& grouptag) +
+
Links a system to a certain group.
+
+ void systemSetAfterTag(const std::string& tag) +
+
Sets the current system to run after the tag.
+
+ void systemSetBeforeTag(const std::string& tag) +
+
Sets the current system to run before the tag.
+
+ void systemAddCondition(ecs::System<bool> condition) +
+
Adds a condition to the current system.
+
+ void compileChain() +
+
Compiles the call chain. Required before callSystems() can be called.
+
+ void callSystems(CommandBuffer& cmds) +
+
Calls all systems in the compiled call chain. compileChain() must be called prior to this.
+
+
+
+

Function documentation

+
+

+ void cubos::core::ecs::Dispatcher::addTag(const std::string& tag) +

+

Adds a tag, and sets it as the current tag for further settings.

+ + + + + + + + + + +
Parameters
tagTag to add.
+
+
+

+ void cubos::core::ecs::Dispatcher::addNegativeTag(const std::string& tag) +

+

Adds a tag, and sets it as the current negative tag for further settings.

+ + + + + + + + + + +
Parameters
tagTag to add.
+
+
+

+ void cubos::core::ecs::Dispatcher::tagInheritTag(const std::string& tag) +

+

Makes the current tag inherit the settings of another tag.

+ + + + + + + + + + +
Parameters
tagTag to inherit from.
+
+
+

+ void cubos::core::ecs::Dispatcher::tagSetAfterTag(const std::string& tag) +

+

Makes the current tag run after the given tag.

+ + + + + + + + + + +
Parameters
tagTag to run after.
+
+
+

+ void cubos::core::ecs::Dispatcher::tagSetBeforeTag(const std::string& tag) +

+

Makes the current tag run before the given tag.

+ + + + + + + + + + +
Parameters
tagTag to run before.
+
+
+

+ void cubos::core::ecs::Dispatcher::tagAddCondition(ecs::System<bool> condition) +

+

Adds a condition to the current tag.

+ + + + + + + + + + +
Parameters
conditionCondition to add.
+
+
+

+ void cubos::core::ecs::Dispatcher::tagRepeatWhile(ecs::System<bool> condition) +

+

Adds a repeat condition to the current tag.

+ + + + + + + + + + +
Parameters
conditionCondition to add.
+
+
+

+ void cubos::core::ecs::Dispatcher::addSystem(std::string name, + ecs::System<void> system) +

+

Adds a system, and sets it as the current system for further configuration.

+ + + + + + + + + + + + + + +
Parameters
nameSystem name.
systemSystem to add.
+
+
+

+ void cubos::core::ecs::Dispatcher::systemAddTag(const std::string& tag) +

+

Sets the tag for the current system.

+ + + + + + + + + + +
Parameters
tagTag to run under.
+
+
+

+ void cubos::core::ecs::Dispatcher::systemAddGroup(const std::string& grouptag) +

+

Links a system to a certain group.

+ + + + + + + + + + +
Parameters
grouptagTag of the group.
+
+
+

+ void cubos::core::ecs::Dispatcher::systemSetAfterTag(const std::string& tag) +

+

Sets the current system to run after the tag.

+ + + + + + + + + + +
Parameters
tagTag to run after.
+
+
+

+ void cubos::core::ecs::Dispatcher::systemSetBeforeTag(const std::string& tag) +

+

Sets the current system to run before the tag.

+ + + + + + + + + + +
Parameters
tagTag to run before.
+
+
+

+ void cubos::core::ecs::Dispatcher::systemAddCondition(ecs::System<bool> condition) +

+

Adds a condition to the current system.

+ + + + + + + + + + +
Parameters
conditionCondition.
+
+
+

+ void cubos::core::ecs::Dispatcher::compileChain() +

+

Compiles the call chain. Required before callSystems() can be called.

+

Takes all pending systems and determines their execution order.

+
+
+

+ void cubos::core::ecs::Dispatcher::callSystems(CommandBuffer& cmds) +

+

Calls all systems in the compiled call chain. compileChain() must be called prior to this.

+ + + + + + + + + + +
Parameters
cmdsCommand buffer.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1EntityPool.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1EntityPool.html new file mode 100644 index 000000000..3372ce4a4 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1EntityPool.html @@ -0,0 +1,296 @@ + + + + + cubos::core::ecs::EntityPool class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::EntityPool class final + +

+

Manages the creation and destruction of entity identifiers, as well as storing their archetype identifiers.

+ +
+

Public functions

+
+
+ auto create(ArchetypeId archetype) -> Entity +
+
Creates a new entity on the given archetype.
+
+ void destroy(uint32_t index) +
+
Removes an entity from the world.
+
+ void archetype(uint32_t index, + ArchetypeId archetype) +
+
Changes the archetype identifier of an entity.
+
+ auto archetype(uint32_t index) const -> ArchetypeId +
+
Gets the archetype identifier of an entity.
+
+ auto generation(uint32_t index) const -> uint32_t +
+
Gets the generation of an entity index.
+
+ auto contains(Entity entity) const -> bool +
+
Checks if a given entity exists.
+
+ auto size() const -> size_t +
+
Gets the number of alive entities in the pool.
+
+
+
+

Function documentation

+
+

+ Entity cubos::core::ecs::EntityPool::create(ArchetypeId archetype) +

+

Creates a new entity on the given archetype.

+ + + + + + + + + + + + + + + + +
Parameters
archetypeArchetype identifier.
ReturnsEntity.
+
+
+

+ void cubos::core::ecs::EntityPool::destroy(uint32_t index) +

+

Removes an entity from the world.

+ + + + + + + + + + +
Parameters
indexEntity index to remove.
+
+
+

+ void cubos::core::ecs::EntityPool::archetype(uint32_t index, + ArchetypeId archetype) +

+

Changes the archetype identifier of an entity.

+ + + + + + + + + + + + + + +
Parameters
indexEntity index.
archetypeNew archetype identifier.
+
+
+

+ ArchetypeId cubos::core::ecs::EntityPool::archetype(uint32_t index) const +

+

Gets the archetype identifier of an entity.

+ + + + + + + + + + + + + + + + +
Parameters
indexEntity index.
ReturnsArchetype identifier.
+
+
+

+ uint32_t cubos::core::ecs::EntityPool::generation(uint32_t index) const +

+

Gets the generation of an entity index.

+ + + + + + + + + + + + + + + + +
Parameters
indexEntity index.
ReturnsGeneration.
+
+
+

+ bool cubos::core::ecs::EntityPool::contains(Entity entity) const +

+

Checks if a given entity exists.

+ + + + + + + + + + + + + + + + +
Parameters
entityEntity to check.
ReturnsWhether the entity exists.
+
+
+

+ size_t cubos::core::ecs::EntityPool::size() const +

+

Gets the number of alive entities in the pool.

+ + + + + + + +
ReturnsNumber of entities.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1EventPipe.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1EventPipe.html new file mode 100644 index 000000000..8280e9c8c --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1EventPipe.html @@ -0,0 +1,299 @@ + + + + + cubos::core::ecs::EventPipe class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::ecs::EventPipe class +

+

Resource which stores events of type T.

+ + + + + + + + + + +
Template parameters
TEvent type.
+ + +
+

Public functions

+
+
+ void push(T event, + unsigned int mask = DEFAULT_PUSH_MASK) +
+
Pushes an event into the event pipe.
+
+ auto getEventMask(std::size_t index) const -> unsigned int +
+
Returns the event mask from event pipe at the given index.
+
+ auto get(std::size_t index) const -> std::pair<const T&, unsigned int> +
+
Returns the event and mask with the given index.
+
+ void clear() +
+
Clears events that have been read by all readers.
+
+ auto sentEvents() const -> std::size_t +
+
Returns the number of events that already were sent.
+
+ auto size() const -> std::size_t +
+
Returns the number of events that are present on the pipe.
+
+ void addReader() +
+
Adds a new reader to reader count.
+
+ void removeReader() +
+
Removes a reader from reader count.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ void cubos::core::ecs::EventPipe<T>::push(T event, + unsigned int mask = DEFAULT_PUSH_MASK) +

+

Pushes an event into the event pipe.

+ + + + + + + + + + + + + + +
Parameters
eventEvent.
maskMask.
+
+
+

+
+ template<typename T> +
+ unsigned int cubos::core::ecs::EventPipe<T>::getEventMask(std::size_t index) const +

+

Returns the event mask from event pipe at the given index.

+ + + + + + + + + + + + + + + + +
Parameters
indexEvent index.
ReturnsEvent mask.
+
+
+

+
+ template<typename T> +
+ std::pair<const T&, unsigned int> cubos::core::ecs::EventPipe<T>::get(std::size_t index) const +

+

Returns the event and mask with the given index.

+ + + + + + + + + + + + + + + + +
Parameters
indexEvent index.
ReturnsEvent and mask.
+
+
+

+
+ template<typename T> +
+ std::size_t cubos::core::ecs::EventPipe<T>::sentEvents() const +

+

Returns the number of events that already were sent.

+ + + + + + + +
ReturnsNumber of events that already were sent.
+
+
+

+
+ template<typename T> +
+ std::size_t cubos::core::ecs::EventPipe<T>::size() const +

+

Returns the number of events that are present on the pipe.

+ + + + + + + +
ReturnsNumber of events that are present on the pipe.
+
+
+

+
+ template<typename T> +
+ void cubos::core::ecs::EventPipe<T>::addReader() +

+

Adds a new reader to reader count.

+

This is necessary to keep track of when its okay to delete events on clear().

+
+
+

+
+ template<typename T> +
+ void cubos::core::ecs::EventPipe<T>::removeReader() +

+

Removes a reader from reader count.

+ +
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1EventReader.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1EventReader.html new file mode 100644 index 000000000..a82343121 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1EventReader.html @@ -0,0 +1,249 @@ + + + + + cubos::core::ecs::EventReader class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename T, unsigned int M = DEFAULT_FILTER_MASK>
+ cubos::core::ecs::EventReader class +

+

System arguments used to read events of type T.

+ + + + + + + + + + + + + + +
Template parameters
TEvent.
MFilter mask.
+ +

Filtering the received events by their mask is also possible via the parameter M. By default, the reader will read all events sent.

+
+

Public types

+
+
+ class Iterator +
+
Used to iterate over events received by a reader.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ EventReader(const EventPipe<T>& pipe, + std::size_t& index) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ auto read() -> const T* +
+
Returns a reference to current event, and advances.
+
+ auto begin() -> Iterator +
+
Returns an iterator to the first event.
+
+ auto end() -> Iterator +
+
Returns an iterator to the end.
+
+
+
+

Function documentation

+
+

+
+ template<typename T, unsigned int M> +
+ cubos::core::ecs::EventReader<T, M>::EventReader(const EventPipe<T>& pipe, + std::size_t& index) +

+

Constructs.

+ + + + + + + + + + + + + + +
Parameters
pipeEvent pipe to read events from.
indexReference to the reader's index.
+

Uses the given index to know which events it has already read. Increments it whenever it reads an event.

+
+
+

+
+ template<typename T, unsigned int M> +
+ const T* cubos::core::ecs::EventReader<T, M>::read() +

+

Returns a reference to current event, and advances.

+ + + + + + + +
ReturnsPointer to current event, or null if there are no more events.
+
+
+

+
+ template<typename T, unsigned int M> +
+ Iterator cubos::core::ecs::EventReader<T, M>::begin() +

+

Returns an iterator to the first event.

+ + + + + + + +
ReturnsIterator.
+
+
+

+
+ template<typename T, unsigned int M> +
+ Iterator cubos::core::ecs::EventReader<T, M>::end() +

+

Returns an iterator to the end.

+ + + + + + + +
ReturnsIterator.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1EventReader_1_1Iterator.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1EventReader_1_1Iterator.html new file mode 100644 index 000000000..37d698be0 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1EventReader_1_1Iterator.html @@ -0,0 +1,103 @@ + + + + + cubos::core::ecs::EventReader::Iterator class | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1EventWriter.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1EventWriter.html new file mode 100644 index 000000000..2cf6aa274 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1EventWriter.html @@ -0,0 +1,195 @@ + + + + + cubos::core::ecs::EventWriter class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::ecs::EventWriter class +

+

System argument which allows the system to send events of type T to other systems.

+ + + + + + + + + + +
Template parameters
T
+ + +
+

Constructors, destructors, conversion operators

+
+
+ EventWriter(EventPipe<T>& pipe) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ void push(T event, + unsigned int mask = DEFAULT_PUSH_MASK) +
+
Sends the given event to the event pipe with the given mask.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ cubos::core::ecs::EventWriter<T>::EventWriter(EventPipe<T>& pipe) +

+

Constructs.

+ + + + + + + + + + +
Parameters
pipeEvent pipe to write events to.
+
+
+

+
+ template<typename T> +
+ void cubos::core::ecs::EventWriter<T>::push(T event, + unsigned int mask = DEFAULT_PUSH_MASK) +

+

Sends the given event to the event pipe with the given mask.

+ + + + + + + + + + + + + + +
Parameters
eventEvent.
maskMask.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Opt.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Opt.html new file mode 100644 index 000000000..5b4922e38 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Opt.html @@ -0,0 +1,304 @@ + + + + + cubos::core::ecs::Opt class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::ecs::Opt class +

+

Wrapper for reference types to indicate that the given argument type is optional in a query.

+ + + + + + + + + + +
Template parameters
TArgument type.
+ +
+

Constructors, destructors, conversion operators

+
+
+ Opt() +
+
Constructs without a value.
+
+ Opt(T value) +
+
Constructs with a value.
+
+ Opt(const Opt<T>& other) +
+
Copy constructor.
+
+ operator bool() const +
+
Checks if the optional contains a value.
+
+
+
+

Public functions

+
+
+ void replace(T value) +
+
Moves the given value into the optional, destroying any previously stored value.
+
+ auto contains() const -> bool +
+
Checks if the optional contains a value.
+
+ auto value() -> T& +
+
Gets the underlying value.
+
+ auto operator*() -> T& +
+
Gets the underlying value.
+
+ auto operator->() -> T* +
+
Gets the underlying value.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ cubos::core::ecs::Opt<T>::Opt(T value) +

+

Constructs with a value.

+ + + + + + + + + + +
Parameters
valueValue.
+
+
+

+
+ template<typename T> +
+ cubos::core::ecs::Opt<T>::Opt(const Opt<T>& other) +

+

Copy constructor.

+ + + + + + + + + + +
Parameters
otherOther optional.
+
+
+

+
+ template<typename T> +
+ cubos::core::ecs::Opt<T>::operator bool() const +

+

Checks if the optional contains a value.

+ + + + + + + +
ReturnsWhether the optional contains a value.
+
+
+

+
+ template<typename T> +
+ bool cubos::core::ecs::Opt<T>::contains() const +

+

Checks if the optional contains a value.

+ + + + + + + +
ReturnsWhether the optional contains a value.
+
+
+

+
+ template<typename T> +
+ T& cubos::core::ecs::Opt<T>::value() +

+

Gets the underlying value.

+ + + + + + + +
ReturnsReference to value.
+

Aborts if there's no value.

+
+
+

+
+ template<typename T> +
+ T& cubos::core::ecs::Opt<T>::operator*() +

+

Gets the underlying value.

+ + + + + + + +
ReturnsReference to value.
+

Aborts if there's no value.

+
+
+

+
+ template<typename T> +
+ T* cubos::core::ecs::Opt<T>::operator->() +

+

Gets the underlying value.

+ + + + + + + +
ReturnsReference to value.
+

Aborts if there's no value.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Query.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Query.html new file mode 100644 index 000000000..88e70d6f3 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Query.html @@ -0,0 +1,331 @@ + + + + + cubos::core::ecs::Query class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename... Ts>
+ cubos::core::ecs::Query class +

+

System argument which holds the result of a query over all entities in world which match the given arguments.

+ + + + + + + + + + +
Template parameters
TsArgument types.
+ +

An example of a valid query is:

Query<Position&, const Velocity&, Opt<Rotation&>, Opt<const Scale&>>

This query will return all entities with a Position and Velocity component. Accessors to Rotation and Scale components are also passed but may be null if the component is not present in the entity. Whenever mutability is not needed, const should be used.

+
+

Constructors, destructors, conversion operators

+
+
+ Query(typename QueryData<Ts...>::View view) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ auto begin() -> Iterator +
+
Returns an iterator pointing to the first query match.
+
+ auto end() -> Iterator +
+
Returns an out of bounds iterator representing the end of the query matches.
+
+ auto pin(int target, + Entity entity) -> Query +
+
Returns a new query equal to this one but with the given target pinned to the given entity.
+
+ auto at(Entity entity) -> Opt<std::tuple<Ts...>> +
+
Accesses the match for the given entity, if there is one.
+
+ auto at(Entity firstEntity, + Entity secondEntity) -> Opt<std::tuple<Ts...>> +
+
Accesses the match for the given entities, if there is one.
+
+ auto first() -> Opt<std::tuple<Ts...>> +
+
Returns the first match of the query, if there's any.
+
+
+
+

Function documentation

+
+

+
+ template<typename... Ts> +
+ cubos::core::ecs::Query<Ts>::Query(typename QueryData<Ts...>::View view) +

+

Constructs.

+ + + + + + + + + + +
Parameters
viewQuery data view.
+
+
+

+
+ template<typename... Ts> +
+ Iterator cubos::core::ecs::Query<Ts>::begin() +

+

Returns an iterator pointing to the first query match.

+ + + + + + + +
ReturnsIterator.
+
+
+

+
+ template<typename... Ts> +
+ Iterator cubos::core::ecs::Query<Ts>::end() +

+

Returns an out of bounds iterator representing the end of the query matches.

+ + + + + + + +
ReturnsIterator.
+
+
+

+
+ template<typename... Ts> +
+ Query cubos::core::ecs::Query<Ts>::pin(int target, + Entity entity) +

+

Returns a new query equal to this one but with the given target pinned to the given entity.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
targetTarget index.
entityEntity.
ReturnsQuery.
+

Effectively this filters out all matches where the given target isn't the given entity.

+
+
+

+
+ template<typename... Ts> +
+ Opt<std::tuple<Ts...>> cubos::core::ecs::Query<Ts>::at(Entity entity) +

+

Accesses the match for the given entity, if there is one.

+ + + + + + + + + + + + + + + + +
Parameters
entityEntity.
ReturnsRequested components, or nothing if the entity does not match the query.
+
+
+

+
+ template<typename... Ts> +
+ Opt<std::tuple<Ts...>> cubos::core::ecs::Query<Ts>::at(Entity firstEntity, + Entity secondEntity) +

+

Accesses the match for the given entities, if there is one.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
firstEntityEntity for the first target.
secondEntityEntity for the second target.
ReturnsRequested data, or nothing if the entities do not match the query.
+
+
+

+
+ template<typename... Ts> +
+ Opt<std::tuple<Ts...>> cubos::core::ecs::Query<Ts>::first() +

+

Returns the first match of the query, if there's any.

+ + + + + + + +
ReturnsRequested data, or nothing if there are no matches.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryArchetypeNode.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryArchetypeNode.html new file mode 100644 index 000000000..3cb9b2809 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryArchetypeNode.html @@ -0,0 +1,268 @@ + + + + + cubos::core::ecs::QueryArchetypeNode class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::QueryArchetypeNode class final + +

+

Node which forces a given target to belong to a set of archetypes.

+ +
+

Base classes

+
+
+ class QueryNode +
+
Query filter step, which receives an iterator and advances it until it points to a valid match.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ QueryArchetypeNode(int target) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ void with(ColumnId column) +
+
Forces the node to match only archetypes with the given column.
+
+ void without(ColumnId column) +
+
Forces the node to match only archetypes without the given column.
+
+ auto equivalent(const QueryArchetypeNode& other) const -> bool +
+
Returns whether two nodes are equivalent.
+
+ auto target() const -> int +
+
Gets the target being filtered.
+
+ auto archetypes() const -> const std::vector<ArchetypeId>& +
+
Gets the known archetypes which match the requirements for the target.
+
+ auto estimate() const -> std::size_t override +
+
Returns a rough estimate on how many matches this node produces by itself.
+
+ void update(World& world) override +
+
Updates the node with new data from the given world.
+
+ auto next(World& world, + TargetMask pins, + Iterator& iterator) const -> bool override +
+
Advances the iterator to the next valid match, or checks if the pinned targets are valid.
+
+
+
+

Function documentation

+
+

+ cubos::core::ecs::QueryArchetypeNode::QueryArchetypeNode(int target) +

+

Constructs.

+ + + + + + + + + + +
Parameters
targetTarget.
+
+
+

+ bool cubos::core::ecs::QueryArchetypeNode::equivalent(const QueryArchetypeNode& other) const +

+

Returns whether two nodes are equivalent.

+ + + + + + + + + + +
Parameters
otherOther node.
+
+
+

+ std::size_t cubos::core::ecs::QueryArchetypeNode::estimate() const override +

+

Returns a rough estimate on how many matches this node produces by itself.

+

Nodes are sorted by this value to minimize the number of iterations. It makes more sense to first run the node which produces the fewest matches, as it will be the most selective.

+
+
+

+ void cubos::core::ecs::QueryArchetypeNode::update(World& world) override +

+

Updates the node with new data from the given world.

+ + + + + + + + + + +
Parameters
worldWorld.
+
+
+

+ bool cubos::core::ecs::QueryArchetypeNode::next(World& world, + TargetMask pins, + Iterator& iterator) const override +

+

Advances the iterator to the next valid match, or checks if the pinned targets are valid.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
worldWorld being queried.
pinsWhether each target is pinned.
iteratorIterator.
ReturnsWhether a match was found.
+

Operates in two different modes:

  • Iterate: at least one of the node targets is not pinned.
  • Validate: all node targets are already pinned.

When iterating, this function should receive an iterator with the cursor index set to SIZE_MAX, or one previously returned by this function. It will update the iterator's cursor index and row to point to the first or next valid match. The relevant target archetypes and cursor rows will be set for any newly pinned targets.

When validating, the function will only check if the pinned targets match the requirements and return true or false without modifying the iterator. The passed iterator should have the pinned targets' archetypes and cursor rows set.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryData.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryData.html new file mode 100644 index 000000000..532dcf57c --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryData.html @@ -0,0 +1,307 @@ + + + + + cubos::core::ecs::QueryData class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename... Ts>
+ cubos::core::ecs::QueryData class +

+

Holds the data necessary to execute a query.

+ + + + + + + + + + +
Template parameters
TsArgument types.
+ +

The argument types of the query specify exactly what data will be accessed during iteration. For example, the query might have been constructed with properties such that a given column must be present on the entity. That doesn't mean that the data will actually end up being accessed.

If an argument type is present which requires a certain column to be present, then that column is automatically added to the query properties, if it isn't there already.

+
+

Constructors, destructors, conversion operators

+
+
+ QueryData(World& world, + const std::vector<QueryTerm>& extraTerms) +
+
Constructs.
+
+ QueryData(QueryData&& other) noexcept +
+
Move constructs.
+
+
+
+

Public functions

+
+
+ auto accesses() const -> const std::unordered_set<DataTypeId, DataTypeIdHash>& +
+
Gets a set with the data types accessed by this query.
+
+ void update() +
+
Fetches any new matching archetypes that have been added since the last call to this function.
+
+ auto view() -> View +
+
Returns a view which can be used to iterate over the matches.
+
+ auto at(Entity entity) -> Opt<std::tuple<Ts...>> +
+
Accesses the match for the given entity, if there is one.
+
+ auto at(Entity firstEntity, + Entity secondEntity) -> Opt<std::tuple<Ts...>> +
+
Accesses the match for the given entities, if there is one.
+
+
+
+

Function documentation

+
+

+
+ template<typename... Ts> +
+ cubos::core::ecs::QueryData<Ts>::QueryData(World& world, + const std::vector<QueryTerm>& extraTerms) +

+

Constructs.

+ + + + + + + + + + + + + + +
Parameters
worldWorld being queried.
extraTermsExtra query terms.
+
+
+

+
+ template<typename... Ts> +
+ cubos::core::ecs::QueryData<Ts>::QueryData(QueryData&& other) noexcept +

+

Move constructs.

+ + + + + + + + + + +
Parameters
otherOther query data.
+
+
+

+
+ template<typename... Ts> +
+ const std::unordered_set<DataTypeId, DataTypeIdHash>& cubos::core::ecs::QueryData<Ts>::accesses() const +

+

Gets a set with the data types accessed by this query.

+ + + + + + + +
ReturnsData type set.
+
+
+

+
+ template<typename... Ts> +
+ View cubos::core::ecs::QueryData<Ts>::view() +

+

Returns a view which can be used to iterate over the matches.

+ + + + + + + +
ReturnsView.
+
+
+

+
+ template<typename... Ts> +
+ Opt<std::tuple<Ts...>> cubos::core::ecs::QueryData<Ts>::at(Entity entity) +

+

Accesses the match for the given entity, if there is one.

+ + + + + + + + + + + + + + + + +
Parameters
entityEntity.
ReturnsRequested data, or nothing if the entity does not match the query.
+
+
+

+
+ template<typename... Ts> +
+ Opt<std::tuple<Ts...>> cubos::core::ecs::QueryData<Ts>::at(Entity firstEntity, + Entity secondEntity) +

+

Accesses the match for the given entities, if there is one.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
firstEntityEntity for the first target.
secondEntityEntity for the second target.
ReturnsRequested data, or nothing if the entities do not match the query.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryFetcher.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryFetcher.html new file mode 100644 index 000000000..ac8418440 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryFetcher.html @@ -0,0 +1,254 @@ + + + + + cubos::core::ecs::QueryFetcher class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::ecs::QueryFetcher class +

+

Type meant to be specialized which implements for each argument type the necessary logic to extract it from the tables.

+ + + + + + + + + + +
Template parameters
TArgument type.
+ +
+

Public static functions

+
+
+ static auto term(World& world) -> QueryTerm +
+
Creates a query term with unspecified targets for the argument type.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ QueryFetcher(World& world, + const QueryTerm& term) +
+
Called when a query is constructed for the first time.
+
+
+
+

Public functions

+
+
+ void prepare(const ArchetypeId* targetArchetypes) +
+
Called when iteration starts for the given archetypes. Always called before fetch(), which may be called multiple times after this.
+
+ auto fetch(std::size_t row) -> T +
+
Called to get the actual desired data for a specific match. Always called after prepare() has been called at least once.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ static QueryTerm cubos::core::ecs::QueryFetcher<T>::term(World& world) +

+

Creates a query term with unspecified targets for the argument type.

+ + + + + + + + + + + + + + + + +
Parameters
worldWorld being queried.
ReturnsTerm information.
+
+
+

+
+ template<typename T> +
+ cubos::core::ecs::QueryFetcher<T>::QueryFetcher(World& world, + const QueryTerm& term) +

+

Called when a query is constructed for the first time.

+ + + + + + + + + + + + + + +
Parameters
worldWorld being queried.
termTerm corresponding to the argument being fetched, with specified targets.
+
+
+

+
+ template<typename T> +
+ void cubos::core::ecs::QueryFetcher<T>::prepare(const ArchetypeId* targetArchetypes) +

+

Called when iteration starts for the given archetypes. Always called before fetch(), which may be called multiple times after this.

+ + + + + + + + + + +
Parameters
targetArchetypesPointer to array with the archetype identifiers for the targets.
+
+
+

+
+ template<typename T> +
+ T cubos::core::ecs::QueryFetcher<T>::fetch(std::size_t row) +

+

Called to get the actual desired data for a specific match. Always called after prepare() has been called at least once.

+ + + + + + + + + + +
Parameters
rowRow to fetch.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryFilter.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryFilter.html new file mode 100644 index 000000000..e2b1fbdb6 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryFilter.html @@ -0,0 +1,222 @@ + + + + + cubos::core::ecs::QueryFilter class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::QueryFilter class + +

+

Used to find matches for the given query terms. Essentially contains the non-templated part of the query logic.

+ +
+

Constructors, destructors, conversion operators

+
+
+ QueryFilter(World& world, + const std::vector<QueryTerm>& terms) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ auto cursorIndex(std::size_t termIndex) const -> std::size_t +
+
Gets the cursor index for the given term index.
+
+ void update() +
+
Fetches any new matching archetypes that have been added since the last call to this function.
+
+ auto view() -> View +
+
Returns a view which can be used to iterate over the matches.
+
+ auto targetCount() const -> int +
+
Gets the number of targets.
+
+
+
+

Function documentation

+
+

+ cubos::core::ecs::QueryFilter::QueryFilter(World& world, + const std::vector<QueryTerm>& terms) +

+

Constructs.

+ + + + + + + + + + + + + + +
Parameters
worldWorld being queried.
termsQuery terms.
+
+
+

+ std::size_t cubos::core::ecs::QueryFilter::cursorIndex(std::size_t termIndex) const +

+

Gets the cursor index for the given term index.

+ + + + + + + + + + + + + + + + +
Parameters
termIndexTerm index.
ReturnsCursor index.
+
+
+

+ View cubos::core::ecs::QueryFilter::view() +

+

Returns a view which can be used to iterate over the matches.

+ + + + + + + +
ReturnsView.
+
+
+

+ int cubos::core::ecs::QueryFilter::targetCount() const +

+

Gets the number of targets.

+ + + + + + + +
ReturnsTarget count.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryNode.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryNode.html new file mode 100644 index 000000000..68c6fd6d4 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryNode.html @@ -0,0 +1,277 @@ + + + + + cubos::core::ecs::QueryNode class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::QueryNode class + +

+

Query filter step, which receives an iterator and advances it until it points to a valid match.

+ +
+

Derived classes

+
+
+ class QueryArchetypeNode final +
+
Node which forces a given target to belong to a set of archetypes.
+
+ class QueryRelatedNode final +
+
Node which forces two given targets to be related with a given relation.
+
+
+
+

Public types

+
+
+ using TargetMask = unsigned char +
+
Target mask type.
+
+
+
+

Public static variables

+
+
+ static int MaxTargetCount constexpr +
+
Maximum number of targets.
+
+ static int MaxCursorCount constexpr +
+
Maximum number of cursors.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ QueryNode(int cursor) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ auto cursor() const -> int +
+
Gets the cursor index of the node.
+
+ auto pins() const -> TargetMask +
+
Gets the mask which indicates which targets the node pins.
+
+ auto estimate() const -> std::size_t pure virtual +
+
Returns a rough estimate on how many matches this node produces by itself.
+
+ void update(World& world) pure virtual +
+
Updates the node with new data from the given world.
+
+ auto next(World& world, + TargetMask pins, + Iterator& iterator) const -> bool pure virtual +
+
Advances the iterator to the next valid match, or checks if the pinned targets are valid.
+
+
+
+

Protected functions

+
+
+ void pins(int target) +
+
Indicates that the node pins the given target.
+
+
+
+

Function documentation

+
+

+ std::size_t cubos::core::ecs::QueryNode::estimate() const pure virtual +

+

Returns a rough estimate on how many matches this node produces by itself.

+

Nodes are sorted by this value to minimize the number of iterations. It makes more sense to first run the node which produces the fewest matches, as it will be the most selective.

+
+
+

+ void cubos::core::ecs::QueryNode::update(World& world) pure virtual +

+

Updates the node with new data from the given world.

+ + + + + + + + + + +
Parameters
worldWorld.
+
+
+

+ bool cubos::core::ecs::QueryNode::next(World& world, + TargetMask pins, + Iterator& iterator) const pure virtual +

+

Advances the iterator to the next valid match, or checks if the pinned targets are valid.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
worldWorld being queried.
pinsWhether each target is pinned.
iteratorIterator.
ReturnsWhether a match was found.
+

Operates in two different modes:

  • Iterate: at least one of the node targets is not pinned.
  • Validate: all node targets are already pinned.

When iterating, this function should receive an iterator with the cursor index set to SIZE_MAX, or one previously returned by this function. It will update the iterator's cursor index and row to point to the first or next valid match. The relevant target archetypes and cursor rows will be set for any newly pinned targets.

When validating, the function will only check if the pinned targets match the requirements and return true or false without modifying the iterator. The passed iterator should have the pinned targets' archetypes and cursor rows set.

+
+
+

+ void cubos::core::ecs::QueryNode::pins(int target) protected +

+

Indicates that the node pins the given target.

+ + + + + + + + + + +
Parameters
targetTarget.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryRelatedNode.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryRelatedNode.html new file mode 100644 index 000000000..bc35e2723 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1QueryRelatedNode.html @@ -0,0 +1,267 @@ + + + + + cubos::core::ecs::QueryRelatedNode class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::QueryRelatedNode class final + +

+

Node which forces two given targets to be related with a given relation.

+ +
+

Base classes

+
+
+ class QueryNode +
+
Query filter step, which receives an iterator and advances it until it points to a valid match.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ QueryRelatedNode(int cursor, + DataTypeId dataType, + bool isSymmetric, + bool includeDuplicates, + Traversal traversal, + QueryArchetypeNode& fromNode, + QueryArchetypeNode& toNode) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ auto estimate() const -> std::size_t override +
+
Returns a rough estimate on how many matches this node produces by itself.
+
+ void update(World& world) override +
+
Updates the node with new data from the given world.
+
+ auto next(World& world, + TargetMask pins, + Iterator& iterator) const -> bool override +
+
Advances the iterator to the next valid match, or checks if the pinned targets are valid.
+
+
+
+

Function documentation

+
+

+ cubos::core::ecs::QueryRelatedNode::QueryRelatedNode(int cursor, + DataTypeId dataType, + bool isSymmetric, + bool includeDuplicates, + Traversal traversal, + QueryArchetypeNode& fromNode, + QueryArchetypeNode& toNode) +

+

Constructs.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
cursorCursor index.
dataTypeRelation data type.
isSymmetricWhether the relation is symmetric.
includeDuplicatesWhether, if the relation is symmetric, a relation may appear twice.
traversalTraversal type, in case we're filtering a tree relation.
fromNodeFrom target node.
toNodeTo target node.
+
+
+

+ std::size_t cubos::core::ecs::QueryRelatedNode::estimate() const override +

+

Returns a rough estimate on how many matches this node produces by itself.

+

Nodes are sorted by this value to minimize the number of iterations. It makes more sense to first run the node which produces the fewest matches, as it will be the most selective.

+
+
+

+ void cubos::core::ecs::QueryRelatedNode::update(World& world) override +

+

Updates the node with new data from the given world.

+ + + + + + + + + + +
Parameters
worldWorld.
+
+
+

+ bool cubos::core::ecs::QueryRelatedNode::next(World& world, + TargetMask pins, + Iterator& iterator) const override +

+

Advances the iterator to the next valid match, or checks if the pinned targets are valid.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
worldWorld being queried.
pinsWhether each target is pinned.
iteratorIterator.
ReturnsWhether a match was found.
+

Operates in two different modes:

  • Iterate: at least one of the node targets is not pinned.
  • Validate: all node targets are already pinned.

When iterating, this function should receive an iterator with the cursor index set to SIZE_MAX, or one previously returned by this function. It will update the iterator's cursor index and row to point to the first or next valid match. The relevant target archetypes and cursor rows will be set for any newly pinned targets.

When validating, the function will only check if the pinned targets match the requirements and return true or false without modifying the iterator. The passed iterator should have the pinned targets' archetypes and cursor rows set.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1ReadResource.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1ReadResource.html new file mode 100644 index 000000000..4c8ab7df8 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1ReadResource.html @@ -0,0 +1,185 @@ + + + + + cubos::core::ecs::ReadResource class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::ecs::ReadResource class +

+

Utility struct used to reference a resource of type T for reading.

+ + + + + + + + + + +
Template parameters
TResource type.
+ +
+

Constructors, destructors, conversion operators

+
+
+ ReadResource(ReadResource&& other) noexcept +
+
Move construct.
+
+
+
+

Public functions

+
+
+ auto get() const -> const T& +
+
Gets the underlying resource reference.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ cubos::core::ecs::ReadResource<T>::ReadResource(ReadResource&& other) noexcept +

+

Move construct.

+ + + + + + + + + + +
Parameters
otherOther resource to move from.
+
+
+

+
+ template<typename T> +
+ const T& cubos::core::ecs::ReadResource<T>::get() const +

+

Gets the underlying resource reference.

+ + + + + + + +
ReturnsResource reference.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1ResourceManager.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1ResourceManager.html new file mode 100644 index 000000000..bca324061 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1ResourceManager.html @@ -0,0 +1,224 @@ + + + + + cubos::core::ecs::ResourceManager class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::ResourceManager class final + +

+

Holds and manages resources.

+ +

Used internally by World.

+
+

Public functions

+
+
+
template<typename T, typename... TArgs>
+ void add(TArgs... args) +
+
Registers a new resource type in the resource manager.
+
+
template<typename T>
+ auto read() const -> ReadResource<T> +
+
Locks a resource for reading and returns it.
+
+
template<typename T>
+ auto write() const -> WriteResource<T> +
+
Locks a resource for writing and returns it.
+
+
+
+

Function documentation

+
+

+
+ template<typename T, typename... TArgs> +
+ void cubos::core::ecs::ResourceManager::add(TArgs... args) +

+

Registers a new resource type in the resource manager.

+ + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TResource type.
TArgsTypes of the arguments of the constructor of the resource.
Parameters
argsArguments of the constructor of the resource.
+

This function is not thread-safe and should be called before any other function.

+
+
+

+
+ template<typename T> +
+ ReadResource<T> cubos::core::ecs::ResourceManager::read() const +

+

Locks a resource for reading and returns it.

+ + + + + + + + + + + + + + + + +
Template parameters
TResource type.
ReturnsResource lock.
+
+
+

+
+ template<typename T> +
+ WriteResource<T> cubos::core::ecs::ResourceManager::write() const +

+

Locks a resource for writing and returns it.

+ + + + + + + + + + + + + + + + +
Template parameters
TResource type.
ReturnsResource lock.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1SparseRelationTable.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1SparseRelationTable.html new file mode 100644 index 000000000..42988d660 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1SparseRelationTable.html @@ -0,0 +1,827 @@ + + + + + cubos::core::ecs::SparseRelationTable class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::SparseRelationTable class final + +

+

A table which stores relations. Allows for quick insertion, deletion and iteration.

+ +

Internally, the table is stored simply as a vector of relations and their data. Each row in this table stores:

  • the 'from' entity index;
  • the 'to' entity index;
  • the previous and next rows with the same 'from' index;
  • the previous and next rows with the same 'to' index;
  • the relation data itself.

To make random accesses more efficient, we also store an hashtable which maps entity index pairs to rows. This way, we can quickly check if a relation exists or where it's stored.

Additionally, we store two other hashtables, one which associate 'from' and 'to' indices to rows in the table which represent the first and last nodes of linked lists, where each node is a row with the same 'from' or 'to' index, depending on the list.

These linked lists are essential to provide fast query times, as instead of having to iterate over the entire table and filter for entity, we only need to follow the linked list chain.

+
+

Public types

+
+
+ enum class Transformation { None, + Swap, + SwapIfGreater } +
+
Transformations to apply while moving relations between tables.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ SparseRelationTable(const reflection::Type& relationType) +
+
Constructs with the given relation type.
+
+
+
+

Public functions

+
+
+ auto insert(uint32_t from, + uint32_t to, + void* value) -> bool +
+
Adds a relation between the given indices. If it already exists, overwrites it.
+
+ auto erase(uint32_t from, + uint32_t to) -> bool +
+
Removes a relation between the given indices. If it didn't exist, does nothing.
+
+ auto eraseFrom(uint32_t from) -> std::size_t +
+
Removes all relations from the given index.
+
+ auto moveFrom(uint32_t from, + SparseRelationTable& other, + Transformation transformation) -> std::size_t +
+
Moves all relations with the given from index to another table.
+
+ auto eraseTo(uint32_t to) -> std::size_t +
+
Removes all relations to the given index.
+
+ auto moveTo(uint32_t to, + SparseRelationTable& other, + Transformation transformation) -> std::size_t +
+
Moves all relations with the given to index to another table.
+
+ auto contains(uint32_t from, + uint32_t to) const -> bool +
+
Checks whether the given relation exists between the given indices.
+
+ auto row(uint32_t from, + uint32_t to) const -> std::size_t +
+
Gets the row of the relation with the given indices, or size() if there is none.
+
+ auto at(std::size_t row) -> void* +
+
Get the relation at the given row.
+
+ auto at(std::size_t row) const -> const void* +
+
Get the relation at the given row.
+
+ void indices(std::size_t row, + uint32_t& from, + uint32_t& to) const +
+
Get the entity indices at the given row.
+
+ auto from(std::size_t row) const -> uint32_t +
+
Get the 'from' entity index at the given row.
+
+ auto to(std::size_t row) const -> uint32_t +
+
Get the 'to' entity index at the given row.
+
+ auto firstFrom(uint32_t index) const -> std::size_t +
+
Gets the first row with the given from index, or size() if there is none.
+
+ auto firstTo(uint32_t index) const -> std::size_t +
+
Gets the first row with the given to index, or size() if there is none.
+
+ auto nextFrom(std::size_t row) const -> std::size_t +
+
Gets the next row with the same from index, or size() if there is none.
+
+ auto nextTo(std::size_t row) const -> std::size_t +
+
Gets the next row with the same to index, or size() if there is none.
+
+ auto begin() const -> Iterator +
+
Gets an iterator to the first relation of the table.
+
+ auto end() const -> Iterator +
+
Gets an iterator which represents the end of the table.
+
+ auto viewFrom(uint32_t from) const -> View +
+
Returns a view of the relations with the given from index.
+
+ auto viewTo(uint32_t to) const -> View +
+
Returns a view of the relations with the given to index.
+
+ auto size() const -> std::size_t +
+
Returns the number of relations on the table.
+
+
+
+

Enum documentation

+
+

+ enum class cubos::core::ecs::SparseRelationTable::Transformation +

+

Transformations to apply while moving relations between tables.

+ + + + + + + + + + + + + + + + +
Enumerators
None +

Keep the relations as they are.

+
Swap +

Flip the 'from' and 'to' indices.

+
SwapIfGreater +

Swap if the 'from' index is greater than the 'to' index.

+
+
+
+
+

Function documentation

+
+

+ cubos::core::ecs::SparseRelationTable::SparseRelationTable(const reflection::Type& relationType) +

+

Constructs with the given relation type.

+ + + + + + + + + + +
Parameters
relationTypeRelation type.
+ +
+
+

+ bool cubos::core::ecs::SparseRelationTable::insert(uint32_t from, + uint32_t to, + void* value) +

+

Adds a relation between the given indices. If it already exists, overwrites it.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
fromFrom index.
toTo index.
valueRelation value to move from.
ReturnsWhether the relation already existed.
+
+
+

+ bool cubos::core::ecs::SparseRelationTable::erase(uint32_t from, + uint32_t to) +

+

Removes a relation between the given indices. If it didn't exist, does nothing.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
fromFrom index.
toTo index.
ReturnsWhether the relation existed.
+
+
+

+ std::size_t cubos::core::ecs::SparseRelationTable::eraseFrom(uint32_t from) +

+

Removes all relations from the given index.

+ + + + + + + + + + + + + + + + +
Parameters
fromFrom index.
ReturnsHow many relations were erased.
+
+
+

+ std::size_t cubos::core::ecs::SparseRelationTable::moveFrom(uint32_t from, + SparseRelationTable& other, + Transformation transformation) +

+

Moves all relations with the given from index to another table.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
fromFrom index.
otherOther table. Must have the same relation type.
transformationTransformation to apply to the relations.
ReturnsHow many relations were erased.
+
+
+

+ std::size_t cubos::core::ecs::SparseRelationTable::eraseTo(uint32_t to) +

+

Removes all relations to the given index.

+ + + + + + + + + + + + + + + + +
Parameters
toTo index.
ReturnsHow many relations were moved.
+
+
+

+ std::size_t cubos::core::ecs::SparseRelationTable::moveTo(uint32_t to, + SparseRelationTable& other, + Transformation transformation) +

+

Moves all relations with the given to index to another table.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
toTo index index.
otherOther table. Must have the same relation type.
transformationTransformation to apply to the relations.
ReturnsHow many relations were moved.
+
+
+

+ bool cubos::core::ecs::SparseRelationTable::contains(uint32_t from, + uint32_t to) const +

+

Checks whether the given relation exists between the given indices.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
fromFrom index.
toTo index.
ReturnsWhether the relation exists.
+
+
+

+ std::size_t cubos::core::ecs::SparseRelationTable::row(uint32_t from, + uint32_t to) const +

+

Gets the row of the relation with the given indices, or size() if there is none.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
fromFrom index.
toTo index.
ReturnsRow of the data.
+
+
+

+ void* cubos::core::ecs::SparseRelationTable::at(std::size_t row) +

+

Get the relation at the given row.

+ + + + + + + + + + + + + + + + +
Parameters
rowRow of the relation to get.
ReturnsPointer to the relation.
+ +
+
+

+ const void* cubos::core::ecs::SparseRelationTable::at(std::size_t row) const +

+

Get the relation at the given row.

+ + + + + + + + + + + + + + + + +
Parameters
rowRow of the relation to get.
ReturnsPointer to the relation.
+ +
+
+

+ void cubos::core::ecs::SparseRelationTable::indices(std::size_t row, + uint32_t& from, + uint32_t& to) const +

+

Get the entity indices at the given row.

+ + + + + + + + + + + + + + + + + + +
Parameters
rowRow to get.
from outFrom index.
to outTo index.
+ +
+
+

+ uint32_t cubos::core::ecs::SparseRelationTable::from(std::size_t row) const +

+

Get the 'from' entity index at the given row.

+ + + + + + + + + + + + + + + + +
Parameters
rowRow to get.
ReturnsFrom index.
+ +
+
+

+ uint32_t cubos::core::ecs::SparseRelationTable::to(std::size_t row) const +

+

Get the 'to' entity index at the given row.

+ + + + + + + + + + + + + + + + +
Parameters
rowRow to get.
ReturnsFrom index.
+ +
+
+

+ std::size_t cubos::core::ecs::SparseRelationTable::firstFrom(uint32_t index) const +

+

Gets the first row with the given from index, or size() if there is none.

+ + + + + + + + + + + + + + + + +
Parameters
indexFrom index.
ReturnsFirst row with the given from index.
+
+
+

+ std::size_t cubos::core::ecs::SparseRelationTable::firstTo(uint32_t index) const +

+

Gets the first row with the given to index, or size() if there is none.

+ + + + + + + + + + + + + + + + +
Parameters
indexTo index.
ReturnsFirst row with the given to index.
+
+
+

+ std::size_t cubos::core::ecs::SparseRelationTable::nextFrom(std::size_t row) const +

+

Gets the next row with the same from index, or size() if there is none.

+ + + + + + + + + + + + + + + + +
Parameters
rowRow to get the next from.
ReturnsNext row with the same from index.
+
+
+

+ std::size_t cubos::core::ecs::SparseRelationTable::nextTo(std::size_t row) const +

+

Gets the next row with the same to index, or size() if there is none.

+ + + + + + + + + + + + + + + + +
Parameters
rowRow to get the next to.
ReturnsNext row with the same to index.
+
+
+

+ Iterator cubos::core::ecs::SparseRelationTable::begin() const +

+

Gets an iterator to the first relation of the table.

+ + + + + + + +
ReturnsIterator.
+
+
+

+ Iterator cubos::core::ecs::SparseRelationTable::end() const +

+

Gets an iterator which represents the end of the table.

+ + + + + + + +
ReturnsIterator.
+
+
+

+ View cubos::core::ecs::SparseRelationTable::viewFrom(uint32_t from) const +

+

Returns a view of the relations with the given from index.

+ + + + + + + + + + + + + + + + +
Parameters
fromFrom index.
ReturnsRelation view.
+
+
+

+ View cubos::core::ecs::SparseRelationTable::viewTo(uint32_t to) const +

+

Returns a view of the relations with the given to index.

+ + + + + + + + + + + + + + + + +
Parameters
toTo index.
ReturnsRelation view.
+
+
+

+ std::size_t cubos::core::ecs::SparseRelationTable::size() const +

+

Returns the number of relations on the table.

+ + + + + + + +
ReturnsRelation count.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1SparseRelationTableRegistry.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1SparseRelationTableRegistry.html new file mode 100644 index 000000000..25be0e773 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1SparseRelationTableRegistry.html @@ -0,0 +1,419 @@ + + + + + cubos::core::ecs::SparseRelationTableRegistry class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::SparseRelationTableRegistry class + +

+

Stores all of the sparse relation tables.

+ +
+

Public types

+
+
+ class TypeIndex +
+
Stores the ids of tables of a given type.
+
+ using Iterator = std::unordered_map<DataTypeId, TypeIndex, DataTypeIdHash>::const_iterator +
+
Used to iterate over type indices in the registry.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ SparseRelationTableRegistry() +
+
Constructs.
+
+
+
+

Public functions

+
+
+ auto contains(SparseRelationTableId id) const -> bool +
+
Checks if there's a table with the given identifier.
+
+ auto create(SparseRelationTableId id, + Types& types) -> SparseRelationTable& +
+
Returns a reference to the table with the given identifier.
+
+ auto at(SparseRelationTableId id) -> SparseRelationTable& +
+
Returns a reference to the table with the given identifier.
+
+ auto at(SparseRelationTableId id) const -> const SparseRelationTable& +
+
Returns a reference to the table with the given identifier.
+
+ auto type(DataTypeId type) const -> const TypeIndex& +
+
Returns the index used to search for tables of relations with a given type.
+
+ void move(ArchetypeId source, + ArchetypeId target, + uint32_t index) +
+
Moves all relations of an entity from an archetype to another.
+
+ void erase(ArchetypeId archetype, + uint32_t index) +
+
Removes all relations of an entity.
+
+ auto forEach(std::size_t counter, + auto func) const -> std::size_t +
+
Calls the given function for each new table.
+
+ auto begin() const -> Iterator +
+
Gets an iterator to the start of the type indices of this registry.
+
+ auto end() const -> Iterator +
+
Gets an iterator to the end of the type indices of this registry.
+
+
+
+

Function documentation

+
+

+ bool cubos::core::ecs::SparseRelationTableRegistry::contains(SparseRelationTableId id) const +

+

Checks if there's a table with the given identifier.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier.
ReturnsWhether it contains the table or not.
+
+
+

+ SparseRelationTable& cubos::core::ecs::SparseRelationTableRegistry::create(SparseRelationTableId id, + Types& types) +

+

Returns a reference to the table with the given identifier.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
idIdentifier.
typesType registry used to initialize the table, if necessary.
ReturnsReference to table.
+

Creates the table if it doesn't exist already.

+
+
+

+ SparseRelationTable& cubos::core::ecs::SparseRelationTableRegistry::at(SparseRelationTableId id) +

+

Returns a reference to the table with the given identifier.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier.
ReturnsReference to table.
+

Aborts if the table doesn't exist.

+
+
+

+ const SparseRelationTable& cubos::core::ecs::SparseRelationTableRegistry::at(SparseRelationTableId id) const +

+

Returns a reference to the table with the given identifier.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier.
ReturnsReference to table.
+

Aborts if the table doesn't exist.

+
+
+

+ const TypeIndex& cubos::core::ecs::SparseRelationTableRegistry::type(DataTypeId type) const +

+

Returns the index used to search for tables of relations with a given type.

+ + + + + + + + + + + + + + + + +
Parameters
typeType identifier.
ReturnsType index.
+
+
+

+ void cubos::core::ecs::SparseRelationTableRegistry::move(ArchetypeId source, + ArchetypeId target, + uint32_t index) +

+

Moves all relations of an entity from an archetype to another.

+ + + + + + + + + + + + + + + + + + +
Parameters
sourceOld archetype.
targetNew archetype.
indexEntity index.
+
+
+

+ void cubos::core::ecs::SparseRelationTableRegistry::erase(ArchetypeId archetype, + uint32_t index) +

+

Removes all relations of an entity.

+ + + + + + + + + + + + + + +
Parameters
archetypeEntity archetype.
indexEntity index.
+
+
+

+ std::size_t cubos::core::ecs::SparseRelationTableRegistry::forEach(std::size_t counter, + auto func) const +

+

Calls the given function for each new table.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
counterCounter previously returned by this function. Zero should be used for the first call.
funcFunction which receives a table identifier.
ReturnsCounter to be passed to this function in a future call.
+
+
+

+ Iterator cubos::core::ecs::SparseRelationTableRegistry::begin() const +

+

Gets an iterator to the start of the type indices of this registry.

+ + + + + + + +
ReturnsIterator.
+
+
+

+ Iterator cubos::core::ecs::SparseRelationTableRegistry::end() const +

+

Gets an iterator to the end of the type indices of this registry.

+ + + + + + + +
ReturnsIterator.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1SparseRelationTableRegistry_1_1TypeIndex.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1SparseRelationTableRegistry_1_1TypeIndex.html new file mode 100644 index 000000000..c2ebf3d8b --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1SparseRelationTableRegistry_1_1TypeIndex.html @@ -0,0 +1,197 @@ + + + + + cubos::core::ecs::SparseRelationTableRegistry::TypeIndex class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::SparseRelationTableRegistry::TypeIndex class + +

+

Stores the ids of tables of a given type.

+ +
+

Public functions

+
+
+ void insert(SparseRelationTableId id) +
+
Inserts a new table identifier into the index.
+
+ auto from() const -> const auto& +
+
Returns a reference to a map which maps archetypes to the tables where it is the 'from' archetype.
+
+ auto to() const -> const auto& +
+
Returns a reference to a map which maps archetypes to the tables where it is the 'to' archetype.
+
+ auto maxDepth() const -> int +
+
Returns the maximum depth of the tables in this index.
+
+
+
+

Function documentation

+
+

+ void cubos::core::ecs::SparseRelationTableRegistry::TypeIndex::insert(SparseRelationTableId id) +

+

Inserts a new table identifier into the index.

+ + + + + + + + + + +
Parameters
idTable identifier.
+
+
+

+ const auto& cubos::core::ecs::SparseRelationTableRegistry::TypeIndex::from() const +

+

Returns a reference to a map which maps archetypes to the tables where it is the 'from' archetype.

+ + + + + + + +
ReturnsMap from archetypes to vectors of table identifiers.
+
+
+

+ const auto& cubos::core::ecs::SparseRelationTableRegistry::TypeIndex::to() const +

+

Returns a reference to a map which maps archetypes to the tables where it is the 'to' archetype.

+ + + + + + + +
ReturnsMap from archetypes to vectors of table identifiers.
+
+
+

+ int cubos::core::ecs::SparseRelationTableRegistry::TypeIndex::maxDepth() const +

+

Returns the maximum depth of the tables in this index.

+ + + + + + + +
ReturnsMaximum depth.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1System.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1System.html new file mode 100644 index 000000000..6e23254ad --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1System.html @@ -0,0 +1,258 @@ + + + + + cubos::core::ecs::System class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::ecs::System class +

+

Holds a system with a return type T.

+ + + + + + + + + + +
Template parameters
TSystem return type.
+ +
+

Public static functions

+
+
+ static auto make(World& world, + auto function, + const std::vector<SystemOptions>& options = {}) -> System +
+
Creates a new system for the given world with the given function and options.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ System(System&& system) defaulted noexcept +
+
Move constructs.
+
+
+
+

Public functions

+
+
+ auto run(CommandBuffer& cmdBuffer) -> T +
+
Runs the system.
+
+ auto access() const -> const SystemAccess& +
+
Gets a reference to the access patterns of the system.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ static System cubos::core::ecs::System<T>::make(World& world, + auto function, + const std::vector<SystemOptions>& options = {}) +

+

Creates a new system for the given world with the given function and options.

+ + + + + + + + + + + + + + + + + + +
Parameters
worldWorld the system will access.
functionSystem function, which should return T.
optionsOptions for the system arguments.
+

The first option is applied to the first argument which requests it, and the same for subsequent options. If there are more options than arguments which request them, aborts. Otherwise, if there are more arguments requesting options than supplied options, the remaining arguments are assigned default-value options.

+
+
+

+
+ template<typename T> +
+ cubos::core::ecs::System<T>::System(System&& system) defaulted noexcept +

+

Move constructs.

+ + + + + + + + + + +
Parameters
systemOther system.
+
+
+

+
+ template<typename T> +
+ T cubos::core::ecs::System<T>::run(CommandBuffer& cmdBuffer) +

+

Runs the system.

+ + + + + + + + + + + + + + + + +
Parameters
cmdBufferCommand buffer.
ReturnsReturn value.
+
+
+

+
+ template<typename T> +
+ const SystemAccess& cubos::core::ecs::System<T>::access() const +

+

Gets a reference to the access patterns of the system.

+ + + + + + + +
ReturnsAccess patterns.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1SystemFetcher.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1SystemFetcher.html new file mode 100644 index 000000000..9bc53bb69 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1SystemFetcher.html @@ -0,0 +1,228 @@ + + + + + cubos::core::ecs::SystemFetcher class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::ecs::SystemFetcher class +

+

Type meant to be specialized which implements for each argument type the necessary logic to extract it from the world.

+ + + + + + + + + + +
Template parameters
TArgument type.
+ +
+

Public static variables

+
+
+ static bool ConsumesOptions constexpr +
+
Indicates whether this argument type consumes system options.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ SystemFetcher(World& world, + const SystemOptions& options) +
+
Called when a system is constructed for the first time.
+
+
+
+

Public functions

+
+
+ void analyze(SystemAccess& access) const +
+
Called to determine the access patterns of the argument.
+
+ auto fetch(CommandBuffer& cmdBuffer) -> T +
+
Called each system run to fetch the data from the world.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ cubos::core::ecs::SystemFetcher<T>::SystemFetcher(World& world, + const SystemOptions& options) +

+

Called when a system is constructed for the first time.

+ + + + + + + + + + + + + + +
Parameters
worldWorld to extract data from.
optionsArgument options.
+
+
+

+
+ template<typename T> +
+ void cubos::core::ecs::SystemFetcher<T>::analyze(SystemAccess& access) const +

+

Called to determine the access patterns of the argument.

+ + + + + + + + + + +
Parameters
access outAccess patterns to add info to.
+
+
+

+
+ template<typename T> +
+ T cubos::core::ecs::SystemFetcher<T>::fetch(CommandBuffer& cmdBuffer) +

+

Called each system run to fetch the data from the world.

+ + + + + + + + + + +
Parameters
cmdBufferCommand buffer.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Tables.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Tables.html new file mode 100644 index 000000000..7086219c1 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Tables.html @@ -0,0 +1,194 @@ + + + + + cubos::core::ecs::Tables class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::Tables class final + +

+

Stores the tables of a given world.

+ +
+

Public functions

+
+
+ auto dense() -> DenseTableRegistry& +
+
Gets a reference to the dense table registry.
+
+ auto dense() const -> const DenseTableRegistry& +
+
Gets a reference to the dense table registry.
+
+ auto sparseRelation() -> SparseRelationTableRegistry& +
+
Gets a reference to the sparse relation table registry.
+
+ auto sparseRelation() const -> const SparseRelationTableRegistry& +
+
Gets a reference to the sparse relation table registry.
+
+
+
+

Function documentation

+
+

+ DenseTableRegistry& cubos::core::ecs::Tables::dense() +

+

Gets a reference to the dense table registry.

+ + + + + + + +
ReturnsReference to dense table registry.
+
+
+

+ const DenseTableRegistry& cubos::core::ecs::Tables::dense() const +

+

Gets a reference to the dense table registry.

+ + + + + + + +
ReturnsReference to dense table registry.
+
+
+

+ SparseRelationTableRegistry& cubos::core::ecs::Tables::sparseRelation() +

+

Gets a reference to the sparse relation table registry.

+ + + + + + + +
ReturnsReference to sparse relation table registry.
+
+
+

+ const SparseRelationTableRegistry& cubos::core::ecs::Tables::sparseRelation() const +

+

Gets a reference to the sparse relation table registry.

+ + + + + + + +
ReturnsReference to sparse relation table registry.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1TagBuilder.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1TagBuilder.html new file mode 100644 index 000000000..bf811b721 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1TagBuilder.html @@ -0,0 +1,310 @@ + + + + + cubos::core::ecs::TagBuilder class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::TagBuilder class + +

+

Used to chain configurations related to tags.

+ +
+

Constructors, destructors, conversion operators

+
+
+ TagBuilder(World& world, + core::ecs::Dispatcher& dispatcher, + std::vector<std::string>& tags) +
+
Construct.
+
+
+
+

Public functions

+
+
+ auto before(const std::string& tag) -> TagBuilder& +
+
Sets the current tag to be executed before another tag.
+
+ auto after(const std::string& tag) -> TagBuilder& +
+
Sets the current tag to be executed after another tag.
+
+ auto tagged(const std::string& tag) -> TagBuilder& +
+
Tags all systems on this tag with the given tag.
+
+
template<typename F>
+ auto runIf(F func) -> TagBuilder& +
+
Adds a condition to the current tag. If this condition returns false, systems with this tag will not be executed. For the tagged systems to run, all conditions must return true.
+
+
template<typename F>
+ auto repeatWhile(F func) -> TagBuilder& +
+
Makes all systems within the tag repeat as a group until the given condition evaluates to false.
+
+
+
+

Function documentation

+
+

+ cubos::core::ecs::TagBuilder::TagBuilder(World& world, + core::ecs::Dispatcher& dispatcher, + std::vector<std::string>& tags) +

+

Construct.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
worldWorld.
dispatcherDispatcher being configured.
tagsVector which stores the tags for this dispatcher.
ReturnsReference to this object, for chaining.
+
+
+

+ TagBuilder& cubos::core::ecs::TagBuilder::before(const std::string& tag) +

+

Sets the current tag to be executed before another tag.

+ + + + + + + + + + + + + + + + +
Parameters
tagTag to be executed before.
ReturnsReference to this object, for chaining.
+
+
+

+ TagBuilder& cubos::core::ecs::TagBuilder::after(const std::string& tag) +

+

Sets the current tag to be executed after another tag.

+ + + + + + + + + + + + + + + + +
Parameters
tagTag to be executed after.
ReturnsReference to this object, for chaining.
+
+
+

+ TagBuilder& cubos::core::ecs::TagBuilder::tagged(const std::string& tag) +

+

Tags all systems on this tag with the given tag.

+ + + + + + + + + + + + + + + + +
Parameters
tagTag to be inherited from.
ReturnsReference to this object, for chaining.
+
+
+

+
+ template<typename F> +
+ TagBuilder& cubos::core::ecs::TagBuilder::runIf(F func) +

+

Adds a condition to the current tag. If this condition returns false, systems with this tag will not be executed. For the tagged systems to run, all conditions must return true.

+ + + + + + + + + + + + + + + + +
Parameters
funcCondition function.
ReturnsReference to this object, for chaining.
+
+
+

+
+ template<typename F> +
+ TagBuilder& cubos::core::ecs::TagBuilder::repeatWhile(F func) +

+

Makes all systems within the tag repeat as a group until the given condition evaluates to false.

+ + + + + + + + + + + + + + + + +
Parameters
funcCondition function.
ReturnsReference to this object, for chaining.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1TypeBuilder.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1TypeBuilder.html new file mode 100644 index 000000000..6479c47fb --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1TypeBuilder.html @@ -0,0 +1,296 @@ + + + + + cubos::core::ecs::TypeBuilder class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::ecs::TypeBuilder class +

+

Builder for reflection::Type objects which represent ECS types.

+ + + + + + + + + + +
Template parameters
TRelation type.
+ +

Used to reduce the amount of boilerplate code required to define a ECS types. Automatically adds the reflection::ConstructibleTrait and reflection::FieldsTrait. The type T must be default-constructible, copy-constructible and move-constructible.

+
+

Constructors, destructors, conversion operators

+
+
+ TypeBuilder(std::string name) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ auto symmetric() && -> TypeBuilder&& +
+
Makes the type symmetric. Only used by relation types.
+
+ auto tree() && -> TypeBuilder&& +
+
Makes the type a tree relation. Only used by relation types.
+
+ auto ephemeral() && -> TypeBuilder&& +
+
Makes the type ephemeral.
+
+
template<typename F>
+ auto withField(std::string name, + F T::* pointer) && -> TypeBuilder&& +
+
Adds a field to the type.
+
+ auto build() && -> reflection::Type& +
+
Builds the type.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ cubos::core::ecs::TypeBuilder<T>::TypeBuilder(std::string name) +

+

Constructs.

+ + + + + + + + + + +
Parameters
nameType name, including namespace.
+
+
+

+
+ template<typename T> +
+ TypeBuilder&& cubos::core::ecs::TypeBuilder<T>::symmetric() && +

+

Makes the type symmetric. Only used by relation types.

+ + + + + + + +
ReturnsBuilder.
+
+
+

+
+ template<typename T> +
+ TypeBuilder&& cubos::core::ecs::TypeBuilder<T>::tree() && +

+

Makes the type a tree relation. Only used by relation types.

+ + + + + + + +
ReturnsBuilder.
+
+
+

+
+ template<typename T> +
+ TypeBuilder&& cubos::core::ecs::TypeBuilder<T>::ephemeral() && +

+

Makes the type ephemeral.

+ + + + + + + +
ReturnsBuilder.
+
+
+

+
+ template<typename T> + template<typename F> +
+ TypeBuilder&& cubos::core::ecs::TypeBuilder<T>::withField(std::string name, + F T::* pointer) && +

+

Adds a field to the type.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
FField type.
Parameters
nameField name.
pointerField pointer.
ReturnsBuilder.
+
+
+

+
+ template<typename T> +
+ reflection::Type& cubos::core::ecs::TypeBuilder<T>::build() && +

+

Builds the type.

+ + + + + + + +
ReturnsRelation type.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Types.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Types.html new file mode 100644 index 000000000..1b464a988 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1Types.html @@ -0,0 +1,477 @@ + + + + + cubos::core::ecs::Types class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::Types class final + +

+

Registry of all data types used in an ECS world.

+ +
+

Public functions

+
+
+ void addComponent(const reflection::Type& type) +
+
Registers a component type.
+
+ void addRelation(const reflection::Type& type) +
+
Registers a relation type.
+
+ auto id(const reflection::Type& type) const -> DataTypeId +
+
Gets the identifier of a data type.
+
+
template<reflection::Reflectable T>
+ auto id() const -> DataTypeId +
+
Gets the identifier of a data type.
+
+ auto id(const std::string& name) const -> DataTypeId +
+
Gets the identifier of a data type.
+
+ auto type(DataTypeId id) const -> const reflection::Type& +
+
Gets a data type from its identifier.
+
+ auto contains(const reflection::Type& type) const -> bool +
+
Checks if a data type is registered.
+
+ auto contains(const std::string& name) const -> bool +
+
Checks if a data type is registered.
+
+ auto isComponent(DataTypeId id) const -> bool +
+
Checks if the given data type is a component.
+
+ auto isRelation(DataTypeId id) const -> bool +
+
Checks if the given data type is a relation.
+
+ auto isSymmetricRelation(DataTypeId id) const -> bool +
+
Checks if the given data type is a symmetric relation.
+
+ auto isTreeRelation(DataTypeId id) const -> bool +
+
Checks if the given data type is a tree relation.
+
+ auto components() const -> reflection::TypeRegistry +
+
Gets a type registry with only the component types.
+
+ auto relations() const -> reflection::TypeRegistry +
+
Gets a type registry with only the relation types.
+
+
+
+

Function documentation

+
+

+ void cubos::core::ecs::Types::addComponent(const reflection::Type& type) +

+

Registers a component type.

+ + + + + + + + + + +
Parameters
typeComponent type.
+
+
+

+ void cubos::core::ecs::Types::addRelation(const reflection::Type& type) +

+

Registers a relation type.

+ + + + + + + + + + +
Parameters
typeRelation type.
+
+
+

+ DataTypeId cubos::core::ecs::Types::id(const reflection::Type& type) const +

+

Gets the identifier of a data type.

+ + + + + + + + + + + + + + + + +
Parameters
typeData type.
ReturnsData type identifier.
+

Aborts if the data type is not registered.

+
+
+

+
+ template<reflection::Reflectable T> +
+ DataTypeId cubos::core::ecs::Types::id() const +

+

Gets the identifier of a data type.

+ + + + + + + + + + + + + + + + +
Template parameters
TData type.
ReturnsData type identifier.
+

Aborts if the data type is not registered.

+
+
+

+ DataTypeId cubos::core::ecs::Types::id(const std::string& name) const +

+

Gets the identifier of a data type.

+ + + + + + + + + + + + + + + + +
Parameters
nameData type name.
ReturnsData type identifier.
+

Aborts if the data type is not registered.

+
+
+

+ const reflection::Type& cubos::core::ecs::Types::type(DataTypeId id) const +

+

Gets a data type from its identifier.

+ + + + + + + + + + + + + + + + +
Parameters
idData type identifier.
ReturnsData type.
+
+
+

+ bool cubos::core::ecs::Types::contains(const reflection::Type& type) const +

+

Checks if a data type is registered.

+ + + + + + + + + + + + + + + + +
Parameters
typeData type.
ReturnsWhether the data type is registered.
+
+
+

+ bool cubos::core::ecs::Types::contains(const std::string& name) const +

+

Checks if a data type is registered.

+ + + + + + + + + + + + + + + + +
Parameters
nameData type name.
ReturnsWhether the data type is registered.
+
+
+

+ bool cubos::core::ecs::Types::isComponent(DataTypeId id) const +

+

Checks if the given data type is a component.

+ + + + + + + + + + + + + + + + +
Parameters
idData type identifier.
ReturnsWhether the identifier refers to a component.
+
+
+

+ bool cubos::core::ecs::Types::isRelation(DataTypeId id) const +

+

Checks if the given data type is a relation.

+ + + + + + + + + + + + + + + + +
Parameters
idData type identifier.
ReturnsWhether the identifier refers to a relation.
+
+
+

+ bool cubos::core::ecs::Types::isSymmetricRelation(DataTypeId id) const +

+

Checks if the given data type is a symmetric relation.

+ + + + + + + + + + + + + + + + +
Parameters
idData type identifier.
ReturnsWhether the identifier refers to a symmetric relation.
+
+
+

+ bool cubos::core::ecs::Types::isTreeRelation(DataTypeId id) const +

+

Checks if the given data type is a tree relation.

+ + + + + + + + + + + + + + + + +
Parameters
idData type identifier.
ReturnsWhether the identifier refers to a tree relation.
+
+
+

+ reflection::TypeRegistry cubos::core::ecs::Types::components() const +

+

Gets a type registry with only the component types.

+ + + + + + + +
ReturnsComponent type registry.
+
+
+

+ reflection::TypeRegistry cubos::core::ecs::Types::relations() const +

+

Gets a type registry with only the relation types.

+ + + + + + + +
ReturnsRelation type registry.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1World.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1World.html new file mode 100644 index 000000000..d174139e7 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1World.html @@ -0,0 +1,1208 @@ + + + + + cubos::core::ecs::World class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::World class + +

+

Holds entities, their components and resources.

+ + +
+

Constructors, destructors, conversion operators

+
+
+ World() +
+
World constructor.
+
+
+
+

Public functions

+
+
+
template<typename T, typename... TArgs>
+ void registerResource(TArgs... args) +
+
Registers and inserts a new resource type.
+
+ void registerComponent(const reflection::Type& type) +
+
Registers a component type.
+
+
template<reflection::Reflectable T>
+ void registerComponent() +
+
Registers a component type.
+
+ void registerRelation(const reflection::Type& type) +
+
Registers a relation type.
+
+
template<reflection::Reflectable T>
+ void registerRelation() +
+
Registers a relation type.
+
+ auto types() -> Types& +
+
Returns the types registry of the world.
+
+ auto types() const -> const Types& +
+
Returns the types registry of the world.
+
+ auto tables() -> Tables& +
+
Returns the tables of the world.
+
+ auto tables() const -> const Tables& +
+
Returns the tables of the world.
+
+ auto archetypeGraph() -> ArchetypeGraph& +
+
Returns the archetype graph of the world.
+
+ auto archetypeGraph() const -> const ArchetypeGraph& +
+
Returns the archetype graph of the world.
+
+
template<typename T>
+ auto read() const -> ReadResource<T> +
+
Locks a resource for reading and returns it.
+
+
template<typename T>
+ auto write() const -> WriteResource<T> +
+
Locks a resource for writing and returns it.
+
+ auto create() -> Entity +
+
Creates a new entity.
+
+ void createAt(Entity entity) +
+
Creates a new entity with the given identifier.
+
+ auto reserve() -> Entity +
+
Reserves an entity identifier, without actually creating an entity.
+
+ void destroy(Entity entity) +
+
Destroys an entity.
+
+ auto generation(uint32_t index) const -> uint32_t +
+
Gets the generation of the entity with the given index.
+
+ auto archetype(Entity entity) const -> ArchetypeId +
+
Gets the archetype of the given entity.
+
+ auto isAlive(Entity entity) const -> bool +
+
Checks if an entity is still alive.
+
+ auto components(Entity entity) -> Components +
+
Creates a components view for the given entity.
+
+ auto components(Entity entity) const -> ConstComponents +
+
Creates a components view for the given entity.
+
+ auto relationsFrom(Entity entity) -> Relations +
+
Creates a view for relations coming from the given entity.
+
+ auto relationsFrom(Entity entity) const -> ConstRelations +
+
Creates a view for relations coming from the given entity.
+
+ auto relationsTo(Entity entity) -> Relations +
+
Creates a view for relations going into the given entity.
+
+ auto relationsTo(Entity entity) const -> ConstRelations +
+
Creates a view for relations going into the given entity.
+
+ void relate(Entity from, + Entity to, + const reflection::Type& type, + void* value) +
+
Inserts a relation between the two given entities.
+
+
template<reflection::Reflectable T>
+ void relate(Entity from, + Entity to, + T value) +
+
Inserts a relation between the two given entities.
+
+ void unrelate(Entity from, + Entity to, + const reflection::Type& type) +
+
Removes the relation, if there's any, between the two given entities.
+
+
template<reflection::Reflectable T>
+ void unrelate(Entity from, + Entity to) +
+
Removes the relation, if there's any, between the two given entities.
+
+ auto related(Entity from, + Entity to, + const reflection::Type& type) const -> bool +
+
Checks if there's a relation of the given type between the two given entities.
+
+
template<typename T>
+ auto related(Entity from, + Entity to) const -> bool +
+
Checks if there's a relation of the given type between the two given entities.
+
+ auto relation(Entity from, + Entity to, + const reflection::Type& type) -> void* +
+
Gets a pointer to the relation value between the two given entities.
+
+ auto relation(Entity from, + Entity to, + const reflection::Type& type) const -> const void* +
+
Gets a pointer to the relation value between the two given entities.
+
+
template<typename T>
+ auto relation(Entity from, + Entity to) -> T& +
+
Gets a reference to the relation value between the two given entities.
+
+
template<typename T>
+ auto relation(Entity from, + Entity to) const -> const T& +
+
Gets a reference to the relation value between the two given entities.
+
+ auto entityCount() const -> std::size_t +
+
Gets the number of alive entities.
+
+
+
+

Function documentation

+
+

+
+ template<typename T, typename... TArgs> +
+ void cubos::core::ecs::World::registerResource(TArgs... args) +

+

Registers and inserts a new resource type.

+ + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TResource type.
TArgsTypes of the arguments of the constructor of the resource.
Parameters
argsArguments of the constructor of the resource.
+ +
+
+

+ void cubos::core::ecs::World::registerComponent(const reflection::Type& type) +

+

Registers a component type.

+ + + + + + + + + + +
Parameters
typeComponent type.
+
+
+

+
+ template<reflection::Reflectable T> +
+ void cubos::core::ecs::World::registerComponent() +

+

Registers a component type.

+ + + + + + + + + + +
Template parameters
TComponent type.
+ +
+
+

+ void cubos::core::ecs::World::registerRelation(const reflection::Type& type) +

+

Registers a relation type.

+ + + + + + + + + + +
Parameters
typeRelation type.
+
+
+

+
+ template<reflection::Reflectable T> +
+ void cubos::core::ecs::World::registerRelation() +

+

Registers a relation type.

+ + + + + + + + + + +
Template parameters
TRelation type.
+
+
+

+ Types& cubos::core::ecs::World::types() +

+

Returns the types registry of the world.

+ + + + + + + +
ReturnsTypes registry.
+
+
+

+ const Types& cubos::core::ecs::World::types() const +

+

Returns the types registry of the world.

+ + + + + + + +
ReturnsTypes registry.
+
+
+

+ Tables& cubos::core::ecs::World::tables() +

+

Returns the tables of the world.

+ + + + + + + +
ReturnsTables.
+
+
+

+ const Tables& cubos::core::ecs::World::tables() const +

+

Returns the tables of the world.

+ + + + + + + +
ReturnsTables.
+
+
+

+ ArchetypeGraph& cubos::core::ecs::World::archetypeGraph() +

+

Returns the archetype graph of the world.

+ + + + + + + +
ReturnsArchetype graph.
+
+
+

+ const ArchetypeGraph& cubos::core::ecs::World::archetypeGraph() const +

+

Returns the archetype graph of the world.

+ + + + + + + +
ReturnsArchetype graph.
+
+
+

+
+ template<typename T> +
+ ReadResource<T> cubos::core::ecs::World::read() const +

+

Locks a resource for reading and returns it.

+ + + + + + + + + + + + + + + + +
Template parameters
TResource type.
ReturnsResource lock.
+
+
+

+
+ template<typename T> +
+ WriteResource<T> cubos::core::ecs::World::write() const +

+

Locks a resource for writing and returns it.

+ + + + + + + + + + + + + + + + +
Template parameters
TResource type.
ReturnsResource lock.
+
+
+

+ Entity cubos::core::ecs::World::create() +

+

Creates a new entity.

+ + + + + + + +
ReturnsEntity identifier.
+
+
+

+ void cubos::core::ecs::World::createAt(Entity entity) +

+

Creates a new entity with the given identifier.

+ + + + + + + + + + + + + + + + +
Parameters
entityEntity identifier.
ReturnsEntity.
+

Aborts if the entity already exists.

+
+
+

+ Entity cubos::core::ecs::World::reserve() +

+

Reserves an entity identifier, without actually creating an entity.

+ + + + + + + +
ReturnsEntity identifier.
+

The entity can be later created with a call to createAt().

+
+
+

+ void cubos::core::ecs::World::destroy(Entity entity) +

+

Destroys an entity.

+ + + + + + + + + + +
Parameters
entityEntity identifier.
+

If an entity has already been destroyed, this function does nothing.

+
+
+

+ uint32_t cubos::core::ecs::World::generation(uint32_t index) const +

+

Gets the generation of the entity with the given index.

+ + + + + + + + + + + + + + + + +
Parameters
indexEntity index.
ReturnsEntity generation.
+
+
+

+ ArchetypeId cubos::core::ecs::World::archetype(Entity entity) const +

+

Gets the archetype of the given entity.

+ + + + + + + + + + + + + + + + +
Parameters
entityEntity.
ReturnsArchetype identifier.
+
+
+

+ bool cubos::core::ecs::World::isAlive(Entity entity) const +

+

Checks if an entity is still alive.

+ + + + + + + + + + + + + + + + +
Parameters
entityEntity.
ReturnsWhether the entity is alive.
+
+
+

+ Components cubos::core::ecs::World::components(Entity entity) +

+

Creates a components view for the given entity.

+ + + + + + + + + + + + + + + + +
Parameters
entityEntity.
ReturnsComponents view.
+

The given entity must be alive.

+
+
+

+ ConstComponents cubos::core::ecs::World::components(Entity entity) const +

+

Creates a components view for the given entity.

+ + + + + + + + + + + + + + + + +
Parameters
entityEntity.
ReturnsComponents view.
+

The given entity must be alive.

+
+
+

+ Relations cubos::core::ecs::World::relationsFrom(Entity entity) +

+

Creates a view for relations coming from the given entity.

+ + + + + + + + + + + + + + + + +
Parameters
entityFrom entity.
ReturnsRelations view.
+

The given entity must be alive.

+
+
+

+ ConstRelations cubos::core::ecs::World::relationsFrom(Entity entity) const +

+

Creates a view for relations coming from the given entity.

+ + + + + + + + + + + + + + + + +
Parameters
entityFrom entity.
ReturnsRelations view.
+

The given entity must be alive.

+
+
+

+ Relations cubos::core::ecs::World::relationsTo(Entity entity) +

+

Creates a view for relations going into the given entity.

+ + + + + + + + + + + + + + + + +
Parameters
entityTo entity.
ReturnsRelations view.
+

The given entity must be alive.

+
+
+

+ ConstRelations cubos::core::ecs::World::relationsTo(Entity entity) const +

+

Creates a view for relations going into the given entity.

+ + + + + + + + + + + + + + + + +
Parameters
entityTo entity.
ReturnsRelations view.
+

The given entity must be alive.

+
+
+

+ void cubos::core::ecs::World::relate(Entity from, + Entity to, + const reflection::Type& type, + void* value) +

+

Inserts a relation between the two given entities.

+ + + + + + + + + + + + + + + + + + + + + + +
Parameters
fromFrom entity.
toTo entity.
typeRelation type.
valueRelation value to move.
+

If the relation already exists, it is overwritten.

+
+
+

+
+ template<reflection::Reflectable T> +
+ void cubos::core::ecs::World::relate(Entity from, + Entity to, + T value) +

+

Inserts a relation between the two given entities.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TRelation type.
Parameters
fromFrom entity.
toTo entity.
valueRelation value.
+

If the relation already exists, it is overwritten.

+
+
+

+ void cubos::core::ecs::World::unrelate(Entity from, + Entity to, + const reflection::Type& type) +

+

Removes the relation, if there's any, between the two given entities.

+ + + + + + + + + + + + + + + + + + +
Parameters
fromFrom entity.
toTo entity.
typeRelation type.
+
+
+

+
+ template<reflection::Reflectable T> +
+ void cubos::core::ecs::World::unrelate(Entity from, + Entity to) +

+

Removes the relation, if there's any, between the two given entities.

+ + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TRelation type.
Parameters
fromFrom entity.
toTo entity.
+
+
+

+ bool cubos::core::ecs::World::related(Entity from, + Entity to, + const reflection::Type& type) const +

+

Checks if there's a relation of the given type between the two given entities.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
fromFrom entity.
toTo entity.
typeRelation type.
ReturnsWhether the relation exists.
+
+
+

+
+ template<typename T> +
+ bool cubos::core::ecs::World::related(Entity from, + Entity to) const +

+

Checks if there's a relation of the given type between the two given entities.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TRelation type.
Parameters
fromFrom entity.
toTo entity.
ReturnsWhether the relation exists.
+
+
+

+ void* cubos::core::ecs::World::relation(Entity from, + Entity to, + const reflection::Type& type) +

+

Gets a pointer to the relation value between the two given entities.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
fromFrom entity.
toTo entity.
typeRelation type.
ReturnsPointer to relation value.
+

The relation must exist.

+
+
+

+ const void* cubos::core::ecs::World::relation(Entity from, + Entity to, + const reflection::Type& type) const +

+

Gets a pointer to the relation value between the two given entities.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
fromFrom entity.
toTo entity.
typeRelation type.
ReturnsPointer to relation value.
+

The relation must exist.

+
+
+

+
+ template<typename T> +
+ T& cubos::core::ecs::World::relation(Entity from, + Entity to) +

+

Gets a reference to the relation value between the two given entities.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TRelation type.
Parameters
fromFrom entity.
toTo entity.
ReturnsReference to relation value.
+

The relation must exist.

+
+
+

+
+ template<typename T> +
+ const T& cubos::core::ecs::World::relation(Entity from, + Entity to) const +

+

Gets a reference to the relation value between the two given entities.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TRelation type.
Parameters
fromFrom entity.
toTo entity.
ReturnsReference to relation value.
+

The relation must exist.

+
+
+

+ std::size_t cubos::core::ecs::World::entityCount() const +

+

Gets the number of alive entities.

+ + + + + + + +
ReturnsNumber of alive entities.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1WriteResource.html b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1WriteResource.html new file mode 100644 index 000000000..07cf9248c --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1ecs_1_1WriteResource.html @@ -0,0 +1,185 @@ + + + + + cubos::core::ecs::WriteResource class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::ecs::WriteResource class +

+

Utility struct used to reference a resource of type T for writing.

+ + + + + + + + + + +
Template parameters
TResource type.
+ +
+

Constructors, destructors, conversion operators

+
+
+ WriteResource(WriteResource&& other) noexcept +
+
Move construct.
+
+
+
+

Public functions

+
+
+ auto get() const -> T& +
+
Gets the underlying resource reference.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ cubos::core::ecs::WriteResource<T>::WriteResource(WriteResource&& other) noexcept +

+

Move construct.

+ + + + + + + + + + +
Parameters
otherOther resource to move from.
+
+
+

+
+ template<typename T> +
+ T& cubos::core::ecs::WriteResource<T>::get() const +

+

Gets the underlying resource reference.

+ + + + + + + +
ReturnsResource reference.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1Debug.html b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1Debug.html new file mode 100644 index 000000000..f43b8ca65 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1Debug.html @@ -0,0 +1,375 @@ + + + + + cubos::core::gl::Debug class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::Debug class + +

+

Singleton with static methods used to draw primitive objects on screen for debugging purposes.

+ +
+

Public static functions

+
+
+ static void init(RenderDevice& renderDevice) +
+
Initializes the debug rendering system.
+
+ static void drawLine(glm::vec3 start, + glm::vec3 end, + bool relative = false, + glm::vec3 color = glm::vec3(1), + float time = 0.0F) +
+
Draws a line that will stay visible for a specified amount of time.
+
+ static void drawBox(geom::Box box, + glm::mat4 transform, + glm::vec3 color = glm::vec3(1), + float time = 0) +
+
Draws a filled box that will stay visible for a specified amount of time.
+
+ static void drawWireBox(geom::Box box, + glm::mat4 transform, + glm::vec3 color = glm::vec3(1), + float time = 0) +
+
Draws a wireframe box that will stay visible for a specified amount of time.
+
+ static void drawSphere(glm::vec3 center, + float radius, + float time, + glm::vec3 color = glm::vec3(1)) +
+
Draws a filled sphere that will stay visible for a specified amount of time.
+
+ static void drawWireSphere(glm::vec3 center, + float radius, + float time, + glm::vec3 color = glm::vec3(1)) +
+
Draws a wireframe sphere that will stay visible for a specified amount of time.
+
+ static void flush(glm::mat4 vp, + double deltaT) +
+
Renders all objects in the debug renderer's buffer and removes all objects that have exhausted their requested time.
+
+ static void terminate() +
+
Cleans up the debug rendering system's resources.
+
+
+
+

Function documentation

+
+

+ static void cubos::core::gl::Debug::init(RenderDevice& renderDevice) +

+

Initializes the debug rendering system.

+ + + + + + + + + + +
Parameters
renderDeviceRender device to use.
+
+
+

+ static void cubos::core::gl::Debug::drawLine(glm::vec3 start, + glm::vec3 end, + bool relative = false, + glm::vec3 color = glm::vec3(1), + float time = 0.0F) +

+

Draws a line that will stay visible for a specified amount of time.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
startStarting point of the line.
endEnding point of the line.
relativeWhether the ending point is relative to the starting point.
colorColor of the drawn line.
timeHow long will it be visible for? If 0, for a single frame.
+
+
+

+ static void cubos::core::gl::Debug::drawBox(geom::Box box, + glm::mat4 transform, + glm::vec3 color = glm::vec3(1), + float time = 0) +

+

Draws a filled box that will stay visible for a specified amount of time.

+ + + + + + + + + + + + + + + + + + + + + + +
Parameters
boxBox to draw.
transformTransformation matrix to apply to the box.
colorColor of the drawn cube.
timeHow long will it be visible for? If 0, for a single frame.
+
+
+

+ static void cubos::core::gl::Debug::drawWireBox(geom::Box box, + glm::mat4 transform, + glm::vec3 color = glm::vec3(1), + float time = 0) +

+

Draws a wireframe box that will stay visible for a specified amount of time.

+ + + + + + + + + + + + + + + + + + + + + + +
Parameters
boxBox to draw.
transformTransformation matrix to apply to the box.
colorColor of the drawn cube.
timeHow long will it be visible for? If 0, for a single frame.
+
+
+

+ static void cubos::core::gl::Debug::drawSphere(glm::vec3 center, + float radius, + float time, + glm::vec3 color = glm::vec3(1)) +

+

Draws a filled sphere that will stay visible for a specified amount of time.

+ + + + + + + + + + + + + + + + + + + + + + +
Parameters
centerPosition of the sphere's center in world space.
radiusRadius of the sphere.
timeHow long will it be visible for? If 0, for a single frame.
colorColor of the drawn sphere.
+
+
+

+ static void cubos::core::gl::Debug::drawWireSphere(glm::vec3 center, + float radius, + float time, + glm::vec3 color = glm::vec3(1)) +

+

Draws a wireframe sphere that will stay visible for a specified amount of time.

+ + + + + + + + + + + + + + + + + + + + + + +
Parameters
centerPosition of the sphere's center in world space.
radiusRadius of the sphere.
timeHow long will it be visible for? If 0, for a single frame.
colorColor of the drawn sphere.
+
+
+

+ static void cubos::core::gl::Debug::flush(glm::mat4 vp, + double deltaT) +

+

Renders all objects in the debug renderer's buffer and removes all objects that have exhausted their requested time.

+ + + + + + + + + + + + + + +
Parameters
vpView-Projection matrix that the objects should be drawn with.
deltaTTime that has passed since the last call to flush.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1RenderDevice.html b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1RenderDevice.html new file mode 100644 index 000000000..ffdf6f8e1 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1RenderDevice.html @@ -0,0 +1,1288 @@ + + + + + cubos::core::gl::RenderDevice class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::RenderDevice class + +

+

Interface used to wrap low-level rendering APIs such as OpenGL.

+ +

Using this interface, the engine never directly interacts with OpenGL or any other low-level rendering API. This allows use to use different rendering APIs without having to change the engine code, which is useful for porting the engine to different platforms.

+
+

Constructors, destructors, conversion operators

+
+
+ RenderDevice(const RenderDevice&) deleted +
+
Forbid copy construction.
+
+
+
+

Public functions

+
+
+ auto createFramebuffer(const FramebufferDesc& desc) -> Framebuffer pure virtual +
+
Creates a new framebuffer.
+
+ void setFramebuffer(Framebuffer fb) pure virtual +
+
Sets the current framebuffer.
+
+ auto createRasterState(const RasterStateDesc& desc) -> RasterState pure virtual +
+
Creates a new rasterizer state.
+
+ void setRasterState(RasterState rs) pure virtual +
+
Sets the current rasterizer state.
+
+ auto createDepthStencilState(const DepthStencilStateDesc& desc) -> DepthStencilState pure virtual +
+
Creates a new depth stencil state.
+
+ void setDepthStencilState(DepthStencilState dss) pure virtual +
+
Sets the current depth stencil state.
+
+ auto createBlendState(const BlendStateDesc& desc) -> BlendState pure virtual +
+
Creates a new blend state.
+
+ void setBlendState(BlendState bs) pure virtual +
+
Sets the current blend state.
+
+ auto createSampler(const SamplerDesc& desc) -> Sampler pure virtual +
+
Creates a new texture sampler.
+
+ auto createTexture1D(const Texture1DDesc& desc) -> Texture1D pure virtual +
+
Creates a new 1D texture.
+
+ auto createTexture2D(const Texture2DDesc& desc) -> Texture2D pure virtual +
+
Creates a new 2D texture.
+
+ auto createTexture2DArray(const Texture2DArrayDesc& desc) -> Texture2DArray pure virtual +
+
Creates a new 2D texture array.
+
+ auto createTexture3D(const Texture3DDesc& desc) -> Texture3D pure virtual +
+
Creates a new 3D texture.
+
+ auto createCubeMap(const CubeMapDesc& desc) -> CubeMap pure virtual +
+
Creates a new cube map.
+
+ auto createCubeMapArray(const CubeMapArrayDesc& desc) -> CubeMapArray pure virtual +
+
Creates a new cube map array.
+
+ auto createConstantBuffer(std::size_t size, + const void* data, + Usage usage) -> ConstantBuffer pure virtual +
+
Creates a new constant buffer.
+
+ auto createIndexBuffer(std::size_t size, + const void* data, + IndexFormat format, + Usage usage) -> IndexBuffer pure virtual +
+
Creates a new index buffer.
+
+ void setIndexBuffer(IndexBuffer ib) pure virtual +
+
Sets the current index buffer.
+
+ auto createVertexBuffer(std::size_t size, + const void* data, + Usage usage) -> VertexBuffer pure virtual +
+
Creates a new vertex buffer.
+
+ auto createVertexArray(const VertexArrayDesc& desc) -> VertexArray pure virtual +
+
Creates a new vertex array.
+
+ void setVertexArray(VertexArray va) pure virtual +
+
Sets the current vertex array.
+
+ auto createShaderStage(Stage stage, + const char* src) -> ShaderStage pure virtual +
+
Creates a new shader stage from GLSL source code.
+
+ auto createShaderPipeline(ShaderStage vs, + ShaderStage ps) -> ShaderPipeline pure virtual +
+
Creates a new shader pipeline from vertex and pixel shaders.
+
+ auto createShaderPipeline(ShaderStage vs, + ShaderStage gs, + ShaderStage ps) -> ShaderPipeline pure virtual +
+
Creates a new shader pipeline from vertex, pixel and geometry shaders.
+
+ auto createShaderPipeline(ShaderStage cs) -> ShaderPipeline pure virtual +
+
Creates a new shader pipeline from a compute shader. Unsupported on some platforms.
+
+ void setShaderPipeline(ShaderPipeline pipeline) pure virtual +
+
Sets the current shader pipeline used for rendering.
+
+ void clearColor(float r, + float g, + float b, + float a) pure virtual +
+
Clears the color buffer bit on the current framebuffer to a specific color.
+
+ void clearTargetColor(std::size_t target, + float r, + float g, + float b, + float a) pure virtual +
+
Clears the color buffer of a specific target on the current framebuffer to a specific color.
+
+ void clearDepth(float depth) pure virtual +
+
Clears the depth buffer bit on the current framebuffer to a specific value.
+
+ void clearStencil(int stencil) pure virtual +
+
Clears the stencil buffer bit on the current framebuffer to a specific value.
+
+ void drawLines(std::size_t offset, + std::size_t count) pure virtual +
+
Draws lines.
+
+ void drawTriangles(std::size_t offset, + std::size_t count) pure virtual +
+
Draws tringles.
+
+ void drawTrianglesIndexed(std::size_t offset, + std::size_t count) pure virtual +
+
Draws tringles with an index buffer.
+
+ void drawTrianglesInstanced(std::size_t offset, + std::size_t count, + std::size_t instanceCount) pure virtual +
+
Draws tringles multiple times.
+
+ void drawTrianglesIndexedInstanced(std::size_t offset, + std::size_t count, + std::size_t instanceCount) pure virtual +
+
Draws tringles multiple times with an index buffer.
+
+ void dispatchCompute(std::size_t x, + std::size_t y, + std::size_t z) pure virtual +
+
Dispatches a compute pipeline.
+
+ void memoryBarrier(MemoryBarriers barriers) pure virtual +
+
Defines a barrier ordering memory transactions. Unsupported on some platforms.
+
+ void setViewport(int x, + int y, + int w, + int h) pure virtual +
+
Sets the current viewport.
+
+ void setScissor(int x, + int y, + int w, + int h) pure virtual +
+
Sets the current scissor rectangle.
+
+ auto getProperty(Property prop) -> int pure virtual +
+
Gets a runtime property of the render device.
+
+
+
+

Function documentation

+
+

+ Framebuffer cubos::core::gl::RenderDevice::createFramebuffer(const FramebufferDesc& desc) pure virtual +

+

Creates a new framebuffer.

+ + + + + + + + + + + + + + + + +
Parameters
descFramebuffer description.
ReturnsFramebuffer handle, or nullptr on failure.
+
+
+

+ void cubos::core::gl::RenderDevice::setFramebuffer(Framebuffer fb) pure virtual +

+

Sets the current framebuffer.

+ + + + + + + + + + +
Parameters
fbFramebuffer handle.
+
+
+

+ RasterState cubos::core::gl::RenderDevice::createRasterState(const RasterStateDesc& desc) pure virtual +

+

Creates a new rasterizer state.

+ + + + + + + + + + + + + + + + +
Parameters
descRasterizer state description.
ReturnsRasterizer state handle, or nullptr on failure.
+
+
+

+ void cubos::core::gl::RenderDevice::setRasterState(RasterState rs) pure virtual +

+

Sets the current rasterizer state.

+ + + + + + + + + + +
Parameters
rsRasterizer state handle.
+
+
+

+ DepthStencilState cubos::core::gl::RenderDevice::createDepthStencilState(const DepthStencilStateDesc& desc) pure virtual +

+

Creates a new depth stencil state.

+ + + + + + + + + + + + + + + + +
Parameters
descDepth stencil state description.
ReturnsDepth stencil state handle, or nullptr on failure.
+
+
+

+ void cubos::core::gl::RenderDevice::setDepthStencilState(DepthStencilState dss) pure virtual +

+

Sets the current depth stencil state.

+ + + + + + + + + + +
Parameters
dssDepth stencil state handle.
+
+
+

+ BlendState cubos::core::gl::RenderDevice::createBlendState(const BlendStateDesc& desc) pure virtual +

+

Creates a new blend state.

+ + + + + + + + + + + + + + + + +
Parameters
descBlend state description.
ReturnsBlend state handle, or nullptr on failure.
+
+
+

+ void cubos::core::gl::RenderDevice::setBlendState(BlendState bs) pure virtual +

+

Sets the current blend state.

+ + + + + + + + + + +
Parameters
bsBlend state handle.
+
+
+

+ Sampler cubos::core::gl::RenderDevice::createSampler(const SamplerDesc& desc) pure virtual +

+

Creates a new texture sampler.

+ + + + + + + + + + + + + + + + +
Parameters
descSampler description.
ReturnsSampler handle, or nullptr on failure.
+
+
+

+ Texture1D cubos::core::gl::RenderDevice::createTexture1D(const Texture1DDesc& desc) pure virtual +

+

Creates a new 1D texture.

+ + + + + + + + + + + + + + + + +
Parameters
desc1D texture description.
ReturnsTexture handle, or nullptr on failure.
+
+
+

+ Texture2D cubos::core::gl::RenderDevice::createTexture2D(const Texture2DDesc& desc) pure virtual +

+

Creates a new 2D texture.

+ + + + + + + + + + + + + + + + +
Parameters
desc2D texture description.
ReturnsTexture handle, or nullptr on failure.
+
+
+

+ Texture2DArray cubos::core::gl::RenderDevice::createTexture2DArray(const Texture2DArrayDesc& desc) pure virtual +

+

Creates a new 2D texture array.

+ + + + + + + + + + + + + + + + +
Parameters
desc2D texture array description.
ReturnsTexture array handle, or nullptr on failure.
+
+
+

+ Texture3D cubos::core::gl::RenderDevice::createTexture3D(const Texture3DDesc& desc) pure virtual +

+

Creates a new 3D texture.

+ + + + + + + + + + + + + + + + +
Parameters
desc3D texture description.
ReturnsTexture handle, or nullptr on failure.
+
+
+

+ CubeMap cubos::core::gl::RenderDevice::createCubeMap(const CubeMapDesc& desc) pure virtual +

+

Creates a new cube map.

+ + + + + + + + + + + + + + + + +
Parameters
descCube map description.
ReturnsCube map handle, or nullptr on failure.
+
+
+

+ CubeMapArray cubos::core::gl::RenderDevice::createCubeMapArray(const CubeMapArrayDesc& desc) pure virtual +

+

Creates a new cube map array.

+ + + + + + + + + + + + + + + + +
Parameters
descCube map array description.
ReturnsCube map array handle, or nullptr on failure.
+
+
+

+ ConstantBuffer cubos::core::gl::RenderDevice::createConstantBuffer(std::size_t size, + const void* data, + Usage usage) pure virtual +

+

Creates a new constant buffer.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
sizeSize in bytes.
dataInitial data, can be nullptr.
usageUsage which the buffer will have.
ReturnsConstant buffer handle, or nullptr on failure.
+
+
+

+ IndexBuffer cubos::core::gl::RenderDevice::createIndexBuffer(std::size_t size, + const void* data, + IndexFormat format, + Usage usage) pure virtual +

+

Creates a new index buffer.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
sizeSize in bytes.
dataInitial data, can be nullptr.
formatIndex format.
usageUsage which the buffer will have.
ReturnsIndex buffer handle, or nullptr on failure.
+
+
+

+ void cubos::core::gl::RenderDevice::setIndexBuffer(IndexBuffer ib) pure virtual +

+

Sets the current index buffer.

+ + + + + + + + + + +
Parameters
ibIndex buffer handle.
+
+
+

+ VertexBuffer cubos::core::gl::RenderDevice::createVertexBuffer(std::size_t size, + const void* data, + Usage usage) pure virtual +

+

Creates a new vertex buffer.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
sizeSize in bytes.
dataInitial data, can be nullptr.
usageUsage which the buffer will have.
ReturnsVertex buffer handle, or nullptr on failure.
+
+
+

+ VertexArray cubos::core::gl::RenderDevice::createVertexArray(const VertexArrayDesc& desc) pure virtual +

+

Creates a new vertex array.

+ + + + + + + + + + + + + + + + +
Parameters
descVertex array description.
ReturnsVertex array handle, or nullptr on failure.
+
+
+

+ void cubos::core::gl::RenderDevice::setVertexArray(VertexArray va) pure virtual +

+

Sets the current vertex array.

+ + + + + + + + + + +
Parameters
vaVertex array handle.
+
+
+

+ ShaderStage cubos::core::gl::RenderDevice::createShaderStage(Stage stage, + const char* src) pure virtual +

+

Creates a new shader stage from GLSL source code.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
stageShader stage.
srcGLSL source code.
ReturnsShader stage handle, or nullptr on failure.
+ +
+
+

+ ShaderPipeline cubos::core::gl::RenderDevice::createShaderPipeline(ShaderStage vs, + ShaderStage ps) pure virtual +

+

Creates a new shader pipeline from vertex and pixel shaders.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
vsVertex shader stage.
psPixel shader stage.
ReturnsShader pipeline handle, or nullptr on failure.
+
+
+

+ ShaderPipeline cubos::core::gl::RenderDevice::createShaderPipeline(ShaderStage vs, + ShaderStage gs, + ShaderStage ps) pure virtual +

+

Creates a new shader pipeline from vertex, pixel and geometry shaders.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
vsVertex shader stage.
gsGeometry shader stage.
psPixel shader stage.
ReturnsShader pipeline handle, or nullptr on failure.
+
+
+

+ ShaderPipeline cubos::core::gl::RenderDevice::createShaderPipeline(ShaderStage cs) pure virtual +

+

Creates a new shader pipeline from a compute shader. Unsupported on some platforms.

+ + + + + + + + + + + + + + + + +
Parameters
csCompute shader stage.
ReturnsShader pipeline handle, or nullptr on failure.
+ +
+
+

+ void cubos::core::gl::RenderDevice::setShaderPipeline(ShaderPipeline pipeline) pure virtual +

+

Sets the current shader pipeline used for rendering.

+ + + + + + + + + + +
Parameters
pipelineShader pipeline handle.
+
+
+

+ void cubos::core::gl::RenderDevice::clearColor(float r, + float g, + float b, + float a) pure virtual +

+

Clears the color buffer bit on the current framebuffer to a specific color.

+ + + + + + + + + + + + + + + + + + + + + + +
Parameters
rRed component.
gGreen component.
bBlue component.
aAlpha component.
+
+
+

+ void cubos::core::gl::RenderDevice::clearTargetColor(std::size_t target, + float r, + float g, + float b, + float a) pure virtual +

+

Clears the color buffer of a specific target on the current framebuffer to a specific color.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
targetTarget index.
rRed component.
gGreen component.
bBlue component.
aAlpha component.
+
+
+

+ void cubos::core::gl::RenderDevice::clearDepth(float depth) pure virtual +

+

Clears the depth buffer bit on the current framebuffer to a specific value.

+ + + + + + + + + + +
Parameters
depthDepth value.
+
+
+

+ void cubos::core::gl::RenderDevice::clearStencil(int stencil) pure virtual +

+

Clears the stencil buffer bit on the current framebuffer to a specific value.

+ + + + + + + + + + +
Parameters
stencilStencil value.
+
+
+

+ void cubos::core::gl::RenderDevice::drawLines(std::size_t offset, + std::size_t count) pure virtual +

+

Draws lines.

+ + + + + + + + + + + + + + +
Parameters
offsetIndex of the first vertex to be drawn.
countNumber of vertices that will be drawn.
+
+
+

+ void cubos::core::gl::RenderDevice::drawTriangles(std::size_t offset, + std::size_t count) pure virtual +

+

Draws tringles.

+ + + + + + + + + + + + + + +
Parameters
offsetIndex of the first vertex to be drawn.
countNumber of vertices that will be drawn.
+
+
+

+ void cubos::core::gl::RenderDevice::drawTrianglesIndexed(std::size_t offset, + std::size_t count) pure virtual +

+

Draws tringles with an index buffer.

+ + + + + + + + + + + + + + +
Parameters
offsetIndex of the first indice to be drawn.
countNumber of indices that will be drawn.
+
+
+

+ void cubos::core::gl::RenderDevice::drawTrianglesInstanced(std::size_t offset, + std::size_t count, + std::size_t instanceCount) pure virtual +

+

Draws tringles multiple times.

+ + + + + + + + + + + + + + + + + + +
Parameters
offsetIndex of the first vertex to be drawn.
countNumber of vertices that will be drawn.
instanceCountNumber of instances drawn.
+
+
+

+ void cubos::core::gl::RenderDevice::drawTrianglesIndexedInstanced(std::size_t offset, + std::size_t count, + std::size_t instanceCount) pure virtual +

+

Draws tringles multiple times with an index buffer.

+ + + + + + + + + + + + + + + + + + +
Parameters
offsetIndex of the first indice to be drawn.
countNumber of indices that will be drawn.
instanceCountNumber of instances drawn.
+
+
+

+ void cubos::core::gl::RenderDevice::dispatchCompute(std::size_t x, + std::size_t y, + std::size_t z) pure virtual +

+

Dispatches a compute pipeline.

+ + + + + + + + + + + + + + + + + + +
Parameters
xX dimension of the work group.
yY dimension of the work group.
zZ dimension of the work group.
+
+
+

+ void cubos::core::gl::RenderDevice::memoryBarrier(MemoryBarriers barriers) pure virtual +

+

Defines a barrier ordering memory transactions. Unsupported on some platforms.

+ + + + + + + + + + +
Parameters
barriersBarriers to apply.
+

This ensure that all memory transactions before the barrier are completed before the barrier is executed.

+
+
+

+ void cubos::core::gl::RenderDevice::setViewport(int x, + int y, + int w, + int h) pure virtual +

+

Sets the current viewport.

+ + + + + + + + + + + + + + + + + + + + + + +
Parameters
xBottom left viewport corner X coordinate.
yBottom left viewport corner Y coordinate.
wViewport width.
hViewport height.
+
+
+

+ void cubos::core::gl::RenderDevice::setScissor(int x, + int y, + int w, + int h) pure virtual +

+

Sets the current scissor rectangle.

+ + + + + + + + + + + + + + + + + + + + + + +
Parameters
xBottom left scissor rectangle corner X coordinate.
yBottom left scissor rectangle corner Y coordinate.
wScissor rectangle width.
hScissor rectangle height.
+
+
+

+ int cubos::core::gl::RenderDevice::getProperty(Property prop) pure virtual +

+

Gets a runtime property of the render device.

+ + + + + + + + + + +
Parameters
propProperty name.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1BlendState.html b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1BlendState.html new file mode 100644 index 000000000..b05a2fbe1 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1BlendState.html @@ -0,0 +1,103 @@ + + + + + cubos::core::gl::impl::BlendState class | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1ConstantBuffer.html b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1ConstantBuffer.html new file mode 100644 index 000000000..033fd45cf --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1ConstantBuffer.html @@ -0,0 +1,144 @@ + + + + + cubos::core::gl::impl::ConstantBuffer class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::impl::ConstantBuffer class + +

+

Abstract constant buffer.

+ +
+

Public functions

+
+
+ auto map() -> void* pure virtual +
+
Maps the constant buffer to a region in memory. Must be matched with a call to unmap().
+
+ void unmap() pure virtual +
+
Unmaps the constant buffer, updating it with data written to the mapped region.
+
+
+
+

Function documentation

+
+

+ void* cubos::core::gl::impl::ConstantBuffer::map() pure virtual +

+

Maps the constant buffer to a region in memory. Must be matched with a call to unmap().

+ + + + + + + +
ReturnsPointer to the memory region.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1CubeMap.html b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1CubeMap.html new file mode 100644 index 000000000..d0a6ddc2e --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1CubeMap.html @@ -0,0 +1,183 @@ + + + + + cubos::core::gl::impl::CubeMap class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::impl::CubeMap class + +

+

Abstract cube map.

+ +
+

Public functions

+
+
+ void update(std::size_t x, + std::size_t y, + std::size_t width, + std::size_t height, + const void* data, + CubeFace face, + std::size_t level = 0) pure virtual +
+
Updates a cube map's face with new data, which must have the same format used when the cube map was created.
+
+ void generateMipmaps() pure virtual +
+
Generates mipmaps on this cube map.
+
+
+
+

Function documentation

+
+

+ void cubos::core::gl::impl::CubeMap::update(std::size_t x, + std::size_t y, + std::size_t width, + std::size_t height, + const void* data, + CubeFace face, + std::size_t level = 0) pure virtual +

+

Updates a cube map's face with new data, which must have the same format used when the cube map was created.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
xDestination X coordinate.
yDestination Y coordinate.
widthWidth of the section which will be updated.
heightHeight of the section which will be updated.
dataPointer to the new data.
faceFace to update.
levelMip level to update.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1CubeMapArray.html b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1CubeMapArray.html new file mode 100644 index 000000000..d946408ad --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1CubeMapArray.html @@ -0,0 +1,189 @@ + + + + + cubos::core::gl::impl::CubeMapArray class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::impl::CubeMapArray class + +

+

Abstract cube map.

+ +
+

Public functions

+
+
+ void update(std::size_t x, + std::size_t y, + std::size_t i, + std::size_t width, + std::size_t height, + const void* data, + CubeFace face, + std::size_t level = 0) pure virtual +
+
Updates a cube map's face with new data, which must have the same format used when the cube map was created.
+
+ void generateMipmaps() pure virtual +
+
Generates mipmaps on this cube map.
+
+
+
+

Function documentation

+
+

+ void cubos::core::gl::impl::CubeMapArray::update(std::size_t x, + std::size_t y, + std::size_t i, + std::size_t width, + std::size_t height, + const void* data, + CubeFace face, + std::size_t level = 0) pure virtual +

+

Updates a cube map's face with new data, which must have the same format used when the cube map was created.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
xDestination X coordinate.
yDestination Y coordinate.
iIndex of the destination texture within the array.
widthWidth of the section which will be updated.
heightHeight of the section which will be updated.
dataPointer to the new data.
faceFace to update.
levelMip level to update.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1DepthStencilState.html b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1DepthStencilState.html new file mode 100644 index 000000000..40fc5cb01 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1DepthStencilState.html @@ -0,0 +1,103 @@ + + + + + cubos::core::gl::impl::DepthStencilState class | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Framebuffer.html b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Framebuffer.html new file mode 100644 index 000000000..d65da9093 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Framebuffer.html @@ -0,0 +1,103 @@ + + + + + cubos::core::gl::impl::Framebuffer class | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1IndexBuffer.html b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1IndexBuffer.html new file mode 100644 index 000000000..e67b83d72 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1IndexBuffer.html @@ -0,0 +1,144 @@ + + + + + cubos::core::gl::impl::IndexBuffer class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::impl::IndexBuffer class + +

+

Abstract index buffer.

+ +
+

Public functions

+
+
+ auto map() -> void* pure virtual +
+
Maps the index buffer to a region in memory. Must be matched with a call to unmap().
+
+ void unmap() pure virtual +
+
Unmaps the index buffer, updating it with data written to the mapped region.
+
+
+
+

Function documentation

+
+

+ void* cubos::core::gl::impl::IndexBuffer::map() pure virtual +

+

Maps the index buffer to a region in memory. Must be matched with a call to unmap().

+ + + + + + + +
ReturnsPointer to the memory region.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1RasterState.html b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1RasterState.html new file mode 100644 index 000000000..b2936bf8f --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1RasterState.html @@ -0,0 +1,103 @@ + + + + + cubos::core::gl::impl::RasterState class | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Sampler.html b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Sampler.html new file mode 100644 index 000000000..c046eda88 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Sampler.html @@ -0,0 +1,103 @@ + + + + + cubos::core::gl::impl::Sampler class | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderBindingPoint.html b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderBindingPoint.html new file mode 100644 index 000000000..1e5e9ce3e --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderBindingPoint.html @@ -0,0 +1,624 @@ + + + + + cubos::core::gl::impl::ShaderBindingPoint class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::impl::ShaderBindingPoint class + +

+

Abstract shader binding point.

+ +
+

Public functions

+
+
+ void bind(gl::Sampler sampler) pure virtual +
+
Binds a sampler to the binding point.
+
+ void bind(gl::Texture1D tex) pure virtual +
+
Binds a 1D texture to the binding point.
+
+ void bind(gl::Texture2D tex) pure virtual +
+
Binds a 2D texture to the binding point.
+
+ void bind(gl::Texture2DArray tex) pure virtual +
+
Binds a 2D texture array to the binding point.
+
+ void bind(gl::Texture3D tex) pure virtual +
+
Binds a 3D texture to the binding point.
+
+ void bind(gl::CubeMap cubeMap) pure virtual +
+
Binds a cube map to the binding point.
+
+ void bind(gl::CubeMapArray cubeMap) pure virtual +
+
Binds a cube map array to the binding point.
+
+ void bind(gl::ConstantBuffer cb) pure virtual +
+
Binds a constant buffer to the binding point.
+
+ void bind(gl::Texture2D tex, + int level, + Access access) pure virtual +
+
Binds a level of a 2D texture to an image unit.
+
+ void setConstant(glm::vec2 val) pure virtual +
+
Sets the value of the uniform tied to the binding point to the provided vec2 value.
+
+ void setConstant(glm::vec3 val) pure virtual +
+
Sets the value of the uniform tied to the binding point to the provided vec3 value.
+
+ void setConstant(glm::vec4 val) pure virtual +
+
Sets the value of the uniform tied to the binding point to the provided vec4 value.
+
+ void setConstant(glm::ivec2 val) pure virtual +
+
Sets the value of the uniform tied to the binding point to the provided integer vec2 value.
+
+ void setConstant(glm::ivec3 val) pure virtual +
+
Sets the value of the uniform tied to the binding point to the provided integer vec3 value.
+
+ void setConstant(glm::ivec4 val) pure virtual +
+
Sets the value of the uniform tied to the binding point to the provided integer vec4 value.
+
+ void setConstant(glm::uvec2 val) pure virtual +
+
Sets the value of the uniform tied to the binding point to the provided unsigned integer vec2 value.
+
+ void setConstant(glm::uvec3 val) pure virtual +
+
Sets the value of the uniform tied to the binding point to the provided unsigned integer vec3 value.
+
+ void setConstant(glm::uvec4 val) pure virtual +
+
Sets the value of the uniform tied to the binding point to the provided unsigned integer vec4 value.
+
+ void setConstant(glm::mat4 val) pure virtual +
+
Sets the value of the uniform tied to the binding point to the provided mat4 value.
+
+ void setConstant(float val) pure virtual +
+
Sets the value of the uniform tied to the binding point to the provided float value.
+
+ void setConstant(int val) pure virtual +
+
Sets the value of the uniform tied to the binding point to the provided int value.
+
+ void setConstant(unsigned int val) pure virtual +
+
Sets the value of the uniform tied to the binding point to the provided unsigned int value.
+
+ auto queryConstantBufferStructure(ConstantBufferStructure* structure) -> bool pure virtual +
+
Gets the constant buffer structure of this binding point.
+
+
+
+

Function documentation

+
+

+ void cubos::core::gl::impl::ShaderBindingPoint::bind(gl::Sampler sampler) pure virtual +

+

Binds a sampler to the binding point.

+ + + + + + + + + + +
Parameters
samplerSampler to bind.
+

If this binding point doesn't support a sampler, an error is logged.

+
+
+

+ void cubos::core::gl::impl::ShaderBindingPoint::bind(gl::Texture1D tex) pure virtual +

+

Binds a 1D texture to the binding point.

+ + + + + + + + + + +
Parameters
texTexture to bind.
+

If this binding point doesn't support a 1D texture, an error is logged.

+
+
+

+ void cubos::core::gl::impl::ShaderBindingPoint::bind(gl::Texture2D tex) pure virtual +

+

Binds a 2D texture to the binding point.

+ + + + + + + + + + +
Parameters
texTexture to bind.
+

If this binding point doesn't support a 2D texture, an error is logged.

+
+
+

+ void cubos::core::gl::impl::ShaderBindingPoint::bind(gl::Texture2DArray tex) pure virtual +

+

Binds a 2D texture array to the binding point.

+ + + + + + + + + + +
Parameters
texTexture array to bind.
+

If this binding point doesn't support a 2D texture array, an error is logged.

+
+
+

+ void cubos::core::gl::impl::ShaderBindingPoint::bind(gl::Texture3D tex) pure virtual +

+

Binds a 3D texture to the binding point.

+ + + + + + + + + + +
Parameters
texTexture to bind.
+

If this binding point doesn't support a 3D texture, an error is logged.

+
+
+

+ void cubos::core::gl::impl::ShaderBindingPoint::bind(gl::CubeMap cubeMap) pure virtual +

+

Binds a cube map to the binding point.

+ + + + + + + + + + +
Parameters
cubeMapCube map to bind.
+

If this binding point doesn't support a cube map, an error is logged.

+
+
+

+ void cubos::core::gl::impl::ShaderBindingPoint::bind(gl::CubeMapArray cubeMap) pure virtual +

+

Binds a cube map array to the binding point.

+ + + + + + + + + + +
Parameters
cubeMapCube map to bind.
+

If this binding point doesn't support a cube map array, an error is logged.

+
+
+

+ void cubos::core::gl::impl::ShaderBindingPoint::bind(gl::ConstantBuffer cb) pure virtual +

+

Binds a constant buffer to the binding point.

+ + + + + + + + + + +
Parameters
cbConstant buffer to bind.
+

If this binding point doesn't support a constant buffer, an error is logged.

+
+
+

+ void cubos::core::gl::impl::ShaderBindingPoint::bind(gl::Texture2D tex, + int level, + Access access) pure virtual +

+

Binds a level of a 2D texture to an image unit.

+ + + + + + + + + + + + + + + + + + +
Parameters
texTexture to bind.
levelMip level to bind.
accessAccess mode.
+

If this binding point doesn't support an image unit, an error is logged.

+
+
+

+ void cubos::core::gl::impl::ShaderBindingPoint::setConstant(glm::vec2 val) pure virtual +

+

Sets the value of the uniform tied to the binding point to the provided vec2 value.

+ + + + + + + + + + +
Parameters
valValue to set.
+
+
+

+ void cubos::core::gl::impl::ShaderBindingPoint::setConstant(glm::vec3 val) pure virtual +

+

Sets the value of the uniform tied to the binding point to the provided vec3 value.

+ + + + + + + + + + +
Parameters
valValue to set.
+
+
+

+ void cubos::core::gl::impl::ShaderBindingPoint::setConstant(glm::vec4 val) pure virtual +

+

Sets the value of the uniform tied to the binding point to the provided vec4 value.

+ + + + + + + + + + +
Parameters
valValue to set.
+
+
+

+ void cubos::core::gl::impl::ShaderBindingPoint::setConstant(glm::ivec2 val) pure virtual +

+

Sets the value of the uniform tied to the binding point to the provided integer vec2 value.

+ + + + + + + + + + +
Parameters
valValue to set.
+
+
+

+ void cubos::core::gl::impl::ShaderBindingPoint::setConstant(glm::ivec3 val) pure virtual +

+

Sets the value of the uniform tied to the binding point to the provided integer vec3 value.

+ + + + + + + + + + +
Parameters
valValue to set.
+
+
+

+ void cubos::core::gl::impl::ShaderBindingPoint::setConstant(glm::ivec4 val) pure virtual +

+

Sets the value of the uniform tied to the binding point to the provided integer vec4 value.

+ + + + + + + + + + +
Parameters
valValue to set.
+
+
+

+ void cubos::core::gl::impl::ShaderBindingPoint::setConstant(glm::uvec2 val) pure virtual +

+

Sets the value of the uniform tied to the binding point to the provided unsigned integer vec2 value.

+ + + + + + + + + + +
Parameters
valValue to set.
+
+
+

+ void cubos::core::gl::impl::ShaderBindingPoint::setConstant(glm::uvec3 val) pure virtual +

+

Sets the value of the uniform tied to the binding point to the provided unsigned integer vec3 value.

+ + + + + + + + + + +
Parameters
valValue to set.
+
+
+

+ void cubos::core::gl::impl::ShaderBindingPoint::setConstant(glm::uvec4 val) pure virtual +

+

Sets the value of the uniform tied to the binding point to the provided unsigned integer vec4 value.

+ + + + + + + + + + +
Parameters
valValue to set.
+
+
+

+ void cubos::core::gl::impl::ShaderBindingPoint::setConstant(glm::mat4 val) pure virtual +

+

Sets the value of the uniform tied to the binding point to the provided mat4 value.

+ + + + + + + + + + +
Parameters
valValue to set.
+
+
+

+ void cubos::core::gl::impl::ShaderBindingPoint::setConstant(float val) pure virtual +

+

Sets the value of the uniform tied to the binding point to the provided float value.

+ + + + + + + + + + +
Parameters
valValue to set.
+
+
+

+ void cubos::core::gl::impl::ShaderBindingPoint::setConstant(int val) pure virtual +

+

Sets the value of the uniform tied to the binding point to the provided int value.

+ + + + + + + + + + +
Parameters
valValue to set.
+
+
+

+ void cubos::core::gl::impl::ShaderBindingPoint::setConstant(unsigned int val) pure virtual +

+

Sets the value of the uniform tied to the binding point to the provided unsigned int value.

+ + + + + + + + + + +
Parameters
valValue to set.
+
+
+

+ bool cubos::core::gl::impl::ShaderBindingPoint::queryConstantBufferStructure(ConstantBufferStructure* structure) pure virtual +

+

Gets the constant buffer structure of this binding point.

+ + + + + + + +
ReturnsWhether the query was successful.
+

If this binding point doesn't support a constant buffer, an error is logged.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderPipeline.html b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderPipeline.html new file mode 100644 index 000000000..84037ba06 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderPipeline.html @@ -0,0 +1,140 @@ + + + + + cubos::core::gl::impl::ShaderPipeline class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::impl::ShaderPipeline class + +

+

Abstract shader pipeline.

+ +
+

Public functions

+
+
+ auto getBindingPoint(const char* name) -> gl::ShaderBindingPoint pure virtual +
+
Gets a binding point from its name.
+
+
+
+

Function documentation

+
+

+ gl::ShaderBindingPoint cubos::core::gl::impl::ShaderPipeline::getBindingPoint(const char* name) pure virtual +

+

Gets a binding point from its name.

+ + + + + + + +
ReturnsBinding point, or nullptr if no binding point is found.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderStage.html b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderStage.html new file mode 100644 index 000000000..2d02d2678 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderStage.html @@ -0,0 +1,140 @@ + + + + + cubos::core::gl::impl::ShaderStage class | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Texture1D.html b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Texture1D.html new file mode 100644 index 000000000..e59960018 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Texture1D.html @@ -0,0 +1,165 @@ + + + + + cubos::core::gl::impl::Texture1D class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::impl::Texture1D class + +

+

Abstract 1D texture.

+ +
+

Public functions

+
+
+ void update(std::size_t x, + std::size_t width, + const void* data, + std::size_t level = 0) pure virtual +
+
Updates the texture with new data, which must have the same format used when the texture was created.
+
+ void generateMipmaps() pure virtual +
+
Generates mipmaps on this texture.
+
+
+
+

Function documentation

+
+

+ void cubos::core::gl::impl::Texture1D::update(std::size_t x, + std::size_t width, + const void* data, + std::size_t level = 0) pure virtual +

+

Updates the texture with new data, which must have the same format used when the texture was created.

+ + + + + + + + + + + + + + + + + + + + + + +
Parameters
xDestination X coordinate.
widthWidth of the section which will be updated.
dataPointer to the new data.
levelMip level to update.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Texture2D.html b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Texture2D.html new file mode 100644 index 000000000..34e7d01a3 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Texture2D.html @@ -0,0 +1,204 @@ + + + + + cubos::core::gl::impl::Texture2D class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::impl::Texture2D class + +

+

Abstract 2D texture.

+ +
+

Public functions

+
+
+ void update(std::size_t x, + std::size_t y, + std::size_t width, + std::size_t height, + const void* data, + std::size_t level = 0) pure virtual +
+
Updates the texture with new data, which must have the same format used when the texture was created.
+
+ void read(void* outputBuffer, + std::size_t level = 0) pure virtual +
+
Reads texture data into a buffer, which must have the same format used when the texture was created.
+
+ void generateMipmaps() pure virtual +
+
Generates mipmaps on this texture.
+
+
+
+

Function documentation

+
+

+ void cubos::core::gl::impl::Texture2D::update(std::size_t x, + std::size_t y, + std::size_t width, + std::size_t height, + const void* data, + std::size_t level = 0) pure virtual +

+

Updates the texture with new data, which must have the same format used when the texture was created.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
xDestination X coordinate.
yDestination Y coordinate.
widthWidth of the section which will be updated.
heightHeight of the section which will be updated.
dataPointer to the new data.
levelMip level to update.
+
+
+

+ void cubos::core::gl::impl::Texture2D::read(void* outputBuffer, + std::size_t level = 0) pure virtual +

+

Reads texture data into a buffer, which must have the same format used when the texture was created.

+ + + + + + + + + + + + + + +
Parameters
outputBufferBuffer to write the data to.
levelMip level to read.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Texture2DArray.html b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Texture2DArray.html new file mode 100644 index 000000000..8e33caf70 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Texture2DArray.html @@ -0,0 +1,183 @@ + + + + + cubos::core::gl::impl::Texture2DArray class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::impl::Texture2DArray class + +

+

Abstract 2D texture array.

+ +
+

Public functions

+
+
+ void update(std::size_t x, + std::size_t y, + std::size_t i, + std::size_t width, + std::size_t height, + const void* data, + std::size_t level = 0) pure virtual +
+
Updates the texture with new data, which must have the same format used when the texture was created.
+
+ void generateMipmaps() pure virtual +
+
Generates mipmaps on this texture.
+
+
+
+

Function documentation

+
+

+ void cubos::core::gl::impl::Texture2DArray::update(std::size_t x, + std::size_t y, + std::size_t i, + std::size_t width, + std::size_t height, + const void* data, + std::size_t level = 0) pure virtual +

+

Updates the texture with new data, which must have the same format used when the texture was created.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
xDestination X coordinate.
yDestination Y coordinate.
iIndex of the destination texture within the array.
widthWidth of the section which will be updated.
heightHeight of the section which will be updated.
dataPointer to the new data.
levelMip level to update.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Texture3D.html b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Texture3D.html new file mode 100644 index 000000000..5aecc0eb5 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1Texture3D.html @@ -0,0 +1,189 @@ + + + + + cubos::core::gl::impl::Texture3D class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::impl::Texture3D class + +

+

Abstract 3D texture.

+ +
+

Public functions

+
+
+ void update(std::size_t x, + std::size_t y, + std::size_t z, + std::size_t width, + std::size_t height, + std::size_t depth, + const void* data, + std::size_t level = 0) pure virtual +
+
Updates the texture with new data, which must have the same format used when the texture was created.
+
+ void generateMipmaps() pure virtual +
+
Generates mipmaps on this texture.
+
+
+
+

Function documentation

+
+

+ void cubos::core::gl::impl::Texture3D::update(std::size_t x, + std::size_t y, + std::size_t z, + std::size_t width, + std::size_t height, + std::size_t depth, + const void* data, + std::size_t level = 0) pure virtual +

+

Updates the texture with new data, which must have the same format used when the texture was created.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
xDestination X coordinate.
yDestination Y coordinate.
zDestination Z coordinate.
widthWidth of the section which will be updated.
heightHeight of the section which will be updated.
depthDepth of the section which will be updated.
dataPointer to the new data.
levelMip level to update.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1VertexArray.html b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1VertexArray.html new file mode 100644 index 000000000..9da9d18e2 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1VertexArray.html @@ -0,0 +1,103 @@ + + + + + cubos::core::gl::impl::VertexArray class | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1VertexBuffer.html b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1VertexBuffer.html new file mode 100644 index 000000000..13b717d55 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1gl_1_1impl_1_1VertexBuffer.html @@ -0,0 +1,144 @@ + + + + + cubos::core::gl::impl::VertexBuffer class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::impl::VertexBuffer class + +

+

Abstract vertex buffer.

+ +
+

Public functions

+
+
+ auto map() -> void* pure virtual +
+
Maps the vertex buffer to a region in memory. Must be matched with a call to unmap().
+
+ void unmap() pure virtual +
+
Unmaps the vertex buffer, updating it with data written to the mapped region.
+
+
+
+

Function documentation

+
+

+ void* cubos::core::gl::impl::VertexBuffer::map() pure virtual +

+

Maps the vertex buffer to a region in memory. Must be matched with a call to unmap().

+ + + + + + + +
ReturnsPointer to the memory region.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1io_1_1BaseWindow.html b/docs-preview/pr-1032/classcubos_1_1core_1_1io_1_1BaseWindow.html new file mode 100644 index 000000000..db5da19eb --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1io_1_1BaseWindow.html @@ -0,0 +1,534 @@ + + + + + cubos::core::io::BaseWindow class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::io::BaseWindow class + +

+

Interface used to wrap low-level window API implementations.

+ +

Allows polling of input events and creates a gl::RenderDevice for rendering to the window.

+
+

Public functions

+
+
+ void pushEvent(WindowEvent&& event) +
+
Pushes an event to the event queue.
+
+ auto pollEvent() -> std::optional<WindowEvent> +
+
Polls the window for events.
+
+ void swapBuffers() pure virtual +
+
Swaps the window buffers.
+
+ auto renderDevice() const -> gl::RenderDevice& pure virtual +
+
Gets the render device associated with this window.
+
+ auto size() const -> glm::ivec2 pure virtual +
+
Gets the window size, which may differ from the framebuffer size.
+
+ auto framebufferSize() const -> glm::ivec2 pure virtual +
+
Gets the window framebuffer size, which may differ from the window size.
+
+ auto contentScale() const -> float pure virtual +
+
Gets the window content scale, commonly known as "DPI scale".
+
+ auto shouldClose() const -> bool pure virtual +
+
Checks whether the window should close.
+
+ auto time() const -> double pure virtual +
+
Gets the time since the window was created.
+
+ void mouseState(MouseState state) pure virtual +
+
Sets the mouse state when the window is focused.
+
+ auto mouseState() const -> MouseState pure virtual +
+
Gets the mouse state when the window is focused.
+
+ auto getMousePosition() -> glm::ivec2 pure virtual +
+
Gets the position of the mouse cursor.
+
+ void setMousePosition(glm::ivec2 position) pure virtual +
+
Sets the position of the mouse cursor.
+
+ auto createCursor(Cursor::Standard standard) -> std::shared_ptr<Cursor> pure virtual +
+
Creates a new cursor with a standard shape.
+
+ void cursor(std::shared_ptr<Cursor> cursor) pure virtual +
+
Sets the current cursor. Pass nullptr to use the default cursor.
+
+ void clipboard(const std::string& text) pure virtual +
+
Sets the content of the clipboard.
+
+ auto clipboard() const -> const char* pure virtual +
+
Gets the content of the clipboard.
+
+ auto modifiers() const -> Modifiers pure virtual +
+
Gets the last used keyboard modifiers.
+
+ auto pressed(Key key, + Modifiers modifiers = Modifiers::None) const -> bool pure virtual +
+
Checks if a key is currently pressed with (at least) the given modifiers.
+
+ auto gamepadState(int gamepad, + GamepadState& state) const -> bool pure virtual +
+
Gets the state of the specified gamepad.
+
+
+
+

Protected functions

+
+
+ void pollEvents() pure virtual +
+
Asks the implementation to fill the event queue with new events.
+
+
+
+

Function documentation

+
+

+ void cubos::core::io::BaseWindow::pushEvent(WindowEvent&& event) +

+

Pushes an event to the event queue.

+ + + + + + + + + + +
Parameters
eventEvent to push.
+
+
+

+ std::optional<WindowEvent> cubos::core::io::BaseWindow::pollEvent() +

+

Polls the window for events.

+ + + + + + + +
ReturnsNext event, or std::nullopt if there are no more events.
+
+
+

+ gl::RenderDevice& cubos::core::io::BaseWindow::renderDevice() const pure virtual +

+

Gets the render device associated with this window.

+ + + + + + + +
ReturnsRender device associated with this window.
+
+
+

+ glm::ivec2 cubos::core::io::BaseWindow::size() const pure virtual +

+

Gets the window size, which may differ from the framebuffer size.

+ + + + + + + +
ReturnsWindow size, in screen coordinates.
+
+
+

+ glm::ivec2 cubos::core::io::BaseWindow::framebufferSize() const pure virtual +

+

Gets the window framebuffer size, which may differ from the window size.

+ + + + + + + +
ReturnsWindow framebuffer size, in pixels.
+
+
+

+ float cubos::core::io::BaseWindow::contentScale() const pure virtual +

+

Gets the window content scale, commonly known as "DPI scale".

+ + + + + + + +
ReturnsRatio between the current DPI and the platform's default DPI.
+
+
+

+ bool cubos::core::io::BaseWindow::shouldClose() const pure virtual +

+

Checks whether the window should close.

+ + + + + + + +
ReturnsWhether the window should close.
+
+
+

+ double cubos::core::io::BaseWindow::time() const pure virtual +

+

Gets the time since the window was created.

+ + + + + + + +
ReturnsTime since the window was created, in seconds.
+
+
+

+ void cubos::core::io::BaseWindow::mouseState(MouseState state) pure virtual +

+

Sets the mouse state when the window is focused.

+ + + + + + + + + + +
Parameters
stateMouse state.
+
+
+

+ MouseState cubos::core::io::BaseWindow::mouseState() const pure virtual +

+

Gets the mouse state when the window is focused.

+ + + + + + + +
ReturnsMouse state when the window is focused.
+
+
+

+ glm::ivec2 cubos::core::io::BaseWindow::getMousePosition() pure virtual +

+

Gets the position of the mouse cursor.

+ + + + + + + +
ReturnsPosition of the mouse cursor, in screen coordinates.
+
+
+

+ void cubos::core::io::BaseWindow::setMousePosition(glm::ivec2 position) pure virtual +

+

Sets the position of the mouse cursor.

+ + + + + + + + + + +
Parameters
positionNew position of the mouse cursor, in screen coordinates.
+
+
+

+ std::shared_ptr<Cursor> cubos::core::io::BaseWindow::createCursor(Cursor::Standard standard) pure virtual +

+

Creates a new cursor with a standard shape.

+ + + + + + + + + + + + + + + + +
Parameters
standardStandard cursor to use.
ReturnsNew cursor, or nullptr if creation failed.
+
+
+

+ void cubos::core::io::BaseWindow::cursor(std::shared_ptr<Cursor> cursor) pure virtual +

+

Sets the current cursor. Pass nullptr to use the default cursor.

+ + + + + + + + + + +
Parameters
cursorNew cursor.
+
+
+

+ void cubos::core::io::BaseWindow::clipboard(const std::string& text) pure virtual +

+

Sets the content of the clipboard.

+ + + + + + + + + + +
Parameters
textNew clipboard text.
+
+
+

+ const char* cubos::core::io::BaseWindow::clipboard() const pure virtual +

+

Gets the content of the clipboard.

+ + + + + + + +
ReturnsText from the clipboard. Guaranteed to be valid until the next call.
+ +
+
+

+ Modifiers cubos::core::io::BaseWindow::modifiers() const pure virtual +

+

Gets the last used keyboard modifiers.

+ + + + + + + +
ReturnsActive keyboard modifiers.
+
+
+

+ bool cubos::core::io::BaseWindow::pressed(Key key, + Modifiers modifiers = Modifiers::None) const pure virtual +

+

Checks if a key is currently pressed with (at least) the given modifiers.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
keyKey to check.
modifiersModifiers to check.
ReturnsWhether the key and modifiers (or a superset of) are currently pressed.
+
+
+

+ bool cubos::core::io::BaseWindow::gamepadState(int gamepad, + GamepadState& state) const pure virtual +

+

Gets the state of the specified gamepad.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
gamepadGamepad to get the state of.
stateState to fill with the gamepad state.
ReturnsWhether the gamepad was found.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1io_1_1Cursor.html b/docs-preview/pr-1032/classcubos_1_1core_1_1io_1_1Cursor.html new file mode 100644 index 000000000..34a08b348 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1io_1_1Cursor.html @@ -0,0 +1,206 @@ + + + + + cubos::core::io::Cursor class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::io::Cursor class + +

+

Handle for a custom mouse cursor.

+ +
+

Public types

+
+
+ enum class Standard { Arrow, + IBeam, + Cross, + Hand, + EWResize, + NSResize, + NWSEResize, + NESWResize, + AllResize, + NotAllowed } +
+
Identifiers for the different standard cursors.
+
+
+
+

Enum documentation

+
+

+ enum class cubos::core::io::Cursor::Standard +

+

Identifiers for the different standard cursors.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Enumerators
Arrow +

Standard arrow cursor.

+
IBeam +

Standard I-beam cursor.

+
Cross +

Standard crosshair cursor.

+
Hand +

Standard hand cursor.

+
EWResize +

Standard horizontal resize cursor.

+
NSResize +

Standard vertical resize cursor.

+
NWSEResize +

Standard diagonal resize cursor (top-left to bottom-right).

+
NESWResize +

Standard diagonal resize cursor (top-right to bottom-left).

+
AllResize +

Standard all directions resize cursor.

+
NotAllowed +

Standard not allowed cursor.

+
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1AnyValue.html b/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1AnyValue.html new file mode 100644 index 000000000..a53a9d67a --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1AnyValue.html @@ -0,0 +1,370 @@ + + + + + cubos::core::memory::AnyValue class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::memory::AnyValue class final + +

+

Stores a blob of a given reflected type.

+ +
+

Public static functions

+
+
+ static auto defaultConstruct(const reflection::Type& type) -> AnyValue noexcept +
+
Default constructs a value with the given type.
+
+ static auto copyConstruct(const reflection::Type& type, + const void* value) -> AnyValue noexcept +
+
Copy constructs a value with the given type.
+
+ static auto moveConstruct(const reflection::Type& type, + void* value) -> AnyValue noexcept +
+
Move constructs a value with the given type.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ AnyValue() +
+
Constructs an empty AnyValue.
+
+ AnyValue(AnyValue&& other) noexcept +
+
Move constructs.
+
+ AnyValue(const AnyValue& other) noexcept +
+
Copy constructs.
+
+
+
+

Public functions

+
+
+ auto operator=(AnyValue&& other) -> AnyValue& noexcept +
+
Move assignment.
+
+ auto type() const -> const reflection::Type& +
+
Get the type of the elements stored in the vector.
+
+ auto get() -> void* +
+
Gets a pointer to the underlying value.
+
+ auto get() const -> const void* +
+
Gets a pointer to the underlying value.
+
+ auto valid() const -> bool +
+
Checks whether value is valid or not (holds a value).
+
+
+
+

Function documentation

+
+

+ static AnyValue cubos::core::memory::AnyValue::defaultConstruct(const reflection::Type& type) noexcept +

+

Default constructs a value with the given type.

+ + + + + + + + + + + + + + + + +
Parameters
typeValue type.
ReturnsValue.
+ +
+
+

+ static AnyValue cubos::core::memory::AnyValue::copyConstruct(const reflection::Type& type, + const void* value) noexcept +

+

Copy constructs a value with the given type.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
typeValue type.
valueValue to copy.
ReturnsValue.
+ +
+
+

+ static AnyValue cubos::core::memory::AnyValue::moveConstruct(const reflection::Type& type, + void* value) noexcept +

+

Move constructs a value with the given type.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
typeValue type.
valueValue to move.
ReturnsValue.
+ +
+
+

+ cubos::core::memory::AnyValue::AnyValue(AnyValue&& other) noexcept +

+

Move constructs.

+ + + + + + + + + + +
Parameters
otherValue.
+
+
+

+ cubos::core::memory::AnyValue::AnyValue(const AnyValue& other) noexcept +

+

Copy constructs.

+ + + + + + + + + + +
Parameters
otherValue.
+
+
+

+ AnyValue& cubos::core::memory::AnyValue::operator=(AnyValue&& other) noexcept +

+

Move assignment.

+ + + + + + + + + + +
Parameters
otherValue.
+
+
+

+ const reflection::Type& cubos::core::memory::AnyValue::type() const +

+

Get the type of the elements stored in the vector.

+ + + + + + + +
ReturnsElement type.
+ +
+
+

+ void* cubos::core::memory::AnyValue::get() +

+

Gets a pointer to the underlying value.

+ + + + + + + +
ReturnsValue.
+
+
+

+ const void* cubos::core::memory::AnyValue::get() const +

+

Gets a pointer to the underlying value.

+ + + + + + + +
ReturnsValue.
+
+
+

+ bool cubos::core::memory::AnyValue::valid() const +

+

Checks whether value is valid or not (holds a value).

+ + + + + + + +
ReturnsTrue is valid.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1AnyVector.html b/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1AnyVector.html new file mode 100644 index 000000000..6627cf4c3 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1AnyVector.html @@ -0,0 +1,529 @@ + + + + + cubos::core::memory::AnyVector class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::memory::AnyVector class final + +

+

Stores a dynamically sized array of blobs of a given reflected type.

+ +
+

Constructors, destructors, conversion operators

+
+
+ AnyVector(const reflection::Type& elementType) +
+
Constructs with the given element type.
+
+ AnyVector(AnyVector&& other) noexcept +
+
Move constructs.
+
+
+
+

Public functions

+
+
+ auto elementType() const -> const reflection::Type& +
+
Get the type of the elements stored in the vector.
+
+ void reserve(std::size_t capacity) +
+
Reserves space for at least capacity elements.
+
+ void pushUninit() +
+
Pushes an uninitialized element to the back of the vector.
+
+ void pushDefault() +
+
Pushes a new default-constructed element to the back of the vector.
+
+ void pushCopy(const void* value) +
+
Pushes a new copy-constructed element to the back of the vector.
+
+ void pushMove(void* value) +
+
Pushes a new move-constructed element to the back of the vector.
+
+ void setDefault(std::size_t index) +
+
Overwrites the element at the given index with a new default-constructed element.
+
+ void setCopy(std::size_t index, + const void* value) +
+
Overwrites the element at the given index with a new copy-constructed element.
+
+ void setMove(std::size_t index, + void* value) +
+
Overwrites the element at the given index with a new move-constructed element.
+
+ void pop() +
+
Removes the last element from the vector.
+
+ void swapErase(std::size_t index) +
+
Removes the element at the given index from the vector, moving the last element to its place if it isn't the last element.
+
+ void swapMove(std::size_t index, + void* destination) +
+
Moves the element at the given index from the vector into the given address, moving the last element to its place if it isn't the last element.
+
+ void clear() +
+
Removes all elements from the vector.
+
+ auto at(std::size_t index) -> void* +
+
Get the element at the given index.
+
+ auto at(std::size_t index) const -> const void* +
+
Get the element at the given index.
+
+ auto size() const -> std::size_t +
+
Get the number of elements in the vector.
+
+ auto capacity() const -> std::size_t +
+
Get the number of elements the vector can hold without reallocating.
+
+ auto empty() const -> bool +
+
Checks if the vector is empty.
+
+
+
+

Function documentation

+
+

+ cubos::core::memory::AnyVector::AnyVector(const reflection::Type& elementType) +

+

Constructs with the given element type.

+ + + + + + + + + + +
Parameters
elementTypeElement type.
+ +
+
+

+ cubos::core::memory::AnyVector::AnyVector(AnyVector&& other) noexcept +

+

Move constructs.

+ + + + + + + + + + +
Parameters
otherVector.
+
+
+

+ const reflection::Type& cubos::core::memory::AnyVector::elementType() const +

+

Get the type of the elements stored in the vector.

+ + + + + + + +
ReturnsElement type.
+
+
+

+ void cubos::core::memory::AnyVector::reserve(std::size_t capacity) +

+

Reserves space for at least capacity elements.

+ + + + + + + + + + +
Parameters
capacityMinimum capacity.
+ +
+
+

+ void cubos::core::memory::AnyVector::pushUninit() +

+

Pushes an uninitialized element to the back of the vector.

+ +
+
+

+ void cubos::core::memory::AnyVector::pushDefault() +

+

Pushes a new default-constructed element to the back of the vector.

+ +
+
+

+ void cubos::core::memory::AnyVector::pushCopy(const void* value) +

+

Pushes a new copy-constructed element to the back of the vector.

+ + + + + + + + + + +
Parameters
valueElement to copy.
+ +
+
+

+ void cubos::core::memory::AnyVector::pushMove(void* value) +

+

Pushes a new move-constructed element to the back of the vector.

+ + + + + + + + + + +
Parameters
valueElement to move.
+
+
+

+ void cubos::core::memory::AnyVector::setDefault(std::size_t index) +

+

Overwrites the element at the given index with a new default-constructed element.

+ + + + + + + + + + +
Parameters
indexElement index.
+ +
+
+

+ void cubos::core::memory::AnyVector::setCopy(std::size_t index, + const void* value) +

+

Overwrites the element at the given index with a new copy-constructed element.

+ + + + + + + + + + + + + + +
Parameters
indexElement index.
valueElement to copy.
+ +
+
+

+ void cubos::core::memory::AnyVector::setMove(std::size_t index, + void* value) +

+

Overwrites the element at the given index with a new move-constructed element.

+ + + + + + + + + + + + + + +
Parameters
indexElement index.
valueElement to move.
+ +
+
+

+ void cubos::core::memory::AnyVector::pop() +

+

Removes the last element from the vector.

+ +
+
+

+ void cubos::core::memory::AnyVector::swapErase(std::size_t index) +

+

Removes the element at the given index from the vector, moving the last element to its place if it isn't the last element.

+ + + + + + + + + + +
Parameters
indexElement index.
+ +
+
+

+ void cubos::core::memory::AnyVector::swapMove(std::size_t index, + void* destination) +

+

Moves the element at the given index from the vector into the given address, moving the last element to its place if it isn't the last element.

+ + + + + + + + + + + + + + +
Parameters
indexElement index.
destinationAddress to move the element to.
+ +
+
+

+ void* cubos::core::memory::AnyVector::at(std::size_t index) +

+

Get the element at the given index.

+ + + + + + + + + + + + + + + + +
Parameters
indexIndex of the element to get.
ReturnsPointer to the element.
+ +
+
+

+ const void* cubos::core::memory::AnyVector::at(std::size_t index) const +

+

Get the element at the given index.

+ + + + + + + + + + + + + + + + +
Parameters
indexIndex of the element to get.
ReturnsPointer to the element.
+ +
+
+

+ std::size_t cubos::core::memory::AnyVector::size() const +

+

Get the number of elements in the vector.

+ + + + + + + +
ReturnsElement count.
+
+
+

+ std::size_t cubos::core::memory::AnyVector::capacity() const +

+

Get the number of elements the vector can hold without reallocating.

+ + + + + + + +
ReturnsElement capacity.
+
+
+

+ bool cubos::core::memory::AnyVector::empty() const +

+

Checks if the vector is empty.

+ + + + + + + +
ReturnsWhether the vector is empty.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1BufferStream.html b/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1BufferStream.html new file mode 100644 index 000000000..73d46dd1d --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1BufferStream.html @@ -0,0 +1,444 @@ + + + + + cubos::core::memory::BufferStream class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::memory::BufferStream class + +

+

Stream implementation which writes to/reads from a buffer.

+ +
+

Base classes

+
+
+ class Stream +
+
Interface class for memory streams. Abstracts away sources or destinations of data.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ BufferStream(void* buffer, + std::size_t size, + bool readOnly = false) +
+
Constructs using an existing buffer.
+
+ BufferStream(const void* buffer, + std::size_t size) +
+
Constructs using a read-only buffer.
+
+ BufferStream(std::size_t size = 16) +
+
Constructs using a new buffer, managed internally and which grows as needed.
+
+ BufferStream(const BufferStream& other) +
+
Constructs a copy of another buffer stream. If the given buffer stream owns its buffer, the copy will also create its own buffer. Otherwise, it will share the buffer with the original.
+
+ BufferStream(BufferStream&& other) noexcept +
+
Move constructs.
+
+
+
+

Public functions

+
+
+ auto getBuffer() const -> const void* +
+
Gets the buffer of this stream.
+
+ auto string() const -> std::string +
+
Creates a string from the buffer of this stream.
+
+ auto read(void* data, + std::size_t size) -> std::size_t override +
+
Reads data from the stream.
+
+ auto write(const void* data, + std::size_t size) -> std::size_t override +
+
Writes data to the stream.
+
+ auto tell() const -> std::size_t override +
+
Gets the current position in the stream.
+
+ void seek(ptrdiff_t offset, + SeekOrigin origin) override +
+
Seeks to a position in the stream.
+
+ auto eof() const -> bool override +
+
Checks if the stream still has content to read.
+
+ auto peek() const -> char override +
+
Peeks one byte from the stream.
+
+
+
+

Function documentation

+
+

+ cubos::core::memory::BufferStream::BufferStream(void* buffer, + std::size_t size, + bool readOnly = false) +

+

Constructs using an existing buffer.

+ + + + + + + + + + + + + + + + + + +
Parameters
bufferBuffer to read/write from.
sizeSize of the buffer.
readOnlyWhether the buffer is read-only.
+
+
+

+ cubos::core::memory::BufferStream::BufferStream(const void* buffer, + std::size_t size) +

+

Constructs using a read-only buffer.

+ + + + + + + + + + + + + + +
Parameters
bufferBuffer to read/write from.
sizeSize of the buffer.
+
+
+

+ cubos::core::memory::BufferStream::BufferStream(std::size_t size = 16) +

+

Constructs using a new buffer, managed internally and which grows as needed.

+ + + + + + + + + + +
Parameters
sizeInitial size of the buffer.
+
+
+

+ cubos::core::memory::BufferStream::BufferStream(const BufferStream& other) +

+

Constructs a copy of another buffer stream. If the given buffer stream owns its buffer, the copy will also create its own buffer. Otherwise, it will share the buffer with the original.

+ + + + + + + + + + +
Parameters
otherBuffer stream to copy.
+
+
+

+ cubos::core::memory::BufferStream::BufferStream(BufferStream&& other) noexcept +

+

Move constructs.

+ + + + + + + + + + +
Parameters
otherBuffer stream to move.
+
+
+

+ const void* cubos::core::memory::BufferStream::getBuffer() const +

+

Gets the buffer of this stream.

+ + + + + + + +
ReturnsBuffer.
+
+
+

+ std::string cubos::core::memory::BufferStream::string() const +

+

Creates a string from the buffer of this stream.

+ + + + + + + +
ReturnsString.
+
+
+

+ std::size_t cubos::core::memory::BufferStream::read(void* data, + std::size_t size) override +

+

Reads data from the stream.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
dataBuffer to read data into.
sizeSize of the buffer.
ReturnsNumber of bytes read.
+
+
+

+ std::size_t cubos::core::memory::BufferStream::write(const void* data, + std::size_t size) override +

+

Writes data to the stream.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
dataBuffer to write data from.
sizeSize of the buffer.
ReturnsNumber of bytes written.
+
+
+

+ std::size_t cubos::core::memory::BufferStream::tell() const override +

+

Gets the current position in the stream.

+ + + + + + + +
ReturnsCurrent position in the stream, or SIZE_MAX if the position is unknown.
+
+
+

+ void cubos::core::memory::BufferStream::seek(ptrdiff_t offset, + SeekOrigin origin) override +

+

Seeks to a position in the stream.

+ + + + + + + + + + + + + + +
Parameters
offsetOffset to seek to.
originOrigin of the offset.
+
+
+

+ bool cubos::core::memory::BufferStream::eof() const override +

+

Checks if the stream still has content to read.

+ + + + + + + +
ReturnsWhether the stream has reached the end.
+
+
+

+ char cubos::core::memory::BufferStream::peek() const override +

+

Peeks one byte from the stream.

+ + + + + + + +
ReturnsPeeked byte.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1Function_3_01R_07Ts_8_8_8_08_4.html b/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1Function_3_01R_07Ts_8_8_8_08_4.html new file mode 100644 index 000000000..6b16c2553 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1Function_3_01R_07Ts_8_8_8_08_4.html @@ -0,0 +1,311 @@ + + + + + cubos::core::memory::Function<R(Ts...)> class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename R, typename... Ts>
+ cubos::core::memory::Function<R(Ts...)> class final +

+

Generic function pointer which can also store capturing lambda functions.

+ + + + + + + + + + + + + + +
Template parameters
RReturn type.
TsArgument types.
+ +

Should be used with care as this class needs to do heap allocations to store captured data.

+
+

Constructors, destructors, conversion operators

+
+
+ Function() defaulted noexcept +
+
Default constructs.
+
+ Function(Function&& other) noexcept +
+
Move constructs.
+
+
template<typename F>
+ Function(F function) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ auto operator=(std::nullptr_t) -> Function& +
+
Frees the underlying function.
+
+ auto operator=(Function&& other) -> Function& noexcept +
+
Move assigns.
+
+ auto operator()(Ts... args) -> R +
+
Invokes the underlying function.
+
+ auto operator==(std::nullptr_t) const -> bool +
+
Checks if the function is null.
+
+
+
+

Function documentation

+
+

+
+ template<typename R, typename... Ts> +
+ cubos::core::memory::Function<R(Ts...)><R, Ts>::Function(Function&& other) noexcept +

+

Move constructs.

+ + + + + + + + + + +
Parameters
otherOther.
+
+
+

+
+ template<typename R, typename... Ts> + template<typename F> +
+ cubos::core::memory::Function<R(Ts...)><R, Ts>::Function(F function) +

+

Constructs.

+ + + + + + + + + + + + + + + + + + + +
Template parameters
FFunction type.
Parameters
functionFunction.
+
+
+

+
+ template<typename R, typename... Ts> +
+ Function& cubos::core::memory::Function<R(Ts...)><R, Ts>::operator=(std::nullptr_t) +

+

Frees the underlying function.

+ + + + + + + +
ReturnsThis.
+
+
+

+
+ template<typename R, typename... Ts> +
+ Function& cubos::core::memory::Function<R(Ts...)><R, Ts>::operator=(Function&& other) noexcept +

+

Move assigns.

+ + + + + + + + + + + + + + + + +
Parameters
otherOther.
ReturnsThis.
+
+
+

+
+ template<typename R, typename... Ts> +
+ R cubos::core::memory::Function<R(Ts...)><R, Ts>::operator()(Ts... args) +

+

Invokes the underlying function.

+ + + + + + + + + + + + + + + + +
Parameters
argsArgument values.
ReturnsReturn value.
+

Must not be null.

+
+
+

+
+ template<typename R, typename... Ts> +
+ bool cubos::core::memory::Function<R(Ts...)><R, Ts>::operator==(std::nullptr_t) const +

+

Checks if the function is null.

+ + + + + + + +
ReturnsWhether the function is null.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1ReadGuard.html b/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1ReadGuard.html new file mode 100644 index 000000000..2c9411a8f --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1ReadGuard.html @@ -0,0 +1,263 @@ + + + + + cubos::core::memory::ReadGuard class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename T, typename Lock>
+ cubos::core::memory::ReadGuard class +

+

Provides safe read-only access to an object using a lock.

+ + + + + + + + + + + + + + +
Template parameters
TGuarded object type.
LockHeld lock type.
+ +

This class was created because there are multiple parts of the code that need to provide access to objects in a thread-safe manner.

Usage example

using AssetMetaRead = core::memory::ReadGuard<AssetMeta, std::shared_lock<std::shared_mutex>>;
+
+

Constructors, destructors, conversion operators

+
+
+ ReadGuard(const T& object, + Lock&& lock) +
+
Constructor.
+
+ ReadGuard(ReadGuard&& other) noexcept +
+
Move constructor.
+
+
+
+

Public functions

+
+
+ auto get() const -> const T& +
+
Gets a reference to the underlying object.
+
+ auto operator*() const -> const T& +
+
Gets a reference to the underlying object.
+
+ auto operator->() const -> const T* +
+
Gets a pointer to the underlying object.
+
+
+
+

Function documentation

+
+

+
+ template<typename T, typename Lock> +
+ cubos::core::memory::ReadGuard<T, Lock>::ReadGuard(const T& object, + Lock&& lock) +

+

Constructor.

+ + + + + + + + + + + + + + +
Parameters
objectObject to guard.
lockLock to hold.
+
+
+

+
+ template<typename T, typename Lock> +
+ cubos::core::memory::ReadGuard<T, Lock>::ReadGuard(ReadGuard&& other) noexcept +

+

Move constructor.

+ + + + + + + + + + +
Parameters
otherGuard to move from.
+
+
+

+
+ template<typename T, typename Lock> +
+ const T& cubos::core::memory::ReadGuard<T, Lock>::get() const +

+

Gets a reference to the underlying object.

+ + + + + + + +
ReturnsUnderlying object.
+
+
+

+
+ template<typename T, typename Lock> +
+ const T& cubos::core::memory::ReadGuard<T, Lock>::operator*() const +

+

Gets a reference to the underlying object.

+ + + + + + + +
ReturnsUnderlying object.
+
+
+

+
+ template<typename T, typename Lock> +
+ const T* cubos::core::memory::ReadGuard<T, Lock>::operator->() const +

+

Gets a pointer to the underlying object.

+ + + + + + + +
ReturnsUnderlying object.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1StandardStream.html b/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1StandardStream.html new file mode 100644 index 000000000..85bde55a5 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1StandardStream.html @@ -0,0 +1,333 @@ + + + + + cubos::core::memory::StandardStream class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::memory::StandardStream class + +

+

Stream implementation which wraps a libc file pointer.

+ +
+

Base classes

+
+
+ class Stream +
+
Interface class for memory streams. Abstracts away sources or destinations of data.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ StandardStream(FILE* file, + bool close = false) +
+
Constructs.
+
+ StandardStream(StandardStream&& other) noexcept +
+
Move constructs.
+
+
+
+

Public functions

+
+
+ auto read(void* data, + std::size_t size) -> std::size_t override +
+
Reads data from the stream.
+
+ auto write(const void* data, + std::size_t size) -> std::size_t override +
+
Writes data to the stream.
+
+ auto tell() const -> std::size_t override +
+
Gets the current position in the stream.
+
+ void seek(ptrdiff_t offset, + SeekOrigin origin) override +
+
Seeks to a position in the stream.
+
+ auto eof() const -> bool override +
+
Checks if the stream still has content to read.
+
+ auto peek() const -> char override +
+
Peeks one byte from the stream.
+
+
+
+

Function documentation

+
+

+ cubos::core::memory::StandardStream::StandardStream(FILE* file, + bool close = false) +

+

Constructs.

+ + + + + + + + + + + + + + +
Parameters
fileFile to read/write from.
closeShould the file be closed when this stream is destructed?
+
+
+

+ cubos::core::memory::StandardStream::StandardStream(StandardStream&& other) noexcept +

+

Move constructs.

+ + + + + + + + + + +
Parameters
otherMoved stream.
+
+
+

+ std::size_t cubos::core::memory::StandardStream::read(void* data, + std::size_t size) override +

+

Reads data from the stream.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
dataBuffer to read data into.
sizeSize of the buffer.
ReturnsNumber of bytes read.
+
+
+

+ std::size_t cubos::core::memory::StandardStream::write(const void* data, + std::size_t size) override +

+

Writes data to the stream.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
dataBuffer to write data from.
sizeSize of the buffer.
ReturnsNumber of bytes written.
+
+
+

+ std::size_t cubos::core::memory::StandardStream::tell() const override +

+

Gets the current position in the stream.

+ + + + + + + +
ReturnsCurrent position in the stream, or SIZE_MAX if the position is unknown.
+
+
+

+ void cubos::core::memory::StandardStream::seek(ptrdiff_t offset, + SeekOrigin origin) override +

+

Seeks to a position in the stream.

+ + + + + + + + + + + + + + +
Parameters
offsetOffset to seek to.
originOrigin of the offset.
+
+
+

+ bool cubos::core::memory::StandardStream::eof() const override +

+

Checks if the stream still has content to read.

+ + + + + + + +
ReturnsWhether the stream has reached the end.
+
+
+

+ char cubos::core::memory::StandardStream::peek() const override +

+

Peeks one byte from the stream.

+ + + + + + + +
ReturnsPeeked byte.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1Stream.html b/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1Stream.html new file mode 100644 index 000000000..340254631 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1Stream.html @@ -0,0 +1,1012 @@ + + + + + cubos::core::memory::Stream class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::memory::Stream class + +

+

Interface class for memory streams. Abstracts away sources or destinations of data.

+ +

Motivation

Why do we have our own streams? Well, the standard library streams are hard to use and extend, and very template heavy. Using our own streams allows us to abstract away more easily where the data is coming from, or going to, allowing us, for example, to embed files into the executable and not have to worry about the code that reads them.

+
+

Derived classes

+
+
+
template<typename T>
+ class cubos::core::data::FileStream final +
+
Wrapper around an implementation-specific file stream which keeps the file alive and does some sanity checks.
+
+ class BufferStream +
+
Stream implementation which writes to/reads from a buffer.
+
+ class StandardStream +
+
Stream implementation which wraps a libc file pointer.
+
+
+
+

Public static variables

+
+
+ static Stream& stdIn +
+
Stream wrapper for stdin.
+
+ static Stream& stdOut +
+
Stream wrapper for stdout.
+
+ static Stream& stdErr +
+
Stream wrapper for stderr.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ Stream() defaulted +
+
Constructs.
+
+ Stream(Stream&&) defaulted +
+
Move constructs.
+
+ Stream(const Stream&) deleted +
+
Forbid copy construction.
+
+
template<typename T>
+ requires(::std::is_integral_v<T> && ::std::is_signed_v<T>) void print(T value +
+
Prints a signed integer to the stream.
+
+
template<typename T>
+ requires(::std::is_integral_v<T> && !::std::is_signed_v<T>) inline void print(T value +
+
Prints a signed integer to the stream.
+
+
+
+

Public functions

+
+
+ auto read(void* data, + std::size_t size) -> std::size_t pure virtual +
+
Reads data from the stream.
+
+ auto write(const void* data, + std::size_t size) -> std::size_t pure virtual +
+
Writes data to the stream.
+
+ auto tell() const -> std::size_t pure virtual +
+
Gets the current position in the stream.
+
+ void seek(ptrdiff_t offset, + SeekOrigin origin) pure virtual +
+
Seeks to a position in the stream.
+
+ auto eof() const -> bool pure virtual +
+
Checks if the stream still has content to read.
+
+ auto peek() const -> char pure virtual +
+
Peeks one byte from the stream.
+
+ auto get() -> char +
+
Gets one byte from the stream.
+
+ void put(char c) +
+
Puts one byte into the stream.
+
+ void print(int64_t value, + std::size_t base = 10) +
+
Prints a 64 bit signed integer to the stream.
+
+ void print(uint64_t value, + std::size_t base = 10) +
+
Prints a 64 bit unsigned integer to the stream.
+
+ void print(float value, + std::size_t decimalPlaces = 4) +
+
Prints a float to the stream.
+
+ void print(double value, + std::size_t decimalPlaces = 4) +
+
Prints a double to the stream.
+
+ void print(const char* str) +
+
Prints a string to the stream.
+
+ void print(const char* str, + std::size_t size) +
+
Prints a string to the stream.
+
+ void print(const ::std::string& str) +
+
Prints a string to the stream.
+
+
template<typename T, typename... TArgs>
+ void printf(const char* fmt, + T arg, + TArgs... args) +
+
Prints a formatted string the stream.
+
+ void printf(const char* fmt) +
+
Prints a string to the stream.
+
+ void parse(int8_t& value, + std::size_t base = 10) +
+
Parses a 8 bit signed integer from the stream.
+
+ void parse(int16_t& value, + std::size_t base = 10) +
+
Parses a 16 bit signed integer from the stream.
+
+ void parse(int32_t& value, + std::size_t base = 10) +
+
Parses a 32 bit signed integer from the stream.
+
+ void parse(int64_t& value, + std::size_t base = 10) +
+
Parses a 64 bit signed integer from the stream.
+
+ void parse(uint8_t& value, + std::size_t base = 10) +
+
Parses a 8 bit unsigned integer from the stream.
+
+ void parse(uint16_t& value, + std::size_t base = 10) +
+
Parses a 16 bit unsigned integer from the stream.
+
+ void parse(uint32_t& value, + std::size_t base = 10) +
+
Parses a 32 bit unsigned integer from the stream.
+
+ void parse(uint64_t& value, + std::size_t base = 10) +
+
Parses a 64 bit unsigned integer from the stream.
+
+ void parse(float& value) +
+
Parses a float from the stream.
+
+ void parse(double& value) +
+
Parses a double from the stream.
+
+ void readUntil(std::string& str, + const char* terminator) +
+
Reads a string from the stream until the terminator (or \0) is found.
+
+ auto readUntil(char* buffer, + std::size_t size, + const char* terminator) -> std::size_t +
+
Reads a string from the stream until the terminator (or \0) is found.
+
+ void ignore(std::size_t size) +
+
Ignores a number of bytes from the stream.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ cubos::core::memory::Stream::requires(::std::is_integral_v<T> && ::std::is_signed_v<T>) void print(T value +

+

Prints a signed integer to the stream.

+ + + + + + + + + + +
Template parameters
TType of the integer.
+
+
+

+
+ template<typename T> +
+ cubos::core::memory::Stream::requires(::std::is_integral_v<T> && !::std::is_signed_v<T>) inline void print(T value +

+

Prints a signed integer to the stream.

+ + + + + + + + + + +
Template parameters
TInteger type.
+
+
+

+ std::size_t cubos::core::memory::Stream::read(void* data, + std::size_t size) pure virtual +

+

Reads data from the stream.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
dataBuffer to read data into.
sizeSize of the buffer.
ReturnsNumber of bytes read.
+
+
+

+ std::size_t cubos::core::memory::Stream::write(const void* data, + std::size_t size) pure virtual +

+

Writes data to the stream.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
dataBuffer to write data from.
sizeSize of the buffer.
ReturnsNumber of bytes written.
+
+
+

+ std::size_t cubos::core::memory::Stream::tell() const pure virtual +

+

Gets the current position in the stream.

+ + + + + + + +
ReturnsCurrent position in the stream, or SIZE_MAX if the position is unknown.
+
+
+

+ void cubos::core::memory::Stream::seek(ptrdiff_t offset, + SeekOrigin origin) pure virtual +

+

Seeks to a position in the stream.

+ + + + + + + + + + + + + + +
Parameters
offsetOffset to seek to.
originOrigin of the offset.
+
+
+

+ bool cubos::core::memory::Stream::eof() const pure virtual +

+

Checks if the stream still has content to read.

+ + + + + + + +
ReturnsWhether the stream has reached the end.
+
+
+

+ char cubos::core::memory::Stream::peek() const pure virtual +

+

Peeks one byte from the stream.

+ + + + + + + +
ReturnsPeeked byte.
+
+
+

+ char cubos::core::memory::Stream::get() +

+

Gets one byte from the stream.

+ + + + + + + +
ReturnsRead byte.
+
+
+

+ void cubos::core::memory::Stream::put(char c) +

+

Puts one byte into the stream.

+ + + + + + + + + + +
Parameters
cByte to put.
+
+
+

+ void cubos::core::memory::Stream::print(int64_t value, + std::size_t base = 10) +

+

Prints a 64 bit signed integer to the stream.

+ + + + + + + + + + + + + + +
Parameters
valueValue to print.
baseBase to use.
+
+
+

+ void cubos::core::memory::Stream::print(uint64_t value, + std::size_t base = 10) +

+

Prints a 64 bit unsigned integer to the stream.

+ + + + + + + + + + + + + + +
Parameters
valueValue to print.
baseBase to use.
+
+
+

+ void cubos::core::memory::Stream::print(float value, + std::size_t decimalPlaces = 4) +

+

Prints a float to the stream.

+ + + + + + + + + + + + + + +
Parameters
valueValue to print.
decimalPlacesNumber of decimal places to print.
+
+
+

+ void cubos::core::memory::Stream::print(double value, + std::size_t decimalPlaces = 4) +

+

Prints a double to the stream.

+ + + + + + + + + + + + + + +
Parameters
valueValue to print.
decimalPlacesNumber of decimal places to print.
+
+
+

+ void cubos::core::memory::Stream::print(const char* str) +

+

Prints a string to the stream.

+ + + + + + + + + + +
Parameters
strString to print.
+
+
+

+ void cubos::core::memory::Stream::print(const char* str, + std::size_t size) +

+

Prints a string to the stream.

+ + + + + + + + + + + + + + +
Parameters
strString to print.
sizeSize of the string.
+
+
+

+ void cubos::core::memory::Stream::print(const ::std::string& str) +

+

Prints a string to the stream.

+ + + + + + + + + + +
Parameters
strValue to print.
+
+
+

+
+ template<typename T, typename... TArgs> +
+ void cubos::core::memory::Stream::printf(const char* fmt, + T arg, + TArgs... args) +

+

Prints a formatted string the stream.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TType of the first argument.
TArgsTypes of the remaining arguments.
Parameters
fmtFormat string.
argFirst argument to print.
argsRemaining arguments to print.
+
Usage
stream.printf("Hello, {}!\n", "world");
+stream.printf("{} + {} = {}\n", 1, 2, 3);
+stream.printf("\\{} {}\n", 1, 2); // This will print "{} 2"
+
+
+

+ void cubos::core::memory::Stream::printf(const char* fmt) +

+

Prints a string to the stream.

+ + + + + + + + + + +
Parameters
fmtFormat string.
+ +
+
+

+ void cubos::core::memory::Stream::parse(int8_t& value, + std::size_t base = 10) +

+

Parses a 8 bit signed integer from the stream.

+ + + + + + + + + + + + + + +
Parameters
value outParsed value.
baseBase to use.
+
+
+

+ void cubos::core::memory::Stream::parse(int16_t& value, + std::size_t base = 10) +

+

Parses a 16 bit signed integer from the stream.

+ + + + + + + + + + + + + + +
Parameters
value outParsed value.
baseBase to use.
+
+
+

+ void cubos::core::memory::Stream::parse(int32_t& value, + std::size_t base = 10) +

+

Parses a 32 bit signed integer from the stream.

+ + + + + + + + + + + + + + +
Parameters
value outParsed value.
baseBase to use.
+
+
+

+ void cubos::core::memory::Stream::parse(int64_t& value, + std::size_t base = 10) +

+

Parses a 64 bit signed integer from the stream.

+ + + + + + + + + + + + + + +
Parameters
value outParsed value.
baseBase to use.
+
+
+

+ void cubos::core::memory::Stream::parse(uint8_t& value, + std::size_t base = 10) +

+

Parses a 8 bit unsigned integer from the stream.

+ + + + + + + + + + + + + + +
Parameters
value outParsed value.
baseBase to use.
+
+
+

+ void cubos::core::memory::Stream::parse(uint16_t& value, + std::size_t base = 10) +

+

Parses a 16 bit unsigned integer from the stream.

+ + + + + + + + + + + + + + +
Parameters
value outParsed value.
baseBase to use.
+
+
+

+ void cubos::core::memory::Stream::parse(uint32_t& value, + std::size_t base = 10) +

+

Parses a 32 bit unsigned integer from the stream.

+ + + + + + + + + + + + + + +
Parameters
value outParsed value.
baseBase to use.
+
+
+

+ void cubos::core::memory::Stream::parse(uint64_t& value, + std::size_t base = 10) +

+

Parses a 64 bit unsigned integer from the stream.

+ + + + + + + + + + + + + + +
Parameters
value outParsed value.
baseBase to use.
+
+
+

+ void cubos::core::memory::Stream::parse(float& value) +

+

Parses a float from the stream.

+ + + + + + + + + + +
Parameters
value outParsed value.
+
+
+

+ void cubos::core::memory::Stream::parse(double& value) +

+

Parses a double from the stream.

+ + + + + + + + + + +
Parameters
value outParsed value.
+
+
+

+ void cubos::core::memory::Stream::readUntil(std::string& str, + const char* terminator) +

+

Reads a string from the stream until the terminator (or \0) is found.

+ + + + + + + + + + + + + + +
Parameters
str outRead string.
terminatorOptional terminator to use.
+
+
+

+ std::size_t cubos::core::memory::Stream::readUntil(char* buffer, + std::size_t size, + const char* terminator) +

+

Reads a string from the stream until the terminator (or \0) is found.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
bufferBuffer to read into.
sizeSize of the buffer.
terminatorOptional terminator to use.
ReturnsNumber of bytes read.
+
+
+

+ void cubos::core::memory::Stream::ignore(std::size_t size) +

+

Ignores a number of bytes from the stream.

+ + + + + + + + + + +
Parameters
sizeNumber of bytes to ignore.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1TypeMap.html b/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1TypeMap.html new file mode 100644 index 000000000..568f0b519 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1TypeMap.html @@ -0,0 +1,583 @@ + + + + + cubos::core::memory::TypeMap class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename V>
+ cubos::core::memory::TypeMap class +

+

A map that stores values of type V, using reflection types as keys.

+ + + + + + + + + + +
Template parameters
VValues type.
+ +
+

Public functions

+
+
+ void insert(const reflection::Type& type, + V value) +
+
Sets the value associated to the given type.
+
+
template<reflection::Reflectable K>
+ void insert(V value) +
+
Sets the value associated to the given type.
+
+ auto erase(const reflection::Type& type) -> bool +
+
Removes the entry associated to the given type.
+
+
template<reflection::Reflectable K>
+ auto erase() -> bool +
+
Removes the entry associated to the given type.
+
+ auto contains(const reflection::Type& type) const -> bool +
+
Checks if there's a an entry with the given type.
+
+
template<reflection::Reflectable K>
+ auto contains() const -> bool +
+
Checks if there's a an entry with the given type.
+
+ auto at(const reflection::Type& type) -> V& +
+
Gets the value associated to the given type.
+
+
template<reflection::Reflectable K>
+ auto at() -> V& +
+
Gets the value associated to the given type.
+
+ auto at(const reflection::Type& type) const -> const V& +
+
Gets the value associated to the given type.
+
+
template<reflection::Reflectable K>
+ auto at() const -> const V& +
+
Gets the value associated to the given type.
+
+ void clear() +
+
Removes all entries from the map.
+
+ auto size() const -> std::size_t +
+
Gets the number of entries in the map.
+
+ auto empty() const -> bool +
+
Checks if the map is empty.
+
+ auto begin() -> auto +
+
Gets an iterator to the beginning of the map.
+
+ auto end() -> auto +
+
Gets an iterator to the end of the map.
+
+ auto begin() const -> auto +
+
Gets an iterator to the beginning of the map.
+
+ auto end() const -> auto +
+
Gets an iterator to the end of the map.
+
+
+
+

Function documentation

+
+

+
+ template<typename V> +
+ void cubos::core::memory::TypeMap<V>::insert(const reflection::Type& type, + V value) +

+

Sets the value associated to the given type.

+ + + + + + + + + + + + + + +
Parameters
typeType.
valueValue.
+ +
+
+

+
+ template<typename V> + template<reflection::Reflectable K> +
+ void cubos::core::memory::TypeMap<V>::insert(V value) +

+

Sets the value associated to the given type.

+ + + + + + + + + + + + + + + + + + + +
Template parameters
KType.
Parameters
valueValue.
+ +
+
+

+
+ template<typename V> +
+ bool cubos::core::memory::TypeMap<V>::erase(const reflection::Type& type) +

+

Removes the entry associated to the given type.

+ + + + + + + + + + + + + + + + +
Parameters
typeType.
ReturnsWhether the entry was removed.
+
+
+

+
+ template<typename V> + template<reflection::Reflectable K> +
+ bool cubos::core::memory::TypeMap<V>::erase() +

+

Removes the entry associated to the given type.

+ + + + + + + + + + + + + + + + +
Template parameters
KType.
ReturnsWhether the entry was removed.
+
+
+

+
+ template<typename V> +
+ bool cubos::core::memory::TypeMap<V>::contains(const reflection::Type& type) const +

+

Checks if there's a an entry with the given type.

+ + + + + + + + + + + + + + + + +
Parameters
typeType.
ReturnsWhether there's an entry with the given type.
+
+
+

+
+ template<typename V> + template<reflection::Reflectable K> +
+ bool cubos::core::memory::TypeMap<V>::contains() const +

+

Checks if there's a an entry with the given type.

+ + + + + + + + + + + + + + + + +
Template parameters
KType.
ReturnsWhether there's an entry with the given type.
+
+
+

+
+ template<typename V> +
+ V& cubos::core::memory::TypeMap<V>::at(const reflection::Type& type) +

+

Gets the value associated to the given type.

+ + + + + + + + + + + + + + + + +
Parameters
typeType.
ReturnsReference to the value.
+ +
+
+

+
+ template<typename V> + template<reflection::Reflectable K> +
+ V& cubos::core::memory::TypeMap<V>::at() +

+

Gets the value associated to the given type.

+ + + + + + + + + + + + + + + + +
Template parameters
KType.
ReturnsReference to the value.
+ +
+
+

+
+ template<typename V> +
+ const V& cubos::core::memory::TypeMap<V>::at(const reflection::Type& type) const +

+

Gets the value associated to the given type.

+ + + + + + + + + + + + + + + + +
Parameters
typeType.
ReturnsReference to the value.
+ +
+
+

+
+ template<typename V> + template<reflection::Reflectable K> +
+ const V& cubos::core::memory::TypeMap<V>::at() const +

+

Gets the value associated to the given type.

+ + + + + + + + + + + + + + + + +
Template parameters
KType.
ReturnsReference to the value.
+ +
+
+

+
+ template<typename V> +
+ std::size_t cubos::core::memory::TypeMap<V>::size() const +

+

Gets the number of entries in the map.

+ + + + + + + +
ReturnsValues count.
+
+
+

+
+ template<typename V> +
+ bool cubos::core::memory::TypeMap<V>::empty() const +

+

Checks if the map is empty.

+ + + + + + + +
ReturnsWhether the map is empty.
+
+
+

+
+ template<typename V> +
+ auto cubos::core::memory::TypeMap<V>::begin() +

+

Gets an iterator to the beginning of the map.

+ + + + + + + +
ReturnsIterator.
+
+
+

+
+ template<typename V> +
+ auto cubos::core::memory::TypeMap<V>::end() +

+

Gets an iterator to the end of the map.

+ + + + + + + +
ReturnsIterator.
+
+
+

+
+ template<typename V> +
+ auto cubos::core::memory::TypeMap<V>::begin() const +

+

Gets an iterator to the beginning of the map.

+ + + + + + + +
ReturnsIterator.
+
+
+

+
+ template<typename V> +
+ auto cubos::core::memory::TypeMap<V>::end() const +

+

Gets an iterator to the end of the map.

+ + + + + + + +
ReturnsIterator.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1UnorderedBimap.html b/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1UnorderedBimap.html new file mode 100644 index 000000000..471fcc0ae --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1UnorderedBimap.html @@ -0,0 +1,483 @@ + + + + + cubos::core::memory::UnorderedBimap class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename L, typename R, typename LHash = std::hash<L>, typename RHash = std::hash<R>>
+ cubos::core::memory::UnorderedBimap class final +

+

A bidirectional hash table.

+ + + + + + + + + + + + + + + + + + + + + + +
Template parameters
LLeft type.
RRight type.
LHashHash functor type for L.
RHashHash functor type for R.
+ +
+

Public functions

+
+
+ void insert(L left, + R right) +
+
Adds a new entry to the map.
+
+ auto eraseLeft(const L& left) -> bool +
+
Removes the entry associated to the given left value.
+
+ auto eraseRight(const R& right) -> bool +
+
Removes the entry associated to the given right value.
+
+ auto contains(const L& left, + const R& right) const -> bool +
+
Checks if the map has the given entry.
+
+ auto containsLeft(const L& left) const -> bool +
+
Checks if the map contains the given left value.
+
+ auto containsRight(const R& right) const -> bool +
+
Checks if the map contains the given right value.
+
+ auto atLeft(const L& left) const -> const R& +
+
Gets the right value associated to the given left value.
+
+ auto atRight(const R& right) const -> const L& +
+
Gets the left value associated to the given right value.
+
+ void clear() +
+
Clears the map.
+
+ auto size() const -> std::size_t +
+
Gets the number of entries in the map.
+
+ auto empty() const -> bool +
+
Checks if the map is empty.
+
+ auto begin() const -> Iterator +
+
Gets an iterator to the beginning of the map.
+
+ auto end() const -> Iterator +
+
Gets an iterator to the end of the map.
+
+
+
+

Function documentation

+
+

+
+ template<typename L, typename R, typename LHash, typename RHash> +
+ void cubos::core::memory::UnorderedBimap<L, R, LHash, RHash>::insert(L left, + R right) +

+

Adds a new entry to the map.

+ + + + + + + + + + + + + + +
Parameters
leftLeft value.
rightRight value.
+ +
+
+

+
+ template<typename L, typename R, typename LHash, typename RHash> +
+ bool cubos::core::memory::UnorderedBimap<L, R, LHash, RHash>::eraseLeft(const L& left) +

+

Removes the entry associated to the given left value.

+ + + + + + + + + + + + + + + + +
Parameters
leftLeft value.
ReturnsWhether the entry was removed.
+
+
+

+
+ template<typename L, typename R, typename LHash, typename RHash> +
+ bool cubos::core::memory::UnorderedBimap<L, R, LHash, RHash>::eraseRight(const R& right) +

+

Removes the entry associated to the given right value.

+ + + + + + + + + + + + + + + + +
Parameters
rightRight value.
ReturnsWhether the entry was removed.
+
+
+

+
+ template<typename L, typename R, typename LHash, typename RHash> +
+ bool cubos::core::memory::UnorderedBimap<L, R, LHash, RHash>::contains(const L& left, + const R& right) const +

+

Checks if the map has the given entry.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
leftLeft value.
rightRight value.
ReturnsWhether the map has the entry.
+
+
+

+
+ template<typename L, typename R, typename LHash, typename RHash> +
+ bool cubos::core::memory::UnorderedBimap<L, R, LHash, RHash>::containsLeft(const L& left) const +

+

Checks if the map contains the given left value.

+ + + + + + + + + + + + + + + + +
Parameters
leftLeft value.
ReturnsWhether the map contains the value.
+
+
+

+
+ template<typename L, typename R, typename LHash, typename RHash> +
+ bool cubos::core::memory::UnorderedBimap<L, R, LHash, RHash>::containsRight(const R& right) const +

+

Checks if the map contains the given right value.

+ + + + + + + + + + + + + + + + +
Parameters
rightRight value.
ReturnsWhether the map contains the value.
+
+
+

+
+ template<typename L, typename R, typename LHash, typename RHash> +
+ const R& cubos::core::memory::UnorderedBimap<L, R, LHash, RHash>::atLeft(const L& left) const +

+

Gets the right value associated to the given left value.

+ + + + + + + + + + + + + + + + +
Parameters
leftLeft value.
ReturnsRight value.
+ +
+
+

+
+ template<typename L, typename R, typename LHash, typename RHash> +
+ const L& cubos::core::memory::UnorderedBimap<L, R, LHash, RHash>::atRight(const R& right) const +

+

Gets the left value associated to the given right value.

+ + + + + + + + + + + + + + + + +
Parameters
rightRight value.
ReturnsLeft value.
+ +
+
+

+
+ template<typename L, typename R, typename LHash, typename RHash> +
+ std::size_t cubos::core::memory::UnorderedBimap<L, R, LHash, RHash>::size() const +

+

Gets the number of entries in the map.

+ + + + + + + +
ReturnsEntry count.
+
+
+

+
+ template<typename L, typename R, typename LHash, typename RHash> +
+ bool cubos::core::memory::UnorderedBimap<L, R, LHash, RHash>::empty() const +

+

Checks if the map is empty.

+ + + + + + + +
ReturnsWhether the map is empty.
+
+
+

+
+ template<typename L, typename R, typename LHash, typename RHash> +
+ Iterator cubos::core::memory::UnorderedBimap<L, R, LHash, RHash>::begin() const +

+

Gets an iterator to the beginning of the map.

+ + + + + + + +
ReturnsIterator.
+
+
+

+
+ template<typename L, typename R, typename LHash, typename RHash> +
+ Iterator cubos::core::memory::UnorderedBimap<L, R, LHash, RHash>::end() const +

+

Gets an iterator to the end of the map.

+ + + + + + + +
ReturnsIterator.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1WriteGuard.html b/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1WriteGuard.html new file mode 100644 index 000000000..e9272a827 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1memory_1_1WriteGuard.html @@ -0,0 +1,326 @@ + + + + + cubos::core::memory::WriteGuard class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename T, typename Lock>
+ cubos::core::memory::WriteGuard class +

+

Provides safe read-write access to an object using a lock.

+ + + + + + + + + + + + + + +
Template parameters
TGuarded object type.
LockHeld lock type.
+ +

This class was created because there are multiple parts of the code that need to provide access to objects in a thread-safe manner.

Usage example

using AssetMetaWrite = core::memory::WriteGuard<AssetMeta, std::unique_lock<std::shared_mutex>>;
+
+

Constructors, destructors, conversion operators

+
+
+ WriteGuard(T& object, + Lock&& lock) +
+
Constructor.
+
+ WriteGuard(WriteGuard&& other) noexcept +
+
Move constructs.
+
+
+
+

Public functions

+
+
+ auto get() -> T& +
+
Gets a reference to the underlying object.
+
+ auto operator*() -> T& +
+
Gets a reference to the underlying object.
+
+ auto operator->() -> T* +
+
Gets a pointer to the underlying object.
+
+ auto get() const -> const T& +
+
Gets a reference to the underlying object.
+
+ auto operator*() const -> const T& +
+
Gets a reference to the underlying object.
+
+ auto operator->() const -> const T* +
+
Gets a pointer to the underlying object.
+
+
+
+

Function documentation

+
+

+
+ template<typename T, typename Lock> +
+ cubos::core::memory::WriteGuard<T, Lock>::WriteGuard(T& object, + Lock&& lock) +

+

Constructor.

+ + + + + + + + + + + + + + +
Parameters
objectObject to guard.
lockLock to hold.
+
+
+

+
+ template<typename T, typename Lock> +
+ cubos::core::memory::WriteGuard<T, Lock>::WriteGuard(WriteGuard&& other) noexcept +

+

Move constructs.

+ + + + + + + + + + +
Parameters
otherGuard to move from.
+
+
+

+
+ template<typename T, typename Lock> +
+ T& cubos::core::memory::WriteGuard<T, Lock>::get() +

+

Gets a reference to the underlying object.

+ + + + + + + +
ReturnsUnderlying object.
+
+
+

+
+ template<typename T, typename Lock> +
+ T& cubos::core::memory::WriteGuard<T, Lock>::operator*() +

+

Gets a reference to the underlying object.

+ + + + + + + +
ReturnsUnderlying object.
+
+
+

+
+ template<typename T, typename Lock> +
+ T* cubos::core::memory::WriteGuard<T, Lock>::operator->() +

+

Gets a pointer to the underlying object.

+ + + + + + + +
ReturnsUnderlying object.
+
+
+

+
+ template<typename T, typename Lock> +
+ const T& cubos::core::memory::WriteGuard<T, Lock>::get() const +

+

Gets a reference to the underlying object.

+ + + + + + + +
ReturnsUnderlying object.
+
+
+

+
+ template<typename T, typename Lock> +
+ const T& cubos::core::memory::WriteGuard<T, Lock>::operator*() const +

+

Gets a reference to the underlying object.

+ + + + + + + +
ReturnsUnderlying object.
+
+
+

+
+ template<typename T, typename Lock> +
+ const T* cubos::core::memory::WriteGuard<T, Lock>::operator->() const +

+

Gets a pointer to the underlying object.

+ + + + + + + +
ReturnsUnderlying object.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1ArrayTrait.html b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1ArrayTrait.html new file mode 100644 index 000000000..3497d9aae --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1ArrayTrait.html @@ -0,0 +1,438 @@ + + + + + cubos::core::reflection::ArrayTrait class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::reflection::ArrayTrait class final + +

+

Exposes array-like functionality of a type.

+ + +
+

Public types

+
+
+ using Length = std::size_t(*)(const void*instance) +
+
Function pointer to get the length of an array instance.
+
+ using AddressOf = uintptr_t(*)(const void*instance, std::size_t index) +
+
Function pointer to get the address of an element in an array instance.
+
+ using InsertDefault = void(*)(void*instance, std::size_t index) +
+
Function pointer to insert a default value into the array.
+
+ using InsertCopy = void(*)(void*instance, std::size_t index, const void*value) +
+
Function pointer to insert a copy of the given value into the array.
+
+ using InsertMove = void(*)(void*instance, std::size_t index, void*value) +
+
Function pointer to move the given value into the array.
+
+ using Erase = void(*)(void*instance, std::size_t index) +
+
Function pointer to remove an element of the array.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ ArrayTrait(const Type& elementType, + Length length, + AddressOf addressOf) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ void setInsertDefault(InsertDefault insertDefault) +
+
Sets the default-construct insert operation to the trait.
+
+ void setInsertCopy(InsertCopy insertCopy) +
+
Sets the copy-construct insert operation to the trait.
+
+ void setInsertMove(InsertMove insertMove) +
+
Sets the move-construct insert operation to the trait.
+
+ void setErase(Erase erase) +
+
Sets the erase operation to the trait.
+
+ auto hasInsertDefault() const -> bool +
+
Checks if default-construct insert is supported.
+
+ auto hasInsertCopy() const -> bool +
+
Checks if copy-construct insert is supported.
+
+ auto hasInsertMove() const -> bool +
+
Checks if move-construct insert is supported.
+
+ auto hasErase() const -> bool +
+
Checks if erase is supported.
+
+ auto hasResize() const -> bool +
+
Checks if resize is supported.
+
+ auto elementType() const -> const Type& +
+
Returns the element type of the array.
+
+ auto view(void* instance) const -> View +
+
Returns a view of the given array instance.
+
+ auto view(const void* instance) const -> ConstView +
+
Returns a view of the given array instance.
+
+
+
+

Function documentation

+
+

+ cubos::core::reflection::ArrayTrait::ArrayTrait(const Type& elementType, + Length length, + AddressOf addressOf) +

+

Constructs.

+ + + + + + + + + + + + + + + + + + +
Parameters
elementType
lengthFunction used to get the length of an array.
addressOfFunction used to address an element in an array.
+
+
+

+ void cubos::core::reflection::ArrayTrait::setInsertDefault(InsertDefault insertDefault) +

+

Sets the default-construct insert operation to the trait.

+ + + + + + + + + + +
Parameters
insertDefaultFunction pointer.
+
+
+

+ void cubos::core::reflection::ArrayTrait::setInsertCopy(InsertCopy insertCopy) +

+

Sets the copy-construct insert operation to the trait.

+ + + + + + + + + + +
Parameters
insertCopyFunction pointer.
+
+
+

+ void cubos::core::reflection::ArrayTrait::setInsertMove(InsertMove insertMove) +

+

Sets the move-construct insert operation to the trait.

+ + + + + + + + + + +
Parameters
insertMoveFunction pointer.
+
+
+

+ void cubos::core::reflection::ArrayTrait::setErase(Erase erase) +

+

Sets the erase operation to the trait.

+ + + + + + + + + + +
Parameters
eraseFunction pointer.
+
+
+

+ bool cubos::core::reflection::ArrayTrait::hasInsertDefault() const +

+

Checks if default-construct insert is supported.

+ + + + + + + +
ReturnsWhether the operation is supported.
+
+
+

+ bool cubos::core::reflection::ArrayTrait::hasInsertCopy() const +

+

Checks if copy-construct insert is supported.

+ + + + + + + +
ReturnsWhether the operation is supported.
+
+
+

+ bool cubos::core::reflection::ArrayTrait::hasInsertMove() const +

+

Checks if move-construct insert is supported.

+ + + + + + + +
ReturnsWhether the operation is supported.
+
+
+

+ bool cubos::core::reflection::ArrayTrait::hasErase() const +

+

Checks if erase is supported.

+ + + + + + + +
ReturnsWhether the operation is supported.
+
+
+

+ bool cubos::core::reflection::ArrayTrait::hasResize() const +

+

Checks if resize is supported.

+ + + + + + + +
ReturnsWhether the operation is supported.
+
+
+

+ const Type& cubos::core::reflection::ArrayTrait::elementType() const +

+

Returns the element type of the array.

+ + + + + + + +
ReturnsElement type.
+
+
+

+ View cubos::core::reflection::ArrayTrait::view(void* instance) const +

+

Returns a view of the given array instance.

+ + + + + + + + + + + + + + + + +
Parameters
instanceArray instance.
ReturnsArray view.
+
+
+

+ ConstView cubos::core::reflection::ArrayTrait::view(const void* instance) const +

+

Returns a view of the given array instance.

+ + + + + + + + + + + + + + + + +
Parameters
instanceArray instance.
ReturnsArray view.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1ConstructibleTrait.html b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1ConstructibleTrait.html new file mode 100644 index 000000000..f32aab59c --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1ConstructibleTrait.html @@ -0,0 +1,499 @@ + + + + + cubos::core::reflection::ConstructibleTrait class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::reflection::ConstructibleTrait class + +

+

Describes how a reflected type may be constructed and destructed.

+ + +
+

Public types

+
+
+
template<typename T>
+ class Builder +
+
Builder for ConstructibleTrait.
+
+ using Destructor = void(*)(void*instance) +
+
Function pointer to the destructor of a type.
+
+ using DefaultConstructor = void(*)(void*instance) +
+
Function pointer to the default constructor of a type.
+
+ using CopyConstructor = void(*)(void*instance, const void*other) +
+
Function pointer to the copy constructor of a type.
+
+ using MoveConstructor = void(*)(void*instance, void*other) +
+
Function pointer to the move constructor of a type.
+
+
+
+

Public static functions

+
+
+
template<typename T>
+ static auto typed() -> Builder<T> +
+
Returns a trait builder for the given type.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ ConstructibleTrait(std::size_t size, + std::size_t alignment, + void(*)(void*) destructor) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ auto withDefaultConstructor(DefaultConstructor defaultConstructor) && -> ConstructibleTrait&& +
+
Sets the default constructor of the type.
+
+ auto withCopyConstructor(CopyConstructor copyConstructor) && -> ConstructibleTrait&& +
+
Sets the copy constructor of the type.
+
+ auto withMoveConstructor(MoveConstructor moveConstructor) && -> ConstructibleTrait&& +
+
Sets the move constructor of the type.
+
+ auto size() const -> std::size_t +
+
Returns the size of the type in bytes.
+
+ auto alignment() const -> std::size_t +
+
Returns the alignment of the type in bytes.
+
+ auto hasDefaultConstruct() const -> bool +
+
Checks if default construction is supported.
+
+ auto hasCopyConstruct() const -> bool +
+
Checks if copy construction is supported.
+
+ auto hasMoveConstruct() const -> bool +
+
Checks if move construction is supported.
+
+ void destruct(void* instance) const +
+
Destructs an instance of the type.
+
+ void defaultConstruct(void* instance) const +
+
Default constructs an instance of the type.
+
+ void copyConstruct(void* instance, + const void* other) const +
+
Copy constructs an instance of the type.
+
+ void moveConstruct(void* instance, + void* other) const +
+
Move constructs an instance of the type.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ static Builder<T> cubos::core::reflection::ConstructibleTrait::typed() +

+

Returns a trait builder for the given type.

+ + + + + + + + + + + + + + + + +
Template parameters
TType to build a trait for.
ReturnsTrait builder.
+
+
+

+ cubos::core::reflection::ConstructibleTrait::ConstructibleTrait(std::size_t size, + std::size_t alignment, + void(*)(void*) destructor) +

+

Constructs.

+ + + + + + + + + + + + + + + + + + +
Parameters
sizeSize of the type in bytes.
alignmentAlignment of the type in bytes (must be a power of two).
destructorFunction pointer to the destructor of the type.
+
+
+

+ ConstructibleTrait&& cubos::core::reflection::ConstructibleTrait::withDefaultConstructor(DefaultConstructor defaultConstructor) && +

+

Sets the default constructor of the type.

+ + + + + + + + + + + + + + + + +
Parameters
defaultConstructorFunction pointer to the default constructor of the type.
ReturnsTrait.
+

Aborts if the default constructor has already been set.

+
+
+

+ ConstructibleTrait&& cubos::core::reflection::ConstructibleTrait::withCopyConstructor(CopyConstructor copyConstructor) && +

+

Sets the copy constructor of the type.

+ + + + + + + + + + + + + + + + +
Parameters
copyConstructorFunction pointer to the copy constructor of the type.
ReturnsTrait.
+

Aborts if the copy constructor has already been set.

+
+
+

+ ConstructibleTrait&& cubos::core::reflection::ConstructibleTrait::withMoveConstructor(MoveConstructor moveConstructor) && +

+

Sets the move constructor of the type.

+ + + + + + + + + + + + + + + + +
Parameters
moveConstructorFunction pointer to the move constructor of the type.
ReturnsTrait.
+

Aborts if the copy constructor has already been set.

+
+
+

+ std::size_t cubos::core::reflection::ConstructibleTrait::size() const +

+

Returns the size of the type in bytes.

+ + + + + + + +
ReturnsSize of the type in bytes.
+
+
+

+ std::size_t cubos::core::reflection::ConstructibleTrait::alignment() const +

+

Returns the alignment of the type in bytes.

+ + + + + + + +
ReturnsAlignment of the type in bytes.
+
+
+

+ bool cubos::core::reflection::ConstructibleTrait::hasDefaultConstruct() const +

+

Checks if default construction is supported.

+ + + + + + + +
ReturnsWhether the operation is supported.
+
+
+

+ bool cubos::core::reflection::ConstructibleTrait::hasCopyConstruct() const +

+

Checks if copy construction is supported.

+ + + + + + + +
ReturnsWhether the operation is supported.
+
+
+

+ bool cubos::core::reflection::ConstructibleTrait::hasMoveConstruct() const +

+

Checks if move construction is supported.

+ + + + + + + +
ReturnsWhether the operation is supported.
+
+
+

+ void cubos::core::reflection::ConstructibleTrait::destruct(void* instance) const +

+

Destructs an instance of the type.

+ + + + + + + + + + +
Parameters
instancePointer to the instance to destruct.
+
+
+

+ void cubos::core::reflection::ConstructibleTrait::defaultConstruct(void* instance) const +

+

Default constructs an instance of the type.

+ + + + + + + + + + +
Parameters
instancePointer to the location to construct the instance at.
+ +
+
+

+ void cubos::core::reflection::ConstructibleTrait::copyConstruct(void* instance, + const void* other) const +

+

Copy constructs an instance of the type.

+ + + + + + + + + + + + + + +
Parameters
instancePointer to the location to construct the instance at.
otherPointer to the instance to copy construct from.
+ +
+
+

+ void cubos::core::reflection::ConstructibleTrait::moveConstruct(void* instance, + void* other) const +

+

Move constructs an instance of the type.

+ + + + + + + + + + + + + + +
Parameters
instancePointer to the location to construct the instance at.
otherPointer to the instance to move construct from.
+ +
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1ConstructibleTrait_1_1Builder.html b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1ConstructibleTrait_1_1Builder.html new file mode 100644 index 000000000..234128602 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1ConstructibleTrait_1_1Builder.html @@ -0,0 +1,238 @@ + + + + + cubos::core::reflection::ConstructibleTrait::Builder class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::reflection::ConstructibleTrait::Builder class +

+

Builder for ConstructibleTrait.

+ +
+

Constructors, destructors, conversion operators

+
+
+ Builder() +
+
Constructs.
+
+
+
+

Public functions

+
+
+ auto build() && -> ConstructibleTrait +
+
Returns the constructed trait.
+
+ auto withDefaultConstructor() && -> Builder&& +
+
Sets the default constructor of the type.
+
+ auto withCopyConstructor() && -> Builder&& +
+
Sets the copy constructor of the type.
+
+ auto withMoveConstructor() && -> Builder&& +
+
Sets the move constructor of the type.
+
+ auto withBasicConstructors() && -> Builder&& +
+
Sets the default, copy and move constructors of the type.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ ConstructibleTrait cubos::core::reflection::ConstructibleTrait::Builder<T>::build() && +

+

Returns the constructed trait.

+ + + + + + + +
ReturnsConstructed trait.
+
+
+

+
+ template<typename T> +
+ Builder&& cubos::core::reflection::ConstructibleTrait::Builder<T>::withDefaultConstructor() && +

+

Sets the default constructor of the type.

+ + + + + + + +
ReturnsBuilder.
+
+
+

+
+ template<typename T> +
+ Builder&& cubos::core::reflection::ConstructibleTrait::Builder<T>::withCopyConstructor() && +

+

Sets the copy constructor of the type.

+ + + + + + + +
ReturnsBuilder.
+
+
+

+
+ template<typename T> +
+ Builder&& cubos::core::reflection::ConstructibleTrait::Builder<T>::withMoveConstructor() && +

+

Sets the move constructor of the type.

+ + + + + + + +
ReturnsBuilder.
+
+
+

+
+ template<typename T> +
+ Builder&& cubos::core::reflection::ConstructibleTrait::Builder<T>::withBasicConstructors() && +

+

Sets the default, copy and move constructors of the type.

+ + + + + + + +
ReturnsBuilder.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1DictionaryTrait.html b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1DictionaryTrait.html new file mode 100644 index 000000000..a696ed4e4 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1DictionaryTrait.html @@ -0,0 +1,494 @@ + + + + + cubos::core::reflection::DictionaryTrait class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::reflection::DictionaryTrait class final + +

+

Exposes dictionary-like functionality of a type.

+ + +
+

Public types

+
+
+ using Length = std::size_t(*)(const void*instance) +
+
Function pointer to get the length of a dictionary instance.
+
+ using Begin = void*(*)(uintptr_t instance, bool writeable) +
+
Function pointer to get an iterator to the first key-value pair of a dictionary instance.
+
+ using Find = void*(*)(uintptr_t instance, const void*key, bool writeable) +
+
Function pointer to get an iterator to a value in an dictionary instance.
+
+ using Advance = bool(*)(uintptr_t instance, void*iterator, bool writeable) +
+
Function pointer to advance an iterator.
+
+ using Stop = void(*)(void*iterator, bool writeable) +
+
Function pointer to destroy an iterator instance.
+
+ using Key = const void*(*)(const void*iterator, bool writeable) +
+
Function pointer to get the address of the key pointed to by an iterator.
+
+ using Value = uintptr_t(*)(const void*iterator, bool writeable) +
+
Function pointer to get the address of the value pointed to by an iterator.
+
+ using InsertDefault = void(*)(void*instance, const void*key) +
+
Function pointer to insert a default value into a dictionary instance.
+
+ using InsertCopy = void(*)(void*instance, const void*key, const void*value) +
+
Function pointer to insert a copy of the given value into a dictionary instance.
+
+ using InsertMove = void(*)(void*instance, const void*key, void*value) +
+
Function pointer to move the given value into a dictionary instance.
+
+ using Erase = void(*)(void*instance, const void*iterator) +
+
Function pointer to remove a key-value pair of a dictionary instance.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ DictionaryTrait(const Type& keyType, + const Type& valueType, + Length length, + Begin begin, + Find find, + Advance advance, + Stop stop, + Key key, + Value value) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ void setInsertDefault(InsertDefault insertDefault) +
+
Sets the default-construct insert operation of the trait.
+
+ void setInsertCopy(InsertCopy insertCopy) +
+
Sets the copy-construct insert operation of the trait.
+
+ void setInsertMove(InsertMove insertMove) +
+
Sets the move-construct insert operation of the trait.
+
+ void setErase(Erase erase) +
+
Sets the erase operation of the trait.
+
+ auto hasInsertDefault() const -> bool +
+
Checks if default-construct insert is supported.
+
+ auto hasInsertCopy() const -> bool +
+
Checks if copy-construct insert is supported.
+
+ auto hasInsertMove() const -> bool +
+
Checks if move-construct insert is supported.
+
+ auto hasErase() const -> bool +
+
Checks if erase is supported.
+
+ auto keyType() const -> const Type& +
+
Returns the key type of the dictionary.
+
+ auto valueType() const -> const Type& +
+
Returns the value type of the dictionary.
+
+ auto view(void* instance) const -> View +
+
Returns a view of the given dictionary instance.
+
+ auto view(const void* instance) const -> ConstView +
+
Returns a view of the given dictionary instance.
+
+
+
+

Function documentation

+
+

+ cubos::core::reflection::DictionaryTrait::DictionaryTrait(const Type& keyType, + const Type& valueType, + Length length, + Begin begin, + Find find, + Advance advance, + Stop stop, + Key key, + Value value) +

+

Constructs.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
keyTypeKey type of the dictionary.
valueTypeValue type of the dictionary.
lengthFunction used to get the length of a dictionary.
beginFunction used to get an iterator to the first key-value pair of a
findFunction used to find a key-value pair in a dictionary.
advanceFunction used to advance an iterator.
stopFunction used to destroy an iterator.
keyFunction used to get the address of the key pointed to by an iterator.
valueFunction used to get the address of the value pointed to by an iterator.
+
+
+

+ void cubos::core::reflection::DictionaryTrait::setInsertDefault(InsertDefault insertDefault) +

+

Sets the default-construct insert operation of the trait.

+ + + + + + + + + + +
Parameters
insertDefaultFunction pointer.
+
+
+

+ void cubos::core::reflection::DictionaryTrait::setInsertCopy(InsertCopy insertCopy) +

+

Sets the copy-construct insert operation of the trait.

+ + + + + + + + + + +
Parameters
insertCopyFunction pointer.
+
+
+

+ void cubos::core::reflection::DictionaryTrait::setInsertMove(InsertMove insertMove) +

+

Sets the move-construct insert operation of the trait.

+ + + + + + + + + + +
Parameters
insertMoveFunction pointer.
+
+
+

+ void cubos::core::reflection::DictionaryTrait::setErase(Erase erase) +

+

Sets the erase operation of the trait.

+ + + + + + + + + + +
Parameters
eraseFunction pointer.
+
+
+

+ bool cubos::core::reflection::DictionaryTrait::hasInsertDefault() const +

+

Checks if default-construct insert is supported.

+ + + + + + + +
ReturnsWhether the operation is supported.
+
+
+

+ bool cubos::core::reflection::DictionaryTrait::hasInsertCopy() const +

+

Checks if copy-construct insert is supported.

+ + + + + + + +
ReturnsWhether the operation is supported.
+
+
+

+ bool cubos::core::reflection::DictionaryTrait::hasInsertMove() const +

+

Checks if move-construct insert is supported.

+ + + + + + + +
ReturnsWhether the operation is supported.
+
+
+

+ bool cubos::core::reflection::DictionaryTrait::hasErase() const +

+

Checks if erase is supported.

+ + + + + + + +
ReturnsWhether the operation is supported.
+
+
+

+ const Type& cubos::core::reflection::DictionaryTrait::keyType() const +

+

Returns the key type of the dictionary.

+ + + + + + + +
ReturnsKey type.
+
+
+

+ const Type& cubos::core::reflection::DictionaryTrait::valueType() const +

+

Returns the value type of the dictionary.

+ + + + + + + +
ReturnsValue type.
+
+
+

+ View cubos::core::reflection::DictionaryTrait::view(void* instance) const +

+

Returns a view of the given dictionary instance.

+ + + + + + + + + + + + + + + + +
Parameters
instanceDictionary instance.
ReturnsDictionary view.
+
+
+

+ ConstView cubos::core::reflection::DictionaryTrait::view(const void* instance) const +

+

Returns a view of the given dictionary instance.

+ + + + + + + + + + + + + + + + +
Parameters
instanceDictionary instance.
ReturnsDictionary view.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1EnumTrait.html b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1EnumTrait.html new file mode 100644 index 000000000..2816cb634 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1EnumTrait.html @@ -0,0 +1,490 @@ + + + + + cubos::core::reflection::EnumTrait class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::reflection::EnumTrait class + +

+

Provides enumeration functionality to an enumerated type.

+ + +
+

Public types

+
+
+ using Tester = bool(*)(const void*instance) +
+
Function pointer to test if a value matches the variant.
+
+ using Setter = void(*)(void*instance) +
+
Function pointer to set the value of the variant.
+
+
+
+

Public static functions

+
+
+
template<typename T>
+ static auto toString(const T& value) -> const std::string& +
+
Converts an enumeration value to its string representation.
+
+
template<typename T>
+ static auto fromString(T& value, + const std::string& str) -> bool +
+
Converts a string to a value of a specified type.
+
+ static auto end() -> Iterator +
+
Gets an iterator to the last variant of the type.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ EnumTrait() defaulted +
+
Constructs.
+
+ EnumTrait(EnumTrait&& other) noexcept +
+
Move constructs.
+
+
+
+

Public functions

+
+
+ void addVariant(std::string name, + Tester tester, + Setter setter) +
+
Adds a variant to the type.
+
+ auto withVariant(std::string name, + Tester tester, + Setter setter) && -> EnumTrait&& +
+
Adds a variant to the type.
+
+
template<auto V>
+ auto withVariant(std::string name) && -> EnumTrait&& +
+
Adds a variant to the type.
+
+ auto contains(const std::string& name) const -> bool +
+
Checks if a variant with the given name exists.
+
+ auto at(const std::string& name) const -> const Variant& +
+
Gets the variant with the specified name.
+
+ auto variant(const void* value) const -> const Variant& +
+
Gets the variant associated with the given value.
+
+ auto begin() const -> Iterator +
+
Gets an iterator to the first variant of the type.
+
+ auto size() const -> std::size_t +
+
Returns how many enum variants there are in the trait.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ static const std::string& cubos::core::reflection::EnumTrait::toString(const T& value) +

+

Converts an enumeration value to its string representation.

+ + + + + + + + + + + + + + + + +
Parameters
valueEnumeration value to be converted.
ReturnsString representation.
+
+
+

+
+ template<typename T> +
+ static bool cubos::core::reflection::EnumTrait::fromString(T& value, + const std::string& str) +

+

Converts a string to a value of a specified type.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
value in/outVariable to store the converted value.
strString to be converted to the specified value type.
ReturnsWhether the conversion was successful, false otherwise.
+
+
+

+ static Iterator cubos::core::reflection::EnumTrait::end() +

+

Gets an iterator to the last variant of the type.

+ + + + + + + +
ReturnsIterator.
+
+
+

+ cubos::core::reflection::EnumTrait::EnumTrait(EnumTrait&& other) noexcept +

+

Move constructs.

+ + + + + + + + + + +
Parameters
otherOther trait.
+
+
+

+ void cubos::core::reflection::EnumTrait::addVariant(std::string name, + Tester tester, + Setter setter) +

+

Adds a variant to the type.

+ + + + + + + + + + + + + + + + + + +
Parameters
nameVariant name.
testerFunction to test if a value matches the variant.
setterFunction to set the value of the variant.
+
+
+

+ EnumTrait&& cubos::core::reflection::EnumTrait::withVariant(std::string name, + Tester tester, + Setter setter) && +

+

Adds a variant to the type.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
nameVariant name.
testerFunction to test if a value matches the variant.
setterFunction to set the value of the variant.
ReturnsTrait.
+
+
+

+
+ template<auto V> +
+ EnumTrait&& cubos::core::reflection::EnumTrait::withVariant(std::string name) && +

+

Adds a variant to the type.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
VEnumeration value.
Parameters
nameVariant name.
ReturnsTrait.
+
+
+

+ bool cubos::core::reflection::EnumTrait::contains(const std::string& name) const +

+

Checks if a variant with the given name exists.

+ + + + + + + + + + + + + + + + +
Parameters
nameVariant name.
ReturnsWhether the variant exists.
+
+
+

+ const Variant& cubos::core::reflection::EnumTrait::at(const std::string& name) const +

+

Gets the variant with the specified name.

+ + + + + + + + + + + + + + + + +
Parameters
nameVariant name.
ReturnsReference.
+ +
+
+

+ const Variant& cubos::core::reflection::EnumTrait::variant(const void* value) const +

+

Gets the variant associated with the given value.

+ + + + + + + + + + + + + + + + +
Parameters
valuePointer to the value for which to retrieve the variant.
ReturnsReference.
+
+
+

+ Iterator cubos::core::reflection::EnumTrait::begin() const +

+

Gets an iterator to the first variant of the type.

+ + + + + + + +
ReturnsIterator.
+
+
+

+ std::size_t cubos::core::reflection::EnumTrait::size() const +

+

Returns how many enum variants there are in the trait.

+ + + + + + + +
ReturnsVariant count.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1FieldsTrait.html b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1FieldsTrait.html new file mode 100644 index 000000000..7a747529b --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1FieldsTrait.html @@ -0,0 +1,472 @@ + + + + + cubos::core::reflection::FieldsTrait class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::reflection::FieldsTrait class + +

+

Describes the fields of a reflected type.

+ + +
+

Public types

+
+
+
template<typename O, typename F>
+ class AddressOfImpl +
+
Implementation of AddressOf for a pointer to member.
+
+
+
+

Public static functions

+
+
+ static auto end() -> Iterator +
+
Gets an iterator which represents the end of the field list of a type.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ FieldsTrait() defaulted +
+
Constructs.
+
+ FieldsTrait(FieldsTrait&& other) noexcept +
+
Move constructs.
+
+
+
+

Public functions

+
+
+ void addField(const Type& type, + std::string name, + AddressOf* addressOf) +
+
Adds a field to the type. The getter will be deleted using delete and thus must be allocated using new.
+
+ auto withField(const Type& type, + std::string name, + AddressOf* addressOf) && -> FieldsTrait&& +
+
Adds a field to the type. The getter will be deleted using delete and thus must be allocated using new.
+
+
template<typename O, typename F>
+ void addField(std::string name, + F O::* pointer) +
+
Adds a field to the type.
+
+
template<typename O, typename F>
+ auto withField(std::string name, + F O::* pointer) && -> FieldsTrait&& +
+
Adds a field to the type.
+
+ auto field(const std::string& name) const -> const Field* +
+
Gets the field with the given name.
+
+ auto begin() const -> Iterator +
+
Gets an iterator to the first field of the type.
+
+ auto size() const -> std::size_t +
+
Returns how many fields there are in the trait.
+
+ auto view(void* instance) const -> View +
+
Returns a view of the given object instance.
+
+ auto view(const void* instance) const -> ConstView +
+
Returns a view of the given object instance.
+
+
+
+

Function documentation

+
+

+ static Iterator cubos::core::reflection::FieldsTrait::end() +

+

Gets an iterator which represents the end of the field list of a type.

+ + + + + + + +
ReturnsIterator.
+
+
+

+ cubos::core::reflection::FieldsTrait::FieldsTrait(FieldsTrait&& other) noexcept +

+

Move constructs.

+ + + + + + + + + + +
Parameters
otherOther trait.
+
+
+

+ void cubos::core::reflection::FieldsTrait::addField(const Type& type, + std::string name, + AddressOf* addressOf) +

+

Adds a field to the type. The getter will be deleted using delete and thus must be allocated using new.

+ + + + + + + + + + + + + + + + + + +
Parameters
typeField type.
nameField name.
addressOfGetter for the address of the field on a given instance.
+
+
+

+ FieldsTrait&& cubos::core::reflection::FieldsTrait::withField(const Type& type, + std::string name, + AddressOf* addressOf) && +

+

Adds a field to the type. The getter will be deleted using delete and thus must be allocated using new.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
typeField type.
nameField name.
addressOfGetter for the address of the field on a given instance.
ReturnsTrait.
+
+
+

+
+ template<typename O, typename F> +
+ void cubos::core::reflection::FieldsTrait::addField(std::string name, + F O::* pointer) +

+

Adds a field to the type.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
OObject type.
FField type.
Parameters
nameField name.
pointerField pointer.
+
+
+

+
+ template<typename O, typename F> +
+ FieldsTrait&& cubos::core::reflection::FieldsTrait::withField(std::string name, + F O::* pointer) && +

+

Adds a field to the type.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
OObject type.
FField type.
Parameters
nameField name.
pointerField pointer.
ReturnsTrait.
+
+
+

+ const Field* cubos::core::reflection::FieldsTrait::field(const std::string& name) const +

+

Gets the field with the given name.

+ + + + + + + + + + + + + + + + +
Parameters
nameField name.
ReturnsField with the given name, or null if no such field exists.
+
+
+

+ Iterator cubos::core::reflection::FieldsTrait::begin() const +

+

Gets an iterator to the first field of the type.

+ + + + + + + +
ReturnsIterator.
+
+
+

+ std::size_t cubos::core::reflection::FieldsTrait::size() const +

+

Returns how many fields there are in the trait.

+ + + + + + + +
ReturnsField count.
+
+
+

+ View cubos::core::reflection::FieldsTrait::view(void* instance) const +

+

Returns a view of the given object instance.

+ + + + + + + + + + + + + + + + +
Parameters
instanceObject instance.
ReturnsObject view.
+
+
+

+ ConstView cubos::core::reflection::FieldsTrait::view(const void* instance) const +

+

Returns a view of the given object instance.

+ + + + + + + + + + + + + + + + +
Parameters
instanceObject instance.
ReturnsObject view.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1FieldsTrait_1_1AddressOfImpl.html b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1FieldsTrait_1_1AddressOfImpl.html new file mode 100644 index 000000000..a32b5e189 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1FieldsTrait_1_1AddressOfImpl.html @@ -0,0 +1,198 @@ + + + + + cubos::core::reflection::FieldsTrait::AddressOfImpl class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename O, typename F>
+ cubos::core::reflection::FieldsTrait::AddressOfImpl class +

+

Implementation of AddressOf for a pointer to member.

+ + + + + + + + + + + + + + +
Template parameters
OObject type.
FField type.
+ +
+

Constructors, destructors, conversion operators

+
+
+ AddressOfImpl(F O::* pointer) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ auto get(const void* instance) const -> uintptr_t override +
+
Gets the address of the field on a given instance.
+
+
+
+

Function documentation

+
+

+
+ template<typename O, typename F> +
+ cubos::core::reflection::FieldsTrait::AddressOfImpl<O, F>::AddressOfImpl(F O::* pointer) +

+

Constructs.

+ + + + + + + + + + +
Parameters
pointerPointer to member.
+
+
+

+
+ template<typename O, typename F> +
+ uintptr_t cubos::core::reflection::FieldsTrait::AddressOfImpl<O, F>::get(const void* instance) const override +

+

Gets the address of the field on a given instance.

+ + + + + + + + + + + + + + + + +
Parameters
instancePointer to the instance.
ReturnsAddress of the field on the given instance.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1MaskTrait.html b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1MaskTrait.html new file mode 100644 index 000000000..e9de15f5f --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1MaskTrait.html @@ -0,0 +1,466 @@ + + + + + cubos::core::reflection::MaskTrait class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::reflection::MaskTrait class + +

+

Provides mask functionality to an enum mask type.

+ + +
+

Public types

+
+
+ using Tester = bool(*)(const void*instance) +
+
Function pointer to test if a bit is set on the mask.
+
+ using Setter = void(*)(void*instance) +
+
Function pointer to set the bit on the mask.
+
+ using Clearer = void(*)(void*instance) +
+
Function pointer to clear the bit on the mask.
+
+
+
+

Public static functions

+
+
+ static auto end() -> Iterator +
+
Gets an iterator to the last bit of the type.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ MaskTrait() defaulted +
+
Constructs.
+
+ MaskTrait(MaskTrait&& other) noexcept +
+
Move constructs.
+
+
+
+

Public functions

+
+
+ void addBit(std::string name, + Tester tester, + Setter setter, + Clearer clearer) +
+
Adds a bit to the type.
+
+ auto withBit(std::string name, + Tester tester, + Setter setter, + Clearer clearer) && -> MaskTrait&& +
+
Adds a bit to the type.
+
+
template<auto B>
+ auto withBit(std::string name) && -> MaskTrait&& +
+
Adds a bit to the type.
+
+ auto contains(const std::string& name) const -> bool +
+
Checks if a bit with the given name exists.
+
+ auto at(const std::string& name) const -> const Bit& +
+
Gets the bit with the specified name.
+
+ auto begin() const -> Iterator +
+
Gets an iterator to the first bit of the type.
+
+ auto size() const -> std::size_t +
+
Returns how many bits there are in the trait.
+
+ auto view(void* instance) const -> View +
+
Returns a view of the given mask instance.
+
+ auto view(const void* instance) const -> ConstView +
+
Returns a view of the given mask instance.
+
+
+
+

Function documentation

+
+

+ static Iterator cubos::core::reflection::MaskTrait::end() +

+

Gets an iterator to the last bit of the type.

+ + + + + + + +
ReturnsIterator.
+
+
+

+ cubos::core::reflection::MaskTrait::MaskTrait(MaskTrait&& other) noexcept +

+

Move constructs.

+ + + + + + + + + + +
Parameters
otherOther trait.
+
+
+

+ void cubos::core::reflection::MaskTrait::addBit(std::string name, + Tester tester, + Setter setter, + Clearer clearer) +

+

Adds a bit to the type.

+ + + + + + + + + + + + + + + + + + + + + + +
Parameters
nameBit name.
testerFunction to test if a bit is set on the mask.
setterFunction to set a bit on the mask.
clearerFunction to clear a bit on the mask.
+
+
+

+ MaskTrait&& cubos::core::reflection::MaskTrait::withBit(std::string name, + Tester tester, + Setter setter, + Clearer clearer) && +

+

Adds a bit to the type.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
nameBit name.
testerFunction to test if a bit is set on the mask.
setterFunction to set a bit on the mask.
clearerFunction to clear a bit on the mask.
ReturnsTrait.
+
+
+

+
+ template<auto B> +
+ MaskTrait&& cubos::core::reflection::MaskTrait::withBit(std::string name) && +

+

Adds a bit to the type.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
BBit value.
Parameters
nameBit name.
ReturnsTrait.
+

The bit type must implement at least the operators '&', '|' and '~'.

+
+
+

+ bool cubos::core::reflection::MaskTrait::contains(const std::string& name) const +

+

Checks if a bit with the given name exists.

+ + + + + + + + + + + + + + + + +
Parameters
nameBit name.
ReturnsWhether the bit exists.
+
+
+

+ const Bit& cubos::core::reflection::MaskTrait::at(const std::string& name) const +

+

Gets the bit with the specified name.

+ + + + + + + + + + + + + + + + +
Parameters
nameBit name.
ReturnsReference.
+ +
+
+

+ Iterator cubos::core::reflection::MaskTrait::begin() const +

+

Gets an iterator to the first bit of the type.

+ + + + + + + +
ReturnsIterator.
+
+
+

+ std::size_t cubos::core::reflection::MaskTrait::size() const +

+

Returns how many bits there are in the trait.

+ + + + + + + +
ReturnsBit count.
+
+
+

+ View cubos::core::reflection::MaskTrait::view(void* instance) const +

+

Returns a view of the given mask instance.

+ + + + + + + + + + + + + + + + +
Parameters
instanceMask instance.
ReturnsMask view.
+
+
+

+ ConstView cubos::core::reflection::MaskTrait::view(const void* instance) const +

+

Returns a view of the given mask instance.

+ + + + + + + + + + + + + + + + +
Parameters
instanceMask instance.
ReturnsMask view.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1NullableTrait.html b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1NullableTrait.html new file mode 100644 index 000000000..80beaeec2 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1NullableTrait.html @@ -0,0 +1,218 @@ + + + + + cubos::core::reflection::NullableTrait class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::reflection::NullableTrait class + +

+

Used to manipulate values of null-representable types.

+ + +
+

Public types

+
+
+ using IsNull = bool(*)(const void*instance) +
+
Function pointer to check if a value represents null.
+
+ using SetToNull = void(*)(void*instance) +
+
Function pointer to set a value to its null representation.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ NullableTrait(IsNull isNull, + SetToNull setToNull) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ auto isNull(const void* instance) const -> bool +
+
Checks if the given value represents null.
+
+ void setToNull(void* instance) const +
+
Sets a value to its null representation.
+
+
+
+

Function documentation

+
+

+ cubos::core::reflection::NullableTrait::NullableTrait(IsNull isNull, + SetToNull setToNull) +

+

Constructs.

+ + + + + + + + + + + + + + +
Parameters
isNullIsNull.
setToNullSetToNull.
+
+
+

+ bool cubos::core::reflection::NullableTrait::isNull(const void* instance) const +

+

Checks if the given value represents null.

+ + + + + + + + + + + + + + + + +
Parameters
instanceInstance.
ReturnsWhether the value represents null.
+
+
+

+ void cubos::core::reflection::NullableTrait::setToNull(void* instance) const +

+

Sets a value to its null representation.

+ + + + + + + + + + +
Parameters
instanceInstance.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1StringConversionTrait.html b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1StringConversionTrait.html new file mode 100644 index 000000000..7241abb4f --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1StringConversionTrait.html @@ -0,0 +1,230 @@ + + + + + cubos::core::reflection::StringConversionTrait class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::reflection::StringConversionTrait class + +

+

Stores functions for converting a type to and from a string.

+ + +
+

Public types

+
+
+ using Into = std::string(*)(const void*instance) +
+
Function pointer to convert an instance of the type into a string.
+
+ using From = bool(*)(void*instance, const std::string&string) +
+
Function pointer to convert a string into an instance of the type.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ StringConversionTrait(Into into, + From from) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ auto into(const void* instance) const -> std::string +
+
Converts an instance of the type into a string.
+
+ auto from(void* instance, + const std::string& string) const -> bool +
+
Converts a string to an instance of the type.
+
+
+
+

Function documentation

+
+

+ cubos::core::reflection::StringConversionTrait::StringConversionTrait(Into into, + From from) +

+

Constructs.

+ + + + + + + + + + + + + + +
Parameters
intoInto.
fromFrom.
+
+
+

+ std::string cubos::core::reflection::StringConversionTrait::into(const void* instance) const +

+

Converts an instance of the type into a string.

+ + + + + + + + + + + + + + + + +
Parameters
instanceInstance.
ReturnsString.
+
+
+

+ bool cubos::core::reflection::StringConversionTrait::from(void* instance, + const std::string& string) const +

+

Converts a string to an instance of the type.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
instanceInstance.
stringString.
ReturnsWhether the string was valid.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1Type.html b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1Type.html new file mode 100644 index 000000000..f5306983d --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1Type.html @@ -0,0 +1,357 @@ + + + + + cubos::core::reflection::Type class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::reflection::Type class final + +

+

Describes a reflected type.

+ +

Holds the name of a type and the traits associated with it. Traits can be of any type, which means you can define your own custom traits.

+
+

Public static functions

+
+
+ static auto create(std::string name) -> Type& +
+
Constructs with a type the given name.
+
+ static void destroy(Type& type) +
+
Destroys the given type.
+
+
+
+

Public functions

+
+
+ auto name() const -> const std::string& +
+
Returns the name of the type.
+
+
template<typename T>
+ auto is() const -> bool +
+
Checks if this type represents the type T.
+
+
template<typename T>
+ auto with(T trait) -> Type& +
+
Adds the given trait to the type.
+
+
template<typename T>
+ auto has() const -> bool +
+
Returns whether the type has the given trait.
+
+
template<typename T>
+ auto get() const -> const T& +
+
Returns the given trait of the type.
+
+ auto operator==(const Type& other) const -> bool +
+
Equality operator.
+
+
+
+

Function documentation

+
+

+ static Type& cubos::core::reflection::Type::create(std::string name) +

+

Constructs with a type the given name.

+ + + + + + + + + + + + + + + + +
Parameters
nameName of the type.
ReturnsReference to the type.
+
+
+

+ static void cubos::core::reflection::Type::destroy(Type& type) +

+

Destroys the given type.

+ + + + + + + + + + +
Parameters
typeType to destroy.
+
+
+

+ const std::string& cubos::core::reflection::Type::name() const +

+

Returns the name of the type.

+ + + + + + + +
ReturnsName of the type.
+
+
+

+
+ template<typename T> +
+ bool cubos::core::reflection::Type::is() const +

+

Checks if this type represents the type T.

+ + + + + + + + + + + + + + + + +
Template parameters
TType to check.
ReturnsWhether this type represents the type T.
+
+
+

+
+ template<typename T> +
+ Type& cubos::core::reflection::Type::with(T trait) +

+

Adds the given trait to the type.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TTrait type.
Parameters
traitTrait value.
ReturnsReference to this type, for chaining.
+

Aborts if the trait is already present in the type.

+
+
+

+
+ template<typename T> +
+ bool cubos::core::reflection::Type::has() const +

+

Returns whether the type has the given trait.

+ + + + + + + + + + + + + + + + +
Template parameters
TTrait type.
ReturnsWhether the type has the given trait.
+
+
+

+
+ template<typename T> +
+ const T& cubos::core::reflection::Type::get() const +

+

Returns the given trait of the type.

+ + + + + + + + + + + + + + + + +
Template parameters
TTrait type.
ReturnsReference to the trait.
+

Aborts if the type does not have the given trait.

+
+
+

+ bool cubos::core::reflection::Type::operator==(const Type& other) const +

+

Equality operator.

+ + + + + + + + + + + + + + + + +
Parameters
otherType object to compare.
ReturnsWhether the objects have the same address, which indicates equality.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1TypeRegistry.html b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1TypeRegistry.html new file mode 100644 index 000000000..59a180a57 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1core_1_1reflection_1_1TypeRegistry.html @@ -0,0 +1,351 @@ + + + + + cubos::core::reflection::TypeRegistry class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::reflection::TypeRegistry class final + +

+

Stores a set of types which can be accessed by name.

+ +
+

Public functions

+
+
+ void insert(const Type& type) +
+
Registers the given type.
+
+ void insert(const TypeRegistry& other) +
+
Calls insert for each type in the given type registry.
+
+
template<Reflectable T>
+ void insert() +
+
Registers the given type.
+
+ auto contains(const Type& type) const -> bool +
+
Checks if the given type is registered.
+
+
template<Reflectable T>
+ auto contains() const -> bool +
+
+
+ auto contains(const std::string& name) const -> bool +
+
Checks if a type with the given name is registered.
+
+ auto at(const std::string& name) const -> const Type& +
+
Returns the type with the given name.
+
+ auto size() const -> std::size_t +
+
Returns the number of registered types.
+
+ auto begin() const -> Iterator +
+
Gets an iterator to the beginning of the registry.
+
+ auto end() const -> Iterator +
+
Gets an iterator to the end of the registry.
+
+
+
+

Function documentation

+
+

+ void cubos::core::reflection::TypeRegistry::insert(const Type& type) +

+

Registers the given type.

+ + + + + + + + + + +
Parameters
typeType to register.
+

Does nothing if the type is already registered. Aborts if a different type with the same name is already registered.

+
+
+

+ void cubos::core::reflection::TypeRegistry::insert(const TypeRegistry& other) +

+

Calls insert for each type in the given type registry.

+ + + + + + + + + + +
Parameters
otherType registry to copy types from.
+
+
+

+
+ template<Reflectable T> +
+ void cubos::core::reflection::TypeRegistry::insert() +

+

Registers the given type.

+ + + + + + + + + + +
Template parameters
TType to register.
+

Does nothing if the type is already registered. Aborts if a different type with the same name is already registered.

+
+
+

+ bool cubos::core::reflection::TypeRegistry::contains(const Type& type) const +

+

Checks if the given type is registered.

+ + + + + + + + + + + + + + + + +
Parameters
typeType to check.
ReturnsWhether the given type is registered.
+
+
+

+
+ template<Reflectable T> +
+ bool cubos::core::reflection::TypeRegistry::contains() const +

+ + + + + + + + + + +
Template parameters
TType to check.
+
+
+

+ bool cubos::core::reflection::TypeRegistry::contains(const std::string& name) const +

+

Checks if a type with the given name is registered.

+ + + + + + + + + + + + + + + + +
Parameters
nameName of the type.
ReturnsWhether a type with the given name is registered.
+
+
+

+ const Type& cubos::core::reflection::TypeRegistry::at(const std::string& name) const +

+

Returns the type with the given name.

+ + + + + + + + + + + + + + + + +
Parameters
nameName of the type.
ReturnsType with the given name.
+

Aborts if contains(const std::string&) returns false.

+
+
+

+ std::size_t cubos::core::reflection::TypeRegistry::size() const +

+

Returns the number of registered types.

+ + + + + + + +
ReturnsNumber of registered types.
+
+
+

+ Iterator cubos::core::reflection::TypeRegistry::begin() const +

+

Gets an iterator to the beginning of the registry.

+ + + + + + + +
ReturnsIterator.
+
+
+

+ Iterator cubos::core::reflection::TypeRegistry::end() const +

+

Gets an iterator to the end of the registry.

+ + + + + + + +
ReturnsIterator.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1AnyAsset.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1AnyAsset.html new file mode 100644 index 000000000..37ee5b449 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1AnyAsset.html @@ -0,0 +1,452 @@ + + + + + cubos::engine::AnyAsset class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::AnyAsset class + +

+

Handle to an asset of any type. May either be weak or strong. Weak handles do not guarantee the asset is loaded, while strong handles do.

+ +

Assets are identified by their UUID. This is a unique 128-bit number which is assigned to each asset when it is imported or created. Default constructed handles are null handles, which are not associated with any asset.

Serialization:

  • can be serialized or deserialized without context, i.e. the UUID is stored directly.
  • when deserialized, the handle is always a weak handle.
+
+

Derived classes

+
+
+
template<core::reflection::Reflectable T>
+ class Asset +
+
Handle to an asset of a specific type.
+
+
template<core::reflection::Reflectable T>
+ class Asset +
+
Handle to an asset of a specific type.
+
+
template<core::reflection::Reflectable T>
+ class Asset +
+
Handle to an asset of a specific type.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ AnyAsset(std::nullptr_t ptr = nullptr) +
+
Constructs a null handle.
+
+ AnyAsset(uuids::uuid id) +
+
Constructs a weak handle.
+
+ AnyAsset(std::string_view str) +
+
Constructs a weak handle. If the string is not a valid UUID, the handle will be null.
+
+ AnyAsset(const AnyAsset& other) +
+
Constructs a copy of the given handle.
+
+ AnyAsset(AnyAsset&& other) noexcept +
+
Constructs a handle from the given handle.
+
+
template<core::reflection::Reflectable T>
+ operator Asset<T>() const +
+
Converts this handle to a handle of a specific type.
+
+
+
+

Public functions

+
+
+ auto operator=(const AnyAsset& other) -> AnyAsset& +
+
Overwrites this handle with a copy of the given handle.
+
+ auto operator=(AnyAsset&& other) -> AnyAsset& noexcept +
+
Overwrites this handle with the given handle.
+
+ auto operator==(const AnyAsset& other) const -> bool +
+
Equality operator for comparing two AnyAsset objects.
+
+ auto getVersion() const -> int +
+
Gets the version of the asset last seen by this handle.
+
+ auto getId() const -> uuids::uuid +
+
Gets the UUID of the asset.
+
+ auto isNull() const -> bool +
+
Checks if the handle is null.
+
+ auto isStrong() const -> bool +
+
Checks if the handle is strong.
+
+ void makeWeak() +
+
Makes this handle a weak handle, decreasing the asset's reference count if it was strong.
+
+
+
+

Public variables

+
+
+ uuids::uuid reflectedId +
+
Avoid using this field, use getId() instead.
+
+
+
+

Protected static functions

+
+
+ static auto makeType(std::string name) -> core::reflection::Type& +
+
Constructs a type with the given name, constructible trait and UUID field.
+
+
+
+

Function documentation

+
+

+ cubos::engine::AnyAsset::AnyAsset(uuids::uuid id) +

+

Constructs a weak handle.

+ + + + + + + + + + +
Parameters
idUUID of the asset.
+
+
+

+ cubos::engine::AnyAsset::AnyAsset(std::string_view str) +

+

Constructs a weak handle. If the string is not a valid UUID, the handle will be null.

+ + + + + + + + + + +
Parameters
strString representation of the UUID.
+
+
+

+ cubos::engine::AnyAsset::AnyAsset(const AnyAsset& other) +

+

Constructs a copy of the given handle.

+ + + + + + + + + + +
Parameters
otherHandle to copy.
+
+
+

+ cubos::engine::AnyAsset::AnyAsset(AnyAsset&& other) noexcept +

+

Constructs a handle from the given handle.

+ + + + + + + + + + +
Parameters
otherHandle to move.
+
+
+

+
+ template<core::reflection::Reflectable T> +
+ cubos::engine::AnyAsset::operator Asset<T>() const +

+

Converts this handle to a handle of a specific type.

+ + + + + + + + + + + + + + + + +
Template parameters
TType of the asset.
ReturnsHandle to the same asset, but of the specified type.
+
+
+

+ AnyAsset& cubos::engine::AnyAsset::operator=(const AnyAsset& other) +

+

Overwrites this handle with a copy of the given handle.

+ + + + + + + + + + +
Parameters
otherHandle to copy.
+
+
+

+ AnyAsset& cubos::engine::AnyAsset::operator=(AnyAsset&& other) noexcept +

+

Overwrites this handle with the given handle.

+ + + + + + + + + + +
Parameters
otherHandle to move.
+
+
+

+ bool cubos::engine::AnyAsset::operator==(const AnyAsset& other) const +

+

Equality operator for comparing two AnyAsset objects.

+ + + + + + + + + + + + + + + + +
Parameters
otherThe other AnyAsset to compare.
ReturnsTrue if the two AnyAsset objects have the same UUID , otherwise false.
+
+
+

+ int cubos::engine::AnyAsset::getVersion() const +

+

Gets the version of the asset last seen by this handle.

+ + + + + + + +
ReturnsAsset version.
+
+
+

+ uuids::uuid cubos::engine::AnyAsset::getId() const +

+

Gets the UUID of the asset.

+ + + + + + + +
ReturnsAsset UUID.
+
+
+

+ bool cubos::engine::AnyAsset::isNull() const +

+

Checks if the handle is null.

+ + + + + + + +
ReturnsWhether the handle is null.
+
+
+

+ bool cubos::engine::AnyAsset::isStrong() const +

+

Checks if the handle is strong.

+ + + + + + + +
ReturnsWhether the handle is strong.
+
+
+

+ static core::reflection::Type& cubos::engine::AnyAsset::makeType(std::string name) protected +

+

Constructs a type with the given name, constructible trait and UUID field.

+ + + + + + + + + + +
Parameters
nameType name.
+

Added so that typed asset handles don't duplicate the existing reflection code of the base class.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1Asset.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1Asset.html new file mode 100644 index 000000000..2d5663268 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1Asset.html @@ -0,0 +1,332 @@ + + + + + cubos::engine::Asset class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<core::reflection::Reflectable T>
+ cubos::engine::Asset class +

+

Handle to an asset of a specific type.

+ + + + + + + + + + +
Template parameters
TType of the asset.
+ + +
+

Base classes

+
+
+ class AnyAsset +
+
Handle to an asset of any type. May either be weak or strong. Weak handles do not guarantee the asset is loaded, while strong handles do.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ AnyAsset(std::nullptr_t ptr = nullptr) +
+
Constructs a null handle.
+
+ AnyAsset(uuids::uuid id) +
+
Constructs a weak handle.
+
+ AnyAsset(std::string_view str) +
+
Constructs a weak handle. If the string is not a valid UUID, the handle will be null.
+
+ AnyAsset(const AnyAsset& other) +
+
Constructs a copy of the given handle.
+
+ AnyAsset(AnyAsset&& other) noexcept +
+
Constructs a handle from the given handle.
+
+
+
+

Public functions

+
+
+ auto toAny() const -> AnyAsset +
+
Constructs a generic handle version of this handle.
+
+ auto operator=(const AnyAsset& other) -> Asset<T>& +
+
Overwrites this handle with a copy of the given handle.
+
+ auto operator=(AnyAsset&& other) -> Asset<T>& noexcept +
+
Overwrites this handle with the given handle.
+
+
+
+

Function documentation

+
+

+
+ template<core::reflection::Reflectable T> +
+ cubos::engine::Asset<T>::AnyAsset(uuids::uuid id) +

+

Constructs a weak handle.

+ + + + + + + + + + +
Parameters
idUUID of the asset.
+
+
+

+
+ template<core::reflection::Reflectable T> +
+ cubos::engine::Asset<T>::AnyAsset(std::string_view str) +

+

Constructs a weak handle. If the string is not a valid UUID, the handle will be null.

+ + + + + + + + + + +
Parameters
strString representation of the UUID.
+
+
+

+
+ template<core::reflection::Reflectable T> +
+ cubos::engine::Asset<T>::AnyAsset(const AnyAsset& other) +

+

Constructs a copy of the given handle.

+ + + + + + + + + + +
Parameters
otherHandle to copy.
+
+
+

+
+ template<core::reflection::Reflectable T> +
+ cubos::engine::Asset<T>::AnyAsset(AnyAsset&& other) noexcept +

+

Constructs a handle from the given handle.

+ + + + + + + + + + +
Parameters
otherHandle to move.
+
+
+

+
+ template<core::reflection::Reflectable T> +
+ AnyAsset cubos::engine::Asset<T>::toAny() const +

+

Constructs a generic handle version of this handle.

+ + + + + + + +
ReturnsGeneric handle to the same asset.
+
+
+

+
+ template<core::reflection::Reflectable T> +
+ Asset<T>& cubos::engine::Asset<T>::operator=(const AnyAsset& other) +

+

Overwrites this handle with a copy of the given handle.

+ + + + + + + + + + + + + + + + +
Parameters
otherHandle to copy.
ReturnsReference to this object, for chaining.
+
+
+

+
+ template<core::reflection::Reflectable T> +
+ Asset<T>& cubos::engine::Asset<T>::operator=(AnyAsset&& other) noexcept +

+

Overwrites this handle with the given handle.

+ + + + + + + + + + + + + + + + +
Parameters
otherHandle to move.
ReturnsReference to this object, for chaining.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1AssetBridge.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1AssetBridge.html new file mode 100644 index 000000000..015d264ce --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1AssetBridge.html @@ -0,0 +1,246 @@ + + + + + cubos::engine::AssetBridge class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::AssetBridge class + +

+

Bridges are the objects responsible for loading and saving assets from/to disk. They form the bridge between the asset manager and the virtual file system.

+ +

Not all bridges need to implement the save method. You could have an asset type which could be loaded but not saved, for example.

Bridges should take into account that the asset manager calls them from a different thread than the one that created them.

+
+

Derived classes

+
+
+ class FileBridge +
+
Abstract bridge type defined to reduce boilerplate code in bridge implementations which open a single file to load and save assets.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ AssetBridge(const core::reflection::Type& type) explicit +
+
Constructs a bridge.
+
+
+
+

Public functions

+
+
+ auto load(Assets& assets, + const AnyAsset& handle) -> bool pure virtual +
+
Loads an asset.
+
+ auto save(const Assets& assets, + const AnyAsset& handle) -> bool virtual +
+
Saves an asset.
+
+ auto assetType() const -> const core::reflection::Type& +
+
Gets the type of the assets the bridge loads.
+
+
+
+

Function documentation

+
+

+ cubos::engine::AssetBridge::AssetBridge(const core::reflection::Type& type) explicit +

+

Constructs a bridge.

+ + + + + + + + + + +
Parameters
typeType of assets loaded by the bridge.
+
+
+

+ bool cubos::engine::AssetBridge::load(Assets& assets, + const AnyAsset& handle) pure virtual +

+

Loads an asset.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
assetsManager to write into.
handleHandle of the asset being loaded.
ReturnsWhether the asset was successfully loaded.
+

The metadata of the given asset should already be present in the asset manager.

+
+
+

+ bool cubos::engine::AssetBridge::save(const Assets& assets, + const AnyAsset& handle) virtual +

+

Saves an asset.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
assetsManager to read from.
handleHandle of the asset being saved.
ReturnsWhether the asset was successfully saved.
+

The asset should be loaded in the asset manager.

+
+
+

+ const core::reflection::Type& cubos::engine::AssetBridge::assetType() const +

+

Gets the type of the assets the bridge loads.

+ + + + + + + +
ReturnsType of the asset.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1AssetMeta.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1AssetMeta.html new file mode 100644 index 000000000..d7e3208a5 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1AssetMeta.html @@ -0,0 +1,244 @@ + + + + + cubos::engine::AssetMeta class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::AssetMeta class final + +

+

Stores metadata about an asset - the data stored in .meta files. Each asset has a corresponding meta object, which contains load or import parameters.

+ +

Serialization:

  • can be serialized and deserialized without context.
  • when serialized with the type AssetMeta::Exclude in the context, the specified keys are excluded from the serialization.
+
+

Public types

+
+
+ struct Exclude +
+
Used as context to exclude parameters from being serialized.
+
+
+
+

Public functions

+
+
+ auto get(std::string_view key) const -> std::optional<std::string> +
+
Gets the value of a parameter on the asset's metadata.
+
+ void set(std::string_view key, + std::string_view value) +
+
Sets a parameter on the asset's metadata.
+
+ void remove(std::string_view key) +
+
Removes a parameter from the asset's metadata.
+
+ auto params() const -> const std::unordered_map<std::string, std::string>& +
+
Gets the parameters of the asset's metadata.
+
+ auto params() -> std::unordered_map<std::string, std::string>& +
+
Gets the parameters of the asset's metadata.
+
+
+
+

Function documentation

+
+

+ std::optional<std::string> cubos::engine::AssetMeta::get(std::string_view key) const +

+

Gets the value of a parameter on the asset's metadata.

+ + + + + + + + + + + + + + + + +
Parameters
keyKey of the parameter.
ReturnsThe value of the parameter, if the parameter exists.
+
+
+

+ void cubos::engine::AssetMeta::set(std::string_view key, + std::string_view value) +

+

Sets a parameter on the asset's metadata.

+ + + + + + + + + + + + + + +
Parameters
keyKey of the parameter.
valueValue of the parameter.
+
+
+

+ void cubos::engine::AssetMeta::remove(std::string_view key) +

+

Removes a parameter from the asset's metadata.

+ + + + + + + + + + +
Parameters
keyKey of the parameter.
+
+
+

+ const std::unordered_map<std::string, std::string>& cubos::engine::AssetMeta::params() const +

+

Gets the parameters of the asset's metadata.

+ + + + + + + +
ReturnsParameters of the asset.
+
+
+

+ std::unordered_map<std::string, std::string>& cubos::engine::AssetMeta::params() +

+

Gets the parameters of the asset's metadata.

+ + + + + + + +
ReturnsParameters of the asset.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1Assets.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1Assets.html new file mode 100644 index 000000000..c53b69375 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1Assets.html @@ -0,0 +1,708 @@ + + + + + cubos::engine::Assets class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::Assets class final + +

+

Resource which manages all assets. Responsible for loading and unloading assets, storing them in memory, and providing access to them.

+ +

Assets are all identified through Asset handles.

+
+

Public types

+
+
+ enum class Status { Unknown, + Unloaded, + Loading, + Loaded } +
+
Possible statuses for an asset.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ Assets() +
+
Constructs an empty manager without any bridges or metadata.
+
+ Assets(const Assets&) deleted +
+
Forbid copying.
+
+ Assets(Assets&&) deleted +
+
Forbid moving.
+
+
+
+

Public functions

+
+
+ void registerBridge(const std::string& extension, + std::shared_ptr<AssetBridge> bridge) +
+
Registers a new bridge for the given extension.
+
+ void cleanup() +
+
Cleans up all assets that are not in use. Should be called periodically to free up memory.
+
+ void loadMeta(std::string_view path) +
+
Loads all metadata from the virtual filesystem, in the given path. If the path points to a directory, it will be recursively searched for metadata files.
+
+ auto load(AnyAsset handle) const -> AnyAsset +
+
Loads the asset with the given handle, upgrading the handle to a strong one.
+
+ auto saveMeta(const AnyAsset& handle) const -> bool +
+
Saves changes made to an asset's metadata.
+
+ auto save(const AnyAsset& handle) const -> bool +
+
Saves changes made to the asset with the given handle.
+
+ auto readMeta(const AnyAsset& handle) const -> AssetMetaRead +
+
Gets read-only access to the metadata associated with the given handle.
+
+ auto writeMeta(const AnyAsset& handle) -> AssetMetaWrite +
+
Gets read-write access to the metadata associated with the given handle.
+
+
template<typename T>
+ auto read(Asset<T> handle) const -> AssetRead<T> +
+
Gets read-only access to the asset data associated with the given handle.
+
+
template<typename T>
+ auto write(Asset<T> handle) -> AssetWrite<T> +
+
Gets read-write access to the asset data associated with the given handle.
+
+ auto status(const AnyAsset& handle) const -> Status +
+
Gets the status of the asset with the given handle.
+
+ auto update(AnyAsset& handle) const -> bool +
+
Updates the given handle to the latest version of the asset.
+
+
template<typename T>
+ auto update(Asset<T>& handle) const -> bool +
+
Updates the given handle to the latest version of the asset.
+
+ void invalidate(const AnyAsset& handle) +
+
Unloads the given asset. Can be used to force assets to be reloaded.
+
+
template<typename T>
+ auto create(T data) -> Asset<T> +
+
Creates a new asset with a random UUID with the given data (and empty metadata).
+
+
template<typename T>
+ auto store(AnyAsset handle, + T data) -> AnyAsset +
+
Stores the given asset data in memory, associated with the given handle.
+
+ auto listAll() const -> std::vector<AnyAsset> +
+
Gets all assets that have been registered.
+
+ auto type(const AnyAsset& handle) const -> const core::reflection::Type& +
+
Gets the type of an asset.
+
+
+
+

Enum documentation

+
+

+ enum class cubos::engine::Assets::Status +

+

Possible statuses for an asset.

+ + + + + + + + + + + + + + + + + + + + +
Enumerators
Unknown +

No metadata is associated with the asset.

+
Unloaded +

The asset is not loaded.

+
Loading +

The asset is being loaded.

+
Loaded +

The asset is loaded.

+
+
+
+
+

Function documentation

+
+

+ void cubos::engine::Assets::registerBridge(const std::string& extension, + std::shared_ptr<AssetBridge> bridge) +

+

Registers a new bridge for the given extension.

+ + + + + + + + + + + + + + +
Parameters
extensionExtension to register the bridge for.
bridgeBridge to register.
+

If more than one extension match a given asset's name, the longest extension is picked.

+
+
+

+ void cubos::engine::Assets::loadMeta(std::string_view path) +

+

Loads all metadata from the virtual filesystem, in the given path. If the path points to a directory, it will be recursively searched for metadata files.

+ + + + + + + + + + +
Parameters
pathPath to load metadata from.
+
+
+

+ AnyAsset cubos::engine::Assets::load(AnyAsset handle) const +

+

Loads the asset with the given handle, upgrading the handle to a strong one.

+ + + + + + + + + + + + + + + + +
Parameters
handleHandle to load the asset for.
ReturnsStrong handle to the asset, or a null handle if an error occurred.
+

This method doesn't block, thus the asset may have not yet been loaded when it returns. If the manager is unable to find the asset or a bridge for loading it, a null handle is returned. If an error occurs while loading the asset, it will only fail in read() or be visible through status().

+
+
+

+ bool cubos::engine::Assets::saveMeta(const AnyAsset& handle) const +

+

Saves changes made to an asset's metadata.

+ + + + + + + + + + + + + + + + +
Parameters
handleHandle identifying the asset to save.
ReturnsWhether the operation was successful.
+

This method blocks until the asset is saved.

+
+
+

+ bool cubos::engine::Assets::save(const AnyAsset& handle) const +

+

Saves changes made to the asset with the given handle.

+ + + + + + + + + + + + + + + + +
Parameters
handleHandle identifying the asset to save.
ReturnsWhether the operation was successful.
+

This method blocks until the asset is saved.

+
+
+

+ AssetMetaRead cubos::engine::Assets::readMeta(const AnyAsset& handle) const +

+

Gets read-only access to the metadata associated with the given handle.

+ + + + + + + + + + + + + + + + +
Parameters
handleHandle of the asset to get the metadata for.
ReturnsReference to the metadata.
+

Aborts if the asset is unknown.

+
+
+

+ AssetMetaWrite cubos::engine::Assets::writeMeta(const AnyAsset& handle) +

+

Gets read-write access to the metadata associated with the given handle.

+ + + + + + + + + + + + + + + + +
Parameters
handleHandle to get the metadata for.
ReturnsReference to the metadata.
+

If the asset is unknown, an empty metadata object is returned.

+
+
+

+
+ template<typename T> +
+ AssetRead<T> cubos::engine::Assets::read(Asset<T> handle) const +

+

Gets read-only access to the asset data associated with the given handle.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TType of the asset data.
Parameters
handleHandle to get the asset data for.
ReturnsReference to the asset data.
+

If the asset is not loaded, this blocks until it is. If the asset cannot be loaded, abort is called.

+
+
+

+
+ template<typename T> +
+ AssetWrite<T> cubos::engine::Assets::write(Asset<T> handle) +

+

Gets read-write access to the asset data associated with the given handle.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TType of the asset data.
Parameters
handleHandle to get the asset data for.
ReturnsReference to the asset data.
+

If the asset is not loaded, this blocks until it is. If the asset cannot be loaded, abort is called. This increases the asset's version.

+
+
+

+ Status cubos::engine::Assets::status(const AnyAsset& handle) const +

+

Gets the status of the asset with the given handle.

+ + + + + + + + + + + + + + + + +
Parameters
handleHandle to check the status for.
ReturnsStatus of the asset.
+
+
+

+ bool cubos::engine::Assets::update(AnyAsset& handle) const +

+

Updates the given handle to the latest version of the asset.

+ + + + + + + + + + + + + + + + +
Parameters
handleHandle to update.
ReturnsWhether the version was updated.
+

Can be used to implement hot-reloading.

+
+
+

+
+ template<typename T> +
+ bool cubos::engine::Assets::update(Asset<T>& handle) const +

+

Updates the given handle to the latest version of the asset.

+ + + + + + + + + + + + + + + + +
Parameters
handleHandle to update.
ReturnsWhether the version was updated.
+

Can be used to implement hot-reloading.

+
+
+

+ void cubos::engine::Assets::invalidate(const AnyAsset& handle) +

+

Unloads the given asset. Can be used to force assets to be reloaded.

+ + + + + + + + + + +
Parameters
handleHandle to unload.
+
+
+

+
+ template<typename T> +
+ Asset<T> cubos::engine::Assets::create(T data) +

+

Creates a new asset with a random UUID with the given data (and empty metadata).

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TType of the asset data.
Parameters
dataAsset data to store.
ReturnsStrong handle to the new asset.
+
+
+

+
+ template<typename T> +
+ AnyAsset cubos::engine::Assets::store(AnyAsset handle, + T data) +

+

Stores the given asset data in memory, associated with the given handle.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TType of the asset data.
Parameters
handleHandle to associate the asset with.
dataAsset data to store.
ReturnsStrong handle to the asset.
+

If an asset with the same handle already exists, it will be replaced. If no metadata is associated with the handle, an empty one will be created. This increases the asset's version.

+
+
+

+ std::vector<AnyAsset> cubos::engine::Assets::listAll() const +

+

Gets all assets that have been registered.

+ + + + + + + +
ReturnsVector with all registered assets.
+
+
+

+ const core::reflection::Type& cubos::engine::Assets::type(const AnyAsset& handle) const +

+

Gets the type of an asset.

+ + + + + + + + + + + + + + + + +
Parameters
handleHandle to check the type for.
ReturnsAsset type.
+

If the asset is not loaded, its type is deduced from its bridge. If there's also no associated bridge, aborts. If the asset does not exist, aborts.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1BaseRenderer.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1BaseRenderer.html new file mode 100644 index 000000000..fa15305b4 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1BaseRenderer.html @@ -0,0 +1,433 @@ + + + + + cubos::engine::BaseRenderer class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::BaseRenderer class + +

+

Interface which abstracts different rendering methods.

+ +

This abstraction allows us to, for example, switch between a raytracing and a deferred rendering method as we need to, without changing the API. This is useful since not all computers support realtime raytracing.

+
+

Derived classes

+
+
+ class DeferredRenderer +
+
Renderer implementation which uses deferred rendering.
+
+
+
+

Public types

+
+
+ struct Viewport +
+
Struct which holds the viewport information for a camera, to be used for drawing.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ BaseRenderer(core::gl::RenderDevice& renderDevice, + glm::uvec2 size) +
+
Constructs.
+
+ BaseRenderer(const BaseRenderer&) deleted +
+
Deleted copy constructor.
+
+
+
+

Public functions

+
+
+ auto upload(const VoxelGrid& grid) -> RendererGrid pure virtual +
+
Uploads a grid to the GPU and returns an handle which can be used to draw it.
+
+ void setPalette(const VoxelPalette& palette) pure virtual +
+
Sets the current palette of the renderer.
+
+ void resize(glm::uvec2 size) +
+
Resizes the renderer's framebuffers.
+
+ auto size() const -> glm::uvec2 +
+
Gets the current size of the renderer's framebuffers.
+
+ void render(const glm::mat4& view, + const Viewport& viewport, + const engine::Camera& camera, + const RendererFrame& frame, + const core::gl::Framebuffer& pickingBuffer = nullptr, + bool usePostProcessing = true, + const core::gl::Framebuffer& target = nullptr) +
+
Draws a frame.
+
+ auto pps() -> PostProcessingManager& +
+
Gets a reference to the post processing manager.
+
+
+
+

Protected functions

+
+
+ void onResize(glm::uvec2 size) pure virtual +
+
Called when resize() is called.
+
+ void onRender(const glm::mat4& view, + const Viewport& viewport, + const Camera& camera, + const RendererFrame& frame, + core::gl::Framebuffer target, + core::gl::Framebuffer pickingBuffer) pure virtual +
+
Called when render() is called, before applying post processing effects.
+
+
+
+

Protected variables

+
+
+ core::gl::RenderDevice& mRenderDevice +
+
Render device being used.
+
+
+
+

Function documentation

+
+

+ cubos::engine::BaseRenderer::BaseRenderer(core::gl::RenderDevice& renderDevice, + glm::uvec2 size) +

+

Constructs.

+ + + + + + + + + + + + + + +
Parameters
renderDeviceRender device to use.
sizeSize of the window.
+ +
+
+

+ RendererGrid cubos::engine::BaseRenderer::upload(const VoxelGrid& grid) pure virtual +

+

Uploads a grid to the GPU and returns an handle which can be used to draw it.

+ + + + + + + + + + + + + + + + +
Parameters
gridGrid to upload.
ReturnsHandle of the grid.
+
+
+

+ void cubos::engine::BaseRenderer::setPalette(const VoxelPalette& palette) pure virtual +

+

Sets the current palette of the renderer.

+ + + + + + + + + + +
Parameters
palettePalette to set.
+
+
+

+ void cubos::engine::BaseRenderer::resize(glm::uvec2 size) +

+

Resizes the renderer's framebuffers.

+ + + + + + + + + + +
Parameters
sizeNew size of the window.
+
+
+

+ glm::uvec2 cubos::engine::BaseRenderer::size() const +

+

Gets the current size of the renderer's framebuffers.

+ + + + + + + +
ReturnsCurrent size.
+
+
+

+ void cubos::engine::BaseRenderer::render(const glm::mat4& view, + const Viewport& viewport, + const engine::Camera& camera, + const RendererFrame& frame, + const core::gl::Framebuffer& pickingBuffer = nullptr, + bool usePostProcessing = true, + const core::gl::Framebuffer& target = nullptr) +

+

Draws a frame.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
viewCamera view transform.
viewportCamera viewport.
cameraCamera to use.
frameFrame to draw.
pickingBufferScreen picking framebuffer.
usePostProcessingWhether to use post processing.
targetTarget framebuffer to draw to.
+
+
+

+ PostProcessingManager& cubos::engine::BaseRenderer::pps() +

+

Gets a reference to the post processing manager.

+ + + + + + + +
ReturnsPost processing manager.
+
+
+

+ void cubos::engine::BaseRenderer::onResize(glm::uvec2 size) pure virtual protected +

+

Called when resize() is called.

+ + + + + + + + + + +
Parameters
sizeNew size of the framebuffer.
+

Renderer implementations should override this function to resize their framebuffers.

+
+
+

+ void cubos::engine::BaseRenderer::onRender(const glm::mat4& view, + const Viewport& viewport, + const Camera& camera, + const RendererFrame& frame, + core::gl::Framebuffer target, + core::gl::Framebuffer pickingBuffer) pure virtual protected +

+

Called when render() is called, before applying post processing effects.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
viewCamera view transform.
viewportCamera viewport.
cameraCamera to use.
frameFrame to draw.
targetTarget framebuffer.
pickingBufferScreen picking framebuffer.
+

Renderer implementations should implement this function to draw the frame. When post processing is enabled, the target framebuffer will be the internal texture which will be used for post processing.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1BinaryBridge.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1BinaryBridge.html new file mode 100644 index 000000000..6082a953e --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1BinaryBridge.html @@ -0,0 +1,259 @@ + + + + + cubos::engine::BinaryBridge class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::engine::BinaryBridge class +

+

Bridge for loading and saving assets which are serialized to and from a binary file.

+ + + + + + + + + + +
Template parameters
TType of asset to load and save. Must be default constructible.
+ +

This bridge automatically serializes and deserializes assets of type T to from a binary file. Thus, T must be serializable and deserializable. No additional context is given to the serializer or deserializer.

+
+

Base classes

+
+
+ class FileBridge +
+
Abstract bridge type defined to reduce boilerplate code in bridge implementations which open a single file to load and save assets.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ BinaryBridge(bool littleEndian = true) +
+
Constructs a bridge.
+
+
+
+

Protected functions

+
+
+ auto loadFromFile(Assets& assets, + const AnyAsset& handle, + core::memory::Stream& stream) -> bool override +
+
Loads an asset from a file stream.
+
+ auto saveToFile(const Assets& assets, + const AnyAsset& handle, + core::memory::Stream& stream) -> bool override +
+
Saves an asset to a file stream.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ cubos::engine::BinaryBridge<T>::BinaryBridge(bool littleEndian = true) +

+

Constructs a bridge.

+ + + + + + + + + + +
Parameters
littleEndianWhether to use little endian byte order.
+
+
+

+
+ template<typename T> +
+ bool cubos::engine::BinaryBridge<T>::loadFromFile(Assets& assets, + const AnyAsset& handle, + core::memory::Stream& stream) override protected +

+

Loads an asset from a file stream.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
assetsManager to write into.
handleHandle of the asset being loaded.
streamFile stream.
ReturnsWhether the asset was successfully loaded.
+
+
+

+
+ template<typename T> +
+ bool cubos::engine::BinaryBridge<T>::saveToFile(const Assets& assets, + const AnyAsset& handle, + core::memory::Stream& stream) override protected +

+

Saves an asset to a file stream.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
assetsManager to read from.
handleHandle of the asset being saved.
streamFile stream.
ReturnsWhether the asset was successfully saved.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1DataInspector.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1DataInspector.html new file mode 100644 index 000000000..a113bd5bf --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1DataInspector.html @@ -0,0 +1,257 @@ + + + + + cubos::engine::DataInspector class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::DataInspector class final + +

+

Resource which allows the user to inspect or modify any reflectable value on the UI.

+ + +
+

Public functions

+
+
+ void show(const core::reflection::Type& type, + const void* value) +
+
Displays a reflectable value on the UI.
+
+ auto edit(const core::reflection::Type& type, + void* value) -> bool +
+
Displays a reflectable value on the UI and allows modifying it.
+
+
template<typename T>
+ void show(const T& value) +
+
Displays a reflectable value on the UI.
+
+
template<typename T>
+ auto edit(T& value) -> bool +
+
Displays a reflectable value on the UI and allows modifying it.
+
+
+
+

Function documentation

+
+

+ void cubos::engine::DataInspector::show(const core::reflection::Type& type, + const void* value) +

+

Displays a reflectable value on the UI.

+ + + + + + + + + + + + + + +
Parameters
typeValue type.
valuePointer to value.
+
+
+

+ bool cubos::engine::DataInspector::edit(const core::reflection::Type& type, + void* value) +

+

Displays a reflectable value on the UI and allows modifying it.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
typeValue type.
valuePointer to value.
ReturnsWhether the object was modified.
+
+
+

+
+ template<typename T> +
+ void cubos::engine::DataInspector::show(const T& value) +

+

Displays a reflectable value on the UI.

+ + + + + + + + + + + + + + + + + + + +
Template parameters
TValue type.
Parameters
valuePointer to value.
+
+
+

+
+ template<typename T> +
+ bool cubos::engine::DataInspector::edit(T& value) +

+

Displays a reflectable value on the UI and allows modifying it.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TValue type.
Parameters
valuePointer to value.
ReturnsWhether the object was modified.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1DeferredRenderer.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1DeferredRenderer.html new file mode 100644 index 000000000..3c68c7ae6 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1DeferredRenderer.html @@ -0,0 +1,300 @@ + + + + + cubos::engine::DeferredRenderer class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::DeferredRenderer class + +

+

Renderer implementation which uses deferred rendering.

+ +

Voxel grids are first triangulated, and then the triangles are uploaded to the GPU. The rendering is done in two passes:

  1. Render the scene to the GBuffer textures: position, normal and material.
  2. Take the GBuffer textures and calculate the color of the pixels with the lighting applied.
+
+

Base classes

+
+
+ class BaseRenderer +
+
Interface which abstracts different rendering methods.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ DeferredRenderer(core::gl::RenderDevice& renderDevice, + glm::uvec2 size, + Settings& settings) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ auto upload(const VoxelGrid& grid) -> RendererGrid override +
+
Uploads a grid to the GPU and returns an handle which can be used to draw it.
+
+ void setPalette(const VoxelPalette& palette) override +
+
Sets the current palette of the renderer.
+
+
+
+

Protected functions

+
+
+ void onResize(glm::uvec2 size) override +
+
Called when resize() is called.
+
+ void onRender(const glm::mat4& view, + const Viewport& viewport, + const Camera& camera, + const RendererFrame& frame, + core::gl::Framebuffer target, + core::gl::Framebuffer pickingBuffer) override +
+
Called when render() is called, before applying post processing effects.
+
+
+
+

Function documentation

+
+

+ cubos::engine::DeferredRenderer::DeferredRenderer(core::gl::RenderDevice& renderDevice, + glm::uvec2 size, + Settings& settings) +

+

Constructs.

+ + + + + + + + + + + + + + + + + + +
Parameters
renderDeviceRender device to use.
sizeSize of the window.
settingsSettings to use.
+
+
+

+ RendererGrid cubos::engine::DeferredRenderer::upload(const VoxelGrid& grid) override +

+

Uploads a grid to the GPU and returns an handle which can be used to draw it.

+ + + + + + + + + + + + + + + + +
Parameters
gridGrid to upload.
ReturnsHandle of the grid.
+
+
+

+ void cubos::engine::DeferredRenderer::setPalette(const VoxelPalette& palette) override +

+

Sets the current palette of the renderer.

+ + + + + + + + + + +
Parameters
palettePalette to set.
+
+
+

+ void cubos::engine::DeferredRenderer::onResize(glm::uvec2 size) override protected +

+

Called when resize() is called.

+ + + + + + + + + + +
Parameters
sizeNew size of the framebuffer.
+

Renderer implementations should override this function to resize their framebuffers.

+
+
+

+ void cubos::engine::DeferredRenderer::onRender(const glm::mat4& view, + const Viewport& viewport, + const Camera& camera, + const RendererFrame& frame, + core::gl::Framebuffer target, + core::gl::Framebuffer pickingBuffer) override protected +

+

Called when render() is called, before applying post processing effects.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
viewCamera view transform.
viewportCamera viewport.
cameraCamera to use.
frameFrame to draw.
targetTarget framebuffer.
pickingBufferScreen picking framebuffer.
+

Renderer implementations should implement this function to draw the frame. When post processing is enabled, the target framebuffer will be the internal texture which will be used for post processing.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1FileBridge.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1FileBridge.html new file mode 100644 index 000000000..043270055 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1FileBridge.html @@ -0,0 +1,337 @@ + + + + + cubos::engine::FileBridge class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::FileBridge class + +

+

Abstract bridge type defined to reduce boilerplate code in bridge implementations which open a single file to load and save assets.

+ +

This bridge should be used as a base class for bridges which load and save assets. Child classes must implement the loadFromFile() and saveToFile() methods, which are called with a file stream to load and save the asset from and to, respectively.

+
+

Base classes

+
+
+ class AssetBridge +
+
Bridges are the objects responsible for loading and saving assets from/to disk. They form the bridge between the asset manager and the virtual file system.
+
+
+
+

Derived classes

+
+
+
template<typename T>
+ class BinaryBridge +
+
Bridge for loading and saving assets which are serialized to and from a binary file.
+
+
template<typename T>
+ class JSONBridge +
+
Bridge for loading and saving assets which are serialized to and from a JSON file.
+
+ class SceneBridge +
+
Bridge which loads and saves Scene assets.
+
+
template<typename T>
+ class JSONBridge +
+
Bridge for loading and saving assets which are serialized to and from a JSON file.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ FileBridge(const core::reflection::Type& type) explicit +
+
Constructs a bridge.
+
+
+
+

Public functions

+
+
+ auto load(Assets& assets, + const AnyAsset& handle) -> bool final +
+
Loads an asset.
+
+ auto save(const Assets& assets, + const AnyAsset& handle) -> bool final +
+
Saves an asset.
+
+
+
+

Protected functions

+
+
+ auto loadFromFile(Assets& assets, + const AnyAsset& handle, + core::memory::Stream& stream) -> bool pure virtual +
+
Loads an asset from a file stream.
+
+ auto saveToFile(const Assets& assets, + const AnyAsset& handle, + core::memory::Stream& stream) -> bool pure virtual +
+
Saves an asset to a file stream.
+
+
+
+

Function documentation

+
+

+ cubos::engine::FileBridge::FileBridge(const core::reflection::Type& type) explicit +

+

Constructs a bridge.

+ + + + + + + + + + +
Parameters
typeType of assets loaded by the bridge.
+
+
+

+ bool cubos::engine::FileBridge::load(Assets& assets, + const AnyAsset& handle) final +

+

Loads an asset.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
assetsManager to write into.
handleHandle of the asset being loaded.
ReturnsWhether the asset was successfully loaded.
+

The metadata of the given asset should already be present in the asset manager.

+
+
+

+ bool cubos::engine::FileBridge::save(const Assets& assets, + const AnyAsset& handle) final +

+

Saves an asset.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
assetsManager to read from.
handleHandle of the asset being saved.
ReturnsWhether the asset was successfully saved.
+

The asset should be loaded in the asset manager.

+
+
+

+ bool cubos::engine::FileBridge::loadFromFile(Assets& assets, + const AnyAsset& handle, + core::memory::Stream& stream) pure virtual protected +

+

Loads an asset from a file stream.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
assetsManager to write into.
handleHandle of the asset being loaded.
streamFile stream.
ReturnsWhether the asset was successfully loaded.
+
+
+

+ bool cubos::engine::FileBridge::saveToFile(const Assets& assets, + const AnyAsset& handle, + core::memory::Stream& stream) pure virtual protected +

+

Saves an asset to a file stream.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
assetsManager to read from.
handleHandle of the asset being saved.
streamFile stream.
ReturnsWhether the asset was successfully saved.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1Gizmos.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1Gizmos.html new file mode 100644 index 000000000..c57601816 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1Gizmos.html @@ -0,0 +1,697 @@ + + + + + cubos::engine::Gizmos class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::Gizmos class final + +

+

Resource which queues commands for drawing gizmos, basic primitives useful for debugging and tools.

+ +
+

Public types

+
+
+ class Gizmo +
+
Class that describes a type of gizmo.
+
+ enum Space { World, + View, + Screen } +
+
Space to draw a gizmo in.
+
+
+
+

Public functions

+
+
+ void color(const glm::vec3& color) +
+
Sets the color to be used when drawing any subsequent gizmos.
+
+ void drawLine(const std::string& id, + glm::vec3 from, + glm::vec3 to, + float lifespan = 0.0F, + Space space = Space::World) +
+
Draws a line gizmo.
+
+ void drawBox(const std::string& id, + glm::vec3 corner, + glm::vec3 oppositeCorner, + float lifespan = 0.0F, + Space space = Space::World) +
+
Draws a filled box gizmo.
+
+ void drawCutCone(const std::string& id, + glm::vec3 firstBaseCenter, + float firstBaseRadius, + glm::vec3 secondBaseCenter, + float secondBaseRadius, + float lifespan = 0.0F, + Space space = Space::World) +
+
Draws a cut cone gizmo.
+
+ void drawRing(const std::string& id, + glm::vec3 firstBasePosition, + glm::vec3 secondBasePosition, + float outerRadius, + float innerRadius, + float lifespan = 0.0F, + Space space = Space::World) +
+
Draws a ring gizmo.
+
+ void drawArrow(const std::string& id, + glm::vec3 origin, + glm::vec3 direction, + float girth, + float width, + float ratio = 0.F, + float lifespan = 0.0F, + Space space = Space::World) +
+
Draws an arrow gizmo.
+
+ void drawWireBox(const std::string& id, + glm::vec3 corner, + glm::vec3 oppositeCorner, + float lifespan = 0.0F, + Space space = Space::World) +
+
Draws a wireframe box gizmo.
+
+ void drawWireBox(const std::string& id, + const glm::mat4& transform, + float lifespan = 0.0F, + Space space = Space::World) +
+
Draws a wireframe box gizmo.
+
+ auto pressed(const std::string& id) const -> bool +
+
Checks whether the left mouse button was pressed over a gizmo.
+
+ auto locked(const std::string& id) const -> bool +
+
Checks whether the left mouse button was pressed over a gizmo.
+
+ auto hovered(const std::string& id) const -> bool +
+
Checks whether the mouse cursor is over a gizmo.
+
+ void handleInput(uint32_t hovered, + bool pressed) +
+
Notifies that a given gizmo is being hovered. Called automatically by an internal system.
+
+ void setLocked(uint32_t locked) +
+
Notifies that a given gizmo is locked.
+
+ void releaseLocked() +
+
Notifies that the previously locked gizmo is no longer locked.
+
+
+
+

Public variables

+
+
+ std::vector<std::shared_ptr<Gizmo>> worldGizmos +
+
Queued gizmos to be drawn in world space.
+
+ std::vector<std::shared_ptr<Gizmo>> viewGizmos +
+
Queued gizmos to be drawn in viewport space.
+
+ std::vector<std::shared_ptr<Gizmo>> screenGizmos +
+
Queued gizmos to be drawn in screen space.
+
+ bool mLocking +
+
Whether the mouse has just now been pressed.
+
+
+
+

Enum documentation

+
+

+ enum cubos::engine::Gizmos::Space +

+

Space to draw a gizmo in.

+ + + + + + + + + + + + + + + + +
Enumerators
World +

Draw gizmo in the game world.

+
View +

Draw gizmo in every camera's viewport.

+
Screen +

Draw gizmo in the screen.

+
+
+
+
+

Function documentation

+
+

+ void cubos::engine::Gizmos::color(const glm::vec3& color) +

+

Sets the color to be used when drawing any subsequent gizmos.

+ + + + + + + + + + +
Parameters
colorColor to be used.
+
+
+

+ void cubos::engine::Gizmos::drawLine(const std::string& id, + glm::vec3 from, + glm::vec3 to, + float lifespan = 0.0F, + Space space = Space::World) +

+

Draws a line gizmo.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the gizmo.
fromOne of the ends of the line to be drawn.
toThe other end of the line to be drawn.
lifespanHow long the line will be on screen for, in seconds. Defaults to 0, which means a single frame.
spaceSpace to draw the gizmo in.
+
+
+

+ void cubos::engine::Gizmos::drawBox(const std::string& id, + glm::vec3 corner, + glm::vec3 oppositeCorner, + float lifespan = 0.0F, + Space space = Space::World) +

+

Draws a filled box gizmo.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the gizmo.
cornerOne of the corners of the box to be drawn.
oppositeCornerThe opposite corner of the box to be drawn.
lifespanHow long the line will be on screen for, in seconds. Defaults to 0, which means a single frame.
spaceSpace to draw the gizmo in.
+
+
+

+ void cubos::engine::Gizmos::drawCutCone(const std::string& id, + glm::vec3 firstBaseCenter, + float firstBaseRadius, + glm::vec3 secondBaseCenter, + float secondBaseRadius, + float lifespan = 0.0F, + Space space = Space::World) +

+

Draws a cut cone gizmo.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the gizmo.
firstBaseCenterCenter of one of the bases.
firstBaseRadiusRadius of one of the bases.
secondBaseCenterCenter of the second base.
secondBaseRadiusRadius of the second base.
lifespanHow long the line will be on screen for, in seconds. Defaults to 0, which means a single frame.
spaceSpace to draw the gizmo in.
+
+
+

+ void cubos::engine::Gizmos::drawRing(const std::string& id, + glm::vec3 firstBasePosition, + glm::vec3 secondBasePosition, + float outerRadius, + float innerRadius, + float lifespan = 0.0F, + Space space = Space::World) +

+

Draws a ring gizmo.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the gizmo.
firstBasePositionCenter of one of the bases.
secondBasePositionCenter of the second base.
outerRadiusRadius of one of the ring.
innerRadiusRadius of the of the hole.
lifespanHow long the line will be on screen for, in seconds. Defaults to 0, which means a single frame.
spaceSpace to draw the gizmo in.
+
+
+

+ void cubos::engine::Gizmos::drawArrow(const std::string& id, + glm::vec3 origin, + glm::vec3 direction, + float girth, + float width, + float ratio = 0.F, + float lifespan = 0.0F, + Space space = Space::World) +

+

Draws an arrow gizmo.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the gizmo.
originPoint from which the arrow starts.
directionDirection of the arrow.
girthRadius of the cylinder part of the arrow.
widthRadius of the base of the cone at the tip of the arrow.
ratioPoint of the arrow at which the cylinder ends and the cone begins.
lifespanHow long the line will be on screen for, in seconds. Defaults to 0, which means a single frame.
spaceSpace to draw the gizmo in.
+
+
+

+ void cubos::engine::Gizmos::drawWireBox(const std::string& id, + glm::vec3 corner, + glm::vec3 oppositeCorner, + float lifespan = 0.0F, + Space space = Space::World) +

+

Draws a wireframe box gizmo.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the gizmo.
cornerOne of the corners of the box to be drawn.
oppositeCornerThe opposite corner of the box to be drawn.
lifespanHow long the line will be on screen for, in seconds. Defaults to 0, which means a single frame.
spaceSpace to draw the gizmo in.
+
+
+

+ void cubos::engine::Gizmos::drawWireBox(const std::string& id, + const glm::mat4& transform, + float lifespan = 0.0F, + Space space = Space::World) +

+

Draws a wireframe box gizmo.

+ + + + + + + + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the gizmo.
transformTransformation matrix to apply to a unit-sized box centered at the origin.
lifespanHow long the line will be on screen for, in seconds. Defaults to 0, which means a single frame.
spaceSpace to draw the gizmo in.
+
+
+

+ bool cubos::engine::Gizmos::pressed(const std::string& id) const +

+

Checks whether the left mouse button was pressed over a gizmo.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the gizmo.
ReturnsWhether the gizmo was pressed.
+
+
+

+ bool cubos::engine::Gizmos::locked(const std::string& id) const +

+

Checks whether the left mouse button was pressed over a gizmo.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the gizmo.
ReturnsWhether the gizmo was pressed.
+
+
+

+ bool cubos::engine::Gizmos::hovered(const std::string& id) const +

+

Checks whether the mouse cursor is over a gizmo.

+ + + + + + + + + + + + + + + + +
Parameters
idIdentifier of the gizmo.
ReturnsWhether the mouse button is over a gizmo.
+
+
+

+ void cubos::engine::Gizmos::handleInput(uint32_t hovered, + bool pressed) +

+

Notifies that a given gizmo is being hovered. Called automatically by an internal system.

+ + + + + + + + + + + + + + +
Parameters
hoveredGizmo being hovered.
pressedWhether the mouse left button is pressed.
+
+
+

+ void cubos::engine::Gizmos::setLocked(uint32_t locked) +

+

Notifies that a given gizmo is locked.

+ + + + + + + + + + +
Parameters
lockedGizmo being locked.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1Gizmos_1_1Gizmo.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1Gizmos_1_1Gizmo.html new file mode 100644 index 000000000..39ec3a4d9 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1Gizmos_1_1Gizmo.html @@ -0,0 +1,200 @@ + + + + + cubos::engine::Gizmos::Gizmo class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::Gizmos::Gizmo class + +

+

Class that describes a type of gizmo.

+ +
+

Public functions

+
+
+ void draw(GizmosRenderer& renderer, + DrawPhase phase, + const glm::mat<4, 4, float, glm::packed_highp>& mvp) pure virtual +
+
Draws the gizmo to screen.
+
+ auto decreaseLifespan(float delta) -> bool +
+
Decreases the time the gizmo has left before it is destroyed.
+
+
+
+

Public variables

+
+
+ const uint32_t id +
+
Gizmo identifier.
+
+
+
+

Protected variables

+
+
+ glm::vec3 mColor +
+
Color of the gizmo.
+
+ float mLifespan +
+
Time in seconds the gizmo has left to live.
+
+
+
+

Function documentation

+
+

+ void cubos::engine::Gizmos::Gizmo::draw(GizmosRenderer& renderer, + DrawPhase phase, + const glm::mat<4, 4, float, glm::packed_highp>& mvp) pure virtual +

+

Draws the gizmo to screen.

+ + + + + + + + + + + + + + + + + + +
Parameters
rendererRenderer.
phase
mvpThe view projection matrix to use for drawing the gizmo.
+
+
+

+ bool cubos::engine::Gizmos::Gizmo::decreaseLifespan(float delta) +

+

Decreases the time the gizmo has left before it is destroyed.

+ + + + + + + + + + +
Parameters
deltaSeconds since the last frame.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1Input.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1Input.html new file mode 100644 index 000000000..32fa506db --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1Input.html @@ -0,0 +1,560 @@ + + + + + cubos::engine::Input class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::Input class final + +

+

Resource which stores the input bindings for multiple players.

+ +

Its state is updated accordingly as events are received by the Input.

+
+

Public types

+
+
+ using Key = core::io::Key +
+
Alias for core::io::Key.
+
+ using Modifiers = core::io::Modifiers +
+
Alias for core::io::Modifiers.
+
+ using GamepadButton = core::io::GamepadButton +
+
Alias for core::io::GamepadButton.
+
+ using GamepadAxis = core::io::GamepadAxis +
+
Alias for core::io::GamepadAxis.
+
+ using MouseButton = core::io::MouseButton +
+
Alias for core::io::MouseButton.
+
+
+
+

Public static functions

+
+
+ static void handle(const core::io::Window& window, + const core::io::WindowEvent& event) +
+
Handle all other events - discards them.
+
+
+
+

Public functions

+
+
+ void clear() +
+
Clears all bindings.
+
+ void clear(int player) +
+
Clears all bindings for a specific player.
+
+ void bind(const InputBindings& bindings, + int player = 0) +
+
Sets the bindings for a specific player.
+
+ void gamepad(int player, + int gamepad) +
+
Sets the gamepad for a specific player.
+
+ auto gamepad(int player) const -> int +
+
Gets the gamepad for a specific player.
+
+ auto pressed(const char* actionName, + int player = 0) const -> bool +
+
Gets an action state for a specific player.
+
+ auto axis(const char* axisName, + int player = 0) const -> float +
+
Gets an axis value for a specific player.
+
+ void handle(const core::io::Window& window, + const core::io::KeyEvent& event) +
+
Handle a key event.
+
+ void handle(const core::io::Window& window, + const core::io::GamepadConnectionEvent& event) +
+
Handle a gamepad connection event.
+
+ void handle(const core::io::Window& window, + const core::io::MouseButtonEvent& event) +
+
Handle a mouse button event.
+
+ void handle(const core::io::Window& window, + const core::io::MouseMoveEvent& event) +
+
Handle a mouse movement event.
+
+ void updateMouse() +
+
Resets the previous mouse position to equal the current.
+
+ auto mousePosition() const -> glm::ivec2 +
+
Gets the mouse position in screen space.
+
+ auto previousMousePosition() const -> glm::ivec2 +
+
Gets the mouse position in the previous frame in screen space.
+
+ auto mouseDelta() const -> glm::ivec2 +
+
Gets displacement of the mouse during the last frame, in screen space.
+
+ void pollGamepads(const core::io::Window& window) +
+
Polls the input state of the gamepads.
+
+ auto bindings() const -> const std::unordered_map<int, InputBindings>& +
+
Gets the bindings for each player.
+
+
+
+

Function documentation

+
+

+ static void cubos::engine::Input::handle(const core::io::Window& window, + const core::io::WindowEvent& event) +

+

Handle all other events - discards them.

+ + + + + + + + + + + + + + +
Parameters
windowWindow that received the event.
eventEvent to discard.
+

This is method exists so that std::visit can be used with core::io::WindowEvent on handle().

+
+
+

+ void cubos::engine::Input::clear(int player) +

+

Clears all bindings for a specific player.

+ + + + + + + + + + +
Parameters
playerPlayer whose bindings will be cleared.
+
+
+

+ void cubos::engine::Input::bind(const InputBindings& bindings, + int player = 0) +

+

Sets the bindings for a specific player.

+ + + + + + + + + + + + + + +
Parameters
bindingsBindings to set.
playerPlayer whose bindings will be set.
+
+
+

+ void cubos::engine::Input::gamepad(int player, + int gamepad) +

+

Sets the gamepad for a specific player.

+ + + + + + + + + + + + + + +
Parameters
playerPlayer whose gamepad will be set.
gamepadGamepad to set.
+
+
+

+ int cubos::engine::Input::gamepad(int player) const +

+

Gets the gamepad for a specific player.

+ + + + + + + + + + + + + + + + +
Parameters
playerPlayer whose gamepad will be retrieved.
ReturnsGamepad if it exists, -1 otherwise.
+
+
+

+ bool cubos::engine::Input::pressed(const char* actionName, + int player = 0) const +

+

Gets an action state for a specific player.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
actionNameName of the action.
playerPlayer whose action state will be retrieved.
ReturnsWhether the action exists and is pressed.
+
+
+

+ float cubos::engine::Input::axis(const char* axisName, + int player = 0) const +

+

Gets an axis value for a specific player.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
axisNameName of the axis.
playerPlayer whose axis value will be retrieved.
ReturnsAxis value if the axis exists, 0.0 otherwise.
+
+
+

+ void cubos::engine::Input::handle(const core::io::Window& window, + const core::io::KeyEvent& event) +

+

Handle a key event.

+ + + + + + + + + + + + + + +
Parameters
windowWindow that received the event.
eventKey event.
+
+
+

+ void cubos::engine::Input::handle(const core::io::Window& window, + const core::io::GamepadConnectionEvent& event) +

+

Handle a gamepad connection event.

+ + + + + + + + + + + + + + +
Parameters
windowWindow that received the event.
eventGamepad connection event.
+
+
+

+ void cubos::engine::Input::handle(const core::io::Window& window, + const core::io::MouseButtonEvent& event) +

+

Handle a mouse button event.

+ + + + + + + + + + + + + + +
Parameters
windowWindow that received the event.
eventMouse button event.
+
+
+

+ void cubos::engine::Input::handle(const core::io::Window& window, + const core::io::MouseMoveEvent& event) +

+

Handle a mouse movement event.

+ + + + + + + + + + + + + + +
Parameters
windowWindow that received the event.
eventMouse movement event.
+
+
+

+ glm::ivec2 cubos::engine::Input::mousePosition() const +

+

Gets the mouse position in screen space.

+ + + + + + + +
ReturnsMouse position.
+
+
+

+ glm::ivec2 cubos::engine::Input::previousMousePosition() const +

+

Gets the mouse position in the previous frame in screen space.

+ + + + + + + +
ReturnsMouse position in the previous frame.
+
+
+

+ glm::ivec2 cubos::engine::Input::mouseDelta() const +

+

Gets displacement of the mouse during the last frame, in screen space.

+ + + + + + + +
ReturnsMouse displacement.
+
+
+

+ void cubos::engine::Input::pollGamepads(const core::io::Window& window) +

+

Polls the input state of the gamepads.

+ + + + + + + + + + +
Parameters
windowWindow to poll the gamepad state from.
+
+
+

+ const std::unordered_map<int, InputBindings>& cubos::engine::Input::bindings() const +

+

Gets the bindings for each player.

+ + + + + + + +
ReturnsBindings for each player.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1InputAction.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1InputAction.html new file mode 100644 index 000000000..0400dff02 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1InputAction.html @@ -0,0 +1,313 @@ + + + + + cubos::engine::InputAction class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::InputAction class final + +

+

Stores the state of a single input action, such as "jump" or "attack".

+ +

Can be bound to multiple keys, and will be considered "pressed" if any of them are pressed.

+
+

Constructors, destructors, conversion operators

+
+
+ InputAction() defaulted +
+
Constructs without any bindings.
+
+ InputAction(std::vector<core::io::KeyWithModifiers> keys, + std::vector<core::io::GamepadButton> gamepadButtons, + std::vector<core::io::MouseButton> mouseButtons) +
+
Constructs with existing bindings.
+
+
+
+

Public functions

+
+
+ auto keys() const -> const std::vector<core::io::KeyWithModifiers>& +
+
Gets the key bindings.
+
+ auto keys() -> std::vector<core::io::KeyWithModifiers>& +
+
Gets the key bindings.
+
+ auto gamepadButtons() const -> const std::vector<core::io::GamepadButton>& +
+
Gets the gamepad button bindings.
+
+ auto gamepadButtons() -> std::vector<core::io::GamepadButton>& +
+
Gets the gamepad button bindings.
+
+ auto mouseButtons() const -> const std::vector<core::io::MouseButton>& +
+
Gets the mouse button bindings.
+
+ auto mouseButtons() -> std::vector<core::io::MouseButton>& +
+
Gets the mouse button bindings.
+
+ auto pressed() const -> bool +
+
Checks if this action is pressed.
+
+ void pressed(bool pressed) +
+
Sets whether this action is pressed.
+
+
+
+

Function documentation

+
+

+ cubos::engine::InputAction::InputAction(std::vector<core::io::KeyWithModifiers> keys, + std::vector<core::io::GamepadButton> gamepadButtons, + std::vector<core::io::MouseButton> mouseButtons) +

+

Constructs with existing bindings.

+ + + + + + + + + + + + + + + + + + +
Parameters
keysKey bindings.
gamepadButtonsGamepad button bindings.
mouseButtonsMouse button bindings.
+
+
+

+ const std::vector<core::io::KeyWithModifiers>& cubos::engine::InputAction::keys() const +

+

Gets the key bindings.

+ + + + + + + +
ReturnsVector of keys.
+
+
+

+ std::vector<core::io::KeyWithModifiers>& cubos::engine::InputAction::keys() +

+

Gets the key bindings.

+ + + + + + + +
ReturnsVector of keys.
+
+
+

+ const std::vector<core::io::GamepadButton>& cubos::engine::InputAction::gamepadButtons() const +

+

Gets the gamepad button bindings.

+ + + + + + + +
ReturnsVector of buttons.
+
+
+

+ std::vector<core::io::GamepadButton>& cubos::engine::InputAction::gamepadButtons() +

+

Gets the gamepad button bindings.

+ + + + + + + +
ReturnsVector of buttons.
+
+
+

+ const std::vector<core::io::MouseButton>& cubos::engine::InputAction::mouseButtons() const +

+

Gets the mouse button bindings.

+ + + + + + + +
ReturnsVector of buttons.
+
+
+

+ std::vector<core::io::MouseButton>& cubos::engine::InputAction::mouseButtons() +

+

Gets the mouse button bindings.

+ + + + + + + +
ReturnsVector of buttons.
+
+
+

+ bool cubos::engine::InputAction::pressed() const +

+

Checks if this action is pressed.

+ + + + + + + +
ReturnsWhether this action is pressed.
+
+
+

+ void cubos::engine::InputAction::pressed(bool pressed) +

+

Sets whether this action is pressed.

+ + + + + + + + + + +
Parameters
pressedNew pressed state.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1InputAxis.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1InputAxis.html new file mode 100644 index 000000000..65876c9d1 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1InputAxis.html @@ -0,0 +1,313 @@ + + + + + cubos::engine::InputAxis class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::InputAxis class final + +

+

Stores the state of a single input axis, such as "move forward" or "move right".

+ +

Can be bound to multiple keys, and will have a value in the range [-1, 1] based on the the state of its bindings.

+
+

Constructors, destructors, conversion operators

+
+
+ InputAxis() defaulted +
+
Constructs without any bindings.
+
+ InputAxis(std::vector<core::io::KeyWithModifiers> positive, + std::vector<core::io::KeyWithModifiers> negative, + std::vector<core::io::GamepadAxis> gamepadAxes) +
+
Constructs with existing bindings.
+
+
+
+

Public functions

+
+
+ auto positive() const -> const std::vector<core::io::KeyWithModifiers>& +
+
Gets the positive key bindings.
+
+ auto negative() const -> const std::vector<core::io::KeyWithModifiers>& +
+
Gets the negative key bindings.
+
+ auto gamepadAxes() const -> const std::vector<core::io::GamepadAxis>& +
+
Gets the gamepad axis bindings.
+
+ auto positive() -> std::vector<core::io::KeyWithModifiers>& +
+
Gets the positive key bindings.
+
+ auto negative() -> std::vector<core::io::KeyWithModifiers>& +
+
Gets the negative key bindings.
+
+ auto gamepadAxes() -> std::vector<core::io::GamepadAxis>& +
+
Gets the gamepad axis bindings.
+
+ auto value() const -> float +
+
Gets the value.
+
+ void value(float value) +
+
Sets the value.
+
+
+
+

Function documentation

+
+

+ cubos::engine::InputAxis::InputAxis(std::vector<core::io::KeyWithModifiers> positive, + std::vector<core::io::KeyWithModifiers> negative, + std::vector<core::io::GamepadAxis> gamepadAxes) +

+

Constructs with existing bindings.

+ + + + + + + + + + + + + + + + + + +
Parameters
positivePositive key bindings.
negativeNegative key bindings.
gamepadAxesGamepad axis bindings.
+
+
+

+ const std::vector<core::io::KeyWithModifiers>& cubos::engine::InputAxis::positive() const +

+

Gets the positive key bindings.

+ + + + + + + +
ReturnsVector of positive keys.
+
+
+

+ const std::vector<core::io::KeyWithModifiers>& cubos::engine::InputAxis::negative() const +

+

Gets the negative key bindings.

+ + + + + + + +
ReturnsVector of negative keys.
+
+
+

+ const std::vector<core::io::GamepadAxis>& cubos::engine::InputAxis::gamepadAxes() const +

+

Gets the gamepad axis bindings.

+ + + + + + + +
ReturnsVector of gamepad axes.
+
+
+

+ std::vector<core::io::KeyWithModifiers>& cubos::engine::InputAxis::positive() +

+

Gets the positive key bindings.

+ + + + + + + +
ReturnsVector of positive keys.
+
+
+

+ std::vector<core::io::KeyWithModifiers>& cubos::engine::InputAxis::negative() +

+

Gets the negative key bindings.

+ + + + + + + +
ReturnsVector of negative keys.
+
+
+

+ std::vector<core::io::GamepadAxis>& cubos::engine::InputAxis::gamepadAxes() +

+

Gets the gamepad axis bindings.

+ + + + + + + +
ReturnsVector of gamepad axes.
+
+
+

+ float cubos::engine::InputAxis::value() const +

+

Gets the value.

+ + + + + + + +
ReturnsValue.
+
+
+

+ void cubos::engine::InputAxis::value(float value) +

+

Sets the value.

+ + + + + + + + + + +
Parameters
valueNew value.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1InputBindings.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1InputBindings.html new file mode 100644 index 000000000..5a0f7f018 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1InputBindings.html @@ -0,0 +1,195 @@ + + + + + cubos::engine::InputBindings class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::InputBindings class final + +

+

Stores the input bindings for a single player.

+ +

It contains a map of input actions and a map of input axes.

+
+

Public functions

+
+
+ auto actions() const -> const std::unordered_map<std::string, InputAction>& +
+
Gets the input actions map.
+
+ auto axes() const -> const std::unordered_map<std::string, InputAxis>& +
+
Gets the input axes map.
+
+ auto actions() -> std::unordered_map<std::string, InputAction>& +
+
Gets the input actions map.
+
+ auto axes() -> std::unordered_map<std::string, InputAxis>& +
+
Gets the input axes map.
+
+
+
+

Function documentation

+
+

+ const std::unordered_map<std::string, InputAction>& cubos::engine::InputBindings::actions() const +

+

Gets the input actions map.

+ + + + + + + +
ReturnsInput actions map.
+
+
+

+ const std::unordered_map<std::string, InputAxis>& cubos::engine::InputBindings::axes() const +

+

Gets the input axes map.

+ + + + + + + +
ReturnsInput axes map.
+
+
+

+ std::unordered_map<std::string, InputAction>& cubos::engine::InputBindings::actions() +

+

Gets the input actions map.

+ + + + + + + +
ReturnsInput actions map.
+
+
+

+ std::unordered_map<std::string, InputAxis>& cubos::engine::InputBindings::axes() +

+

Gets the input axes map.

+ + + + + + + +
ReturnsInput axes map.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1JSONBridge.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1JSONBridge.html new file mode 100644 index 000000000..9eaaa5779 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1JSONBridge.html @@ -0,0 +1,239 @@ + + + + + cubos::engine::JSONBridge class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::engine::JSONBridge class +

+

Bridge for loading and saving assets which are serialized to and from a JSON file.

+ + + + + + + + + + +
Template parameters
TType of asset to load and save. Must be default constructible.
+ +

This bridge automatically serializes and deserializes assets of type T to and from a JSON file. Thus, T must be serializable and deserializable. No additional context is given to the serializer or deserializer.

+
+

Base classes

+
+
+ class FileBridge +
+
Abstract bridge type defined to reduce boilerplate code in bridge implementations which open a single file to load and save assets.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ JSONBridge() +
+
Constructs a bridge.
+
+
+
+

Protected functions

+
+
+ auto loadFromFile(Assets& assets, + const AnyAsset& handle, + core::memory::Stream& stream) -> bool override +
+
Loads an asset from a file stream.
+
+ auto saveToFile(const Assets& assets, + const AnyAsset& handle, + core::memory::Stream& stream) -> bool override +
+
Saves an asset to a file stream.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ bool cubos::engine::JSONBridge<T>::loadFromFile(Assets& assets, + const AnyAsset& handle, + core::memory::Stream& stream) override protected +

+

Loads an asset from a file stream.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
assetsManager to write into.
handleHandle of the asset being loaded.
streamFile stream.
ReturnsWhether the asset was successfully loaded.
+
+
+

+
+ template<typename T> +
+ bool cubos::engine::JSONBridge<T>::saveToFile(const Assets& assets, + const AnyAsset& handle, + core::memory::Stream& stream) override protected +

+

Saves an asset to a file stream.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
assetsManager to read from.
handleHandle of the asset being saved.
streamFile stream.
ReturnsWhether the asset was successfully saved.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1PostProcessingBloom.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1PostProcessingBloom.html new file mode 100644 index 000000000..107a48732 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1PostProcessingBloom.html @@ -0,0 +1,393 @@ + + + + + cubos::engine::PostProcessingBloom class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::PostProcessingBloom class + +

+

A post processing pass that adds a "bloom" effect to any bright objects in the scene.

+ +

Implementation based on the following tutorial.

+
+

Base classes

+
+
+ class PostProcessingPass +
+
A generic post processing pass.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ PostProcessingBloom(core::gl::RenderDevice& renderDevice, + glm::uvec2 size) +
+
Constructs with default arguments.
+
+ PostProcessingBloom(core::gl::RenderDevice& renderDevice, + glm::uvec2 size, + unsigned int iterations, + float threshold, + float softThreshold, + float intensity) +
+
Constructs with custom settings.
+
+
+
+

Public functions

+
+
+ auto getThreshold() const -> float +
+
Gets the threshold for the bloom effect.
+
+ auto getSoftThreshold() const -> float +
+
Gets the soft threshold ratio.
+
+ auto getIntensity() const -> float +
+
Gets the intensity of the bloom effect.
+
+ void setThreshold(float threshold) +
+
Sets the threshold for the bloom effect.
+
+ void setSoftThreshold(float softThreshold) +
+
Sets the soft threshold ratio.
+
+ void setIntensity(float intensity) +
+
Sets the intensity of the bloom effect.
+
+ void generateTextures() +
+
Generates the textures used by the pass.
+
+ void resize(glm::uvec2 size) override +
+
Called when the window framebuffer size changes.
+
+ void execute(std::map<PostProcessingInput, core::gl::Texture2D>& inputs, + core::gl::Texture2D prev, + core::gl::Framebuffer out) const override +
+
Called each frame.
+
+
+
+

Function documentation

+
+

+ cubos::engine::PostProcessingBloom::PostProcessingBloom(core::gl::RenderDevice& renderDevice, + glm::uvec2 size) +

+

Constructs with default arguments.

+ + + + + + + + + + + + + + +
Parameters
renderDeviceRender device to use.
sizeSize of the window.
+
+
+

+ cubos::engine::PostProcessingBloom::PostProcessingBloom(core::gl::RenderDevice& renderDevice, + glm::uvec2 size, + unsigned int iterations, + float threshold, + float softThreshold, + float intensity) +

+

Constructs with custom settings.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
renderDeviceRender device to use.
sizeSize of the window.
iterationsNumber of iterations for downsample/upsample step
thresholdPixel brightness threshold to be considered for bloom effect
softThresholdRatio for including pixels that don't pass the threshold test
intensityIntensity of the bloom effect.
+
+
+

+ float cubos::engine::PostProcessingBloom::getThreshold() const +

+

Gets the threshold for the bloom effect.

+ + + + + + + +
ReturnsThreshold for the bloom effect.
+
+
+

+ float cubos::engine::PostProcessingBloom::getSoftThreshold() const +

+

Gets the soft threshold ratio.

+ + + + + + + +
ReturnsSoft threshold ratio.
+
+
+

+ float cubos::engine::PostProcessingBloom::getIntensity() const +

+

Gets the intensity of the bloom effect.

+ + + + + + + +
ReturnsIntensity of the bloom effect.
+
+
+

+ void cubos::engine::PostProcessingBloom::setThreshold(float threshold) +

+

Sets the threshold for the bloom effect.

+ + + + + + + + + + +
Parameters
thresholdNew threshold.
+
+
+

+ void cubos::engine::PostProcessingBloom::setSoftThreshold(float softThreshold) +

+

Sets the soft threshold ratio.

+ + + + + + + + + + +
Parameters
softThresholdRatio for including pixels that don't pass the threshold test.
+
+
+

+ void cubos::engine::PostProcessingBloom::setIntensity(float intensity) +

+

Sets the intensity of the bloom effect.

+ + + + + + + + + + +
Parameters
intensityIntensity of the bloom effect.
+
+
+

+ void cubos::engine::PostProcessingBloom::resize(glm::uvec2 size) override +

+

Called when the window framebuffer size changes.

+ + + + + + + + + + +
Parameters
sizeNew size of the window.
+
+
+

+ void cubos::engine::PostProcessingBloom::execute(std::map<PostProcessingInput, core::gl::Texture2D>& inputs, + core::gl::Texture2D prev, + core::gl::Framebuffer out) const override +

+

Called each frame.

+ + + + + + + + + + + + + + + + + + +
Parameters
inputsAvailable extra input textures.
prevResulting texture of the previous pass.
outFramebuffer where the pass will render to.
+

The inputs argument is mutable to allow passes to their own inputs for future passes. This argument is used, for example, to pass the extra outputs of the deferred renderer to the post processing passes which might need them.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1PostProcessingCopy.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1PostProcessingCopy.html new file mode 100644 index 000000000..d448f6bb2 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1PostProcessingCopy.html @@ -0,0 +1,221 @@ + + + + + cubos::engine::PostProcessingCopy class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::PostProcessingCopy class + +

+

A simple post processing pass that copies the input texture to the output.

+ +

This pass is useless and is only used as an example and for testing.

+
+

Base classes

+
+
+ class PostProcessingPass +
+
A generic post processing pass.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ PostProcessingCopy(core::gl::RenderDevice& renderDevice, + glm::uvec2 size) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ void resize(glm::uvec2 size) override +
+
Called when the window framebuffer size changes.
+
+ void execute(std::map<PostProcessingInput, core::gl::Texture2D>& inputs, + core::gl::Texture2D prev, + core::gl::Framebuffer out) const override +
+
Called each frame.
+
+
+
+

Function documentation

+
+

+ cubos::engine::PostProcessingCopy::PostProcessingCopy(core::gl::RenderDevice& renderDevice, + glm::uvec2 size) +

+

Constructs.

+ + + + + + + + + + + + + + +
Parameters
renderDeviceRender device to use.
sizeSize of the window.
+
+
+

+ void cubos::engine::PostProcessingCopy::resize(glm::uvec2 size) override +

+

Called when the window framebuffer size changes.

+ + + + + + + + + + +
Parameters
sizeNew size of the window.
+
+
+

+ void cubos::engine::PostProcessingCopy::execute(std::map<PostProcessingInput, core::gl::Texture2D>& inputs, + core::gl::Texture2D prev, + core::gl::Framebuffer out) const override +

+

Called each frame.

+ + + + + + + + + + + + + + + + + + +
Parameters
inputsAvailable extra input textures.
prevResulting texture of the previous pass.
outFramebuffer where the pass will render to.
+

The inputs argument is mutable to allow passes to their own inputs for future passes. This argument is used, for example, to pass the extra outputs of the deferred renderer to the post processing passes which might need them.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1PostProcessingManager.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1PostProcessingManager.html new file mode 100644 index 000000000..d1a858d32 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1PostProcessingManager.html @@ -0,0 +1,296 @@ + + + + + cubos::engine::PostProcessingManager class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::PostProcessingManager class final + +

+

Responsible for managing the post processing passes.

+ +

This class is renderer agnostic. It can be used with any renderer implementation. Passes are executed in the order they are added, and take as input the output of the previous pass and the outputs of the renderer.

+
+

Constructors, destructors, conversion operators

+
+
+ PostProcessingManager(core::gl::RenderDevice& renderDevice, + glm::uvec2 size) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ void resize(glm::uvec2 size) +
+
Called when the window framebuffer size changes.
+
+ void provideInput(PostProcessingInput input, + core::gl::Texture2D texture) +
+
Provides a texture input to be used by the passes.
+
+
template<typename T>
+ auto addPass() -> std::size_t +
+
Adds a pass to the manager.
+
+ void removePass(std::size_t id) +
+
Removes a pass from the manager.
+
+ void execute(const core::gl::Framebuffer& out) +
+
Applies all post processing passes sequentially, and outputs the result to the given framebuffer.
+
+ auto passCount() const -> std::size_t +
+
Gets the number of passes in the manager.
+
+
+
+

Function documentation

+
+

+ cubos::engine::PostProcessingManager::PostProcessingManager(core::gl::RenderDevice& renderDevice, + glm::uvec2 size) +

+

Constructs.

+ + + + + + + + + + + + + + +
Parameters
renderDeviceRender device to use.
sizeSize of the window.
+
+
+

+ void cubos::engine::PostProcessingManager::resize(glm::uvec2 size) +

+

Called when the window framebuffer size changes.

+ + + + + + + + + + +
Parameters
sizeNew size of the window.
+
+
+

+ void cubos::engine::PostProcessingManager::provideInput(PostProcessingInput input, + core::gl::Texture2D texture) +

+

Provides a texture input to be used by the passes.

+ + + + + + + + + + + + + + +
Parameters
inputInput identifier.
textureTexture to provide.
+
+
+

+
+ template<typename T> +
+ std::size_t cubos::engine::PostProcessingManager::addPass() +

+

Adds a pass to the manager.

+ + + + + + + + + + + + + + + + +
Template parameters
TType of the pass to add.
ReturnsID of the pass.
+
+
+

+ void cubos::engine::PostProcessingManager::removePass(std::size_t id) +

+

Removes a pass from the manager.

+ + + + + + + + + + +
Parameters
idID of the pass.
+
+
+

+ void cubos::engine::PostProcessingManager::execute(const core::gl::Framebuffer& out) +

+

Applies all post processing passes sequentially, and outputs the result to the given framebuffer.

+ + + + + + + + + + +
Parameters
outFramebuffer to output to.
+

The lighting input must have been provided before calling this function, since it acts as the input for the first pass.

+
+
+

+ std::size_t cubos::engine::PostProcessingManager::passCount() const +

+

Gets the number of passes in the manager.

+ + + + + + + +
ReturnsNumber of passes.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1PostProcessingPass.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1PostProcessingPass.html new file mode 100644 index 000000000..55c6f6428 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1PostProcessingPass.html @@ -0,0 +1,233 @@ + + + + + cubos::engine::PostProcessingPass class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::PostProcessingPass class + +

+

A generic post processing pass.

+ +

All passes must have the same constructor arguments: the render device and the size of the window. They should never be constructed directly, and instead should be created using the PostProcessingManager.

+
+

Derived classes

+
+
+ class PostProcessingBloom +
+
A post processing pass that adds a "bloom" effect to any bright objects in the scene.
+
+ class PostProcessingCopy +
+
A simple post processing pass that copies the input texture to the output.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ PostProcessingPass(core::gl::RenderDevice& renderDevice) +
+
Constructs.
+
+ PostProcessingPass(const PostProcessingPass&) deleted +
+
Deleted copy constructor.
+
+
+
+

Public functions

+
+
+ void resize(glm::uvec2 size) pure virtual +
+
Called when the window framebuffer size changes.
+
+ void execute(std::map<PostProcessingInput, core::gl::Texture2D>& inputs, + core::gl::Texture2D prev, + core::gl::Framebuffer out) const pure virtual +
+
Called each frame.
+
+
+
+

Protected variables

+
+
+ core::gl::RenderDevice& mRenderDevice +
+
Render device to use.
+
+
+
+

Function documentation

+
+

+ cubos::engine::PostProcessingPass::PostProcessingPass(core::gl::RenderDevice& renderDevice) +

+

Constructs.

+ + + + + + + + + + +
Parameters
renderDeviceRender device to use.
+
+
+

+ void cubos::engine::PostProcessingPass::resize(glm::uvec2 size) pure virtual +

+

Called when the window framebuffer size changes.

+ + + + + + + + + + +
Parameters
sizeNew size of the window.
+
+
+

+ void cubos::engine::PostProcessingPass::execute(std::map<PostProcessingInput, core::gl::Texture2D>& inputs, + core::gl::Texture2D prev, + core::gl::Framebuffer out) const pure virtual +

+

Called each frame.

+ + + + + + + + + + + + + + + + + + +
Parameters
inputsAvailable extra input textures.
prevResulting texture of the previous pass.
outFramebuffer where the pass will render to.
+

The inputs argument is mutable to allow passes to their own inputs for future passes. This argument is used, for example, to pass the extra outputs of the deferred renderer to the post processing passes which might need them.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1RendererFrame.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1RendererFrame.html new file mode 100644 index 000000000..89a627958 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1RendererFrame.html @@ -0,0 +1,416 @@ + + + + + cubos::engine::RendererFrame class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::RendererFrame class final + +

+

Resource which describes a scene to be drawn by the renderer.

+ +

Each frame, the Renderer will query entities with renderer components, such as RenderableGrid and PointLight, and add them to the RendererFrame.

+
+

Public types

+
+
+ struct DrawCmd +
+
Data of a single draw command.
+
+
+
+

Public functions

+
+
+ void draw(RendererGrid grid, + glm::mat4 modelMat, + uint32_t entityIndex) +
+
Submits a draw command.
+
+ void ambient(const glm::vec3& color) +
+
Sets the ambient light of the scene.
+
+ void skyGradient(glm::vec3 bottom, + glm::vec3 top) +
+
Sets the sky gradient of the scene.
+
+ void light(glm::mat4 transform, + const SpotLight& light) +
+
Adds a spot light to the frame.
+
+ void light(glm::mat4 transform, + const DirectionalLight& light) +
+
Adds a directional light to the frame.
+
+ void light(glm::mat4 transform, + const PointLight& light) +
+
Adds a point light to the frame.
+
+ void clear() +
+
Clears the frame, removing all draw calls and lights.
+
+ auto drawCmds() const -> const std::vector<DrawCmd>& +
+
Gets all of the draw commands stored in the frame.
+
+ auto ambient() const -> const glm::vec3& +
+
Gets the ambient light of the scene.
+
+ auto skyGradient(int i) const -> const glm::vec3& +
+
Gets the sky gradient of the scene.
+
+ auto spotLights() const -> const std::vector<std::pair<glm::mat4, SpotLight>>& +
+
Gets the spot lights of the frame.
+
+ auto directionalLights() const -> const std::vector<std::pair<glm::mat4, DirectionalLight>>& +
+
Gets the directional lights of the frame.
+
+ auto pointLights() const -> const std::vector<std::pair<glm::mat4, PointLight>>& +
+
Gets the point lights of the frame.
+
+
+
+

Function documentation

+
+

+ void cubos::engine::RendererFrame::draw(RendererGrid grid, + glm::mat4 modelMat, + uint32_t entityIndex) +

+

Submits a draw command.

+ + + + + + + + + + + + + + + + + + +
Parameters
gridHandle of the grid to draw.
modelMatModel matrix of the grid, used for applying transformations.
entityIndexIdentifier of the entity being drawn.
+
+
+

+ void cubos::engine::RendererFrame::ambient(const glm::vec3& color) +

+

Sets the ambient light of the scene.

+ + + + + + + + + + +
Parameters
colorColor of the ambient light.
+
+
+

+ void cubos::engine::RendererFrame::skyGradient(glm::vec3 bottom, + glm::vec3 top) +

+

Sets the sky gradient of the scene.

+ + + + + + + + + + + + + + +
Parameters
bottomBottom sky color.
topTop sky color.
+
+
+

+ void cubos::engine::RendererFrame::light(glm::mat4 transform, + const SpotLight& light) +

+

Adds a spot light to the frame.

+ + + + + + + + + + + + + + +
Parameters
transformLight transform matrix.
lightSpot light to add.
+
+
+

+ void cubos::engine::RendererFrame::light(glm::mat4 transform, + const DirectionalLight& light) +

+

Adds a directional light to the frame.

+ + + + + + + + + + + + + + +
Parameters
transformLight transform matrix.
lightDirectional light to add.
+
+
+

+ void cubos::engine::RendererFrame::light(glm::mat4 transform, + const PointLight& light) +

+

Adds a point light to the frame.

+ + + + + + + + + + + + + + +
Parameters
transformLight transform matrix.
lightPoint light to add.
+
+
+

+ const std::vector<DrawCmd>& cubos::engine::RendererFrame::drawCmds() const +

+

Gets all of the draw commands stored in the frame.

+ + + + + + + +
ReturnsDraw commands.
+
+
+

+ const glm::vec3& cubos::engine::RendererFrame::ambient() const +

+

Gets the ambient light of the scene.

+ + + + + + + +
ReturnsDmbient light.
+
+
+

+ const glm::vec3& cubos::engine::RendererFrame::skyGradient(int i) const +

+

Gets the sky gradient of the scene.

+ + + + + + + + + + + + + + + + +
Parameters
iIndex of the color (0 = bottom, 1 = top).
ReturnsAmbient light.
+
+
+

+ const std::vector<std::pair<glm::mat4, SpotLight>>& cubos::engine::RendererFrame::spotLights() const +

+

Gets the spot lights of the frame.

+ + + + + + + +
ReturnsSpot lights.
+
+
+

+ const std::vector<std::pair<glm::mat4, DirectionalLight>>& cubos::engine::RendererFrame::directionalLights() const +

+

Gets the directional lights of the frame.

+ + + + + + + +
ReturnsDirectional lights.
+
+
+

+ const std::vector<std::pair<glm::mat4, PointLight>>& cubos::engine::RendererFrame::pointLights() const +

+

Gets the point lights of the frame.

+ + + + + + + +
ReturnsPoint lights.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1SceneBridge.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1SceneBridge.html new file mode 100644 index 000000000..87462feca --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1SceneBridge.html @@ -0,0 +1,300 @@ + + + + + cubos::engine::SceneBridge class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::SceneBridge class + +

+

Bridge which loads and saves Scene assets.

+ +

Scenes are stored as JSON files with two top-level objects:

  • "imports" - a dictionary of names to asset IDs of other scenes to import.
  • "entities" - a dictionary of names to serialized entities.

Entities imported from sub-scenes can be overriden by defining them in the current scene. For example:

{
+    "imports": {
+        "foo": "6f42ae5a-59d1-5df3-8720-83b8df6dd536"
+    },
+    "entities": {
+        "baz": {
+            "cubos::engine::Position": {
+                "x": 10
+            }
+        },
+        "foo.bar": {
+            "Parent": "baz",
+        }
+    }
+}

This scene will import the sub-scene with ID 6f42ae5a-59d1-5df3-8720-83b8df6dd536, and prefix all of its entities with foo.. The entity foo.bar will override the entity bar from the imported scene, while the entity baz will be added to the scene.

+
+

Base classes

+
+
+ class FileBridge +
+
Abstract bridge type defined to reduce boilerplate code in bridge implementations which open a single file to load and save assets.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ SceneBridge(core::reflection::TypeRegistry components, + core::reflection::TypeRegistry relations) +
+
Constructs a bridge.
+
+
+
+

Public functions

+
+
+ auto components() -> core::reflection::TypeRegistry& +
+
Returns the type registry used to deserialize components.
+
+ auto relations() -> core::reflection::TypeRegistry& +
+
Returns the type registry used to deserialize relations.
+
+
+
+

Protected functions

+
+
+ auto loadFromFile(Assets& assets, + const AnyAsset& handle, + core::memory::Stream& stream) -> bool override +
+
Loads an asset from a file stream.
+
+ auto saveToFile(const Assets& assets, + const AnyAsset& handle, + core::memory::Stream& stream) -> bool override +
+
Saves an asset to a file stream.
+
+
+
+

Function documentation

+
+

+ cubos::engine::SceneBridge::SceneBridge(core::reflection::TypeRegistry components, + core::reflection::TypeRegistry relations) +

+

Constructs a bridge.

+ + + + + + + + + + + + + + +
Parameters
componentsComponent type registry.
relationsRelation type registry.
+
+
+

+ core::reflection::TypeRegistry& cubos::engine::SceneBridge::components() +

+

Returns the type registry used to deserialize components.

+ + + + + + + +
ReturnsComponent type registry.
+
+
+

+ core::reflection::TypeRegistry& cubos::engine::SceneBridge::relations() +

+

Returns the type registry used to deserialize relations.

+ + + + + + + +
ReturnsRelations type registry.
+
+
+

+ bool cubos::engine::SceneBridge::loadFromFile(Assets& assets, + const AnyAsset& handle, + core::memory::Stream& stream) override protected +

+

Loads an asset from a file stream.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
assetsManager to write into.
handleHandle of the asset being loaded.
streamFile stream.
ReturnsWhether the asset was successfully loaded.
+
+
+

+ bool cubos::engine::SceneBridge::saveToFile(const Assets& assets, + const AnyAsset& handle, + core::memory::Stream& stream) override protected +

+

Saves an asset to a file stream.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
assetsManager to read from.
handleHandle of the asset being saved.
streamFile stream.
ReturnsWhether the asset was successfully saved.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1ScreenPicker.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1ScreenPicker.html new file mode 100644 index 000000000..58048519b --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1ScreenPicker.html @@ -0,0 +1,243 @@ + + + + + cubos::engine::ScreenPicker class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::ScreenPicker class final + +

+

Resource which provides a texture to store entity/gizmo ids, for selection with a mouse.

+ +
+

Public functions

+
+
+ void init(cubos::core::gl::RenderDevice* currentRenderDevice, + glm::ivec2 size) +
+
Initializes ScreenPicker for a render device.
+
+ void resizeTexture(glm::ivec2 size) +
+
Resizes the picking texture.
+
+ void clearTexture() +
+
Clears the picking texture.
+
+ auto framebuffer() -> core::gl::Framebuffer +
+
Returns the framebuffer used to draw to the picking texture.
+
+ auto at(int x, + int y) const -> uint32_t +
+
Returns the identifier associated to the pixel in the coords (x, y).
+
+ auto size() const -> glm::uvec2 +
+
Returns the size of the picking texture in pixels.
+
+
+
+

Function documentation

+
+

+ void cubos::engine::ScreenPicker::init(cubos::core::gl::RenderDevice* currentRenderDevice, + glm::ivec2 size) +

+

Initializes ScreenPicker for a render device.

+ + + + + + + + + + + + + + +
Parameters
currentRenderDeviceCurrent Render device being used.
sizeThe size of the window in pixels.
+
+
+

+ void cubos::engine::ScreenPicker::resizeTexture(glm::ivec2 size) +

+

Resizes the picking texture.

+ + + + + + + + + + +
Parameters
sizeNew size of the texture.
+
+
+

+ core::gl::Framebuffer cubos::engine::ScreenPicker::framebuffer() +

+

Returns the framebuffer used to draw to the picking texture.

+ + + + + + + +
ReturnsFramebuffer used to draw to the picking texture.
+
+
+

+ uint32_t cubos::engine::ScreenPicker::at(int x, + int y) const +

+

Returns the identifier associated to the pixel in the coords (x, y).

+ + + + + + + + + + + + + + + + + + + + +
Parameters
xCoordinate of pixel in x axis
yCoordinate of pixel in y axis
ReturnsEntity or gizmo identifier associated to the pixel in the coords (x, y).
+
+
+

+ glm::uvec2 cubos::engine::ScreenPicker::size() const +

+

Returns the size of the picking texture in pixels.

+ + + + + + + +
ReturnsSize of the picking texture in pixels.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1Settings.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1Settings.html new file mode 100644 index 000000000..26f91909e --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1Settings.html @@ -0,0 +1,436 @@ + + + + + cubos::engine::Settings class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::Settings class final + +

+

Stores settings as key-value pairs and provides methods to retrieve them.

+ +
+

Public functions

+
+
+ void clear() +
+
Clears all the settings.
+
+ void setBool(const std::string& key, + bool value) +
+
Defines a new boolean setting.
+
+ auto getBool(const std::string& key, + bool defaultValue) -> bool +
+
Retrieves the bool setting with the given key.
+
+ void setString(const std::string& key, + const std::string& value) +
+
Defines a new string setting.
+
+ auto getString(const std::string& key, + const std::string& defaultValue) -> std::string +
+
Retrieves the string setting with the given key.
+
+ void setInteger(const std::string& key, + int value) +
+
Defines a new integer setting.
+
+ auto getInteger(const std::string& key, + int defaultValue) -> int +
+
Retrieves the integer setting with the given key.
+
+ void setDouble(const std::string& key, + double value) +
+
Defines a new double setting.
+
+ auto getDouble(const std::string& key, + double defaultValue) -> double +
+
Retrieves the double setting with the given key.
+
+ void merge(const Settings& settingsToMerge) +
+
Merges the settings from settingsToMerge.
+
+ auto getValues() const -> const std::unordered_map<std::string, std::string>& +
+
+
+ auto getValues() -> std::unordered_map<std::string, std::string>& +
+
+
+
+
+

Function documentation

+
+

+ void cubos::engine::Settings::setBool(const std::string& key, + bool value) +

+

Defines a new boolean setting.

+ + + + + + + + + + + + + + +
Parameters
keyKey.
valueValue.
+

If the setting already exists, overwrites its value.

+
+
+

+ bool cubos::engine::Settings::getBool(const std::string& key, + bool defaultValue) +

+

Retrieves the bool setting with the given key.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
keyKey.
defaultValueDefault value.
ReturnsCurrent value.
+

If no setting exists with such key, sets it to defaultValue and returns it. If the setting exists but its value is not "true", returns false.

+
+
+

+ void cubos::engine::Settings::setString(const std::string& key, + const std::string& value) +

+

Defines a new string setting.

+ + + + + + + + + + + + + + +
Parameters
keyKey.
valueValue.
+

If the setting already exists, overwrites its value.

+
+
+

+ std::string cubos::engine::Settings::getString(const std::string& key, + const std::string& defaultValue) +

+

Retrieves the string setting with the given key.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
keyKey.
defaultValueDefault value.
ReturnsCurrent value.
+

If no setting exists with such key, sets it to defaultValue and returns it.

+
+
+

+ void cubos::engine::Settings::setInteger(const std::string& key, + int value) +

+

Defines a new integer setting.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
keyKey.
valueValue.
ReturnsCurrent value.
+

If the setting already exists, overwrites its value.

+
+
+

+ int cubos::engine::Settings::getInteger(const std::string& key, + int defaultValue) +

+

Retrieves the integer setting with the given key.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
keyKey.
defaultValueDefault value.
ReturnsCurrent value.
+

If no setting exists with such key, sets it to defaultValue and returns it. If the setting exists but its value is not a valid integer, returns defaultValue.

+
+
+

+ void cubos::engine::Settings::setDouble(const std::string& key, + double value) +

+

Defines a new double setting.

+ + + + + + + + + + + + + + +
Parameters
keyKey.
valueValue.
+

If the setting already exists, overwrites its value.

+
+
+

+ double cubos::engine::Settings::getDouble(const std::string& key, + double defaultValue) +

+

Retrieves the double setting with the given key.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
keyKey.
defaultValueDefault value.
ReturnsCurrent value.
+

If no setting exists with such key, sets it to defaultValue and returns it. If the setting exists but its value is not a valid double, returns the default value.

+
+
+

+ void cubos::engine::Settings::merge(const Settings& settingsToMerge) +

+

Merges the settings from settingsToMerge.

+ + + + + + + + + + +
Parameters
settingsToMergeSettings to be merged to this instance.
+

If a setting from settingsToMerge is already defined in this instance, its value is overwritten.

+
+
+

+ const std::unordered_map<std::string, std::string>& cubos::engine::Settings::getValues() const +

+ + + + + + + +
ReturnsUnderlying std::unordered_map with the settings.
+
+
+

+ std::unordered_map<std::string, std::string>& cubos::engine::Settings::getValues() +

+ + + + + + + +
ReturnsUnderlying std::unordered_map with the settings.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1VoxelGrid.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1VoxelGrid.html new file mode 100644 index 000000000..201138df7 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1VoxelGrid.html @@ -0,0 +1,367 @@ + + + + + cubos::engine::VoxelGrid class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::VoxelGrid class final + +

+

Represents a voxel object using a 3D grid.

+ + +
+

Constructors, destructors, conversion operators

+
+
+ VoxelGrid() +
+
Constructs an empty single-voxel grid.
+
+ VoxelGrid(const glm::uvec3& size) +
+
Constructs an empty grid with the given size.
+
+ VoxelGrid(const glm::uvec3& size, + const std::vector<uint16_t>& indices) +
+
Constructs a grid with the given size and initial data.
+
+ VoxelGrid(VoxelGrid&& other) noexcept +
+
Move constructs.
+
+
+
+

Public functions

+
+
+ auto operator=(const VoxelGrid& rhs) -> VoxelGrid& +
+
Makes this grid a copy of another grid.
+
+ void setSize(const glm::uvec3& size) +
+
Resizes the grid. New voxels are initialized to 0.
+
+ auto size() const -> const glm::uvec3& +
+
Gets the size of the grid.
+
+ void clear() +
+
Sets all voxels to 0.
+
+ void set(const glm::ivec3& position, + uint16_t mat) +
+
Sets the material index of a voxel.
+
+ auto get(const glm::ivec3& position) const -> uint16_t +
+
Gets the material index of a voxel.
+
+ auto convert(const VoxelPalette& src, + const VoxelPalette& dst, + float minSimilarity) -> bool +
+
Converts the material indices of this grid from one palette to another.
+
+
+
+

Function documentation

+
+

+ cubos::engine::VoxelGrid::VoxelGrid(const glm::uvec3& size) +

+

Constructs an empty grid with the given size.

+ + + + + + + + + + +
Parameters
sizeSize of the grid.
+
+
+

+ cubos::engine::VoxelGrid::VoxelGrid(const glm::uvec3& size, + const std::vector<uint16_t>& indices) +

+

Constructs a grid with the given size and initial data.

+ + + + + + + + + + + + + + +
Parameters
sizeSize of the grid.
indicesMaterial indices of the voxels.
+ +
+
+

+ cubos::engine::VoxelGrid::VoxelGrid(VoxelGrid&& other) noexcept +

+

Move constructs.

+ + + + + + + + + + +
Parameters
otherOther grid.
+
+
+

+ VoxelGrid& cubos::engine::VoxelGrid::operator=(const VoxelGrid& rhs) +

+

Makes this grid a copy of another grid.

+ + + + + + + + + + + + + + + + +
Parameters
rhsOther grid.
ReturnsThis grid, for chaining.
+
+
+

+ void cubos::engine::VoxelGrid::setSize(const glm::uvec3& size) +

+

Resizes the grid. New voxels are initialized to 0.

+ + + + + + + + + + +
Parameters
sizeNew size of the grid.
+
+
+

+ const glm::uvec3& cubos::engine::VoxelGrid::size() const +

+

Gets the size of the grid.

+ + + + + + + +
ReturnsSize of the grid.
+
+
+

+ void cubos::engine::VoxelGrid::set(const glm::ivec3& position, + uint16_t mat) +

+

Sets the material index of a voxel.

+ + + + + + + + + + + + + + +
Parameters
positionVoxel coordinates.
matMaterial index to set.
+
+
+

+ uint16_t cubos::engine::VoxelGrid::get(const glm::ivec3& position) const +

+

Gets the material index of a voxel.

+ + + + + + + + + + + + + + + + +
Parameters
positionVoxel coordinates.
ReturnsMaterial index of the voxel.
+
+
+

+ bool cubos::engine::VoxelGrid::convert(const VoxelPalette& src, + const VoxelPalette& dst, + float minSimilarity) +

+

Converts the material indices of this grid from one palette to another.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
srcOriginal palette.
dstNew palette.
minSimilarityMinimum similarity between two materials to consider them the same.
ReturnsWhether the conversion was successful.
+

For each material, it will search for another material in the second palette which is similar enough to the original one. The conversion fails if no matching index is found.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1VoxelPalette.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1VoxelPalette.html new file mode 100644 index 000000000..27210bcf8 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1VoxelPalette.html @@ -0,0 +1,408 @@ + + + + + cubos::engine::VoxelPalette class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::VoxelPalette class final + +

+

Holds a palette of materials. Supports up to 65535 materials.

+ +

Instead of storing the materials themselves in voxel data, CUBOS. uses palettes, and stores the index of the material in the palette instead.

This allows for more efficient storage of voxel data, since now instead of storing the whole material per each voxel, we just store a 16-bit integer.

+
+

Public types

+
+
+ class Iterator +
+
Used to iterate over materials on the palette.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ VoxelPalette(std::vector<VoxelMaterial>&& materials) +
+
Constructs a palette with the given materials.
+
+ VoxelPalette() defaulted +
+
Constructs an empty palette.
+
+
+
+

Public functions

+
+
+ auto data() const -> const VoxelMaterial* +
+
Gets a pointer to the array of materials on the palette.
+
+ auto size() const -> uint16_t +
+
Gets the number of materials in the palette, excluding the empty material.
+
+ auto get(uint16_t index) const -> const VoxelMaterial& +
+
Gets the material with the given index.
+
+ void set(uint16_t index, + const VoxelMaterial& material) +
+
Sets the material at the given index.
+
+ auto find(const VoxelMaterial& material) const -> uint16_t +
+
Searches for the index of the material most similar with the given material.
+
+ auto add(const VoxelMaterial& material, + float similarity = 1.0F) -> uint16_t +
+
Adds a material to the palette, if one not similar enough already exists.
+
+ auto push(const VoxelMaterial& material) -> uint16_t +
+
Pushes a material to the palette without checking for uniqueness.
+
+ void merge(const VoxelPalette& palette, + float similarity = 1.0F) +
+
Merges another palette into this one.
+
+ auto begin() -> Iterator +
+
Returns an iterator to the first material.
+
+ auto end() -> Iterator +
+
Returns an iterator to the last material.
+
+
+
+

Function documentation

+
+

+ cubos::engine::VoxelPalette::VoxelPalette(std::vector<VoxelMaterial>&& materials) +

+

Constructs a palette with the given materials.

+ + + + + + + + + + +
Parameters
materialsMaterials to add to the palette.
+
+
+

+ const VoxelMaterial* cubos::engine::VoxelPalette::data() const +

+

Gets a pointer to the array of materials on the palette.

+ + + + + + + +
ReturnsPointer to the array of materials on the palette.
+ +
+
+

+ uint16_t cubos::engine::VoxelPalette::size() const +

+

Gets the number of materials in the palette, excluding the empty material.

+ + + + + + + +
ReturnsNumber of materials in the palette.
+
+
+

+ const VoxelMaterial& cubos::engine::VoxelPalette::get(uint16_t index) const +

+

Gets the material with the given index.

+ + + + + + + + + + + + + + + + +
Parameters
indexIndex of the material to get (1-based, 0 is empty).
ReturnsMaterial at the given index.
+
+
+

+ void cubos::engine::VoxelPalette::set(uint16_t index, + const VoxelMaterial& material) +

+

Sets the material at the given index.

+ + + + + + + + + + + + + + +
Parameters
indexIndex of the material to set (1-based, 0 is empty).
materialMaterial to set.
+
+
+

+ uint16_t cubos::engine::VoxelPalette::find(const VoxelMaterial& material) const +

+

Searches for the index of the material most similar with the given material.

+ + + + + + + + + + + + + + + + +
Parameters
materialMaterial to compare with.
ReturnsIndex of the material.
+
+
+

+ uint16_t cubos::engine::VoxelPalette::add(const VoxelMaterial& material, + float similarity = 1.0F) +

+

Adds a material to the palette, if one not similar enough already exists.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
materialMaterial to add.
similarityMinimum similarity for a material to be considered similar enough.
ReturnsIndex of the material in the palette (1-based, 0 is empty).
+ +
+
+

+ uint16_t cubos::engine::VoxelPalette::push(const VoxelMaterial& material) +

+

Pushes a material to the palette without checking for uniqueness.

+ + + + + + + + + + + + + + + + +
Parameters
materialMaterial to push.
ReturnsSize of the palette.
+ +
+
+

+ void cubos::engine::VoxelPalette::merge(const VoxelPalette& palette, + float similarity = 1.0F) +

+

Merges another palette into this one.

+ + + + + + + + + + + + + + +
Parameters
palettePalette to merge.
similarityMinimum similarity for two materials to be merged.
+ +
+
+

+ Iterator cubos::engine::VoxelPalette::begin() +

+

Returns an iterator to the first material.

+ + + + + + + +
ReturnsIterator.
+
+
+

+ Iterator cubos::engine::VoxelPalette::end() +

+

Returns an iterator to the last material.

+ + + + + + + +
ReturnsIterator.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1VoxelPalette_1_1Iterator.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1VoxelPalette_1_1Iterator.html new file mode 100644 index 000000000..007a22222 --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1VoxelPalette_1_1Iterator.html @@ -0,0 +1,103 @@ + + + + + cubos::engine::VoxelPalette::Iterator class | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1impl_1_1RendererGrid.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1impl_1_1RendererGrid.html new file mode 100644 index 000000000..bc6176c2a --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1impl_1_1RendererGrid.html @@ -0,0 +1,103 @@ + + + + + cubos::engine::impl::RendererGrid class | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classcubos_1_1engine_1_1old_1_1JSONBridge.html b/docs-preview/pr-1032/classcubos_1_1engine_1_1old_1_1JSONBridge.html new file mode 100644 index 000000000..defea4daa --- /dev/null +++ b/docs-preview/pr-1032/classcubos_1_1engine_1_1old_1_1JSONBridge.html @@ -0,0 +1,260 @@ + + + + + cubos::engine::old::JSONBridge class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::engine::old::JSONBridge class +

+

Bridge for loading and saving assets which are serialized to and from a JSON file.

+ + + + + + + + + + +
Template parameters
TType of asset to load and save. Must be default constructible.
+ +

This bridge automatically serializes and deserializes assets of type T to and from a JSON file. Thus, T must be serializable and deserializable. No additional context is given to the serializer or deserializer.

+
+

Base classes

+
+
+ class cubos::engine::FileBridge +
+
Abstract bridge type defined to reduce boilerplate code in bridge implementations which open a single file to load and save assets.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ JSONBridge(int indentation = 4) +
+
Constructs a bridge.
+
+
+
+

Protected functions

+
+
+ auto loadFromFile(Assets& assets, + const AnyAsset& handle, + core::memory::Stream& stream) -> bool override +
+
Loads an asset from a file stream.
+
+ auto saveToFile(const Assets& assets, + const AnyAsset& handle, + core::memory::Stream& stream) -> bool override +
+
Saves an asset to a file stream.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ cubos::engine::old::JSONBridge<T>::JSONBridge(int indentation = 4) +

+

Constructs a bridge.

+ + + + + + + + + + +
Parameters
indentationIndentation level to use when saving the JSON file.
+

If the indentation level is set to -1, all whitespace is removed.

+
+
+

+
+ template<typename T> +
+ bool cubos::engine::old::JSONBridge<T>::loadFromFile(Assets& assets, + const AnyAsset& handle, + core::memory::Stream& stream) override protected +

+

Loads an asset from a file stream.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
assetsManager to write into.
handleHandle of the asset being loaded.
streamFile stream.
ReturnsWhether the asset was successfully loaded.
+
+
+

+
+ template<typename T> +
+ bool cubos::engine::old::JSONBridge<T>::saveToFile(const Assets& assets, + const AnyAsset& handle, + core::memory::Stream& stream) override protected +

+

Saves an asset to a file stream.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
assetsManager to read from.
handleHandle of the asset being saved.
streamFile stream.
ReturnsWhether the asset was successfully saved.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/classtesseratos_1_1Toolbox.html b/docs-preview/pr-1032/classtesseratos_1_1Toolbox.html new file mode 100644 index 000000000..923c4cfcc --- /dev/null +++ b/docs-preview/pr-1032/classtesseratos_1_1Toolbox.html @@ -0,0 +1,248 @@ + + + + + tesseratos::Toolbox class | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ tesseratos::Toolbox class final + +

+

Resource which manages other tools windows.

+ +
+

Public functions

+
+
+ auto isOpen(const std::string& toolName) -> bool +
+
Checks if the tool with the given name is open.
+
+ void open(const std::string& toolName) +
+
Opens a tool.
+
+ void close(const std::string& toolName) +
+
Closes a tool.
+
+ void toggle(const std::string& toolName) +
+
If the given tool is open, closes it. Otherwise, opens it.
+
+ auto begin() const -> auto +
+
Returns the beggining of the map with known tools.
+
+ auto end() const -> auto +
+
Returns the end of the map with known tools.
+
+
+
+

Function documentation

+
+

+ bool tesseratos::Toolbox::isOpen(const std::string& toolName) +

+

Checks if the tool with the given name is open.

+ + + + + + + + + + + + + + + + +
Parameters
toolNameTool name.
ReturnsWhether the tool is open.
+
+
+

+ void tesseratos::Toolbox::open(const std::string& toolName) +

+

Opens a tool.

+ + + + + + + + + + +
Parameters
toolNameTool name.
+
+
+

+ void tesseratos::Toolbox::close(const std::string& toolName) +

+

Closes a tool.

+ + + + + + + + + + +
Parameters
toolNameTool name.
+
+
+

+ void tesseratos::Toolbox::toggle(const std::string& toolName) +

+

If the given tool is open, closes it. Otherwise, opens it.

+ + + + + + + + + + +
Parameters
toolNameTool name.
+
+
+

+ auto tesseratos::Toolbox::begin() const +

+

Returns the beggining of the map with known tools.

+ + + + + + + +
ReturnsBegginng of the map.
+
+
+

+ auto tesseratos::Toolbox::end() const +

+

Returns the end of the map with known tools.

+ + + + + + + +
ReturnsEnd of the map.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/collider_8hpp.html b/docs-preview/pr-1032/collider_8hpp.html new file mode 100644 index 000000000..5faa1862b --- /dev/null +++ b/docs-preview/pr-1032/collider_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/collisions/collider.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/colliding__with_8hpp.html b/docs-preview/pr-1032/colliding__with_8hpp.html new file mode 100644 index 000000000..c5977316d --- /dev/null +++ b/docs-preview/pr-1032/colliding__with_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/collisions/colliding_with.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/collision__event_8hpp.html b/docs-preview/pr-1032/collision__event_8hpp.html new file mode 100644 index 000000000..28386a0d1 --- /dev/null +++ b/docs-preview/pr-1032/collision__event_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/collisions/collision_event.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/column_8hpp.html b/docs-preview/pr-1032/column_8hpp.html new file mode 100644 index 000000000..dee6541e3 --- /dev/null +++ b/docs-preview/pr-1032/column_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/ecs/table/column.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/command__buffer_8hpp.html b/docs-preview/pr-1032/command__buffer_8hpp.html new file mode 100644 index 000000000..709ef6a7e --- /dev/null +++ b/docs-preview/pr-1032/command__buffer_8hpp.html @@ -0,0 +1,136 @@ + + + + + core/ecs/command_buffer.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/commands_8hpp.html b/docs-preview/pr-1032/commands_8hpp.html new file mode 100644 index 000000000..6b0bfdd3e --- /dev/null +++ b/docs-preview/pr-1032/commands_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/ecs/system/arguments/commands.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/comparison_8hpp.html b/docs-preview/pr-1032/comparison_8hpp.html new file mode 100644 index 000000000..7a4acbbcf --- /dev/null +++ b/docs-preview/pr-1032/comparison_8hpp.html @@ -0,0 +1,136 @@ + + + + + core/reflection/comparison.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/constructible_8hpp.html b/docs-preview/pr-1032/constructible_8hpp.html new file mode 100644 index 000000000..3c0396078 --- /dev/null +++ b/docs-preview/pr-1032/constructible_8hpp.html @@ -0,0 +1,139 @@ + + + + + core/reflection/traits/constructible.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/reflection/traits/constructible.hpp file +

+

Class cubos::core::reflection::ConstructibleTrait.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::reflection
+
Reflection module.
+
+
+
+

Classes

+
+
+ class cubos::core::reflection::ConstructibleTrait +
+
Describes how a reflected type may be constructed and destructed.
+
+
template<typename T>
+ class cubos::core::reflection::ConstructibleTrait::Builder +
+
Builder for ConstructibleTrait.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/constructible__utils_8hpp.html b/docs-preview/pr-1032/constructible__utils_8hpp.html new file mode 100644 index 000000000..f22957c1a --- /dev/null +++ b/docs-preview/pr-1032/constructible__utils_8hpp.html @@ -0,0 +1,136 @@ + + + + + core/reflection/traits/constructible_utils.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/reflection/traits/constructible_utils.hpp file +

+

Utilities for cubos::core::reflection::ConstructibleTrait.

+ + +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::reflection
+
Reflection module.
+
+
+
+

Functions

+
+
+
template<typename T>
+ auto autoConstructibleTrait() -> ConstructibleTrait +
+
Returns a ConstructibleTrait with the default, copy and move constructors, set only if the type has them.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/contribution.html b/docs-preview/pr-1032/contribution.html new file mode 100644 index 000000000..94df8d245 --- /dev/null +++ b/docs-preview/pr-1032/contribution.html @@ -0,0 +1,114 @@ + + + + + Contribution guidelines | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Contribution guidelines +

+

Guide on the project's conventions and code style.

+

Commits

Commits should be concise and small, such that they are easy to review. Avoid at all costs including non-related changes in a commit - use git add -p or something similar to force yourself to review the changes you are commiting, and to avoid accidentally commiting unrelated changes.

Commits should follow Conventional Commits and be written in imperative mood. As scopes, we use the names of the labels that start by B- in the label list (e.g.: assets, audio). If the commit affects multiple of those areas, then pick one of the labels that start by A- (e.g.: core, engine, tesseratos). If a commit affects more than one of those, then you can ommit the scope.

If your description is too long, you can add a body to the commit message. The body should be separated from the description by a blank line.

Examples of good commit messages:

feat(core): add CUBOS_FAIL, CUBOS_UNREACHABLE and CUBOS_DEBUG_ASSERT 
+test(core): move filesystem tests to data/fs
+fix(core): fix segfault when popping a sub context
+feat(engine): implement system for sweeping the markers  
+docs(engine): add comments to colliders
+chore: replace GoogleTest submodule with doctest

Examples of bad commit messages:

fix: fix bug
+make it work
+feat(core): Add CUBOS_FAIL
+docs(engine): added comments to colliders

Pull Requests

Pull requests should be concise and small, and if needed, split into multiple smaller PRs so that they are easier to review. If your PR is still not finished, mark it as a draft. When working on new features, draft PRs should be created so that other contributors can have an idea of what is being worked on.

Any features added in a PR should be covered by tests and documentation, including new examples demonstrating the feature.

Documentation

We use Doxygen for documentation, which means that the documentation is mostly written in the code itself. When adding new files, classes, functions, etc, make sure to at least add a triple slash comment (///) with a @brief section describing what it does, otherwise Doxygen will omit it from the documentation.

Make sure to document all function parameters, template parameters and return values. Take a look at other files to get a grasp of the documentation style we use.

When changing the code, the documentation should be updated accordingly.

Plugins

Engine plugins should document which components and resources they add, which tags and settings are used, and how to use them. Take a look at the documentation of other plugins such as the renderer plugin to get an idea of how it should look like.

Every type or function that is part of the public API of a plugin should be added to its corresponding group in the Doxygen documentation, using the @ingroup tag.

Code Style

Casing

We use camelCase for functions, methods, local variables and fields. Private fields are prefixed with m (e.g. mMyField). PascalCase is used for class names and constants. UPPER_CASE is used for macros. snake_case is used for namespaces, folders and files.

Formatting

Code is formatted using clang format. Although we have an action that runs clang format on every PR, it is recommended that you run it locally before commiting your changes, to make it easier for the reviewers to read your code.

We also check the code with clang tidy, which is a static analysis tool which picks up many common mistakes and code smell. This runs on every commit you push to your branch.

Macros

Avoid using macros whenever possible - use constexpr variables or functions instead. If you do need to use a macro to make an implementation more readable, restrict the macro to the source file where it is used. Defining macros in header files is heavily discouraged.

Namespaces

Avoid using namespace in header files. In source files, prefer using foo::bar::X over using namespace foo::bar. If your code is under the namespace foo::bar, you can use using namespace foo::bar in the source files, to make the code more readable.

When closing a namespace the namespace name should be added as a comment. E.g.:

namespace foo
+{
+    ...
+} // namespace foo
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/controller_8hpp.html b/docs-preview/pr-1032/controller_8hpp.html new file mode 100644 index 000000000..3a41770b2 --- /dev/null +++ b/docs-preview/pr-1032/controller_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/utils/free_camera/controller.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/copy__pass_8hpp.html b/docs-preview/pr-1032/copy__pass_8hpp.html new file mode 100644 index 000000000..bcd0ed68f --- /dev/null +++ b/docs-preview/pr-1032/copy__pass_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/renderer/pps/copy_pass.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/core_2include_2cubos_2core_2data_2des_2json_8hpp.html b/docs-preview/pr-1032/core_2include_2cubos_2core_2data_2des_2json_8hpp.html new file mode 100644 index 000000000..f8558073c --- /dev/null +++ b/docs-preview/pr-1032/core_2include_2cubos_2core_2data_2des_2json_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/data/des/json.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/core_2include_2cubos_2core_2data_2fs_2file_8hpp.html b/docs-preview/pr-1032/core_2include_2cubos_2core_2data_2fs_2file_8hpp.html new file mode 100644 index 000000000..50dccc9d5 --- /dev/null +++ b/docs-preview/pr-1032/core_2include_2cubos_2core_2data_2fs_2file_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/data/fs/file.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/core_2include_2cubos_2core_2data_2ser_2json_8hpp.html b/docs-preview/pr-1032/core_2include_2cubos_2core_2data_2ser_2json_8hpp.html new file mode 100644 index 000000000..f09014995 --- /dev/null +++ b/docs-preview/pr-1032/core_2include_2cubos_2core_2data_2ser_2json_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/data/ser/json.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/core_2include_2cubos_2core_2ecs_2resource_2manager_8hpp.html b/docs-preview/pr-1032/core_2include_2cubos_2core_2ecs_2resource_2manager_8hpp.html new file mode 100644 index 000000000..dc5029f4e --- /dev/null +++ b/docs-preview/pr-1032/core_2include_2cubos_2core_2ecs_2resource_2manager_8hpp.html @@ -0,0 +1,144 @@ + + + + + core/ecs/resource/manager.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/ecs/resource/manager.hpp file +

+

Class cubos::core::ecs::ResourceManager and related types.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::ecs
+
ECS module.
+
+
+
+

Classes

+
+
+
template<typename T>
+ class cubos::core::ecs::ReadResource +
+
Utility struct used to reference a resource of type T for reading.
+
+
template<typename T>
+ class cubos::core::ecs::WriteResource +
+
Utility struct used to reference a resource of type T for writing.
+
+ class cubos::core::ecs::ResourceManager +
+
Holds and manages resources.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/core_2include_2cubos_2core_2geom_2box_8hpp.html b/docs-preview/pr-1032/core_2include_2cubos_2core_2geom_2box_8hpp.html new file mode 100644 index 000000000..4b7f4da7f --- /dev/null +++ b/docs-preview/pr-1032/core_2include_2cubos_2core_2geom_2box_8hpp.html @@ -0,0 +1,136 @@ + + + + + core/geom/box.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/core_2include_2cubos_2core_2geom_2capsule_8hpp.html b/docs-preview/pr-1032/core_2include_2cubos_2core_2geom_2capsule_8hpp.html new file mode 100644 index 000000000..9591eed3b --- /dev/null +++ b/docs-preview/pr-1032/core_2include_2cubos_2core_2geom_2capsule_8hpp.html @@ -0,0 +1,136 @@ + + + + + core/geom/capsule.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/cstring_8hpp.html b/docs-preview/pr-1032/cstring_8hpp.html new file mode 100644 index 000000000..405cc35db --- /dev/null +++ b/docs-preview/pr-1032/cstring_8hpp.html @@ -0,0 +1,102 @@ + + + + + core/reflection/external/cstring.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/cubos_8hpp.html b/docs-preview/pr-1032/cubos_8hpp.html new file mode 100644 index 000000000..797524138 --- /dev/null +++ b/docs-preview/pr-1032/cubos_8hpp.html @@ -0,0 +1,150 @@ + + + + + core/ecs/cubos.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/ecs/cubos.hpp file +

+

Class cubos::engine::Cubos.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::ecs
+
ECS module.
+
+
+
+

Classes

+
+
+ struct cubos::core::ecs::DeltaTime +
+
Resource which stores the time since the last iteration of the main loop started.
+
+ struct cubos::core::ecs::ShouldQuit +
+
Resource used as a flag to indicate whether the main loop should stop running.
+
+ struct cubos::core::ecs::Arguments +
+
Resource which stores the command-line arguments.
+
+ class cubos::core::ecs::TagBuilder +
+
Used to chain configurations related to tags.
+
+ class cubos::core::ecs::Cubos +
+
Represents the engine itself, and exposes the interface with which the game developer interacts with. Ties up all the different parts of the engine together.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/cursor_8hpp.html b/docs-preview/pr-1032/cursor_8hpp.html new file mode 100644 index 000000000..319f9f51b --- /dev/null +++ b/docs-preview/pr-1032/cursor_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/io/cursor.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/damping_8hpp.html b/docs-preview/pr-1032/damping_8hpp.html new file mode 100644 index 000000000..c17d6b97a --- /dev/null +++ b/docs-preview/pr-1032/damping_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/physics/resources/damping.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/data_2ser_2debug_8hpp.html b/docs-preview/pr-1032/data_2ser_2debug_8hpp.html new file mode 100644 index 000000000..e3bac52a6 --- /dev/null +++ b/docs-preview/pr-1032/data_2ser_2debug_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/data/ser/debug.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/data_8hpp.html b/docs-preview/pr-1032/data_8hpp.html new file mode 100644 index 000000000..0b64cd270 --- /dev/null +++ b/docs-preview/pr-1032/data_8hpp.html @@ -0,0 +1,135 @@ + + + + + core/ecs/query/data.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/data__inspector_8hpp.html b/docs-preview/pr-1032/data__inspector_8hpp.html new file mode 100644 index 000000000..a434a8a13 --- /dev/null +++ b/docs-preview/pr-1032/data__inspector_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/imgui/data_inspector.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/deferred__renderer_8hpp.html b/docs-preview/pr-1032/deferred__renderer_8hpp.html new file mode 100644 index 000000000..09ee7ca25 --- /dev/null +++ b/docs-preview/pr-1032/deferred__renderer_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/renderer/deferred_renderer.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dense_2registry_8hpp.html b/docs-preview/pr-1032/dense_2registry_8hpp.html new file mode 100644 index 000000000..929f2f20e --- /dev/null +++ b/docs-preview/pr-1032/dense_2registry_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/ecs/table/dense/registry.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dense_2table_8hpp.html b/docs-preview/pr-1032/dense_2table_8hpp.html new file mode 100644 index 000000000..c6a5eb9e1 --- /dev/null +++ b/docs-preview/pr-1032/dense_2table_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/ecs/table/dense/table.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/des_2deserializer_8hpp.html b/docs-preview/pr-1032/des_2deserializer_8hpp.html new file mode 100644 index 000000000..542a402e1 --- /dev/null +++ b/docs-preview/pr-1032/des_2deserializer_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/data/des/deserializer.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/data/des/deserializer.hpp file +

+

Class cubos::core::data::Deserializer.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::data
+
Data module.
+
+
+
+

Classes

+
+
+ class cubos::core::data::Deserializer +
+
Base class for deserializers, which defines the interface for deserializing arbitrary data using its reflection metadata.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dictionary_8hpp.html b/docs-preview/pr-1032/dictionary_8hpp.html new file mode 100644 index 000000000..18870b76c --- /dev/null +++ b/docs-preview/pr-1032/dictionary_8hpp.html @@ -0,0 +1,142 @@ + + + + + core/reflection/traits/dictionary.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/reflection/traits/dictionary.hpp file +

+

Class cubos::core::reflection::DictionaryTrait.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::reflection
+
Reflection module.
+
+
+
+

Classes

+
+
+ class cubos::core::reflection::DictionaryTrait +
+
Exposes dictionary-like functionality of a type.
+
+ struct cubos::core::reflection::DictionaryTrait::View::Iterator::Entry +
+
Output structure for the iterator.
+
+ struct cubos::core::reflection::DictionaryTrait::ConstView::Iterator::Entry +
+
Output structure for the iterator.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_00300fcbde38ee57d1255bf5757a56e9.html b/docs-preview/pr-1032/dir_00300fcbde38ee57d1255bf5757a56e9.html new file mode 100644 index 000000000..2a05f1e02 --- /dev/null +++ b/docs-preview/pr-1032/dir_00300fcbde38ee57d1255bf5757a56e9.html @@ -0,0 +1,120 @@ + + + + + engine/splitscreen/ directory | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ engine/splitscreen/ directory +

+

Splitscreen plugin directory.

+ +
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_043da9b7d60f46877cefd90a49e157c3.html b/docs-preview/pr-1032/dir_043da9b7d60f46877cefd90a49e157c3.html new file mode 100644 index 000000000..dc445a1b7 --- /dev/null +++ b/docs-preview/pr-1032/dir_043da9b7d60f46877cefd90a49e157c3.html @@ -0,0 +1,120 @@ + + + + + core/ecs/resource/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_0835e003fa277f66ce5cf543d578f6a2.html b/docs-preview/pr-1032/dir_0835e003fa277f66ce5cf543d578f6a2.html new file mode 100644 index 000000000..9e6b39558 --- /dev/null +++ b/docs-preview/pr-1032/dir_0835e003fa277f66ce5cf543d578f6a2.html @@ -0,0 +1,136 @@ + + + + + engine/assets/ directory | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ engine/assets/ directory +

+

Assets plugin directory.

+ +
+

Directories

+
+
directory bridges/
+
cubos::engine::AssetBridge implementations directory.
+
+
+
+

Files

+
+
file asset.hpp
+
Classes cubos::engine::AnyAsset and cubos::engine::Asset.
+
file assets.hpp
+
Resource cubos::engine::Assets.
+
file bridge.hpp
+
Class cubos::engine::AssetBridge.
+
file meta.hpp
+
Class cubos::engine::AssetMeta.
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_0b39c986537c7114081f36bbdae17547.html b/docs-preview/pr-1032/dir_0b39c986537c7114081f36bbdae17547.html new file mode 100644 index 000000000..ccb9f5124 --- /dev/null +++ b/docs-preview/pr-1032/dir_0b39c986537c7114081f36bbdae17547.html @@ -0,0 +1,132 @@ + + + + + core/ecs/table/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_1849b6590c20a7c40f18c0337f505edf.html b/docs-preview/pr-1032/dir_1849b6590c20a7c40f18c0337f505edf.html new file mode 100644 index 000000000..244620034 --- /dev/null +++ b/docs-preview/pr-1032/dir_1849b6590c20a7c40f18c0337f505edf.html @@ -0,0 +1,136 @@ + + + + + core/ecs/system/ directory | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/ecs/system/ directory +

+

System directory.

+ +
+

Directories

+
+
directory arguments/
+
Arguments directory.
+
+
+
+

Files

+
+
file access.hpp
+
Struct cubos::core::ecs::SystemAccess.
+
file dispatcher.hpp
+
Class cubos::core::ecs::Dispatcher.
+
file fetcher.hpp
+
Class cubos::core::ecs::SystemFetcher.
+
file options.hpp
+
Struct cubos::core::ecs::SystemOptions.
+
file system.hpp
+
Class cubos::core::ecs::System.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_18699a5452817121af2ab0a7c7f1cc3e.html b/docs-preview/pr-1032/dir_18699a5452817121af2ab0a7c7f1cc3e.html new file mode 100644 index 000000000..8253ff6f7 --- /dev/null +++ b/docs-preview/pr-1032/dir_18699a5452817121af2ab0a7c7f1cc3e.html @@ -0,0 +1,120 @@ + + + + + tesseratos/entity_selector/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_26a5878ebb5e9988b6ffa6f152301254.html b/docs-preview/pr-1032/dir_26a5878ebb5e9988b6ffa6f152301254.html new file mode 100644 index 000000000..8714db36a --- /dev/null +++ b/docs-preview/pr-1032/dir_26a5878ebb5e9988b6ffa6f152301254.html @@ -0,0 +1,128 @@ + + + + + core/ecs/query/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_2a25e2bce65ce0f842dba5b7b3a0e22d.html b/docs-preview/pr-1032/dir_2a25e2bce65ce0f842dba5b7b3a0e22d.html new file mode 100644 index 000000000..e0b2bd65a --- /dev/null +++ b/docs-preview/pr-1032/dir_2a25e2bce65ce0f842dba5b7b3a0e22d.html @@ -0,0 +1,154 @@ + + + + + tesseratos/ directory | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ tesseratos/ directory +

+

Tesseratos module.

+ +
+

Directories

+
+
directory asset_explorer/
+
Asset explorer plugin directory.
+
directory collider_gizmos/
+
Collider gizmos plugin directory.
+
directory debug_camera/
+
Debug camera plugin directory.
+
directory ecs_statistics/
+
ECS Statistics plugin directory.
+
directory entity_inspector/
+
Entity inspector plugin directory.
+
directory entity_selector/
+
Entity selector plugin directory.
+
directory metrics_panel/
+
Metrics plugin directory.
+
directory play_pause/
+
Play Pause plugin directory.
+
directory scene_editor/
+
Scene editor plugin directory.
+
directory settings_inspector/
+
Settings inspector plugin directory.
+
directory toolbox/
+
Toolbox plugin directory.
+
directory transform_gizmo/
+
Transform gizmo plugin directory.
+
directory voxel_palette_editor/
+
Palette editor plugin directory.
+
directory world_inspector/
+
World inspector plugin directory.
+
+
+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_2a3f20446d92cb0b384d0cf4f4d26d60.html b/docs-preview/pr-1032/dir_2a3f20446d92cb0b384d0cf4f4d26d60.html new file mode 100644 index 000000000..6f2ef444f --- /dev/null +++ b/docs-preview/pr-1032/dir_2a3f20446d92cb0b384d0cf4f4d26d60.html @@ -0,0 +1,120 @@ + + + + + engine/window/ directory | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ engine/window/ directory +

+

Window plugin directory.

+ +
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_3504744c369d3ac8de67ffae1d44d2b4.html b/docs-preview/pr-1032/dir_3504744c369d3ac8de67ffae1d44d2b4.html new file mode 100644 index 000000000..fa4fbbdb4 --- /dev/null +++ b/docs-preview/pr-1032/dir_3504744c369d3ac8de67ffae1d44d2b4.html @@ -0,0 +1,122 @@ + + + + + engine/fixed_step/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_3764e76d8ec4e739fc24b5bb90adc3af.html b/docs-preview/pr-1032/dir_3764e76d8ec4e739fc24b5bb90adc3af.html new file mode 100644 index 000000000..505b7290b --- /dev/null +++ b/docs-preview/pr-1032/dir_3764e76d8ec4e739fc24b5bb90adc3af.html @@ -0,0 +1,128 @@ + + + + + core/ecs/entity/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_38aac728ad33877355e223e23ac4ab7a.html b/docs-preview/pr-1032/dir_38aac728ad33877355e223e23ac4ab7a.html new file mode 100644 index 000000000..8f281a366 --- /dev/null +++ b/docs-preview/pr-1032/dir_38aac728ad33877355e223e23ac4ab7a.html @@ -0,0 +1,124 @@ + + + + + core/data/ser/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_38dc3202db19a8deaf7e1516278a105d.html b/docs-preview/pr-1032/dir_38dc3202db19a8deaf7e1516278a105d.html new file mode 100644 index 000000000..b01ad59f4 --- /dev/null +++ b/docs-preview/pr-1032/dir_38dc3202db19a8deaf7e1516278a105d.html @@ -0,0 +1,120 @@ + + + + + tesseratos/world_inspector/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_38e9fb064544086d3594e70a41f6b257.html b/docs-preview/pr-1032/dir_38e9fb064544086d3594e70a41f6b257.html new file mode 100644 index 000000000..05c5a75f5 --- /dev/null +++ b/docs-preview/pr-1032/dir_38e9fb064544086d3594e70a41f6b257.html @@ -0,0 +1,124 @@ + + + + + engine/scene/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_3e72b743a5c62924583b661b2c5525f9.html b/docs-preview/pr-1032/dir_3e72b743a5c62924583b661b2c5525f9.html new file mode 100644 index 000000000..fe37ed419 --- /dev/null +++ b/docs-preview/pr-1032/dir_3e72b743a5c62924583b661b2c5525f9.html @@ -0,0 +1,120 @@ + + + + + tesseratos/ecs_statistics/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_4149d46e02eca8eae23b140f2d5369cf.html b/docs-preview/pr-1032/dir_4149d46e02eca8eae23b140f2d5369cf.html new file mode 100644 index 000000000..512d75467 --- /dev/null +++ b/docs-preview/pr-1032/dir_4149d46e02eca8eae23b140f2d5369cf.html @@ -0,0 +1,123 @@ + + + + + tesseratos/asset_explorer/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_459dda10180a6131eb62bc74e02d0b6e.html b/docs-preview/pr-1032/dir_459dda10180a6131eb62bc74e02d0b6e.html new file mode 100644 index 000000000..1d1c03f58 --- /dev/null +++ b/docs-preview/pr-1032/dir_459dda10180a6131eb62bc74e02d0b6e.html @@ -0,0 +1,122 @@ + + + + + engine/imgui/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_46c6a4a310169812045f09ba6135aa36.html b/docs-preview/pr-1032/dir_46c6a4a310169812045f09ba6135aa36.html new file mode 100644 index 000000000..e55e24680 --- /dev/null +++ b/docs-preview/pr-1032/dir_46c6a4a310169812045f09ba6135aa36.html @@ -0,0 +1,122 @@ + + + + + engine/collisions/shapes/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_56f03f6936f99956d731d9e98d524876.html b/docs-preview/pr-1032/dir_56f03f6936f99956d731d9e98d524876.html new file mode 100644 index 000000000..8daba165c --- /dev/null +++ b/docs-preview/pr-1032/dir_56f03f6936f99956d731d9e98d524876.html @@ -0,0 +1,120 @@ + + + + + tesseratos/debug_camera/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_57aff98960b24114775613a58ec786ad.html b/docs-preview/pr-1032/dir_57aff98960b24114775613a58ec786ad.html new file mode 100644 index 000000000..c4424bb49 --- /dev/null +++ b/docs-preview/pr-1032/dir_57aff98960b24114775613a58ec786ad.html @@ -0,0 +1,122 @@ + + + + + engine/screen_picker/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_5f701044e65d6c264a6c1dc66b1052c2.html b/docs-preview/pr-1032/dir_5f701044e65d6c264a6c1dc66b1052c2.html new file mode 100644 index 000000000..98dd88998 --- /dev/null +++ b/docs-preview/pr-1032/dir_5f701044e65d6c264a6c1dc66b1052c2.html @@ -0,0 +1,132 @@ + + + + + engine/transform/ directory | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ engine/transform/ directory +

+

Transform plugin directory.

+ +
+

Files

+
+
file child_of.hpp
+
Relation cubos::engine::ChildOf.
+
file local_to_parent.hpp
+
Component cubos::engine::LocalToParent.
+
file local_to_world.hpp
+
Component cubos::engine::LocalToWorld.
+
file plugin.hpp
+
Plugin entry point.
+
file position.hpp
+
Component cubos::engine::Position.
+
file rotation.hpp
+
Component cubos::engine::Rotation.
+
file scale.hpp
+
Component cubos::engine::Scale.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_60b52edecd3c8caac6b76bd0bb2ba3ce.html b/docs-preview/pr-1032/dir_60b52edecd3c8caac6b76bd0bb2ba3ce.html new file mode 100644 index 000000000..c9db671b5 --- /dev/null +++ b/docs-preview/pr-1032/dir_60b52edecd3c8caac6b76bd0bb2ba3ce.html @@ -0,0 +1,120 @@ + + + + + tesseratos/scene_editor/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_64a2fed96ae76f57d94061df7c919db3.html b/docs-preview/pr-1032/dir_64a2fed96ae76f57d94061df7c919db3.html new file mode 100644 index 000000000..b4b0937b7 --- /dev/null +++ b/docs-preview/pr-1032/dir_64a2fed96ae76f57d94061df7c919db3.html @@ -0,0 +1,102 @@ + + + + + events/ directory | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ events/ directory +

+

Event arguments.

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_672562f1eb3ea0be7f3aa3e89e72ecd2.html b/docs-preview/pr-1032/dir_672562f1eb3ea0be7f3aa3e89e72ecd2.html new file mode 100644 index 000000000..c60e52a40 --- /dev/null +++ b/docs-preview/pr-1032/dir_672562f1eb3ea0be7f3aa3e89e72ecd2.html @@ -0,0 +1,126 @@ + + + + + engine/renderer/pps/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_696376665c0dc3694e56f168acfac677.html b/docs-preview/pr-1032/dir_696376665c0dc3694e56f168acfac677.html new file mode 100644 index 000000000..597fdcc39 --- /dev/null +++ b/docs-preview/pr-1032/dir_696376665c0dc3694e56f168acfac677.html @@ -0,0 +1,120 @@ + + + + + tesseratos/entity_inspector/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_69c88e5af9faf72eaf159ee3e83d9db2.html b/docs-preview/pr-1032/dir_69c88e5af9faf72eaf159ee3e83d9db2.html new file mode 100644 index 000000000..9fc77f52a --- /dev/null +++ b/docs-preview/pr-1032/dir_69c88e5af9faf72eaf159ee3e83d9db2.html @@ -0,0 +1,126 @@ + + + + + core/ecs/system/arguments/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_6c4c9e5f04768b915dbc2edba08d4f5c.html b/docs-preview/pr-1032/dir_6c4c9e5f04768b915dbc2edba08d4f5c.html new file mode 100644 index 000000000..d2c010f29 --- /dev/null +++ b/docs-preview/pr-1032/dir_6c4c9e5f04768b915dbc2edba08d4f5c.html @@ -0,0 +1,122 @@ + + + + + core/data/des/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_6c897dd97bedf3914ee8a4d9f7f6549c.html b/docs-preview/pr-1032/dir_6c897dd97bedf3914ee8a4d9f7f6549c.html new file mode 100644 index 000000000..f04188de6 --- /dev/null +++ b/docs-preview/pr-1032/dir_6c897dd97bedf3914ee8a4d9f7f6549c.html @@ -0,0 +1,144 @@ + + + + + core/ directory | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/ directory +

+

Core module.

+ +
+

Directories

+
+
directory al/
+
Audio module.
+
directory data/
+
Data module.
+
directory ecs/
+
ECS module.
+
directory geom/
+
Geometry module.
+
directory gl/
+
Graphics module.
+
directory io/
+
Input and output module.
+
directory memory/
+
Memory module.
+
directory reflection/
+
Reflection module.
+
+
+
+

Files

+
+
file log.hpp
+
Logging and assertion macros.
+
file thread_pool.hpp
+
Class cubos::core::ThreadPool.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_6e7fefd5d33489e77ed24a475a1b2d04.html b/docs-preview/pr-1032/dir_6e7fefd5d33489e77ed24a475a1b2d04.html new file mode 100644 index 000000000..2f55494da --- /dev/null +++ b/docs-preview/pr-1032/dir_6e7fefd5d33489e77ed24a475a1b2d04.html @@ -0,0 +1,122 @@ + + + + + engine/utils/free_camera/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_7376bacbd9e6243f425bd4c56d48edd9.html b/docs-preview/pr-1032/dir_7376bacbd9e6243f425bd4c56d48edd9.html new file mode 100644 index 000000000..5712b520b --- /dev/null +++ b/docs-preview/pr-1032/dir_7376bacbd9e6243f425bd4c56d48edd9.html @@ -0,0 +1,126 @@ + + + + + core/io/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_73cd920be1d9b25db5feb4d2a202c641.html b/docs-preview/pr-1032/dir_73cd920be1d9b25db5feb4d2a202c641.html new file mode 100644 index 000000000..af9bf10f0 --- /dev/null +++ b/docs-preview/pr-1032/dir_73cd920be1d9b25db5feb4d2a202c641.html @@ -0,0 +1,136 @@ + + + + + core/reflection/external/ directory | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/reflection/external/ directory +

+

Reflection declarations for external types.

+ +
+

Files

+
+
file cstring.hpp
+
Reflection declaration for C-strings.
+
file glm.hpp
+
Reflection declarations for external glm types.
+
file map.hpp
+
Reflection declaration for std::map.
+
file primitives.hpp
+
Reflection declarations for primitive types.
+
file string.hpp
+
Reflection declaration for std::string.
+
file string_view.hpp
+
Reflection declaration for std::string_view.
+
file unordered_map.hpp
+
Reflection declaration for std::unordered_map.
+
file uuid.hpp
+
Reflection declaration for uuids::uuid.
+
file vector.hpp
+
Reflection declaration for std::vector.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_79f402fdd7bbb1d73f9fd1aa85f618da.html b/docs-preview/pr-1032/dir_79f402fdd7bbb1d73f9fd1aa85f618da.html new file mode 100644 index 000000000..af34a9514 --- /dev/null +++ b/docs-preview/pr-1032/dir_79f402fdd7bbb1d73f9fd1aa85f618da.html @@ -0,0 +1,130 @@ + + + + + core/data/fs/ directory | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/data/fs/ directory +

+

Filesystem utilities directory.

+ +
+

Files

+
+
file archive.hpp
+
Class cubos::core::data::Archive.
+
file embedded_archive.hpp
+
Class cubos::core::data::EmbeddedArchive.
+
file file.hpp
+
Class cubos::core::data::File.
+
file file_stream.hpp
+
Class cubos::core::data::FileStream.
+
file file_system.hpp
+
Class cubos::core::data::FileSystem.
+
file standard_archive.hpp
+
Class cubos::core::data::StandardArchive.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_85f1b5bc6fb8e602e74068211760bfae.html b/docs-preview/pr-1032/dir_85f1b5bc6fb8e602e74068211760bfae.html new file mode 100644 index 000000000..e1a4f8c93 --- /dev/null +++ b/docs-preview/pr-1032/dir_85f1b5bc6fb8e602e74068211760bfae.html @@ -0,0 +1,136 @@ + + + + + core/reflection/traits/ directory | CUBOS. Docs + + + + + + + +
+
+ +
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_8711f680e2d25dedddc79c2be2b1fda2.html b/docs-preview/pr-1032/dir_8711f680e2d25dedddc79c2be2b1fda2.html new file mode 100644 index 000000000..8642dc43e --- /dev/null +++ b/docs-preview/pr-1032/dir_8711f680e2d25dedddc79c2be2b1fda2.html @@ -0,0 +1,122 @@ + + + + + engine/settings/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_87a7847ee77970235330560d79c37ce0.html b/docs-preview/pr-1032/dir_87a7847ee77970235330560d79c37ce0.html new file mode 100644 index 000000000..4ff9522f5 --- /dev/null +++ b/docs-preview/pr-1032/dir_87a7847ee77970235330560d79c37ce0.html @@ -0,0 +1,148 @@ + + + + + engine/renderer/ directory | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ engine/renderer/ directory +

+

Renderer plugin directory.

+ +
+

Directories

+
+
directory pps/
+
Post processing directory.
+
+
+
+

Files

+
+
file camera.hpp
+
Component cubos::engine::Camera.
+
file deferred_renderer.hpp
+
Renderer implementation cubos::engine::DeferredRenderer.
+
file directional_light.hpp
+
Component cubos::engine::DirectionalLight.
+
file environment.hpp
+
Resource cubos::engine::RendererEnvironment.
+
file frame.hpp
+
Resource cubos::engine::RendererFrame.
+
file plugin.hpp
+
Plugin entry point, resource cubos::engine::ActiveCameras and components cubos::engine::RenderableGrid and cubos::engine::Camera.
+
file point_light.hpp
+
Component cubos::engine::PointLight.
+
file renderer.hpp
+
Class cubos::engine::BaseRenderer and resource cubos::engine::Renderer.
+
file spot_light.hpp
+
Component cubos::engine::SpotLight.
+
file vertex.hpp
+
Class cubos::engine::VoxelVertex and function cubos::engine::triangulate.
+
file viewport.hpp
+
Component cubos::engine::Viewport.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_8e5f84d20b1aa89c94160461e78e26c4.html b/docs-preview/pr-1032/dir_8e5f84d20b1aa89c94160461e78e26c4.html new file mode 100644 index 000000000..410336562 --- /dev/null +++ b/docs-preview/pr-1032/dir_8e5f84d20b1aa89c94160461e78e26c4.html @@ -0,0 +1,128 @@ + + + + + engine/input/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_95549d37735ad5b142799f042eef0d37.html b/docs-preview/pr-1032/dir_95549d37735ad5b142799f042eef0d37.html new file mode 100644 index 000000000..c070ea890 --- /dev/null +++ b/docs-preview/pr-1032/dir_95549d37735ad5b142799f042eef0d37.html @@ -0,0 +1,124 @@ + + + + + core/data/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_983a8c8cc77436ec11afd1f0c4e2ef1f.html b/docs-preview/pr-1032/dir_983a8c8cc77436ec11afd1f0c4e2ef1f.html new file mode 100644 index 000000000..fea941cdd --- /dev/null +++ b/docs-preview/pr-1032/dir_983a8c8cc77436ec11afd1f0c4e2ef1f.html @@ -0,0 +1,120 @@ + + + + + tesseratos/play_pause/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_9b04cf786b414c0d644db09287f665e6.html b/docs-preview/pr-1032/dir_9b04cf786b414c0d644db09287f665e6.html new file mode 100644 index 000000000..9cf0dede7 --- /dev/null +++ b/docs-preview/pr-1032/dir_9b04cf786b414c0d644db09287f665e6.html @@ -0,0 +1,126 @@ + + + + + engine/voxels/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_9bdaf8f561be1ffd03f616379797b70b.html b/docs-preview/pr-1032/dir_9bdaf8f561be1ffd03f616379797b70b.html new file mode 100644 index 000000000..12931cef1 --- /dev/null +++ b/docs-preview/pr-1032/dir_9bdaf8f561be1ffd03f616379797b70b.html @@ -0,0 +1,140 @@ + + + + + core/memory/ directory | CUBOS. Docs + + + + + + + +
+
+ +
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_9f228de11f2fc2633236213a3ef5c992.html b/docs-preview/pr-1032/dir_9f228de11f2fc2633236213a3ef5c992.html new file mode 100644 index 000000000..9715743ea --- /dev/null +++ b/docs-preview/pr-1032/dir_9f228de11f2fc2633236213a3ef5c992.html @@ -0,0 +1,124 @@ + + + + + core/ecs/table/sparse_relation/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_a1cc7ffab82768b4f8702a03c85b938c.html b/docs-preview/pr-1032/dir_a1cc7ffab82768b4f8702a03c85b938c.html new file mode 100644 index 000000000..5808f1263 --- /dev/null +++ b/docs-preview/pr-1032/dir_a1cc7ffab82768b4f8702a03c85b938c.html @@ -0,0 +1,120 @@ + + + + + tesseratos/transform_gizmo/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_ae52c41efe1aaae7a392cb947b223e9f.html b/docs-preview/pr-1032/dir_ae52c41efe1aaae7a392cb947b223e9f.html new file mode 100644 index 000000000..0a5330d1a --- /dev/null +++ b/docs-preview/pr-1032/dir_ae52c41efe1aaae7a392cb947b223e9f.html @@ -0,0 +1,120 @@ + + + + + tesseratos/metrics_panel/ directory | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ tesseratos/metrics_panel/ directory +

+

Metrics plugin directory.

+ +
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_b6daa990b896c2c0c53126427e4d978d.html b/docs-preview/pr-1032/dir_b6daa990b896c2c0c53126427e4d978d.html new file mode 100644 index 000000000..921ff2dd2 --- /dev/null +++ b/docs-preview/pr-1032/dir_b6daa990b896c2c0c53126427e4d978d.html @@ -0,0 +1,148 @@ + + + + + core/ecs/ directory | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/ecs/ directory +

+

ECS module.

+ +
+

Directories

+
+
directory entity/
+
Entity directory.
+
directory query/
+
Query directory.
+
directory resource/
+
Resource directory.
+
directory system/
+
System directory.
+
directory table/
+
Table directory.
+
+
+
+

Files

+
+
file blueprint.hpp
+
Class cubos::core::ecs::Blueprint.
+
file command_buffer.hpp
+
Class cubos::core::ecs::CommandBuffer.
+
file cubos.hpp
+
Class cubos::engine::Cubos.
+
file name.hpp
+
Class cubos::core::ecs::Name.
+
file reflection.hpp
+
Class cubos::core::ecs::TypeBuilder.
+
file types.hpp
+
Class cubos::core::ecs::Types.
+
file world.hpp
+
Class cubos::core::ecs::World.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_bafb7af0e03e95b24a45ff63060ab57b.html b/docs-preview/pr-1032/dir_bafb7af0e03e95b24a45ff63060ab57b.html new file mode 100644 index 000000000..a6fb60df6 --- /dev/null +++ b/docs-preview/pr-1032/dir_bafb7af0e03e95b24a45ff63060ab57b.html @@ -0,0 +1,148 @@ + + + + + engine/ directory | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ engine/ directory +

+

Engine module.

+ +
+

Directories

+
+
directory assets/
+
Assets plugin directory.
+
directory collisions/
+
Collisions plugin directory.
+
directory fixed_step/
+
Fixed Time Step plugin directory.
+
directory gizmos/
+
Gizmos plugin directory.
+
directory imgui/
+
ImGui integration ImGui plugin directory.
+
directory input/
+
Input plugin directory.
+
directory physics/
+
Physics plugin directory.
+
directory renderer/
+
Renderer plugin directory.
+
directory scene/
+
Scene plugin directory.
+
directory screen_picker/
+
ScreenPicker plugin directory.
+
directory settings/
+
Settings plugin directory.
+
directory splitscreen/
+
Splitscreen plugin directory.
+
directory transform/
+
Transform plugin directory.
+
directory voxels/
+
Voxels plugin directory.
+
directory window/
+
Window plugin directory.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_bc092de7c4be29a20e8c6c4d7f3164b3.html b/docs-preview/pr-1032/dir_bc092de7c4be29a20e8c6c4d7f3164b3.html new file mode 100644 index 000000000..1ce3ff94c --- /dev/null +++ b/docs-preview/pr-1032/dir_bc092de7c4be29a20e8c6c4d7f3164b3.html @@ -0,0 +1,120 @@ + + + + + tesseratos/settings_inspector/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_bd9be39c2ccf4132268583193b02b48c.html b/docs-preview/pr-1032/dir_bd9be39c2ccf4132268583193b02b48c.html new file mode 100644 index 000000000..47cd3ec3b --- /dev/null +++ b/docs-preview/pr-1032/dir_bd9be39c2ccf4132268583193b02b48c.html @@ -0,0 +1,124 @@ + + + + + engine/assets/bridges/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_c1b5957eb0512b9978230dfb34d9655b.html b/docs-preview/pr-1032/dir_c1b5957eb0512b9978230dfb34d9655b.html new file mode 100644 index 000000000..ee0c5c34c --- /dev/null +++ b/docs-preview/pr-1032/dir_c1b5957eb0512b9978230dfb34d9655b.html @@ -0,0 +1,122 @@ + + + + + core/ecs/table/dense/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_c1deef5baf41393ad8a994c3fd53e62f.html b/docs-preview/pr-1032/dir_c1deef5baf41393ad8a994c3fd53e62f.html new file mode 100644 index 000000000..2c8d8453c --- /dev/null +++ b/docs-preview/pr-1032/dir_c1deef5baf41393ad8a994c3fd53e62f.html @@ -0,0 +1,126 @@ + + + + + core/geom/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_c26f946019c5d6937d16d4e3329f697e.html b/docs-preview/pr-1032/dir_c26f946019c5d6937d16d4e3329f697e.html new file mode 100644 index 000000000..d57eb7a09 --- /dev/null +++ b/docs-preview/pr-1032/dir_c26f946019c5d6937d16d4e3329f697e.html @@ -0,0 +1,120 @@ + + + + + tesseratos/toolbox/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_c3ed6a1192e5b1b0ac8a4baf7bd6e376.html b/docs-preview/pr-1032/dir_c3ed6a1192e5b1b0ac8a4baf7bd6e376.html new file mode 100644 index 000000000..a182f3eb1 --- /dev/null +++ b/docs-preview/pr-1032/dir_c3ed6a1192e5b1b0ac8a4baf7bd6e376.html @@ -0,0 +1,120 @@ + + + + + tesseratos/voxel_palette_editor/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_c4311188e9cc606330f5e3e0b9dd5059.html b/docs-preview/pr-1032/dir_c4311188e9cc606330f5e3e0b9dd5059.html new file mode 100644 index 000000000..4a7c8049c --- /dev/null +++ b/docs-preview/pr-1032/dir_c4311188e9cc606330f5e3e0b9dd5059.html @@ -0,0 +1,124 @@ + + + + + core/gl/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_ce4a27e99b2102cfb79fc5b09181f4e6.html b/docs-preview/pr-1032/dir_ce4a27e99b2102cfb79fc5b09181f4e6.html new file mode 100644 index 000000000..6e94ce84e --- /dev/null +++ b/docs-preview/pr-1032/dir_ce4a27e99b2102cfb79fc5b09181f4e6.html @@ -0,0 +1,122 @@ + + + + + engine/gizmos/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_d28a4e16d9deb548c857866e71f89c35.html b/docs-preview/pr-1032/dir_d28a4e16d9deb548c857866e71f89c35.html new file mode 100644 index 000000000..f8185d896 --- /dev/null +++ b/docs-preview/pr-1032/dir_d28a4e16d9deb548c857866e71f89c35.html @@ -0,0 +1,120 @@ + + + + + tesseratos/collider_gizmos/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_db86702e1371d7558db3699dd3786a14.html b/docs-preview/pr-1032/dir_db86702e1371d7558db3699dd3786a14.html new file mode 100644 index 000000000..f151290dd --- /dev/null +++ b/docs-preview/pr-1032/dir_db86702e1371d7558db3699dd3786a14.html @@ -0,0 +1,134 @@ + + + + + engine/collisions/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_f4414684a5bb1e1b8e9ba236e8bdb594.html b/docs-preview/pr-1032/dir_f4414684a5bb1e1b8e9ba236e8bdb594.html new file mode 100644 index 000000000..385b340a8 --- /dev/null +++ b/docs-preview/pr-1032/dir_f4414684a5bb1e1b8e9ba236e8bdb594.html @@ -0,0 +1,136 @@ + + + + + core/reflection/ directory | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/reflection/ directory +

+

Reflection module.

+ +
+

Directories

+
+
directory external/
+
Reflection declarations for external types.
+
directory traits/
+
Reflection module built-in traits.
+
+
+
+

Files

+
+
file comparison.hpp
+
Function cubos::core::reflection::compare.
+
file reflect.hpp
+
Function cubos::core::reflection::reflect and related macros.
+
file type.hpp
+
Class cubos::core::reflection::Type.
+
file type_registry.hpp
+
Class cubos::core::reflection::TypeRegistry.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_f6f65ff657bd34b22e5078310628f4e7.html b/docs-preview/pr-1032/dir_f6f65ff657bd34b22e5078310628f4e7.html new file mode 100644 index 000000000..0dd57649b --- /dev/null +++ b/docs-preview/pr-1032/dir_f6f65ff657bd34b22e5078310628f4e7.html @@ -0,0 +1,120 @@ + + + + + core/al/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dir_fc8110eaf6ef50e82d21b749d50a1849.html b/docs-preview/pr-1032/dir_fc8110eaf6ef50e82d21b749d50a1849.html new file mode 100644 index 000000000..6acb7d2ed --- /dev/null +++ b/docs-preview/pr-1032/dir_fc8110eaf6ef50e82d21b749d50a1849.html @@ -0,0 +1,122 @@ + + + + + engine/physics/ directory | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/directional__light_8hpp.html b/docs-preview/pr-1032/directional__light_8hpp.html new file mode 100644 index 000000000..ebba7f56e --- /dev/null +++ b/docs-preview/pr-1032/directional__light_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/renderer/directional_light.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/dispatcher_8hpp.html b/docs-preview/pr-1032/dispatcher_8hpp.html new file mode 100644 index 000000000..15ded46f2 --- /dev/null +++ b/docs-preview/pr-1032/dispatcher_8hpp.html @@ -0,0 +1,146 @@ + + + + + core/ecs/system/dispatcher.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/ecs/system/dispatcher.hpp file +

+

Class cubos::core::ecs::Dispatcher.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::ecs
+
ECS module.
+
+
+
+

Classes

+
+
+ class cubos::core::ecs::Dispatcher +
+
Used to add systems and relations between them and then dispatch them all at once.
+
+ struct cubos::core::ecs::Dispatcher::Dependency +
+
Internal class to specify system dependencies.
+
+ struct cubos::core::ecs::Dispatcher::SystemSettings +
+
Internal class with settings pertaining to system/tag execution.
+
+ struct cubos::core::ecs::Dispatcher::System +
+
Internal class to handle tag settings.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/embedded__archive_8hpp.html b/docs-preview/pr-1032/embedded__archive_8hpp.html new file mode 100644 index 000000000..dc8fc4a04 --- /dev/null +++ b/docs-preview/pr-1032/embedded__archive_8hpp.html @@ -0,0 +1,142 @@ + + + + + core/data/fs/embedded_archive.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/data/fs/embedded_archive.hpp file +

+

Class cubos::core::data::EmbeddedArchive.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::data
+
Data module.
+
+
+
+

Classes

+
+
+ class cubos::core::data::EmbeddedArchive +
+
Archive implementation which reads data embedded in the application. Meant to be used with the quadrados embed tool.
+
+ struct cubos::core::data::EmbeddedArchive::Data +
+
Describes the structure of the embedded data.
+
+ struct cubos::core::data::EmbeddedArchive::Data::Entry +
+
Describes a file entry in the embedded data.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/endianness_8hpp.html b/docs-preview/pr-1032/endianness_8hpp.html new file mode 100644 index 000000000..a591a96be --- /dev/null +++ b/docs-preview/pr-1032/endianness_8hpp.html @@ -0,0 +1,159 @@ + + + + + core/memory/endianness.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/memory/endianness.hpp file +

+

Endianness utility functions.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::memory
+
Memory module.
+
+
+
+

Functions

+
+
+
template<typename T>
+ auto swapBytes(T value) -> T +
+
Swaps the bytes of a value, changing its endianness.
+
+ auto isLittleEndian() -> bool +
+
Checks if the current platform is little endian.
+
+
template<typename T>
+ auto fromLittleEndian(T value) -> T +
+
Converts a value from little endianness to local endianness.
+
+
template<typename T>
+ auto toLittleEndian(T value) -> T +
+
Converts a value from local endianness to little endianness.
+
+
template<typename T>
+ auto fromBigEndian(T value) -> T +
+
Converts a value from big endianness to local endianness.
+
+
template<typename T>
+ auto toBigEndian(T value) -> T +
+
Converts a value from local endianness to big endianness.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/engine_2include_2cubos_2engine_2assets_2bridges_2file_8hpp.html b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2assets_2bridges_2file_8hpp.html new file mode 100644 index 000000000..43af64846 --- /dev/null +++ b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2assets_2bridges_2file_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/assets/bridges/file.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/engine_2include_2cubos_2engine_2assets_2bridges_2json_8hpp.html b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2assets_2bridges_2json_8hpp.html new file mode 100644 index 000000000..7896a000a --- /dev/null +++ b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2assets_2bridges_2json_8hpp.html @@ -0,0 +1,133 @@ + + + + + engine/assets/bridges/json.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/engine_2include_2cubos_2engine_2assets_2bridges_2old_2json_8hpp.html b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2assets_2bridges_2old_2json_8hpp.html new file mode 100644 index 000000000..889f43d3b --- /dev/null +++ b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2assets_2bridges_2old_2json_8hpp.html @@ -0,0 +1,133 @@ + + + + + engine/assets/bridges/old/json.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/engine_2include_2cubos_2engine_2assets_2plugin_8hpp.html b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2assets_2plugin_8hpp.html new file mode 100644 index 000000000..4aab1e947 --- /dev/null +++ b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2assets_2plugin_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/assets/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/engine_2include_2cubos_2engine_2collisions_2plugin_8hpp.html b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2collisions_2plugin_8hpp.html new file mode 100644 index 000000000..f879eff44 --- /dev/null +++ b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2collisions_2plugin_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/collisions/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/engine_2include_2cubos_2engine_2collisions_2shapes_2box_8hpp.html b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2collisions_2shapes_2box_8hpp.html new file mode 100644 index 000000000..6cdb20168 --- /dev/null +++ b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2collisions_2shapes_2box_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/collisions/shapes/box.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/engine_2include_2cubos_2engine_2collisions_2shapes_2capsule_8hpp.html b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2collisions_2shapes_2capsule_8hpp.html new file mode 100644 index 000000000..b03115f3d --- /dev/null +++ b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2collisions_2shapes_2capsule_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/collisions/shapes/capsule.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/engine_2include_2cubos_2engine_2fixed__step_2plugin_8hpp.html b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2fixed__step_2plugin_8hpp.html new file mode 100644 index 000000000..5a0db5d0a --- /dev/null +++ b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2fixed__step_2plugin_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/fixed_step/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/engine_2include_2cubos_2engine_2gizmos_2plugin_8hpp.html b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2gizmos_2plugin_8hpp.html new file mode 100644 index 000000000..355097e16 --- /dev/null +++ b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2gizmos_2plugin_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/gizmos/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/engine_2include_2cubos_2engine_2imgui_2plugin_8hpp.html b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2imgui_2plugin_8hpp.html new file mode 100644 index 000000000..5bc2a85f7 --- /dev/null +++ b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2imgui_2plugin_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/imgui/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/engine_2include_2cubos_2engine_2input_2plugin_8hpp.html b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2input_2plugin_8hpp.html new file mode 100644 index 000000000..ed9d47f0f --- /dev/null +++ b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2input_2plugin_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/input/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/engine_2include_2cubos_2engine_2physics_2plugin_8hpp.html b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2physics_2plugin_8hpp.html new file mode 100644 index 000000000..50497e704 --- /dev/null +++ b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2physics_2plugin_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/physics/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/engine_2include_2cubos_2engine_2renderer_2plugin_8hpp.html b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2renderer_2plugin_8hpp.html new file mode 100644 index 000000000..cf878ae9c --- /dev/null +++ b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2renderer_2plugin_8hpp.html @@ -0,0 +1,150 @@ + + + + + engine/renderer/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ engine/renderer/plugin.hpp file +

+

Plugin entry point, resource cubos::engine::ActiveCameras and components cubos::engine::RenderableGrid and cubos::engine::Camera.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::engine
+
Engine module.
+
+
+
+

Classes

+
+
+ struct cubos::engine::RenderableGrid +
+
Component which makes a voxel grid be rendered by the renderer plugin.
+
+ struct cubos::engine::ActiveCameras +
+
Resource which identifies the camera entities to be used by the renderer.
+
+ struct cubos::engine::ActiveVoxelPalette +
+
Resource which holds an asset handle to the currently active palette.
+
+
+
+

Functions

+
+
+ void rendererPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/engine_2include_2cubos_2engine_2renderer_2pps_2manager_8hpp.html b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2renderer_2pps_2manager_8hpp.html new file mode 100644 index 000000000..df93865da --- /dev/null +++ b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2renderer_2pps_2manager_8hpp.html @@ -0,0 +1,144 @@ + + + + + engine/renderer/pps/manager.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ engine/renderer/pps/manager.hpp file +

+

Class cubos::engine::PostProcessingManager.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::engine
+
Engine module.
+
+
+
+

Classes

+
+
+ class cubos::engine::PostProcessingManager +
+
Responsible for managing the post processing passes.
+
+
+
+

Enums

+
+
+ enum class PostProcessingInput { Lighting, + Position, + Normal } +
+
Possible renderer outputs which can then be used as input for a post processing pass.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/engine_2include_2cubos_2engine_2scene_2plugin_8hpp.html b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2scene_2plugin_8hpp.html new file mode 100644 index 000000000..0e3751bcf --- /dev/null +++ b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2scene_2plugin_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/scene/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/engine_2include_2cubos_2engine_2screen__picker_2plugin_8hpp.html b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2screen__picker_2plugin_8hpp.html new file mode 100644 index 000000000..2cad6b62c --- /dev/null +++ b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2screen__picker_2plugin_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/screen_picker/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/engine_2include_2cubos_2engine_2settings_2plugin_8hpp.html b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2settings_2plugin_8hpp.html new file mode 100644 index 000000000..e21d1ef1c --- /dev/null +++ b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2settings_2plugin_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/settings/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/engine_2include_2cubos_2engine_2splitscreen_2plugin_8hpp.html b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2splitscreen_2plugin_8hpp.html new file mode 100644 index 000000000..8f50bc88e --- /dev/null +++ b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2splitscreen_2plugin_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/splitscreen/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/engine_2include_2cubos_2engine_2transform_2plugin_8hpp.html b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2transform_2plugin_8hpp.html new file mode 100644 index 000000000..d6f403411 --- /dev/null +++ b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2transform_2plugin_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/transform/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/engine_2include_2cubos_2engine_2utils_2free__camera_2plugin_8hpp.html b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2utils_2free__camera_2plugin_8hpp.html new file mode 100644 index 000000000..9a6c7260a --- /dev/null +++ b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2utils_2free__camera_2plugin_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/utils/free_camera/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/engine_2include_2cubos_2engine_2voxels_2plugin_8hpp.html b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2voxels_2plugin_8hpp.html new file mode 100644 index 000000000..228d4bebf --- /dev/null +++ b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2voxels_2plugin_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/voxels/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/engine_2include_2cubos_2engine_2window_2plugin_8hpp.html b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2window_2plugin_8hpp.html new file mode 100644 index 000000000..bdbcd3c0f --- /dev/null +++ b/docs-preview/pr-1032/engine_2include_2cubos_2engine_2window_2plugin_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/window/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/entity_8hpp.html b/docs-preview/pr-1032/entity_8hpp.html new file mode 100644 index 000000000..dade8759d --- /dev/null +++ b/docs-preview/pr-1032/entity_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/ecs/entity/entity.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/enum_8hpp.html b/docs-preview/pr-1032/enum_8hpp.html new file mode 100644 index 000000000..b2c22db87 --- /dev/null +++ b/docs-preview/pr-1032/enum_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/reflection/traits/enum.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/environment_8hpp.html b/docs-preview/pr-1032/environment_8hpp.html new file mode 100644 index 000000000..3ba608596 --- /dev/null +++ b/docs-preview/pr-1032/environment_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/renderer/environment.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-core-data-des-custom.html b/docs-preview/pr-1032/examples-core-data-des-custom.html new file mode 100644 index 000000000..ad1373459 --- /dev/null +++ b/docs-preview/pr-1032/examples-core-data-des-custom.html @@ -0,0 +1,197 @@ + + + + + Examples » Core » Data » Deserialization » Custom Deserializer | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Core » + Data » + Deserialization » + Custom Deserializer +

+

Implementing your own Deserializer.

+

To define your own deserializer type, you'll need to include core/data/des/deserializer.hpp. For simplicity, in this sample we'll use the following aliases:

#include <cubos/core/data/des/deserializer.hpp>
+
+using cubos::core::data::Deserializer;
+using cubos::core::reflection::Type;

We'll define a deserializer that will print the data to the standard output.

class MyDeserializer : public Deserializer
+{
+public:
+    MyDeserializer();
+
+protected:
+    bool decompose(const Type& type, void* value) override;
+};

In the constructor, we should set hooks to be called for deserializing primitive types or any other type we want to handle specifically.

In this example, we'll only handle int32_t, but usually you should at least cover all primitive types.

#include <cubos/core/reflection/external/primitives.hpp>
+
+using cubos::core::reflection::reflect;
+
+MyDeserializer::MyDeserializer()
+{
+    this->hook<int32_t>([](int32_t& value) {
+        Stream::stdOut.print("enter an int32_t: ");
+        Stream::stdIn.parse(value);
+        return true;
+    });
+}

The only other thing you need to do is implement the deserializer::decompose method, which acts as a catch-all for any type without a specific hook.

Here, we can use traits such as FieldsTrait to access the fields of a type and write to them.

In this sample, we'll only be handling fields and arrays, but you should try to cover as many kinds of data as possible.

#include <cubos/core/reflection/traits/array.hpp>
+#include <cubos/core/reflection/traits/fields.hpp>
+#include <cubos/core/reflection/type.hpp>
+
+using cubos::core::reflection::ArrayTrait;
+using cubos::core::reflection::FieldsTrait;
+
+bool MyDeserializer::decompose(const Type& type, void* value)
+{
+    if (type.has<ArrayTrait>())
+    {
+        const auto& arrayTrait = type.get<ArrayTrait>();
+        auto arrayView = arrayTrait.view(value);
+
+        auto length = static_cast<uint64_t>(arrayView.length());
+        Stream::stdOut.printf("enter array size: ", length);
+        Stream::stdIn.parse(length);
+
+        for (std::size_t i = 0; i < static_cast<std::size_t>(length); ++i)
+        {
+            if (i == arrayView.length())
+            {
+                arrayView.insertDefault(i);
+            }
+
+            Stream::stdOut.printf("writing array[{}]: ", i);
+            this->read(arrayTrait.elementType(), arrayView.get(i));
+        }
+
+        while (arrayView.length() > static_cast<std::size_t>(length))
+        {
+            arrayView.erase(static_cast<std::size_t>(length));
+        }
+
+        return true;
+    }

We start by checking if the type can be viewed as an array. If it can, we'll ask the user how many elements they want the array to have. We resize it, and then, we recurse into the elements. If the type doesn't have this trait, we'll fallback into checking if it has fields.

    if (type.has<FieldsTrait>())
+    {
+        for (const auto& [field, fieldValue] : type.get<FieldsTrait>().view(value))
+        {
+            Stream::stdOut.printf("writing field '{}': ", field->name());
+            if (!this->read(field->type(), fieldValue))
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    CUBOS_WARN("Cannot decompose {}", type.name());
+    return false;
+}

If the type has fields, we'll iterate over them and ask the user to enter values for them. Otherwise, we'll fail by returning false.

Using our deserializer is as simple as constructing it and calling Deserializer::read on the data we want to deserialize.

In this case, we'll be deserializing a std::vector<glm::ivec3>, which is an array of objects with three int32_t fields.

#include <glm/vec3.hpp>
+
+#include <cubos/core/reflection/external/glm.hpp>
+#include <cubos/core/reflection/external/vector.hpp>
+
+int main()
+{
+    std::vector<glm::ivec3> vec{};
+    MyDeserializer des{};
+    des.read(vec);
+
+    Stream::stdOut.print("-----------\n");
+    Stream::stdOut.print("Resulting vec: [ ");
+    for (const auto& v : vec)
+    {
+        Stream::stdOut.printf("({}, {}, {}) ", v.x, v.y, v.z);
+    }
+    Stream::stdOut.print("]\n");
+}

This should output the values you enter when you execute it.

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-core-data-des.html b/docs-preview/pr-1032/examples-core-data-des.html new file mode 100644 index 000000000..80caf94e6 --- /dev/null +++ b/docs-preview/pr-1032/examples-core-data-des.html @@ -0,0 +1,106 @@ + + + + + Examples » Core » Data » Deserialization | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-core-data-ser-custom.html b/docs-preview/pr-1032/examples-core-data-ser-custom.html new file mode 100644 index 000000000..74249c666 --- /dev/null +++ b/docs-preview/pr-1032/examples-core-data-ser-custom.html @@ -0,0 +1,182 @@ + + + + + Examples » Core » Data » Serialization » Custom Serializer | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Core » + Data » + Serialization » + Custom Serializer +

+

Implementing your own Serializer.

+

To define your own serializer type, you'll need to include core/data/ser/serializer.hpp. For simplicity, in this sample we'll use the following aliases:

#include <cubos/core/data/ser/serializer.hpp>
+
+using cubos::core::data::Serializer;
+using cubos::core::reflection::Type;

We'll define a serializer that will print the data to the standard output.

class MySerializer : public Serializer
+{
+public:
+    MySerializer();
+
+protected:
+    bool decompose(const Type& type, const void* value) override;
+};

In the constructor, we should set hooks to be called for serializing primitive types or any other type we want to handle specifically.

In this example, we'll only handle int32_t, but usually you should at least cover all primitive types.

#include <cubos/core/reflection/external/primitives.hpp>
+
+using cubos::core::reflection::reflect;
+
+MySerializer::MySerializer()
+{
+    this->hook<int32_t>([](const int32_t& value) {
+        Stream::stdOut.print(value);
+        return true;
+    });
+}

The only other thing you need to do is implement the Serializer::decompose method, which acts as a catch-all for any type without a specific hook.

Here, we can use traits such as FieldsTrait to get the fields of a type and print them.

In this sample, we'll only be handling fields and arrays, but you should try to cover as many kinds of data as possible.

#include <cubos/core/reflection/traits/array.hpp>
+#include <cubos/core/reflection/traits/fields.hpp>
+#include <cubos/core/reflection/type.hpp>
+
+using cubos::core::reflection::ArrayTrait;
+using cubos::core::reflection::FieldsTrait;
+
+bool MySerializer::decompose(const Type& type, const void* value)
+{
+    if (type.has<ArrayTrait>())
+    {
+        const auto& arrayTrait = type.get<ArrayTrait>();
+
+        Stream::stdOut.put('[');
+        for (const auto* element : arrayTrait.view(value))
+        {
+            if (!this->write(arrayTrait.elementType(), element))
+            {
+                return false;
+            }
+            Stream::stdOut.print(", ");
+        }
+        Stream::stdOut.put(']');
+
+        return true;
+    }

We start by checking if the type can be viewed as an array. If it can, we recurse into its elements. Otherwise, we'll fallback to the fields of the type.

    if (type.has<FieldsTrait>())
+    {
+        Stream::stdOut.put('{');
+        for (const auto& [field, fieldValue] : type.get<FieldsTrait>().view(value))
+        {
+            Stream::stdOut.printf("{}: ", field->name());
+            if (!this->write(field->type(), fieldValue))
+            {
+                return false;
+            }
+            Stream::stdOut.print(", ");
+        }
+        Stream::stdOut.put('}');
+
+        return true;
+    }
+
+    CUBOS_WARN("Cannot decompose {}", type.name());
+    return false;
+}

If the type has fields, we'll iterate over them and print them. Otherwise, we'll fail by returning false.

Using our serializer is as simple as constructing it and calling Serializer::write on the data we want to serialize.

In this case, we'll be serializing a std::vector<glm::ivec3>, which is an array of objects with three int32_t fields.

#include <glm/vec3.hpp>
+
+#include <cubos/core/reflection/external/glm.hpp>
+#include <cubos/core/reflection/external/vector.hpp>
+
+int main()
+{
+    std::vector<glm::ivec3> vec{{1, 2, 3}, {4, 5, 6}};
+
+    MySerializer ser{};
+    ser.write(vec);
+}

This should output:

// [{x: 1, y: 2, z: 3, }, {x: 4, y: 5, z: 6, }, ]
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-core-data-ser-json.html b/docs-preview/pr-1032/examples-core-data-ser-json.html new file mode 100644 index 000000000..bf337721e --- /dev/null +++ b/docs-preview/pr-1032/examples-core-data-ser-json.html @@ -0,0 +1,121 @@ + + + + + Examples » Core » Data » Serialization » JSON Serializer | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Core » + Data » + Serialization » + JSON Serializer +

+

Implementing JSONSerializer.

+

You'll need to include core/data/ser/json.hpp. For simplicity, in this sample we'll use the following aliases:

#include <cubos/core/data/ser/serializer.hpp>
+
+using cubos::core::data::Serializer;
+using cubos::core::reflection::Type;

Using the JSON serializer is as simple as calling JSONSerializer::write on the data we want to serialize.

In this case, we'll be serializing a std::vector<std::vector<std::vector<glm::ivec3>>>, which is a nested array of objects with three int32_t fields.

#include <glm/vec3.hpp>
+
+#include <cubos/core/reflection/external/glm.hpp>
+#include <cubos/core/reflection/external/vector.hpp>
+
+int main()
+{
+    std::vector<glm::ivec3> vec{{1, 2, 3}, {4, 5, 6}};
+
+    MySerializer ser{};
+    ser.write(vec);
+}

This should output:

// [{x: 1, y: 2, z: 3, }, {x: 4, y: 5, z: 6, }, ]
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-core-data-ser.html b/docs-preview/pr-1032/examples-core-data-ser.html new file mode 100644 index 000000000..947b5f318 --- /dev/null +++ b/docs-preview/pr-1032/examples-core-data-ser.html @@ -0,0 +1,106 @@ + + + + + Examples » Core » Data » Serialization | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-core-data.html b/docs-preview/pr-1032/examples-core-data.html new file mode 100644 index 000000000..690b7c845 --- /dev/null +++ b/docs-preview/pr-1032/examples-core-data.html @@ -0,0 +1,105 @@ + + + + + Examples » Core » Data | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-core-logging.html b/docs-preview/pr-1032/examples-core-logging.html new file mode 100644 index 000000000..bbf49dad6 --- /dev/null +++ b/docs-preview/pr-1032/examples-core-logging.html @@ -0,0 +1,116 @@ + + + + + Examples » Core » Logging | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Core » + Logging +

+

Using the logging system.

+

Logging in CUBOS. is done through the logging macros defined in core/log.hpp.

#include <cubos/core/log.hpp>

There are six logging levels, each with its own macro. In order of increasing severity, they are:

    CUBOS_TRACE("Trace message");
+    CUBOS_DEBUG("Debug message");
+    CUBOS_INFO("Info message");
+    CUBOS_WARN("Warning message");
+    CUBOS_ERROR("Error message");
+    CUBOS_CRITICAL("Critical message");

The minimum registered log level is set with Logger::level. On this sample, to demonstrate CUBOS_TRACE, we set it to Trace:

    cubos::core::Logger::level(cubos::core::Logger::Level::Trace);

These macros can also take arguments, which can be of any reflectable type.

    CUBOS_INFO("An integer: {}", 1);
+    CUBOS_INFO("A glm::vec3: {}", glm::vec3(0.0F, 1.0F, 2.0F));
+    CUBOS_INFO("An std::unordered_map: {}", std::unordered_map<int, const char*>{{1, "one"}, {2, "two"}});
+}

To print external types, such as glm math types, STL types (std::string, ...) or primitives (int, ...), you'll have to include their respective headers in the core/reflection/external directory. Notice that although we aren't printing C-strings directly, we must still include them as our std::unordered_map contains const char*s.

#include <cubos/core/reflection/external/cstring.hpp>
+#include <cubos/core/reflection/external/glm.hpp>
+#include <cubos/core/reflection/external/primitives.hpp>
+#include <cubos/core/reflection/external/unordered_map.hpp>
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-core-reflection-basic.html b/docs-preview/pr-1032/examples-core-reflection-basic.html new file mode 100644 index 000000000..fc3508b80 --- /dev/null +++ b/docs-preview/pr-1032/examples-core-reflection-basic.html @@ -0,0 +1,138 @@ + + + + + Examples » Core » Reflection » Basic Usage | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Core » + Reflection » + Basic Usage +

+

Defining and using reflectable types.

+

Lets say you have a type Person, which you want to be able to reflect. You can declare it as reflectable using the macro CUBOS_REFLECT, for example, in your header, like this:

#include <cubos/core/reflection/reflect.hpp>
+
+struct Person
+{
+    CUBOS_REFLECT;
+    int age;
+    float weight;
+};

The file core/reflection/reflect.hpp is a very lightweight header which you should include when declaring types as reflectable. It only defines the reflection macros and the reflection function. Avoid including other unnecessary reflection headers, which might be heavier, in order to reduce compile times.

In your source file, you must define the reflection data for your type. This is done through the CUBOS_REFLECT_IMPL macro:

#include <cubos/core/reflection/type.hpp>
+
+using cubos::core::reflection::Type;
+
+CUBOS_REFLECT_IMPL(Person)
+{
+    return Type::create("Person");
+}

To access this reflection data, you should use the cubos::core::reflection::reflect function, which is also defined in the core/reflection/reflect.hpp header.

int main()
+{
+    using cubos::core::reflection::reflect;
+
+    const auto& personType = reflect<Person>();
+    CUBOS_ASSERT(personType.name() == "Person");

Lets say you want to associate your own data to your types, to describe them further. For example, imagine you're making a GUI editor for your game and you which to display the fields of your types in a tree view, with different colors for different types. You could associate colors to your types by defining a trait:

struct ColorTrait
+{
+    float r, g, b;
+};

Now, when you define your type reflection, you add your trait with the Type::with method.

CUBOS_REFLECT_IMPL(Position)
+{
+    return Type::create("Position").with(ColorTrait{.r = 0.0F, .g = 1.0F, .b = 0.0F});
+}

To check if a type has a trait, you use the Type::has method.

    const auto& positionType = reflect<Position>();
+    CUBOS_ASSERT(positionType.has<ColorTrait>());
+    CUBOS_ASSERT(!personType.has<ColorTrait>());

To actually access the trait data, you use the Type::get method.

    const auto& colorTrait = positionType.get<ColorTrait>();
+    CUBOS_ASSERT(colorTrait.r == 0.0F);
+    CUBOS_ASSERT(colorTrait.g == 1.0F);
+    CUBOS_ASSERT(colorTrait.b == 0.0F);
+    return 0;
+}
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-core-reflection-traits-array.html b/docs-preview/pr-1032/examples-core-reflection-traits-array.html new file mode 100644 index 000000000..827564305 --- /dev/null +++ b/docs-preview/pr-1032/examples-core-reflection-traits-array.html @@ -0,0 +1,145 @@ + + + + + Examples » Core » Reflection » Array Trait | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Core » + Reflection » + Array Trait +

+

Exposing and using array functionality of a type.

+

The ArrayTrait trait is used to expose the array functionality of a type. In this example, we will write a function which takes a type and an instance of that type, and prints its elements:

#include <cubos/core/reflection/traits/array.hpp>
+#include <cubos/core/reflection/type.hpp>
+
+using cubos::core::reflection::ArrayTrait;
+using cubos::core::reflection::Type;
+
+void printArray(const Type& type, const void* instance)
+{
+    const auto& arrayTrait = type.get<ArrayTrait>();

Through the trait, we can access the size of the array and its element type:

    auto arrayView = arrayTrait.view(instance);
+    CUBOS_INFO("Array with {} elements of type {}", arrayView.length(), arrayTrait.elementType().name());

We can also get pointers to the elements of the array and iterate over them:

    if (!arrayTrait.elementType().is<int32_t>())
+    {
+        CUBOS_INFO("This function does not support printing arrays of types other than int32_t");
+        return;
+    }
+
+    for (const auto* element : arrayView)
+    {
+        CUBOS_INFO("{}", *static_cast<const int32_t*>(element));
+    }
+}

In this example, we're only supporting arrays of int32_ts, but we could for example implement a printing function which supports all primitive types.

To make calling our function easier, we can add a convenience typed wrapper:

template <typename T>
+void printArray(const T& array)
+{
+    using cubos::core::reflection::reflect;
+
+    printArray(reflect<T>(), &array);
+}

Using this function is now as simple as:

// You must also include <cubos/core/reflection/external/primitives.hpp> :)
+#include <cubos/core/reflection/external/vector.hpp>
+
+int main()
+{
+    std::vector<int32_t> vec = {1, 1, 2, 3, 5, 8, 13};
+    printArray(vec);
+}

Its important to note that both the includes above are necessary, as we're reflecting the type std::vector<int32_t>, which also means reflecting int32_t.

Executing the sample should output:

// Array with 7 elements of type int32_t
+// 1
+// 1
+// 2
+// 3
+// 5
+// 8
+// 13
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-core-reflection-traits-constructible.html b/docs-preview/pr-1032/examples-core-reflection-traits-constructible.html new file mode 100644 index 000000000..9899aa0e9 --- /dev/null +++ b/docs-preview/pr-1032/examples-core-reflection-traits-constructible.html @@ -0,0 +1,133 @@ + + + + + Examples » Core » Reflection » Constructible Trait | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Core » + Reflection » + Constructible Trait +

+

Exposing the destructor and constructors of a type.

+

You may find it useful while working with type-erased data to be able to create copies of the data, destroy it, or move it around. The ConstructibleTrait trait exposes the size, alignment, destructor and constructors of a type.

Lets say you have a type Scale, which you want to be able to reflect, with a default value of 1.0:

#include <cubos/core/reflection/reflect.hpp>
+
+struct Scale
+{
+    CUBOS_REFLECT;
+    float value = 1.0F;
+};

We're going to add the ConstructibleTrait trait to it, so that we can create instances of it at runtime:

#include <cubos/core/reflection/traits/constructible.hpp>
+#include <cubos/core/reflection/type.hpp>
+
+using cubos::core::reflection::ConstructibleTrait;
+using cubos::core::reflection::Type;
+
+CUBOS_REFLECT_IMPL(Scale)
+{
+    return Type::create("Scale").with(ConstructibleTrait::typed<Scale>().withDefaultConstructor().build());
+}

Now, we can access the trait from the reflected type:

int main()
+{
+    using cubos::core::reflection::reflect;
+
+    const auto& scaleType = reflect<Scale>();
+    CUBOS_ASSERT(scaleType.has<ConstructibleTrait>());
+    const auto& constructible = scaleType.get<ConstructibleTrait>();

Imagine for a moment that you don't know the type of the data you're working, and you only have access to its reflection data through scaleType. If you want to create a default instance of the type, you can call the default constructor stored in the trait:

    // Allocate memory for the instance and default-construct it.
+    void* instance = operator new(constructible.size());
+    constructible.defaultConstruct(instance);
+    CUBOS_ASSERT(static_cast<Scale*>(instance)->value == 1.0F);

Don't forget to destroy the instance manually when you're done with it:

    // Destroy the instance and deallocate its memory.
+    constructible.destruct(instance);
+    operator delete(instance);
+}
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-core-reflection-traits-dictionary.html b/docs-preview/pr-1032/examples-core-reflection-traits-dictionary.html new file mode 100644 index 000000000..f53806dd0 --- /dev/null +++ b/docs-preview/pr-1032/examples-core-reflection-traits-dictionary.html @@ -0,0 +1,154 @@ + + + + + Examples » Core » Reflection » Dictionary Trait | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Core » + Reflection » + Dictionary Trait +

+

Exposing and using dictionary functionality of a type.

+

The DictionaryTrait trait is used to expose the dictionary functionality of a type. In this example, we will write a function which takes a type and an instance of that type, and prints its entries:

#include <cubos/core/reflection/traits/dictionary.hpp>
+#include <cubos/core/reflection/type.hpp>
+
+using cubos::core::reflection::DictionaryTrait;
+using cubos::core::reflection::Type;
+
+void printDictionary(const Type& type, const void* instance)
+{
+    const auto& dictionaryTrait = type.get<DictionaryTrait>();

Through the trait, we can access the size of the dictionary and its key and value types:

    auto dictionaryView = dictionaryTrait.view(instance);
+    CUBOS_INFO("Dictionary with {} entries of key type {} and value type {}", dictionaryView.length(),
+               dictionaryTrait.keyType().name(), dictionaryTrait.valueType().name());

We can also iterate over the entries of a dictionary and access them:

    if (!dictionaryTrait.keyType().is<int32_t>() || !dictionaryTrait.valueType().is<int32_t>())
+    {
+        CUBOS_INFO("This function does not support printing dictionary with key and value types other than int32_t");
+        return;
+    }
+
+    for (auto [key, value] : dictionaryView)
+    {
+        CUBOS_INFO("{} -> {}", *static_cast<const int32_t*>(key), *static_cast<const int32_t*>(value));
+    }
+}

In this example, we're only supporting dictionaris which map int32_ts, but we could for example implement a printing function which supports all primitive types.

To make calling our function easier, we can add a convenience typed wrapper:

template <typename T>
+void printDictionary(const T& dictionary)
+{
+    using cubos::core::reflection::reflect;
+
+    printDictionary(reflect<T>(), &dictionary);
+}

Using this function is now as simple as:

#include <cubos/core/reflection/external/map.hpp>
+#include <cubos/core/reflection/external/primitives.hpp>
+
+int main()
+{
+    std::map<int32_t, int32_t> map = {
+        {1, 2},
+        {2, 4},
+        {3, 6},
+        {4, 8},
+    };
+    printDictionary(map);
+
+    // Dictionary with 4 entries of key type int32_t and value type int32_t
+    // 1 -> 2
+    // 2 -> 4
+    // 3 -> 6
+    // 4 -> 8
+}

Its important to note that both the includes above are necessary, as we're reflecting the type std::map<int32_t, int32_t>, which also means reflecting int32_t.

Executing the sample should output:

    // Dictionary with 4 entries of key type int32_t and value type int32_t
+    // 1 -> 2
+    // 2 -> 4
+    // 3 -> 6
+    // 4 -> 8
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-core-reflection-traits-enum.html b/docs-preview/pr-1032/examples-core-reflection-traits-enum.html new file mode 100644 index 000000000..36318bc03 --- /dev/null +++ b/docs-preview/pr-1032/examples-core-reflection-traits-enum.html @@ -0,0 +1,162 @@ + + + + + Enum Trait | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Enum Trait +

+

Exposing an enumeration with variants.

+

In this example, we'll explore how to expose an enumeration along with its variants using cubos::core::reflection::EnumTrait.

#include <cubos/core/reflection/reflect.hpp>
+
+enum class Color
+{
+    Red,
+    Green,
+    Blue
+};
#include <cubos/core/reflection/traits/enum.hpp>
+#include <cubos/core/reflection/type.hpp>
+
+using cubos::core::reflection::EnumTrait;
+using cubos::core::reflection::Type;
+
+template <>
+CUBOS_REFLECT_EXTERNAL_IMPL(Color)
+{
+    return Type::create("Color").with(
+        EnumTrait{}.withVariant<Color::Red>("Red").withVariant<Color::Green>("Green").withVariant<Color::Blue>("Blue"));
+}

This section includes the necessary headers for reflection and defines the reflection for the Color enumeration.

Output:

int main()
+{
+    using cubos::core::reflection::reflect;
+
+    const auto& colorType = reflect<Color>();
+    CUBOS_ASSERT(colorType.has<EnumTrait>());
+
+    const auto& variants = colorType.get<EnumTrait>();
+    CUBOS_ASSERT(variants.contains("Red"));
+    CUBOS_ASSERT(variants.contains("Green"));
+    CUBOS_ASSERT(variants.contains("Blue"));
+    CUBOS_ASSERT(!variants.contains("White"));
+
+    Color c = Color::Red;
+    CUBOS_ASSERT(variants.at("Red").test(&c));
+
+    c = Color::Green;
+    CUBOS_ASSERT(variants.at("Green").test(&c));
+
+    c = Color::Blue;
+    CUBOS_ASSERT(variants.at("Blue").test(&c));
+    variants.at("Red").set(&c);
+    CUBOS_ASSERT(variants.at("Red").test(&c));
+    CUBOS_ASSERT(variants.at("Red").name() == "Red");
+    CUBOS_ASSERT(variants.size() == 3);
+
+    for (const auto& v : variants)
+    {
+        CUBOS_INFO("Variant {}", v.name());
+    }
+
+    CUBOS_INFO("{}", EnumTrait::toString(Color::Red)); // should print Red
+    Color buf;
+    CUBOS_ASSERT(EnumTrait::fromString(buf, "Green"));
+    CUBOS_INFO("{}", EnumTrait::toString(buf)); // should print Green
+
+    return 0;
+}
[2023-11-19 13:09:36.117] [info] [main.cpp:59] Variant 'Red'
+[2023-11-19 13:09:36.118] [info] [main.cpp:59] Variant 'Green'
+[2023-11-19 13:09:36.119] [info] [main.cpp:59] Variant 'Blue'
+[2023-11-19 13:09:36.119] [info] [main.cpp:62] 'Red'
+[2023-11-19 13:09:36.119] [info] [main.cpp:65] 'Green'
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-core-reflection-traits-fields.html b/docs-preview/pr-1032/examples-core-reflection-traits-fields.html new file mode 100644 index 000000000..a2c1219ef --- /dev/null +++ b/docs-preview/pr-1032/examples-core-reflection-traits-fields.html @@ -0,0 +1,162 @@ + + + + + Examples » Core » Reflection » Fields Trait | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Core » + Reflection » + Fields Trait +

+

Exposing the fields of a type.

+

For structured types, like classes and structs, you might want to expose its public fields using the FieldsTrait trait. In this example, we'll expose the fields of the following type:

#include <cubos/core/reflection/reflect.hpp>
+
+struct Person
+{
+    CUBOS_REFLECT;
+    int32_t age;
+    float weight;
+    bool dead;
+};

In its reflection definition, we'll add the FieldsTrait trait to it with each of the fields we want to expose:

#include <cubos/core/reflection/traits/fields.hpp>
+#include <cubos/core/reflection/type.hpp>
+
+// Since we're exposing fields of primitive types (int32_t, float and bool), its important to
+// include the header which defines their reflection.
+#include <cubos/core/reflection/external/primitives.hpp>
+
+using cubos::core::reflection::FieldsTrait;
+using cubos::core::reflection::Type;
+
+CUBOS_REFLECT_IMPL(Person)
+{
+    return Type::create("Person").with(FieldsTrait()
+                                           .withField("age", &Person::age)
+                                           .withField("weight", &Person::weight)
+                                           .withField("dead", &Person::dead));
+}

Accessing this trait is the same as with any other trait:

int main()
+{
+    using cubos::core::reflection::reflect;
+
+    const auto& personType = reflect<Person>();
+    CUBOS_ASSERT(personType.has<FieldsTrait>());
+    const auto& fields = personType.get<FieldsTrait>();

We can iterate over the fields of the type with it:

    for (const auto& field : fields)
+    {
+        CUBOS_INFO("Field {} of type {}", field.name(), field.type().name());
+    }

This should output:

    // Field 'age' of type 'int32_t'
+    // Field 'weight' of type 'float'
+    // Field 'dead' of type 'bool'

Its also possible to access the fields of an instance of the type, and iterate over them:

    Person person{.age = 21, .weight = 68.4F, .dead = false};
+    auto view = fields.view(&person);
+
+    for (auto [field, value] : view)
+    {
+        if (field->type().is<int32_t>())
+        {
+            CUBOS_INFO("Field {}: {}", field->name(), *static_cast<int32_t*>(value));
+        }
+        else if (field->type().is<float>())
+        {
+            CUBOS_INFO("Field {}: {}", field->name(), *static_cast<float*>(value));
+        }
+        else
+        {
+            CUBOS_INFO("Field {}: unsupported type {}", field->name(), field->type().name());
+        }
+    }
    // Field 'age': 21
+    // Field 'weight': 68.4
+    // Field 'dead': unsupported type 'bool'

Its also possible to access the fields by name:

    *static_cast<float*>(view.get("weight")) += 20.0F;
+    CUBOS_INFO("New weight: {}", person.weight); // 88.4
+}
// New weight: 88.4
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-core-reflection-traits-mask.html b/docs-preview/pr-1032/examples-core-reflection-traits-mask.html new file mode 100644 index 000000000..b43d7451b --- /dev/null +++ b/docs-preview/pr-1032/examples-core-reflection-traits-mask.html @@ -0,0 +1,174 @@ + + + + + Mask Trait | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Mask Trait +

+

Exposing a bit mask type.

+

In this example, we'll explore how to expose a bit mask along with its bits using cubos::core::reflection::MaskTrait.

#include <cubos/core/reflection/reflect.hpp>
+
+enum class Permissions
+{
+    None = 0,
+
+    Read = 1,
+    Write = 2,
+    Execute = 4
+};
+
+inline Permissions operator~(Permissions p)
+{
+    return static_cast<Permissions>(~static_cast<int>(p));
+}
+
+inline Permissions operator|(Permissions a, Permissions b)
+{
+    return static_cast<Permissions>(static_cast<int>(a) | static_cast<int>(b));
+}
+
+inline Permissions operator&(Permissions a, Permissions b)
+{
+    return static_cast<Permissions>(static_cast<int>(a) & static_cast<int>(b));
+}
#include <cubos/core/reflection/traits/mask.hpp>
+#include <cubos/core/reflection/type.hpp>
+
+using cubos::core::reflection::MaskTrait;
+using cubos::core::reflection::Type;
+
+template <>
+CUBOS_REFLECT_EXTERNAL_IMPL(Permissions)
+{
+    return Type::create("Permissions")
+        .with(MaskTrait{}
+                  .withBit<Permissions::Read>("Read")
+                  .withBit<Permissions::Write>("Write")
+                  .withBit<Permissions::Execute>("Execute"));
+}

Notice that we don't include the None type in the trait, as it doesn't correspond to a bit.

int main()
+{
+    using cubos::core::reflection::reflect;
+
+    const auto& permissionsType = reflect<Permissions>();
+    CUBOS_ASSERT(permissionsType.has<MaskTrait>());
+
+    const auto& mask = permissionsType.get<MaskTrait>();
+    CUBOS_ASSERT(mask.contains("Read"));
+    CUBOS_ASSERT(mask.contains("Write"));
+    CUBOS_ASSERT(mask.contains("Execute"));
+    CUBOS_ASSERT(!mask.contains("None"));
+
+    auto p = Permissions::Read | Permissions::Write;
+    CUBOS_ASSERT(mask.view(&p).test("Read"));
+    CUBOS_ASSERT(mask.view(&p).test("Write"));
+    CUBOS_ASSERT(!mask.view(&p).test("Execute"));
+
+    for (const auto& b : mask)
+    {
+        CUBOS_INFO("Type has bit {}", b.name());
+    }
+
+    for (const auto& b : mask.view(&p))
+    {
+        CUBOS_INFO("Value has bit {} set", b.name());
+    }
+
+    return 0;
+}
// Type has bit "Read"
+// Type has bit "Write"
+// Type has bit "Execute"
+// Value has bit "Read" set
+// Value has bit "Write" set
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-core-reflection-traits-nullable.html b/docs-preview/pr-1032/examples-core-reflection-traits-nullable.html new file mode 100644 index 000000000..a84420c7f --- /dev/null +++ b/docs-preview/pr-1032/examples-core-reflection-traits-nullable.html @@ -0,0 +1,156 @@ + + + + + Nullable Trait | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Nullable Trait +

+

Handling null type representation.

+

The NullableTrait is a reflection trait designed to provide a mechanism for representing a null state for a specific type. This is particularly useful when working with types that are not literally null but can be conceptually treated as null in certain scenarios.

Consider a scenario where you have a data structure, such as the Entity struct, which represents an entity with an index and a generation. In some cases, you may want to define a special state that indicates the absence of a valid entity instead of checking if both fields are UINT32_MAX. So, instead of using a separate boolean flag to represent this state, the NullableTrait allows you to define a custom condition for considering an instance of the type as "null".

So, let's see how we can use this. First, we create a reflectable structure:

#include <cubos/core/reflection/reflect.hpp>
+
+struct MyEntity
+{
+    CUBOS_REFLECT;
+    uint32_t idx;
+    uint32_t generation;
+};

In the reflection definition, we use the NullableTrait to define the conditions under which an instance of MyEntity is considered null, and also another to set it to null.

#include <cubos/core/reflection/traits/nullable.hpp>
+#include <cubos/core/reflection/type.hpp>
+
+// Since we're exposing fields of primitive types (uint32_t), its important to
+// include the header which defines their reflection.
+#include <cubos/core/reflection/external/primitives.hpp>
+
+using cubos::core::reflection::NullableTrait;
+using cubos::core::reflection::Type;
+
+CUBOS_REFLECT_IMPL(MyEntity)
+{
+    return Type::create("MyEntity")
+        .with(NullableTrait{[](const void* instance) {
+                                const auto* ent = static_cast<const MyEntity*>(instance);
+                                return ent->idx == UINT32_MAX && ent->generation == UINT32_MAX;
+                            },
+                            [](void* instance) {
+                                auto* ent = static_cast<MyEntity*>(instance);
+                                ent->idx = UINT32_MAX;
+                                ent->generation = UINT32_MAX;
+                            }});
+}

Now, we can simply use it:

int main()
+{
+    using cubos::core::reflection::reflect;
+
+    // Retrieve the reflection information for MyEntity
+    const auto& entityType = reflect<MyEntity>();
+
+    // Check if MyEntity has the NullableTrait
+    CUBOS_ASSERT(entityType.has<NullableTrait>());
+
+    // Retrieve the NullableTrait for MyEntity
+    const auto& nullableTrait = entityType.get<NullableTrait>();
+
+    // Create an instance of MyEntity
+    MyEntity ent{1, 1};
+
+    // Check if the instance is not null
+    CUBOS_ASSERT(!nullableTrait.isNull(&ent));
+
+    // Set the instance to the null state
+    nullableTrait.setToNull(&ent);
+
+    // Check if the instance is now null
+    CUBOS_ASSERT(nullableTrait.isNull(&ent));
+}
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-core-reflection-traits-string-conversion.html b/docs-preview/pr-1032/examples-core-reflection-traits-string-conversion.html new file mode 100644 index 000000000..8d909625e --- /dev/null +++ b/docs-preview/pr-1032/examples-core-reflection-traits-string-conversion.html @@ -0,0 +1,136 @@ + + + + + Examples » Core » Reflection » String Conversion Trait | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Core » + Reflection » + String Conversion Trait +

+

Exposing string conversion functions of a type.

+

Lets say you have a type Name, which is just a wrapper around an std::string. If you want it to be picked up by (de)serializers and other reflection consumers as just a string, you can add the StringConversionTrait to your type.

#include <cubos/core/reflection/reflect.hpp>
+
+struct Name
+{
+    CUBOS_REFLECT;
+    std::string inner;
+};

The trait's constructor takes two functions: one to convert an instance of the to a string, and the other to convert a string to an instance of the type. The first method never fails, but the second one should return a boolean indicating whether the passed string was valid.

#include <cubos/core/reflection/traits/string_conversion.hpp>
+#include <cubos/core/reflection/type.hpp>
+
+using cubos::core::reflection::StringConversionTrait;
+using cubos::core::reflection::Type;
+
+CUBOS_REFLECT_IMPL(Name)
+{
+    return Type::create("Name").with(
+        StringConversionTrait{[](const void* instance) { return static_cast<const Name*>(instance)->inner; },
+                              [](void* instance, const std::string& string) {
+                                  static_cast<Name*>(instance)->inner = string;
+                                  return !string.empty(); // Only accept non-empty strings.
+                              }});
+}

Now, we can access the trait from the reflected type:

int main()
+{
+    using cubos::core::reflection::reflect;
+
+    const auto& nameType = reflect<Name>();
+    CUBOS_ASSERT(nameType.has<StringConversionTrait>());
+    const auto& stringConversion = nameType.get<StringConversionTrait>();

Using the trait is as simple as:

    Name name{"Michael"};
+    CUBOS_ASSERT(stringConversion.into(&name) == "Michael");
    CUBOS_ASSERT(stringConversion.from(&name, "John") == true); // Valid name, returns true
+    CUBOS_ASSERT(name.inner == "John");
+    CUBOS_ASSERT(stringConversion.from(&name, "") == false); // Invalid name, returns false
+}
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-core-reflection.html b/docs-preview/pr-1032/examples-core-reflection.html new file mode 100644 index 000000000..a219e683a --- /dev/null +++ b/docs-preview/pr-1032/examples-core-reflection.html @@ -0,0 +1,105 @@ + + + + + Examples » Core » Reflection | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-core.html b/docs-preview/pr-1032/examples-core.html new file mode 100644 index 000000000..4278f4699 --- /dev/null +++ b/docs-preview/pr-1032/examples-core.html @@ -0,0 +1,104 @@ + + + + + Examples » Core | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Core +

+

Showcases features of the Core library.

+

The following examples have fully documented tutorials:

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-engine-assets-bridge.html b/docs-preview/pr-1032/examples-engine-assets-bridge.html new file mode 100644 index 000000000..c1cc2cefb --- /dev/null +++ b/docs-preview/pr-1032/examples-engine-assets-bridge.html @@ -0,0 +1,143 @@ + + + + + Examples » Engine » Assets » Introduction and Custom Bridges | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Engine » + Assets » + Introduction and Custom Bridges +

+

Basic Assets plugin features and creating your own bridges.

+

This example demonstrates how we can create a custom asset bridge to load assets of a given type. More specifically, we'll go through how we can create a bridge which loads std::strings from text files.

We define our bridge class by inheriting from cubos::engine::FileBridge, which offers a simple interface for loading and saving assets from files.

class TextBridge : public FileBridge
+{
+public:
+    TextBridge()
+        : FileBridge(cubos::core::reflection::reflect<std::string>())
+    {
+    }

We pass typeid(std::string) to the base class, so that the engine knows which type of assets this bridge can load. Then, we'll need to implement both the loadFromFile and saveToFile methods.

In the first method, we receive the assets manager where we should store the loaded data, the handle to the asset we're loading, and a stream to read the file data from.

    bool loadFromFile(Assets& assets, const AnyAsset& handle, Stream& stream) override
+    {
+        // Dump the file's contents into a string.
+        std::string contents;
+        stream.readUntil(contents, nullptr);
+
+        // Store the asset's data.
+        assets.store(handle, std::move(contents));
+        return true;
+    }

In the second method, we receive the assets manager, the handle to the asset we're saving, and a stream to write the file data to.

    bool saveToFile(const Assets& assets, const AnyAsset& handle, Stream& stream) override
+    {
+        // Get the asset's data.
+        auto contents = assets.read<std::string>(handle);
+
+        // Write the data to the file.
+        stream.print(*contents);
+        return true;
+    }
+};

Now that we have our bridge type, we must register it with the assets manager before using it.

    cubos.startupSystem("setup bridge to load .txt files").tagged("cubos.assets.bridge").call([](Assets& assets) {
+        assets.registerBridge(".txt", std::make_unique<TextBridge>());
+    });

After this system runs, any time we load an asset whose path ends with .txt, the assets manager will use our bridge to load it.

In this sample we have a file sample.txt on the assets/ directory containing the following text:

How are you holding up?
+Because I'm a potato
+<clap clap clap>

We also have a file sample.txt.meta, which describes the asset for the engine. In this case, we only need to specify its UUID, which was generated on a UUID generator website:

{
+    "id": "6f42ae5a-59d1-5df3-8720-83b8df6dd536"
+}

Then, we can load it from our code:

    // Assets are identified through UUIDs which are defined in their .meta files.
+    static const Asset<std::string> SampleAsset = AnyAsset("6f42ae5a-59d1-5df3-8720-83b8df6dd536");
+
+    cubos.startupSystem("access .txt asset").tagged("cubos.assets").call([](const Assets& assets) {
+        // Access the text asset - will be loaded automatically.
+        auto text = assets.read(SampleAsset);
+        Stream::stdOut.print(*text);
+    });

Some care must be taken when registering bridges or loading assets during the startup phase. Systems which add bridges should be tagged with cubos.assets.bridge so that they run before any assets are loaded. Similarly, startup systems which load assets should be tagged with cubos.assets so that they run after all bridges have been registered.

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-engine-assets-json.html b/docs-preview/pr-1032/examples-engine-assets-json.html new file mode 100644 index 000000000..a8e390e15 --- /dev/null +++ b/docs-preview/pr-1032/examples-engine-assets-json.html @@ -0,0 +1,125 @@ + + + + + Examples » Engine » Assets » Loading Reflectable Assets | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Engine » + Assets » + Loading Reflectable Assets +

+

Loading reflectable assets from JSON.

+

We'll use the following type as an example:

struct Strings
+{
+    CUBOS_REFLECT;
+    std::vector<std::string> strings;
+};
+
+CUBOS_REFLECT_IMPL(Strings)
+{
+    return Type::create("Strings").with(FieldsTrait{}.withField("strings", &Strings::strings));
+}

Then, we must register a bridge for this type. We provide JSONBridge for easily loading and saving reflectable assets as JSON.

    cubos.startupSystem("setup bridge to load .strings files").tagged("cubos.assets.bridge").call([](Assets& assets) {
+        assets.registerBridge(".strings", std::make_unique<JSONBridge<Strings>>());
+    });

With the bridge registered, we can just load it from its handle:

    static const Asset<Strings> SampleAsset = AnyAsset("6f42ae5a-59d1-5df3-8720-83b8df6dd536");
+
+    cubos.startupSystem("access .strings asset").tagged("cubos.assets").call([](Assets& assets) {
+        auto read = assets.read(SampleAsset);
+        for (const auto& str : read->strings)
+        {
+            Stream::stdOut.printf("String: {}\n", str);
+        }
+    });

These sytems are configured the usual way, as explained in Introduction and Custom Bridges.

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-engine-assets-saving.html b/docs-preview/pr-1032/examples-engine-assets-saving.html new file mode 100644 index 000000000..46e4b8954 --- /dev/null +++ b/docs-preview/pr-1032/examples-engine-assets-saving.html @@ -0,0 +1,120 @@ + + + + + Examples » Engine » Assets » Creating and Saving | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Engine » + Assets » + Creating and Saving +

+

Creating and saving assets.

+

This example demonstrates how a new asset can be created programatically and how it can be saved to the assets directory, which is useful while working on tools such as TESSERATOS

Before we go any further, if we want to save assets to the filesystem, we must allow assets to be modified. This is done through the following setting:

    cubos.startupSystem("configure Assets plugin").tagged("cubos.settings").call([](Settings& settings) {
+        // If we want to save assets, we must set this to false.
+        settings.setBool("assets.io.readOnly", false);

We'll use the following asset type as an example, with a JSONBridge registered for it with the extension .int.

struct IntegerAsset
+{
+    CUBOS_REFLECT;
+    int value;
+};
+
+CUBOS_REFLECT_IMPL(IntegerAsset)
+{
+    return Type::create("IntegerAsset").with(FieldsTrait{}.withField("value", &IntegerAsset::value));
+}

First, we'll create an asset of this type:

    cubos.startupSystem("create and save asset").tagged("cubos.assets").call([](Assets& assets) {
+        // Create a new asset (with a random UUID).
+        auto handle = assets.create(IntegerAsset{1337});

Then, we'll assign it a path and save it. It's important that the path ends with the correct extension, so that Assets knows which bridge to use when loading it.

        assets.writeMeta(handle)->set("path", "/assets/sample/sample.int");
+        assets.save(handle);

With this, the files sample/sample.int and sample/sample.int.meta should have appeared on the assets/ directory. The .meta file contains the UUID of the asset, which is used by the engine to identify it.

Try running the sample yourself to see the files being created!

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-engine-assets.html b/docs-preview/pr-1032/examples-engine-assets.html new file mode 100644 index 000000000..338f3b9eb --- /dev/null +++ b/docs-preview/pr-1032/examples-engine-assets.html @@ -0,0 +1,105 @@ + + + + + Examples » Engine » Assets | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-engine-events.html b/docs-preview/pr-1032/examples-engine-events.html new file mode 100644 index 000000000..caf235996 --- /dev/null +++ b/docs-preview/pr-1032/examples-engine-events.html @@ -0,0 +1,161 @@ + + + + + Examples » Engine » Events | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Engine » + Events +

+

Using the EventReader and EventWriter.

+

This example shows how the EventReader and the EventWriter system arguments can be used to communicate from one system to another.

Firstly, we need to create and register the event we want to emit. Here, our event is a simple struct with a single field, however, you can use any type you want.

struct MyEvent
+{
+    int value;
+};
    cubos.addEvent<MyEvent>();

To receive these events, we can make a simple system which takes the EventReader system argument and iterates through all the events it has. This will be the layout of all our reader systems (A, C, D).

    cubos.system("A").before("b").call([](EventReader<MyEvent> reader) {
+        for (const auto& event : reader)
+        {
+            CUBOS_INFO("A read {}", event.value);
+        }
+    });
+
+    cubos.system("C").tagged("c").after("b").call([](EventReader<MyEvent> reader) {
+        for (const auto& event : reader)
+        {
+            CUBOS_INFO("C read {}", event.value);
+        }
+    });
+
+    cubos.system("D").after("c").call([](EventReader<MyEvent> reader) {
+        for (const auto& event : reader)
+        {
+            CUBOS_INFO("D read {}", event.value);
+        }
+    });

Now, to emit these events, we will use the EventWriter system argument. This system will emit 3 events on the first frame and another 3 on the second frame. By setting the value of the ShouldQuit resource to true on the second frame, the engine stops before reaching the third frame.

    cubos.system("B").tagged("b").call([](EventWriter<MyEvent> writer, State& state, ShouldQuit& quit) {
+        state.step += 1;
+        if (state.step == 1) // Write 1 2 3 on first run.
+        {
+            writer.push({1});
+            writer.push({2});
+            writer.push({3});
+            CUBOS_INFO("B wrote 1 2 3");
+        }
+        else if (state.step == 2)
+        {
+            quit.value = true; // Stop the loop.
+            writer.push({4});
+            writer.push({5});
+            writer.push({6});
+            CUBOS_INFO("B wrote 4 5 6");
+        }
+    });

These are the expected results with this order.

    // Should print:
+    // B wrote 1 2 3
+    // C read 1
+    // C read 2
+    // C read 3
+    // D read 1
+    // D read 2
+    // D read 3
+    // A read 1
+    // A read 2
+    // A read 3
+    // B wrote 4 5 6
+    // C read 4
+    // C read 5
+    // C read 6
+    // D read 4
+    // D read 5
+    // D read 6

There are a couple of things to note here. First, the order in which the systems appear to receive the event. C receives the event, followed by D, this happens because even though A comes before C it also come before B, which is where the event is emitted, this means that C and D can read the event emitted by B on that same frame, while A will only read it on the next frame. This also explains why on the second run, A is never displayed, indeed, the engine quit before A got a chance to receive it's so desired events. This shows how the results of the execution of systems that use events may vary with the order set for them, so special care should be taken when defining this.

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-engine-gizmos.html b/docs-preview/pr-1032/examples-engine-gizmos.html new file mode 100644 index 000000000..421fbb3a1 --- /dev/null +++ b/docs-preview/pr-1032/examples-engine-gizmos.html @@ -0,0 +1,155 @@ + + + + + Examples » Engine » Gizmos | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Engine » + Gizmos +

+

Using the Gizmos plugin.

+

This example shows the Gizmos plugin, which allows drawing simple primitives. These are not intended for use in the final product, only in developer tools and for debugging.

The plugin function is included from the engine/gizmos/plugin.hpp header.

    Cubos cubos{argc, argv};
+    cubos.addPlugin(gizmosPlugin);

To draw a gizmo, all you need to do is to get a reference to the cubos::engine::Gizmos resource, and then call the draw function on it for the gizmo you want to draw. Additionally, you can also call the cubos::engine::Gizmos::color function to set the color for future gizmos. So, for example if you want to draw an arrow in a given system, all you need to do is the following:

    cubos.startupSystem("draw line at startup")
+        .tagged("sample.init")
+        .after("cubos.gizmos.init")
+        .call([](Gizmos& gizmos) {
+            gizmos.color({1, 0, 1});
+            gizmos.drawArrow("arrow", {0.6F, 0.6F, 0.0F}, {-0.1F, -0.1F, 0.0F}, 0.003F, 0.009F, 0.7F, 10.0F,
+                             Gizmos::Space::Screen);
+        });

This code will draw an arrow poiting at the center of the screen, and it will stay there for 10 seconds.

In this other example, we draw lines, a box, and a wire box. Unlike the one in the previous example, this system is not a start-up system, so the draw functions get called every single frame. When this happens, you should set the lifetime of a gizmo to 0, which means it will be drawn for a single frame only. This way we avoid drawing gizmos on top of identical ones that were already there, or in the case of moving gizmos, leaving a trail of old version behind them.

Let's start with the lines. We are using four cameras in our scene, so let's add two lines to separate each camera. These lines will be in Screen space, as we want them to be just drawn once, indepently of the number of cameras; and we want them to use screen coordinates, as they should be drawn in the middle of the screen.

        gizmos.color({1.0F, 1.0F, 1.0F});
+        gizmos.drawLine("separator line", {1.0F, 0.5F, 0.5F}, {0.0F, 0.5F, 0.5F}, 0, Gizmos::Space::Screen);
+        gizmos.drawLine("separator line", {0.5F, 1.0F, 0.5F}, {0.5F, 0.0F, 0.5F}, 0, Gizmos::Space::Screen);

Let's now add a wireboxe. We want to know were exactly is the centre of each camera, so let's add a reticule. This box will be in View space, as we want it to be drawn once per camera and we want it to use view coordinates, as it should be drawn in the middle of each viewport.

        gizmos.color({1.0F, 0.5F, 1.0F});
+        gizmos.drawBox("box", {0.4, 0.4, 0}, {0.55, 0.55, 0}, 0, Gizmos::Space::View);

Let's add a box. This box will be in World space, as it's the last space left to cover. It will be drawn by any camera that is looking at it, much like if it was an object in the world.

        gizmos.color({0.2F, 0.2F, 1.0F});
+        gizmos.drawWireBox("wire box", {-5, -5, -5}, {-7, -7, -7}, 0, Gizmos::Space::World);

Finally let's add a cut cone. A cut cone is cylinder with faces that can have different radiuses. If you set one of the bases to have a radius of 0, you'll have a simple cone. If you set them both to have the same radius, you'll have a cylinder. Our cut cone will have different radiuses:

        if (gizmos.hovered("cut cone"))
+        {
+            gizmos.color({0.25F, 0.15F, 0.5F});
+        }
+        else if (gizmos.pressed("cut cone"))
+        {
+            gizmos.color({0.5F, 0.3F, 1});
+        }
+        else
+        {
+            gizmos.color({0.1F, 0.05F, 0.25F});
+        }
+
+        gizmos.drawCutCone("cut cone", {0.7F, 0.7F, 0.7F}, 5.0F, {-3, -3, -3}, 3.0F, 0, Gizmos::Space::World);

For the cut cone, we'll set the color a bit differently: We'll make it so the color of the cone changes depending on whether you are pressing the cone, or have your mouse over it. We'll make it a bit darker while the mouse is not over the cone, a bit lighter when it is, and even lighter when the cone is pressed.

The whole system looks like this:

    cubos.system("draw gizmos").call([](Gizmos& gizmos) {
+        gizmos.color({1.0F, 1.0F, 1.0F});
+        gizmos.drawLine("separator line", {1.0F, 0.5F, 0.5F}, {0.0F, 0.5F, 0.5F}, 0, Gizmos::Space::Screen);
+        gizmos.drawLine("separator line", {0.5F, 1.0F, 0.5F}, {0.5F, 0.0F, 0.5F}, 0, Gizmos::Space::Screen);
+
+        gizmos.color({1.0F, 0.5F, 1.0F});
+        gizmos.drawBox("box", {0.4, 0.4, 0}, {0.55, 0.55, 0}, 0, Gizmos::Space::View);
+
+        gizmos.color({0.2F, 0.2F, 1.0F});
+        gizmos.drawWireBox("wire box", {-5, -5, -5}, {-7, -7, -7}, 0, Gizmos::Space::World);
+
+        if (gizmos.hovered("cut cone"))
+        {
+            gizmos.color({0.25F, 0.15F, 0.5F});
+        }
+        else if (gizmos.pressed("cut cone"))
+        {
+            gizmos.color({0.5F, 0.3F, 1});
+        }
+        else
+        {
+            gizmos.color({0.1F, 0.05F, 0.25F});
+        }
+
+        gizmos.drawCutCone("cut cone", {0.7F, 0.7F, 0.7F}, 5.0F, {-3, -3, -3}, 3.0F, 0, Gizmos::Space::World);
+    });
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-engine-hello-cubos.html b/docs-preview/pr-1032/examples-engine-hello-cubos.html new file mode 100644 index 000000000..971663a70 --- /dev/null +++ b/docs-preview/pr-1032/examples-engine-hello-cubos.html @@ -0,0 +1,138 @@ + + + + + Examples » Engine » Hello CUBOS. | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Engine » + Hello CUBOS. +

+

Using Cubos to create a simple program.

+

This example shows the basics of how cubos::engine::Cubos is used, by making a simple "Hello World" program.

#include <cubos/engine/prelude.hpp>
+
+using namespace cubos::engine;

First we'll need to get a Cubos object.

int main()
+{
+    Cubos cubos{};

The Cubos class represents the engine. We'll need it to add functionality to our program.

Let's start by defining what functionality we want to add, by adding our first system.

    cubos.startupSystem("say Hello CUBOS").call([]() { CUBOS_INFO("Hello CUBOS"); });

This startup system simply prints Hello CUBOS to the console, using one of CUBOS's logging macros. You can find more about them here. Startup systems run only once when the engine is loaded.

Now let's make things more interesting. Let's print Hello World, but split it over two different systems.

    cubos.system("say Hello").tagged("helloTag").call([]() { CUBOS_INFO("Hello"); });
+    cubos.system("say World").tagged("worldTag").call([]() { CUBOS_INFO("World"); });

Instead of using startupSystem, we'll use Cubos::system. This means the systems will be called after the startup systems and repeat every cycle, instead of just once at startup.

Notice that we can't just do as we did for Hello CUBOS and call it a day. We want Hello to come before World, so we'll have to explicitly tell that to the engine, or else we risk having them in the wrong order. To do that we use tags.

    cubos.tag("helloTag").before("worldTag");

Cubos::tag can be used to apply properties to all systems with a given tag, and before makes any systems tagged with it come before systems tagged with the one given as parameter. There's also an after that has the inverse effect.

Now let's see a bit about entities, components and resources. First we are going to need to use a few more things. We'll go over what each does as it comes up.

Lets define a new component type, which stores a single integer, which we can use to identify the entity.

#include <cubos/core/ecs/reflection.hpp>
+#include <cubos/core/reflection/external/primitives.hpp>
+
+struct Num
+{
+    CUBOS_REFLECT;
+
+    int value;
+};
+
+CUBOS_REFLECT_IMPL(Num)
+{
+    return cubos::core::ecs::TypeBuilder<Num>("Num").withField("value", &Num::value).build();
+}

Notice that not only we define the type, but we also define reflection for it. This is a way to let CUBOS know what our data type is made of, making it compatible with serialization, UI debug tools and others automatically.

We also need to register the component type with the Cubos object.

    cubos.addComponent<Num>();

Now, lets create our own resource.

struct Pop
+{
+    int count;
+};

This resource will store the total number of spawned entities, a population counter of sorts. It too needs to be registered.

    cubos.addResource<Pop>();

Now let's create a startup system that spawns some entities.

    cubos.startupSystem("spawn entities").call([](Commands cmds, Pop& pop) {
+        for (int i = 0; i < 10; i++)
+        {
+            cmds.create().add(Num{i});
+            pop.count += 1;
+        }
+    });

Commands is a system argument that allows us to interact with the world, in this case, by creating entities that have a Num component.

To access the resource Pop, we just add a reference to it as a system argument (Pop&).

Finally, we'll want a system that prints our entities.

    cubos.system("check entities").call([](Query<const Num&> query, const Pop& pop) {
+        for (auto [num] : query)
+        {
+            CUBOS_INFO("Entity {} of {}", num.value, pop.count);
+        }
+    });

In this case, we don't change Pop, and only read its value. Thus, we use const Pop&. This allows CUBOS to make some optimizations behind the scenes.

Query allows us to access all entities with a given configuration of components. In this case, it will give us all entities with the Num component.

With everything properly set up, all that remains is to run the engine.

    cubos.run();
+}

Try running the sample yourself, and you should see both the hello world messages and the list of entities we spawned!

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-engine-imgui.html b/docs-preview/pr-1032/examples-engine-imgui.html new file mode 100644 index 000000000..c94384920 --- /dev/null +++ b/docs-preview/pr-1032/examples-engine-imgui.html @@ -0,0 +1,192 @@ + + + + + Examples » Engine » ImGui | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Engine » + ImGui +

+

Using the ImGui integration plugin and cubos::engine::DataInspector resource.

+

The ImGui plugin allows you to integrate the Dear ImGui library with CUBOS., making it quick, straightforward, and effortless to create user interfaces and interactive debugging tools within your applications.

Image

First, let's start by including the header files we need.

#include <iostream>
+#include <map>
+#include <vector>
+
+#include <imgui.h>
+
+#include <cubos/core/reflection/external/map.hpp>
+#include <cubos/core/reflection/external/primitives.hpp>
+#include <cubos/core/reflection/external/string.hpp>
+#include <cubos/core/reflection/external/vector.hpp>
+#include <cubos/core/reflection/reflect.hpp>
+#include <cubos/core/reflection/traits/constructible.hpp>
+#include <cubos/core/reflection/traits/fields.hpp>
+#include <cubos/core/reflection/traits/nullable.hpp>
+
+#include <cubos/engine/imgui/data_inspector.hpp>
+#include <cubos/engine/imgui/plugin.hpp>

Then, make sure to add the plugin.

    cubos.addPlugin(imguiPlugin);

Once the ImGui plugin is added, you can create systems to display ImGui windows and widgets. Here's a system which opens an ImGui window, and its demo.

    cubos.system("show ImGui demo").tagged("cubos.imgui").call([]() {
+        ImGui::Begin("Dear ImGui + CUBOS.");
+        ImGui::Text("Hello world!");
+        ImGui::End();
+
+        ImGui::ShowDemoWindow();
+    });

Ensure that you add your system with the cubos.imgui tag; otherwise, the ImGui elements from that system won't be be visible.

Pretty simple right? You're now equipped to craft and utilize ImGui's functions to design your cool user interface.

Now, we'll also show you how you can use the cubos::engine::DataInspector resource in combination with ImGui integration plugin to inspect/modify data in real time.

To start off, we'll need to have some sort of dummy data shared across our application, so we can inspect/modify later. Let's create a DummyResource with some fields and fill it with random data.

struct Person
+{
+    CUBOS_REFLECT;
+    std::string name;
+    int32_t age;
+    float weight;
+    bool dead;
+};
+
+CUBOS_REFLECT_IMPL(Person)
+{
+    return Type::create("Person")
+        .with(FieldsTrait()
+                  .withField("name", &Person::name)
+                  .withField("age", &Person::age)
+                  .withField("weight", &Person::weight)
+                  .withField("dead", &Person::dead))
+        .with(NullableTrait{[](const void* instance) {
+                                const auto* person = static_cast<const Person*>(instance);
+                                return person->dead;
+                            },
+                            [](void* instance) {
+                                auto* person = static_cast<Person*>(instance);
+                                person->dead = true;
+                            }})
+        .with(ConstructibleTrait::typed<Person>().withDefaultConstructor().build());
+}
+
+struct DummyResource
+{
+    CUBOS_REFLECT;
+
+    int integer;
+    Person person;
+    std::vector<Person> persons;
+    std::vector<int32_t> vec;
+    std::map<int32_t, int32_t> map;
+};
+
+CUBOS_REFLECT_IMPL(DummyResource)
+{
+    return Type::create("DummyResource")
+        .with(FieldsTrait()
+                  .withField("integer", &DummyResource::integer)
+                  .withField("person", &DummyResource::person)
+                  .withField("persons", &DummyResource::persons)
+                  .withField("vec", &DummyResource::vec)
+                  .withField("v", &DummyResource::map))
+        .with(ConstructibleTrait::typed<Person>().withDefaultConstructor().build());
+}
    cubos.addResource<DummyResource>(
+        DummyResource{.integer = 1337,
+                      .person = Person{"roby", 1337, 666.5F, false},
+                      .persons{Person{"roby", 1337, 666.5F, false}, Person{"riscado", 123, 321.0F, false}},
+                      .vec = {12, 59, 25},
+                      .map = {
+                          {1, 2},
+                          {2, 4},
+                          {3, 6},
+                          {4, 8},
+                      }});

Well now, using the cubos::engine::DataInspector is pretty easy, all you have to do is access the resource on your system, and use the functions DataInspector::edit and DataInspector::edit.

    cubos.system("data inspector example")
+        .tagged("cubos.imgui")
+        .call([](DataInspector& inspector, DummyResource& data) {
+            ImGui::Begin("Data Inspector");
+            inspector.edit(data);
+            ImGui::End();
+        });
Image

You can find more about how to use Dear ImGui stuff here.

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-engine-input.html b/docs-preview/pr-1032/examples-engine-input.html new file mode 100644 index 000000000..364b4b814 --- /dev/null +++ b/docs-preview/pr-1032/examples-engine-input.html @@ -0,0 +1,316 @@ + + + + + Examples » Engine » Input | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Engine » + Input +

+

Using the Input plugin.

+

This example shows how the scene-input plugin can be used to handle user input.

The plugin function is included from the engine/input/plugin.hpp header.

    cubos.addPlugin(inputPlugin);

The Input plugin requires a InputBindings asset to be set. Let's take a look at the file the sample uses.

{
+    "actions": {
+        "next-showcase": {
+            "keys": [
+                "Return"
+            ],
+            "gamepadButtons": [
+                "RBumper"
+            ]
+        },
+        "x-or-z": {
+            "keys": [
+                "X",
+                "Z"
+            ]
+        },
+        "shift-space": {
+            "keys": [
+                "Shift-Space"
+            ]
+        },
+        "ctrl-shift-space": {
+            "keys": [
+                "Control-Shift-Space"
+            ]
+        },
+        "left-mb": {
+            "mouseButtons": [
+                "Left"
+            ]
+        },
+        "right-mb": {
+            "mouseButtons": [
+                "Right"
+            ]
+        },
+        "middle-mb": {
+            "mouseButtons": [
+                "Middle"
+            ]
+        },
+        "extra-mb": {
+            "mouseButtons": [
+                "Extra1",
+                "Extra2"
+            ]
+        }
+    },
+    "axes": {
+        "vertical": {
+            "positive": [
+                "W",
+                "Up"
+            ],
+            "negative": [
+                "S",
+                "Down"
+            ],
+            "gamepadAxes": [
+                "LY"
+            ]
+        },
+        "horizontal": {
+            "positive": [
+                "D",
+                "Right"
+            ],
+            "negative": [
+                "A",
+                "Left"
+            ],
+            "gamepadAxes": [
+                "LX"
+            ]
+        },
+        "shift-vertical": {
+            "positive": [
+                "Shift-W",
+                "Shift-Up"
+            ],
+            "negative": [
+                "Shift-S",
+                "Shift-Down"
+            ],
+            "gamepadAxes": []
+        }
+    }
+}

There are two types of bindings: actions and axes. An action is an input that only has two states: pressed or not pressed. This would be most keys on a keyboard. An axe is an input that has a numeric value. For example, the joysticks on a controller can go from -1 to 1, depending on how much they are tilt in which direction. Using axes can also be useful for keys with symmetric behaviour. For example, in this sample, W sets the vertical axe to 1, while S sets it to -1.

To define an action or an axe, you simply have to add it to the respective list, giving it a name. The very first action in the file is called next-showcase. Then, if it's an action, you simply have to define which keys trigger it. You can also define key combinations by using a -. To check which strings map to which keys, you check the names of the variants of the enums Key and Modifier on this file.

Now that we have our bindings file, let's get our application to do something with it. The first thing we're going to need is a reference to the bindings asset. For the purposes of this sample we can simply use an hardcoded reference to the asset.

static const Asset<InputBindings> BindingsAsset = AnyAsset("bf49ba61-5103-41bc-92e0-8a442d7842c3");

To utilize the bindings, loading them is essential. This can be accomplished by establishing a startup systems which reads from the asset and sets the required bindings.

    cubos.startupSystem("load and set the Input Bindings")
+        .tagged("cubos.assets")
+        .call([](const Assets& assets, Input& input) {
+            auto bindings = assets.read<InputBindings>(BindingsAsset);
+            input.bind(*bindings);
+            CUBOS_INFO("Loaded bindings: {}", input.bindings().at(0));
+        });

Getting the input is done through the cubos::engine::Input resource. What this sample does is show in order, a series of prompt to showcase the different functionalities of the Input plugin. For this, it keeps a state integer that indicates the current prompt. Whenever the action next-showcase is triggered, it advances to the next prompt. However, as the plugin currently does not have events, we have to manually check whether the key has just been pressed, is being pressed continuously, or was just released.

    cubos.system("detect input")
+        .after("cubos.input.update")
+        .call([](const Input& input, const Window& window, State& state, ShouldQuit& shouldQuit) {
+            // FIXME: This is an hack to have one-shot actions while we don't have input events.
+            if (input.pressed("next-showcase"))
+            {
+                state.nextPressed = true;
+            }
+            else if (state.nextPressed)
+            {
+                state.nextPressed = false;
+                state.explained = false;
+                state.showcase++;
+            }

What this does is only advance the state when the return key is released. This avoids the state advancing more than once if the user presses it for more than one frame.

Now let's see each of the prompt, to understand the full breadth of the plugin's functionalities.

static void showcaseXZ(const Input& input, bool& explained)
+{
+    if (!explained)
+    {
+        CUBOS_WARN("This showcase will print `X or Z` when either X or Z is pressed. Press Enter to advance to the "
+                   "next showcase.");
+        explained = true;
+    }
+
+    if (input.pressed("x-or-z"))
+    {
+        CUBOS_INFO("X or Z");
+    }
+}

Finding out whether the user is pressing a key is checked by a simple call to Input::pressed.

static void showcaseModifiers(const Input& input, bool& explained)
+{
+    if (!explained)
+    {
+        CUBOS_WARN("Modifiers are supported. This showcase will print `Shift` when Shift+Space is pressed. "
+                   "Press Enter to advance to the next showcase.");
+        explained = true;
+    }
+
+    if (input.pressed("shift-space"))
+    {
+        CUBOS_INFO("Shift");
+    }
+}

Getting modified input (such as with a Control or a Shift hold) is no different from getting non-modified input, just make sure the binding for it is defined in the Bindings asset.

static void showcaseMultipleModifiers(const Input& input, bool& explained)
+{
+    if (!explained)
+    {
+        CUBOS_WARN("Multiple modifiers are supported. This showcase will print `Ctrl Shift` when Ctrl+Shift+Space is "
+                   "pressed. Press Enter to advance to the next showcase.");
+        explained = true;
+    }
+
+    if (input.pressed("ctrl-shift-space"))
+    {
+        CUBOS_INFO("Ctrl Shift");
+    }
+}

You can have more than one modifier.

static void showcaseAxis(const Input& input, bool& explained)
+{
+    if (!explained)
+    {
+        CUBOS_WARN("Axis are supported. This showcase will print the value of the `horizontal` and `vertical` axis "
+                   "when their values is different to 0. Use the arrows and WASD to move the axis. Press Enter to "
+                   "advance to the next showcase.");
+        explained = true;
+    }
+
+    if (input.axis("horizontal") != 0.0F || input.axis("vertical") != 0.0F)
+    {
+        CUBOS_INFO("horizontal: {}, vertical: {}", input.axis("horizontal"), input.axis("vertical"));
+    }
+}

Getting axis is very similar to actions, by calling Input::axis. The difference is that this funtion returns a float instead of a boolean value.

static void showcaseModifierAxis(const Input& input, bool& explained)
+{
+    if (!explained)
+    {
+        CUBOS_WARN("Modifiers are supported with axis. This showcase will print the value of the `shift-vertical` axis "
+                   "when its value is different to 0. Use Shift+arrows and Shift+WASD to move the axis. Press Enter to "
+                   "advance to the next showcase.");
+        explained = true;
+    }
+
+    if (input.axis("shift-vertical") != 0.0F)
+    {
+        CUBOS_INFO("shift-vertical: {}", input.axis("shift-vertical"));
+    }
+}

Modifier keys work with axis too.

static void showcaseUnbound(const Window& window, bool& explained)
+{
+    if (!explained)
+    {
+        CUBOS_WARN("Direct access is supported. This showcase will print `Unbound` when Ctrl+Shift+Y is pressed. Note "
+                   "that Ctrl+Shift+Y is not bound in sample.bind. Press Enter to advance to the next showcase.");
+        explained = true;
+    }
+
+    if (window->pressed(Input::Key::Y, Input::Modifiers::Shift | Input::Modifiers::Control))
+    {
+        CUBOS_INFO("Unbound");
+    }
+}

If, for any reason, you want to read an input that is not defined in the Bindings asset, you cannot use the Input plugin for it. Instead, you will have to call the Window::pressed function.

static void showcaseMouseButtons(const Input& input, bool& explained)
+{
+    if (!explained)
+    {
+        CUBOS_WARN("This showcase will print the name of a mouse button when it is pressed. Press Enter to advance to "
+                   "the next showcase.");
+        explained = true;
+    }
+
+    if (input.pressed("left-mb"))
+    {
+        CUBOS_INFO("Left");
+    }
+    if (input.pressed("right-mb"))
+    {
+        CUBOS_INFO("Right");
+    }
+    if (input.pressed("middle-mb"))
+    {
+        CUBOS_INFO("Middle");
+    }
+    if (input.pressed("extra-mb"))
+    {
+        CUBOS_INFO("Extra1 or Extra2");
+    }
+}

Reading mouse buttons is also supported, just bind them to an action, and then call Input::pressed as usual. To check which strings map to which buttons, you check the names of the variants of the enum MouseButton on this file.

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-engine-renderer.html b/docs-preview/pr-1032/examples-engine-renderer.html new file mode 100644 index 000000000..dc0487820 --- /dev/null +++ b/docs-preview/pr-1032/examples-engine-renderer.html @@ -0,0 +1,150 @@ + + + + + Examples » Engine » Renderer | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Engine » + Renderer +

+

Using the Renderer plugin.

+

This example shows how the Renderer plugin can be used and configured with a simple scene, lighting and split-screen rendering.

Image

The plugin function is included from the engine/renderer/plugin.hpp header. You may need to include other headers, depending on what you want to access.

In this sample we also use the split-screen plugin which automatically sets the viewport of each camera to achieve split-screen.

    cubos.addPlugin(splitscreenPlugin);
+    cubos.addPlugin(rendererPlugin);

The first thing we're going to worry about is setting the VoxelPalette the renderer will use. This palette would usually be loaded from a file, but for this example we'll just create it manually.

Since this system accesses the Renderer resource, which is only initialized on the tag cubos.renderer.init, we should specify that it must run after it.

    cubos.startupSystem("set the palette").after("cubos.renderer.init").call([](Renderer& renderer) {
+        // Create a simple palette with 3 materials (red, green and blue).
+        renderer->setPalette(VoxelPalette{{
+            {{1, 0, 0, 1}},
+            {{0, 1, 0, 1}},
+            {{0, 0, 1, 1}},
+        }});
+    });

We should also spawn a voxel grid, so we have something to render.

    cubos.startupSystem("create a voxel grid").call([](Commands commands, Assets& assets) {
+        // Create a 2x2x2 grid whose voxels alternate between the materials defined in the palette.
+        auto gridAsset = assets.create(VoxelGrid{{2, 2, 2}, {1, 2, 3, 1, 2, 3, 1, 2}});
+
+        // Spawn an entity with a renderable grid component and a identity transform.
+        commands.create().add(RenderableGrid{gridAsset, {-1.0F, 0.0F, -1.0F}}).add(LocalToWorld{});
+    });

If we don't add any lights, the scene will be completely dark. Lets add a simple PointLight.

    cubos.startupSystem("create a point light").call([](Commands commands) {
+        // Spawn a point light.
+        commands.create()
+            .add(PointLight{.color = {1.0F, 1.0F, 1.0F}, .intensity = 1.0F, .range = 10.0F})
+            .add(Position{{1.0F, 3.0F, -2.0F}});
+    });

We can also add some ambient lighting, and even add a sky gradient, through the RendererEnvironment resource.

    cubos.startupSystem("set the environment").call([](RendererEnvironment& env) {
+        env.ambient = {0.2F, 0.2F, 0.2F};
+        env.skyGradient[0] = {0.1F, 0.2F, 0.4F};
+        env.skyGradient[1] = {0.6F, 0.6F, 0.8F};
+    });

Lastly, without a camera, we won't be able to see anything. Cameras can be set using the ActiveCameras resource.

    cubos.startupSystem("create cameras").call([](Commands commands, ActiveCameras& camera) {
+        // Spawn the a camera entity for the first viewport.
+        camera.entities[0] = commands.create()
+                                 .add(Camera{.fovY = 60.0F, .zNear = 0.1F, .zFar = 100.0F})
+                                 .add(Position{{-3.0, 1.0F, -3.0F}})
+                                 .add(Rotation{glm::quatLookAt(glm::normalize(glm::vec3{1.0F, 0.0F, 1.0F}),
+                                                               glm::vec3{0.0F, 1.0F, 0.0F})})
+                                 .entity();
+
+        camera.entities[1] = commands.create()
+                                 .add(Camera{.fovY = 60.0F, .zNear = 0.1F, .zFar = 100.0F})
+                                 .add(Position{{-3.0, 1.0F, -3.0F}})
+                                 .add(Rotation{glm::quatLookAt(glm::normalize(glm::vec3{1.0F, 0.0F, 1.0F}),
+                                                               glm::vec3{0.0F, 1.0F, 0.0F})})
+                                 .entity();
+
+        camera.entities[2] = commands.create()
+                                 .add(Camera{.fovY = 60.0F, .zNear = 0.1F, .zFar = 100.0F})
+                                 .add(Position{{-3.0, 1.0F, -3.0F}})
+                                 .add(Rotation{glm::quatLookAt(glm::normalize(glm::vec3{1.0F, 0.0F, 1.0F}),
+                                                               glm::vec3{0.0F, 1.0F, 0.0F})})
+                                 .entity();
+    });
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-engine-scene.html b/docs-preview/pr-1032/examples-engine-scene.html new file mode 100644 index 000000000..a224493e1 --- /dev/null +++ b/docs-preview/pr-1032/examples-engine-scene.html @@ -0,0 +1,172 @@ + + + + + Examples » Engine » Scene | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Engine » + Scene +

+

Using the Scene plugin.

+

This example shows how the Scene plugin can be used to create scene assets and spawn them on the world.

The plugin function is included from the engine/scene/plugin.hpp header.

    cubos.addPlugin(scenePlugin);

Let's start by taking a look at a scene file.

{
+  "imports": {},
+  "entities": {
+    "root": {
+      "Num": 1
+    },
+    "child": {
+      "Num": 2,
+      "OwnedBy@root": {}
+    }
+  }
+}

Scene files are JSON files with the extension .cubos. They must have two fields: imports and entities. The entities field is an object where each field identifies and describes the components and relations of an entity. In this scene we have two entities, root and child. root has a single component, Num, with a value of 1. child too has a component Num, but also has a relation OwnedBy with root as target, indicated by the character @. In this sample, Num is used so we can later identify the entities.

Let's look at a different scene file now, this time with imports. Imports allows us to instantiate scenes within other scenes.

{
+  "entities": {
+    "main": {
+      "Num": 0
+    },
+    "notmain": {
+      "Num": 120,
+      "OwnedBy@main": {}
+    },
+    "sub1.root": {
+      "DistanceTo@sub2.root": 5,
+      "OwnedBy@main": {}
+    },
+    "sub2.root": {
+      "OwnedBy@main": {}
+    }
+  },
+  "imports": {
+    "sub1": "cd007ba2-ee0d-44fd-bf36-85c829dbe66f",
+    "sub2": "cd007ba2-ee0d-44fd-bf36-85c829dbe66f"
+  }
+}

This file imports the asset with id cd007ba2-ee0d-44fd-bf36-85c829dbe66f, which is the scene we looked at in the previous file, under the name sub1. It then imports the very same scene again, but this time with the name sub2 instead. This effectively instantiates the entities of the previous scene twice in this new scene, each with their names prefixed with either sub1. or sub2.

Also take a look at the DistanceTo relation: it is a symmetric relation, so it doesn't make a different whether wwe put it in sub.root or sub2.root. Since DistanceTo is a relation which holds data, instead of only specifying the target, as we do with OwnedBy, we write a JSON object with a key, "value".

Under entities, we can override the entities in the sub-scenes to edit components or add new ones. For example, by referencing sub1.root we are making local changes to the root entity of that instance of the subscene. The result of the changes we make to both sub1.root and sub2.root is that the owner of these entities will be set to be the main entity.

Now that we have our scene file, let's get our application to load it. The first thing we're going to need is a reference to the scene asset. For the purposes of this sample we can simply use an hardcoded reference to the asset.

static const Asset<Scene> SceneAsset = AnyAsset("f0d86ba8-5f34-440f-a180-d9d12c8e8b91");

Then we'll need a system that spawns that scene. To do this we simply get the Scene object from the asset, and then spawn its entities. Commands::spawn will create in the world a copy of every entity defined in the scene's blueprint. It won't remove the entities already there, so if you want to close a scene, you'll have to do it yourself.

    cubos.startupSystem("spawn the scene")
+        .tagged("spawn")
+        .tagged("cubos.assets")
+        .call([](Commands commands, const Assets& assets) {
+            auto sceneRead = assets.read(SceneAsset);
+            commands.spawn(sceneRead->blueprint);
+        });

In this case, we'll run this system at startup, since we want to spawn it a single time. Since it's a startup system, we'll have to tag it with cubos.assets to make sure it runs only after the scene bridge has been registered. On a real game, you could have, for example, a scene for an enemy which you spawn multiple times, instead of just once at startup.

    cubos.startupSystem("print the scene")
+        .after("spawn")
+        .call([](Query<Entity, const Num&> numQuery, Query<const OwnedBy&, Entity> ownedByQuery,
+                 Query<const DistanceTo&, Entity> distanceToQuery) {
+            using cubos::core::data::DebugSerializer;
+            using cubos::core::memory::Stream;
+
+            DebugSerializer ser{Stream::stdOut};
+
+            for (auto [entity, num] : numQuery)
+            {
+                Stream::stdOut.print("Entity ");
+                ser.write(entity);
+                Stream::stdOut.printf(":\n- Num = {}\n", num.value);
+
+                for (auto [distanceTo, what] : distanceToQuery.pin(0, entity))
+                {
+                    Stream::stdOut.print("- DistanceTo(");
+                    ser.write(what);
+                    Stream::stdOut.printf(") = {}\n", distanceTo.value);
+                }
+
+                for (auto [ownedBy, owner] : ownedByQuery.pin(0, entity))
+                {
+                    Stream::stdOut.print("- OwnedBy(");
+                    ser.write(owner);
+                    Stream::stdOut.print(")\n");
+                }
+            }
+        });

This sample also contains a system which prints the components and relations of the spawned entities. If you run it, it should give you a list that has:

  • an entity with Num set to 0, with no owner. This is the main entity.
  • two entities with Num set to 1, both owned by main. These are the root entities of each instance of the subscene.
  • two entities with Num set to 2, one owned by one of the root entities, another owned by the other root entity. These are the child entities of each instance of the subscene. Notice that both are related with a DistanceTo relation set to 5.
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-engine-settings.html b/docs-preview/pr-1032/examples-engine-settings.html new file mode 100644 index 000000000..3cef3ce3e --- /dev/null +++ b/docs-preview/pr-1032/examples-engine-settings.html @@ -0,0 +1,116 @@ + + + + + Examples » Engine » Settings | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Engine » + Settings +

+

Using the Settings plugin.

+

This example shows how the Settings plugin can be used to load settings from a file and command-line arguments.

int main(int argc, char** argv)
+{
+    Cubos cubos{argc, argv};
+
+    cubos.addPlugin(settingsPlugin);
+
+    cubos.startupSystem("print setting value").after("cubos.settings").call([](Settings& settings) {
+        CUBOS_INFO("{}", settings.getString("greeting", "Hello!"));
+    });
+
+    cubos.run();
+}

We add a system which prints the value of the setting greetings. Notice that we make it run after the tag cubos.settings, so that the settings have already been loaded.

If the setting greetings has been set on the settings.json file next to the sample's executable, or if it has been passed as a command-line argument (e.g. ./engine-sample.settings --greetings "Hello, world!"), the sample will output that value. Otherwise, it will output Hello!, which we set as a default.

Notice that if we want the command-line arguments to be loaded as settings, we need to pass argc and argv to the Cubos::Cubos(int, char**) constructor.

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-engine-voxels.html b/docs-preview/pr-1032/examples-engine-voxels.html new file mode 100644 index 000000000..27978a2d3 --- /dev/null +++ b/docs-preview/pr-1032/examples-engine-voxels.html @@ -0,0 +1,119 @@ + + + + + Examples » Engine » Voxels | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Engine » + Voxels +

+

Using the Voxels plugin.

+

This example shows the Voxels plugin, which registers asset bridges used to load voxel grids (.grid) and palettes (.pal). Check out the Introduction and Custom Bridges sample for an introduction on the Assets plugin.

It is very similar to the Renderer, differing only in the fact that in this sample the grid and palette are loaded from files.

Image

The plugin function is included from the engine/voxels/plugin.hpp header. To see the asset, you'll also need to perform a basic configuration of the Renderer plugin like shown in the Renderer sample.

    cubos.addPlugin(voxelsPlugin);

Lets start by defining the handles of the assets we want to use, as done in the Assets sample.

static const Asset<VoxelGrid> CarAsset = AnyAsset("059c16e7-a439-44c7-9bdc-6e069dba0c75");
+static const Asset<VoxelPalette> PaletteAsset = AnyAsset("1aa5e234-28cb-4386-99b4-39386b0fc215");

In this sample, instead of creating a new palette, we just read the data from the asset identified from the PaletteAsset handle we defined previously. Internally, the assets manager will automatically load the palette asset if it hasn't been loaded before.

    cubos.startupSystem("load and set pallete")
+        .after("cubos.renderer.init")
+        .call([](const Assets& assets, Renderer& renderer) {
+            // Read the palette's data and pass it to the renderer.
+            auto palette = assets.read(PaletteAsset);
+            renderer->setPalette(*palette);
+        });

Now, we can create an entity with our car asset.

    cubos.startupSystem("create a car").tagged("cubos.assets").call([](Commands cmds, const Assets& assets) {
+        // Calculate the necessary offset to center the model on (0, 0, 0).
+        auto car = assets.read(CarAsset);
+        glm::vec3 offset = glm::vec3(car->size().x, 0.0F, car->size().z) / -2.0F;
+
+        // Create the car entity
+        cmds.create().add(RenderableGrid{CarAsset, offset}).add(LocalToWorld{});
+    });

And voilá, you now have a car floating in space.

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples-engine.html b/docs-preview/pr-1032/examples-engine.html new file mode 100644 index 000000000..f6bca8a07 --- /dev/null +++ b/docs-preview/pr-1032/examples-engine.html @@ -0,0 +1,104 @@ + + + + + Examples » Engine | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples » + Engine +

+

Showcases features of the Engine library.

+

The following examples have fully documented tutorials on how to use the multiple plugins of the engine:

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/examples.html b/docs-preview/pr-1032/examples.html new file mode 100644 index 000000000..9aaff9fb9 --- /dev/null +++ b/docs-preview/pr-1032/examples.html @@ -0,0 +1,103 @@ + + + + + Examples | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Examples +

+

Contains examples of specific features of the libraries.

+

If you are just starting out, you should probably start by the engine examples. These cover the actual user-facing features, and are a good place to get a feel for how using the engine looks like, while the core examples are more directed at engine developers trying to understand how specific low-level features are used.

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/favicon-dark.png b/docs-preview/pr-1032/favicon-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..c2498580c1aeb9dc13d311f1785319025ec8e299 GIT binary patch literal 380 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf4nJ z@ErkR#;MwT(m+AU64!{5;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq=1Tkdb&7< zSoGeV?5NFBC~>S_`|=i}-=YT7Padn`>b# z#-|U~KTAvL@1NW}Hzhmx)17mMt7=aCeXE+Tu9&=7S?5gnj;`}NclWK#&8=bGIZyxk=h6Uv70<|T%c?G1a5bK$ zvUi4y=d7&sa{sr>(>;Sq3ti{$JNRyL*!63ieM)Uzu6a?uGU+o`&g43#a^|ex=GfaQ zMT>lHbTFJ?l#{#7u&3NA<)*ff#AJqqNg@qFCx8CzWC;2`r~i!nImh){e;(_7S;cQs XpYeAO6X!QzATW5k`njxgN@xNAhZ>zq literal 0 HcmV?d00001 diff --git a/docs-preview/pr-1032/features-ecs.html b/docs-preview/pr-1032/features-ecs.html new file mode 100644 index 000000000..4f40176fb --- /dev/null +++ b/docs-preview/pr-1032/features-ecs.html @@ -0,0 +1,184 @@ + + + + + Feature Guide » ECS | CUBOS. Docs + + + + + + + + +
+
+
+
+
+

+ Feature Guide » + ECS +

+

What is an ECS and how it's used in CUBOS.

+

Wikipedia defines ECS as:

Entity Component System (ECS) is a software architectural pattern mostly used in video game development for the representation of game world objects. An ECS comprises entities composed from components of data, with systems which operate on entities' components.

ECS follows the principle of composition over inheritance, meaning that every entity is defined not by a type hierarchy, but by the components that are associated with it. Systems act globally over all entities which have the required components.

The ECS thus is a vital part of the engine, since all of the rest is structured around it in some way. This sets the engine apart from other engines which follow a more traditional model, like Unity, Unreal and Godot.

A primer on ECS

Why are we using this?

ECS is a powerful pattern which has been becoming more popular over the years, and even Unity has started integrating it into its engine. The main advantages are flexibility and performance: it avoids a lot of the problems that come with traditional object-oriented programming, and regarding performance, it excels in situations where the number of entities is high, since it makes use of cache locality. Its also easier to parallelize the systems, since they have clearly defined dependencies.

Our implementation

CUBOS. ECS contains the following concepts:

  • Cubos - used to configure and run an ECS world and systems.
  • World - the main object that holds all of the ECS state.
  • Entities - represent objects in the game world (e.g. a car, a player, a tree).
  • Components - data associated with an entity (e.g. Position, Rotation).
  • Relations - data associated to a pair of entities (e.g., ChildOf, CollidingWith)
  • Resources - singleton-like objects which are stored per world and which do not belong to a specific entity (e.g. DeltaTime, Input).
  • Systems - functions which operate on resources and entities' components. This is where the logic is implemented.

One important thing to note is that in an ECS the data is completely decoupled from the logic. What this means is that entities and components do not and should not possess any functionality other than storing data. All of the logic is relegated to the systems.

How do we use it?

Lets say we want to have multiple objects with positions and velocities, and every frame we want to add their velocities to their positions.

In a traditional object-oriented approach, we would have something along the lines of:

class MyObject : public GameObject
+{
+public:
+    // ...
+
+    virtual void update(float deltaTime) override
+    {
+        this->position += this->velocity * deltaTime;
+    }
+
+private:
+    glm::vec3 position;
+    glm::vec3 velocity;
+}

In CUBOS. there are no game objects. Instead, we would define two components and a DeltaTime resource:

struct Position
+{
+    CUBOS_REFLECT;
+
+    glm::vec3 vec = { 0.0f, 0.0f, 0.0f };
+};
+
+struct Velocity
+{
+    CUBOS_REFLECT;
+
+    glm::vec3 vec = { 0.0f, 0.0f, 0.0f };
+};
+
+struct DeltaTime
+{
+    float value = 0.0f;
+};

So, where does the update logic belong? We put it in a system. Systems are functions whose arguments are of certain types, which you can read more about in the ECS module page.

To access a resource, simply add a reference to it as an argument. In this case, we won't be modifying the delta time, so we will use const DeltaTime&. To access entities and their components, we use the Query argument. In this case we we want to access all entities with both positions and velocities, and modify their positions, so we will use Query<Position&, const Velocity&>.

cubos.system("integrate velocity")
+     .call([](const DeltaTime& dt, Query<Position&, const Velocity&> query) 
+     {
+         for (auto [position, velocity] : query)
+         {
+             position->vec += velocity->vec * dt->value;
+         }
+     });

We can then iterate over all queried entities and update their positions using their velocities and the delta time.

Going further

Registering types

Before components, relations and resources are used in a World, they must be registered on it. This should be done once, at the start of the program. For example, using the CUBOS. main class, for the previous example we would write:

cubos.addComponent<Position>();
+cubos.addRelation<ChildOf>();
+cubos.addResource<DeltaTime>();

Commands

When you have direct access to the World, you can manipulate entities directly:

auto entity = world.create();
+world.components(entity).add<Position>();
+world.components(entity).remove<Position>();
+world.components(entity).add<Dead>();
+world.destroy(entity);

If necessary, you can access the world in a system through the arguments const World& or World&. However, this is not recommended, since it becomes impossible to know what the system is accessing, and thus we cannot parallelize it.

Instead, you should use the Commands argument. Through it you can queue operations to be executed at a later time, when its safe to do so.

Imagine we want to have spawners which create new entities on their position and then destroy themselves. We can implement this with a system like this:

cubos.system("spawn entities")
+     .call([](Commands commands, Query<Entity, const Spawner&, const Position&> spawners)
+     {
+         for (auto [entity, spawner, position] : spawners)
+         {
+             commands.create()
+                     .add(position)
+                     .add(Velocity{{0.0F, 0.0F, 1.0F}});
+             commands.destroy(entity);
+         }
+     });

This system iterates over all entities with Spawner and Position components. It creates new entities on their positions with a velocity of (0, 0, 1), and then destroys the spawner entity. The entities are only actually created and destroyed later on, when the commands are executed.

Relations

Relations are just like components, but they're much more powerful. Instead of being associated to a single entity, they're associated to two entities: the 'from' entity and the 'to' entity. There are three types of relations:

  • Default - relations which have a orientation (e.g. from and to have distinct meanings), and which have no restriction on the number.
  • Tree - relations which too have orientation, but with the extra restriction that an entity can only appear in the 'from' side of at least one instance of the relation type. One example is the ChildOf relation.
  • Symmetric - relations whose orientation doesn't matter. One example is the CollidingWith relation.

They can be created using either Commands::relate() or the World::relate() methods. They can also be destroyed using Commands::unrelate() or World::unrelate().

Relations can also be queried in systems - read the multiple-target section on the Queries guide for more information on that.

Blueprints

A common pattern in game engines is to have a way to create entities in bundles, such as Unity's prefabs. In CUBOS. we call these blueprints. A blueprint is a set of entities and their components, which can be spawned into the world as many times as needed.

For example, if we wanted to create a blueprint for a motorbike with two wheels:

auto motorbike = ecs::Blueprint();
+
+auto body = motorbike.create("body");
+motorbike.add(body, Position{...});
+
+auto frontWheel = motorbike.create("front_wheel");
+motorbike.add(frontWheel, Position{...});
+motorbike.relate(frontWheel, body, ChildOf{});
+
+auto backWheel = motorbike.create("back_wheel");
+motorbike.add(backWheel, Position{...});
+motorbike.relate(backWheel, body, ChildOf{});

To spawn the blueprint into the world:

// You can just spawn the bike as is.
+commands.spawn(motorbike);
+
+// Lets say we want to spawn the bike in a different position.
+// You can override components of the spawned entities.
+commands
+    .spawn(motorbike)
+    .add("body", Position{...});

Merging blueprints

It's possible to merge a blueprint into another one. Lets say we have a blueprint for the wheels of the motorbike:

auto wheel = ecs::Blueprint();
+wheel.create("wheel");

When creating the motorbike blueprint, we can merge the wheel blueprint into it:

auto motorbike = ecs::Blueprint();
+auto body = motorbike.create("body", Position{...});
+motorbike.merge("front", wheel);
+motorbike.merge("back", wheel);

When spawning the motorbike blueprint, the entities of the wheel blueprint will be accessible with the prefix we gave them:

commands
+    .spawn(motorbike)
+    .add("front.wheel", ...)
+    .add("back.wheel", ...);
+ +
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/features-plugins.html b/docs-preview/pr-1032/features-plugins.html new file mode 100644 index 000000000..5cb8096e7 --- /dev/null +++ b/docs-preview/pr-1032/features-plugins.html @@ -0,0 +1,138 @@ + + + + + Feature Guide » Plugins | CUBOS. Docs + + + + + + + + + +
+
+
+
+
+

+ Feature Guide » + Plugins +

+

What are plugins and how they can be used to organize your code.

+

Configuring the engine

Plugins are a feature of the cubos::core::ecs::Cubos class. This class is the main thing you'll be interacting with when developing a game with CUBOS.. It is used to configure the engine and run the game loop. Through it, you can register new components, resources and configure systems to be run on specific conditions.

An application which just prints "Hello World!" and which does absolutely nothing else - not even open a window - would look like this:

#include <cubos/engine/prelude.hpp>
+
+#include <iostream>
+
+using cubos::engine::Cubos;
+
+int main()
+{
+    Cubos cubos;
+    cubos.startupSystem([]() {
+        std::cout << "Hello World!" << std::endl;
+    });
+    cubos.run();
+}

What are plugins?

If you had to add every system, component and resource to your game's main source file, it would quickly become a mess. Plugins are just functions which receive a reference to the Cubos class. Nothing more.

The idiomatic way to use plugins is through the Cubos::addPlugin method. It receives a plugin function, and executes it only if it hasn't been executed before. This property is useful for solving dependency issues between plugins. For example, if B and C adds A and D adds B and C, you would be adding A twice.

If we were to put the hello world functionality on a plugin, the previous example would look like this:

#include <cubos/engine/prelude.hpp>
+
+#include <iostream>
+
+using cubos::engine::Cubos;
+
+void helloWorldPlugin(Cubos& cubos)
+{
+    cubos.startupSystem([]() {
+        std::cout << "Hello World!" << std::endl;
+    });
+}
+
+int main()
+{
+    Cubos cubos;
+    cubos.addPlugin(helloWorldPlugin);
+    cubos.run();
+}

What plugins are there?

The engine is basically a big bundle of plugins which add all of kinds of functionality. You can find an exhaustive list of the plugins provided by the engine and their documentation on the engine module page. Check out the engine examples to see how they are used in practice.

+ +
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/features-quadrados.html b/docs-preview/pr-1032/features-quadrados.html new file mode 100644 index 000000000..d39d869fa --- /dev/null +++ b/docs-preview/pr-1032/features-quadrados.html @@ -0,0 +1,123 @@ + + + + + Feature Guide » Quadrados | CUBOS. Docs + + + + + + + + +
+
+
+
+
+

+ Feature Guide » + Quadrados +

+

How to use the Quadrados CLI tool.

+

Quadrados is the CLI tool used to work with CUBOS. At the moment, it contains the following commands:

  • quadrados help - shows the help message;
  • quadrados convert - converts a .qb voxel file into the internal format used by CUBOS., .grd and .pal.
  • quadrados embed - utility used to embed files directly into an executable for use with the EmbeddedArchive.

Convert

The need for this tool arose from the fact that CUBOS. works with a single palette of voxel materials, and voxel objects refer to specific materials by their index in this palette. For example, if we had a single voxel red object, the red color wouldn't be specified in the voxel object. Instead, this object would specify that its material is 1, and the palette would specify that the material 1 is red.

The issue is, voxel formats like .qb and .vox are not designed to store only the indices of materials, but the whole material definition, per voxel. This conflicts with the way CUBOS. works, so we need to convert these formats into the internal format used by CUBOS.. This is where quadrados convert comes in. It takes a .qb voxel file and splits it into a palette (.pal), and one or more voxel grids (.grd).

Usage

This guide will be based on four use cases:

  1. loading a .qb file and creating a new .pal;
  2. loading a .qb file and updating an existing .pal;
  3. loading a .qb file and using, without editing, an existing .pal;
  4. querying the contents of .qb model;

Example 1: Creating a new palette

This use case is most common when importing the first .qb file for a new project. There is no palette file yet, so we need to create one. Lets say the model we want to convert is a car.qb, which contains a single voxel object.

$ quadrados convert car.qb -p main.pal -g car.grd -w

First, we specify the .qb file to convert. Then, we specify the name of the palette we will be outputting. We also need to specify the output file for the voxel grid. Finally, we pass the -w flag which allows us to write to the palette file (which is necessary since there is none at the moment).

Example 2: Updating an existing palette

Lets say we now want to import a street.qb model which contains two voxel grids: the first one is a road and the second one is a tree. Since we already have a palette, we want to add any new materials to it.

$ quadrados convert street.qb -p main.pal -g0 road.grd -g1 tree.grd -w

Once again, we first specify the .qb file to convert. Then, we specify the name of the palette we will be using, which is the same as the one we created in the previous example. This time, we have two grids in the .qb file, so we need to specify the output files for both. This is done by adding an index in front of -g (e.g. -g0 for the first grid, -g1 for the second). Finally, we once again pass the -w flag which allows the palette file to be updated.

Example 3: Using an existing palette

What if we want to add another car model, but without adding materials to the palette? To do this, we will need to ommit the -w flag. This way, the palette will be read, and the most similar materials found will be used. By default, this will only succeed if the materials match exactly.

$ quadrados convert car2.qb -p main.pal -g car2.grd

If this fails, you may see the error message:

Failed to convert grid 0 from its palette to the palette chosen.

One work around is lowering the threshold for material matching. If you want to allow for slightly different materials to be considered as the same, you can pass the -s <SIMILARITY> option. This value is a number from 0 to 1, where 0 is completely different and 1 is completely the same. It represents the minimum similarity between two materials to consider them the same (default is 1).

So, if the materials which aren't matching are very similar, you could add, for example, -s 0.9 to the previous command. This way, the material chosen from the palette will have a similarity of at least 0.9 with the material in the original model.

Example 4: Querying the contents of a model

You may want to check the contents of a .qb file before converting it. One easy way to do this is to use the -v (verbose) flag. This can be added to any of the previous commands to get extra information about what is going on.

It can also be used without any other options, in which case the program will just print the contents of the .qb file. For example:

$ quadrados convert car.qb -v
+Found 1 QB matrices.
+Matrix 0:
+- Position: -7 -5 -16
+- Grid size: 15x11x32
+- Palette size: 10

This tells us that the car.qb model contains exactly one voxel grid, that its position within the model is (-7, -5, -16), that its size is 15x11x32, and that it uses 10 different materials.

Embed

The quadrados embed tool is used to embed files directly into an executable for use with the cubos::core::data::EmbeddedArchive. This is useful for example when you want to ship a game with a set of assets, but don't want to have to distribute them as separate files. This way, you are able to ship a single executable file.

Usage

This tool takes a file and generates a C++ source file which registers data to be used with cubos::core::data::EmbeddedArchive, outputting the code to the standard output. This source file can then be compiled and linked with your executable.

If no name is specified, the name of the file will be used. For example, if you run quadrados embed logo.png > logo.cpp, the name of the registered data will be logo.png.

The data can then be mounted like this:

#include <cubos/core/data/fs/file_system.hpp>
+#include <cubos/core/data/fs/embedded_archive.hpp>
+
+int main()
+{
+    using namespace cubos::core::data;
+
+    FileSystem::mount("/logo.png", std::make_shared<EmbeddedArchive>("logo.png"));
+
+    // ...
+
+    return 0;
+}

It's also possible to embed a whole directory, in which case you will need to use the -r flag. This will recursively embed all files in the directory.

Checkout the embedded_archive sample for a complete example.

+ +
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/features-queries.html b/docs-preview/pr-1032/features-queries.html new file mode 100644 index 000000000..dcd43cc50 --- /dev/null +++ b/docs-preview/pr-1032/features-queries.html @@ -0,0 +1,194 @@ + + + + + Feature Guide » Queries | CUBOS. Docs + + + + + + + + + +
+
+
+
+
+

+ Feature Guide » + Queries +

+

In-depth guide on writing queries.

+

Single-target queries

Let's say you want to implement behavior for regenerating the health of all players of a certain class. One possible way to design this would be to have a component Health, and another for the class, e.g., Mage. Then you could add a system similar to the one below:

cubos.system("heal mages").call([](Query<Health&, const Mage&> query) {
+    for (auto [health, mage] : query)
+    {
+        health.points += 1;
+    }
+});

Notice that we don't actually access the mage component at all. We just want it to be present on the entities given by the query. A better way to write this would be to add an explicit query term:

cubos.system("heal mages")
+     .with<Mage>() // <--- EXPLICIT TERM
+     .call([](Query<Health&> query) {
+         for (auto [health] : query)
+         {
+             health.points += 1;
+         }
+     });

Notice that we could also add .with<Health>() above, but that would be redundant.

Explicit query terms bring a lot of possibilities: they can also be used to specify, for example, that entities should not have a component. With this, we can easily prevent healing mages which are already dead:

cubos.system("heal alive mages")
+     .with<Mage>()
+     .without<Dead>()
+     .call([](Query<Health&> query) {
+        // ...
+     });

But how do we mark entities as Dead? We add the Dead component to entities with Commands::add(), but how do we get the entity handles of the entities with health set to zero? Just adding Entity as a query argument type is enough!

cubos.system("add dead to entities with zero health")
+     .without<Dead>() // no use killing it twice!
+     .call([](Commands cmds, Query<Entity, const Health&> query)
+     {
+        for (auto [entity, health] : query)
+        {
+            if (health.points <= 0)
+            {
+                cmds.add(entity, Dead{});
+            }
+        }
+     });

Multiple-target queries

Until now we've only seen queries matching against single entities, but what if we want to access relations? Relations no longer belong to a single entity - and this is where the query system really starts to shine.

Lets add arrows to our fictional RPG. Arrow entities are identified by, you guessed it, an Arrow component. When an arrow hits an entity with health, we want to destroy the arrow and reduce the health. To check if two entities are colliding, we'll use the CollidingWith relation.

cubos.system("arrow damages entity")
+     .call([](Commands cmds, Query<Entity, const Arrow&, const CollidingWith&, Health&> query) {
+        for (auto [arrowEntity, arrow, collidingWith, health] : query)
+        {
+            health.points -= 10;
+            cmds.destroy(arrowEntity),
+        }
+     });

Notice that once again we're not accessing some of the data: the Arrow and CollidingWith components. We can rewrite the query above as:

cubos.system("arrow damages entity")
+     .entity()
+     .with<Arrow>()
+     .related<CollidingWith>()
+     .with<Health>()
+     .call([](Commands cmds, Query<Entity, Health&> query) {
+        for (auto [arrowEntity, health] : query)
+        {
+            health.points -= 10;
+            cmds.destroy(arrowEntity),
+        }
+     });

Notice that this time we include .entity and .with<Health> on the explicit terms to remove the ambiguity that could arise otherwise. Terms before .related are assigned to the target 0, the relation is assigned to 0, 1 and the terms after it to 1. We could also set those targets manually, if we wanted to, by simply passing them as arguments to the terms (e.g. .with<Health>(1)).

Tree Traversal

Tree relations form hierarchies, and the query system provides a way to traverse them in specific BFS order, if necessary. For example, if you want to traverse the ChildOf tree from top to bottom, you could:

cubos.system("print all ChildOf relations ordered")
+     .entity()
+     .related<ChildOf>(Traversal::Up)
+     .entity()
+     .call([](Query<Entity, Entity> query) {
+        for (auto [child, parent] : query)
+        {
+            CUBOS_INFO("{} is a child of {}", child, parent);
+        }
+     });

The above system would first print all ChildOf relations originating from entities which don't have children, then their parents, and so on until reaching the root entities of the hierarchy. To traverse in the opposite direction you can also use Traversal::Down.

Pinning

Alright, its cool that we can query over all entities, but what if we just want to do something with the children of specific entity? You can just pin the parent target to a specific entity!

Notice that the first target of a relation is identified by 0, the second by 1, and so on.

cubos.system("print all children of some specific entity")
+     .entity()
+     .related<ChildOf>()
+     .call([](Query<Entity> query, const SomeResource& resource) {
+        // Forces all matches of the query to have target 1 = resource.entity
+        for (auto [child] : query.pin(1, resource.entity))
+        {
+            CUBOS_INFO("{} is a child of {}", child, entity.entity);
+        }
+     });

To find the parent of an entity, you could also just go the other way around:

cubos.system("print the parent of some specific entity")
+     .related<ChildOf>()
+     .entity()
+     .call([](Query<Entity> query, const SomeResource& resource) {
+        if (auto match = query.pin(0, resource.entity).first())
+        {
+            auto [parent] = *match;
+            CUBOS_INFO("{} is the parent of {}", resource.entity);
+        }
+     });

Direct access

If you pin all targets of a query, you get either zero or one matches. This can be used to access the components of specific entities, or the relation between two specific entities for example.

For example, to access the health of a specific entity, you could:

cubos.system("access the health of a specific entity")
+     .call([](Query<const Health&> query, const SomeResource& resource) {
+        if (auto match = query.pin(0, resource.entity).first())
+        {
+            auto [health] = *match;
+            // Do something with the health component
+        }
+     });

If you wanted to check if two specific entities are colliding, you could:

cubos.system("test collisions between specific entities")
+     .related<CollidingWith>()
+     .call([](Query<> query, const SomeResource& resource) {
+        if (query.pin(0, resource.first).pin(1, resource.second).first())
+        {
+            // They're colliding!
+        }
+     });

Both of the examples can be shortened using the Query::at() method. With a single target query, instead of query.pin(0, entity).first(), you can write query.at(entity). With two targets, instead of query.pin(0, entityA).pin(1, entityB).first(), you can write query.at(entityA, entityB).

+ +
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/features.html b/docs-preview/pr-1032/features.html new file mode 100644 index 000000000..334bdae32 --- /dev/null +++ b/docs-preview/pr-1032/features.html @@ -0,0 +1,102 @@ + + + + + Feature Guide | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Feature Guide +

+

This is a brief introduction to the CUBOS. engine and its features. Before diving into the documentation of each class and function, it's recommended to read through this guide.

Overview

The CUBOS. engine is divided into two libraries: Core and Engine. Each library has its own namespace, which corresponds to a sub-folder in the include path.

Core provides platform abstraction, containers, utilities, and the ECS module. Engine builds on top of Core and provides higher-level features such as rendering and collisions.

The core library is divided into modules, each of which covers a specific area of functionality. For example, graphics-related functionality is on the cubos::core::gl namespace, under the include path cubos/core/gl.

The engine library is divided into plugins, each of which extends the engine's functionality in some way. You'll learn more about plugins below. For each plugin, there is a corresponding directory in the include path. Categories of plugins are also divided into sub-folders, with their own namespaces.

Tooling

Other than the core and engine libraries, the project also contains Quadrados and Tesseratos. Quadrados is a CLI tool which contains utilities used during game development. Tesseratos is our in-house editor, which is still in its early stages of development.

Learn more

The following guides explain basic concepts of the engine. Its recommend to read through these first to understand the overall principles and only then dive into the documentation of each class and function.

  • ECS - What is an ECS and how it's used in CUBOS.
  • Plugins - What are plugins and how they can be used to organize your code.
  • Queries - In-depth guide on writing queries.
  • Quadrados - How to use the Quadrados CLI tool.

What we don't have and where are we going

The engine is still in its early stages of development, and thus we're missing a lot of features. For example, we don't have physics yet, and the editor tools are very barebones - you can't even load a scene from a file yet. There's no scripting language, thus you will have to write all your game logic in C++.

Making a game with the engine is still very painful. Our goal is to make CUBOS. usable for game jams by people who are not on the team. This means a lot of work, but we're confident we can get there.

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/fields_8hpp.html b/docs-preview/pr-1032/fields_8hpp.html new file mode 100644 index 000000000..3befe32db --- /dev/null +++ b/docs-preview/pr-1032/fields_8hpp.html @@ -0,0 +1,147 @@ + + + + + core/reflection/traits/fields.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/reflection/traits/fields.hpp file +

+

Class cubos::core::reflection::FieldsTrait.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::reflection
+
Reflection module.
+
+
+
+

Classes

+
+
+ class cubos::core::reflection::FieldsTrait +
+
Describes the fields of a reflected type.
+
+
template<typename O, typename F>
+ class cubos::core::reflection::FieldsTrait::AddressOfImpl +
+
Implementation of AddressOf for a pointer to member.
+
+ struct cubos::core::reflection::FieldsTrait::View::Iterator::Output +
+
Output structure for the iterator.
+
+ struct cubos::core::reflection::FieldsTrait::ConstView::Iterator::Output +
+
Output structure for the iterator.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/file__stream_8hpp.html b/docs-preview/pr-1032/file__stream_8hpp.html new file mode 100644 index 000000000..b94236a6d --- /dev/null +++ b/docs-preview/pr-1032/file__stream_8hpp.html @@ -0,0 +1,135 @@ + + + + + core/data/fs/file_stream.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/data/fs/file_stream.hpp file +

+

Class cubos::core::data::FileStream.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::data
+
Data module.
+
+
+
+

Classes

+
+
+
template<typename T>
+ class cubos::core::data::FileStream +
+
Wrapper around an implementation-specific file stream which keeps the file alive and does some sanity checks.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/file__system_8hpp.html b/docs-preview/pr-1032/file__system_8hpp.html new file mode 100644 index 000000000..a58c961ed --- /dev/null +++ b/docs-preview/pr-1032/file__system_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/data/fs/file_system.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/files.html b/docs-preview/pr-1032/files.html new file mode 100644 index 000000000..abe3e7983 --- /dev/null +++ b/docs-preview/pr-1032/files.html @@ -0,0 +1,568 @@ + + + + + CUBOS. Docs + + + + + + + +
+
+
+
+
+

Files

+ + +
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/filter_8hpp.html b/docs-preview/pr-1032/filter_8hpp.html new file mode 100644 index 000000000..dacc28925 --- /dev/null +++ b/docs-preview/pr-1032/filter_8hpp.html @@ -0,0 +1,138 @@ + + + + + core/ecs/query/filter.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/ecs/query/filter.hpp file +

+

Class cubos::core::ecs::QueryFilter.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::ecs
+
ECS module.
+
+
+
+

Classes

+
+
+ class cubos::core::ecs::QueryFilter +
+
Used to find matches for the given query terms. Essentially contains the non-templated part of the query logic.
+
+ struct cubos::core::ecs::QueryFilter::View::Iterator::Match +
+
Output structure of the iterator.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/fixed__delta__time_8hpp.html b/docs-preview/pr-1032/fixed__delta__time_8hpp.html new file mode 100644 index 000000000..fa5264526 --- /dev/null +++ b/docs-preview/pr-1032/fixed__delta__time_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/fixed_step/fixed_delta_time.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/force_8hpp.html b/docs-preview/pr-1032/force_8hpp.html new file mode 100644 index 000000000..7c7d0d9c2 --- /dev/null +++ b/docs-preview/pr-1032/force_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/physics/components/force.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/frame_8hpp.html b/docs-preview/pr-1032/frame_8hpp.html new file mode 100644 index 000000000..f9479e488 --- /dev/null +++ b/docs-preview/pr-1032/frame_8hpp.html @@ -0,0 +1,136 @@ + + + + + engine/renderer/frame.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/function_8hpp.html b/docs-preview/pr-1032/function_8hpp.html new file mode 100644 index 000000000..c793f2fcd --- /dev/null +++ b/docs-preview/pr-1032/function_8hpp.html @@ -0,0 +1,135 @@ + + + + + core/memory/function.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/gamepad_8hpp.html b/docs-preview/pr-1032/gamepad_8hpp.html new file mode 100644 index 000000000..1a7abf222 --- /dev/null +++ b/docs-preview/pr-1032/gamepad_8hpp.html @@ -0,0 +1,193 @@ + + + + + core/io/gamepad.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/io/gamepad.hpp file +

+

Struct cubos::core::io::GamepadState and related enums.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::io
+
Input and output module.
+
+
+
+

Classes

+
+
+ struct cubos::core::io::GamepadState +
+
Holds the state of a gamepad.
+
+
+
+

Enums

+
+
+ enum class GamepadButton { Invalid = -1, + A, + B, + X, + Y, + LBumper, + RBumper, + Back, + Start, + Guide, + LThumb, + RThumb, + Up, + Right, + Down, + Left, + Count } +
+
Gamepad buttons.
+
+ enum class GamepadAxis { Invalid = -1, + LX, + LY, + RX, + RY, + LTrigger, + RTrigger, + Count } +
+
Gamepad axes.
+
+
+
+

Functions

+
+
+ auto gamepadButtonToString(GamepadButton button) -> std::string +
+
Converts a GamepadButton enum to a string.
+
+ auto stringToGamepadButton(const std::string& str) -> GamepadButton +
+
Converts a string to a GamepadButton.
+
+ auto gamepadAxisToString(GamepadAxis axis) -> std::string +
+
Convert a GamepadAxis to a string.
+
+ auto stringToGamepadAxis(const std::string& str) -> GamepadAxis +
+
Convert a string to a GamepadAxis.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/getting-started.html b/docs-preview/pr-1032/getting-started.html new file mode 100644 index 000000000..8a522d781 --- /dev/null +++ b/docs-preview/pr-1032/getting-started.html @@ -0,0 +1,103 @@ + + + + + Getting started | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Getting started +

+

How to download, build and run the engine and where to go from there.

+

Building the engine from source

Getting the code

The CUBOS. source code is hosted on GitHub, so the easiest and only way to get the code right now is to clone the repository with git.

Dependencies

The following dependencies are used to compile CUBOS.:

NameImportanceSubmodule PathInstalled SeparatelyVersion*
CMakeEssential-Yes-
gladEssentialcore/lib/gladNo2.0.4
glfwEssentialcore/lib/glfwOptionally3.3.8
glmEssentialcore/lib/glmOptionally0.9.9.8
stduuidEssentialcore/lib/stduuidNo1.2.3
doctestRequired for testscore/lib/doctestOptionally2.4.11
imguiRequired for imgui pluginengine/lib/imguiNo1.89.9
jsonEssentialcore/lib/jsonNo3.11.2

*versions tested in CI and installed by submodules, others might work

Dependencies marked as Essential are required to compile the engine. If they are installed separately, you must first install them manually. If they're not, it means they come as submodules and you can install them with the engine by cloning the whole repository with the --recursive flag. If you've already cloned the repository, you can install them by running the following command from the root directory of the repository:

git submodule update --init --recursive

Formatting

To contribute you must ensure your code is correctly formatted. Install clang-format and run the following command to enable a pre-commit hook which formats your changes automatically:

git config --local include.path ../.gitconfig

Compiling

If you chose to install some dependencies separately, you must pass the corresponding -D flag to CMake. For example, if you installed GLFW, GLM and CMake separately you would pass the following flags to CMake:

cmake -H. -Bbuild -DGLFW_USE_SUBMODULE=OFF -DGLM_USE_SUBMODULE=OFF

If you are using submodules, you can simply run the following command from the root directory of the repository:

cmake -H. -Bbuild

The following is a list of all the options available to configure the engine:

NameDescription
WITH_GLFWUse GLFW? (Required for now)
WITH_OPENGLUse OpenGL? (Required for now)
GLFW_USE_SUBMODULECompile glfw from source?
GLM_USE_SUBMODULECompile glm from source?
DOCTEST_USE_SUBMODULECompile doctest from source?
BUILD_CORE_SAMPLESBuild CUBOS. core samples?
BUILD_CORE_TESTSBuild CUBOS. core tests?
BUILD_ENGINE_SAMPLESBuild CUBOS. engine samples?
BUILD_ENGINE_TESTSBuild CUBOS. engine tests?
BUILD_DOCUMENTATIONBuild the documentation?
ENABLE_COVERAGEEnable code coverage? (GCC only)
FIX_CLANG_TIDY_ERRORSFix clang-tidy errors automatically?

Running the examples and tests

Examples

Both the core and the engine contain examples which you can run to check if things are running correctly. To build them, you must enable the BUILD_CORE_SAMPLES and/or BUILD_ENGINE_SAMPLES options.

Testing

CUBOS. uses doctest for unit testing the engine. To build them, you must enable the BUILD_CORE_TESTS and/or BUILD_ENGINE_TESTS options.

Whats next?

We recommend you start by reading the feature guide, which introduces you to important concepts and features of the engine, such as what is an ECS and how it is used in CUBOS..

The examples page is also a good place to go if you want to see how specific parts of the engine are used in practice.

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/gizmos_8hpp.html b/docs-preview/pr-1032/gizmos_8hpp.html new file mode 100644 index 000000000..4329a8227 --- /dev/null +++ b/docs-preview/pr-1032/gizmos_8hpp.html @@ -0,0 +1,136 @@ + + + + + engine/gizmos/gizmos.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/gl_2debug_8hpp.html b/docs-preview/pr-1032/gl_2debug_8hpp.html new file mode 100644 index 000000000..b02a395ea --- /dev/null +++ b/docs-preview/pr-1032/gl_2debug_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/gl/debug.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/glm_8hpp.html b/docs-preview/pr-1032/glm_8hpp.html new file mode 100644 index 000000000..e588ca231 --- /dev/null +++ b/docs-preview/pr-1032/glm_8hpp.html @@ -0,0 +1,102 @@ + + + + + core/reflection/external/glm.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/grid_8hpp.html b/docs-preview/pr-1032/grid_8hpp.html new file mode 100644 index 000000000..94e3378ec --- /dev/null +++ b/docs-preview/pr-1032/grid_8hpp.html @@ -0,0 +1,136 @@ + + + + + engine/voxels/grid.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__assets-plugin.html b/docs-preview/pr-1032/group__assets-plugin.html new file mode 100644 index 000000000..2d4d5dd74 --- /dev/null +++ b/docs-preview/pr-1032/group__assets-plugin.html @@ -0,0 +1,303 @@ + + + + + Engine » Assets module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Engine » + Assets module

+

Adds asset management to CUBOS.

+ +

Settings

  • assets.io.enabled - whether asset I/O should be done (default: true).
  • assets.io.path - path to the assets directory - will be mounted to /assets/ (default: assets/).
  • assets.io.readOnly - if true, the assets directory will be mounted as read-only (default: true).

Events

  • AssetEvent - (TODO) emitted when an asset is either loaded, modified or unloaded.

Resources

  • Assets - the asset manager, used to access asset data.

Startup tags

  • cubos.assets.init - initializes the assets manager and loads the meta files (after cubos.settings).
  • cubos.assets.bridge - systes which add bridges to the asset manager should be tagged with this.
  • cubos.assets - startup systems which load assets should be tagged with this.

Tags

  • cubos.assets.cleanup - frees any assets no longer in use.

Dependencies

+
+

Files

+
+
file asset.hpp
+
Classes cubos::engine::AnyAsset and cubos::engine::Asset.
+
file assets.hpp
+
Resource cubos::engine::Assets.
+
file bridge.hpp
+
Class cubos::engine::AssetBridge.
+
file binary.hpp
+
Class cubos::engine::BinaryBridge.
+
file file.hpp
+
Class cubos::engine::FileBridge.
+
file json.hpp
+
Class cubos::engine::JSONBridge.
+
file json.hpp
+
Class cubos::engine::JSONBridge.
+
file meta.hpp
+
Class cubos::engine::AssetMeta.
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Classes

+
+
+ class cubos::engine::AnyAsset +
+
Handle to an asset of any type. May either be weak or strong. Weak handles do not guarantee the asset is loaded, while strong handles do.
+
+
template<core::reflection::Reflectable T>
+ class cubos::engine::Asset +
+
Handle to an asset of a specific type.
+
+ class cubos::engine::Assets +
+
Resource which manages all assets. Responsible for loading and unloading assets, storing them in memory, and providing access to them.
+
+ class cubos::engine::AssetBridge +
+
Bridges are the objects responsible for loading and saving assets from/to disk. They form the bridge between the asset manager and the virtual file system.
+
+
template<typename T>
+ class cubos::engine::BinaryBridge +
+
Bridge for loading and saving assets which are serialized to and from a binary file.
+
+ class cubos::engine::FileBridge +
+
Abstract bridge type defined to reduce boilerplate code in bridge implementations which open a single file to load and save assets.
+
+
template<typename T>
+ class cubos::engine::JSONBridge +
+
Bridge for loading and saving assets which are serialized to and from a JSON file.
+
+
template<typename T>
+ class cubos::engine::old::JSONBridge +
+
Bridge for loading and saving assets which are serialized to and from a JSON file.
+
+ class cubos::engine::AssetMeta +
+
Stores metadata about an asset - the data stored in .meta files. Each asset has a corresponding meta object, which contains load or import parameters.
+
+
+
+

Typedefs

+
+
+ using AssetMetaRead = core::memory::ReadGuard<AssetMeta, std::shared_lock<std::shared_mutex>> +
+
Read-only guard for an asset's metadata.
+
+ using AssetMetaWrite = core::memory::WriteGuard<AssetMeta, std::unique_lock<std::shared_mutex>> +
+
Read-write guard for an asset's metadata.
+
+
template<typename T>
+ using AssetRead = core::memory::ReadGuard<T, std::shared_lock<std::shared_mutex>> +
+
Read-only guard for an asset's data.
+
+
template<typename T>
+ using AssetWrite = core::memory::WriteGuard<T, std::unique_lock<std::shared_mutex>> +
+
Read-write guard for an asset's data.
+
+
+
+

Functions

+
+
+ void assetsPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Typedef documentation

+
+

+ using AssetMetaRead = core::memory::ReadGuard<AssetMeta, std::shared_lock<std::shared_mutex>> + +

+

Read-only guard for an asset's metadata.

+
+
+

+ using AssetMetaWrite = core::memory::WriteGuard<AssetMeta, std::unique_lock<std::shared_mutex>> + +

+

Read-write guard for an asset's metadata.

+
+
+

+ +
+ template<typename T> +
+ using AssetRead = core::memory::ReadGuard<T, std::shared_lock<std::shared_mutex>> +

+

Read-only guard for an asset's data.

+ + + + + + + + + + +
Template parameters
TThe type of the data to guard.
+
+
+

+ +
+ template<typename T> +
+ using AssetWrite = core::memory::WriteGuard<T, std::unique_lock<std::shared_mutex>> +

+

Read-write guard for an asset's data.

+ + + + + + + + + + +
Template parameters
TThe type of the data to guard.
+
+
+
+

Function documentation

+
+

+ void assetsPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__collisions-plugin.html b/docs-preview/pr-1032/group__collisions-plugin.html new file mode 100644 index 000000000..ce30f037a --- /dev/null +++ b/docs-preview/pr-1032/group__collisions-plugin.html @@ -0,0 +1,192 @@ + + + + + Engine » Collisions module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Engine » + Collisions module

+

Adds collision detection to CUBOS.

+ +

Components

Events

  • CollisionEvent - (TODO) emitted when a collision occurs.
  • TriggerEvent - (TODO) emitted when a trigger is entered or exited.

Tags

  • cubos.collisions.setup - new colliders are setup.
  • cubos.collisions.broad - broad phase candidate pairs are generated.

Dependencies

+
+

Files

+
+
file collider.hpp
+
Component cubos::engine::Collider.
+
file colliding_with.hpp
+
Relation cubos::engine::CollidingWith.
+
file collision_event.hpp
+
Event cubos::engine::CollisionEvent.
+
file plugin.hpp
+
Plugin entry point.
+
file box.hpp
+
Component cubos::engine::BoxCollisionShape.
+
file capsule.hpp
+
Component cubos::engine::CapsuleCollisionShape.
+
+
+
+

Classes

+
+
+ struct cubos::engine::Collider +
+
Component which adds a collider to an entity.
+
+ struct cubos::engine::CollidingWith +
+
Relation which represents a collision.
+
+ struct cubos::engine::CollisionEvent +
+
Represents a collision event.
+
+ struct cubos::engine::BoxCollisionShape +
+
Component which adds a box collision shape to an entity, used with a Collider component.
+
+ struct cubos::engine::CapsuleCollisionShape +
+
Component which adds a capsule collision shape to an entity, used with a Collider component.
+
+
+
+

Functions

+
+
+ void collisionsPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void collisionsPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__core-al.html b/docs-preview/pr-1032/group__core-al.html new file mode 100644 index 000000000..4caed25bd --- /dev/null +++ b/docs-preview/pr-1032/group__core-al.html @@ -0,0 +1,153 @@ + + + + + Core » Audio module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Core » + Audio module

+

Provides audio functionality.

+ +
+

Files

+
+
file audio_device.hpp
+
Class cubos::core::al::AudioDevice and related types.
+
+
+
+

Typedefs

+
+
+ using Buffer = std::shared_ptr<impl::Buffer> +
+
Handle to an audio buffer.
+
+ using Source = std::shared_ptr<impl::Source> +
+
Handle to an audio source.
+
+
+
+

Typedef documentation

+
+

+ using Buffer = std::shared_ptr<impl::Buffer> + +

+

Handle to an audio buffer.

+ +
+
+

+ using Source = std::shared_ptr<impl::Source> + +

+

Handle to an audio source.

+ +
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__core-data-des.html b/docs-preview/pr-1032/group__core-data-des.html new file mode 100644 index 000000000..f3ee91939 --- /dev/null +++ b/docs-preview/pr-1032/group__core-data-des.html @@ -0,0 +1,137 @@ + + + + + Core » Data » Deserialization module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Core » + Data » + Deserialization module

+

Provides deserialization utilities.

+ +
+

Files

+
+
file deserializer.hpp
+
Class cubos::core::data::Deserializer.
+
file json.hpp
+
Class cubos::core::data::JSONDeserializer.
+
+
+
+

Classes

+
+
+ class cubos::core::data::Deserializer +
+
Base class for deserializers, which defines the interface for deserializing arbitrary data using its reflection metadata.
+
+ class cubos::core::data::JSONDeserializer +
+
Deserializer implementation which allows reading data from a JSON object.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__core-data-fs.html b/docs-preview/pr-1032/group__core-data-fs.html new file mode 100644 index 000000000..c67d40cc8 --- /dev/null +++ b/docs-preview/pr-1032/group__core-data-fs.html @@ -0,0 +1,162 @@ + + + + + Core » Data » Filesystem module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Core » + Data » + Filesystem module

+

Provides filesystem utilities.

+ +
+

Files

+
+
file archive.hpp
+
Class cubos::core::data::Archive.
+
file embedded_archive.hpp
+
Class cubos::core::data::EmbeddedArchive.
+
file file.hpp
+
Class cubos::core::data::File.
+
file file_stream.hpp
+
Class cubos::core::data::FileStream.
+
file file_system.hpp
+
Class cubos::core::data::FileSystem.
+
file standard_archive.hpp
+
Class cubos::core::data::StandardArchive.
+
+
+
+

Classes

+
+
+ class cubos::core::data::Archive +
+
Interface for a bridge between the CUBOS. virtual file system and the real world.
+
+ class cubos::core::data::EmbeddedArchive +
+
Archive implementation which reads data embedded in the application. Meant to be used with the quadrados embed tool.
+
+ class cubos::core::data::File +
+
Represents a file in the virtual file system of the engine.
+
+
template<typename T>
+ class cubos::core::data::FileStream +
+
Wrapper around an implementation-specific file stream which keeps the file alive and does some sanity checks.
+
+ class cubos::core::data::FileSystem +
+
Singleton which represents the virtual file system of the engine.
+
+ class cubos::core::data::StandardArchive +
+
Archive implementation which reads and writes from/into the OS file system using the standard library.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__core-data-ser.html b/docs-preview/pr-1032/group__core-data-ser.html new file mode 100644 index 000000000..6214fc15f --- /dev/null +++ b/docs-preview/pr-1032/group__core-data-ser.html @@ -0,0 +1,139 @@ + + + + + Core » Data » Serialization module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Core » + Data » + Serialization module

+

Provides serialization utilities.

+ +
+

Files

+
+
file debug.hpp
+
Class cubos::core::data::DebugSerializer.
+
file json.hpp
+
Class cubos::core::data::JSONSerializer.
+
file serializer.hpp
+
Class cubos::core::data::Serializer.
+
+
+
+

Classes

+
+
+ class cubos::core::data::DebugSerializer +
+
Serializer implementation which prints the given data to a stream in a human-readable format not meant to be parsed.
+
+ class cubos::core::data::Serializer +
+
Base class for serializers, which defines the interface for serializing arbitrary data using its reflection metadata.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__core-data.html b/docs-preview/pr-1032/group__core-data.html new file mode 100644 index 000000000..b167386bd --- /dev/null +++ b/docs-preview/pr-1032/group__core-data.html @@ -0,0 +1,124 @@ + + + + + Core » Data module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Core » + Data module

+

Provides filesystem and serialization utilities.

+ +
+

Modules

+
+
module Deserialization
+
Provides deserialization utilities.
+
module Filesystem
+
Provides filesystem utilities.
+
module Serialization
+
Provides serialization utilities.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__core-ecs-entity.html b/docs-preview/pr-1032/group__core-ecs-entity.html new file mode 100644 index 000000000..75d8ccfc1 --- /dev/null +++ b/docs-preview/pr-1032/group__core-ecs-entity.html @@ -0,0 +1,155 @@ + + + + + Core » ECS » Entity module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Core » + ECS » + Entity module

+

Entity part of the ECS.

+ +
+

Files

+
+
file archetype_graph.hpp
+
Class cubos::core::ecs::ArchetypeGraph.
+
file archetype_id.hpp
+
Struct cubos::core::ecs::ArchetypeId.
+
file entity.hpp
+
Struct cubos::core::ecs::Entity.
+
file hash.hpp
+
Struct cubos::core::ecs::EntityHash.
+
file pool.hpp
+
Class cubos::core::ecs::EntityPool.
+
+
+
+

Classes

+
+
+ class cubos::core::ecs::ArchetypeGraph +
+
Stores which column types each archetype holds and the edges which connect them.
+
+ struct cubos::core::ecs::ArchetypeId +
+
Identifies an archetype.
+
+ struct cubos::core::ecs::Entity +
+
Identifies an entity.
+
+ struct cubos::core::ecs::EntityHash +
+
Used to hash Entity objects.
+
+ class cubos::core::ecs::EntityPool +
+
Manages the creation and destruction of entity identifiers, as well as storing their archetype identifiers.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__core-ecs-query.html b/docs-preview/pr-1032/group__core-ecs-query.html new file mode 100644 index 000000000..95305c733 --- /dev/null +++ b/docs-preview/pr-1032/group__core-ecs-query.html @@ -0,0 +1,164 @@ + + + + + Core » ECS » Query module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Core » + ECS » + Query module

+

Defines the query functionality of the ECS.

+ +
+

Files

+
+
file data.hpp
+
Class cubos::core::ecs::QueryData.
+
file fetcher.hpp
+
Class cubos::core::ecs::QueryFetcher.
+
file filter.hpp
+
Class cubos::core::ecs::QueryFilter.
+
file archetype.hpp
+
Class cubos::core::ecs::QueryArchetypeNode.
+
file node.hpp
+
Class cubos::core::ecs::QueryNode.
+
file related.hpp
+
Class cubos::core::ecs::QueryRelatedNode.
+
file opt.hpp
+
Class cubos::core::ecs::Opt.
+
file term.hpp
+
Struct cubos::core::ecs::QueryTerm.
+
+
+
+

Classes

+
+
+
template<typename... Ts>
+ class cubos::core::ecs::QueryData +
+
Holds the data necessary to execute a query.
+
+
template<typename T>
+ class cubos::core::ecs::QueryFetcher +
+
Type meant to be specialized which implements for each argument type the necessary logic to extract it from the tables.
+
+ class cubos::core::ecs::QueryFilter +
+
Used to find matches for the given query terms. Essentially contains the non-templated part of the query logic.
+
+
template<typename T>
+ class cubos::core::ecs::Opt +
+
Wrapper for reference types to indicate that the given argument type is optional in a query.
+
+ struct cubos::core::ecs::QueryTerm +
+
Describes a term in a query.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__core-ecs-resource.html b/docs-preview/pr-1032/group__core-ecs-resource.html new file mode 100644 index 000000000..29145b7d9 --- /dev/null +++ b/docs-preview/pr-1032/group__core-ecs-resource.html @@ -0,0 +1,141 @@ + + + + + Core » ECS » Resource module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Core » + ECS » + Resource module

+

Resource part of the ECS.

+ +
+

Files

+
+
file manager.hpp
+
Class cubos::core::ecs::ResourceManager and related types.
+
+
+
+

Classes

+
+
+
template<typename T>
+ class cubos::core::ecs::ReadResource +
+
Utility struct used to reference a resource of type T for reading.
+
+
template<typename T>
+ class cubos::core::ecs::WriteResource +
+
Utility struct used to reference a resource of type T for writing.
+
+ class cubos::core::ecs::ResourceManager +
+
Holds and manages resources.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__core-ecs-system-arguments.html b/docs-preview/pr-1032/group__core-ecs-system-arguments.html new file mode 100644 index 000000000..686180433 --- /dev/null +++ b/docs-preview/pr-1032/group__core-ecs-system-arguments.html @@ -0,0 +1,164 @@ + + + + + Core » ECS » System » Arguments module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Core » + ECS » + System » + Arguments module

+

Contains types and fetcher specializations for system argument types.

+ +
+

Files

+
+
file commands.hpp
+
Class cubos::core::ecs::Commands.
+
file pipe.hpp
+
Resource cubos::core::ecs::EventPipe.
+
file reader.hpp
+
Class cubos::core::ecs::EventReader.
+
file writer.hpp
+
Class cubos::core::ecs::EventWriter.
+
file query.hpp
+
Class cubos::core::ecs::Query.
+
file resources.hpp
+
Resource system argument specializations.
+
file world.hpp
+
World system argument specializations.
+
+
+
+

Classes

+
+
+ class cubos::core::ecs::Commands +
+
System argument used to write ECS commands and execute them at a later time.
+
+
template<typename T>
+ class cubos::core::ecs::EventPipe +
+
Resource which stores events of type T.
+
+
template<typename T, unsigned int M = DEFAULT_FILTER_MASK>
+ class cubos::core::ecs::EventReader +
+
System arguments used to read events of type T.
+
+
template<typename T>
+ class cubos::core::ecs::EventWriter +
+
System argument which allows the system to send events of type T to other systems.
+
+
template<typename... Ts>
+ class cubos::core::ecs::Query +
+
System argument which holds the result of a query over all entities in world which match the given arguments.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__core-ecs-system.html b/docs-preview/pr-1032/group__core-ecs-system.html new file mode 100644 index 000000000..5aa8056e9 --- /dev/null +++ b/docs-preview/pr-1032/group__core-ecs-system.html @@ -0,0 +1,165 @@ + + + + + Core » ECS » System module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Core » + ECS » + System module

+

System part of the ECS.

+ +
+

Modules

+
+
module Arguments
+
Contains types and fetcher specializations for system argument types.
+
+
+
+

Files

+
+
file access.hpp
+
Struct cubos::core::ecs::SystemAccess.
+
file dispatcher.hpp
+
Class cubos::core::ecs::Dispatcher.
+
file fetcher.hpp
+
Class cubos::core::ecs::SystemFetcher.
+
file options.hpp
+
Struct cubos::core::ecs::SystemOptions.
+
file system.hpp
+
Class cubos::core::ecs::System.
+
+
+
+

Classes

+
+
+ struct cubos::core::ecs::SystemAccess +
+
Describes the types of data a system accesses.
+
+ class cubos::core::ecs::Dispatcher +
+
Used to add systems and relations between them and then dispatch them all at once.
+
+
template<typename T>
+ class cubos::core::ecs::SystemFetcher +
+
Type meant to be specialized which implements for each argument type the necessary logic to extract it from the world.
+
+ struct cubos::core::ecs::SystemOptions +
+
Contains extra options for a specific system argument.
+
+
template<typename T>
+ class cubos::core::ecs::System +
+
Holds a system with a return type T.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__core-ecs-table.html b/docs-preview/pr-1032/group__core-ecs-table.html new file mode 100644 index 000000000..c8e9c8e56 --- /dev/null +++ b/docs-preview/pr-1032/group__core-ecs-table.html @@ -0,0 +1,161 @@ + + + + + Core » ECS » Table module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Core » + ECS » + Table module

+

Contains various table-like data structures which storage data associated to entities.

+ +
+

Files

+
+
file column.hpp
+
Struct cubos::core::ecs::DenseTableId.
+
file registry.hpp
+
Class cubos::core::ecs::DenseTableRegistry.
+
file table.hpp
+
Class cubos::core::ecs::DenseTable.
+
file id.hpp
+
Struct cubos::core::ecs::SparseRelationTableId.
+
file registry.hpp
+
Class cubos::core::ecs::SparseRelationTableRegistry.
+
file tables.hpp
+
Class cubos::core::ecs::Tables.
+
+
+
+

Classes

+
+
+ struct cubos::core::ecs::ColumnId +
+
Identifies a data column type.
+
+ class cubos::core::ecs::DenseTableRegistry +
+
Stores the dense tables of a given world.
+
+ class cubos::core::ecs::DenseTable +
+
Stores the dense data associated to entities of a given archetype.
+
+ struct cubos::core::ecs::SparseRelationTableId +
+
Identifies a sparse relation table.
+
+ class cubos::core::ecs::SparseRelationTableRegistry +
+
Stores all of the sparse relation tables.
+
+ class cubos::core::ecs::Tables +
+
Stores the tables of a given world.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__core-ecs.html b/docs-preview/pr-1032/group__core-ecs.html new file mode 100644 index 000000000..5a89333d0 --- /dev/null +++ b/docs-preview/pr-1032/group__core-ecs.html @@ -0,0 +1,193 @@ + + + + + Core » ECS module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Core » + ECS module

+

Entity Component System library.

+ +

This module is arguably the heart of the engine, as it provides a means to organize and manage the data and logic of both the engine and games built with it. It is, as of now, a bit of a mess. Most of the exposed types are internal to the documentation, and thus it can get hard to navigate (TODO #377).

Data types

  • World - stores entities, components and resources, can be queried.
  • Dispatcher - stores and dispatches systems in the right order.
  • Blueprint - bundle of entities and components which can be spawned using Commands.

System argument types

  • const R& - used to read resource data of type R.
  • R& - used to write resource data of type R.
  • const World& - used to read the world directly (not recommended, ruins parallelism, prefer Commands).
  • World& - used to write the world directly (not recommended, ruins parallelism, prefer Commands).
  • Commands - used to queue entities to be created, destroyed and other operations.
  • EventReader<E> - reads events of type E sent from other systems.
  • EventWriter<E> - sends events of type E to other systems.
  • Query<Args...> - queries the world for entities which match its arguments.

Query argument types

  • const C& - matches entities with the component C, read-only access.
  • C& - matches entities with the component C, write access.
  • Opt<const C&>" - matches all entities, read-only access when the component C is present. -Opt<C&>` - matches all entities, write access when the component C is present.
+
+

Modules

+
+
module Entity
+
Entity part of the ECS.
+
module Query
+
Defines the query functionality of the ECS.
+
module Resource
+
Resource part of the ECS.
+
module System
+
System part of the ECS.
+
module Table
+
Contains various table-like data structures which storage data associated to entities.
+
+
+
+

Files

+
+
file blueprint.hpp
+
Class cubos::core::ecs::Blueprint.
+
file command_buffer.hpp
+
Class cubos::core::ecs::CommandBuffer.
+
file name.hpp
+
Class cubos::core::ecs::Name.
+
file reflection.hpp
+
Class cubos::core::ecs::TypeBuilder.
+
file types.hpp
+
Class cubos::core::ecs::Types.
+
file world.hpp
+
Class cubos::core::ecs::World.
+
+
+
+

Classes

+
+
+ class cubos::core::ecs::Blueprint +
+
Collection of entities and their respective components and relations.
+
+ class cubos::core::ecs::CommandBuffer +
+
Stores commands to execute them later.
+
+ struct cubos::core::ecs::DeltaTime +
+
Resource which stores the time since the last iteration of the main loop started.
+
+ struct cubos::core::ecs::ShouldQuit +
+
Resource used as a flag to indicate whether the main loop should stop running.
+
+ struct cubos::core::ecs::Arguments +
+
Resource which stores the command-line arguments.
+
+ class cubos::core::ecs::TagBuilder +
+
Used to chain configurations related to tags.
+
+ class cubos::core::ecs::Cubos +
+
Represents the engine itself, and exposes the interface with which the game developer interacts with. Ties up all the different parts of the engine together.
+
+
template<typename T>
+ class cubos::core::ecs::TypeBuilder +
+
Builder for reflection::Type objects which represent ECS types.
+
+ class cubos::core::ecs::World +
+
Holds entities, their components and resources.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__core-geom.html b/docs-preview/pr-1032/group__core-geom.html new file mode 100644 index 000000000..99dd16400 --- /dev/null +++ b/docs-preview/pr-1032/group__core-geom.html @@ -0,0 +1,148 @@ + + + + + Core » Geometry module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Core » + Geometry module

+

Provides geometry utilities.

+ +
+

Files

+
+
file aabb.hpp
+
Component cubos::core::geom::AABB.
+
file box.hpp
+
Class cubos::core::geom::Box.
+
file capsule.hpp
+
Class cubos::core::geom::Capsule.
+
file intersections.hpp
+
Class cubos::core::geom::Intersections.
+
+
+
+

Classes

+
+
+ struct cubos::core::geom::AABB +
+
Represents an axis-aligned bounding box.
+
+ struct cubos::core::geom::Box +
+
Represents a box shape.
+
+ struct cubos::core::geom::Capsule +
+
Represents a capsule or sphere shape.
+
+ struct cubos::core::geom::Intersection +
+
Contains info regarding an intersection between shapes.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__core-gl.html b/docs-preview/pr-1032/group__core-gl.html new file mode 100644 index 000000000..bc00a87d5 --- /dev/null +++ b/docs-preview/pr-1032/group__core-gl.html @@ -0,0 +1,1249 @@ + + + + + Core » Graphics module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Core » + Graphics module

+

Provides a graphics API abstraction.

+ +
+

Files

+
+
file debug.hpp
+
Class cubos::core::gl::Debug.
+
file render_device.hpp
+
Class cubos::core::gl::RenderDevice and related types.
+
file util.hpp
+
Function cubos::core::gl::generateScreenQuad.
+
+
+
+

Classes

+
+
+ class cubos::core::gl::Debug +
+
Singleton with static methods used to draw primitive objects on screen for debugging purposes.
+
+ struct cubos::core::gl::FramebufferDesc +
+
Describes a framebuffer.
+
+ struct cubos::core::gl::RasterStateDesc +
+
Decribes a rasterizer state.
+
+ struct cubos::core::gl::DepthStencilStateDesc +
+
Describes a depth stencil state.
+
+ struct cubos::core::gl::BlendStateDesc +
+
Describes a blend state.
+
+ struct cubos::core::gl::SamplerDesc +
+
Describes a sampler.
+
+ struct cubos::core::gl::Texture1DDesc +
+
Describes a 1D texture.
+
+ struct cubos::core::gl::Texture2DDesc +
+
Describes a 2D texture.
+
+ struct cubos::core::gl::Texture2DArrayDesc +
+
Describes a 2D texture array.
+
+ struct cubos::core::gl::Texture3DDesc +
+
Describes a 3D texture.
+
+ struct cubos::core::gl::CubeMapDesc +
+
Describes a cube map.
+
+ struct cubos::core::gl::CubeMapArrayDesc +
+
Describes a cube map array.
+
+ struct cubos::core::gl::ConstantBufferElement +
+
Describes an element in a constant buffer.
+
+ struct cubos::core::gl::ConstantBufferStructure +
+
Describes the structure of a constant buffer.
+
+ struct cubos::core::gl::VertexElement +
+
Describes a vertex element.
+
+ struct cubos::core::gl::VertexArrayDesc +
+
Describes a vertex array.
+
+ class cubos::core::gl::RenderDevice +
+
Interface used to wrap low-level rendering APIs such as OpenGL.
+
+
+
+

Enums

+
+
+ enum class Property { MaxAnisotropy, + ComputeSupported } +
+
Render device properties that can be queried at runtime.
+
+ enum class Usage { Default, + Dynamic, + Static } +
+
Usage mode for buffers and textures.
+
+ enum class Type { Byte, + Short, + Int, + UByte, + UShort, + UInt, + NByte, + NShort, + NUByte, + NUShort, + Float } +
+
Data type.
+
+ enum class IndexFormat { UShort, + UInt } +
+
Index format.
+
+ enum class TextureFormat { R8SNorm, + R16SNorm, + RG8SNorm, + RG16SNorm, + RGBA8SNorm, + RGBA16SNorm, + R8UNorm, + R16UNorm, + RG8UNorm, + RG16UNorm, + RGBA8UNorm, + RGBA16UNorm, + R8SInt, + R16SInt, + RG8SInt, + RG16SInt, + RGBA8SInt, + RGBA16SInt, + R8UInt, + R16UInt, + RG8UInt, + RG16UInt, + RGBA8UInt, + RGBA16UInt, + R16Float, + R32Float, + RG16Float, + RG32Float, + RGB16Float, + RGB32Float, + RGBA16Float, + RGBA32Float, + Depth16, + Depth32, + Depth24Stencil8, + Depth32Stencil8 } +
+
Texture format.
+
+ enum class AddressMode { Repeat, + Mirror, + Clamp, + Border } +
+
Texture address mode.
+
+ enum class TextureFilter { None, + Nearest, + Linear } +
+
Texture filter type.
+
+ enum class Winding { CW, + CCW } +
+
Triangle winding mode.
+
+ enum class Face { Front, + Back, + FrontAndBack } +
+
Specifies a face.
+
+ enum class RasterMode { Wireframe, + Fill } +
+
Rasterizer mode.
+
+ enum class Compare { Never, + Less, + LEqual, + Greater, + GEqual, + Equal, + NEqual, + Always } +
+
Comparison function.
+
+ enum class StencilAction { Zero, + Keep, + Replace, + Increment, + IncrementWrap, + Decrement, + DecrementWrap, + Invert } +
+
Stencil action.
+
+ enum class BlendFactor { Zero, + One, + SrcColor, + InvSrcColor, + DstColor, + InvDstColor, + SrcAlpha, + InvSrcAlpha, + DstAlpha, + InvDstAlpha } +
+
Blend factor.
+
+ enum class BlendOp { Add, + Substract, + RevSubstract, + Min, + Max } +
+
Blend operation.
+
+ enum class Stage { Vertex, + Geometry, + Pixel, + Compute } +
+
Shader stage type.
+
+ enum class CubeFace { PositiveX = 0, + NegativeX = 1, + PositiveY = 2, + NegativeY = 3, + PositiveZ = 4, + NegativeZ = 5 } +
+
Cube map face.
+
+ enum class MemoryBarriers { None = 0, + VertexBuffer = 1, + IndexBuffer = 2, + ConstantBuffer = 4, + ImageAccess = 8, + TextureAccess = 16, + Framebuffer = 32, + All = VertexBuffer | IndexBuffer | ConstantBuffer | ImageAccess | TextureAccess | Framebuffer } +
+
Memory barrier flags for synchronization.
+
+ enum class Access { Read, + Write, + ReadWrite } +
+
Access mode for a resource.
+
+
+
+

Typedefs

+
+
+ using Framebuffer = std::shared_ptr<impl::Framebuffer> +
+
Handle to a framebuffer.
+
+ using RasterState = std::shared_ptr<impl::RasterState> +
+
Handle to a rasterizer state.
+
+ using DepthStencilState = std::shared_ptr<impl::DepthStencilState> +
+
Handle to a depth stencil state.
+
+ using BlendState = std::shared_ptr<impl::BlendState> +
+
Handle to a blend state.
+
+ using Sampler = std::shared_ptr<impl::Sampler> +
+
Handle to a sampler.
+
+ using Texture1D = std::shared_ptr<impl::Texture1D> +
+
Handle to a 1D texture.
+
+ using Texture2D = std::shared_ptr<impl::Texture2D> +
+
Handle to a 2D texture.
+
+ using Texture2DArray = std::shared_ptr<impl::Texture2DArray> +
+
Handle to a 2D texture array.
+
+ using Texture3D = std::shared_ptr<impl::Texture3D> +
+
Handle to a 3D texture.
+
+ using CubeMap = std::shared_ptr<impl::CubeMap> +
+
Handle to a cube map.
+
+ using CubeMapArray = std::shared_ptr<impl::CubeMapArray> +
+
Handle to a cube map array.
+
+ using ConstantBuffer = std::shared_ptr<impl::ConstantBuffer> +
+
Handle to a constant buffer.
+
+ using IndexBuffer = std::shared_ptr<impl::IndexBuffer> +
+
Handle to an index buffer.
+
+ using VertexBuffer = std::shared_ptr<impl::VertexBuffer> +
+
Handle to a vertex buffer.
+
+ using VertexArray = std::shared_ptr<impl::VertexArray> +
+
Handle to a vertex array.
+
+ using ShaderStage = std::shared_ptr<impl::ShaderStage> +
+
Handle to a shader stage.
+
+ using ShaderPipeline = std::shared_ptr<impl::ShaderPipeline> +
+
Handle to a shader pipeline.
+
+ using ShaderBindingPoint = impl::ShaderBindingPoint* +
+
Handle to a shader binding point.
+
+
+
+

Defines

+
+
+ #define CUBOS_CORE_GL_MAX_FRAMEBUFFER_RENDER_TARGET_COUNT +
+
Maximum number of render targets that can be set on a framebuffer.
+
+ #define CUBOS_CORE_GL_MAX_TEXTURE_2D_ARRAY_SIZE +
+
Maximum number of textures on a 2D texture array.
+
+ #define CUBOS_CORE_GL_MAX_CUBEMAP_ARRAY_SIZE +
+
Maximum number of cube maps on a cubemap array.
+
+ #define CUBOS_CORE_GL_MAX_MIP_LEVEL_COUNT +
+
Maximum mip level count.
+
+ #define CUBOS_CORE_GL_MAX_CONSTANT_BUFFER_ELEMENT_NAME_SIZE +
+
Maximum constant buffer element name size.
+
+ #define CUBOS_CORE_GL_MAX_CONSTANT_BUFFER_ELEMENT_COUNT +
+
Maximum constant buffer element count.
+
+ #define CUBOS_CORE_GL_MAX_VERTEX_ARRAY_ELEMENT_COUNT +
+
Maximum number of vertex array elements.
+
+ #define CUBOS_CORE_GL_MAX_VERTEX_ARRAY_BUFFER_COUNT +
+
Maximum number of buffers on a vertex array.
+
+
+
+

Enum documentation

+
+

+ enum class Property + +

+

Render device properties that can be queried at runtime.

+ + + + + + + + + + + + + +
Enumerators
MaxAnisotropy +

Specifies the upper bound of anisotropic filtering.

+
ComputeSupported +

Specifies whether compute shaders and memory barriers are supported (0 or 1).

+
+
+
+

+ enum class Usage + +

+

Usage mode for buffers and textures.

+
+
+

+ enum class Type + +

+

Data type.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Enumerators
Byte +

8 bits signed integer.

+
Short +

16 bits signed integer.

+
Int +

32 bits signed integer.

+
UByte +

8 bits unsigned integer.

+
UShort +

16 bits unsigned integer.

+
UInt +

32 bits unsigned integer.

+
NByte +

Normalized 8 bits signed integer.

+
NShort +

Normalized 16 bits signed integer.

+
NUByte +

Normalized 8 bits unsigned integer.

+
NUShort +

Normalized 16 bits unsigned integer.

+
Float +

32 bits floating point.

+
+
+
+

+ enum class IndexFormat + +

+

Index format.

+ + + + + + + + + + + + +
Enumerators
UShort +

16 bits unsigned integer.

+
UInt +

32 bits unsigned integer.

+
+
+
+

+ enum class TextureFormat + +

+

Texture format.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Enumerators
R8SNorm +

1 channel 8 bits normalized signed integer.

+
R16SNorm +

1 channel 16 bits normalized signed integer.

+
RG8SNorm +

2 channel 8 bits normalized signed integer.

+
RG16SNorm +

2 channel 16 bits normalized signed integer.

+
RGBA8SNorm +

4 channel 8 bits normalized signed integer.

+
RGBA16SNorm +

4 channel 16 bits normalized signed integer.

+
R8UNorm +

1 channel 8 bits normalized unsigned integer.

+
R16UNorm +

1 channel 16 bits normalized unsigned integer.

+
RG8UNorm +

2 channel 8 bits normalized unsigned integer.

+
RG16UNorm +

2 channel 16 bits normalized unsigned integer.

+
RGBA8UNorm +

4 channel 8 bits normalized unsigned integer.

+
RGBA16UNorm +

4 channel 16 bits normalized unsigned integer.

+
R8SInt +

1 channel 8 bits signed integer.

+
R16SInt +

1 channel 16 bits signed integer.

+
RG8SInt +

2 channel 8 bits signed integer.

+
RG16SInt +

2 channel 16 bits signed integer.

+
RGBA8SInt +

4 channel 8 bits signed integer.

+
RGBA16SInt +

4 channel 16 bits signed integer.

+
R8UInt +

1 channel 8 bits unsigned integer.

+
R16UInt +

1 channel 16 bits unsigned integer.

+
RG8UInt +

2 channel 8 bits unsigned integer.

+
RG16UInt +

2 channel 16 bits unsigned integer.

+
RGBA8UInt +

4 channel 8 bits unsigned integer.

+
RGBA16UInt +

4 channel 16 bits unsigned integer.

+
R16Float +

1 channel 16 bits floating point.

+
R32Float +

1 channel 32 bits floating point.

+
RG16Float +

2 channel 16 bits floating point.

+
RG32Float +

2 channel 32 bits floating point.

+
RGB16Float +

3 channel 16 bits floating point.

+
RGB32Float +

3 channel 32 bits floating point.

+
RGBA16Float +

4 channel 16 bits floating point.

+
RGBA32Float +

4 channel 32 bits floating point.

+
Depth16 +

16 depth bits.

+
Depth32 +

32 depth bits.

+
Depth24Stencil8 +

24 depth bits and 8 stencil bits.

+
Depth32Stencil8 +

32 depth bits and 8 stencil bits.

+
+
+
+

+ enum class AddressMode + +

+

Texture address mode.

+
+
+

+ enum class TextureFilter + +

+

Texture filter type.

+
+
+

+ enum class Winding + +

+

Triangle winding mode.

+ + + + + + + + + + + + +
Enumerators
CW +

Clockwise.

+
CCW +

Counterclockwise.

+
+
+
+

+ enum class Face + +

+

Specifies a face.

+
+
+

+ enum class RasterMode + +

+

Rasterizer mode.

+
+
+

+ enum class Compare + +

+

Comparison function.

+
+
+

+ enum class StencilAction + +

+

Stencil action.

+
+
+

+ enum class BlendFactor + +

+

Blend factor.

+
+
+

+ enum class BlendOp + +

+

Blend operation.

+
+
+

+ enum class Stage + +

+

Shader stage type.

+
+
+

+ enum class CubeFace + +

+

Cube map face.

+
+
+

+ enum class MemoryBarriers + +

+

Memory barrier flags for synchronization.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Enumerators
None +

Utility flag to indicate that no memory barrier is set.

+
VertexBuffer +

If set, data sourced from vertex buffers after the barrier will reflect the data written by shaders prior to the barrier.

+
IndexBuffer +

If set, data sourced from index buffers after the barrier will reflect the data written by shaders prior to the barrier.

+
ConstantBuffer +

If set, data sourced from constant buffers after the barrier will reflect the data written by shaders prior to the barrier.

+
ImageAccess +

If set, memory accesses using shader image load, store, and atomic built-in functions issued after the barrier will reflect the data written by shaders prior to the barrier.

+
TextureAccess +

If set, texture accesses from shaders after the barrier will reflect the data written by shaders prior to the barrier.

+
Framebuffer +

If set, reads and writes via framebuffer objects after the barrier will reflect the data written by shaders prior to the barrier.

+
All +

Utility flag to set all memory barriers.

+
+
+
+

+ enum class Access + +

+

Access mode for a resource.

+ + + + + + + + + + + + + + + + +
Enumerators
Read +

Read access.

+
Write +

Write access.

+
ReadWrite +

Read and write access.

+
+
+
+
+

Typedef documentation

+
+

+ using Framebuffer = std::shared_ptr<impl::Framebuffer> + +

+

Handle to a framebuffer.

+ +
+
+

+ using RasterState = std::shared_ptr<impl::RasterState> + +

+

Handle to a rasterizer state.

+ +
+
+

+ using DepthStencilState = std::shared_ptr<impl::DepthStencilState> + +

+

Handle to a depth stencil state.

+ +
+
+

+ using BlendState = std::shared_ptr<impl::BlendState> + +

+

Handle to a blend state.

+ +
+
+

+ using Sampler = std::shared_ptr<impl::Sampler> + +

+

Handle to a sampler.

+ +
+
+

+ using Texture1D = std::shared_ptr<impl::Texture1D> + +

+

Handle to a 1D texture.

+ +
+
+

+ using Texture2D = std::shared_ptr<impl::Texture2D> + +

+

Handle to a 2D texture.

+ +
+
+

+ using Texture2DArray = std::shared_ptr<impl::Texture2DArray> + +

+

Handle to a 2D texture array.

+ +
+
+

+ using Texture3D = std::shared_ptr<impl::Texture3D> + +

+

Handle to a 3D texture.

+ +
+
+

+ using CubeMap = std::shared_ptr<impl::CubeMap> + +

+

Handle to a cube map.

+ +
+
+

+ using CubeMapArray = std::shared_ptr<impl::CubeMapArray> + +

+

Handle to a cube map array.

+ +
+
+

+ using ConstantBuffer = std::shared_ptr<impl::ConstantBuffer> + +

+

Handle to a constant buffer.

+ +
+
+

+ using IndexBuffer = std::shared_ptr<impl::IndexBuffer> + +

+

Handle to an index buffer.

+ +
+
+

+ using VertexBuffer = std::shared_ptr<impl::VertexBuffer> + +

+

Handle to a vertex buffer.

+ +
+
+

+ using VertexArray = std::shared_ptr<impl::VertexArray> + +

+

Handle to a vertex array.

+ +
+
+

+ using ShaderStage = std::shared_ptr<impl::ShaderStage> + +

+

Handle to a shader stage.

+ +
+
+

+ using ShaderPipeline = std::shared_ptr<impl::ShaderPipeline> + +

+

Handle to a shader pipeline.

+ +
+
+

+ using ShaderBindingPoint = impl::ShaderBindingPoint* + +

+

Handle to a shader binding point.

+ +
+
+
+

Define documentation

+
+

+ #define CUBOS_CORE_GL_MAX_FRAMEBUFFER_RENDER_TARGET_COUNT + +

+

Maximum number of render targets that can be set on a framebuffer.

+
+
+

+ #define CUBOS_CORE_GL_MAX_TEXTURE_2D_ARRAY_SIZE + +

+

Maximum number of textures on a 2D texture array.

+
+
+

+ #define CUBOS_CORE_GL_MAX_CUBEMAP_ARRAY_SIZE + +

+

Maximum number of cube maps on a cubemap array.

+
+
+

+ #define CUBOS_CORE_GL_MAX_MIP_LEVEL_COUNT + +

+

Maximum mip level count.

+
+
+

+ #define CUBOS_CORE_GL_MAX_CONSTANT_BUFFER_ELEMENT_NAME_SIZE + +

+

Maximum constant buffer element name size.

+
+
+

+ #define CUBOS_CORE_GL_MAX_CONSTANT_BUFFER_ELEMENT_COUNT + +

+

Maximum constant buffer element count.

+
+
+

+ #define CUBOS_CORE_GL_MAX_VERTEX_ARRAY_ELEMENT_COUNT + +

+

Maximum number of vertex array elements.

+
+
+

+ #define CUBOS_CORE_GL_MAX_VERTEX_ARRAY_BUFFER_COUNT + +

+

Maximum number of buffers on a vertex array.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__core-io.html b/docs-preview/pr-1032/group__core-io.html new file mode 100644 index 000000000..fa825f549 --- /dev/null +++ b/docs-preview/pr-1032/group__core-io.html @@ -0,0 +1,703 @@ + + + + + Core » Input and output module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Core » + Input and output module

+

Provides a window API abstraction.

+ +
+

Files

+
+
file cursor.hpp
+
Class cubos::core::io::Cursor.
+
file gamepad.hpp
+
Struct cubos::core::io::GamepadState and related enums.
+
file keyboard.hpp
+
Enums cubos::core::io::Key and cubos::core::io::Modifiers.
+
file window.hpp
+
Class cubos::core::io::Window and related types.
+
+
+
+

Classes

+
+
+ class cubos::core::io::Cursor +
+
Handle for a custom mouse cursor.
+
+ struct cubos::core::io::GamepadState +
+
Holds the state of a gamepad.
+
+ struct cubos::core::io::KeyWithModifiers +
+
Keyboard key code and modifier flags.
+
+ struct cubos::core::io::KeyEvent +
+
Event sent when a key is pressed or released.
+
+ struct cubos::core::io::ModifiersEvent +
+
Event sent when the modifiers change.
+
+ struct cubos::core::io::MouseButtonEvent +
+
Event sent when a mouse button state changes.
+
+ struct cubos::core::io::MouseMoveEvent +
+
Event sent when the mouse cursor moves.
+
+ struct cubos::core::io::MouseScrollEvent +
+
Event sent when the mouse wheel is scrolled.
+
+ struct cubos::core::io::ResizeEvent +
+
Event sent when the window framebuffer is resized.
+
+ struct cubos::core::io::TextEvent +
+
Event sent when a unicode character is input.
+
+ struct cubos::core::io::GamepadConnectionEvent +
+
Event sent when a gamepad is connected or disconnected.
+
+ class cubos::core::io::BaseWindow +
+
Interface used to wrap low-level window API implementations.
+
+
+
+

Enums

+
+
+ enum class GamepadButton { Invalid = -1, + A, + B, + X, + Y, + LBumper, + RBumper, + Back, + Start, + Guide, + LThumb, + RThumb, + Up, + Right, + Down, + Left, + Count } +
+
Gamepad buttons.
+
+ enum class GamepadAxis { Invalid = -1, + LX, + LY, + RX, + RY, + LTrigger, + RTrigger, + Count } +
+
Gamepad axes.
+
+ enum class Key { Invalid = -1, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + T, + U, + V, + W, + X, + Y, + Z, + Num0, + Num1, + Num2, + Num3, + Num4, + Num5, + Num6, + Num7, + Num8, + Num9, + Escape, + LControl, + LShift, + LAlt, + LSystem, + RControl, + RShift, + RAlt, + RSystem, + Menu, + LBracket, + RBracket, + SemiColon, + Comma, + Period, + Quote, + Slash, + BackSlash, + Tilde, + Equal, + Dash, + Space, + Return, + BackSpace, + Tab, + PageUp, + PageDown, + End, + Home, + Insert, + Delete, + Add, + Subtract, + Multiply, + Divide, + Left, + Right, + Up, + Down, + Numpad0, + Numpad1, + Numpad2, + Numpad3, + Numpad4, + Numpad5, + Numpad6, + Numpad7, + Numpad8, + Numpad9, + F1, + F2, + F3, + F4, + F5, + F6, + F7, + F8, + F9, + F10, + F11, + F12, + Pause, + Count } +
+
Keyboard key codes enum.
+
+ enum class Modifiers { None = 0, + Control = 1, + Shift = 2, + Alt = 4, + System = 8 } +
+
Keyboard modifier flags enum.
+
+ enum class MouseButton { Invalid = -1, + Left, + Right, + Middle, + Extra1, + Extra2 } +
+
Mouse buttons enum.
+
+ enum class MouseAxis { X, + Y, + Scroll } +
+
Mouse axes enums.
+
+ enum class MouseState { Default, + Locked, + Hidden } +
+
Possible mouse states.
+
+
+
+

Typedefs

+
+
+ using WindowEvent = std::variant<KeyEvent, ModifiersEvent, MouseButtonEvent, MouseMoveEvent, MouseScrollEvent, ResizeEvent, TextEvent, GamepadConnectionEvent> +
+
Variant that can hold any of the window events.
+
+ using Window = std::shared_ptr<BaseWindow> +
+
Handle to a window.
+
+
+
+

Functions

+
+
+ auto gamepadButtonToString(GamepadButton button) -> std::string +
+
Converts a GamepadButton enum to a string.
+
+ auto stringToGamepadButton(const std::string& str) -> GamepadButton +
+
Converts a string to a GamepadButton.
+
+ auto gamepadAxisToString(GamepadAxis axis) -> std::string +
+
Convert a GamepadAxis to a string.
+
+ auto stringToGamepadAxis(const std::string& str) -> GamepadAxis +
+
Convert a string to a GamepadAxis.
+
+ auto openWindow(const std::string& title = "CUBOS.", + const glm::ivec2& size = {800, 600}) -> Window +
+
Opens a new window.
+
+ auto mouseButtonToString(MouseButton button) -> std::string +
+
Converts a MouseButton enum to a string.
+
+ auto stringToMouseButton(const std::string& str) -> MouseButton +
+
Convert a string to a MouseButton enum.
+
+
+
+

Enum documentation

+
+

+ enum class GamepadButton + +

+

Gamepad buttons.

+
+
+

+ enum class GamepadAxis + +

+

Gamepad axes.

+
+
+

+ enum class Key + +

+

Keyboard key codes enum.

+
+
+

+ enum class Modifiers + +

+

Keyboard modifier flags enum.

+
+
+

+ enum class MouseButton + +

+

Mouse buttons enum.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Enumerators
Invalid +

Used for unknown mouse buttons.

+
Left +
Right +
Middle +
Extra1 +
Extra2 +
+
+
+

+ enum class MouseAxis + +

+

Mouse axes enums.

+
+
+

+ enum class MouseState + +

+

Possible mouse states.

+ + + + + + + + + + + + + + + + +
Enumerators
Default +

Default mouse state, mouse will function as is specified by the OS.

+
Locked +

Mouse cursor will be hidden and locked to the center of the window, useful for control schemes that require infinite mouse movement.

+
Hidden +

Mouse cursor will be hidden when over the window, otherwise functioning in the same way as MouseState::Default.

+
+
+
+
+

Typedef documentation

+
+

+ using WindowEvent = std::variant<KeyEvent, ModifiersEvent, MouseButtonEvent, MouseMoveEvent, MouseScrollEvent, ResizeEvent, TextEvent, GamepadConnectionEvent> + +

+

Variant that can hold any of the window events.

+
+
+

+ using Window = std::shared_ptr<BaseWindow> + +

+

Handle to a window.

+ +
+
+
+

Function documentation

+
+

+ std::string gamepadButtonToString(GamepadButton button) + +

+

Converts a GamepadButton enum to a string.

+ + + + + + + + + + + + + + + + +
Parameters
buttonButton to convert.
ReturnsString representation.
+
+
+

+ GamepadButton stringToGamepadButton(const std::string& str) + +

+

Converts a string to a GamepadButton.

+ + + + + + + + + + + + + + + + +
Parameters
strString to convert.
ReturnsButton.
+
+
+

+ std::string gamepadAxisToString(GamepadAxis axis) + +

+

Convert a GamepadAxis to a string.

+ + + + + + + + + + + + + + + + +
Parameters
axisAxis to convert.
ReturnsString representation.
+
+
+

+ GamepadAxis stringToGamepadAxis(const std::string& str) + +

+

Convert a string to a GamepadAxis.

+ + + + + + + + + + + + + + + + +
Parameters
strString to convert.
ReturnsAxis.
+
+
+

+ Window openWindow(const std::string& title = "CUBOS.", + const glm::ivec2& size = {800, 600}) + +

+

Opens a new window.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
titleWindow title.
sizeWindow size, in screen coordinates.
ReturnsNew window, or nullptr on failure.
+
+
+

+ std::string mouseButtonToString(MouseButton button) + +

+

Converts a MouseButton enum to a string.

+ + + + + + + + + + + + + + + + +
Parameters
buttonMouseButton to convert.
ReturnsString representation.
+
+
+

+ MouseButton stringToMouseButton(const std::string& str) + +

+

Convert a string to a MouseButton enum.

+ + + + + + + + + + + + + + + + +
Parameters
strThe string to convert.
ReturnsMouseButton.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__core-memory.html b/docs-preview/pr-1032/group__core-memory.html new file mode 100644 index 000000000..ebd25ba40 --- /dev/null +++ b/docs-preview/pr-1032/group__core-memory.html @@ -0,0 +1,530 @@ + + + + + Core » Memory module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Core » + Memory module

+

Provides a stream library and memory utilities.

+ +
+

Files

+
+
file any_value.hpp
+
Class cubos::core::memory::AnyValue.
+
file any_vector.hpp
+
Class cubos::core::memory::AnyVector.
+
file buffer_stream.hpp
+
Class cubos::core::memory::BufferStream.
+
file endianness.hpp
+
Endianness utility functions.
+
file function.hpp
+
Class cubos::core::memory::Function.
+
file guards.hpp
+
Classes cubos::core::memory::ReadGuard and cubos::core::memory::WriteGuard.
+
file move.hpp
+
Functions cubos::core::memory::move and cubos::core::memory::forward.
+
file standard_stream.hpp
+
Class cubos::core::memory::StandardStream.
+
file stream.hpp
+
Class cubos::core::memory::Stream.
+
file type_map.hpp
+
Class cubos::core::memory::TypeMap.
+
file unordered_bimap.hpp
+
Class cubos::core::memory::UnorderedBimap.
+
+
+
+

Classes

+
+
+ class cubos::core::memory::AnyValue +
+
Stores a blob of a given reflected type.
+
+ class cubos::core::memory::AnyVector +
+
Stores a dynamically sized array of blobs of a given reflected type.
+
+ class cubos::core::memory::BufferStream +
+
Stream implementation which writes to/reads from a buffer.
+
+
template<typename R, typename... Ts>
+ class cubos::core::memory::Function<R(Ts...)> +
+
Generic function pointer which can also store capturing lambda functions.
+
+
template<typename T, typename Lock>
+ class cubos::core::memory::ReadGuard +
+
Provides safe read-only access to an object using a lock.
+
+
template<typename T, typename Lock>
+ class cubos::core::memory::WriteGuard +
+
Provides safe read-write access to an object using a lock.
+
+ class cubos::core::memory::StandardStream +
+
Stream implementation which wraps a libc file pointer.
+
+ class cubos::core::memory::Stream +
+
Interface class for memory streams. Abstracts away sources or destinations of data.
+
+
template<typename V>
+ class cubos::core::memory::TypeMap +
+
A map that stores values of type V, using reflection types as keys.
+
+
template<typename L, typename R, typename LHash = std::hash<L>, typename RHash = std::hash<R>>
+ class cubos::core::memory::UnorderedBimap +
+
A bidirectional hash table.
+
+
+
+

Enums

+
+
+ enum class SeekOrigin { Begin, + Current, + End } +
+
Stream seek origin.
+
+
+
+

Functions

+
+
+
template<typename T>
+ auto swapBytes(T value) -> T +
+
Swaps the bytes of a value, changing its endianness.
+
+ auto isLittleEndian() -> bool +
+
Checks if the current platform is little endian.
+
+
template<typename T>
+ auto fromLittleEndian(T value) -> T +
+
Converts a value from little endianness to local endianness.
+
+
template<typename T>
+ auto toLittleEndian(T value) -> T +
+
Converts a value from local endianness to little endianness.
+
+
template<typename T>
+ auto fromBigEndian(T value) -> T +
+
Converts a value from big endianness to local endianness.
+
+
template<typename T>
+ auto toBigEndian(T value) -> T +
+
Converts a value from local endianness to big endianness.
+
+
template<typename T>
+ auto move(T&& value) -> RemoveReference<T>::Type&& noexcept +
+
Returns an R-value reference to the given value.
+
+
template<typename T>
+ auto forward(typename RemoveReference<T>::Type& argument) -> T&& noexcept +
+
Used to cast a templated function parameter to the value category the caller used to pass it, which allows rvalues to be passed as rvalues and lvalues as lvalues.
+
+
+
+

Enum documentation

+
+

+ enum class SeekOrigin + +

+

Stream seek origin.

+
+
+
+

Function documentation

+
+

+ +
+ template<typename T> +
+ T swapBytes(T value) +

+

Swaps the bytes of a value, changing its endianness.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TValue type.
Parameters
valueValue to swap.
ReturnsSwapped value.
+
+
+

+ bool isLittleEndian() + +

+

Checks if the current platform is little endian.

+ + + + + + + +
ReturnsWhether its little endian.
+
+
+

+ +
+ template<typename T> +
+ T fromLittleEndian(T value) +

+

Converts a value from little endianness to local endianness.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TValue type.
Parameters
valueValue to convert.
ReturnsConverted value.
+
+
+

+ +
+ template<typename T> +
+ T toLittleEndian(T value) +

+

Converts a value from local endianness to little endianness.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TValue type.
Parameters
valueValue to convert.
ReturnsConverted value.
+
+
+

+ +
+ template<typename T> +
+ T fromBigEndian(T value) +

+

Converts a value from big endianness to local endianness.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TValue type.
Parameters
valueValue to convert.
ReturnsConverted value.
+
+
+

+ +
+ template<typename T> +
+ T toBigEndian(T value) +

+

Converts a value from local endianness to big endianness.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TValue type.
Parameters
valueValue to convert.
ReturnsConverted value.
+
+
+

+ +
+ template<typename T> +
+ RemoveReference<T>::Type&& move(T&& value) noexcept +

+

Returns an R-value reference to the given value.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TValue type.
Parameters
valueValue to move.
ReturnsMoved value.
+ +
+
+

+ +
+ template<typename T> +
+ T&& forward(typename RemoveReference<T>::Type& argument) noexcept +

+

Used to cast a templated function parameter to the value category the caller used to pass it, which allows rvalues to be passed as rvalues and lvalues as lvalues.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TArgument type.
Parameters
argumentArgument to forward.
ReturnsForwarded argument.
+ +
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__core-reflection.html b/docs-preview/pr-1032/group__core-reflection.html new file mode 100644 index 000000000..3c88679f5 --- /dev/null +++ b/docs-preview/pr-1032/group__core-reflection.html @@ -0,0 +1,487 @@ + + + + + Core » Reflection module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Core » + Reflection module

+

Provides utilities useful for handling type-erased data.

+ + +
+

Files

+
+
file comparison.hpp
+
Function cubos::core::reflection::compare.
+
file cstring.hpp
+
Reflection declaration for C-strings.
+
file glm.hpp
+
Reflection declarations for external glm types.
+
file map.hpp
+
Reflection declaration for std::map.
+
file primitives.hpp
+
Reflection declarations for primitive types.
+
file string.hpp
+
Reflection declaration for std::string.
+
file string_view.hpp
+
Reflection declaration for std::string_view.
+
file unordered_map.hpp
+
Reflection declaration for std::unordered_map.
+
file uuid.hpp
+
Reflection declaration for uuids::uuid.
+
file vector.hpp
+
Reflection declaration for std::vector.
+
file reflect.hpp
+
Function cubos::core::reflection::reflect and related macros.
+
file array.hpp
+
Class cubos::core::reflection::ArrayTrait.
+
file constructible.hpp
+
Class cubos::core::reflection::ConstructibleTrait.
+
file constructible_utils.hpp
+
Utilities for cubos::core::reflection::ConstructibleTrait.
+
file dictionary.hpp
+
Class cubos::core::reflection::DictionaryTrait.
+
file enum.hpp
+
Class cubos::core::reflection::EnumTrait.
+
file fields.hpp
+
Class cubos::core::reflection::FieldsTrait.
+
file mask.hpp
+
Class cubos::core::reflection::MaskTrait.
+
file nullable.hpp
+
Class cubos::core::reflection::NullableTrait.
+
file string_conversion.hpp
+
Class cubos::core::reflection::StringConversionTrait.
+
file type.hpp
+
Class cubos::core::reflection::Type.
+
file type_registry.hpp
+
Class cubos::core::reflection::TypeRegistry.
+
+
+
+

Classes

+
+
+
template<typename T>
+ struct cubos::core::reflection::Reflect +
+
Defines the reflection function for the given type T.
+
+ class cubos::core::reflection::ArrayTrait +
+
Exposes array-like functionality of a type.
+
+ class cubos::core::reflection::ConstructibleTrait +
+
Describes how a reflected type may be constructed and destructed.
+
+ class cubos::core::reflection::DictionaryTrait +
+
Exposes dictionary-like functionality of a type.
+
+ class cubos::core::reflection::EnumTrait +
+
Provides enumeration functionality to an enumerated type.
+
+ class cubos::core::reflection::FieldsTrait +
+
Describes the fields of a reflected type.
+
+ class cubos::core::reflection::MaskTrait +
+
Provides mask functionality to an enum mask type.
+
+ class cubos::core::reflection::NullableTrait +
+
Used to manipulate values of null-representable types.
+
+ class cubos::core::reflection::StringConversionTrait +
+
Stores functions for converting a type to and from a string.
+
+ class cubos::core::reflection::Type +
+
Describes a reflected type.
+
+ class cubos::core::reflection::TypeRegistry +
+
Stores a set of types which can be accessed by name.
+
+
+
+

Functions

+
+
+
template<typename T>
+ auto reflect() -> const Type& +
+
Reflects the given type T.
+
+
template<typename T>
+ auto autoConstructibleTrait() -> ConstructibleTrait +
+
Returns a ConstructibleTrait with the default, copy and move constructors, set only if the type has them.
+
+
+
+

Defines

+
+
+ #define CUBOS_PACK(...) +
+
Helper macro used to pass arguments with commas to other macros, wrapped in parentheses.
+
+ #define CUBOS_REFLECT +
+
Declares a reflection method.
+
+ #define CUBOS_REFLECT_IMPL(T) +
+
Defines a reflection method.
+
+ #define CUBOS_REFLECT_EXTERNAL_DECL_TEMPLATE(T) +
+
Declares a specialization of cubos::core::reflection::Reflect for a templated type.
+
+ #define CUBOS_REFLECT_EXTERNAL_DECL(T) +
+
Declares a specialization of cubos::core::reflection::Reflect for a type.
+
+ #define CUBOS_REFLECT_EXTERNAL_IMPL(T) +
+
Implements a specialization of cubos::core::reflection::Reflect for a type.
+
+ #define CUBOS_REFLECT_EXTERNAL_TEMPLATE(args, + T) +
+
Both declares and implements a specialization of cubos::core::reflection::Reflect for a type.
+
+
+
+

Function documentation

+
+

+ +
+ template<typename T> +
+ const Type& reflect() +

+

Reflects the given type T.

+ + + + + + + + + + + + + + + + +
Template parameters
TType to reflect.
ReturnsType information.
+

Fails to compile if the type does not implement reflection, or, in the case of external types, if its reflection specialization has not been included.

Internally, this function stores a static instance of the reflection data for the given type. Thus the reflection data is only initialized once, the first time this function is called, which means that the returned reference can be safely used as an identifier for the type.

The reflection data is obtained by calling the Reflect<T>::type() function.

+
+
+

+ +
+ template<typename T> +
+ ConstructibleTrait autoConstructibleTrait() +

+

Returns a ConstructibleTrait with the default, copy and move constructors, set only if the type has them.

+ + + + + + + + + + + + + + + + +
Template parameters
TType.
ReturnsConstructibleTrait.
+ +
+
+
+

Define documentation

+
+

+ #define CUBOS_PACK(...) + +

+

Helper macro used to pass arguments with commas to other macros, wrapped in parentheses.

+
#define FOO(T) T foo;
+FOO(int); // expands to int foo;
+FOO(std::map<int, int>); // error: too many arguments to macro 'FOO'
+
+// Instead, use CUBOS_PACK:
+#define FOO(T) CUBOS_PACK T foo;
+FOO((int)); // expands to CUBOS_PACK(int) foo, which expands to int foo;
+FOO((std::map<int, int>)); // expands to CUBOS_PACK(std::map<int, int>) foo, which expands to
+                           // std::map<int, int> foo;
+
+
+

+ #define CUBOS_REFLECT + +

+

Declares a reflection method.

+
// my_type.hpp
+#include <cubos/core/reflection/reflect.hpp>
+
+struct MyType
+{
+    CUBOS_REFLECT; // declares `static const Type& reflect()`
+};
+
+
+

+ #define CUBOS_REFLECT_IMPL(T) + +

+

Defines a reflection method.

+ + + + + + + + + + +
Parameters
TType to reflect.
+
// my_type.cpp
+#include "my_type.hpp"
+
+CUBOS_REFLECT_IMPL(MyType) // defines `const Type& MyType::reflect()`
+{
+    return /* create your type here */;
+}
+
+
+

+ #define CUBOS_REFLECT_EXTERNAL_DECL_TEMPLATE(T) + +

+

Declares a specialization of cubos::core::reflection::Reflect for a templated type.

+ + + + + + + + + + +
Parameters
TType to reflect.
+
// templated_type_reflection.hpp
+#include <cubos/core/reflection/reflect.hpp>
+
+template <typename T>
+CUBOS_REFLECT_EXTERNAL_DECL_TEMPLATE(TemplatedType<T>);
+
+
+

+ #define CUBOS_REFLECT_EXTERNAL_DECL(T) + +

+

Declares a specialization of cubos::core::reflection::Reflect for a type.

+ + + + + + + + + + +
Parameters
TType to reflect.
+
// not_my_type_reflection.hpp
+#include <cubos/core/reflection/reflect.hpp>
+
+CUBOS_REFLECT_EXTERNAL_DECL(NotMyType);
+
+
+

+ #define CUBOS_REFLECT_EXTERNAL_IMPL(T) + +

+

Implements a specialization of cubos::core::reflection::Reflect for a type.

+ + + + + + + + + + +
Parameters
TType to reflect.
+
// not_my_type_reflection.cpp
+#include "not_my_type_reflection.hpp"
+
+CUBOS_REFLECT_EXTERNAL_IMPL(NotMyType)
+{
+    return /* create your type here */;
+}
// templated_type_reflection.hpp
+template <typename T>
+CUBOS_REFLECT_EXTERNAL_IMPL(TemplatedType<T>)
+{
+    return /* create your type here */;
+}
+
+
+

+ #define CUBOS_REFLECT_EXTERNAL_TEMPLATE(args, + T) + +

+

Both declares and implements a specialization of cubos::core::reflection::Reflect for a type.

+ + + + + + + + + + + + + + +
Parameters
argsTemplate parameters, wrapped in parentheses.
TType to reflect, wrapped in parentheses.
+
// templated_type_reflection.hpp
+#include <cubos/core/reflection/reflect.hpp>
+
+CUBOS_REFLECT_EXTERNAL_TEMPLATE((typename T), (TemplatedType<T>))
+{
+    return /* create your type here */;
+}
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__core.html b/docs-preview/pr-1032/group__core.html new file mode 100644 index 000000000..5d8c495c4 --- /dev/null +++ b/docs-preview/pr-1032/group__core.html @@ -0,0 +1,586 @@ + + + + + Core module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Core module

+

CUBOS. core library.

+ +

The core library contains loose utilities and functionality on which the rest of the CUBOS. libraries and applications are built on. Lives in the cubos::core namespace.

This library can be further divided into modules, which are documented in their respective module pages. Each of these modules has its own namespace and directory in the source tree. For example, the ECS module lives in the cubos::core::ecs namespace.

+
+

Modules

+
+
module Audio
+
Provides audio functionality.
+
module Data
+
Provides filesystem and serialization utilities.
+
module ECS
+
Entity Component System library.
+
module Geometry
+
Provides geometry utilities.
+
module Graphics
+
Provides a graphics API abstraction.
+
module Input and output
+
Provides a window API abstraction.
+
module Memory
+
Provides a stream library and memory utilities.
+
module Reflection
+
Provides utilities useful for handling type-erased data.
+
+
+
+

Files

+
+
file log.hpp
+
Logging and assertion macros.
+
file thread_pool.hpp
+
Class cubos::core::ThreadPool.
+
+
+
+

Classes

+
+
+ class cubos::core::Logger +
+
Singleton which holds the logging state.
+
+ class cubos::core::ThreadPool +
+
Manages a pool of threads, to which tasks can be submitted.
+
+
+
+

Defines

+
+
+ #define CUBOS_LOG_LEVEL_TRACE +
+
Trace log level, lowest log level. Very verbose.
+
+ #define CUBOS_LOG_LEVEL_DEBUG +
+
Debug log level. Contains messages useful for debugging, but which are not necessary in release builds.
+
+ #define CUBOS_LOG_LEVEL_INFO +
+
Information log level. Contains important events that are not errors.
+
+ #define CUBOS_LOG_LEVEL_WARN +
+
Warn log level. Contains events that are not errors, but which are unexpected and may be problematic.
+
+ #define CUBOS_LOG_LEVEL_ERROR +
+
Error log level. Contains errors which are recoverable from.
+
+ #define CUBOS_LOG_LEVEL_CRITICAL +
+
Critical log level, highest log level. Contains errors which are unrecoverable from.
+
+ #define CUBOS_LOG_LEVEL_OFF +
+
Off log level, disables all logging.
+
+ #define CUBOS_LOG_LEVEL +
+
Log level to compile in.
+
+ #define CUBOS_TRACE(...) +
+
Used for logging very verbose information.
+
+ #define CUBOS_DEBUG(...) +
+
Used for logging information which is useful for debugging but not necessary in release builds.
+
+ #define CUBOS_INFO(...) +
+
Used for logging information which is useful in release builds.
+
+ #define CUBOS_WARN(...) +
+
Used for logging unexpected events.
+
+ #define CUBOS_ERROR(...) +
+
Used for logging recoverable errors.
+
+ #define CUBOS_CRITICAL(...) +
+
Used for logging unrecoverable errors.
+
+ #define CUBOS_LOG(level, + ...) +
+
Used for logging messages.
+
+ #define CUBOS_FAIL(...) +
+
Aborts a program, optionally printing a critical error message.
+
+ #define CUBOS_UNREACHABLE(...) +
+
Marks a code path as supposedly unreachable. Aborts the program when reached.
+
+ #define CUBOS_TODO(...) +
+
Marks a code path as unfinished. Aborts the program when reached.
+
+ #define CUBOS_ASSERT(cond, + ...) +
+
Asserts that a condition is true, aborting the program if it is not.
+
+ #define CUBOS_ASSERT_IMP(cond, + cons, + ...) +
+
Asserts that an implication is true, aborting the program if it is not.
+
+ #define CUBOS_DEBUG_ASSERT(cond, + ...) +
+
In debug builds asserts that a condition is true, aborting the program if it is not.
+
+
+
+

Define documentation

+
+

+ #define CUBOS_LOG_LEVEL_TRACE + +

+

Trace log level, lowest log level. Very verbose.

+ +
+
+

+ #define CUBOS_LOG_LEVEL_DEBUG + +

+

Debug log level. Contains messages useful for debugging, but which are not necessary in release builds.

+ +
+
+

+ #define CUBOS_LOG_LEVEL_INFO + +

+

Information log level. Contains important events that are not errors.

+ +
+
+

+ #define CUBOS_LOG_LEVEL_WARN + +

+

Warn log level. Contains events that are not errors, but which are unexpected and may be problematic.

+ +
+
+

+ #define CUBOS_LOG_LEVEL_ERROR + +

+

Error log level. Contains errors which are recoverable from.

+ +
+
+

+ #define CUBOS_LOG_LEVEL_CRITICAL + +

+

Critical log level, highest log level. Contains errors which are unrecoverable from.

+ +
+
+

+ #define CUBOS_LOG_LEVEL_OFF + +

+

Off log level, disables all logging.

+ +
+
+

+ #define CUBOS_LOG_LEVEL + +

+

Log level to compile in.

+

This macro essentially controls the minimum log level that will be compiled into the binary.

Should be set to one of the following:

By default, on debug builds, this is set to CUBOS_LOG_LEVEL_TRACE. On release builds, this is set to CUBOS_LOG_LEVEL_INFO.

+
+
+

+ #define CUBOS_TRACE(...) + +

+

Used for logging very verbose information.

+ + + + + + + + + + +
Parameters
...Format string and arguments.
+ +
+
+

+ #define CUBOS_DEBUG(...) + +

+

Used for logging information which is useful for debugging but not necessary in release builds.

+ + + + + + + + + + +
Parameters
...Format string and arguments.
+ +
+
+

+ #define CUBOS_INFO(...) + +

+

Used for logging information which is useful in release builds.

+ + + + + + + + + + +
Parameters
...Format string and arguments.
+ +
+
+

+ #define CUBOS_WARN(...) + +

+

Used for logging unexpected events.

+ + + + + + + + + + +
Parameters
...Format string and arguments.
+ +
+
+

+ #define CUBOS_ERROR(...) + +

+

Used for logging recoverable errors.

+ + + + + + + + + + +
Parameters
...Format string and arguments.
+ +
+
+

+ #define CUBOS_CRITICAL(...) + +

+

Used for logging unrecoverable errors.

+ + + + + + + + + + +
Parameters
...Format string and arguments.
+ +
+
+

+ #define CUBOS_LOG(level, + ...) + +

+

Used for logging messages.

+ + + + + + + + + + + + + + +
Parameters
levelLog level.
...Format string and arguments.
+ +
+
+

+ #define CUBOS_FAIL(...) + +

+

Aborts a program, optionally printing a critical error message.

+ + + + + + + + + + +
Parameters
...Optional format string and arguments.
+
+
+

+ #define CUBOS_UNREACHABLE(...) + +

+

Marks a code path as supposedly unreachable. Aborts the program when reached.

+ + + + + + + + + + +
Parameters
...Optional format string and arguments.
+
+
+

+ #define CUBOS_TODO(...) + +

+

Marks a code path as unfinished. Aborts the program when reached.

+ + + + + + + + + + +
Parameters
...Optional format string and arguments.
+
+
+

+ #define CUBOS_ASSERT(cond, + ...) + +

+

Asserts that a condition is true, aborting the program if it is not.

+ + + + + + + + + + + + + + +
Parameters
condCondition to assert.
...Optional format string and arguments.
+
+
+

+ #define CUBOS_ASSERT_IMP(cond, + cons, + ...) + +

+

Asserts that an implication is true, aborting the program if it is not.

+ + + + + + + + + + + + + + + + + + +
Parameters
condImplication condition.
consImplication consequence.
...Optional format string and arguments.
+
+
+

+ #define CUBOS_DEBUG_ASSERT(cond, + ...) + +

+

In debug builds asserts that a condition is true, aborting the program if it is not.

+ + + + + + + + + + + + + + +
Parameters
condCondition to assert.
...Optional format string and arguments.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__engine.html b/docs-preview/pr-1032/group__engine.html new file mode 100644 index 000000000..ddb29f191 --- /dev/null +++ b/docs-preview/pr-1032/group__engine.html @@ -0,0 +1,170 @@ + + + + + Engine module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Engine module

+

CUBOS. engine library.

+ +

The engine library is built on top of the core library and contains code exclusive to game execution. This includes asset management, rendering and physics. It is built around the Cubos class and designed to be as modular as possible. Each sub-module corresponds to a plugin, or a set of plugins.

The library re-exports some of the core library functionality for convenience such that the user doesn't have to use the cubos::core namespace directly very often.

+
+

Modules

+
+
module Assets
+
Adds asset management to CUBOS.
+
module Collisions
+
Adds collision detection to CUBOS.
+
module Fixed Time Step
+
Adds a tag which makes its systems run at a fixed frame rate.
+
module Gizmos
+
Used to draw gizmos helpful for debugging and tools.
+
module ImGui integration
+
Initializes and configures ImGui for CUBOS.
+
module Input
+
Adds input handling to CUBOS.
+
module Physics
+
Creates and handles the physics simulation.
+
module Renderer
+
Creates and handles the lifecycle of a renderer.
+
module Scene
+
Adds scenes to CUBOS.
+
module ScreenPicker
+
Used to select entities and gizmos by clicking them.
+
module Settings
+
Adds and manages settings.
+
module Splitscreen
+
Adds viewport to all active cameras to achieve a splitscreen layout.
+
module Transform
+
Adds transform components which assign positions, rotations and scaling to entities.
+
module Free Camera
+
Adds the free camera controller component, which locks the mouse and moves an entity.
+
module Voxels
+
Adds grid and palette assets to CUBOS.
+
module Window
+
Creates and handles the lifecycle of a window.
+
+
+
+

Files

+
+
file cubos.hpp
+
Class cubos::engine::Cubos.
+
file settings.hpp
+
Class cubos::engine::Settings.
+
+
+
+

Classes

+
+
+ class cubos::engine::Settings +
+
Stores settings as key-value pairs and provides methods to retrieve them.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__fixed-step-plugin.html b/docs-preview/pr-1032/group__fixed-step-plugin.html new file mode 100644 index 000000000..763c21a33 --- /dev/null +++ b/docs-preview/pr-1032/group__fixed-step-plugin.html @@ -0,0 +1,166 @@ + + + + + Engine » Fixed Time Step module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Engine » + Fixed Time Step module

+

Adds a tag which makes its systems run at a fixed frame rate.

+ +

Resources

  • FixedDeltaTime - holds the value of the fixed delta for the physics update.

Tags

  • cubos.fixedStep
+
+

Files

+
+
file fixed_delta_time.hpp
+
Resource cubos::engine::FixedDeltaTime.
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Classes

+
+
+ struct cubos::engine::FixedDeltaTime +
+
Resource which holds the value of the fixed delta for the fixedStep plugin.
+
+
+
+

Functions

+
+
+ void fixedStepPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void fixedStepPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__free-camera-plugin.html b/docs-preview/pr-1032/group__free-camera-plugin.html new file mode 100644 index 000000000..41c8f62ef --- /dev/null +++ b/docs-preview/pr-1032/group__free-camera-plugin.html @@ -0,0 +1,153 @@ + + + + + Engine » Free Camera module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Engine » + Free Camera module

+

Adds the free camera controller component, which locks the mouse and moves an entity.

+ +

Components

+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Functions

+
+
+ void freeCameraPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void freeCameraPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__gizmos-plugin.html b/docs-preview/pr-1032/group__gizmos-plugin.html new file mode 100644 index 000000000..cfe8a64f6 --- /dev/null +++ b/docs-preview/pr-1032/group__gizmos-plugin.html @@ -0,0 +1,168 @@ + + + + + Engine » Gizmos module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Engine » + Gizmos module

+

Used to draw gizmos helpful for debugging and tools.

+ +

Resources

  • Gizmos - used to queue gizmo draw commands.

Startup tags

  • cubos.gizmos.init - the gizmos renderer is initialized, after cubos.window.init

Tags

  • cubos.gizmos.input - gizmos interaction is handled, after cubos.window.poll and before cubos.gizmos.draw.
  • cubos.gizmos.draw - queued gizmos are rendered to the window, after cubos.renderer.draw and before cubos.window.render.
  • cubos.gizmos.pick - the ScreenPicker resource is accessed to detect gizmos at mouse coordinates, after cubos.gizmos.draw

Dependencies

+
+

Files

+
+
file gizmos.hpp
+
Resource cubos::engine::Gizmos.
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Classes

+
+
+ class cubos::engine::Gizmos +
+
Resource which queues commands for drawing gizmos, basic primitives useful for debugging and tools.
+
+
+
+

Functions

+
+
+ void gizmosPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void gizmosPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__imgui-plugin.html b/docs-preview/pr-1032/group__imgui-plugin.html new file mode 100644 index 000000000..e4076624a --- /dev/null +++ b/docs-preview/pr-1032/group__imgui-plugin.html @@ -0,0 +1,168 @@ + + + + + Engine » ImGui integration module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Engine » + ImGui integration module

+

Initializes and configures ImGui for CUBOS.

+ +

Resources

Startup tags

  • cubos.imgui.init - ImGui is initialized, after cubos.window.init.

Tags

  • cubos.imgui.begin - the ImGui frame begins (after cubos.renderer.draw).
  • cubos.imgui.end - the ImGui frame ends (before cubos.window.render).
  • cubos.imgui - runs between the previous two tags.

Dependencies

+
+

Files

+
+
file data_inspector.hpp
+
Resource cubos::engine::DataInspector.
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Classes

+
+
+ class cubos::engine::DataInspector +
+
Resource which allows the user to inspect or modify any reflectable value on the UI.
+
+
+
+

Functions

+
+
+ void imguiPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void imguiPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__input-plugin.html b/docs-preview/pr-1032/group__input-plugin.html new file mode 100644 index 000000000..3a5bb98eb --- /dev/null +++ b/docs-preview/pr-1032/group__input-plugin.html @@ -0,0 +1,187 @@ + + + + + Engine » Input module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Engine » + Input module

+

Adds input handling to CUBOS.

+ +

Bridges

Events

  • InputEvent - (TODO) emitted when an input event occurs.

Resources

  • Input - stateful input manager, used to query the input state.

Tags

  • cubos.input.update - updates the input state.

Dependencies

+
+

Files

+
+
file action.hpp
+
Class cubos::engine::InputAction.
+
file axis.hpp
+
Class cubos::engine::InputAxis.
+
file bindings.hpp
+
Class cubos::engine::InputBindings.
+
file input.hpp
+
Resource cubos::engine::Input.
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Classes

+
+
+ class cubos::engine::InputAction +
+
Stores the state of a single input action, such as "jump" or "attack".
+
+ class cubos::engine::InputAxis +
+
Stores the state of a single input axis, such as "move forward" or "move right".
+
+ class cubos::engine::InputBindings +
+
Stores the input bindings for a single player.
+
+ class cubos::engine::Input +
+
Resource which stores the input bindings for multiple players.
+
+
+
+

Functions

+
+
+ void inputPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void inputPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__physics-gravity-plugin.html b/docs-preview/pr-1032/group__physics-gravity-plugin.html new file mode 100644 index 000000000..ee004d1fa --- /dev/null +++ b/docs-preview/pr-1032/group__physics-gravity-plugin.html @@ -0,0 +1,176 @@ + + + + + Engine » Physics » Gravity module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Engine » + Physics » + Gravity module

+

Adds gravity to particles.

+ +

Resources

  • Gravity - holds the global value of gravity.
+
+

Files

+
+
file gravity.hpp
+
Gravity plugin, resource cubos::engine::Gravity.
+
+
+
+

Functions

+
+
+ void gravityPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void solverPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void gravityPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+

+ void solverPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__physics-plugin.html b/docs-preview/pr-1032/group__physics-plugin.html new file mode 100644 index 000000000..ee79e364a --- /dev/null +++ b/docs-preview/pr-1032/group__physics-plugin.html @@ -0,0 +1,232 @@ + + + + + Engine » Physics module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Engine » + Physics module

+

Creates and handles the physics simulation.

+ +

Resources

  • Damping - holds the damping value for integration.
  • Substeps - holds the amount of substeps for the physics update.

Components

  • PhysicsBundle - bundle that holds the physics information to give to a new entity.
  • Velocity - holds the information for moving an object straight.
  • Force - holds forces applied on a particle.
  • Impulse - holds impulses applied on a particle.
  • Mass - holds the mass of an object.
  • PreviousPosition - holds the previous position of the entity in a substep.
  • AccumulatedCorrection - holds the corrections accumulated from the constraints solving.

Tags

  • cubos.physics.apply_forces

Dependencies

+
+

Modules

+
+
module Gravity
+
Adds gravity to particles.
+
module Solver
+
Adds solver for constraints.
+
+
+
+

Files

+
+
file accumulated_correction.hpp
+
Component cubos::engine::AccumulatedCorrection.
+
file force.hpp
+
Component cubos::engine::Force.
+
file impulse.hpp
+
Component cubos::engine::Force.
+
file mass.hpp
+
Component cubos::engine::Mass.
+
file previous_position.hpp
+
Component cubos::engine::PreviousPosition.
+
file velocity.hpp
+
Component cubos::engine::Velocity.
+
file physics_bundle.hpp
+
Component cubos::engine::PhysicsBundle.
+
file plugin.hpp
+
Plugin entry point.
+
file damping.hpp
+
Resource cubos::engine::Damping.
+
file gravity.hpp
+
Resource cubos::engine::Gravity.
+
file substeps.hpp
+
Resource cubos::engine::Substeps.
+
+
+
+

Classes

+
+
+ struct cubos::engine::AccumulatedCorrection +
+
Component which holds the corrections accumulated from the constraints solving.
+
+ struct cubos::engine::Force +
+
Component which holds forces applied on a particle.
+
+ struct cubos::engine::Impulse +
+
Component which holds impulses applied on a particle.
+
+ struct cubos::engine::Mass +
+
Component which defines the mass of a particle.
+
+ struct cubos::engine::PreviousPosition +
+
Component which holds the previous position of the entity. Used for the integrator on the update velocity step.
+
+ struct cubos::engine::Velocity +
+
Component which holds velocity and forces applied on a particle.
+
+ struct cubos::engine::PhysicsBundle +
+
Component which encapsulates the creation all components required for physics.
+
+ struct cubos::engine::Damping +
+
Resource which holds the damping value for integration.
+
+ struct cubos::engine::Gravity +
+
Resource which holds the global value of gravity.
+
+ struct cubos::engine::Substeps +
+
Resource which holds the amount of substeps for the physics update.
+
+
+
+

Functions

+
+
+ void physicsPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void physicsPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__physics-solver-plugin.html b/docs-preview/pr-1032/group__physics-solver-plugin.html new file mode 100644 index 000000000..07b4e2093 --- /dev/null +++ b/docs-preview/pr-1032/group__physics-solver-plugin.html @@ -0,0 +1,121 @@ + + + + + Engine » Physics » Solver module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Engine » + Physics » + Solver module

+

Adds solver for constraints.

+ +
+

Files

+
+
file solver.hpp
+
Solver plugin, resource cubos::engine::Solver.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__renderer-plugin.html b/docs-preview/pr-1032/group__renderer-plugin.html new file mode 100644 index 000000000..86ec8dd81 --- /dev/null +++ b/docs-preview/pr-1032/group__renderer-plugin.html @@ -0,0 +1,370 @@ + + + + + Engine » Renderer module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Engine » + Renderer module

+

Creates and handles the lifecycle of a renderer.

+ +

Renders all entities with the RenderableGrid component, using as cameras entities with the Camera component selected by the ActiveCameras resource. Lights are rendered using entities with SpotLight, DirectionalLight or PointLight components.

The rendering environment, such as the ambient lighting and sky color, can be set through the resource RendererEnvironment.

Settings

  • cubos.renderer.ssao.enabled - whether SSAO is enabled.
  • cubos.renderer.bloom.enabled - whether bloom is enabled.

Resources

Components

Startup tags

  • cubos.renderer.init - the renderer is initialized, after cubos.window.init.

Tags

  • cubos.renderer.frame - frame information is collected, after cubos.transform.update.
  • cubos.renderer.draw - frame is rendered to the window, after cubos.renderer.frame and before cubos.window.render.

Dependencies

+
+

Files

+
+
file camera.hpp
+
Component cubos::engine::Camera.
+
file deferred_renderer.hpp
+
Renderer implementation cubos::engine::DeferredRenderer.
+
file directional_light.hpp
+
Component cubos::engine::DirectionalLight.
+
file environment.hpp
+
Resource cubos::engine::RendererEnvironment.
+
file frame.hpp
+
Resource cubos::engine::RendererFrame.
+
file plugin.hpp
+
Plugin entry point, resource cubos::engine::ActiveCameras and components cubos::engine::RenderableGrid and cubos::engine::Camera.
+
file point_light.hpp
+
Component cubos::engine::PointLight.
+
file bloom.hpp
+
Post processing pass implementation cubos::engine::PostProcessingBloom.
+
file copy_pass.hpp
+
Post processing pass implementation cubos::engine::PostProcessingCopy.
+
file manager.hpp
+
Class cubos::engine::PostProcessingManager.
+
file pass.hpp
+
Class cubos::engine::PostProcessingPass.
+
file renderer.hpp
+
Class cubos::engine::BaseRenderer and resource cubos::engine::Renderer.
+
file spot_light.hpp
+
Component cubos::engine::SpotLight.
+
file vertex.hpp
+
Class cubos::engine::VoxelVertex and function cubos::engine::triangulate.
+
file viewport.hpp
+
Component cubos::engine::Viewport.
+
+
+
+

Classes

+
+
+ struct cubos::engine::Camera +
+
Component which defines parameters of a camera used to render the world.
+
+ class cubos::engine::DeferredRenderer +
+
Renderer implementation which uses deferred rendering.
+
+ struct cubos::engine::DirectionalLight +
+
Component which makes an entity behave like a directional light.
+
+ struct cubos::engine::RendererEnvironment +
+
Resource which stores the renderer's ambient light and sky colors.
+
+ class cubos::engine::RendererFrame +
+
Resource which describes a scene to be drawn by the renderer.
+
+ struct cubos::engine::RenderableGrid +
+
Component which makes a voxel grid be rendered by the renderer plugin.
+
+ struct cubos::engine::ActiveCameras +
+
Resource which identifies the camera entities to be used by the renderer.
+
+ struct cubos::engine::ActiveVoxelPalette +
+
Resource which holds an asset handle to the currently active palette.
+
+ struct cubos::engine::PointLight +
+
Component which makes an entity behave like a point light.
+
+ class cubos::engine::PostProcessingBloom +
+
A post processing pass that adds a "bloom" effect to any bright objects in the scene.
+
+ class cubos::engine::PostProcessingCopy +
+
A simple post processing pass that copies the input texture to the output.
+
+ class cubos::engine::PostProcessingManager +
+
Responsible for managing the post processing passes.
+
+ class cubos::engine::PostProcessingPass +
+
A generic post processing pass.
+
+ class cubos::engine::BaseRenderer +
+
Interface which abstracts different rendering methods.
+
+ struct cubos::engine::SpotLight +
+
Component which makes an entity emit a spot light.
+
+ struct cubos::engine::VoxelVertex +
+
Represents a voxel vertex.
+
+ struct cubos::engine::Viewport +
+
Component which defines parameters of a viewport, the actual screen space that will be used by the camera it is attached to. Useful for having multiple camera views shown on screen.
+
+
+
+

Enums

+
+
+ enum class PostProcessingInput { Lighting, + Position, + Normal } +
+
Possible renderer outputs which can then be used as input for a post processing pass.
+
+
+
+

Typedefs

+
+
+ using RendererGrid = std::shared_ptr<impl::RendererGrid> +
+
Handle to a grid uploaded to the GPU, to be used for rendering.
+
+ using Renderer = std::shared_ptr<BaseRenderer> +
+
Resource which is an handle to a generic renderer.
+
+
+
+

Functions

+
+
+ void rendererPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void triangulate(const VoxelGrid& grid, + std::vector<VoxelVertex>& vertices, + std::vector<uint32_t>& indices) +
+
Triangulates a grid of voxels into an indexed mesh.
+
+
+
+

Enum documentation

+
+

+ enum class PostProcessingInput + +

+

Possible renderer outputs which can then be used as input for a post processing pass.

+ + + + + + + + + + + + + + + + +
Enumerators
Lighting +

Renderer output with lighting applied.

+
Position +

GBuffer texture with the world position of the pixels.

+
Normal +

GBuffer texture with the world normal of the pixels.

+
+
+
+
+

Typedef documentation

+
+

+ using RendererGrid = std::shared_ptr<impl::RendererGrid> + +

+

Handle to a grid uploaded to the GPU, to be used for rendering.

+
+
+

+ using Renderer = std::shared_ptr<BaseRenderer> + +

+

Resource which is an handle to a generic renderer.

+
+
+
+

Function documentation

+
+

+ void rendererPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+

+ void triangulate(const VoxelGrid& grid, + std::vector<VoxelVertex>& vertices, + std::vector<uint32_t>& indices) + +

+

Triangulates a grid of voxels into an indexed mesh.

+ + + + + + + + + + + + + + + + + + +
Parameters
gridGrid to triangulate.
verticesVertices of the mesh.
indicesIndices of the mesh.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__scene-plugin.html b/docs-preview/pr-1032/group__scene-plugin.html new file mode 100644 index 000000000..edfcf68cf --- /dev/null +++ b/docs-preview/pr-1032/group__scene-plugin.html @@ -0,0 +1,172 @@ + + + + + Engine » Scene module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Engine » + Scene module

+

Adds scenes to CUBOS.

+ +

Bridges

Dependencies

+
+

Files

+
+
file bridge.hpp
+
Class cubos::engine::SceneBridge.
+
file plugin.hpp
+
Plugin entry point.
+
file scene.hpp
+
Class cubos::engine::Scene.
+
+
+
+

Classes

+
+
+ class cubos::engine::SceneBridge +
+
Bridge which loads and saves Scene assets.
+
+ struct cubos::engine::Scene +
+
Asset equivalent to ECS blueprints - a bundle of entities and their components.
+
+
+
+

Functions

+
+
+ void scenePlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void scenePlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__screen-picker-plugin.html b/docs-preview/pr-1032/group__screen-picker-plugin.html new file mode 100644 index 000000000..ea63c151d --- /dev/null +++ b/docs-preview/pr-1032/group__screen-picker-plugin.html @@ -0,0 +1,168 @@ + + + + + Engine » ScreenPicker module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Engine » + ScreenPicker module

+

Used to select entities and gizmos by clicking them.

+ +

Resources

  • ScreenPicker - provides a texture to store entity and gizmo ids.

Startup tags

  • cubos.screenPicker.init - the ScreenPicker resource is initialized, after cubos.window.init

Tags

  • cubos.screenPicker.clear - the picking texture is cleared
  • cubos.screenPicker.resize - window resize events are handled and the ScreenPicker texture is resized, after cubos.window.poll and before cubos.screenPicker.clear.

Dependencies

+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
file screen_picker.hpp
+
Resource cubos::engine::ScreenPicker.
+
+
+
+

Classes

+
+
+ class cubos::engine::ScreenPicker +
+
Resource which provides a texture to store entity/gizmo ids, for selection with a mouse.
+
+
+
+

Functions

+
+
+ void screenPickerPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void screenPickerPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__settings-plugin.html b/docs-preview/pr-1032/group__settings-plugin.html new file mode 100644 index 000000000..cf058c133 --- /dev/null +++ b/docs-preview/pr-1032/group__settings-plugin.html @@ -0,0 +1,155 @@ + + + + + Engine » Settings module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Engine » + Settings module

+

Adds and manages settings.

+ +

Initially, parses settings from the Arguments resource. Then, the file at settings.path is loaded, as a JSON file. If the file does not exist, it is created. If it can't be parsed, the plugin aborts. Previously set settings will be overriden, and file settings will be overriden by command line arguments.

Settings

  • settings.path - path of the settings file (default: ./settings.json).

Resources

Startup tags

  • cubos.settings - the settings are loaded, overriding values set previously.
+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Functions

+
+
+ void settingsPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void settingsPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__splitscreen-plugin.html b/docs-preview/pr-1032/group__splitscreen-plugin.html new file mode 100644 index 000000000..62849f572 --- /dev/null +++ b/docs-preview/pr-1032/group__splitscreen-plugin.html @@ -0,0 +1,153 @@ + + + + + Engine » Splitscreen module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Engine » + Splitscreen module

+

Adds viewport to all active cameras to achieve a splitscreen layout.

+ +

Dependencies

+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Functions

+
+
+ void splitscreenPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void splitscreenPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__tesseratos-asset-explorer-plugin.html b/docs-preview/pr-1032/group__tesseratos-asset-explorer-plugin.html new file mode 100644 index 000000000..05b363877 --- /dev/null +++ b/docs-preview/pr-1032/group__tesseratos-asset-explorer-plugin.html @@ -0,0 +1,154 @@ + + + + + Tesseratos » Asset explorer module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Tesseratos » + Asset explorer module

+

Allows viewing and selecting assets through a ImGui window.

+ +

Events

Dependencies

+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Functions

+
+
+ void assetExplorerPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void assetExplorerPlugin(cubos::engine::Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__tesseratos-collider-gizmos-plugin.html b/docs-preview/pr-1032/group__tesseratos-collider-gizmos-plugin.html new file mode 100644 index 000000000..1441dd98d --- /dev/null +++ b/docs-preview/pr-1032/group__tesseratos-collider-gizmos-plugin.html @@ -0,0 +1,153 @@ + + + + + Tesseratos » Collider gizmos module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Tesseratos » + Collider gizmos module

+

Draws gizmos for selected colliders.

+ +

Dependencies

+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Functions

+
+
+ void colliderGizmosPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void colliderGizmosPlugin(cubos::engine::Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__tesseratos-debug-camera-plugin.html b/docs-preview/pr-1032/group__tesseratos-debug-camera-plugin.html new file mode 100644 index 000000000..76bd69843 --- /dev/null +++ b/docs-preview/pr-1032/group__tesseratos-debug-camera-plugin.html @@ -0,0 +1,153 @@ + + + + + Tesseratos » Debug camera module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Tesseratos » + Debug camera module

+

Adds a toggleable debug camera.

+ +

Dependencies

+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Functions

+
+
+ void debugCameraPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void debugCameraPlugin(cubos::engine::Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__tesseratos-ecs-statistics-plugin.html b/docs-preview/pr-1032/group__tesseratos-ecs-statistics-plugin.html new file mode 100644 index 000000000..074bc210b --- /dev/null +++ b/docs-preview/pr-1032/group__tesseratos-ecs-statistics-plugin.html @@ -0,0 +1,153 @@ + + + + + Tesseratos » ECS Statistics module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Tesseratos » + ECS Statistics module

+

Shows tons of statistics and information about the internal state of the ECS.

+ +

Dependencies

+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Functions

+
+
+ void ecsStatisticsPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void ecsStatisticsPlugin(cubos::engine::Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__tesseratos-entity-inspector-plugin.html b/docs-preview/pr-1032/group__tesseratos-entity-inspector-plugin.html new file mode 100644 index 000000000..80075d464 --- /dev/null +++ b/docs-preview/pr-1032/group__tesseratos-entity-inspector-plugin.html @@ -0,0 +1,153 @@ + + + + + Tesseratos » Entity inspector module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Tesseratos » + Entity inspector module

+

Allows inspecting and modifying the components of the selected entity through a ImGui window.

+ +

Dependencies

+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Functions

+
+
+ void entityInspectorPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void entityInspectorPlugin(cubos::engine::Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__tesseratos-entity-selector-plugin.html b/docs-preview/pr-1032/group__tesseratos-entity-selector-plugin.html new file mode 100644 index 000000000..37c6a52e6 --- /dev/null +++ b/docs-preview/pr-1032/group__tesseratos-entity-selector-plugin.html @@ -0,0 +1,156 @@ + + + + + Tesseratos » Entity selector module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Tesseratos » + Entity selector module

+

Adds a resource used to select an entity.

+ +

This plugins exists to reduce coupling between plugins. For example, a plugin which allows selecting entities through a ImGui window only needs to depend on this plugin, instead of having to know about all the plugins which care about it. The same applies in the other direction.

Resources

Startup tags

  • cubos.entitySelector.init - the EntitySelector resource is initialized

Tags

  • cubos.entitySelector.input - entity selection is handled, after cubos.window.poll and cubos.renderer.draw

Dependencies

+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Functions

+
+
+ void entitySelectorPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void entitySelectorPlugin(cubos::engine::Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__tesseratos-metrics-panel-plugin.html b/docs-preview/pr-1032/group__tesseratos-metrics-panel-plugin.html new file mode 100644 index 000000000..94b9b3b34 --- /dev/null +++ b/docs-preview/pr-1032/group__tesseratos-metrics-panel-plugin.html @@ -0,0 +1,153 @@ + + + + + Tesseratos » Metrics module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Tesseratos » + Metrics module

+

Shows some useful performance metrics through a ImGui window.

+ +

Dependencies

+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Functions

+
+
+ void metricsPanelPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void metricsPanelPlugin(cubos::engine::Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__tesseratos-play-pause-plugin.html b/docs-preview/pr-1032/group__tesseratos-play-pause-plugin.html new file mode 100644 index 000000000..42950fbda --- /dev/null +++ b/docs-preview/pr-1032/group__tesseratos-play-pause-plugin.html @@ -0,0 +1,153 @@ + + + + + Tesseratos » Play Pause module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Tesseratos » + Play Pause module

+

Allows changing the current simulation speed, or even pause it.

+ +

Dependencies

+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Functions

+
+
+ void playPausePlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void playPausePlugin(cubos::engine::Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__tesseratos-scene-editor-plugin.html b/docs-preview/pr-1032/group__tesseratos-scene-editor-plugin.html new file mode 100644 index 000000000..d2503d220 --- /dev/null +++ b/docs-preview/pr-1032/group__tesseratos-scene-editor-plugin.html @@ -0,0 +1,153 @@ + + + + + Tesseratos » Scene editor module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Tesseratos » + Scene editor module

+

Adds a window to edit scenes and select entities in them.

+ +

Dependencies

+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Functions

+
+
+ void sceneEditorPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void sceneEditorPlugin(cubos::engine::Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__tesseratos-settings-inspector-plugin.html b/docs-preview/pr-1032/group__tesseratos-settings-inspector-plugin.html new file mode 100644 index 000000000..1f23a9c81 --- /dev/null +++ b/docs-preview/pr-1032/group__tesseratos-settings-inspector-plugin.html @@ -0,0 +1,153 @@ + + + + + Tesseratos » Settings inspector module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Tesseratos » + Settings inspector module

+

Allows inspecting the current setting values through a ImGui window.

+ +

Dependencies

+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Functions

+
+
+ void settingsInspectorPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void settingsInspectorPlugin(cubos::engine::Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__tesseratos-toolbox-plugin.html b/docs-preview/pr-1032/group__tesseratos-toolbox-plugin.html new file mode 100644 index 000000000..fd646adf4 --- /dev/null +++ b/docs-preview/pr-1032/group__tesseratos-toolbox-plugin.html @@ -0,0 +1,164 @@ + + + + + Tesseratos » Toolbox module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Tesseratos » + Toolbox module

+

Adds a resource used to keep track of whether each tool is open or not.

+ +

Resources

Dependencies

  • imguiPlugin
+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Classes

+
+
+ class tesseratos::Toolbox +
+
Resource which manages other tools windows.
+
+
+
+

Functions

+
+
+ void toolboxPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void toolboxPlugin(cubos::engine::Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__tesseratos-transform-gizmo-plugin.html b/docs-preview/pr-1032/group__tesseratos-transform-gizmo-plugin.html new file mode 100644 index 000000000..516cbcaf4 --- /dev/null +++ b/docs-preview/pr-1032/group__tesseratos-transform-gizmo-plugin.html @@ -0,0 +1,151 @@ + + + + + Tesseratos » Transform gizmo module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Tesseratos » + Transform gizmo module

+

Add a gizmo that allows changing an entity's position.

+ +
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Functions

+
+
+ void transformGizmoPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void transformGizmoPlugin(cubos::engine::Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__tesseratos-voxel-palette-editor-plugin.html b/docs-preview/pr-1032/group__tesseratos-voxel-palette-editor-plugin.html new file mode 100644 index 000000000..c415a57dc --- /dev/null +++ b/docs-preview/pr-1032/group__tesseratos-voxel-palette-editor-plugin.html @@ -0,0 +1,153 @@ + + + + + Tesseratos » Palette editor module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Tesseratos » + Palette editor module

+

Allows the user to open and inspect/edit a palette asset.

+ +

Dependencies

+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Functions

+
+
+ void voxelPaletteEditorPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void voxelPaletteEditorPlugin(cubos::engine::Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__tesseratos-world-inspector-plugin.html b/docs-preview/pr-1032/group__tesseratos-world-inspector-plugin.html new file mode 100644 index 000000000..08ab85df3 --- /dev/null +++ b/docs-preview/pr-1032/group__tesseratos-world-inspector-plugin.html @@ -0,0 +1,153 @@ + + + + + Tesseratos » World inspector module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Tesseratos » + World inspector module

+

Shows all of the entities in the world through a ImGui window, and allows selecting them.

+ +

Dependencies

+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Functions

+
+
+ void worldInspectorPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void worldInspectorPlugin(cubos::engine::Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__tesseratos.html b/docs-preview/pr-1032/group__tesseratos.html new file mode 100644 index 000000000..170ac742b --- /dev/null +++ b/docs-preview/pr-1032/group__tesseratos.html @@ -0,0 +1,185 @@ + + + + + Tesseratos module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Tesseratos module

+

TESSERATOS. library.

+ +

The tesseratos library provides tools useful for debugging and developing games using CUBOS. It is built on top of the engine library. Each sub-module corresponds to a tool or a set of tools.

+
+

Modules

+
+
module Asset explorer
+
Allows viewing and selecting assets through a ImGui window.
+
module Collider gizmos
+
Draws gizmos for selected colliders.
+
module Debug camera
+
Adds a toggleable debug camera.
+
module ECS Statistics
+
Shows tons of statistics and information about the internal state of the ECS.
+
module Entity inspector
+
Allows inspecting and modifying the components of the selected entity through a ImGui window.
+
module Entity selector
+
Adds a resource used to select an entity.
+
module Metrics
+
Shows some useful performance metrics through a ImGui window.
+
module Play Pause
+
Allows changing the current simulation speed, or even pause it.
+
module Scene editor
+
Adds a window to edit scenes and select entities in them.
+
module Settings inspector
+
Allows inspecting the current setting values through a ImGui window.
+
module Toolbox
+
Adds a resource used to keep track of whether each tool is open or not.
+
module Transform gizmo
+
Add a gizmo that allows changing an entity's position.
+
module Palette editor
+
Allows the user to open and inspect/edit a palette asset.
+
module World inspector
+
Shows all of the entities in the world through a ImGui window, and allows selecting them.
+
+
+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Functions

+
+
+ void plugin(cubos::engine::Cubos& cubos) +
+
Tesseratos entry function.
+
+
+
+

Function documentation

+
+

+ void plugin(cubos::engine::Cubos& cubos) + +

+

Tesseratos entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__transform-plugin.html b/docs-preview/pr-1032/group__transform-plugin.html new file mode 100644 index 000000000..23218b199 --- /dev/null +++ b/docs-preview/pr-1032/group__transform-plugin.html @@ -0,0 +1,197 @@ + + + + + Engine » Transform module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Engine » + Transform module

+

Adds transform components which assign positions, rotations and scaling to entities.

+ +

This plugin operates on entities with LocalToWorld and LocalToParent components, and any combination of the Position, Rotation and Scale components. For example, if you have an entity which doesn't need rotation, but has a position and a scale, you do not need to add the Rotation component, and its transform will still be updated.

Components

  • LocalToParent - holds the local to parent transform matrix.
  • LocalToWorld - holds the local to world transform matrix.
  • Position - holds the position of an entity.
  • Rotation - holds the rotation of an entity.
  • Scale - holds the scaling of an entity.

Relations

  • ChildOf - tree like relation which indicates an entity is a child of another.

Tags

+
+

Files

+
+
file child_of.hpp
+
Relation cubos::engine::ChildOf.
+
file local_to_parent.hpp
+
Component cubos::engine::LocalToParent.
+
file local_to_world.hpp
+
Component cubos::engine::LocalToWorld.
+
file plugin.hpp
+
Plugin entry point.
+
file position.hpp
+
Component cubos::engine::Position.
+
file rotation.hpp
+
Component cubos::engine::Rotation.
+
file scale.hpp
+
Component cubos::engine::Scale.
+
+
+
+

Classes

+
+
+ struct cubos::engine::ChildOf +
+
Tree relation which indicates the 'from' entity is a child of the 'to' entity.
+
+ struct cubos::engine::LocalToParent +
+
Component which stores the transformation matrix of an entity, from local to parent space.
+
+ struct cubos::engine::LocalToWorld +
+
Component which stores the transformation matrix of an entity, from local to world space.
+
+ struct cubos::engine::Position +
+
Component which assigns a position to an entity.
+
+ struct cubos::engine::Rotation +
+
Component which assigns a rotation to an entity.
+
+ struct cubos::engine::Scale +
+
Component which assigns a uniform scale to an entity.
+
+
+
+

Functions

+
+
+ void transformPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void transformPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__voxels-plugin.html b/docs-preview/pr-1032/group__voxels-plugin.html new file mode 100644 index 000000000..8147e561c --- /dev/null +++ b/docs-preview/pr-1032/group__voxels-plugin.html @@ -0,0 +1,178 @@ + + + + + Engine » Voxels module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Engine » + Voxels module

+

Adds grid and palette assets to CUBOS.

+ +

Bridges

Dependencies

+
+

Files

+
+
file grid.hpp
+
Class cubos::engine::VoxelGrid.
+
file material.hpp
+
Class cubos::engine::VoxelMaterial.
+
file palette.hpp
+
Class cubos::engine::VoxelPalette.
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Classes

+
+
+ class cubos::engine::VoxelGrid +
+
Represents a voxel object using a 3D grid.
+
+ struct cubos::engine::VoxelMaterial +
+
Describes a voxel material.
+
+ class cubos::engine::VoxelPalette +
+
Holds a palette of materials. Supports up to 65535 materials.
+
+
+
+

Functions

+
+
+ void voxelsPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void voxelsPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/group__window-plugin.html b/docs-preview/pr-1032/group__window-plugin.html new file mode 100644 index 000000000..9ae932ea0 --- /dev/null +++ b/docs-preview/pr-1032/group__window-plugin.html @@ -0,0 +1,158 @@ + + + + + Engine » Window module | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Engine » + Window module

+

Creates and handles the lifecycle of a window.

+ +

Initially sets ShouldQuit to false, and sets it to true only when the window is closed.

Settings

  • window.title - the window's title (default: CUBOS.).
  • window.width - the window's width (default: 800).
  • window.height - the window's height (default: 600).

Events

Resources

Startup tags

  • cubos.window.init - window is opened, runs after cubos.settings.

Tags

  • cubos.window.poll - the window is polled for events, sending core::io::WindowEvent's.
  • cubos.window.render - the window's back buffers are swapped.

Dependencies

+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Functions

+
+
+ void windowPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void windowPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/guards_8hpp.html b/docs-preview/pr-1032/guards_8hpp.html new file mode 100644 index 000000000..5f8854ccc --- /dev/null +++ b/docs-preview/pr-1032/guards_8hpp.html @@ -0,0 +1,140 @@ + + + + + core/memory/guards.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/memory/guards.hpp file +

+

Classes cubos::core::memory::ReadGuard and cubos::core::memory::WriteGuard.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::memory
+
Memory module.
+
+
+
+

Classes

+
+
+
template<typename T, typename Lock>
+ class cubos::core::memory::ReadGuard +
+
Provides safe read-only access to an object using a lock.
+
+
template<typename T, typename Lock>
+ class cubos::core::memory::WriteGuard +
+
Provides safe read-write access to an object using a lock.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/hash_8hpp.html b/docs-preview/pr-1032/hash_8hpp.html new file mode 100644 index 000000000..04c36741a --- /dev/null +++ b/docs-preview/pr-1032/hash_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/ecs/entity/hash.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/id_8hpp.html b/docs-preview/pr-1032/id_8hpp.html new file mode 100644 index 000000000..915415e90 --- /dev/null +++ b/docs-preview/pr-1032/id_8hpp.html @@ -0,0 +1,140 @@ + + + + + core/ecs/table/sparse_relation/id.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/ecs/table/sparse_relation/id.hpp file +

+

Struct cubos::core::ecs::SparseRelationTableId.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::reflection
+
Reflection module.
+
namespace cubos::core::ecs
+
ECS module.
+
+
+
+

Classes

+
+
+ struct cubos::core::ecs::SparseRelationTableId +
+
Identifies a sparse relation table.
+
+ struct cubos::core::ecs::SparseRelationTableIdHash +
+
Hash functor for SparseRelationTableId.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/img1.png b/docs-preview/pr-1032/img1.png new file mode 100644 index 0000000000000000000000000000000000000000..9133dfe3752fa06ee81a459b09e44a904f95ce78 GIT binary patch literal 11833 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 literal 0 HcmV?d00001 diff --git a/docs-preview/pr-1032/img2.png b/docs-preview/pr-1032/img2.png new file mode 100644 index 0000000000000000000000000000000000000000..7ac6b5daa80ba3ccd0b3976a4ece8d6e49c7cee3 GIT binary patch literal 10174 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 + + + + engine/physics/components/impulse.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/index.html b/docs-preview/pr-1032/index.html new file mode 100644 index 000000000..3a46b6004 --- /dev/null +++ b/docs-preview/pr-1032/index.html @@ -0,0 +1,102 @@ + + + + + Introduction | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ Introduction +

+

Image

Voxel based engine

CUBOS. aims to be a simple, but powerful game engine for PC, where everything is made out of voxels.

It is open source and free to use for any purpose. Written in modern C++ (20) and with data-oriented design in mind, its goal is to be both performant and highly flexible.

Getting started

The best way to get started is to read the getting started guide, which will guide you through the process of downloading and building the engine, as well as where to go from there.

There is also a feature guide which gives you a high-level overview of the engine's design and features. If you're just looking for a quick overview, this is the place to go. You can also take a look at the modules page, which describes each of the engine's modules.

In the examples page you can find examples on how to use specific parts of the engine.

If you're looking to contribute to the project, make sure you read the contribution guidelines, which introduces you to the project's conventions and code style.

Team

CUBOS. is developed by a small team at GameDev Técnico, a student group at Instituto Superior Técnico who make games. Our goal is to build a game engine from the ground up and have fun doing it.

Join us

If you're a student and interested in joining us, please fill out this form.

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/input_8hpp.html b/docs-preview/pr-1032/input_8hpp.html new file mode 100644 index 000000000..e5ee4aa71 --- /dev/null +++ b/docs-preview/pr-1032/input_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/input/input.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/intersections_8hpp.html b/docs-preview/pr-1032/intersections_8hpp.html new file mode 100644 index 000000000..12d76cd6e --- /dev/null +++ b/docs-preview/pr-1032/intersections_8hpp.html @@ -0,0 +1,148 @@ + + + + + core/geom/intersections.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/geom/intersections.hpp file +

+

Class cubos::core::geom::Intersections.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::geom
+
Geometry module.
+
+
+
+

Classes

+
+
+ struct cubos::core::geom::Intersection +
+
Contains info regarding an intersection between shapes.
+
+
+
+

Functions

+
+
+ auto intersects(const Box& box1, + const glm::mat4& localToWorld1, + const Box& box2, + const glm::mat4& localToWorld2, + Intersection& intersect) -> bool +
+
Computes the intersection between two box shapes.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/keyboard_8hpp.html b/docs-preview/pr-1032/keyboard_8hpp.html new file mode 100644 index 000000000..61f6b778b --- /dev/null +++ b/docs-preview/pr-1032/keyboard_8hpp.html @@ -0,0 +1,251 @@ + + + + + core/io/keyboard.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/io/keyboard.hpp file +

+

Enums cubos::core::io::Key and cubos::core::io::Modifiers.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::io
+
Input and output module.
+
+
+
+

Classes

+
+
+ struct cubos::core::io::KeyWithModifiers +
+
Keyboard key code and modifier flags.
+
+
+
+

Enums

+
+
+ enum class Key { Invalid = -1, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + T, + U, + V, + W, + X, + Y, + Z, + Num0, + Num1, + Num2, + Num3, + Num4, + Num5, + Num6, + Num7, + Num8, + Num9, + Escape, + LControl, + LShift, + LAlt, + LSystem, + RControl, + RShift, + RAlt, + RSystem, + Menu, + LBracket, + RBracket, + SemiColon, + Comma, + Period, + Quote, + Slash, + BackSlash, + Tilde, + Equal, + Dash, + Space, + Return, + BackSpace, + Tab, + PageUp, + PageDown, + End, + Home, + Insert, + Delete, + Add, + Subtract, + Multiply, + Divide, + Left, + Right, + Up, + Down, + Numpad0, + Numpad1, + Numpad2, + Numpad3, + Numpad4, + Numpad5, + Numpad6, + Numpad7, + Numpad8, + Numpad9, + F1, + F2, + F3, + F4, + F5, + F6, + F7, + F8, + F9, + F10, + F11, + F12, + Pause, + Count } +
+
Keyboard key codes enum.
+
+ enum class Modifiers { None = 0, + Control = 1, + Shift = 2, + Alt = 4, + System = 8 } +
+
Keyboard modifier flags enum.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/local__to__parent_8hpp.html b/docs-preview/pr-1032/local__to__parent_8hpp.html new file mode 100644 index 000000000..bebbfd710 --- /dev/null +++ b/docs-preview/pr-1032/local__to__parent_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/transform/local_to_parent.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/local__to__world_8hpp.html b/docs-preview/pr-1032/local__to__world_8hpp.html new file mode 100644 index 000000000..421fc6beb --- /dev/null +++ b/docs-preview/pr-1032/local__to__world_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/transform/local_to_world.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/log_8hpp.html b/docs-preview/pr-1032/log_8hpp.html new file mode 100644 index 000000000..57ba1a1c5 --- /dev/null +++ b/docs-preview/pr-1032/log_8hpp.html @@ -0,0 +1,239 @@ + + + + + core/log.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/log.hpp file +

+

Logging and assertion macros.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
+
+
+

Classes

+
+
+ class cubos::core::Logger +
+
Singleton which holds the logging state.
+
+ struct cubos::core::Logger::Location +
+
Identifies a location in the code.
+
+ struct cubos::core::Logger::Timestamp +
+
A timestamp used to identify when a logging message was written.
+
+ struct cubos::core::Logger::Entry +
+
Data created by a call to log.
+
+
+
+

Defines

+
+
+ #define CUBOS_LOG_LEVEL_TRACE +
+
Trace log level, lowest log level. Very verbose.
+
+ #define CUBOS_LOG_LEVEL_DEBUG +
+
Debug log level. Contains messages useful for debugging, but which are not necessary in release builds.
+
+ #define CUBOS_LOG_LEVEL_INFO +
+
Information log level. Contains important events that are not errors.
+
+ #define CUBOS_LOG_LEVEL_WARN +
+
Warn log level. Contains events that are not errors, but which are unexpected and may be problematic.
+
+ #define CUBOS_LOG_LEVEL_ERROR +
+
Error log level. Contains errors which are recoverable from.
+
+ #define CUBOS_LOG_LEVEL_CRITICAL +
+
Critical log level, highest log level. Contains errors which are unrecoverable from.
+
+ #define CUBOS_LOG_LEVEL_OFF +
+
Off log level, disables all logging.
+
+ #define CUBOS_LOG_LEVEL +
+
Log level to compile in.
+
+ #define CUBOS_TRACE(...) +
+
Used for logging very verbose information.
+
+ #define CUBOS_DEBUG(...) +
+
Used for logging information which is useful for debugging but not necessary in release builds.
+
+ #define CUBOS_INFO(...) +
+
Used for logging information which is useful in release builds.
+
+ #define CUBOS_WARN(...) +
+
Used for logging unexpected events.
+
+ #define CUBOS_ERROR(...) +
+
Used for logging recoverable errors.
+
+ #define CUBOS_CRITICAL(...) +
+
Used for logging unrecoverable errors.
+
+ #define CUBOS_LOG(level, + ...) +
+
Used for logging messages.
+
+ #define CUBOS_FAIL(...) +
+
Aborts a program, optionally printing a critical error message.
+
+ #define CUBOS_UNREACHABLE(...) +
+
Marks a code path as supposedly unreachable. Aborts the program when reached.
+
+ #define CUBOS_TODO(...) +
+
Marks a code path as unfinished. Aborts the program when reached.
+
+ #define CUBOS_ASSERT(cond, + ...) +
+
Asserts that a condition is true, aborting the program if it is not.
+
+ #define CUBOS_ASSERT_IMP(cond, + cons, + ...) +
+
Asserts that an implication is true, aborting the program if it is not.
+
+ #define CUBOS_DEBUG_ASSERT(cond, + ...) +
+
In debug builds asserts that a condition is true, aborting the program if it is not.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/m-dark+documentation.compiled.css b/docs-preview/pr-1032/m-dark+documentation.compiled.css new file mode 100644 index 000000000..7d091c2fa --- /dev/null +++ b/docs-preview/pr-1032/m-dark+documentation.compiled.css @@ -0,0 +1,2925 @@ +/* Generated using `./postprocess.py m-dark.css m-documentation.css -o m-dark+documentation.compiled.css`. Do not edit. */ + +/* + This file is part of m.css. + + Copyright © 2017, 2018, 2019, 2020, 2021, 2022, 2023 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +*, ::before, ::after { box-sizing: border-box; } +body { margin: 0; } +.m-container { + width: 100%; + margin: auto; + padding-left: 1rem; + padding-right: 1rem; +} +.m-row { + margin-left: -1rem; + margin-right: -1rem; +} +.m-row::after { + content: ' '; + clear: both; + display: table; +} +.m-row > [class*='m-col-'] { + position: relative; + padding: 1rem; +} +[class*='m-clearfix-']::after { + display: block; + content: ' '; + clear: both; +} +[class*='m-show-'] { + display: none; +} +.m-container-inflate, :not(.m-row) > [class*='m-col-'] { + margin-bottom: 1rem; +} +.m-container-inflate:last-child, :not(.m-row) > [class*='m-col-']:last-child { + margin-bottom: 0; +} +.m-container.m-nopad, [class*='m-col-'].m-nopad, +.m-container.m-nopadx, [class*='m-col-'].m-nopadx, +.m-container.m-nopadl, [class*='m-col-'].m-nopadl { + padding-left: 0; +} +.m-container.m-nopad, [class*='m-col-'].m-nopad, +.m-container.m-nopadx, [class*='m-col-'].m-nopadx, +.m-container.m-nopadr, [class*='m-col-'].m-nopadr { + padding-right: 0; +} +[class*='m-col-'].m-nopad, [class*='m-col-'].m-nopady, [class*='m-col-'].m-nopadt { + padding-top: 0; +} +[class*='m-col-'].m-nopad, [class*='m-col-'].m-nopady, [class*='m-col-'].m-nopadb, +.m-container-inflate.m-nopadb { + padding-bottom: 0; +} +[class*='m-col-t-'] { float: left; } +.m-left-t { + padding-right: 1rem; + float: left; +} +.m-right-t, [class*='m-col-t-'].m-right-t { + padding-left: 1rem; + float: right; +} +.m-center-t, [class*='m-col-t-'].m-center-t { + float: none; +} +.m-center-t, [class*='m-col-t-'].m-center-t { + margin-left: auto; + margin-right: auto; + float: none; +} +.m-col-t-1 { width: calc(1 * 100% / 12); } +.m-col-t-2 { width: calc(2 * 100% / 12); } +.m-col-t-3 { width: calc(3 * 100% / 12); } +.m-col-t-4 { width: calc(4 * 100% / 12); } +.m-col-t-5 { width: calc(5 * 100% / 12); } +.m-col-t-6 { width: calc(6 * 100% / 12); } +.m-col-t-7 { width: calc(7 * 100% / 12); } +.m-col-t-8 { width: calc(8 * 100% / 12); } +.m-col-t-9 { width: calc(9 * 100% / 12); } +.m-col-t-10 { width: calc(10 * 100% / 12); } +.m-col-t-11 { width: calc(11 * 100% / 12); } +.m-col-t-12 { width: calc(12 * 100% / 12); } +.m-push-t-1 { left: calc(1 * 100% / 12); } +.m-push-t-2 { left: calc(2 * 100% / 12); } +.m-push-t-3 { left: calc(3 * 100% / 12); } +.m-push-t-4 { left: calc(4 * 100% / 12); } +.m-push-t-5 { left: calc(5 * 100% / 12); } +.m-push-t-6 { left: calc(6 * 100% / 12); } +.m-push-t-7 { left: calc(7 * 100% / 12); } +.m-push-t-8 { left: calc(8 * 100% / 12); } +.m-push-t-9 { left: calc(9 * 100% / 12); } +.m-push-t-10 { left: calc(10 * 100% / 12); } +.m-push-t-11 { left: calc(11 * 100% / 12); } +.m-pull-t-1 { right: calc(1 * 100% / 12); } +.m-pull-t-2 { right: calc(2 * 100% / 12); } +.m-pull-t-3 { right: calc(3 * 100% / 12); } +.m-pull-t-4 { right: calc(4 * 100% / 12); } +.m-pull-t-5 { right: calc(5 * 100% / 12); } +.m-pull-t-6 { right: calc(6 * 100% / 12); } +.m-pull-t-7 { right: calc(7 * 100% / 12); } +.m-pull-t-8 { right: calc(8 * 100% / 12); } +.m-pull-t-9 { right: calc(9 * 100% / 12); } +.m-pull-t-10 { right: calc(10 * 100% / 12); } +.m-pull-t-11 { right: calc(11 * 100% / 12); } +@media screen and (min-width: 576px) { + .m-container { width: 560px; } + .m-container-inflatable .m-col-s-10 .m-container-inflate:not([class*='m-left-']):not([class*='m-right-']) { + margin-left: -10%; + margin-right: -10%; + } + .m-container-inflatable .m-col-s-10 .m-container-inflate.m-left-s { + margin-left: -10%; + } + .m-container-inflatable .m-col-s-10 .m-container-inflate.m-right-s { + margin-right: -10%; + } + [class*='m-col-s-'] { float: left; } + .m-left-s { + padding-right: 1rem; + float: left; + } + .m-right-s, [class*='m-col-s-'].m-right-s { + padding-left: 1rem; + float: right; + } + .m-center-s, [class*='m-col-s-'].m-center-s { + margin-left: auto; + margin-right: auto; + float: none; + } + .m-col-s-1 { width: calc(1 * 100% / 12); } + .m-col-s-2 { width: calc(2 * 100% / 12); } + .m-col-s-3 { width: calc(3 * 100% / 12); } + .m-col-s-4 { width: calc(4 * 100% / 12); } + .m-col-s-5 { width: calc(5 * 100% / 12); } + .m-col-s-6 { width: calc(6 * 100% / 12); } + .m-col-s-7 { width: calc(7 * 100% / 12); } + .m-col-s-8 { width: calc(8 * 100% / 12); } + .m-col-s-9 { width: calc(9 * 100% / 12); } + .m-col-s-10 { width: calc(10 * 100% / 12); } + .m-col-s-11 { width: calc(11 * 100% / 12); } + .m-col-s-12 { width: calc(12 * 100% / 12); } + .m-push-s-0 { left: calc(0 * 100% / 12); } + .m-push-s-1 { left: calc(1 * 100% / 12); } + .m-push-s-2 { left: calc(2 * 100% / 12); } + .m-push-s-3 { left: calc(3 * 100% / 12); } + .m-push-s-4 { left: calc(4 * 100% / 12); } + .m-push-s-5 { left: calc(5 * 100% / 12); } + .m-push-s-6 { left: calc(6 * 100% / 12); } + .m-push-s-7 { left: calc(7 * 100% / 12); } + .m-push-s-8 { left: calc(8 * 100% / 12); } + .m-push-s-9 { left: calc(9 * 100% / 12); } + .m-push-s-10 { left: calc(10 * 100% / 12); } + .m-push-s-11 { left: calc(11 * 100% / 12); } + .m-pull-s-0 { right: calc(0 * 100% / 12); } + .m-pull-s-1 { right: calc(1 * 100% / 12); } + .m-pull-s-2 { right: calc(2 * 100% / 12); } + .m-pull-s-3 { right: calc(3 * 100% / 12); } + .m-pull-s-4 { right: calc(4 * 100% / 12); } + .m-pull-s-5 { right: calc(5 * 100% / 12); } + .m-pull-s-6 { right: calc(6 * 100% / 12); } + .m-pull-s-7 { right: calc(7 * 100% / 12); } + .m-pull-s-8 { right: calc(8 * 100% / 12); } + .m-pull-s-9 { right: calc(9 * 100% / 12); } + .m-pull-s-10 { right: calc(10 * 100% / 12); } + .m-pull-s-11 { right: calc(11 * 100% / 12); } + .m-clearfix-t::after { display: none; } + .m-hide-s { display: none; } + .m-show-s { display: block; } + .m-col-s-none { + width: auto; + float: none; + } +} +@media screen and (min-width: 768px) { + .m-container { width: 750px; } + .m-container-inflatable .m-col-m-10 .m-container-inflate:not([class*='m-left-']):not([class*='m-right-']) { + margin-left: -10%; + margin-right: -10%; + } + .m-container-inflatable .m-col-m-10 .m-container-inflate.m-left-m { + margin-left: -10%; + } + .m-container-inflatable .m-col-m-10 .m-container-inflate.m-right-m { + margin-right: -10%; + } + [class*='m-col-m-'] { float: left; } + .m-left-m { + padding-right: 1rem; + float: left; + } + .m-right-m, [class*='m-col-m-'].m-right-m { + padding-left: 1rem; + float: right; + } + .m-center-m, [class*='m-col-m-'].m-center-m { + margin-left: auto; + margin-right: auto; + float: none; + } + .m-col-m-1 { width: calc(1 * 100% / 12); } + .m-col-m-2 { width: calc(2 * 100% / 12); } + .m-col-m-3 { width: calc(3 * 100% / 12); } + .m-col-m-4 { width: calc(4 * 100% / 12); } + .m-col-m-5 { width: calc(5 * 100% / 12); } + .m-col-m-6 { width: calc(6 * 100% / 12); } + .m-col-m-7 { width: calc(7 * 100% / 12); } + .m-col-m-8 { width: calc(8 * 100% / 12); } + .m-col-m-9 { width: calc(9 * 100% / 12); } + .m-col-m-10 { width: calc(10 * 100% / 12); } + .m-col-m-11 { width: calc(11 * 100% / 12); } + .m-col-m-12 { width: calc(12 * 100% / 12); } + .m-push-m-0 { left: calc(0 * 100% / 12); } + .m-push-m-1 { left: calc(1 * 100% / 12); } + .m-push-m-2 { left: calc(2 * 100% / 12); } + .m-push-m-3 { left: calc(3 * 100% / 12); } + .m-push-m-4 { left: calc(4 * 100% / 12); } + .m-push-m-5 { left: calc(5 * 100% / 12); } + .m-push-m-6 { left: calc(6 * 100% / 12); } + .m-push-m-7 { left: calc(7 * 100% / 12); } + .m-push-m-8 { left: calc(8 * 100% / 12); } + .m-push-m-9 { left: calc(9 * 100% / 12); } + .m-push-m-10 { left: calc(10 * 100% / 12); } + .m-push-m-11 { left: calc(11 * 100% / 12); } + .m-pull-m-0 { right: calc(0 * 100% / 12); } + .m-pull-m-1 { right: calc(1 * 100% / 12); } + .m-pull-m-2 { right: calc(2 * 100% / 12); } + .m-pull-m-3 { right: calc(3 * 100% / 12); } + .m-pull-m-4 { right: calc(4 * 100% / 12); } + .m-pull-m-5 { right: calc(5 * 100% / 12); } + .m-pull-m-6 { right: calc(6 * 100% / 12); } + .m-pull-m-7 { right: calc(7 * 100% / 12); } + .m-pull-m-8 { right: calc(8 * 100% / 12); } + .m-pull-m-9 { right: calc(9 * 100% / 12); } + .m-pull-m-10 { right: calc(10 * 100% / 12); } + .m-pull-m-11 { right: calc(11 * 100% / 12); } + .m-clearfix-s::after { display: none; } + .m-hide-m { display: none; } + .m-show-m { display: block; } + .m-col-m-none { + width: auto; + float: none; + } +} +@media screen and (min-width: 992px) { + .m-container { width: 960px; } + .m-container-inflatable .m-col-l-10 .m-container-inflate:not([class*='m-left-']):not([class*='m-right-']) { + margin-left: -10%; + margin-right: -10%; + } + .m-container-inflatable .m-col-l-10 .m-container-inflate.m-left-l { + margin-left: -10%; + } + .m-container-inflatable .m-col-l-10 .m-container-inflate.m-right-l { + margin-right: -10%; + } + [class*='m-col-l-'] { float: left; } + .m-left-l { + padding-right: 1rem; + float: left; + } + .m-right-l, [class*='m-col-l-'].m-right-l { + padding-left: 1rem; + float: right; + } + .m-center-l, [class*='m-col-l-'].m-center-l { + margin-left: auto; + margin-right: auto; + float: none; + } + .m-col-l-1 { width: calc(1 * 100% / 12); } + .m-col-l-2 { width: calc(2 * 100% / 12); } + .m-col-l-3 { width: calc(3 * 100% / 12); } + .m-col-l-4 { width: calc(4 * 100% / 12); } + .m-col-l-5 { width: calc(5 * 100% / 12); } + .m-col-l-6 { width: calc(6 * 100% / 12); } + .m-col-l-7 { width: calc(7 * 100% / 12); } + .m-col-l-8 { width: calc(8 * 100% / 12); } + .m-col-l-9 { width: calc(9 * 100% / 12); } + .m-col-l-10 { width: calc(10 * 100% / 12); } + .m-col-l-11 { width: calc(11 * 100% / 12); } + .m-col-l-12 { width: calc(12 * 100% / 12); } + .m-push-l-0 { left: calc(0 * 100% / 12); } + .m-push-l-1 { left: calc(1 * 100% / 12); } + .m-push-l-2 { left: calc(2 * 100% / 12); } + .m-push-l-3 { left: calc(3 * 100% / 12); } + .m-push-l-4 { left: calc(4 * 100% / 12); } + .m-push-l-5 { left: calc(5 * 100% / 12); } + .m-push-l-6 { left: calc(6 * 100% / 12); } + .m-push-l-7 { left: calc(7 * 100% / 12); } + .m-push-l-8 { left: calc(8 * 100% / 12); } + .m-push-l-9 { left: calc(9 * 100% / 12); } + .m-push-l-10 { left: calc(10 * 100% / 12); } + .m-push-l-11 { left: calc(11 * 100% / 12); } + .m-pull-l-0 { right: calc(0 * 100% / 12); } + .m-pull-l-1 { right: calc(1 * 100% / 12); } + .m-pull-l-2 { right: calc(2 * 100% / 12); } + .m-pull-l-3 { right: calc(3 * 100% / 12); } + .m-pull-l-4 { right: calc(4 * 100% / 12); } + .m-pull-l-5 { right: calc(5 * 100% / 12); } + .m-pull-l-6 { right: calc(6 * 100% / 12); } + .m-pull-l-7 { right: calc(7 * 100% / 12); } + .m-pull-l-8 { right: calc(8 * 100% / 12); } + .m-pull-l-9 { right: calc(9 * 100% / 12); } + .m-pull-l-10 { right: calc(10 * 100% / 12); } + .m-pull-l-11 { right: calc(11 * 100% / 12); } + .m-clearfix-m::after { display: none; } + .m-hide-l { display: none; } + .m-show-l { display: block; } + .m-col-l-none { + width: auto; + float: none; + } +} + +html { + font-size: 16px; + background-color: #2f363f; +} +body { + font-family: 'Source Sans Pro', sans-serif; + font-size: 1rem; + line-height: normal; + color: #dcdcdc; +} +h1, h2, h3, h4, h5, h6 { + margin-top: 0; + font-weight: 600; +} +h1 { + margin-bottom: 1rem; +} +h2, h3, h4, h5, h6 { + margin-bottom: 0.5rem; +} +p, ul, ol, dl { + margin-top: 0; +} +ul, ol { + padding-left: 2rem; +} +ul ol, ul ul, ol ol, ol ul { + margin-bottom: 0; +} +main p { + text-indent: 1.5rem; + text-align: justify; +} +main p.m-noindent, li > p, dd > p, table.m-table td > p { + text-indent: 0; + text-align: left; +} +blockquote { + margin-top: 0; + margin-left: 1rem; + margin-right: 1rem; + padding: 1rem; + border-left-style: solid; + border-left-width: 0.25rem; +} +hr { + width: 75%; + border-width: 0.0625rem; + border-style: solid; +} +blockquote, hr { + border-color: #405363; +} +strong, .m-text.m-strong { font-weight: bold; } +em, .m-text.m-em { font-style: italic; } +s, .m-text.m-s { text-decoration: line-through; } +sub, sup, .m-text.m-sub, .m-text.m-sup { + font-size: 0.75rem; + line-height: 0; + position: relative; + vertical-align: baseline; +} +sup, .m-text.m-sup { top: -0.35rem; } +sub, .m-text.m-sub { bottom: -0.2rem; } +abbr { + cursor: help; + text-decoration: underline dotted; +} +a { + color: #5b9dd9; +} +a.m-flat { + text-decoration: none; +} +a:hover, a:focus, a:active { + color: #a5c9ea; +} +a img { border: 0; } +svg a { cursor: pointer; } +mark { + padding: 0.0625rem; + background-color: #c7cf2f; + color: #2f83cc; +} +.m-link-wrap { + word-break: break-all; +} +pre, code { + font-family: 'Source Code Pro', monospace, monospace, monospace; + font-size: 0.9em; + color: #e6e6e6; + background-color: #282e36; +} +pre.m-console, code.m-console { + color: #e6e6e6; + background-color: #1a1c1d; +} +pre { + padding: 0.5rem 1rem; + border-radius: 0.2rem; + overflow-x: auto; + margin-top: 0; +} +pre.m-console-wrap { + white-space: pre-wrap; + word-break: break-all; +} +code { + padding: 0.125rem; +} +*:focus { outline-color: #5b9dd9; } +div.m-scroll { + max-width: 100%; + overflow-x: auto; +} +.m-fullwidth { + width: 100%; +} +.m-spacing-150 { + line-height: 1.5rem; +} +.m-text-center, .m-text-center.m-noindent, table.m-table th.m-text-center, .m-text-center p { + text-align: center; +} +.m-text-left, .m-text-left.m-noindent, table.m-table th.m-text-left, .m-text-right p { + text-align: left; +} +.m-text-right, .m-text-right.m-noindent, table.m-table th.m-text-right, .m-text-right p { + text-align: right; +} +.m-text-top, table.m-table th.m-text-top, table.m-table td.m-text-top { + vertical-align: top; +} +.m-text-middle, table.m-table th.m-text-middle, table.m-table td.m-text-middle { + vertical-align: middle; +} +.m-text-bottom, table.m-table th.m-text-bottom, table.m-table td.m-text-bottom { + vertical-align: bottom; +} +.m-text.m-tiny { font-size: 50.0%; } +.m-text.m-small { font-size: 85.4%; } +.m-text.m-big { font-size: 117%; } +h1 .m-thin, h2 .m-thin, h3 .m-thin, h4 .m-thin, h5 .m-thin, h6 .m-thin { + font-weight: normal; +} +ul.m-unstyled, ol.m-unstyled { + list-style-type: none; + padding-left: 0; +} +ul[class*='m-block-'], ol[class*='m-block-'] { + padding-left: 0; +} +ul[class*='m-block-'] li, ol[class*='m-block-'] li { + display: inline; +} +ul[class*='m-block-bar-'] li:not(:last-child)::after, ol[class*='m-block-bar-'] li:not(:last-child)::after { + content: " | "; +} +ul[class*='m-block-dot-'] li:not(:last-child)::after, ol[class*='m-block-dot-'] li:not(:last-child)::after { + content: " • "; +} +@media screen and (min-width: 576px) { + ul.m-block-bar-s, ol.m-block-bar-s, + ul.m-block-dot-s, ol.m-block-dot-s { padding-left: 2rem; } + ul.m-block-bar-s li, ol.m-block-bar-s li, + ul.m-block-dot-s li, ol.m-block-dot-s li { display: list-item; } + ul.m-block-bar-s li:not(:last-child)::after, ol.m-block-bar-s li:not(:last-child)::after, + ul.m-block-dot-s li:not(:last-child)::after, ol.m-block-dot-s li:not(:last-child)::after { content: ""; } +} +@media screen and (min-width: 768px) { + ul.m-block-bar-m, ol.m-block-bar-m, + ul.m-block-dot-m, ol.m-block-dot-m { padding-left: 2rem; } + ul.m-block-bar-m li, ol.m-block-bar-m li, + ul.m-block-dot-m li, ol.m-block-dot-m li { display: list-item; } + ul.m-block-bar-m li:not(:last-child)::after, ol.m-block-bar-m li:not(:last-child)::after, + ul.m-block-dot-m li:not(:last-child)::after, ol.m-block-dot-m li:not(:last-child)::after { content: ""; } +} +@media screen and (min-width: 992px) { + ul.m-block-bar-l, ol.m-block-bar-l, + ul.m-block-dot-l, ol.m-block-dot-l { padding-left: 2rem; } + ul.m-block-bar-l li, ol.m-block-bar-l li, + ul.m-block-dot-l li, ol.m-block-dot-l li { display: list-item; } + ul.m-block-bar-l li:not(:last-child)::after, ol.m-block-bar-l li:not(:last-child)::after, + ul.m-block-dot-l li:not(:last-child)::after, ol.m-block-dot-l li:not(:last-child)::after { content: ""; } +} +p.m-poem { + text-indent: 0; + text-align: left; + margin-left: 1.5rem; +} +p.m-transition { + color: #405363; + text-indent: 0; + text-align: center; + font-size: 2rem; +} +dl.m-diary { + margin-bottom: 1.25rem; +} +dl.m-diary:last-child { + margin-bottom: 0.25rem; +} +dl.m-diary dt { + font-weight: bold; + width: 6rem; + float: left; + clear: both; + padding-top: 0.25rem; +} +dl.m-diary dd { + padding-top: 0.25rem; + padding-left: 6rem; + margin-left: 0; +} +a.m-footnote, dl.m-footnote dd span.m-footnote { + top: -0.35rem; + font-size: 0.75rem; + line-height: 0; + position: relative; + vertical-align: baseline; +} +a.m-footnote, dl.m-footnote dd span.m-footnote a { + text-decoration: none; +} +a.m-footnote::before { content: '['; } +a.m-footnote::after { content: ']'; } +dl.m-footnote dt { + width: 1.5rem; + float: left; + clear: both; +} +dl.m-footnote dd { + margin-left: 1.5rem; +} +dl.m-footnote { + font-size: 85.4%; +} +dl.m-footnote dd span.m-footnote a { + font-weight: bold; + font-style: italic; +} +.m-note { + border-radius: 0.2rem; + padding: 1rem; +} +.m-frame { + background-color: #2f363f; + border-style: solid; + border-width: 0.125rem; + border-radius: 0.2rem; + border-color: #405363; + padding: 0.875rem; +} +.m-block { + border-style: solid; + border-width: 0.0625rem; + border-left-width: 0.25rem; + border-radius: 0.2rem; + border-color: #405363; + padding: 0.9375rem 0.9375rem 0.9375rem 0.75rem; +} +.m-block.m-badge::after { + content: ' '; + display: block; + clear: both; +} +.m-block.m-badge h3 { + margin-left: 5rem; +} +.m-block.m-badge p { + margin-left: 5rem; + text-indent: 0; +} +.m-block.m-badge img { + width: 4rem; + height: 4rem; + border-radius: 2rem; + float: left; +} +div.m-button { + text-align: center; +} +div.m-button a { + display: inline-block; + border-radius: 0.2rem; + padding-top: 0.75rem; + padding-bottom: 0.75rem; + padding-left: 1.5rem; + padding-right: 1.5rem; + text-decoration: none; + font-size: 1.17rem; +} +div.m-button.m-fullwidth a { + display: block; + padding-left: 0.5rem; + padding-right: 0.5rem; +} +div.m-button a .m-big:first-child { + font-size: 1.37rem; + font-weight: bold; +} +div.m-button a .m-small:last-child { + font-size: 0.854rem; +} +.m-label { + border-radius: 0.2rem; + font-size: 75%; + font-weight: normal; + padding: 0.125rem 0.25rem; + vertical-align: 7.5%; +} +.m-label.m-flat { + border-width: 0.0625rem; + border-style: solid; + border-color: #747474; + padding: 0.0625rem 0.1875rem; +} +table.m-table { + border-collapse: collapse; + margin-left: auto; + margin-right: auto; +} +table.m-table.m-big { + margin-top: 1.75rem; +} +div.m-scroll > table.m-table:last-child { + margin-bottom: 0.0625rem; +} +table.m-table:not(.m-flat) tbody tr:hover { + background-color: #405363; +} +table.m-table th, table.m-table td { + vertical-align: top; + border-style: solid; + border-top-width: 0.0625rem; + border-left-width: 0; + border-right-width: 0; + border-bottom-width: 0; + border-color: #405363; +} +table.m-table caption { + padding-bottom: 0.5rem; +} +table.m-table thead tr:first-child th, table.m-table thead tr:first-child td { + border-top-width: 0.125rem; +} +table.m-table thead th, table.m-table thead td { + border-bottom-width: 0.125rem; + vertical-align: bottom; +} +table.m-table tfoot th, table.m-table tfoot td { + border-top-width: 0.125rem; +} +table.m-table th, table.m-table td { + padding: 0.5rem; +} +table.m-table.m-big th, table.m-table.m-big td { + padding: 0.75rem 1rem; +} +table.m-table th { + text-align: left; +} +table.m-table th.m-thin { + font-weight: normal; +} +table.m-table td.m-default, table.m-table th.m-default, +table.m-table td.m-primary, table.m-table th.m-primary, +table.m-table td.m-success, table.m-table th.m-success, +table.m-table td.m-warning, table.m-table th.m-warning, +table.m-table td.m-danger, table.m-table th.m-danger, +table.m-table td.m-info, table.m-table th.m-info, +table.m-table td.m-dim, table.m-table th.m-dim { + padding-left: 0.4375rem; + padding-right: 0.4375rem; + border-left-width: 0.0625rem; +} +table.m-table.m-big td.m-default, table.m-table.m-big th.m-default, +table.m-table.m-big td.m-primary, table.m-table.m-big th.m-primary, +table.m-table.m-big td.m-success, table.m-table.m-big th.m-success, +table.m-table.m-big td.m-warning, table.m-table.m-big th.m-warning, +table.m-table.m-big td.m-danger, table.m-table.m-big th.m-danger, +table.m-table.m-big td.m-info, table.m-table.m-big th.m-info, +table.m-table.m-big td.m-dim, table.m-table.m-big th.m-dim { + padding-left: 0.9375rem; + padding-right: 0.9375rem; + border-left-width: 0.0625rem; +} +table.m-table tr.m-default td, table.m-table td.m-default, +table.m-table tr.m-default th, table.m-table th.m-default, +table.m-table tr.m-primary td, table.m-table td.m-primary, +table.m-table tr.m-primary th, table.m-table th.m-primary, +table.m-table tr.m-success td, table.m-table td.m-success, +table.m-table tr.m-success th, table.m-table th.m-success, +table.m-table tr.m-warning td, table.m-table td.m-warning, +table.m-table tr.m-warning th, table.m-table th.m-warning, +table.m-table tr.m-danger td, table.m-table td.m-danger, +table.m-table tr.m-danger th, table.m-table th.m-danger, +table.m-table tr.m-info td, table.m-table td.m-info, +table.m-table tr.m-info th, table.m-table th.m-info, +table.m-table tr.m-dim td, table.m-table td.m-dim, +table.m-table tr.m-dim th, table.m-table th.m-dim { + border-color: #2f363f; +} +.m-note pre, .m-note code, +table.m-table tr.m-default pre, table.m-table tr.m-default code, +table.m-table td.m-default pre, table.m-table td.m-default code, +table.m-table th.m-default pre, table.m-table th.m-default code, +table.m-table tr.m-primary pre, table.m-table tr.m-primary code, +table.m-table td.m-primary pre, table.m-table td.m-primary code, +table.m-table th.m-primary pre, table.m-table th.m-primary code, +table.m-table tr.m-success pre, table.m-table tr.m-success code, +table.m-table td.m-success pre, table.m-table td.m-success code, +table.m-table th.m-success pre, table.m-table th.m-success code, +table.m-table tr.m-warning pre, table.m-table tr.m-warning code, +table.m-table td.m-warning pre, table.m-table td.m-warning code, +table.m-table th.m-warning pre, table.m-table th.m-warning code, +table.m-table tr.m-danger pre, table.m-table tr.m-danger code, +table.m-table td.m-danger pre, table.m-table td.m-danger code, +table.m-table th.m-danger pre, table.m-table th.m-danger code, +table.m-table tr.m-info pre, table.m-table tr.m-info code, +table.m-table td.m-info pre, table.m-table td.m-info code, +table.m-table th.m-info pre, table.m-table th.m-info code, +table.m-table tr.m-dim pre, table.m-table tr.m-dim code, +table.m-table td.m-dim pre, table.m-table td.m-dim code, +table.m-table th.m-dim pre, table.m-table th.m-dim code { + background-color: rgba(34, 39, 46, 0.5); +} +img.m-image, svg.m-image { + display: block; + margin-left: auto; + margin-right: auto; +} +div.m-image { + text-align: center; +} +img.m-image, svg.m-image, div.m-image img, div.m-image svg { + max-width: 100%; + border-radius: 0.2rem; +} +div.m-image.m-fullwidth img, div.m-image.m-fullwidth svg { + width: 100%; +} +img.m-image.m-badge, div.m-image.m-badge img { + border-radius: 50%; +} +figure.m-figure { + max-width: 100%; + margin-top: 0; + margin-left: auto; + margin-right: auto; + position: relative; + display: table; +} +figure.m-figure::before { + position: absolute; + content: ' '; + top: 0; + bottom: 0; + left: 0; + right: 0; + z-index: -1; + border-style: solid; + border-width: 0.125rem; + border-radius: 0.2rem; + border-color: #405363; +} +figure.m-figure.m-flat::before { + border-color: transparent; +} +figure.m-figure > * { + margin-left: 1rem; + margin-right: 1rem; + display: table-caption; + caption-side: bottom; +} +figure.m-figure > *:first-child { + display: inline; +} +figure.m-figure > *:last-child { + margin-bottom: 1rem !important; +} +figure.m-figure img, figure.m-figure svg { + position: relative; + margin-left: 0; + margin-right: 0; + margin-bottom: 0; + border-top-left-radius: 0.2rem; + border-top-right-radius: 0.2rem; + max-width: 100%; +} +figure.m-figure.m-flat img, figure.m-figure.m-flat svg { + border-bottom-left-radius: 0.2rem; + border-bottom-right-radius: 0.2rem; +} +figure.m-figure a img, figure.m-figure a svg { + margin-left: -1rem; + margin-right: -1rem; +} +figure.m-figure.m-fullwidth, figure.m-figure.m-fullwidth > * { + display: block; +} +figure.m-figure.m-fullwidth > *:first-child { + display: inline; +} +figure.m-figure.m-fullwidth img, figure.m-figure.m-fullwidth svg { + width: 100%; +} +figure.m-figure.m-fullwidth::after { + content: ' '; + display: block; + margin-top: 1rem; + height: 1px; +} +.m-code-figure, .m-console-figure { + margin-top: 0; + margin-left: 0; + margin-right: 0; + position: relative; + padding: 1rem; +} +.m-code-figure::before, .m-console-figure::before { + position: absolute; + content: ' '; + top: 0; + bottom: 0; + left: 0; + right: 0; + z-index: -1; + border-style: solid; + border-width: 0.125rem; + border-radius: 0.2rem; +} +.m-code-figure::before { + border-color: #282e36; +} +.m-console-figure::before { + border-color: #1a1c1d; +} +.m-code-figure.m-flat::before, .m-console-figure.m-flat::before { + border-color: transparent; +} +.m-code-figure > pre:first-child, .m-console-figure > pre:first-child { + position: relative; + margin: -1rem -1rem 1rem -1rem; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} +.m-code-figure > pre.m-nopad, .m-console-figure > pre.m-nopad { + margin-left: -0.875rem; + margin-right: -0.875rem; + margin-top: -1rem; + margin-bottom: -0.875rem; + padding-left: 0.875rem; +} +figure.m-figure figcaption, .m-code-figure figcaption, .m-console-figure figcaption { + margin-top: 0.5rem; + margin-bottom: 0.5rem; + font-weight: 600; + font-size: 1.17rem; +} +figure.m-figure figcaption a, .m-code-figure figcaption a, .m-console-figure figcaption a { + text-decoration: none; +} +figure.m-figure figcaption .m-figure-description { + margin-top: 0.5rem; + font-weight: normal; + font-size: 1rem; +} +figure.m-figure figcaption .m-figure-description a { + text-decoration: underline; +} +.m-imagegrid > div { + background-color: #2f363f; +} +.m-imagegrid > div > figure { + display: block; + float: left; + position: relative; + margin: 0; +} +.m-imagegrid > div > figure > div, +.m-imagegrid > div > figure > figcaption, +.m-imagegrid > div > figure > a > div, +.m-imagegrid > div > figure > a > figcaption { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + border-color: #2f363f; + border-style: solid; + border-width: 0.25rem; + padding: 0.5rem; +} +.m-imagegrid > div > figure:first-child > div, +.m-imagegrid > div > figure:first-child > figcaption, +.m-imagegrid > div > figure:first-child > a > div, +.m-imagegrid > div > figure:first-child > a > figcaption { + border-left-width: 0; +} +.m-imagegrid > div > figure:last-child > div, +.m-imagegrid > div > figure:last-child > figcaption, +.m-imagegrid > div > figure:last-child > a > div, +.m-imagegrid > div > figure:last-child > a > figcaption { + border-right-width: 0; +} +.m-imagegrid > div > figure > figcaption, +.m-imagegrid > div > figure > a > figcaption { + color: transparent; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 0.75rem; +} +.m-imagegrid > div > figure > div::before, +.m-imagegrid > div > figure > figcaption::before, +.m-imagegrid > div > figure > a > div::before, +.m-imagegrid > div > figure > a > figcaption::before { + content: ''; + display: inline-block; + height: 100%; + vertical-align: bottom; + width: 0; +} +.m-imagegrid > div > figure:hover > figcaption, +.m-imagegrid > div > figure:hover > a > figcaption { + background: linear-gradient(transparent 0%, transparent 75%, rgba(0, 0, 0, 0.85) 100%); + color: #ffffff; +} +.m-imagegrid > div > figure > img, +.m-imagegrid > div > figure > a > img { + width: 100%; + height: 100%; +} +.m-imagegrid > div::after { + display: block; + content: ' '; + clear: both; +} +@media screen and (max-width: 767px) { + .m-imagegrid > div > figure { + float: none; + width: 100% !important; + } + .m-imagegrid > div > figure > div, + .m-imagegrid > div > figure > figcaption, + .m-imagegrid > div > figure > a > div, + .m-imagegrid > div > figure > a > figcaption { + border-left-width: 0; + border-right-width: 0; + } +} +.m-container-inflatable > .m-row > [class*='m-col-'] > .m-note, +.m-container-inflatable > .m-row > [class*='m-col-'] > .m-frame, +.m-container-inflatable > .m-row > [class*='m-col-'] > .m-block, +.m-container-inflatable > .m-row > [class*='m-col-'] > .m-imagegrid, +.m-container-inflatable > .m-row > [class*='m-col-'] > pre, +.m-container-inflatable > .m-row > [class*='m-col-'] > .m-code-figure, +.m-container-inflatable > .m-row > [class*='m-col-'] > .m-console-figure, +.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-note, +.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-frame, +.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-block, +.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-imagegrid, +.m-container-inflatable > .m-row > [class*='m-col-'] section > pre, +.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-code-figure, +.m-container-inflatable > .m-row > [class*='m-col-'] section > .m-console-figure, +.m-container-inflatable [class*='m-center-'] > .m-note, +.m-container-inflatable [class*='m-center-'] > .m-frame, +.m-container-inflatable [class*='m-center-'] > .m-block, +.m-container-inflatable [class*='m-center-'] > .m-imagegrid, +.m-container-inflatable [class*='m-center-'] > pre, +.m-container-inflatable [class*='m-center-'] > .m-code-figure, +.m-container-inflatable [class*='m-center-'] > .m-console-figure, +.m-container-inflatable [class*='m-left-'] > .m-note, +.m-container-inflatable [class*='m-left-'] > .m-frame, +.m-container-inflatable [class*='m-left-'] > .m-block, +.m-container-inflatable [class*='m-left-'] > .m-imagegrid, +.m-container-inflatable [class*='m-left-'] > pre, +.m-container-inflatable [class*='m-left-'] > .m-code-figure, +.m-container-inflatable [class*='m-left-'] > .m-console-figure, +.m-container-inflatable [class*='m-right-'] > .m-note, +.m-container-inflatable [class*='m-right-'] > .m-frame, +.m-container-inflatable [class*='m-right-'] > .m-block, +.m-container-inflatable [class*='m-right-'] > .m-imagegrid, +.m-container-inflatable [class*='m-right-'] > pre, +.m-container-inflatable [class*='m-right-'] > .m-code-figure, +.m-container-inflatable [class*='m-right-'] > .m-console-figure, +.m-container-inflatable .m-container-inflate > .m-note, +.m-container-inflatable .m-container-inflate > .m-frame, +.m-container-inflatable .m-container-inflate > .m-block, +.m-container-inflatable .m-container-inflate > .m-imagegrid, +.m-container-inflatable .m-container-inflate > pre, +.m-container-inflatable .m-container-inflate > .m-code-figure, +.m-container-inflatable .m-container-inflate > .m-console-figure +{ + margin-left: -1rem; + margin-right: -1rem; +} +@media screen and (min-width: 576px) { + .m-container-inflatable .m-center-s > .m-note, + .m-container-inflatable .m-center-s > .m-frame, + .m-container-inflatable .m-center-s > .m-block, + .m-container-inflatable .m-center-s > .m-imagegrid, + .m-container-inflatable .m-center-s > pre, + .m-container-inflatable .m-center-s > .m-code-figure, + .m-container-inflatable .m-center-s > .m-console-figure { + margin-left: -1rem; + margin-right: -1rem; + } + .m-container-inflatable .m-left-s > .m-note, + .m-container-inflatable .m-left-s > .m-frame, + .m-container-inflatable .m-left-s > .m-block, + .m-container-inflatable .m-left-s > .m-imagegrid, + .m-container-inflatable .m-left-s > pre, + .m-container-inflatable .m-left-s > .m-code-figure, + .m-container-inflatable .m-left-s > .m-console-figure { + margin-left: -1rem; + margin-right: 0; + } + .m-container-inflatable .m-right-s > .m-note, + .m-container-inflatable .m-right-s > .m-frame, + .m-container-inflatable .m-right-s > .m-block, + .m-container-inflatable .m-right-s > .m-imagegrid, + .m-container-inflatable .m-right-s > pre, + .m-container-inflatable .m-right-s > .m-code-figure, + .m-container-inflatable .m-right-s > .m-console-figure { + margin-left: 0; + margin-right: -1rem; + } + .m-container-inflatable > .m-row > .m-col-s-10 > .m-imagegrid.m-container-inflate, + .m-container-inflatable > .m-row > .m-col-s-10 section > .m-imagegrid.m-container-inflate { + margin-left: -10%; + margin-right: -10%; + } +} +@media screen and (min-width: 768px) { + .m-container-inflatable .m-center-m > .m-note, + .m-container-inflatable .m-center-m > .m-frame, + .m-container-inflatable .m-center-m > .m-block, + .m-container-inflatable .m-center-m > .m-imagegrid, + .m-container-inflatable .m-center-m > pre, + .m-container-inflatable .m-center-m > .m-code-figure, + .m-container-inflatable .m-center-m > .m-console-figure { + margin-left: -1rem; + margin-right: -1rem; + } + .m-container-inflatable .m-left-m > .m-note, + .m-container-inflatable .m-left-m > .m-frame, + .m-container-inflatable .m-left-m > .m-block, + .m-container-inflatable .m-left-m > .m-imagegrid, + .m-container-inflatable .m-left-m > pre, + .m-container-inflatable .m-left-m > .m-code-figure, + .m-container-inflatable .m-left-m > .m-console-figure { + margin-left: -1rem; + margin-right: 0; + } + .m-container-inflatable .m-right-m > .m-note, + .m-container-inflatable .m-right-m > .m-frame, + .m-container-inflatable .m-right-m > .m-block, + .m-container-inflatable .m-right-m > .m-imagegrid, + .m-container-inflatable .m-right-m > pre, + .m-container-inflatable .m-right-m > .m-code-figure, + .m-container-inflatable .m-right-m > .m-console-figure { + margin-left: 0; + margin-right: -1rem; + } + .m-container-inflatable > .m-row > .m-col-m-10 > .m-imagegrid.m-container-inflate, + .m-container-inflatable > .m-row > .m-col-m-10 section > .m-imagegrid.m-container-inflate { + margin-left: -10%; + margin-right: -10%; + } +} +@media screen and (min-width: 992px) { + .m-container-inflatable .m-center-l > .m-note, + .m-container-inflatable .m-center-l > .m-frame, + .m-container-inflatable .m-center-l > .m-block, + .m-container-inflatable .m-center-l > .m-imagegrid, + .m-container-inflatable .m-center-l > pre, + .m-container-inflatable .m-center-l > .m-code-figure, + .m-container-inflatable .m-center-l > .m-console-figure { + margin-left: -1rem; + margin-right: -1rem; + } + .m-container-inflatable .m-left-l > .m-note, + .m-container-inflatable .m-left-l > .m-frame, + .m-container-inflatable .m-left-l > .m-block, + .m-container-inflatable .m-left-l > .m-imagegrid, + .m-container-inflatable .m-left-l > pre, + .m-container-inflatable .m-left-l > .m-code-figure, + .m-container-inflatable .m-left-l > .m-console-figure { + margin-left: -1rem; + margin-right: 0; + } + .m-container-inflatable .m-right-l > .m-note, + .m-container-inflatable .m-right-l > .m-frame, + .m-container-inflatable .m-right-l > .m-block, + .m-container-inflatable .m-right-l > .m-imagegrid, + .m-container-inflatable .m-right-l > pre, + .m-container-inflatable .m-right-l > .m-code-figure, + .m-container-inflatable .m-right-l > .m-console-figure { + margin-left: 0; + margin-right: -1rem; + } + .m-container-inflatable > .m-row > .m-col-l-10 > .m-imagegrid.m-container-inflate, + .m-container-inflatable > .m-row > .m-col-l-10 section > .m-imagegrid.m-container-inflate { + margin-left: -10%; + margin-right: -10%; + } +} +pre.m-code span.hll { + margin-left: -1.0rem; + margin-right: -1.0rem; + padding-left: 1.0rem; +} +.m-code.m-inverted > span, .m-console.m-inverted > span { + opacity: 0.3333; +} +.m-code.m-inverted > span.hll, .m-console.m-inverted > span.hll { + opacity: 1; + background-color: transparent; + border-color: transparent; +} +.m-code.m-inverted { color: rgba(230, 230, 230, 0.33); } +.m-console.m-inverted { color: rgba(230, 230, 230, 0.33); } +.m-code.m-inverted > span.hll { color: #e6e6e6; } +.m-cosole.m-inverted > span.hll { color: #e6e6e6; } +.m-code-color { + display: inline-block; + width: 0.75rem; + height: 0.75rem; + vertical-align: -0.05rem; + margin-left: 0.2rem; + margin-right: 0.1rem; + border-radius: 0.1rem; +} +div.m-math { + overflow-x: auto; + overflow-y: hidden; +} +div.m-math svg { + margin-left: auto; + margin-right: auto; + display: block; +} +div.m-button a svg.m-math { fill: #22272e; } +div.m-button.m-flat a svg.m-math { fill: #dcdcdc; } +div.m-button.m-flat a:hover svg.m-math, div.m-button.m-default a:focus svg.m-math, +div.m-button.m-default a:active svg.m-math { + fill: #a5c9ea; +} +.m-graph { font-size: 16px; } +div.m-plot svg, div.m-graph svg { + max-width: 100%; + margin-left: auto; + margin-right: auto; + display: block; +} +div.m-plot .m-background { fill: #34424d; } +div.m-plot svg .m-label { font-size: 11px; } +div.m-plot svg .m-title { font-size: 13px; } +div.m-plot svg .m-label, div.m-plot svg .m-title { fill: #dcdcdc; } +div.m-plot svg .m-line { + stroke: #dcdcdc; + stroke-width: 0.8; +} +div.m-plot svg .m-error { + stroke: #ffffff; + stroke-width: 1.5; +} +div.m-plot svg .m-label.m-dim { fill: #747474; } +.m-graph g.m-edge path, .m-graph g.m-cluster polygon, +.m-graph g.m-node.m-flat ellipse, +.m-graph g.m-node.m-flat polygon { + fill: none; +} +.m-graph g.m-node:not(.m-flat) text { + fill: #22272e; +} +figure.m-figure > svg.m-math:first-child, +figure.m-figure > svg.m-graph:first-child { + padding: 1rem; + box-sizing: content-box; +} +figure.m-figure:not(.m-flat) > svg.m-math:first-child, +figure.m-figure:not(.m-flat) > svg.m-graph:first-child { + background-color: #405363; +} +.m-block.m-default { border-left-color: #405363; } +.m-block.m-default h3, .m-block.m-default h4, .m-block.m-default h5, .m-block.m-default h6, +.m-text.m-default, .m-label.m-flat.m-default { + color: #dcdcdc; +} +.m-block.m-default h3 a, .m-block.m-default h4 a, .m-block.m-default h5 a, .m-block.m-default h6 a { + color: #5b9dd9; +} +.m-block.m-primary { border-left-color: #a5c9ea; } +.m-block.m-primary h3, .m-block.m-primary h4, .m-block.m-primary h5, .m-block.m-primary h6, +.m-block.m-primary h3 a, .m-block.m-primary h4 a, .m-block.m-primary h5 a, .m-block.m-primary h6 a, +.m-text.m-primary, .m-label.m-flat.m-primary { + color: #a5c9ea; +} +.m-block.m-success { border-left-color: #3bd267; } +.m-block.m-success h3, .m-block.m-success h4, .m-block.m-success h5, .m-block.m-success h6, +.m-block.m-success h3 a, .m-block.m-success h4 a, .m-block.m-success h5 a, .m-block.m-success h6 a, +.m-text.m-success, .m-label.m-flat.m-success { + color: #3bd267; +} +.m-block.m-warning { border-left-color: #c7cf2f; } +.m-block.m-warning h3, .m-block.m-warning h4, .m-block.m-warning h5, .m-block.m-warning h6, +.m-block.m-warning h3 a, .m-block.m-warning h4 a, .m-block.m-warning h5 a, .m-block.m-warning h6 a, +.m-text.m-warning, .m-label.m-flat.m-warning { + color: #c7cf2f; +} +.m-block.m-danger { border-left-color: #cd3431; } +.m-block.m-danger h3, .m-block.m-danger h4, .m-block.m-danger h5, .m-block.m-danger h6, +.m-block.m-danger h3 a, .m-block.m-danger h4 a, .m-block.m-danger h5 a, .m-block.m-danger h6 a, +.m-text.m-danger, .m-label.m-flat.m-danger { + color: #cd3431; +} +.m-block.m-info { border-left-color: #2f83cc; } +.m-block.m-info h3, .m-block.m-info h4, .m-block.m-info h5, .m-block.m-info h6, +.m-block.m-info h3 a, .m-block.m-info h4 a, .m-block.m-info h5 a, .m-block.m-info h6 a, +.m-text.m-info, .m-label.m-flat.m-info { + color: #2f83cc; +} +.m-block.m-dim { border-left-color: #747474; } +.m-block.m-dim, .m-text.m-dim, .m-label.m-flat.m-dim { + color: #747474; +} +.m-block.m-dim a, .m-text.m-dim a { color: #acacac; } +.m-block.m-dim a:hover, .m-block.m-dim a:focus, .m-block.m-dim a:active, +.m-text.m-dim a:hover, .m-text.m-dim a:focus, .m-text.m-dim a:active { + color: #747474; +} +.m-block.m-flat { border-color: transparent; } +.m-block.m-flat h3, .m-block.m-flat h4, .m-block.m-flat h5, .m-block.m-flat h6 { + color: #dcdcdc; +} +.m-block.m-default h3 a:hover, .m-block.m-default h3 a:focus, .m-block.m-default h3 a:active, +.m-block.m-default h4 a:hover, .m-block.m-default h4 a:focus, .m-block.m-default h4 a:active, +.m-block.m-default h5 a:hover, .m-block.m-default h5 a:focus, .m-block.m-default h5 a:active, +.m-block.m-default h6 a:hover, .m-block.m-default h6 a:focus, .m-block.m-default h6 a:active { + color: #a5c9ea; +} +.m-block.m-primary h3 a:hover, .m-block.m-primary h3 a:focus, .m-block.m-primary h3 a:active, +.m-block.m-primary h4 a:hover, .m-block.m-primary h4 a:focus, .m-block.m-primary h4 a:active, +.m-block.m-primary h5 a:hover, .m-block.m-primary h5 a:focus, .m-block.m-primary h5 a:active, +.m-block.m-primary h6 a:hover, .m-block.m-primary h6 a:focus, .m-block.m-primary h6 a:active { + color: #dcdcdc; +} +.m-block.m-success h3 a:hover, .m-block.m-success h3 a:focus, .m-block.m-success h3 a:active, +.m-block.m-success h4 a:hover, .m-block.m-success h4 a:focus, .m-block.m-success h4 a:active, +.m-block.m-success h5 a:hover, .m-block.m-success h5 a:focus, .m-block.m-success h5 a:active, +.m-block.m-success h6 a:hover, .m-block.m-success h6 a:focus, .m-block.m-success h6 a:active { + color: #acecbe; +} +.m-block.m-warning h3 a:hover, .m-block.m-warning h3 a:focus, .m-block.m-warning h3 a:active, +.m-block.m-warning h4 a:hover, .m-block.m-warning h4 a:focus, .m-block.m-warning h4 a:active, +.m-block.m-warning h5 a:hover, .m-block.m-warning h5 a:focus, .m-block.m-warning h5 a:active, +.m-block.m-warning h6 a:hover, .m-block.m-warning h6 a:focus, .m-block.m-warning h6 a:active { + color: #e9ecae; +} +.m-block.m-danger h3 a:hover, .m-block.m-danger h3 a:focus, .m-block.m-danger h3 a:active, +.m-block.m-danger h4 a:hover, .m-block.m-danger h4 a:focus, .m-block.m-danger h4 a:active, +.m-block.m-danger h5 a:hover, .m-block.m-danger h5 a:focus, .m-block.m-danger h5 a:active, +.m-block.m-danger h6 a:hover, .m-block.m-danger h6 a:focus, .m-block.m-danger h6 a:active { + color: #ff9391; +} +.m-block.m-info h3 a:hover, .m-block.m-info h3 a:focus, .m-block.m-info h3 a:active, +.m-block.m-info h4 a:hover, .m-block.m-info h4 a:focus, .m-block.m-info h4 a:active, +.m-block.m-info h5 a:hover, .m-block.m-info h5 a:focus, .m-block.m-info h5 a:active, +.m-block.m-info h6 a:hover, .m-block.m-info h6 a:focus, .m-block.m-info h6 a:active { + color: #5297d7; +} +div.m-button a, .m-label { color: #22272e; } +div.m-button.m-flat a { color: #dcdcdc; } +div.m-button.m-flat a:hover, div.m-button.m-default a:focus, div.m-button.m-default a:active { + color: #a5c9ea; +} +div.m-button.m-default a, .m-label:not(.m-flat).m-default { background-color: #dcdcdc; } +div.m-button.m-primary a, .m-label:not(.m-flat).m-primary { background-color: #a5c9ea; } +div.m-button.m-success a, .m-label:not(.m-flat).m-success { background-color: #3bd267; } +div.m-button.m-warning a, .m-label:not(.m-flat).m-warning { background-color: #c7cf2f; } +div.m-button.m-danger a, .m-label:not(.m-flat).m-danger { background-color: #cd3431; } +div.m-button.m-info a, .m-label:not(.m-flat).m-info { background-color: #2f83cc; } +div.m-button.m-dim a, .m-label:not(.m-flat).m-dim { background-color: #747474; } +div.m-button.m-default a:hover, div.m-button.m-default a:focus, div.m-button.m-default a:active { + background-color: #a5c9ea; +} +div.m-button.m-primary a:hover, div.m-button.m-primary a:focus, div.m-button.m-primary a:active { + background-color: #dcdcdc; +} +div.m-button.m-success a:hover, div.m-button.m-success a:focus, div.m-button.m-success a:active { + background-color: #acecbe; +} +div.m-button.m-warning a:hover, div.m-button.m-warning a:focus, div.m-button.m-warning a:active { + background-color: #e9ecae; +} +div.m-button.m-danger a:hover, div.m-button.m-danger a:focus, div.m-button.m-danger a:active { + background-color: #ff9391; +} +div.m-button.m-info a:hover, div.m-button.m-info a:focus, div.m-button.m-info a:active { + background-color: #5297d7; +} +div.m-button.m-dim a:hover, div.m-button.m-dim a:focus, div.m-button.m-dim a:active { + background-color: #acacac; +} +.m-note.m-default { background-color: #34424d; } +.m-note.m-default, +table.m-table tr.m-default td, table.m-table td.m-default, +table.m-table tr.m-default th, table.m-table th.m-default { + color: #dcdcdc; +} +.m-note.m-default a:hover, +table.m-table tr.m-default td a:hover, table.m-table td.m-default a:hover, +table.m-table tr.m-default th a:hover, table.m-table th.m-default a:hover, +.m-note.m-default a:focus, +table.m-table tr.m-default td a:focus, table.m-table td.m-default a:focus, +table.m-table tr.m-default th a:focus, table.m-table th.m-default a:focus, +.m-note.m-default a:active, +table.m-table tr.m-default td a:active, table.m-table td.m-default a:active, +table.m-table tr.m-default th a:active, table.m-table th.m-default a:active { + color: #a5c9ea; +} +.m-note.m-primary a, +table.m-table tr.m-primary td a, table.m-table td.m-primary a, +table.m-table tr.m-primary th a, table.m-table th.m-primary a { + color: #5b9dd9; +} +.m-note.m-primary, +table.m-table tr.m-primary td, table.m-table td.m-primary, +table.m-table tr.m-primary th, table.m-table th.m-primary { + background-color: #a5c2db; + color: #2f363f; +} +.m-note.m-primary a, +table.m-table tr.m-primary td a, table.m-table td.m-primary a, +table.m-table tr.m-primary th a, table.m-table th.m-primary a { + color: #2a75b6; +} +.m-note.m-primary a:hover, +table.m-table tr.m-primary td a:hover, table.m-table td.m-primary a:hover, +table.m-table tr.m-primary th a:hover, table.m-table th.m-primary a:hover, +.m-note.m-primary a:focus, +table.m-table tr.m-primary td a:focus, table.m-table td.m-primary a:focus, +table.m-table tr.m-primary th a:focus, table.m-table th.m-primary a:focus, +.m-note.m-primary a:active, +table.m-table tr.m-primary td a:active, table.m-table td.m-primary a:active, +table.m-table tr.m-primary th a:active, table.m-table th.m-primary a:active { + color: #2f363f; +} +.m-note.m-success, +table.m-table tr.m-success td, table.m-table td.m-success, +table.m-table tr.m-success th, table.m-table th.m-success { + background-color: #2a703f; + color: #acecbe; +} +.m-note.m-success a, +table.m-table tr.m-success td a, table.m-table td.m-success a, +table.m-table tr.m-success th a, table.m-table th.m-success a { + color: #3bd267; +} +.m-note.m-success a:hover, +table.m-table tr.m-success td a:hover, table.m-table td.m-success a:hover, +table.m-table tr.m-success th a:hover, table.m-table th.m-success a:hover, +.m-note.m-success a:focus, +table.m-table tr.m-success td a:focus, table.m-table td.m-success a:focus, +table.m-table tr.m-success th a:focus, table.m-table th.m-success a:focus, +.m-note.m-success a:active, +table.m-table tr.m-success td a:active, table.m-table td.m-success a:active, +table.m-table tr.m-success th a:active, table.m-table th.m-success a:active { + color: #acecbe; +} +.m-note.m-warning, table.m-table tr.m-warning td, table.m-table td.m-warning, + table.m-table tr.m-warning th, table.m-table th.m-warning { + background-color: #6d702a; + color: #e9ecae; +} +.m-note.m-warning a, table.m-table tr.m-warning td a, table.m-table td.m-warning a, + table.m-table tr.m-warning th a, table.m-table th.m-warning a { + color: #b8bf2b; +} +.m-note.m-warning a:hover, +table.m-table tr.m-warning td a:hover, table.m-table td.m-warning a:hover, +table.m-table tr.m-warning th a:hover, table.m-table th.m-warning a:hover, +.m-note.m-warning a:focus, +table.m-table tr.m-warning td a:focus, table.m-table td.m-warning a:focus, +table.m-table tr.m-warning th a:focus, table.m-table th.m-warning a:focus, +.m-note.m-warning a:active, +table.m-table tr.m-warning td a:active, table.m-table td.m-warning a:active, +table.m-table tr.m-warning th a:active, table.m-table th.m-warning a:active { + color: #e9ecae; +} +.m-note.m-danger, +table.m-table tr.m-danger td, table.m-table td.m-danger, +table.m-table tr.m-danger th, table.m-table th.m-danger { + background-color: #702b2a; + color: #ff9391; +} +.m-note.m-danger a, +table.m-table tr.m-danger td a, table.m-table td.m-danger a, +table.m-table tr.m-danger th a, table.m-table th.m-danger a { + color: #d85c59; +} +.m-note.m-danger a:hover, +table.m-table tr.m-danger td a:hover, table.m-table td.m-danger a:hover, +table.m-table tr.m-danger th a:hover, table.m-table th.m-danger a:hover, +.m-note.m-danger a:focus, +table.m-table tr.m-danger td a:focus, table.m-table td.m-danger a:focus, +table.m-table tr.m-danger th a:focus, table.m-table th.m-danger a:focus, +.m-note.m-danger a:active, +table.m-table tr.m-danger td a:active, table.m-table td.m-danger a:active, +table.m-table tr.m-danger th a:active, table.m-table th.m-danger a:active { + color: #ff9391; +} +.m-note.m-info, +table.m-table tr.m-info td, table.m-table td.m-info, +table.m-table tr.m-info th, table.m-table th.m-info { + background-color: #2a4f70; + color: #a5caeb; +} +.m-note.m-info a, +table.m-table tr.m-info td a, table.m-table td.m-info a, +table.m-table tr.m-info th a, table.m-table th.m-info a { + color: #5297d7; +} +.m-note.m-info a:hover, +table.m-table tr.m-info td a:hover, table.m-table td.m-info a:hover, +table.m-table tr.m-info th a:hover, table.m-table th.m-info a:hover, +.m-note.m-info a:focus, +table.m-table tr.m-info td a:focus, table.m-table td.m-info a:focus, +table.m-table tr.m-info th a:focus, table.m-table th.m-info a:focus, +.m-note.m-info a:active, +table.m-table tr.m-info td a:active, table.m-table td.m-info a:active, +table.m-table tr.m-info th a:active, table.m-table th.m-info a:active { + color: #a5caeb; +} +.m-note.m-dim, +table.m-table tr.m-dim td, table.m-table td.m-dim, +table.m-table tr.m-dim th, table.m-table th.m-dim { + background-color: #2d3236; + color: #747474; +} +.m-note.m-dim a, +table.m-table tr.m-dim td a, table.m-table td.m-dim a, +table.m-table tr.m-dim th a, table.m-table th.m-dim a { + color: #acacac; +} +.m-note.m-dim a:hover, +table.m-table tr.m-dim td a:hover, table.m-table td.m-dim a:hover, +table.m-table tr.m-dim th a:hover, table.m-table th.m-dim a:hover, +.m-note.m-dim a:focus, +table.m-table tr.m-dim td a:focus, table.m-table td.m-dim a:focus, +table.m-table tr.m-dim th a:focus, table.m-table th.m-dim a:focus, +.m-note.m-dim a:active, +table.m-table tr.m-dim td a:active, table.m-table td.m-dim a:active, +table.m-table tr.m-dim th a:active, table.m-table th.m-dim a:active { + color: #747474; +} +figure.m-figure.m-default::before { border-color: #34424d; } +figure.m-figure.m-default figcaption { color: #dcdcdc; } +figure.m-figure.m-primary::before { border-color: #a5c2db; } +figure.m-figure.m-primary figcaption { color: #a5c9ea; } +figure.m-figure.m-primary figcaption .m-figure-description { color: #dcdcdc; } +figure.m-figure.m-success::before { border-color: #2a703f; } +figure.m-figure.m-success figcaption { color: #3bd267; } +figure.m-figure.m-success figcaption .m-figure-description { color: #dcdcdc; } +figure.m-figure.m-warning::before { border-color: #6d702a; } +figure.m-figure.m-warning figcaption { color: #c7cf2f; } +figure.m-figure.m-warning figcaption .m-figure-description { color: #dcdcdc; } +figure.m-figure.m-danger::before { border-color: #702b2a; } +figure.m-figure.m-danger figcaption { color: #cd3431; } +figure.m-figure.m-danger figcaption .m-figure-description { color: #dcdcdc; } +figure.m-figure.m-info::before { border-color: #2a4f70; } +figure.m-figure.m-info figcaption { color: #2f83cc; } +figure.m-figure.m-info figcaption .m-figure-description { color: #dcdcdc; } +figure.m-figure.m-dim::before { border-color: #2d3236; } +figure.m-figure.m-dim { color: #747474; } +figure.m-figure.m-dim a { color: #acacac; } +figure.m-figure.m-dim a:hover, figure.m-figure.m-dim a:focus, figure.m-figure.m-dim a:active { + color: #747474; +} +.m-math { fill: #dcdcdc; } +.m-math.m-default, .m-math g.m-default, .m-math rect.m-default, +div.m-plot svg .m-bar.m-default, +.m-graph g.m-edge polygon, +.m-graph g.m-node:not(.m-flat) ellipse, +.m-graph g.m-node:not(.m-flat) polygon, +.m-graph g.m-edge text, +.m-graph g.m-node.m-flat text, +.m-graph g.m-cluster text, +.m-graph.m-default g.m-edge polygon, +.m-graph.m-default g.m-node:not(.m-flat) ellipse, +.m-graph.m-default g.m-node:not(.m-flat) polygon, +.m-graph.m-default g.m-edge text, +.m-graph.m-default g.m-node.m-flat text, +.m-graph.m-default g.m-cluster text { + fill: #dcdcdc; +} +.m-graph g.m-edge polygon, +.m-graph g.m-edge path, +.m-graph g.m-node ellipse, +.m-graph g.m-node polygon, +.m-graph g.m-node polyline, +.m-graph g.m-cluster polygon, +.m-graph.m-default g.m-edge polygon, +.m-graph.m-default g.m-edge path, +.m-graph.m-default g.m-node ellipse, +.m-graph.m-default g.m-node polygon, +.m-graph.m-default g.m-node polyline, +.m-graph.m-default g.m-cluster polygon { + stroke: #dcdcdc; +} +.m-math.m-primary, .m-math g.m-primary, .m-math rect.m-primary, +div.m-plot svg .m-bar.m-primary, +.m-graph.m-primary g.m-edge polygon, +.m-graph.m-primary g.m-node:not(.m-flat) ellipse, +.m-graph.m-primary g.m-node:not(.m-flat) polygon, +.m-graph.m-primary g.m-edge text, +.m-graph.m-primary g.m-node.m-flat text, +.m-graph.m-primary g.m-cluster text { + fill: #a5c9ea; +} +.m-graph.m-primary g.m-edge polygon, +.m-graph.m-primary g.m-edge path, +.m-graph.m-primary g.m-node ellipse, +.m-graph.m-primary g.m-node polygon, +.m-graph.m-primary g.m-node polyline, +.m-graph.m-primary g.m-cluster polygon { + stroke: #a5c9ea; +} +.m-math.m-success, .m-math g.m-success, .m-math rect.m-success, +div.m-plot svg .m-bar.m-success, +.m-graph.m-success g.m-edge polygon, +.m-graph.m-success g.m-node:not(.m-flat) ellipse, +.m-graph.m-success g.m-node:not(.m-flat) polygon, +.m-graph.m-success g.m-edge text, +.m-graph.m-success g.m-node.m-flat text, +.m-graph.m-success g.m-cluster text { + fill: #3bd267; +} +.m-graph.m-success g.m-edge polygon, +.m-graph.m-success g.m-edge path, +.m-graph.m-success g.m-node ellipse, +.m-graph.m-success g.m-node polygon, +.m-graph.m-success g.m-node polyline, +.m-graph.m-success g.m-cluster polygon { + stroke: #3bd267; +} +.m-math.m-warning, .m-math g.m-warning, .m-math rect.m-warning, +div.m-plot svg .m-bar.m-warning, +.m-graph.m-warning g.m-edge polygon, +.m-graph.m-warning g.m-node:not(.m-flat) ellipse, +.m-graph.m-warning g.m-node:not(.m-flat) polygon, +.m-graph.m-warning g.m-edge text, +.m-graph.m-warning g.m-node.m-flat text, +.m-graph.m-warning g.m-cluster text { + fill: #c7cf2f; +} +.m-graph.m-warning g.m-edge polygon, +.m-graph.m-warning g.m-edge path, +.m-graph.m-warning g.m-node ellipse, +.m-graph.m-warning g.m-node polygon, +.m-graph.m-warning g.m-node polyline, +.m-graph.m-warning g.m-cluster polygon { + stroke: #c7cf2f; +} +.m-math.m-danger, .m-math g.m-danger, .m-math rect.m-danger, +div.m-plot svg .m-bar.m-danger, +.m-graph.m-danger g.m-edge polygon, +.m-graph.m-danger g.m-node:not(.m-flat) ellipse, +.m-graph.m-danger g.m-node:not(.m-flat) polygon, +.m-graph.m-danger g.m-edge text, +.m-graph.m-danger g.m-node.m-flat text, +.m-graph.m-danger g.m-cluster text { + fill: #cd3431; +} +.m-graph.m-danger g.m-edge polygon, +.m-graph.m-danger g.m-edge path, +.m-graph.m-danger g.m-node ellipse, +.m-graph.m-danger g.m-node polygon, +.m-graph.m-danger g.m-node polyline, +.m-graph.m-danger g.m-cluster polygon { + stroke: #cd3431; +} +.m-math.m-info, .m-math g.m-info, .m-math rect.m-info, +div.m-plot svg .m-bar.m-info, +.m-graph.m-info g.m-edge polygon, +.m-graph.m-info g.m-node:not(.m-flat) ellipse, +.m-graph.m-info g.m-node:not(.m-flat) polygon, +.m-graph.m-info g.m-edge text, +.m-graph.m-info g.m-node.m-flat text, +.m-graph.m-info g.m-cluster text { + fill: #2f83cc; +} +.m-graph.m-info g.m-edge polygon, +.m-graph.m-info g.m-edge path, +.m-graph.m-info g.m-node ellipse, +.m-graph.m-info g.m-node polygon, +.m-graph.m-info g.m-node polyline, +.m-graph.m-info g.m-cluster polygon { + stroke: #2f83cc; +} +.m-math.m-dim, .m-math g.m-dim, .m-math rect.m-dim, +div.m-plot svg .m-bar.m-dim, +.m-graph.m-dim g.m-edge polygon, +.m-graph.m-dim g.m-node:not(.m-flat) ellipse, +.m-graph.m-dim g.m-node:not(.m-flat) polygon, +.m-graph.m-dim g.m-edge text, +.m-graph.m-dim g.m-node.m-flat text, +.m-graph.m-dim g.m-cluster text { + fill: #747474; +} +.m-graph.m-dim g.m-edge polygon, +.m-graph.m-dim g.m-edge path, +.m-graph.m-dim g.m-node ellipse, +.m-graph.m-dim g.m-node polygon, +.m-graph.m-dim g.m-node polyline, +.m-graph.m-dim g.m-cluster polygon { + stroke: #747474; +} +.m-graph g.m-edge.m-default polygon, +.m-graph g.m-node.m-default:not(.m-flat) ellipse, +.m-graph g.m-node.m-default:not(.m-flat) polygon, +.m-graph g.m-edge.m-default text, +.m-graph g.m-node.m-default.m-flat text, +.m-graph g.m-cluster.m-default text { + fill: #dcdcdc; +} +.m-graph g.m-edge.m-default polygon, +.m-graph g.m-edge.m-default path, +.m-graph g.m-node.m-default ellipse, +.m-graph g.m-node.m-default polygon, +.m-graph g.m-node.m-default polyline, +.m-graph g.m-cluster.m-default polygon { + stroke: #dcdcdc; +} +.m-graph g.m-edge.m-primary polygon, +.m-graph g.m-node.m-primary:not(.m-flat) ellipse, +.m-graph g.m-node.m-primary:not(.m-flat) polygon, +.m-graph g.m-edge.m-primary text, +.m-graph g.m-node.m-primary.m-flat text, +.m-graph g.m-cluster.m-primary text { + fill: #a5c9ea; +} +.m-graph g.m-edge.m-primary polygon, +.m-graph g.m-edge.m-primary path, +.m-graph g.m-node.m-primary ellipse, +.m-graph g.m-node.m-primary polygon, +.m-graph g.m-node.m-primary polyline, +.m-graph g.m-cluster.m-primary polygon { + stroke: #a5c9ea; +} +.m-graph g.m-edge.m-success polygon, +.m-graph g.m-node.m-success:not(.m-flat) ellipse, +.m-graph g.m-node.m-success:not(.m-flat) polygon, +.m-graph g.m-edge.m-success text, +.m-graph g.m-node.m-success.m-flat text, +.m-graph g.m-cluster.m-success text { + fill: #3bd267; +} +.m-graph g.m-edge.m-success polygon, +.m-graph g.m-edge.m-success path, +.m-graph g.m-node.m-success ellipse, +.m-graph g.m-node.m-success polygon, +.m-graph g.m-node.m-success polyline, +.m-graph g.m-cluster.m-success polygon { + stroke: #3bd267; +} +.m-graph g.m-edge.m-warning polygon, +.m-graph g.m-node.m-warning:not(.m-flat) ellipse, +.m-graph g.m-node.m-warning:not(.m-flat) polygon, +.m-graph g.m-edge.m-warning text, +.m-graph g.m-node.m-warning.m-flat text, +.m-graph g.m-cluster.m-warning text { + fill: #c7cf2f; +} +.m-graph g.m-edge.m-warning polygon, +.m-graph g.m-edge.m-warning path, +.m-graph g.m-node.m-warning ellipse, +.m-graph g.m-node.m-warning polygon, +.m-graph g.m-node.m-warning polyline, +.m-graph g.m-cluster.m-warning polygon { + stroke: #c7cf2f; +} +.m-graph g.m-edge.m-danger polygon, +.m-graph g.m-node.m-danger:not(.m-flat) ellipse, +.m-graph g.m-node.m-danger:not(.m-flat) polygon, +.m-graph g.m-edge.m-danger text, +.m-graph g.m-node.m-danger.m-flat text, +.m-graph g.m-cluster.m-danger text { + fill: #cd3431; +} +.m-graph g.m-edge.m-danger polygon, +.m-graph g.m-edge.m-danger path, +.m-graph g.m-node.m-danger ellipse, +.m-graph g.m-node.m-danger polygon, +.m-graph g.m-node.m-danger polyline, +.m-graph g.m-cluster.m-danger polygon { + stroke: #cd3431; +} +.m-graph g.m-edge.m-info polygon, +.m-graph g.m-node.m-info:not(.m-flat) ellipse, +.m-graph g.m-node.m-info:not(.m-flat) polygon, +.m-graph g.m-edge.m-info text, +.m-graph g.m-node.m-info.m-flat text, +.m-graph g.m-cluster.m-info text { + fill: #2f83cc; +} +.m-graph g.m-edge.m-info polygon, +.m-graph g.m-edge.m-info path, +.m-graph g.m-node.m-info ellipse, +.m-graph g.m-node.m-info polygon, +.m-graph g.m-node.m-info polyline, +.m-graph g.m-cluster.m-info polygon { + stroke: #2f83cc; +} +.m-graph g.m-edge.m-dim polygon, +.m-graph g.m-node.m-dim:not(.m-flat) ellipse, +.m-graph g.m-node.m-dim:not(.m-flat) polygon, +.m-graph g.m-edge.m-dim text, +.m-graph g.m-node.m-dim.m-flat text, +.m-graph g.m-cluster.m-dim text { + fill: #747474; +} +.m-graph g.m-edge.m-dim polygon, +.m-graph g.m-edge.m-dim path, +.m-graph g.m-node.m-dim ellipse, +.m-graph g.m-node.m-dim polygon, +.m-graph g.m-node.m-dim polyline, +.m-graph g.m-cluster.m-dim polygon { + stroke: #747474; +} +p, ul, ol, dl, blockquote, pre, .m-code-figure, .m-console-figure, hr, .m-note, +.m-frame, .m-block, div.m-button, div.m-scroll, table.m-table, div.m-image, +img.m-image, svg.m-image, figure.m-figure, .m-imagegrid, div.m-math, +div.m-graph, div.m-plot { + margin-bottom: 1rem; +} +p:last-child, p.m-nopadb, ul:last-child, ul.m-nopadb, +ol:last-child, ol.m-nopadb, dl:last-child, dl.m-nopadb, +blockquote:last-child, blockquote.m-nopadb, pre:last-child, pre.m-nopadb, +.m-code-figure:last-child, .m-code-figure.m-nopadb, +.m-console-figure:last-child, .m-console-figure.m-nopadb, +hr:last-child, hr.m-nopadb, .m-note:last-child, .m-note.m-nopadb, +.m-frame:last-child, .m-frame.m-nopadb, .m-block:last-child, .m-block.m-nopadb, +div.m-button:last-child, div.m-button.m-nopadb, +div.m-scroll:last-child, div.m-scroll.m-nopadb, +table.m-table:last-child, table.m-table.m-nopadb, +img.m-image:last-child, img.m-image.m-nopadb, +svg.m-image:last-child, svg.m-image.m-nopadb, +div.m-image:last-child, div.m-image.m-nopadb, +figure.m-figure:last-child, figure.m-figure.m-nopadb, +.m-imagegrid:last-child, .m-imagegrid.m-nopadb, +div.m-math:last-child, div.m-math.m-nopadb, +div.m-graph:last-child, div.m-graph.m-nopadb, +div.m-plot:last-child, div.m-plot.m-nopadb { + margin-bottom: 0; +} +li > p:last-child, li > blockquote:last-child, li > pre:last-child, +li > .m-code-figure:last-child, li > .m-console-figure:last-child, +li > .m-note:last-child, li > .m-frame:last-child, li > .m-block:last-child, +li > div.m-button:last-child, li > div.m-scroll:last-child, li > table.m-table:last-child, +li > img.m-image:last-child, li > svg.m-image:last-child, li > div.m-image:last-child, +li > figure.m-figure:last-child, li > div.m-math:last-child, +li > div.m-graph:last-child, li > div.m-plot:last-child { + margin-bottom: 1rem; +} +li:last-child > p:last-child, li:last-child > p.m-nopadb, +li:last-child > blockquote:last-child, li:last-child > blockquote.m-nopadb, +li:last-child > pre:last-child, li:last-child > pre.m-nopadb, +li:last-child > .m-code-figure:last-child, li:last-child > .m-code-figure.m-nopadb, +li:last-child > .m-console-figure:last-child, li:last-child > .m-console-figure.m-nopadb, +li:last-child > .m-note:last-child, li:last-child > .m-note.m-nopadb, +li:last-child > .m-frame:last-child, li:last-child > .m-frame.m-nopadb, +li:last-child > .m-block:last-child, li:last-child > .m-block.m-nopadb, +li:last-child > div.m-button:last-child, li:last-child > div.m-button.m-nopadb, +li:last-child > div.m-scroll:last-child, li:last-child > div.m-scroll.m-nopadb, +li:last-child > table.m-table:last-child, li:last-child > table.m-table.m-nopadb, +li:last-child > img.m-image:last-child, li:last-child > img.m-image.m-nopadb, +li:last-child > svg.m-image:last-child, li:last-child > svg.m-image.m-nopadb, +li:last-child > div.m-image:last-child, li:last-child > div.m-image.m-nopadb, +li:last-child > figure.m-figure:last-child, li:last-child > figure.m-figure.m-nopadb, +li:last-child > div.m-math:last-child, li:last-child > div.m-math.m-nopadb, +li:last-child > div.m-graph:last-child, li:last-child > div.m-graph.m-nopadb, +li:last-child > div.m-plot:last-child, li:last-child > div.m-plot.m-nopadb { + margin-bottom: 0; +} + +body > header > nav { + width: 100%; + background-color: #22272e; + min-height: 3rem; +} +body > header > nav.m-navbar-landing, +body > header > nav.m-navbar-cover { + background-color: transparent; + position: relative; +} +body > header > nav.m-navbar-landing { + opacity: 0.8; +} +body > header > nav.m-navbar-cover { + background-color: rgba(34, 39, 46, 0.25); + opacity: 1; +} +body > header > nav.m-navbar-landing:hover, +body > header > nav.m-navbar-cover:hover { + background-color: rgba(34, 39, 46, 0.75); + opacity: 1; +} +body> header > nav.m-navbar-landing:target, +body> header > nav.m-navbar-cover:target { + background-color: #22272e; + opacity: 1; +} +body > header > nav.m-navbar-landing #m-navbar-brand.m-navbar-brand-hidden { + visibility: hidden; +} +body > header > nav.m-navbar-landing:target #m-navbar-brand.m-navbar-brand-hidden { + visibility: visible; +} +body > header > nav { + margin-left: auto; + margin-right: auto; + color: #ffffff; +} +body > header > nav a { + text-decoration: none; + text-transform: none; + display: inline-block; + vertical-align: middle; + line-height: 2.75rem; + color: #ffffff; +} +body > header > nav #m-navbar-brand, body > header > nav a#m-navbar-show, body > header > nav a#m-navbar-hide { + font-weight: 600; + font-size: 1.125rem; + padding-left: 1rem; + padding-right: 1rem; +} +body > header > nav a#m-navbar-brand, body > header > nav #m-navbar-brand a { + text-transform: uppercase; +} +body > header > nav a#m-navbar-brand img, body > header > nav #m-navbar-brand a img { + width: 1.75rem; + height: 1.75rem; + vertical-align: -22.5%; + margin-right: 0.5rem; +} +body > header > nav #m-navbar-brand a { + padding-left: 0; + padding-right: 0; +} +body > header > nav #m-navbar-brand .m-thin { + font-weight: normal; +} +body > header > nav #m-navbar-brand .m-breadcrumb { + color: #747474; +} +body > header > nav a#m-navbar-show::before, body > header > nav a#m-navbar-hide::before { + content:'\2630'; +} +body > header > nav #m-navbar-collapse { + padding-bottom: 1rem; +} +body > header > nav #m-navbar-collapse li { + border-style: solid; + border-color: transparent; + border-width: 0 0 0 0.25rem; + margin-left: -1rem; +} +body > header > nav #m-navbar-collapse li a { + border-style: solid; + border-color: transparent; + line-height: 1.5rem; + margin-left: -0.25rem; + padding-left: 0.75rem; + border-width: 0 0 0 0.25rem; + width: 100%; +} +body > header > nav #m-navbar-collapse li a#m-navbar-current { + color: #5b9dd9; + border-color: #5b9dd9; +} +body > header > nav ol { + list-style-type: none; + margin: 0; +} +body > header > nav ol ol { + padding-left: 1.5rem; +} +body > header > nav .m-row > [class*='m-col-'] { + padding-top: 0; + padding-bottom: 0; +} +body > header > nav a:hover, body > header > nav a:focus, body > header > nav a:active { + color: #a5c9ea; +} +body > header > nav #m-navbar-collapse li:hover { + border-color: #a5c9ea; +} +body > header > nav #m-navbar-collapse li a:hover, +body > header > nav #m-navbar-collapse li a:focus, +body > header > nav #m-navbar-collapse li a:active { + border-color: #a5c9ea; + background-color: #292f37; +} +body > header > nav.m-navbar-landing #m-navbar-collapse li a:hover, +body > header > nav.m-navbar-cover #m-navbar-collapse li a:hover, +body > header > nav.m-navbar-landing #m-navbar-collapse li a:focus, +body > header > nav.m-navbar-cover #m-navbar-collapse li a:focus, +body > header > nav.m-navbar-landing #m-navbar-collapse li a:active, +body > header > nav.m-navbar-cover #m-navbar-collapse li a:active { + background-color: rgba(41, 47, 55, 0.5); +} +body > header > nav #m-navbar-hide { + display: none; +} +body > header > nav:target #m-navbar-collapse { + display: block; +} +body > header > nav:target #m-navbar-show { + display: none; +} +body > header > nav:target #m-navbar-hide { + display: inline-block; +} +@media screen and (min-width: 768px) { + body > header > nav #m-navbar-show, body > header > nav #m-navbar-hide, + body > header > nav:target #m-navbar-show, body > header > nav:target #m-navbar-hide { + display: none; + } + body > header > nav #m-navbar-collapse li a { + line-height: 2.75rem; + } + body > header > nav a, body > header > nav #m-navbar-collapse li a { + margin-left: 0; + padding-left: 1rem; + padding-right: 1rem; + white-space: nowrap; + } + body > header > nav #m-navbar-collapse { + padding-bottom: 0; + } + body > header > nav #m-navbar-collapse li ol { + background-color: #22272e; + } + body > header > nav #m-navbar-collapse ol ol li { + margin-left: 0; + padding-left: 0; + border-left-width: 0; + } + body > header > nav #m-navbar-collapse ol ol li a { + padding-left: 0.75rem; + } + body > header > nav #m-navbar-collapse > .m-row > ol > li { + margin-left: 0; + border-left-width: 0; + } + body > header > nav #m-navbar-collapse > .m-row > ol > li > a { + border-width: 0 0 0.25rem 0; + } + body > header > nav #m-navbar-collapse ol { + padding-left: 0; + padding-right: 0; + } + body > header > nav #m-navbar-collapse > .m-row > ol, body > header > nav #m-navbar-collapse > .m-row > ol > li { + float: left; + } + body > header > nav #m-navbar-collapse ol ol { + z-index: 99999; + position: absolute; + visibility: hidden; + } + body > header > nav #m-navbar-collapse li:hover ol { + visibility: visible; + } +} +body > footer { + width: 100%; +} +body > footer > nav { + padding-top: 1rem; + padding-bottom: 1rem; + font-size: 0.85rem; + text-align: center; + color: #c5c5c5; + background-color: #444e5c; +} +body > footer > nav h3, body > footer > nav h3 a { + text-transform: uppercase; + font-weight: normal; +} +body > footer > nav ul { + list-style-type: none; + padding: 0; + margin: 0; +} +body > footer > nav a { + text-decoration: none; + text-transform: none; + color: #ffffff; +} +body > footer > nav a:hover, body > footer > nav a:focus, body > footer > nav a:active { + color: #a5c9ea; +} +body > main { + padding-top: 1rem; + padding-bottom: 1rem; +} +article h1 { + font-size: 1.75rem; +} +article h1 .m-breadcrumb { + color: #747474; + font-weight: normal; +} +article h1 .m-breadcrumb a { + color: #a5c9ea; +} +article h1 .m-breadcrumb a:hover, article h1 a:focus, article h1 a:active { + color: #dcdcdc; +} +article > header h1 { + font-size: 2rem; + margin-bottom: 0.5rem; +} +article h1 a, article > header h1, article > header h1 a, +article section > h2, article section > h2 a, +article section > h3, article section > h3 a, +article section > h4, article section > h4 a, +article section > h5, article section > h5 a, +article section > h6, article section > h6 a { + color: #a5c9ea; +} +article h1 a:hover, article > header h1 a:hover, article > header h1 a:focus, article > header h1 a:active, +article section > h2 a:hover, article section > h2 a:focus, article section > h2 a:active, +article section > h3 a:hover, article section > h3 a:focus, article section > h3 a:active, +article section > h4 a:hover, article section > h4 a:focus, article section > h4 a:active, +article section > h5 a:hover, article section > h5 a:focus, article section > h5 a:active, +article section > h6 a:hover, article section > h6 a:focus, article section > h6 a:active { + color: #dcdcdc; +} +article > header .m-date { + display: block; + width: 2.5rem; + float: left; + text-align: center; + line-height: 95%; + font-size: 0.75rem; + font-weight: normal; + white-space: nowrap; + border-right-style: solid; + border-right-width: 0.125rem; + border-color: #a5c9ea; + padding-right: 0.75rem; + margin-top: -0.1rem; + margin-right: 0.75rem; + margin-bottom: 0.25rem; +} +article > header .m-date-day { + display: block; + font-weight: bold; + padding-top: 0.2rem; + padding-bottom: 0.15rem; + font-size: 1.25rem; +} +article > header p { + color: #f0f0f0; + font-size: 1.125rem; +} +article > header h1::after { + content: " "; + clear: both; + display: table; +} +article > footer { + color: #c5c5c5; +} +article > footer p { + font-style: italic; + font-size: 0.85rem; + text-indent: 0; +} +article section:target { + margin-left: -1.0rem; + border-left-style: solid; + border-left-width: 0.25rem; + padding-left: 0.75rem; + border-color: #a5c9ea; +} +article h1 a, article > header h1 a, article section > h2 a, article section > h3 a, +article section > h4 a, article section > h5 a, article section > h6 a { + text-decoration: none; +} +#m-landing-image, #m-cover-image, article#m-jumbo > header #m-jumbo-image { + background-size: cover; + background-color: #0f1217; + background-position: center center; + background-repeat: no-repeat; + margin-top: -4rem; + padding-top: 5rem; +} +#m-landing-image { + color: #ffffff; +} +#m-cover-image { + height: 30rem; + margin-bottom: -26rem; +} +#m-landing-cover h1 { + font-size: 2.8rem; + margin-top: -0.5rem; + padding-left: 1.5rem; + padding-bottom: 1rem; + text-transform: lowercase; +} +#m-landing-cover { + padding-bottom: 10rem; + margin-bottom: -6rem; +} +article#m-jumbo { + margin-top: -1rem; +} +#m-landing-cover, #m-cover-image > div, article#m-jumbo > header #m-jumbo-cover { + background: linear-gradient(transparent 0%, transparent 50%, #2f363f 100%); + width: 100%; + height: 100%; +} +article#m-jumbo > header h1, article#m-jumbo > header h2 { + text-align: center; + font-weight: bold; +} +article#m-jumbo > header a { + text-decoration: none; +} +article#m-jumbo > header #m-jumbo-cover { + padding-bottom: 5rem; +} +article#m-jumbo > header #m-jumbo-image { + font-size: 2vmin; + margin-bottom: -3rem; +} +article#m-jumbo > header h1 { + font-size: 8vmin; +} +article#m-jumbo > header h2 { + font-size: 3vmin; +} +@media screen and (max-height: 640px) , screen and (max-width: 640px) { + article#m-jumbo > header h1 { + font-size: 3rem; + } + article#m-jumbo > header #m-jumbo-image, article#m-jumbo > header h2 { + font-size: 1rem; + } +} +article#m-jumbo > header, article#m-jumbo > header h1, article#m-jumbo > header a { + color: #ffffff; +} +article#m-jumbo > header a:hover, article#m-jumbo > header a:focus, article#m-jumbo > header a:active { + color: #f0f0f0; +} +article#m-jumbo.m-inverted > header, article#m-jumbo.m-inverted > header h1, article#m-jumbo.m-inverted > header a { + color: #000000; +} +article#m-jumbo.m-inverted > header a:hover, article#m-jumbo.m-inverted > header a:focus, article#m-jumbo.m-inverted > header a:active { + color: #0f0f0f; +} +.m-landing-news h3 a { + color: #dcdcdc; + text-decoration: none; + text-transform: uppercase; +} +.m-landing-news h3 a:hover, .m-landing-news h3 a:hover, .m-landing-news h3 a:focus, .m-landing-news h3 a:active { + color: #a5c9ea; +} +.m-landing-news time { + display: inline-block; + margin-left: 1rem; + float: right; +} +.m-article-pagination { + text-align: center; + padding: 1rem; +} +nav.m-navpanel { + text-align: center; +} +nav.m-navpanel h3 { + text-transform: uppercase; + font-weight: normal; +} +nav.m-navpanel ol { + text-transform: lowercase; +} +nav.m-navpanel ol, nav.m-navpanel ul { + list-style-type: none; + padding: 0; +} +nav.m-navpanel a { + color: #ffffff; + text-decoration: none; +} +nav.m-navpanel a:hover, nav.m-navpanel a:focus, nav.m-navpanel a:active { + color: #a5c9ea; +} +ul.m-tagcloud li { display: inline; } +ul.m-tagcloud li.m-tag-1 { font-size: 0.75rem; } +ul.m-tagcloud li.m-tag-2 { font-size: 0.825rem; } +ul.m-tagcloud li.m-tag-3 { font-size: 1rem; } +ul.m-tagcloud li.m-tag-4 { font-size: 1.25rem; } +ul.m-tagcloud li.m-tag-5 { font-size: 1.5rem; } +article section:target figure.m-code-figure, article section:target figure.m-console-figure { + z-index: 1; +} +article, article > header, article section { margin-bottom: 1rem; } +article:last-child, article section:last-child { margin-bottom: 0; } +.m-container-inflatable section:target > .m-note, +.m-container-inflatable section:target > .m-frame, +.m-container-inflatable section:target > .m-block, +.m-container-inflatable section:target > pre, +.m-container-inflatable section:target > .m-code-figure > pre:first-child, +.m-container-inflatable section:target > .m-console-figure > pre:first-child, +.m-container-inflatable section:target section > .m-note, +.m-container-inflatable section:target section > .m-frame, +.m-container-inflatable section:target section > .m-block, +.m-container-inflatable section:target section > pre, +.m-container-inflatable section:target section > .m-code-figure > pre:first-child, +.m-container-inflatable section:target section > .m-console-figure > pre:first-child, +.m-container-inflatable section:target [class*='m-center-'] > .m-note, +.m-container-inflatable section:target [class*='m-center-'] > .m-frame, +.m-container-inflatable section:target [class*='m-center-'] > .m-block, +.m-container-inflatable section:target [class*='m-center-'] > pre, +.m-container-inflatable section:target [class*='m-center-'] > .m-code-figure > pre:first-child, +.m-container-inflatable section:target [class*='m-center-'] > .m-console-figure > pre:first-child, +.m-container-inflatable section:target [class*='m-left-'] > .m-note, +.m-container-inflatable section:target [class*='m-left-'] > .m-frame, +.m-container-inflatable section:target [class*='m-left-'] > .m-block, +.m-container-inflatable section:target [class*='m-left-'] > pre, +.m-container-inflatable section:target [class*='m-left-'] > .m-code-figure > pre:first-child, +.m-container-inflatable section:target [class*='m-left-'] > .m-console-figure > pre:first-child, +.m-container-inflatable section:target [class*='m-right-'] > .m-note, +.m-container-inflatable section:target [class*='m-right-'] > .m-frame, +.m-container-inflatable section:target [class*='m-right-'] > .m-block, +.m-container-inflatable section:target [class*='m-right-'] > pre, +.m-container-inflatable section:target [class*='m-right-'] > .m-code-figure > pre:first-child, +.m-container-inflatable section:target [class*='m-right-'] > .m-console-figure > pre:first-child, +.m-container-inflatable section:target .m-container-inflate > .m-note, +.m-container-inflatable section:target .m-container-inflate > .m-frame, +.m-container-inflatable section:target .m-container-inflate > .m-block, +.m-container-inflatable section:target .m-container-inflate > pre, +.m-container-inflatable section:target .m-container-inflate > .m-code-figure > pre:first-child, +.m-container-inflatable section:target .m-container-inflate > .m-console-figure > pre:first-child { + margin-left: -1.0rem; + border-left-style: solid; + border-left-width: 0.25rem; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + padding-left: 0.75rem; +} +.m-container-inflatable section:target > .m-code-figure::before, +.m-container-inflatable section:target > .m-console-figure::before, +.m-container-inflatable section:target section > .m-code-figure::before, +.m-container-inflatable section:target section > .m-console-figure::before, +.m-container-inflatable section:target [class*='m-center-'] > .m-code-figure::before, +.m-container-inflatable section:target [class*='m-center-'] > .m-console-figure::before, +.m-container-inflatable section:target [class*='m-left-'] > .m-code-figure::before, +.m-container-inflatable section:target [class*='m-left-'] > .m-console-figure::before, +.m-container-inflatable section:target [class*='m-right-'] > .m-code-figure::before, +.m-container-inflatable section:target [class*='m-right-'] > .m-console-figure::before, +.m-container-inflatable section:target .m-container-inflate > .m-code-figure::before, +.m-container-inflatable section:target .m-container-inflate > .m-console-figure::before { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + border-left-width: 0.25rem; +} +.m-container-inflatable section:target > .m-code-figure > pre.m-nopad, +.m-container-inflatable section:target > .m-console-figure > pre.m-nopad { + margin-left: -0.75rem; + padding-left: -0.75rem; +} +@media screen and (min-width: 576px) { + .m-container-inflatable section:target .m-center-s > .m-note, + .m-container-inflatable section:target .m-center-s > pre, + .m-container-inflatable section:target .m-center-s > figure.m-code-figure > pre:first-child, + .m-container-inflatable section:target .m-center-s > figure.m-console-figure > pre:first-child, + .m-container-inflatable section:target .m-right-s > figure.m-code-figure > pre:first-child, + .m-container-inflatable section:target .m-right-s > figure.m-console-figure > pre:first-child { + border-left-width: 0; + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; + padding-left: 1rem; + } + .m-container-inflatable section:target .m-center-s > .m-block, + .m-container-inflatable section:target .m-right-s > .m-block { + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; + } + .m-container-inflatable section:target .m-center-s > .m-frame, + .m-container-inflatable section:target .m-right-s > .m-frame { + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; + border-left-width: 0.125rem; + padding-left: 0.875rem; + } + .m-container-inflatable section:target .m-right-s > .m-block, + .m-container-inflatable section:target .m-right-s > .m-frame { + margin-left: 0; + } + .m-container-inflatable section:target .m-right-s > .m-note, + .m-container-inflatable section:target .m-right-s > pre { + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; + margin-left: 0; + border-left-width: 0; + padding-left: 1rem; + } + .m-container-inflatable section:target .m-center-s > figure.m-code-figure::before, + .m-container-inflatable section:target .m-center-s > figure.m-console-figure::before, + .m-container-inflatable section:target .m-right-s > figure.m-code-figure::before, + .m-container-inflatable section:target .m-right-s > figure.m-console-figure::before { + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; + border-left-width: 0.125rem; + } +} +@media screen and (min-width: 768px) { + .m-container-inflatable section:target .m-center-m > .m-note, + .m-container-inflatable section:target .m-center-m > pre, + .m-container-inflatable section:target .m-center-m > figure.m-code-figure > pre:first-child, + .m-container-inflatable section:target .m-center-m > figure.m-console-figure > pre:first-child, + .m-container-inflatable section:target .m-right-m > figure.m-code-figure > pre:first-child, + .m-container-inflatable section:target .m-right-m > figure.m-console-figure > pre:first-child { + border-left-width: 0; + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; + padding-left: 1rem; + } + .m-container-inflatable section:target .m-center-m > .m-block, + .m-container-inflatable section:target .m-right-m > .m-block { + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; + } + .m-container-inflatable section:target .m-center-m > .m-frame, + .m-container-inflatable section:target .m-right-m > .m-frame { + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; + border-left-width: 0.125rem; + padding-left: 0.875rem; + } + .m-container-inflatable section:target .m-right-m > .m-block, + .m-container-inflatable section:target .m-right-m > .m-frame { + margin-left: 0; + } + .m-container-inflatable section:target .m-right-m > .m-note, + .m-container-inflatable section:target .m-right-m > pre { + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; + margin-left: 0; + border-left-width: 0; + padding-left: 1rem; + } + .m-container-inflatable section:target .m-center-m > figure.m-code-figure::before, + .m-container-inflatable section:target .m-center-m > figure.m-console-figure::before, + .m-container-inflatable section:target .m-right-m > figure.m-code-figure::before, + .m-container-inflatable section:target .m-right-m > figure.m-console-figure::before { + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; + border-left-width: 0.125rem; + } +} +@media screen and (min-width: 992px) { + .m-container-inflatable section:target .m-center-l > .m-note, + .m-container-inflatable section:target .m-center-l > pre, + .m-container-inflatable section:target .m-center-l > figure.m-code-figure > pre:first-child, + .m-container-inflatable section:target .m-center-l > figure.m-console-figure > pre:first-child, + .m-container-inflatable section:target .m-right-l > figure.m-code-figure > pre:first-child, + .m-container-inflatable section:target .m-right-l > figure.m-console-figure > pre:first-child { + border-left-width: 0; + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; + padding-left: 1rem; + } + .m-container-inflatable section:target .m-center-l > .m-block, + .m-container-inflatable section:target .m-right-l > .m-block { + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; + } + .m-container-inflatable section:target .m-center-l > .m-frame, + .m-container-inflatable section:target .m-right-l > .m-frame { + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; + border-left-width: 0.125rem; + padding-left: 0.875rem; + } + .m-container-inflatable section:target .m-right-l > .m-block, + .m-container-inflatable section:target .m-right-l > .m-frame { + margin-left: 0; + } + .m-container-inflatable section:target .m-right-l > .m-note, + .m-container-inflatable section:target .m-right-l > pre { + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; + margin-left: 0; + border-left-width: 0; + padding-left: 1rem; + } + .m-container-inflatable section:target .m-center-l > figure.m-code-figure::before, + .m-container-inflatable section:target .m-center-l > figure.m-console-figure::before, + .m-container-inflatable section:target .m-right-l > figure.m-code-figure::before, + .m-container-inflatable section:target .m-right-l > figure.m-console-figure::before { + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; + border-left-width: 0.125rem; + } +} +.m-container-inflatable section:target > figure.m-code-figure::before, +.m-container-inflatable section:target > figure.m-console-figure::before, +.m-container-inflatable section:target section > figure.m-code-figure::before, +.m-container-inflatable section:target section > figure.m-console-figure::before, +.m-container-inflatable section:target [class*='m-center-'] > figure.m-code-figure::before, +.m-container-inflatable section:target [class*='m-center-'] > figure.m-console-figure::before, +.m-container-inflatable section:target [class*='m-left-'] > figure.m-code-figure::before, +.m-container-inflatable section:target [class*='m-left-'] > figure.m-console-figure::before, +.m-container-inflatable section:target [class*='m-right-'] > figure.m-code-figure::before, +.m-container-inflatable section:target [class*='m-right-'] > figure.m-console-figure::before, +.m-container-inflatable section:target .m-container-inflatable > figure.m-code-figure::before, +.m-container-inflatable section:target .m-container-inflatable > figure.m-console-figure::before { + border-left-color: #405363; +} +@media screen and (min-width: 576px) { + .m-container-inflatable section:target .m-center-s > figure.m-code-figure::before, + .m-container-inflatable section:target .m-right-s > figure.m-code-figure::before { + border-color: #282e36; + } + .m-container-inflatable section:target .m-center-s > figure.m-console-figure::before, + .m-container-inflatable section:target .m-right-s > figure.m-console-figure::before { + border-color: #1a1c1d; + } +} +@media screen and (min-width: 768px) { + .m-container-inflatable section:target .m-center-m > figure.m-code-figure::before, + .m-container-inflatable section:target .m-right-m > figure.m-code-figure::before { + border-color: #282e36; + } + .m-container-inflatable section:target .m-center-m > figure.m-console-figure::before, + .m-container-inflatable section:target .m-right-m > figure.m-console-figure::before { + border-color: #1a1c1d; + } +} +@media screen and (min-width: 992px) { + .m-container-inflatable section:target .m-center-l > figure.m-code-figure::before, + .m-container-inflatable section:target .m-right-l > figure.m-code-figure::before { + border-color: #282e36; + } + .m-container-inflatable section:target .m-center-l > figure.m-console-figure::before, + .m-container-inflatable section:target .m-right-l > figure.m-console-figure::before { + border-color: #1a1c1d; + } +} +.m-container-inflatable section:target pre, +.m-container-inflatable section:target figure.m-code-figure > pre:first-child, +.m-container-inflatable section:target figure.m-console-figure > pre:first-child { + border-color: #405363; +} +.m-container-inflatable section:target .m-note.m-default { + border-color: #405363; +} +.m-container-inflatable section:target .m-note.m-primary { + border-color: #a5c9ea; +} +.m-container-inflatable section:target .m-note.m-success { + border-color: #3bd267; +} +.m-container-inflatable section:target .m-note.m-warning { + border-color: #c7cf2f; +} +.m-container-inflatable section:target .m-note.m-danger { + border-color: #cd3431; +} +.m-container-inflatable section:target .m-note.m-info { + border-color: #2f83cc; +} +.m-container-inflatable section:target .m-note.m-dim { + border-color: #747474; +} + +.m-code .hll { background-color: #34424d } +.m-code .c { color: #a5c9ea } +.m-code .k { color: #ffffff; font-weight: bold } +.m-code .n { color: #dcdcdc } +.m-code .o { color: #aaaaaa } +.m-code .p { color: #aaaaaa } +.m-code .ch { color: #a5c9ea } +.m-code .cm { color: #a5c9ea } +.m-code .cp { color: #3bd267 } +.m-code .cpf { color: #c7cf2f } +.m-code .c1 { color: #a5c9ea } +.m-code .cs { color: #a5c9ea } +.m-code .gd { color: #cd3431 } +.m-code .ge { color: #e6e6e6; font-style: italic } +.m-code .gh { color: #ffffff; font-weight: bold } +.m-code .gi { color: #3bd267 } +.m-code .gs { color: #e6e6e6; font-weight: bold } +.m-code .gu { color: #5b9dd9 } +.m-code .kc { color: #ffffff; font-weight: bold } +.m-code .kd { color: #ffffff; font-weight: bold } +.m-code .kn { color: #ffffff; font-weight: bold } +.m-code .kp { color: #ffffff; font-weight: bold } +.m-code .kr { color: #ffffff; font-weight: bold } +.m-code .kt { color: #ffffff; font-weight: bold } +.m-code .m { color: #c7cf2f } +.m-code .s { color: #e07f7c } +.m-code .na { color: #dcdcdc; font-weight: bold } +.m-code .nb { color: #ffffff; font-weight: bold } +.m-code .nc { color: #dcdcdc; font-weight: bold } +.m-code .no { color: #dcdcdc } +.m-code .nd { color: #dcdcdc } +.m-code .ni { color: #dcdcdc } +.m-code .ne { color: #dcdcdc } +.m-code .nf { color: #dcdcdc } +.m-code .nl { color: #dcdcdc } +.m-code .nn { color: #dcdcdc } +.m-code .nx { color: #dcdcdc } +.m-code .py { color: #dcdcdc } +.m-code .nt { color: #dcdcdc; font-weight: bold } +.m-code .nv { color: #c7cf2f } +.m-code .ow { color: #dcdcdc; font-weight: bold } +.m-code .mb { color: #c7cf2f } +.m-code .mf { color: #c7cf2f } +.m-code .mh { color: #c7cf2f } +.m-code .mi { color: #c7cf2f } +.m-code .mo { color: #c7cf2f } +.m-code .sa { color: #e07f7c } +.m-code .sb { color: #e07f7c } +.m-code .sc { color: #e07cdc } +.m-code .dl { color: #e07f7c } +.m-code .sd { color: #e07f7c } +.m-code .s2 { color: #e07f7c } +.m-code .se { color: #e07cdc } +.m-code .sh { color: #e07f7c } +.m-code .si { color: #a5c9ea } +.m-code .sx { color: #e07f7c } +.m-code .sr { color: #e07f7c } +.m-code .s1 { color: #e07f7c } +.m-code .ss { color: #e07f7c } +.m-code .bp { color: #ffffff; font-weight: bold } +.m-code .fm { color: #dcdcdc } +.m-code .vc { color: #c7cf2f } +.m-code .vg { color: #c7cf2f } +.m-code .vi { color: #c7cf2f } +.m-code .vm { color: #c7cf2f } +.m-code .il { color: #c7cf2f } + +.m-console .hll { background-color: #ffffcc } +.m-console .g-AnsiBackgroundBlack { background-color: #232627 } +.m-console .g-AnsiBackgroundBlue { background-color: #1d99f3 } +.m-console .g-AnsiBackgroundBrightBlack { background-color: #7f8c8d } +.m-console .g-AnsiBackgroundBrightBlue { background-color: #3daee9 } +.m-console .g-AnsiBackgroundBrightCyan { background-color: #16a085 } +.m-console .g-AnsiBackgroundBrightGreen { background-color: #1cdc9a } +.m-console .g-AnsiBackgroundBrightMagenta { background-color: #8e44ad } +.m-console .g-AnsiBackgroundBrightRed { background-color: #c0392b } +.m-console .g-AnsiBackgroundBrightWhite { background-color: #ffffff } +.m-console .g-AnsiBackgroundBrightYellow { background-color: #fdbc4b } +.m-console .g-AnsiBackgroundCyan { background-color: #1abc9c } +.m-console .g-AnsiBackgroundGreen { background-color: #11d116 } +.m-console .g-AnsiBackgroundMagenta { background-color: #9b59b6 } +.m-console .g-AnsiBackgroundRed { background-color: #ed1515 } +.m-console .g-AnsiBackgroundWhite { background-color: #fcfcfc } +.m-console .g-AnsiBackgroundYellow { background-color: #f67400 } +.m-console .g-AnsiBlack { color: #232627 } +.m-console .g-AnsiBlue { color: #1d99f3 } +.m-console .g-AnsiBrightBlack { color: #7f8c8d; font-weight: bold } +.m-console .g-AnsiBrightBlue { color: #3daee9; font-weight: bold } +.m-console .g-AnsiBrightCyan { color: #16a085; font-weight: bold } +.m-console .g-AnsiBrightDefault { color: #ffffff; font-weight: bold } +.m-console .g-AnsiBrightGreen { color: #1cdc9a; font-weight: bold } +.m-console .g-AnsiBrightInvertedDefault { color: #1a1c1d; font-weight: bold } +.m-console .g-AnsiBrightMagenta { color: #8e44ad; font-weight: bold } +.m-console .g-AnsiBrightRed { color: #c0392b; font-weight: bold } +.m-console .g-AnsiBrightWhite { color: #ffffff; font-weight: bold } +.m-console .g-AnsiBrightYellow { color: #fdbc4b; font-weight: bold } +.m-console .g-AnsiCyan { color: #1abc9c } +.m-console .g-AnsiGreen { color: #11d116 } +.m-console .g-AnsiInvertedDefault { color: #1a1c1d } +.m-console .g-AnsiMagenta { color: #9b59b6 } +.m-console .g-AnsiRed { color: #ed1515 } +.m-console .g-AnsiWhite { color: #fcfcfc } +.m-console .g-AnsiYellow { color: #f67400 } +.m-console .go { color: #fcfcfc } +.m-console .gp { color: #16a085; font-weight: bold } +.m-console .w { color: #fcfcfc } + +a.m-doc, a.m-doc-self, a.m-doc-external, +ul.m-doc li.m-doc-expansible > a:first-child, ul.m-doc li.m-doc-collapsible > a:first-child, +.m-code.m-inverted.m-doc-include > a { + text-decoration: none; +} +a.m-doc, a.m-doc-self { + font-weight: bold; +} +.m-thin a.m-doc, .m-thin a.m-doc-self { + font-weight: normal; +} +ul.m-doc li.m-doc-expansible > a:first-child, +ul.m-doc li.m-doc-collapsible > a:first-child, +ul.m-doc li.m-doc-expansible > a:first-child:hover, +ul.m-doc li.m-doc-expansible > a:first-child:focus, +ul.m-doc li.m-doc-expansible > a:first-child:active, +ul.m-doc li.m-doc-collapsible > a:first-child:hover, +ul.m-doc li.m-doc-collapsible > a:first-child:focus, +ul.m-doc li.m-doc-collapsible > a:first-child:active { + color: #dcdcdc; +} +a.m-doc-self, +ul.m-doc li.m-doc-expansible > a:first-child::before, +ul.m-doc li.m-doc-collapsible > a:first-child::before { + color: #a5c9ea; +} +a.m-doc-self:hover, a.m-doc-self:focus, a.m-doc-self:active, +ul.m-doc li.m-doc-expansible > a:first-child:hover::before, +ul.m-doc li.m-doc-expansible > a:first-child:focus::before, +ul.m-doc li.m-doc-expansible > a:first-child:active::before, +ul.m-doc li.m-doc-collapsible > a:first-child:hover::before, +ul.m-doc li.m-doc-collapsible > a:first-child:focus::before, +ul.m-doc li.m-doc-collapsible > a:first-child:active::before { + color: #dcdcdc; +} +h3 a.m-doc-external { + font-weight: normal; +} +span.m-doc-wrap-bumper { + margin-right: -1rem; +} +span.m-doc-wrap { + margin-left: 1rem; + display: inline-block; + vertical-align: text-top; + white-space: pre-line; + max-width: 100%; +} +dl.m-doc dd { + margin-bottom: 0.5rem; +} +dl.m-doc dd { + margin-left: 0; + padding-left: 2.5rem; +} +dl.m-doc dt:target, dl.m-doc dt:target + dd { + margin-left: -1.0rem; + border-left-style: solid; + border-left-width: 0.25rem; + border-color: #a5c9ea; +} +dl.m-doc dt:target { padding-left: 0.75rem; } +dl.m-doc dt:target + dd { padding-left: 3.25rem; } +ul.m-doc { + list-style: none; + margin-left: 1.0375rem; + padding-left: 0.9rem; + border-left-color: #405363; + border-left-width: 0.0625rem; + border-left-style: solid; +} +ul.m-doc li { + text-indent: -1rem; + padding-left: 1rem; +} +ul.m-doc li.m-doc-expansible > ul { + display: none; +} +ul.m-doc li.m-doc-expansible, ul.m-doc li.m-doc-collapsible { + padding-left: 0.6rem; +} +ul.m-doc li.m-doc-expansible > ul.m-doc, ul.m-doc li.m-doc-collapsible > ul.m-doc { + margin-left: 0.5rem; +} +ul.m-doc li.m-doc-expansible > a:first-child::before, ul.m-doc li.m-doc-collapsible > a:first-child::before { + background-color: #2f363f; + display: inline-block; + width: 0.4rem; + font-weight: bold; +} +ul.m-doc li.m-doc-expansible > a:first-child::before { content: '⊕'; } +ul.m-doc li.m-doc-collapsible > a:first-child::before { content: '⊖'; } +h1 .m-doc-template, h1 .m-doc-include { + font-size: 1.3rem; + font-weight: normal; +} +h1 .m-doc-include:last-child { + margin-bottom: -0.5rem; +} +h3 .m-doc-template, h3 .m-doc-include { + font-size: 1rem; + font-weight: normal; +} +.m-doc-template, dl.m-doc dd, ul.m-doc li > span.m-doc { + color: #747474; +} +dl.m-doc dd svg.m-math, ul.m-doc li > span.m-doc svg.m-math { + fill: #747474; +} +.m-doc-template a, dl.m-doc dd a, ul.m-doc li > span.m-doc a { + color: #acacac; +} +.m-doc-template a:hover, .m-doc-template a:focus, .m-doc-template a:active, +dl.m-doc dd a:hover, dl.m-doc dd a:focus, dl.m-doc dd a:active, +ul.m-doc li > span.m-doc a:hover, ul.m-doc li > span.m-doc a:focus, ul.m-doc li > span.m-doc a:active { + color: #747474; +} +.m-code.m-inverted.m-doc-include > a:link, +.m-code.m-inverted.m-doc-include > a:visited { + opacity: 0.6666; +} +.m-code.m-inverted.m-doc-include > a:hover, +.m-code.m-inverted.m-doc-include > a:focus, +.m-code.m-inverted.m-doc-include > a:active { + opacity: 1; +} +article section.m-doc-details > div { + margin-top: 0; + margin-left: 0; + margin-right: 0; + position: relative; + padding: 1rem; +} +article section.m-doc-details > div::before { + position: absolute; + content: ' '; + top: 0; + bottom: 0; + left: 0; + right: 0; + z-index: -1; + border-style: solid; + border-width: 0.125rem; + border-radius: 0.2rem; + border-color: #282e36; +} +article section.m-doc-details > div > h3:first-child { + position: relative; + margin: -1rem -1rem 1rem -1rem; + padding: 0.5rem 1rem; + background-color: #282e36; + border-top-left-radius: 0.2rem; + border-top-right-radius: 0.2rem; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} +article section.m-doc-details:target { + border-color: transparent; +} +article section.m-doc-details:target > div { + z-index: 1; +} +.m-container-inflatable > .m-row > [class*='m-col-'] section.m-doc-details > div { + margin-left: -1rem; + margin-right: -1rem; +} +.m-container-inflatable section.m-doc-details:target > div > h3:first-child, +.m-container-inflatable section.m-doc-details:target section > div > h3:first-child { + margin-left: -1.0rem; + border-left-style: solid; + border-left-color: #dcdcdc; + border-left-width: 0.25rem; + padding-left: 0.75rem; +} +.m-container-inflatable section.m-doc-details:target > div::before, +.m-container-inflatable section-dox-details:target section > div.m::before { + border-left-width: 0.25rem; + border-left-color: #a5c9ea; +} +a.m-doc-search-icon { + padding-left: 1rem; + padding-right: 1rem; +} +a.m-doc-search-icon svg { + fill: #ffffff; +} +body > header > nav #m-navbar-collapse a.m-doc-search-icon svg { + vertical-align: -5%; +} +a.m-doc-search-icon:focus svg, a.m-doc-search-icon:hover svg, a.m-doc-search-icon:active svg { + fill: #a5c9ea; +} +.m-doc-search { + display: none; + z-index: 10; + position: fixed; + left: 0; + right: 0; + top: 0; + bottom: 0; + background-color: rgba(34, 39, 46, 0.75); +} +.m-doc-search:target { + display: block; +} +.m-doc-search > a { + display: block; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; +} +.m-doc-search-header { + margin-top: 2.5rem; + padding: 0.5rem 1rem; + height: 2rem; +} +.m-doc-search-header > div:first-child { + float: right; +} +.m-doc-search-content { + background-color: #22272e; + border-radius: 0.2rem; + padding: 1rem; +} +.m-doc-search input { + width: 100%; + height: 3rem; + font-size: 1.2rem; + border-width: 0; + color: #dcdcdc; + background-color: #34424d; + border-radius: 0.2rem; + margin-bottom: 1rem; + padding: 0 1rem; +} +.m-doc-search #search-notfound { + display: none; +} +.m-doc-search ul#search-results { + list-style-type: none; + padding-left: 0; + max-height: calc(100vh - 12.5rem); + overflow-y: auto; + display: none; +} +.m-doc-search ul#search-results li a { + display: block; + padding-left: 1rem; + padding-right: 1rem; + text-decoration: none; + width: 100%; + line-height: 1.5rem; + color: #dcdcdc; +} +.m-doc-search ul#search-results li a > div { + white-space: nowrap; + overflow: hidden; +} +.m-doc-search ul#search-results li a > div:not(.m-doc-search-alias) { + direction: rtl; +} +.m-doc-search ul#search-results li a .m-label { + float: right; + line-height: 1rem; + margin-top: 0.1rem; + margin-left: 0.25rem; +} +.m-doc-search ul#search-results li a .m-label.m-flat { + margin-right: -0.75rem; +} +.m-doc-search ul#search-results li#search-current a { + background-color: #34424d; +} +.m-doc-search ul#search-results li#search-current.m-doc-search-copied a { + background-color: #2a703f; +} +.m-doc-search-typed { + color: #5b9dd9; +} +.m-doc-search input[type="search"] { -webkit-appearance: textfield; } +.m-doc-search input[type="search"]::-webkit-search-decoration, +.m-doc-search input[type="search"]::-webkit-search-cancel-button, +.m-doc-search input[type="search"]::-webkit-search-results-button, +.m-doc-search input[type="search"]::-webkit-search-results-decoration { + display: none; +} diff --git a/docs-preview/pr-1032/map_8hpp.html b/docs-preview/pr-1032/map_8hpp.html new file mode 100644 index 000000000..010a196bc --- /dev/null +++ b/docs-preview/pr-1032/map_8hpp.html @@ -0,0 +1,102 @@ + + + + + core/reflection/external/map.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/mask_8hpp.html b/docs-preview/pr-1032/mask_8hpp.html new file mode 100644 index 000000000..e6fe199c1 --- /dev/null +++ b/docs-preview/pr-1032/mask_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/reflection/traits/mask.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/mass_8hpp.html b/docs-preview/pr-1032/mass_8hpp.html new file mode 100644 index 000000000..aece7a1a7 --- /dev/null +++ b/docs-preview/pr-1032/mass_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/physics/components/mass.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/material_8hpp.html b/docs-preview/pr-1032/material_8hpp.html new file mode 100644 index 000000000..d86627927 --- /dev/null +++ b/docs-preview/pr-1032/material_8hpp.html @@ -0,0 +1,136 @@ + + + + + engine/voxels/material.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/meta_8hpp.html b/docs-preview/pr-1032/meta_8hpp.html new file mode 100644 index 000000000..7621b39f0 --- /dev/null +++ b/docs-preview/pr-1032/meta_8hpp.html @@ -0,0 +1,136 @@ + + + + + engine/assets/meta.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ engine/assets/meta.hpp file +

+

Class cubos::engine::AssetMeta.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::engine
+
Engine module.
+
+
+
+

Classes

+
+
+ class cubos::engine::AssetMeta +
+
Stores metadata about an asset - the data stored in .meta files. Each asset has a corresponding meta object, which contains load or import parameters.
+
+ struct cubos::engine::AssetMeta::Exclude +
+
Used as context to exclude parameters from being serialized.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/modules.html b/docs-preview/pr-1032/modules.html new file mode 100644 index 000000000..ad699a37e --- /dev/null +++ b/docs-preview/pr-1032/modules.html @@ -0,0 +1,197 @@ + + + + + CUBOS. Docs + + + + + + + +
+
+
+
+
+

Modules

+
    +
  • + module Core CUBOS. core library. +
      +
    • module Audio Provides audio functionality.
    • +
    • + module Data Provides filesystem and serialization utilities. + +
    • +
    • + module ECS Entity Component System library. +
        +
      • module Entity Entity part of the ECS.
      • +
      • module Query Defines the query functionality of the ECS.
      • +
      • module Resource Resource part of the ECS.
      • +
      • + module System System part of the ECS. +
          +
        • module Arguments Contains types and fetcher specializations for system argument types.
        • +
        +
      • +
      • module Table Contains various table-like data structures which storage data associated to entities.
      • +
      +
    • +
    • module Geometry Provides geometry utilities.
    • +
    • module Graphics Provides a graphics API abstraction.
    • +
    • module Input and output Provides a window API abstraction.
    • +
    • module Memory Provides a stream library and memory utilities.
    • +
    • module Reflection Provides utilities useful for handling type-erased data.
    • +
    +
  • +
  • + module Engine CUBOS. engine library. +
      +
    • module Assets Adds asset management to CUBOS.
    • +
    • module Collisions Adds collision detection to CUBOS.
    • +
    • module Fixed Time Step Adds a tag which makes its systems run at a fixed frame rate.
    • +
    • module Gizmos Used to draw gizmos helpful for debugging and tools.
    • +
    • module ImGui integration Initializes and configures ImGui for CUBOS.
    • +
    • module Input Adds input handling to CUBOS.
    • +
    • + module Physics Creates and handles the physics simulation. +
        +
      • module Gravity Adds gravity to particles.
      • +
      • module Solver Adds solver for constraints.
      • +
      +
    • +
    • module Renderer Creates and handles the lifecycle of a renderer.
    • +
    • module Scene Adds scenes to CUBOS.
    • +
    • module ScreenPicker Used to select entities and gizmos by clicking them.
    • +
    • module Settings Adds and manages settings.
    • +
    • module Splitscreen Adds viewport to all active cameras to achieve a splitscreen layout.
    • +
    • module Transform Adds transform components which assign positions, rotations and scaling to entities.
    • +
    • module Free Camera Adds the free camera controller component, which locks the mouse and moves an entity.
    • +
    • module Voxels Adds grid and palette assets to CUBOS.
    • +
    • module Window Creates and handles the lifecycle of a window.
    • +
    +
  • +
  • + module Tesseratos TESSERATOS. library. +
      +
    • module Asset explorer Allows viewing and selecting assets through a ImGui window.
    • +
    • module Collider gizmos Draws gizmos for selected colliders.
    • +
    • module Debug camera Adds a toggleable debug camera.
    • +
    • module ECS Statistics Shows tons of statistics and information about the internal state of the ECS.
    • +
    • module Entity inspector Allows inspecting and modifying the components of the selected entity through a ImGui window.
    • +
    • module Entity selector Adds a resource used to select an entity.
    • +
    • module Metrics Shows some useful performance metrics through a ImGui window.
    • +
    • module Play Pause Allows changing the current simulation speed, or even pause it.
    • +
    • module Scene editor Adds a window to edit scenes and select entities in them.
    • +
    • module Settings inspector Allows inspecting the current setting values through a ImGui window.
    • +
    • module Toolbox Adds a resource used to keep track of whether each tool is open or not.
    • +
    • module Transform gizmo Add a gizmo that allows changing an entity's position.
    • +
    • module Palette editor Allows the user to open and inspect/edit a palette asset.
    • +
    • module World inspector Shows all of the entities in the world through a ImGui window, and allows selecting them.
    • +
    +
  • +
+ +
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/move_8hpp.html b/docs-preview/pr-1032/move_8hpp.html new file mode 100644 index 000000000..777ad61b5 --- /dev/null +++ b/docs-preview/pr-1032/move_8hpp.html @@ -0,0 +1,161 @@ + + + + + core/memory/move.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/memory/move.hpp file +

+

Functions cubos::core::memory::move and cubos::core::memory::forward.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::memory
+
Memory module.
+
+
+
+

Classes

+
+
+
template<typename T>
+ struct cubos::core::memory::RemoveReference +
+
Provides a type which is the same as the given type, but without any references.
+
+
template<typename T>
+ struct cubos::core::memory::IsLValueReference +
+
Used to check if a type is an rvalue reference.
+
+
+
+

Functions

+
+
+
template<typename T>
+ auto move(T&& value) -> RemoveReference<T>::Type&& noexcept +
+
Returns an R-value reference to the given value.
+
+
template<typename T>
+ auto forward(typename RemoveReference<T>::Type& argument) -> T&& noexcept +
+
Used to cast a templated function parameter to the value category the caller used to pass it, which allows rvalues to be passed as rvalues and lvalues as lvalues.
+
+
template<typename T>
+ auto forward(typename RemoveReference<T>::Type&& argument) -> T&& noexcept +
+
Used to cast a templated function parameter to the value category the caller used to pass it, which allows rvalues to be passed as rvalues and lvalues as lvalues.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/name_8hpp.html b/docs-preview/pr-1032/name_8hpp.html new file mode 100644 index 000000000..e8a9a99bc --- /dev/null +++ b/docs-preview/pr-1032/name_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/ecs/name.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/namespacecubos.html b/docs-preview/pr-1032/namespacecubos.html new file mode 100644 index 000000000..bfe0d3a5e --- /dev/null +++ b/docs-preview/pr-1032/namespacecubos.html @@ -0,0 +1,122 @@ + + + + + cubos namespace | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos namespace +

+

CUBOS. libraries namespace.

+ +
+

Namespaces

+
+
namespace core
+
Core namespace.
+
namespace engine
+
Engine module.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/namespacecubos_1_1core.html b/docs-preview/pr-1032/namespacecubos_1_1core.html new file mode 100644 index 000000000..9008f61d4 --- /dev/null +++ b/docs-preview/pr-1032/namespacecubos_1_1core.html @@ -0,0 +1,148 @@ + + + + + cubos::core namespace | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core namespace +

+

Core namespace.

+ +
+

Namespaces

+
+
namespace al
+
Audio module.
+
namespace data
+
Data module.
+
namespace ecs
+
ECS module.
+
namespace geom
+
Geometry module.
+
namespace gl
+
Graphics module.
+
namespace io
+
Input and output module.
+
namespace memory
+
Memory module.
+
namespace reflection
+
Reflection module.
+
+
+
+

Classes

+
+
+ class Logger +
+
Singleton which holds the logging state.
+
+ class ThreadPool +
+
Manages a pool of threads, to which tasks can be submitted.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/namespacecubos_1_1core_1_1al.html b/docs-preview/pr-1032/namespacecubos_1_1core_1_1al.html new file mode 100644 index 000000000..453bf6dea --- /dev/null +++ b/docs-preview/pr-1032/namespacecubos_1_1core_1_1al.html @@ -0,0 +1,167 @@ + + + + + cubos::core::al namespace | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::al namespace +

+

Audio module.

+ +
+

Namespaces

+
+
namespace impl
+
Namespace to store the abstract types implemented by the audio device implementations.
+
+
+
+

Classes

+
+
+ class AudioDevice +
+
Audio device interface used to wrap low-level audio rendering APIs.
+
+
+
+

Enums

+
+
+ enum class Format { Mono8, + Mono16, + Stereo8, + Stereo16 } +
+
Possible audio formats.
+
+
+
+

Typedefs

+
+
+ using Buffer = std::shared_ptr<impl::Buffer> +
+
Handle to an audio buffer.
+
+ using Source = std::shared_ptr<impl::Source> +
+
Handle to an audio source.
+
+
+
+

Enum documentation

+
+

+ enum class cubos::core::al::Format + +

+

Possible audio formats.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/namespacecubos_1_1core_1_1al_1_1impl.html b/docs-preview/pr-1032/namespacecubos_1_1core_1_1al_1_1impl.html new file mode 100644 index 000000000..f2977c136 --- /dev/null +++ b/docs-preview/pr-1032/namespacecubos_1_1core_1_1al_1_1impl.html @@ -0,0 +1,126 @@ + + + + + cubos::core::al::impl namespace | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::al::impl namespace +

+

Namespace to store the abstract types implemented by the audio device implementations.

+ +
+

Classes

+
+
+ class Buffer +
+
Abstract audio buffer.
+
+ class Source +
+
Abstract audio source.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/namespacecubos_1_1core_1_1data.html b/docs-preview/pr-1032/namespacecubos_1_1core_1_1data.html new file mode 100644 index 000000000..5e865f86f --- /dev/null +++ b/docs-preview/pr-1032/namespacecubos_1_1core_1_1data.html @@ -0,0 +1,163 @@ + + + + + cubos::core::data namespace | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data namespace +

+

Data module.

+ +
+

Classes

+
+
+ class Deserializer +
+
Base class for deserializers, which defines the interface for deserializing arbitrary data using its reflection metadata.
+
+ class JSONDeserializer +
+
Deserializer implementation which allows reading data from a JSON object.
+
+ class Archive +
+
Interface for a bridge between the CUBOS. virtual file system and the real world.
+
+ class EmbeddedArchive +
+
Archive implementation which reads data embedded in the application. Meant to be used with the quadrados embed tool.
+
+ class File +
+
Represents a file in the virtual file system of the engine.
+
+
template<typename T>
+ class FileStream +
+
Wrapper around an implementation-specific file stream which keeps the file alive and does some sanity checks.
+
+ class FileSystem +
+
Singleton which represents the virtual file system of the engine.
+
+ class StandardArchive +
+
Archive implementation which reads and writes from/into the OS file system using the standard library.
+
+ class DebugSerializer +
+
Serializer implementation which prints the given data to a stream in a human-readable format not meant to be parsed.
+
+ class JSONSerializer +
+
Implementation of the abstract Serializer class for serializing to JSON.
+
+ class Serializer +
+
Base class for serializers, which defines the interface for serializing arbitrary data using its reflection metadata.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/namespacecubos_1_1core_1_1data_1_1old_1_1impl.html b/docs-preview/pr-1032/namespacecubos_1_1core_1_1data_1_1old_1_1impl.html new file mode 100644 index 000000000..b0b67855b --- /dev/null +++ b/docs-preview/pr-1032/namespacecubos_1_1core_1_1data_1_1old_1_1impl.html @@ -0,0 +1,122 @@ + + + + + cubos::core::data::old::impl namespace | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data::old::impl namespace +

+ +

Implementation specific classes for the above functions are hidden in this namespace.

+
+

Classes

+
+
+ class Packager +
+
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/namespacecubos_1_1core_1_1ecs.html b/docs-preview/pr-1032/namespacecubos_1_1core_1_1ecs.html new file mode 100644 index 000000000..9ece7b988 --- /dev/null +++ b/docs-preview/pr-1032/namespacecubos_1_1core_1_1ecs.html @@ -0,0 +1,430 @@ + + + + + cubos::core::ecs namespace | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs namespace +

+

ECS module.

+ +
+

Namespaces

+
+
namespace impl
+
Contains functions used internally by the implementation of the ECS.
+
+
+
+

Classes

+
+
+ class Blueprint +
+
Collection of entities and their respective components and relations.
+
+ class CommandBuffer +
+
Stores commands to execute them later.
+
+ struct DeltaTime +
+
Resource which stores the time since the last iteration of the main loop started.
+
+ struct ShouldQuit +
+
Resource used as a flag to indicate whether the main loop should stop running.
+
+ struct Arguments +
+
Resource which stores the command-line arguments.
+
+ class TagBuilder +
+
Used to chain configurations related to tags.
+
+ class Cubos +
+
Represents the engine itself, and exposes the interface with which the game developer interacts with. Ties up all the different parts of the engine together.
+
+ class ArchetypeGraph +
+
Stores which column types each archetype holds and the edges which connect them.
+
+ struct ArchetypeId +
+
Identifies an archetype.
+
+ struct ArchetypeIdHash +
+
Hash functor for ArchetypeId.
+
+ struct Entity +
+
Identifies an entity.
+
+ struct EntityHash +
+
Used to hash Entity objects.
+
+ class EntityPool +
+
Manages the creation and destruction of entity identifiers, as well as storing their archetype identifiers.
+
+ struct Name +
+
Component which stores the name of an entity.
+
+
template<typename... Ts>
+ class QueryData +
+
Holds the data necessary to execute a query.
+
+
template<typename T>
+ class QueryFetcher +
+
Type meant to be specialized which implements for each argument type the necessary logic to extract it from the tables.
+
+ class QueryFilter +
+
Used to find matches for the given query terms. Essentially contains the non-templated part of the query logic.
+
+ class QueryArchetypeNode +
+
Node which forces a given target to belong to a set of archetypes.
+
+ class QueryNode +
+
Query filter step, which receives an iterator and advances it until it points to a valid match.
+
+ class QueryRelatedNode +
+
Node which forces two given targets to be related with a given relation.
+
+
template<typename T>
+ class Opt +
+
Wrapper for reference types to indicate that the given argument type is optional in a query.
+
+ struct QueryTerm +
+
Describes a term in a query.
+
+ struct SymmetricTrait +
+
Trait used to identify symmetric relations.
+
+ struct TreeTrait +
+
Trait used to identify tree relations.
+
+ struct EphemeralTrait +
+
Trait used to identify types which are ephemeral and should not be persisted.
+
+
template<typename T>
+ class TypeBuilder +
+
Builder for reflection::Type objects which represent ECS types.
+
+
template<typename T>
+ class ReadResource +
+
Utility struct used to reference a resource of type T for reading.
+
+
template<typename T>
+ class WriteResource +
+
Utility struct used to reference a resource of type T for writing.
+
+ class ResourceManager +
+
Holds and manages resources.
+
+ struct SystemAccess +
+
Describes the types of data a system accesses.
+
+ class Commands +
+
System argument used to write ECS commands and execute them at a later time.
+
+
template<typename T>
+ class EventPipe +
+
Resource which stores events of type T.
+
+
template<typename T, unsigned int M = DEFAULT_FILTER_MASK>
+ class EventReader +
+
System arguments used to read events of type T.
+
+
template<typename T>
+ class EventWriter +
+
System argument which allows the system to send events of type T to other systems.
+
+
template<typename... Ts>
+ class Query +
+
System argument which holds the result of a query over all entities in world which match the given arguments.
+
+ class Dispatcher +
+
Used to add systems and relations between them and then dispatch them all at once.
+
+
template<typename T>
+ class SystemFetcher +
+
Type meant to be specialized which implements for each argument type the necessary logic to extract it from the world.
+
+ struct SystemOptions +
+
Contains extra options for a specific system argument.
+
+
template<typename T>
+ class System +
+
Holds a system with a return type T.
+
+ struct ColumnId +
+
Identifies a data column type.
+
+ class DenseTableRegistry +
+
Stores the dense tables of a given world.
+
+ class DenseTable +
+
Stores the dense data associated to entities of a given archetype.
+
+ struct SparseRelationTableId +
+
Identifies a sparse relation table.
+
+ struct SparseRelationTableIdHash +
+
Hash functor for SparseRelationTableId.
+
+ class SparseRelationTableRegistry +
+
Stores all of the sparse relation tables.
+
+ class SparseRelationTable +
+
A table which stores relations. Allows for quick insertion, deletion and iteration.
+
+ class Tables +
+
Stores the tables of a given world.
+
+ struct DataTypeId +
+
Identifies a data type registered in the world.
+
+ struct DataTypeIdHash +
+
Hash functor for DataTypeId.
+
+ class Types +
+
Registry of all data types used in an ECS world.
+
+ class World +
+
Holds entities, their components and resources.
+
+
+
+

Enums

+
+
+ enum class Traversal { Random, + Down, + Up } +
+
Possible traversal types for tree relation terms.
+
+
+
+

Functions

+
+
+ void convertEntities(const std::unordered_map<Entity, Entity, EntityHash>& map, + const reflection::Type& type, + void* value) +
+
Converts entities in a value to their respective new entities. If an entity is not found in the map, it is left unchanged.
+
+
+
+

Enum documentation

+
+

+ enum class cubos::core::ecs::Traversal + +

+

Possible traversal types for tree relation terms.

+ + + + + + + + + + + + + + + + +
Enumerators
Random +

Default traversal order. No specific ordering is required.

+
Down +

Starts in the topmost entity and traverses down the relation.

+
Up +

Starts in the bottommost entity and traverses up the relation.

+
+
+
+
+

Function documentation

+
+

+ void cubos::core::ecs::convertEntities(const std::unordered_map<Entity, Entity, EntityHash>& map, + const reflection::Type& type, + void* value) + +

+

Converts entities in a value to their respective new entities. If an entity is not found in the map, it is left unchanged.

+ + + + + + + + + + + + + + + + + + +
Parameters
mapMap of old entities to new entities.
typeValue type.
valueValue.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/namespacecubos_1_1core_1_1ecs_1_1impl.html b/docs-preview/pr-1032/namespacecubos_1_1core_1_1ecs_1_1impl.html new file mode 100644 index 000000000..aaeedc19a --- /dev/null +++ b/docs-preview/pr-1032/namespacecubos_1_1core_1_1ecs_1_1impl.html @@ -0,0 +1,103 @@ + + + + + cubos::core::ecs::impl namespace | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::impl namespace +

+

Contains functions used internally by the implementation of the ECS.

+

Used to avoid cluttering the public namespace with implementation details.

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/namespacecubos_1_1core_1_1geom.html b/docs-preview/pr-1032/namespacecubos_1_1core_1_1geom.html new file mode 100644 index 000000000..226faf7aa --- /dev/null +++ b/docs-preview/pr-1032/namespacecubos_1_1core_1_1geom.html @@ -0,0 +1,189 @@ + + + + + cubos::core::geom namespace | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::geom namespace +

+

Geometry module.

+ +
+

Classes

+
+
+ struct AABB +
+
Represents an axis-aligned bounding box.
+
+ struct Box +
+
Represents a box shape.
+
+ struct Capsule +
+
Represents a capsule or sphere shape.
+
+ struct Intersection +
+
Contains info regarding an intersection between shapes.
+
+
+
+

Functions

+
+
+ auto intersects(const Box& box1, + const glm::mat4& localToWorld1, + const Box& box2, + const glm::mat4& localToWorld2, + Intersection& intersect) -> bool +
+
Computes the intersection between two box shapes.
+
+
+
+

Function documentation

+
+

+ bool cubos::core::geom::intersects(const Box& box1, + const glm::mat4& localToWorld1, + const Box& box2, + const glm::mat4& localToWorld2, + Intersection& intersect) + +

+

Computes the intersection between two box shapes.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
box1Box shape of the first entity.
localToWorld1Local to world matrix of the first entity.
box2Box shape of the second entity.
localToWorld2Local to world matrix of the second entity.
intersect
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/namespacecubos_1_1core_1_1gl.html b/docs-preview/pr-1032/namespacecubos_1_1core_1_1gl.html new file mode 100644 index 000000000..6ecc683c3 --- /dev/null +++ b/docs-preview/pr-1032/namespacecubos_1_1core_1_1gl.html @@ -0,0 +1,496 @@ + + + + + cubos::core::gl namespace | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl namespace +

+

Graphics module.

+ +
+

Namespaces

+
+
namespace impl
+
Namespace to store the abstract types implemented by the render device implementations.
+
+
+
+

Classes

+
+
+ class Debug +
+
Singleton with static methods used to draw primitive objects on screen for debugging purposes.
+
+ struct FramebufferDesc +
+
Describes a framebuffer.
+
+ struct RasterStateDesc +
+
Decribes a rasterizer state.
+
+ struct DepthStencilStateDesc +
+
Describes a depth stencil state.
+
+ struct BlendStateDesc +
+
Describes a blend state.
+
+ struct SamplerDesc +
+
Describes a sampler.
+
+ struct Texture1DDesc +
+
Describes a 1D texture.
+
+ struct Texture2DDesc +
+
Describes a 2D texture.
+
+ struct Texture2DArrayDesc +
+
Describes a 2D texture array.
+
+ struct Texture3DDesc +
+
Describes a 3D texture.
+
+ struct CubeMapDesc +
+
Describes a cube map.
+
+ struct CubeMapArrayDesc +
+
Describes a cube map array.
+
+ struct ConstantBufferElement +
+
Describes an element in a constant buffer.
+
+ struct ConstantBufferStructure +
+
Describes the structure of a constant buffer.
+
+ struct VertexElement +
+
Describes a vertex element.
+
+ struct VertexArrayDesc +
+
Describes a vertex array.
+
+ class RenderDevice +
+
Interface used to wrap low-level rendering APIs such as OpenGL.
+
+
+
+

Enums

+
+
+ enum class Property { MaxAnisotropy, + ComputeSupported } +
+
Render device properties that can be queried at runtime.
+
+ enum class Usage { Default, + Dynamic, + Static } +
+
Usage mode for buffers and textures.
+
+ enum class Type { Byte, + Short, + Int, + UByte, + UShort, + UInt, + NByte, + NShort, + NUByte, + NUShort, + Float } +
+
Data type.
+
+ enum class IndexFormat { UShort, + UInt } +
+
Index format.
+
+ enum class TextureFormat { R8SNorm, + R16SNorm, + RG8SNorm, + RG16SNorm, + RGBA8SNorm, + RGBA16SNorm, + R8UNorm, + R16UNorm, + RG8UNorm, + RG16UNorm, + RGBA8UNorm, + RGBA16UNorm, + R8SInt, + R16SInt, + RG8SInt, + RG16SInt, + RGBA8SInt, + RGBA16SInt, + R8UInt, + R16UInt, + RG8UInt, + RG16UInt, + RGBA8UInt, + RGBA16UInt, + R16Float, + R32Float, + RG16Float, + RG32Float, + RGB16Float, + RGB32Float, + RGBA16Float, + RGBA32Float, + Depth16, + Depth32, + Depth24Stencil8, + Depth32Stencil8 } +
+
Texture format.
+
+ enum class AddressMode { Repeat, + Mirror, + Clamp, + Border } +
+
Texture address mode.
+
+ enum class TextureFilter { None, + Nearest, + Linear } +
+
Texture filter type.
+
+ enum class Winding { CW, + CCW } +
+
Triangle winding mode.
+
+ enum class Face { Front, + Back, + FrontAndBack } +
+
Specifies a face.
+
+ enum class RasterMode { Wireframe, + Fill } +
+
Rasterizer mode.
+
+ enum class Compare { Never, + Less, + LEqual, + Greater, + GEqual, + Equal, + NEqual, + Always } +
+
Comparison function.
+
+ enum class StencilAction { Zero, + Keep, + Replace, + Increment, + IncrementWrap, + Decrement, + DecrementWrap, + Invert } +
+
Stencil action.
+
+ enum class BlendFactor { Zero, + One, + SrcColor, + InvSrcColor, + DstColor, + InvDstColor, + SrcAlpha, + InvSrcAlpha, + DstAlpha, + InvDstAlpha } +
+
Blend factor.
+
+ enum class BlendOp { Add, + Substract, + RevSubstract, + Min, + Max } +
+
Blend operation.
+
+ enum class Stage { Vertex, + Geometry, + Pixel, + Compute } +
+
Shader stage type.
+
+ enum class CubeFace { PositiveX = 0, + NegativeX = 1, + PositiveY = 2, + NegativeY = 3, + PositiveZ = 4, + NegativeZ = 5 } +
+
Cube map face.
+
+ enum class MemoryBarriers { None = 0, + VertexBuffer = 1, + IndexBuffer = 2, + ConstantBuffer = 4, + ImageAccess = 8, + TextureAccess = 16, + Framebuffer = 32, + All = VertexBuffer | IndexBuffer | ConstantBuffer | ImageAccess | TextureAccess | Framebuffer } +
+
Memory barrier flags for synchronization.
+
+ enum class Access { Read, + Write, + ReadWrite } +
+
Access mode for a resource.
+
+
+
+

Typedefs

+
+
+ using Framebuffer = std::shared_ptr<impl::Framebuffer> +
+
Handle to a framebuffer.
+
+ using RasterState = std::shared_ptr<impl::RasterState> +
+
Handle to a rasterizer state.
+
+ using DepthStencilState = std::shared_ptr<impl::DepthStencilState> +
+
Handle to a depth stencil state.
+
+ using BlendState = std::shared_ptr<impl::BlendState> +
+
Handle to a blend state.
+
+ using Sampler = std::shared_ptr<impl::Sampler> +
+
Handle to a sampler.
+
+ using Texture1D = std::shared_ptr<impl::Texture1D> +
+
Handle to a 1D texture.
+
+ using Texture2D = std::shared_ptr<impl::Texture2D> +
+
Handle to a 2D texture.
+
+ using Texture2DArray = std::shared_ptr<impl::Texture2DArray> +
+
Handle to a 2D texture array.
+
+ using Texture3D = std::shared_ptr<impl::Texture3D> +
+
Handle to a 3D texture.
+
+ using CubeMap = std::shared_ptr<impl::CubeMap> +
+
Handle to a cube map.
+
+ using CubeMapArray = std::shared_ptr<impl::CubeMapArray> +
+
Handle to a cube map array.
+
+ using ConstantBuffer = std::shared_ptr<impl::ConstantBuffer> +
+
Handle to a constant buffer.
+
+ using IndexBuffer = std::shared_ptr<impl::IndexBuffer> +
+
Handle to an index buffer.
+
+ using VertexBuffer = std::shared_ptr<impl::VertexBuffer> +
+
Handle to a vertex buffer.
+
+ using VertexArray = std::shared_ptr<impl::VertexArray> +
+
Handle to a vertex array.
+
+ using ShaderStage = std::shared_ptr<impl::ShaderStage> +
+
Handle to a shader stage.
+
+ using ShaderPipeline = std::shared_ptr<impl::ShaderPipeline> +
+
Handle to a shader pipeline.
+
+ using ShaderBindingPoint = impl::ShaderBindingPoint* +
+
Handle to a shader binding point.
+
+
+
+

Functions

+
+
+ void generateScreenQuad(RenderDevice& renderDevice, + const ShaderPipeline& pipeline, + VertexArray& va) +
+
Creates the resources required to draw a quad that fills the screen and returns its VertexArray.
+
+
+
+

Function documentation

+
+

+ void cubos::core::gl::generateScreenQuad(RenderDevice& renderDevice, + const ShaderPipeline& pipeline, + VertexArray& va) + +

+

Creates the resources required to draw a quad that fills the screen and returns its VertexArray.

+ + + + + + + + + + + + + + + + + + +
Parameters
renderDeviceRenderDevice to be used for generation of the quad.
pipelinePipeline to associate the quad's VertexArray with.
va outHandle of the quad's VertexArray.
+

The quad provided by this function consists of two one sided triangles, with vertices containing the 2D position and UV coordinates. This function assumes the shader pipeline provided takes as input attributes a vec2 position and a vec2 uv.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/namespacecubos_1_1core_1_1gl_1_1impl.html b/docs-preview/pr-1032/namespacecubos_1_1core_1_1gl_1_1impl.html new file mode 100644 index 000000000..69725f19e --- /dev/null +++ b/docs-preview/pr-1032/namespacecubos_1_1core_1_1gl_1_1impl.html @@ -0,0 +1,190 @@ + + + + + cubos::core::gl::impl namespace | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::impl namespace +

+

Namespace to store the abstract types implemented by the render device implementations.

+ +
+

Classes

+
+
+ class Framebuffer +
+
Abstract framebuffer.
+
+ class RasterState +
+
Abstract rasterizer state.
+
+ class DepthStencilState +
+
Abstract depth stencil state.
+
+ class BlendState +
+
Abstract blend state.
+
+ class Sampler +
+
Abstract sampler.
+
+ class Texture1D +
+
Abstract 1D texture.
+
+ class Texture2D +
+
Abstract 2D texture.
+
+ class Texture2DArray +
+
Abstract 2D texture array.
+
+ class Texture3D +
+
Abstract 3D texture.
+
+ class CubeMap +
+
Abstract cube map.
+
+ class CubeMapArray +
+
Abstract cube map.
+
+ class ConstantBuffer +
+
Abstract constant buffer.
+
+ class IndexBuffer +
+
Abstract index buffer.
+
+ class VertexBuffer +
+
Abstract vertex buffer.
+
+ class VertexArray +
+
Abstract vertex array.
+
+ class ShaderStage +
+
Abstract shader stage.
+
+ class ShaderPipeline +
+
Abstract shader pipeline.
+
+ class ShaderBindingPoint +
+
Abstract shader binding point.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/namespacecubos_1_1core_1_1io.html b/docs-preview/pr-1032/namespacecubos_1_1core_1_1io.html new file mode 100644 index 000000000..31ae4b28c --- /dev/null +++ b/docs-preview/pr-1032/namespacecubos_1_1core_1_1io.html @@ -0,0 +1,384 @@ + + + + + cubos::core::io namespace | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::io namespace +

+

Input and output module.

+ +
+

Classes

+
+
+ class Cursor +
+
Handle for a custom mouse cursor.
+
+ struct GamepadState +
+
Holds the state of a gamepad.
+
+ struct KeyWithModifiers +
+
Keyboard key code and modifier flags.
+
+ struct KeyEvent +
+
Event sent when a key is pressed or released.
+
+ struct ModifiersEvent +
+
Event sent when the modifiers change.
+
+ struct MouseButtonEvent +
+
Event sent when a mouse button state changes.
+
+ struct MouseMoveEvent +
+
Event sent when the mouse cursor moves.
+
+ struct MouseScrollEvent +
+
Event sent when the mouse wheel is scrolled.
+
+ struct ResizeEvent +
+
Event sent when the window framebuffer is resized.
+
+ struct TextEvent +
+
Event sent when a unicode character is input.
+
+ struct GamepadConnectionEvent +
+
Event sent when a gamepad is connected or disconnected.
+
+ class BaseWindow +
+
Interface used to wrap low-level window API implementations.
+
+
+
+

Enums

+
+
+ enum class GamepadButton { Invalid = -1, + A, + B, + X, + Y, + LBumper, + RBumper, + Back, + Start, + Guide, + LThumb, + RThumb, + Up, + Right, + Down, + Left, + Count } +
+
Gamepad buttons.
+
+ enum class GamepadAxis { Invalid = -1, + LX, + LY, + RX, + RY, + LTrigger, + RTrigger, + Count } +
+
Gamepad axes.
+
+ enum class Key { Invalid = -1, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + T, + U, + V, + W, + X, + Y, + Z, + Num0, + Num1, + Num2, + Num3, + Num4, + Num5, + Num6, + Num7, + Num8, + Num9, + Escape, + LControl, + LShift, + LAlt, + LSystem, + RControl, + RShift, + RAlt, + RSystem, + Menu, + LBracket, + RBracket, + SemiColon, + Comma, + Period, + Quote, + Slash, + BackSlash, + Tilde, + Equal, + Dash, + Space, + Return, + BackSpace, + Tab, + PageUp, + PageDown, + End, + Home, + Insert, + Delete, + Add, + Subtract, + Multiply, + Divide, + Left, + Right, + Up, + Down, + Numpad0, + Numpad1, + Numpad2, + Numpad3, + Numpad4, + Numpad5, + Numpad6, + Numpad7, + Numpad8, + Numpad9, + F1, + F2, + F3, + F4, + F5, + F6, + F7, + F8, + F9, + F10, + F11, + F12, + Pause, + Count } +
+
Keyboard key codes enum.
+
+ enum class Modifiers { None = 0, + Control = 1, + Shift = 2, + Alt = 4, + System = 8 } +
+
Keyboard modifier flags enum.
+
+ enum class MouseButton { Invalid = -1, + Left, + Right, + Middle, + Extra1, + Extra2 } +
+
Mouse buttons enum.
+
+ enum class MouseAxis { X, + Y, + Scroll } +
+
Mouse axes enums.
+
+ enum class MouseState { Default, + Locked, + Hidden } +
+
Possible mouse states.
+
+
+
+

Typedefs

+
+
+ using WindowEvent = std::variant<KeyEvent, ModifiersEvent, MouseButtonEvent, MouseMoveEvent, MouseScrollEvent, ResizeEvent, TextEvent, GamepadConnectionEvent> +
+
Variant that can hold any of the window events.
+
+ using Window = std::shared_ptr<BaseWindow> +
+
Handle to a window.
+
+
+
+

Functions

+
+
+ auto gamepadButtonToString(GamepadButton button) -> std::string +
+
Converts a GamepadButton enum to a string.
+
+ auto stringToGamepadButton(const std::string& str) -> GamepadButton +
+
Converts a string to a GamepadButton.
+
+ auto gamepadAxisToString(GamepadAxis axis) -> std::string +
+
Convert a GamepadAxis to a string.
+
+ auto stringToGamepadAxis(const std::string& str) -> GamepadAxis +
+
Convert a string to a GamepadAxis.
+
+ auto openWindow(const std::string& title = "CUBOS.", + const glm::ivec2& size = {800, 600}) -> Window +
+
Opens a new window.
+
+ auto mouseButtonToString(MouseButton button) -> std::string +
+
Converts a MouseButton enum to a string.
+
+ auto stringToMouseButton(const std::string& str) -> MouseButton +
+
Convert a string to a MouseButton enum.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/namespacecubos_1_1core_1_1memory.html b/docs-preview/pr-1032/namespacecubos_1_1core_1_1memory.html new file mode 100644 index 000000000..64eaaba03 --- /dev/null +++ b/docs-preview/pr-1032/namespacecubos_1_1core_1_1memory.html @@ -0,0 +1,275 @@ + + + + + cubos::core::memory namespace | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::memory namespace +

+

Memory module.

+ +
+

Classes

+
+
+ class AnyValue +
+
Stores a blob of a given reflected type.
+
+ class AnyVector +
+
Stores a dynamically sized array of blobs of a given reflected type.
+
+ class BufferStream +
+
Stream implementation which writes to/reads from a buffer.
+
+
template<typename R, typename... Ts>
+ class Function<R(Ts...)> +
+
Generic function pointer which can also store capturing lambda functions.
+
+
template<typename T, typename Lock>
+ class ReadGuard +
+
Provides safe read-only access to an object using a lock.
+
+
template<typename T, typename Lock>
+ class WriteGuard +
+
Provides safe read-write access to an object using a lock.
+
+
template<typename T>
+ struct RemoveReference +
+
Provides a type which is the same as the given type, but without any references.
+
+
template<typename T>
+ struct IsLValueReference +
+
Used to check if a type is an rvalue reference.
+
+ class StandardStream +
+
Stream implementation which wraps a libc file pointer.
+
+ class Stream +
+
Interface class for memory streams. Abstracts away sources or destinations of data.
+
+
template<typename V>
+ class TypeMap +
+
A map that stores values of type V, using reflection types as keys.
+
+
template<typename L, typename R, typename LHash = std::hash<L>, typename RHash = std::hash<R>>
+ class UnorderedBimap +
+
A bidirectional hash table.
+
+
+
+

Enums

+
+
+ enum class SeekOrigin { Begin, + Current, + End } +
+
Stream seek origin.
+
+
+
+

Functions

+
+
+
template<typename T>
+ auto swapBytes(T value) -> T +
+
Swaps the bytes of a value, changing its endianness.
+
+ auto isLittleEndian() -> bool +
+
Checks if the current platform is little endian.
+
+
template<typename T>
+ auto fromLittleEndian(T value) -> T +
+
Converts a value from little endianness to local endianness.
+
+
template<typename T>
+ auto toLittleEndian(T value) -> T +
+
Converts a value from local endianness to little endianness.
+
+
template<typename T>
+ auto fromBigEndian(T value) -> T +
+
Converts a value from big endianness to local endianness.
+
+
template<typename T>
+ auto toBigEndian(T value) -> T +
+
Converts a value from local endianness to big endianness.
+
+
template<typename T>
+ auto move(T&& value) -> RemoveReference<T>::Type&& noexcept +
+
Returns an R-value reference to the given value.
+
+
template<typename T>
+ auto forward(typename RemoveReference<T>::Type& argument) -> T&& noexcept +
+
Used to cast a templated function parameter to the value category the caller used to pass it, which allows rvalues to be passed as rvalues and lvalues as lvalues.
+
+
template<typename T>
+ auto forward(typename RemoveReference<T>::Type&& argument) -> T&& noexcept +
+
Used to cast a templated function parameter to the value category the caller used to pass it, which allows rvalues to be passed as rvalues and lvalues as lvalues.
+
+
+
+

Function documentation

+
+

+ +
+ template<typename T> +
+ T&& cubos::core::memory::forward(typename RemoveReference<T>::Type&& argument) noexcept +

+

Used to cast a templated function parameter to the value category the caller used to pass it, which allows rvalues to be passed as rvalues and lvalues as lvalues.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TArgument type.
Parameters
argumentArgument to forward.
ReturnsForwarded argument.
+ +
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/namespacecubos_1_1core_1_1reflection.html b/docs-preview/pr-1032/namespacecubos_1_1core_1_1reflection.html new file mode 100644 index 000000000..9f462f61a --- /dev/null +++ b/docs-preview/pr-1032/namespacecubos_1_1core_1_1reflection.html @@ -0,0 +1,223 @@ + + + + + cubos::core::reflection namespace | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::reflection namespace +

+

Reflection module.

+ +
+

Classes

+
+
+
template<typename T>
+ struct Reflect +
+
Defines the reflection function for the given type T.
+
+ class ArrayTrait +
+
Exposes array-like functionality of a type.
+
+ class ConstructibleTrait +
+
Describes how a reflected type may be constructed and destructed.
+
+ class DictionaryTrait +
+
Exposes dictionary-like functionality of a type.
+
+ class EnumTrait +
+
Provides enumeration functionality to an enumerated type.
+
+ class FieldsTrait +
+
Describes the fields of a reflected type.
+
+ class MaskTrait +
+
Provides mask functionality to an enum mask type.
+
+ class NullableTrait +
+
Used to manipulate values of null-representable types.
+
+ class StringConversionTrait +
+
Stores functions for converting a type to and from a string.
+
+ class Type +
+
Describes a reflected type.
+
+ class TypeRegistry +
+
Stores a set of types which can be accessed by name.
+
+
+
+

Functions

+
+
+ auto compare(const Type& type, + void* a, + void* b) -> bool +
+
Compares two instances of the same type.
+
+
template<typename T>
+ auto reflect() -> const Type& +
+
Reflects the given type T.
+
+
template<typename T>
+ auto autoConstructibleTrait() -> ConstructibleTrait +
+
Returns a ConstructibleTrait with the default, copy and move constructors, set only if the type has them.
+
+
+
+

Function documentation

+
+

+ bool cubos::core::reflection::compare(const Type& type, + void* a, + void* b) + +

+

Compares two instances of the same type.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
typeThe type of the data being compared
aOne of the instances.
bThe other instance.
ReturnsTrue if the values are equal, false otherwise.
+ +
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/namespacecubos_1_1engine.html b/docs-preview/pr-1032/namespacecubos_1_1engine.html new file mode 100644 index 000000000..91636b5c8 --- /dev/null +++ b/docs-preview/pr-1032/namespacecubos_1_1engine.html @@ -0,0 +1,660 @@ + + + + + cubos::engine namespace | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine namespace +

+

Engine module.

+ +

[Component Refl]

+
+

Namespaces

+
+
namespace impl
+
Namespace to store the abstract types implemented by the renderer implementations.
+
+
+
+

Classes

+
+
+
template<core::reflection::Reflectable T>
+ class Asset +
+
Handle to an asset of a specific type.
+
+ class AnyAsset +
+
Handle to an asset of any type. May either be weak or strong. Weak handles do not guarantee the asset is loaded, while strong handles do.
+
+ class Assets +
+
Resource which manages all assets. Responsible for loading and unloading assets, storing them in memory, and providing access to them.
+
+ class AssetBridge +
+
Bridges are the objects responsible for loading and saving assets from/to disk. They form the bridge between the asset manager and the virtual file system.
+
+
template<typename T>
+ class BinaryBridge +
+
Bridge for loading and saving assets which are serialized to and from a binary file.
+
+ class FileBridge +
+
Abstract bridge type defined to reduce boilerplate code in bridge implementations which open a single file to load and save assets.
+
+
template<typename T>
+ class JSONBridge +
+
Bridge for loading and saving assets which are serialized to and from a JSON file.
+
+ class AssetMeta +
+
Stores metadata about an asset - the data stored in .meta files. Each asset has a corresponding meta object, which contains load or import parameters.
+
+ struct Collider +
+
Component which adds a collider to an entity.
+
+ struct CollidingWith +
+
Relation which represents a collision.
+
+ struct CollisionEvent +
+
Represents a collision event.
+
+ struct BoxCollisionShape +
+
Component which adds a box collision shape to an entity, used with a Collider component.
+
+ struct CapsuleCollisionShape +
+
Component which adds a capsule collision shape to an entity, used with a Collider component.
+
+ struct FixedDeltaTime +
+
Resource which holds the value of the fixed delta for the fixedStep plugin.
+
+ class Gizmos +
+
Resource which queues commands for drawing gizmos, basic primitives useful for debugging and tools.
+
+ class DataInspector +
+
Resource which allows the user to inspect or modify any reflectable value on the UI.
+
+ class InputAction +
+
Stores the state of a single input action, such as "jump" or "attack".
+
+ class InputAxis +
+
Stores the state of a single input axis, such as "move forward" or "move right".
+
+ class InputBindings +
+
Stores the input bindings for a single player.
+
+ class Input +
+
Resource which stores the input bindings for multiple players.
+
+ struct AccumulatedCorrection +
+
Component which holds the corrections accumulated from the constraints solving.
+
+ struct Force +
+
Component which holds forces applied on a particle.
+
+ struct Impulse +
+
Component which holds impulses applied on a particle.
+
+ struct Mass +
+
Component which defines the mass of a particle.
+
+ struct PreviousPosition +
+
Component which holds the previous position of the entity. Used for the integrator on the update velocity step.
+
+ struct Velocity +
+
Component which holds velocity and forces applied on a particle.
+
+ struct PhysicsBundle +
+
Component which encapsulates the creation all components required for physics.
+
+ struct Damping +
+
Resource which holds the damping value for integration.
+
+ struct Gravity +
+
Resource which holds the global value of gravity.
+
+ struct Substeps +
+
Resource which holds the amount of substeps for the physics update.
+
+ struct Camera +
+
Component which defines parameters of a camera used to render the world.
+
+ class DeferredRenderer +
+
Renderer implementation which uses deferred rendering.
+
+ struct DirectionalLight +
+
Component which makes an entity behave like a directional light.
+
+ struct RendererEnvironment +
+
Resource which stores the renderer's ambient light and sky colors.
+
+ class RendererFrame +
+
Resource which describes a scene to be drawn by the renderer.
+
+ struct RenderableGrid +
+
Component which makes a voxel grid be rendered by the renderer plugin.
+
+ struct ActiveCameras +
+
Resource which identifies the camera entities to be used by the renderer.
+
+ struct ActiveVoxelPalette +
+
Resource which holds an asset handle to the currently active palette.
+
+ struct PointLight +
+
Component which makes an entity behave like a point light.
+
+ class PostProcessingBloom +
+
A post processing pass that adds a "bloom" effect to any bright objects in the scene.
+
+ class PostProcessingCopy +
+
A simple post processing pass that copies the input texture to the output.
+
+ class PostProcessingManager +
+
Responsible for managing the post processing passes.
+
+ class PostProcessingPass +
+
A generic post processing pass.
+
+ class BaseRenderer +
+
Interface which abstracts different rendering methods.
+
+ struct SpotLight +
+
Component which makes an entity emit a spot light.
+
+ struct VoxelVertex +
+
Represents a voxel vertex.
+
+ struct Viewport +
+
Component which defines parameters of a viewport, the actual screen space that will be used by the camera it is attached to. Useful for having multiple camera views shown on screen.
+
+ class SceneBridge +
+
Bridge which loads and saves Scene assets.
+
+ struct Scene +
+
Asset equivalent to ECS blueprints - a bundle of entities and their components.
+
+ class ScreenPicker +
+
Resource which provides a texture to store entity/gizmo ids, for selection with a mouse.
+
+ class Settings +
+
Stores settings as key-value pairs and provides methods to retrieve them.
+
+ struct ChildOf +
+
Tree relation which indicates the 'from' entity is a child of the 'to' entity.
+
+ struct LocalToParent +
+
Component which stores the transformation matrix of an entity, from local to parent space.
+
+ struct LocalToWorld +
+
Component which stores the transformation matrix of an entity, from local to world space.
+
+ struct Position +
+
Component which assigns a position to an entity.
+
+ struct Rotation +
+
Component which assigns a rotation to an entity.
+
+ struct Scale +
+
Component which assigns a uniform scale to an entity.
+
+ struct FreeCameraController +
+
Component which moves the camera.
+
+ class VoxelGrid +
+
Represents a voxel object using a 3D grid.
+
+ struct VoxelMaterial +
+
Describes a voxel material.
+
+ class VoxelPalette +
+
Holds a palette of materials. Supports up to 65535 materials.
+
+
+
+

Enums

+
+
+ enum class PostProcessingInput { Lighting, + Position, + Normal } +
+
Possible renderer outputs which can then be used as input for a post processing pass.
+
+
+
+

Typedefs

+
+
+ using AssetMetaRead = core::memory::ReadGuard<AssetMeta, std::shared_lock<std::shared_mutex>> +
+
Read-only guard for an asset's metadata.
+
+ using AssetMetaWrite = core::memory::WriteGuard<AssetMeta, std::unique_lock<std::shared_mutex>> +
+
Read-write guard for an asset's metadata.
+
+
template<typename T>
+ using AssetRead = core::memory::ReadGuard<T, std::shared_lock<std::shared_mutex>> +
+
Read-only guard for an asset's data.
+
+
template<typename T>
+ using AssetWrite = core::memory::WriteGuard<T, std::unique_lock<std::shared_mutex>> +
+
Read-write guard for an asset's data.
+
+ using Cubos = core::ecs::Cubos +
+
Represents the engine itself, and exposes the interface with which the game developer interacts with. Ties up all the different parts of the engine together.
+
+ using DeltaTime = core::ecs::DeltaTime +
+
Resource which stores the time since the last iteration of the main loop started.
+
+ using ShouldQuit = core::ecs::ShouldQuit +
+
Resource used as a flag to indicate whether the main loop should stop running.
+
+ using Arguments = core::ecs::Arguments +
+
Resource which stores the command-line arguments.
+
+
template<typename... ComponentTypes>
+ using Query = core::ecs::Query<ComponentTypes...> +
+
System argument which holds the result of a query over all entities in world which match the given arguments.
+
+ using Entity = core::ecs::Entity +
+
Identifies an entity.
+
+ using Commands = core::ecs::Commands +
+
System argument used to write ECS commands and execute them at a later time.
+
+
template<typename T>
+ using Opt = core::ecs::Opt<T> +
+
Wrapper for reference types to indicate that the given argument type is optional in a query.
+
+
template<typename T, unsigned int M = DEFAULT_FILTER_MASK>
+ using EventReader = core::ecs::EventReader<T, M> +
+
System arguments used to read events of type T.
+
+
template<typename T>
+ using EventWriter = core::ecs::EventWriter<T> +
+
System argument which allows the system to send events of type T to other systems.
+
+ using RendererGrid = std::shared_ptr<impl::RendererGrid> +
+
Handle to a grid uploaded to the GPU, to be used for rendering.
+
+ using Renderer = std::shared_ptr<BaseRenderer> +
+
Resource which is an handle to a generic renderer.
+
+
+
+

Functions

+
+
+ void assetsPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void collisionsPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void fixedStepPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void gizmosPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void imguiPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void inputPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void physicsPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void gravityPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void solverPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void rendererPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void triangulate(const VoxelGrid& grid, + std::vector<VoxelVertex>& vertices, + std::vector<uint32_t>& indices) +
+
Triangulates a grid of voxels into an indexed mesh.
+
+ void scenePlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void screenPickerPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void settingsPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void splitscreenPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void transformPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void freeCameraPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void voxelsPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void windowPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Typedef documentation

+
+

+ using cubos::engine::DeltaTime = core::ecs::DeltaTime +

+

Resource which stores the time since the last iteration of the main loop started.

+

This resource is added and updated by the Cubos class.

+
+
+

+ using cubos::engine::ShouldQuit = core::ecs::ShouldQuit +

+

Resource used as a flag to indicate whether the main loop should stop running.

+

This resource is added by the Cubos class, initially set to true.

+
+
+

+ using cubos::engine::Arguments = core::ecs::Arguments +

+

Resource which stores the command-line arguments.

+

This resource is added by the Cubos class.

+
+
+

+
+ template<typename... ComponentTypes> +
+ using cubos::engine::Query = core::ecs::Query<ComponentTypes...> +

+

System argument which holds the result of a query over all entities in world which match the given arguments.

+

An example of a valid query is:

Query<Position&, const Velocity&, Opt<Rotation&>, Opt<const Scale&>>

This query will return all entities with a Position and Velocity component. Accessors to Rotation and Scale components are also passed but may be null if the component is not present in the entity. Whenever mutability is not needed, const should be used.

+
+
+

+ using cubos::engine::Entity = core::ecs::Entity +

+

Identifies an entity.

+

When serializing/deserializing, if there's a data::old::SerializationMap<Entity, std::string, EntityHash> in the context, it will be used to (de)serialize strings representing the entities. Otherwise, the identifiers will be (de)serialized as objects with two fields: their index and their generation.

+
+
+

+ using cubos::engine::Commands = core::ecs::Commands +

+

System argument used to write ECS commands and execute them at a later time.

+

Internally wraps a reference to a CommandBuffer object.

+
+
+

+
+ template<typename T> +
+ using cubos::engine::Opt = core::ecs::Opt<T> +

+

Wrapper for reference types to indicate that the given argument type is optional in a query.

+ + + + + + + + + + +
Template parameters
TArgument type.
+
+
+

+
+ template<typename T, unsigned int M = DEFAULT_FILTER_MASK> +
+ using cubos::engine::EventReader = core::ecs::EventReader<T, M> +

+

System arguments used to read events of type T.

+ + + + + + + + + + + + + + +
Template parameters
TEvent.
MFilter mask.
+

Filtering the received events by their mask is also possible via the parameter M. By default, the reader will read all events sent.

+
+
+

+
+ template<typename T> +
+ using cubos::engine::EventWriter = core::ecs::EventWriter<T> +

+

System argument which allows the system to send events of type T to other systems.

+ + + + + + + + + + +
Template parameters
T
+ +
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/namespacecubos_1_1engine_1_1impl.html b/docs-preview/pr-1032/namespacecubos_1_1engine_1_1impl.html new file mode 100644 index 000000000..2a8c463ed --- /dev/null +++ b/docs-preview/pr-1032/namespacecubos_1_1engine_1_1impl.html @@ -0,0 +1,122 @@ + + + + + cubos::engine::impl namespace | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::impl namespace +

+

Namespace to store the abstract types implemented by the renderer implementations.

+ +
+

Classes

+
+
+ class RendererGrid +
+
Represents a grid which was uploaded to the GPU.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/namespaces.html b/docs-preview/pr-1032/namespaces.html new file mode 100644 index 000000000..64f04374e --- /dev/null +++ b/docs-preview/pr-1032/namespaces.html @@ -0,0 +1,157 @@ + + + + + CUBOS. Docs + + + + + + + +
+
+
+
+
+

Namespaces

+ + +
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/namespacetesseratos.html b/docs-preview/pr-1032/namespacetesseratos.html new file mode 100644 index 000000000..31663200b --- /dev/null +++ b/docs-preview/pr-1032/namespacetesseratos.html @@ -0,0 +1,298 @@ + + + + + tesseratos namespace | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ tesseratos namespace +

+

Tesseratos module.

+ +
+

Classes

+
+
+ struct AssetSelectedEvent +
+
Event sent when an asset is selected.
+
+ struct EntitySelector +
+
Resource which identifies the currently selected entity.
+
+ class Toolbox +
+
Resource which manages other tools windows.
+
+
+
+

Functions

+
+
+ void assetExplorerPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+ auto assetSelectionPopup(const std::string& title, + cubos::engine::AnyAsset& selectedAsset, + const cubos::core::reflection::Type& type, + const cubos::engine::Assets& assets) -> bool +
+
Displays a modal popup to select an asset of a specified type.
+
+
template<typename T>
+ auto assetSelectionPopup(const std::string& title, + cubos::engine::AnyAsset& selectedAsset, + const cubos::engine::Assets& assets) -> bool +
+
Displays a modal popup to select an asset of a specified type.
+
+ void colliderGizmosPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+ void debugCameraPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+ void ecsStatisticsPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+ void entityInspectorPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+ void entitySelectorPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+ void metricsPanelPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+ void playPausePlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+ void plugin(cubos::engine::Cubos& cubos) +
+
Tesseratos entry function.
+
+ void sceneEditorPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+ void settingsInspectorPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+ void toolboxPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+ void transformGizmoPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+ void voxelPaletteEditorPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+ void worldInspectorPlugin(cubos::engine::Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ bool tesseratos::assetSelectionPopup(const std::string& title, + cubos::engine::AnyAsset& selectedAsset, + const cubos::core::reflection::Type& type, + const cubos::engine::Assets& assets) + +

+

Displays a modal popup to select an asset of a specified type.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
titlePopup title.
selectedAsset outOutput asset.
typeAsset type to filter by.
assetsAssets database to query.
ReturnsWhether an asset is selected.
+
+
+

+ +
+ template<typename T> +
+ bool tesseratos::assetSelectionPopup(const std::string& title, + cubos::engine::AnyAsset& selectedAsset, + const cubos::engine::Assets& assets) +

+

Displays a modal popup to select an asset of a specified type.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TAsset type to filter by.
Parameters
titlePopup title.
selectedAsset outOutput asset.
assetsAssets database to query.
ReturnsWhether an asset is selected.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/node_8hpp.html b/docs-preview/pr-1032/node_8hpp.html new file mode 100644 index 000000000..b70110fd5 --- /dev/null +++ b/docs-preview/pr-1032/node_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/ecs/query/node/node.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/nullable_8hpp.html b/docs-preview/pr-1032/nullable_8hpp.html new file mode 100644 index 000000000..5168db02e --- /dev/null +++ b/docs-preview/pr-1032/nullable_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/reflection/traits/nullable.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/opt_8hpp.html b/docs-preview/pr-1032/opt_8hpp.html new file mode 100644 index 000000000..141de86a8 --- /dev/null +++ b/docs-preview/pr-1032/opt_8hpp.html @@ -0,0 +1,135 @@ + + + + + core/ecs/query/opt.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/options_8hpp.html b/docs-preview/pr-1032/options_8hpp.html new file mode 100644 index 000000000..bc6647e2a --- /dev/null +++ b/docs-preview/pr-1032/options_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/ecs/system/options.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/pages.html b/docs-preview/pr-1032/pages.html new file mode 100644 index 000000000..bc98f15b9 --- /dev/null +++ b/docs-preview/pr-1032/pages.html @@ -0,0 +1,193 @@ + + + + + CUBOS. Docs + + + + + + + +
+
+
+
+
+

Pages

+ + +
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/palette_8hpp.html b/docs-preview/pr-1032/palette_8hpp.html new file mode 100644 index 000000000..2b0fb1780 --- /dev/null +++ b/docs-preview/pr-1032/palette_8hpp.html @@ -0,0 +1,140 @@ + + + + + engine/voxels/palette.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ engine/voxels/palette.hpp file +

+

Class cubos::engine::VoxelPalette.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::engine
+
Engine module.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::data
+
Data module.
+
+
+
+

Classes

+
+
+ class cubos::engine::VoxelPalette +
+
Holds a palette of materials. Supports up to 65535 materials.
+
+ class cubos::engine::VoxelPalette::Iterator +
+
Used to iterate over materials on the palette.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/pass_8hpp.html b/docs-preview/pr-1032/pass_8hpp.html new file mode 100644 index 000000000..2480a4235 --- /dev/null +++ b/docs-preview/pr-1032/pass_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/renderer/pps/pass.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/physics__bundle_8hpp.html b/docs-preview/pr-1032/physics__bundle_8hpp.html new file mode 100644 index 000000000..50e7b6267 --- /dev/null +++ b/docs-preview/pr-1032/physics__bundle_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/physics/physics_bundle.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/pipe_8hpp.html b/docs-preview/pr-1032/pipe_8hpp.html new file mode 100644 index 000000000..c48991efa --- /dev/null +++ b/docs-preview/pr-1032/pipe_8hpp.html @@ -0,0 +1,135 @@ + + + + + core/ecs/system/arguments/event/pipe.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/plugins_2gravity_8hpp.html b/docs-preview/pr-1032/plugins_2gravity_8hpp.html new file mode 100644 index 000000000..5d87da9e5 --- /dev/null +++ b/docs-preview/pr-1032/plugins_2gravity_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/physics/plugins/gravity.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/point__light_8hpp.html b/docs-preview/pr-1032/point__light_8hpp.html new file mode 100644 index 000000000..2dbb7e2cf --- /dev/null +++ b/docs-preview/pr-1032/point__light_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/renderer/point_light.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/pool_8hpp.html b/docs-preview/pr-1032/pool_8hpp.html new file mode 100644 index 000000000..676dbb935 --- /dev/null +++ b/docs-preview/pr-1032/pool_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/ecs/entity/pool.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/popup_8hpp.html b/docs-preview/pr-1032/popup_8hpp.html new file mode 100644 index 000000000..24ec71b0e --- /dev/null +++ b/docs-preview/pr-1032/popup_8hpp.html @@ -0,0 +1,140 @@ + + + + + tesseratos/asset_explorer/popup.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ tesseratos/asset_explorer/popup.hpp file +

+

Utility function to show up a popup containing assets with given type.

+ +
+

Namespaces

+
+
namespace tesseratos
+
Tesseratos module.
+
+
+
+

Functions

+
+
+ auto assetSelectionPopup(const std::string& title, + cubos::engine::AnyAsset& selectedAsset, + const cubos::core::reflection::Type& type, + const cubos::engine::Assets& assets) -> bool +
+
Displays a modal popup to select an asset of a specified type.
+
+
template<typename T>
+ auto assetSelectionPopup(const std::string& title, + cubos::engine::AnyAsset& selectedAsset, + const cubos::engine::Assets& assets) -> bool +
+
Displays a modal popup to select an asset of a specified type.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/position_8hpp.html b/docs-preview/pr-1032/position_8hpp.html new file mode 100644 index 000000000..1c888d156 --- /dev/null +++ b/docs-preview/pr-1032/position_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/transform/position.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/previous__position_8hpp.html b/docs-preview/pr-1032/previous__position_8hpp.html new file mode 100644 index 000000000..a3047b607 --- /dev/null +++ b/docs-preview/pr-1032/previous__position_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/physics/components/previous_position.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/primitives_8hpp.html b/docs-preview/pr-1032/primitives_8hpp.html new file mode 100644 index 000000000..73e67b78e --- /dev/null +++ b/docs-preview/pr-1032/primitives_8hpp.html @@ -0,0 +1,102 @@ + + + + + core/reflection/external/primitives.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/reflection/external/primitives.hpp file +

+

Reflection declarations for primitive types.

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/query_2fetcher_8hpp.html b/docs-preview/pr-1032/query_2fetcher_8hpp.html new file mode 100644 index 000000000..726c748a4 --- /dev/null +++ b/docs-preview/pr-1032/query_2fetcher_8hpp.html @@ -0,0 +1,135 @@ + + + + + core/ecs/query/fetcher.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/ecs/query/fetcher.hpp file +

+

Class cubos::core::ecs::QueryFetcher.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::ecs
+
ECS module.
+
+
+
+

Classes

+
+
+
template<typename T>
+ class cubos::core::ecs::QueryFetcher +
+
Type meant to be specialized which implements for each argument type the necessary logic to extract it from the tables.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/query_8hpp.html b/docs-preview/pr-1032/query_8hpp.html new file mode 100644 index 000000000..6a9b7db35 --- /dev/null +++ b/docs-preview/pr-1032/query_8hpp.html @@ -0,0 +1,135 @@ + + + + + core/ecs/system/arguments/query.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/ecs/system/arguments/query.hpp file +

+

Class cubos::core::ecs::Query.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::ecs
+
ECS module.
+
+
+
+

Classes

+
+
+
template<typename... Ts>
+ class cubos::core::ecs::Query +
+
System argument which holds the result of a query over all entities in world which match the given arguments.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/reader_8hpp.html b/docs-preview/pr-1032/reader_8hpp.html new file mode 100644 index 000000000..155b19771 --- /dev/null +++ b/docs-preview/pr-1032/reader_8hpp.html @@ -0,0 +1,139 @@ + + + + + core/ecs/system/arguments/event/reader.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/ecs/system/arguments/event/reader.hpp file +

+

Class cubos::core::ecs::EventReader.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::ecs
+
ECS module.
+
+
+
+

Classes

+
+
+
template<typename T, unsigned int M = DEFAULT_FILTER_MASK>
+ class cubos::core::ecs::EventReader +
+
System arguments used to read events of type T.
+
+ class cubos::core::ecs::EventReader::Iterator +
+
Used to iterate over events received by a reader.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/reflect_8hpp.html b/docs-preview/pr-1032/reflect_8hpp.html new file mode 100644 index 000000000..74c6aa3f9 --- /dev/null +++ b/docs-preview/pr-1032/reflect_8hpp.html @@ -0,0 +1,182 @@ + + + + + core/reflection/reflect.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/reflection/reflect.hpp file +

+

Function cubos::core::reflection::reflect and related macros.

+ +

Meant to be as minimal as possible in order to keep compile times low.

+
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::reflection
+
Reflection module.
+
+
+
+

Classes

+
+
+
template<typename T>
+ struct cubos::core::reflection::Reflect +
+
Defines the reflection function for the given type T.
+
+
+
+

Functions

+
+
+
template<typename T>
+ auto reflect() -> const Type& +
+
Reflects the given type T.
+
+
+
+

Defines

+
+
+ #define CUBOS_PACK(...) +
+
Helper macro used to pass arguments with commas to other macros, wrapped in parentheses.
+
+ #define CUBOS_REFLECT +
+
Declares a reflection method.
+
+ #define CUBOS_REFLECT_IMPL(T) +
+
Defines a reflection method.
+
+ #define CUBOS_REFLECT_EXTERNAL_DECL_TEMPLATE(T) +
+
Declares a specialization of cubos::core::reflection::Reflect for a templated type.
+
+ #define CUBOS_REFLECT_EXTERNAL_DECL(T) +
+
Declares a specialization of cubos::core::reflection::Reflect for a type.
+
+ #define CUBOS_REFLECT_EXTERNAL_IMPL(T) +
+
Implements a specialization of cubos::core::reflection::Reflect for a type.
+
+ #define CUBOS_REFLECT_EXTERNAL_TEMPLATE(args, + T) +
+
Both declares and implements a specialization of cubos::core::reflection::Reflect for a type.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/reflection_8hpp.html b/docs-preview/pr-1032/reflection_8hpp.html new file mode 100644 index 000000000..59c20f771 --- /dev/null +++ b/docs-preview/pr-1032/reflection_8hpp.html @@ -0,0 +1,147 @@ + + + + + core/ecs/reflection.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/ecs/reflection.hpp file +

+

Class cubos::core::ecs::TypeBuilder.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::ecs
+
ECS module.
+
+
+
+

Classes

+
+
+ struct cubos::core::ecs::SymmetricTrait +
+
Trait used to identify symmetric relations.
+
+ struct cubos::core::ecs::TreeTrait +
+
Trait used to identify tree relations.
+
+ struct cubos::core::ecs::EphemeralTrait +
+
Trait used to identify types which are ephemeral and should not be persisted.
+
+
template<typename T>
+ class cubos::core::ecs::TypeBuilder +
+
Builder for reflection::Type objects which represent ECS types.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/related_8hpp.html b/docs-preview/pr-1032/related_8hpp.html new file mode 100644 index 000000000..79c6c400a --- /dev/null +++ b/docs-preview/pr-1032/related_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/ecs/query/node/related.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/render__device_8hpp.html b/docs-preview/pr-1032/render__device_8hpp.html new file mode 100644 index 000000000..0adf0dc3f --- /dev/null +++ b/docs-preview/pr-1032/render__device_8hpp.html @@ -0,0 +1,596 @@ + + + + + core/gl/render_device.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/gl/render_device.hpp file +

+

Class cubos::core::gl::RenderDevice and related types.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::gl
+
Graphics module.
+
namespace cubos::core::gl::impl
+
Namespace to store the abstract types implemented by the render device implementations.
+
+
+
+

Classes

+
+
+ struct cubos::core::gl::FramebufferDesc +
+
Describes a framebuffer.
+
+ struct cubos::core::gl::FramebufferDesc::CubeMapTarget +
+
Describes a cube map target.
+
+ struct cubos::core::gl::FramebufferDesc::Texture2DTarget +
+
Describes a 2D texture target.
+
+ struct cubos::core::gl::FramebufferDesc::CubeMapArrayTarget +
+
Describes a cube map array target.
+
+ struct cubos::core::gl::FramebufferDesc::Texture2DArrayTarget +
+
Describes a 2D texture array target.
+
+ struct cubos::core::gl::FramebufferDesc::FramebufferTarget +
+
Describes a framebuffer target.
+
+ struct cubos::core::gl::RasterStateDesc +
+
Decribes a rasterizer state.
+
+ struct cubos::core::gl::DepthStencilStateDesc +
+
Describes a depth stencil state.
+
+ struct cubos::core::gl::DepthStencilStateDesc::Depth +
+
Decribes a depth state.
+
+ struct cubos::core::gl::DepthStencilStateDesc::Stencil +
+
Describes a stencil state.
+
+ struct cubos::core::gl::DepthStencilStateDesc::Stencil::Face +
+
Decribes a stencil face.
+
+ struct cubos::core::gl::BlendStateDesc +
+
Describes a blend state.
+
+ struct cubos::core::gl::SamplerDesc +
+
Describes a sampler.
+
+ struct cubos::core::gl::Texture1DDesc +
+
Describes a 1D texture.
+
+ struct cubos::core::gl::Texture2DDesc +
+
Describes a 2D texture.
+
+ struct cubos::core::gl::Texture2DArrayDesc +
+
Describes a 2D texture array.
+
+ struct cubos::core::gl::Texture3DDesc +
+
Describes a 3D texture.
+
+ struct cubos::core::gl::CubeMapDesc +
+
Describes a cube map.
+
+ struct cubos::core::gl::CubeMapArrayDesc +
+
Describes a cube map array.
+
+ struct cubos::core::gl::ConstantBufferElement +
+
Describes an element in a constant buffer.
+
+ struct cubos::core::gl::ConstantBufferStructure +
+
Describes the structure of a constant buffer.
+
+ struct cubos::core::gl::VertexElement +
+
Describes a vertex element.
+
+ struct cubos::core::gl::VertexArrayDesc +
+
Describes a vertex array.
+
+ class cubos::core::gl::RenderDevice +
+
Interface used to wrap low-level rendering APIs such as OpenGL.
+
+ class cubos::core::gl::impl::Framebuffer +
+
Abstract framebuffer.
+
+ class cubos::core::gl::impl::RasterState +
+
Abstract rasterizer state.
+
+ class cubos::core::gl::impl::DepthStencilState +
+
Abstract depth stencil state.
+
+ class cubos::core::gl::impl::BlendState +
+
Abstract blend state.
+
+ class cubos::core::gl::impl::Sampler +
+
Abstract sampler.
+
+ class cubos::core::gl::impl::Texture1D +
+
Abstract 1D texture.
+
+ class cubos::core::gl::impl::Texture2D +
+
Abstract 2D texture.
+
+ class cubos::core::gl::impl::Texture2DArray +
+
Abstract 2D texture array.
+
+ class cubos::core::gl::impl::Texture3D +
+
Abstract 3D texture.
+
+ class cubos::core::gl::impl::CubeMap +
+
Abstract cube map.
+
+ class cubos::core::gl::impl::CubeMapArray +
+
Abstract cube map.
+
+ class cubos::core::gl::impl::ConstantBuffer +
+
Abstract constant buffer.
+
+ class cubos::core::gl::impl::IndexBuffer +
+
Abstract index buffer.
+
+ class cubos::core::gl::impl::VertexBuffer +
+
Abstract vertex buffer.
+
+ class cubos::core::gl::impl::VertexArray +
+
Abstract vertex array.
+
+ class cubos::core::gl::impl::ShaderStage +
+
Abstract shader stage.
+
+ class cubos::core::gl::impl::ShaderPipeline +
+
Abstract shader pipeline.
+
+ class cubos::core::gl::impl::ShaderBindingPoint +
+
Abstract shader binding point.
+
+
+
+

Enums

+
+
+ enum class Property { MaxAnisotropy, + ComputeSupported } +
+
Render device properties that can be queried at runtime.
+
+ enum class Usage { Default, + Dynamic, + Static } +
+
Usage mode for buffers and textures.
+
+ enum class Type { Byte, + Short, + Int, + UByte, + UShort, + UInt, + NByte, + NShort, + NUByte, + NUShort, + Float } +
+
Data type.
+
+ enum class IndexFormat { UShort, + UInt } +
+
Index format.
+
+ enum class TextureFormat { R8SNorm, + R16SNorm, + RG8SNorm, + RG16SNorm, + RGBA8SNorm, + RGBA16SNorm, + R8UNorm, + R16UNorm, + RG8UNorm, + RG16UNorm, + RGBA8UNorm, + RGBA16UNorm, + R8SInt, + R16SInt, + RG8SInt, + RG16SInt, + RGBA8SInt, + RGBA16SInt, + R8UInt, + R16UInt, + RG8UInt, + RG16UInt, + RGBA8UInt, + RGBA16UInt, + R16Float, + R32Float, + RG16Float, + RG32Float, + RGB16Float, + RGB32Float, + RGBA16Float, + RGBA32Float, + Depth16, + Depth32, + Depth24Stencil8, + Depth32Stencil8 } +
+
Texture format.
+
+ enum class AddressMode { Repeat, + Mirror, + Clamp, + Border } +
+
Texture address mode.
+
+ enum class TextureFilter { None, + Nearest, + Linear } +
+
Texture filter type.
+
+ enum class Winding { CW, + CCW } +
+
Triangle winding mode.
+
+ enum class Face { Front, + Back, + FrontAndBack } +
+
Specifies a face.
+
+ enum class RasterMode { Wireframe, + Fill } +
+
Rasterizer mode.
+
+ enum class Compare { Never, + Less, + LEqual, + Greater, + GEqual, + Equal, + NEqual, + Always } +
+
Comparison function.
+
+ enum class StencilAction { Zero, + Keep, + Replace, + Increment, + IncrementWrap, + Decrement, + DecrementWrap, + Invert } +
+
Stencil action.
+
+ enum class BlendFactor { Zero, + One, + SrcColor, + InvSrcColor, + DstColor, + InvDstColor, + SrcAlpha, + InvSrcAlpha, + DstAlpha, + InvDstAlpha } +
+
Blend factor.
+
+ enum class BlendOp { Add, + Substract, + RevSubstract, + Min, + Max } +
+
Blend operation.
+
+ enum class Stage { Vertex, + Geometry, + Pixel, + Compute } +
+
Shader stage type.
+
+ enum class CubeFace { PositiveX = 0, + NegativeX = 1, + PositiveY = 2, + NegativeY = 3, + PositiveZ = 4, + NegativeZ = 5 } +
+
Cube map face.
+
+ enum class MemoryBarriers { None = 0, + VertexBuffer = 1, + IndexBuffer = 2, + ConstantBuffer = 4, + ImageAccess = 8, + TextureAccess = 16, + Framebuffer = 32, + All = VertexBuffer | IndexBuffer | ConstantBuffer | ImageAccess | TextureAccess | Framebuffer } +
+
Memory barrier flags for synchronization.
+
+ enum class Access { Read, + Write, + ReadWrite } +
+
Access mode for a resource.
+
+
+
+

Typedefs

+
+
+ using Framebuffer = std::shared_ptr<impl::Framebuffer> +
+
Handle to a framebuffer.
+
+ using RasterState = std::shared_ptr<impl::RasterState> +
+
Handle to a rasterizer state.
+
+ using DepthStencilState = std::shared_ptr<impl::DepthStencilState> +
+
Handle to a depth stencil state.
+
+ using BlendState = std::shared_ptr<impl::BlendState> +
+
Handle to a blend state.
+
+ using Sampler = std::shared_ptr<impl::Sampler> +
+
Handle to a sampler.
+
+ using Texture1D = std::shared_ptr<impl::Texture1D> +
+
Handle to a 1D texture.
+
+ using Texture2D = std::shared_ptr<impl::Texture2D> +
+
Handle to a 2D texture.
+
+ using Texture2DArray = std::shared_ptr<impl::Texture2DArray> +
+
Handle to a 2D texture array.
+
+ using Texture3D = std::shared_ptr<impl::Texture3D> +
+
Handle to a 3D texture.
+
+ using CubeMap = std::shared_ptr<impl::CubeMap> +
+
Handle to a cube map.
+
+ using CubeMapArray = std::shared_ptr<impl::CubeMapArray> +
+
Handle to a cube map array.
+
+ using ConstantBuffer = std::shared_ptr<impl::ConstantBuffer> +
+
Handle to a constant buffer.
+
+ using IndexBuffer = std::shared_ptr<impl::IndexBuffer> +
+
Handle to an index buffer.
+
+ using VertexBuffer = std::shared_ptr<impl::VertexBuffer> +
+
Handle to a vertex buffer.
+
+ using VertexArray = std::shared_ptr<impl::VertexArray> +
+
Handle to a vertex array.
+
+ using ShaderStage = std::shared_ptr<impl::ShaderStage> +
+
Handle to a shader stage.
+
+ using ShaderPipeline = std::shared_ptr<impl::ShaderPipeline> +
+
Handle to a shader pipeline.
+
+ using ShaderBindingPoint = impl::ShaderBindingPoint* +
+
Handle to a shader binding point.
+
+
+
+

Defines

+
+
+ #define CUBOS_CORE_GL_MAX_FRAMEBUFFER_RENDER_TARGET_COUNT +
+
Maximum number of render targets that can be set on a framebuffer.
+
+ #define CUBOS_CORE_GL_MAX_TEXTURE_2D_ARRAY_SIZE +
+
Maximum number of textures on a 2D texture array.
+
+ #define CUBOS_CORE_GL_MAX_CUBEMAP_ARRAY_SIZE +
+
Maximum number of cube maps on a cubemap array.
+
+ #define CUBOS_CORE_GL_MAX_MIP_LEVEL_COUNT +
+
Maximum mip level count.
+
+ #define CUBOS_CORE_GL_MAX_CONSTANT_BUFFER_ELEMENT_NAME_SIZE +
+
Maximum constant buffer element name size.
+
+ #define CUBOS_CORE_GL_MAX_CONSTANT_BUFFER_ELEMENT_COUNT +
+
Maximum constant buffer element count.
+
+ #define CUBOS_CORE_GL_MAX_VERTEX_ARRAY_ELEMENT_COUNT +
+
Maximum number of vertex array elements.
+
+ #define CUBOS_CORE_GL_MAX_VERTEX_ARRAY_BUFFER_COUNT +
+
Maximum number of buffers on a vertex array.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/renderer_8hpp.html b/docs-preview/pr-1032/renderer_8hpp.html new file mode 100644 index 000000000..a938f11a7 --- /dev/null +++ b/docs-preview/pr-1032/renderer_8hpp.html @@ -0,0 +1,156 @@ + + + + + engine/renderer/renderer.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ engine/renderer/renderer.hpp file +

+

Class cubos::engine::BaseRenderer and resource cubos::engine::Renderer.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::engine
+
Engine module.
+
namespace cubos::engine::impl
+
Namespace to store the abstract types implemented by the renderer implementations.
+
+
+
+

Classes

+
+
+ class cubos::engine::BaseRenderer +
+
Interface which abstracts different rendering methods.
+
+ struct cubos::engine::BaseRenderer::Viewport +
+
Struct which holds the viewport information for a camera, to be used for drawing.
+
+ class cubos::engine::impl::RendererGrid +
+
Represents a grid which was uploaded to the GPU.
+
+
+
+

Typedefs

+
+
+ using RendererGrid = std::shared_ptr<impl::RendererGrid> +
+
Handle to a grid uploaded to the GPU, to be used for rendering.
+
+ using Renderer = std::shared_ptr<BaseRenderer> +
+
Resource which is an handle to a generic renderer.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/renderer_output.png b/docs-preview/pr-1032/renderer_output.png new file mode 100644 index 0000000000000000000000000000000000000000..1867409f1acdefc1e9144c8491d1babf9227dcc0 GIT binary patch literal 118782 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 + + + + engine/physics/resources/gravity.hpp file | CUBOS. Docs + + + + + + + + +
+ + + +
+ + diff --git a/docs-preview/pr-1032/resources_8hpp.html b/docs-preview/pr-1032/resources_8hpp.html new file mode 100644 index 000000000..094edb7fc --- /dev/null +++ b/docs-preview/pr-1032/resources_8hpp.html @@ -0,0 +1,124 @@ + + + + + core/ecs/system/arguments/resources.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/rotation_8hpp.html b/docs-preview/pr-1032/rotation_8hpp.html new file mode 100644 index 000000000..c96347eb1 --- /dev/null +++ b/docs-preview/pr-1032/rotation_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/transform/rotation.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/scale_8hpp.html b/docs-preview/pr-1032/scale_8hpp.html new file mode 100644 index 000000000..bde95bc97 --- /dev/null +++ b/docs-preview/pr-1032/scale_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/transform/scale.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/scene_2bridge_8hpp.html b/docs-preview/pr-1032/scene_2bridge_8hpp.html new file mode 100644 index 000000000..91a3a9c12 --- /dev/null +++ b/docs-preview/pr-1032/scene_2bridge_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/scene/bridge.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/scene_8hpp.html b/docs-preview/pr-1032/scene_8hpp.html new file mode 100644 index 000000000..f6937dd56 --- /dev/null +++ b/docs-preview/pr-1032/scene_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/scene/scene.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/screen__picker_8hpp.html b/docs-preview/pr-1032/screen__picker_8hpp.html new file mode 100644 index 000000000..0df955ddb --- /dev/null +++ b/docs-preview/pr-1032/screen__picker_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/screen_picker/screen_picker.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/search-v2.js b/docs-preview/pr-1032/search-v2.js new file mode 100644 index 000000000..1fb71e1f8 --- /dev/null +++ b/docs-preview/pr-1032/search-v2.js @@ -0,0 +1,897 @@ +/* + This file is part of m.css. + + Copyright © 2017, 2018, 2019, 2020, 2021, 2022, 2023 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +"use strict"; /* it summons the Cthulhu in a proper way, they say */ + +var Search = { + formatVersion: 2, /* the data filename contains this number too */ + + dataSize: 0, /* used mainly by tests, not here */ + symbolCount: '…', + trie: null, + map: null, + mapFlagsOffset: null, + typeMap: null, + maxResults: 0, + + /* Type sizes and masks. The data is always fetched as 16/32bit number and + then masked to 1, 2, 3 or 4 bytes. Fortunately on LE a mask is enough, + on BE we'd have to read N bytes before and then mask. */ + nameSizeBytes: null, + nameSizeMask: null, + resultIdBytes: null, + resultIdMask: null, + fileOffsetBytes: null, + fileOffsetMask: null, + lookaheadBarrierMask: null, + + /* Always contains at least the root node offset and then one node offset + per entered character */ + searchString: '', + searchStack: [], + + /* So items don't get selected right away when a cursor is over results but + only after mouse moves */ + mouseMovedSinceLastRender: false, + + /* Whether we can go back in history in order to hide the search box or + not. We can't do that if we arrived directly on #search from outside. */ + canGoBackToHideSearch: false, + + /* Autocompletion in the input field is whitelisted only for character + input (so not deletion, cut, or anything else). This is flipped in the + onkeypress event and reset after each oninput event. */ + autocompleteNextInputEvent: false, + + init: function(buffer, maxResults) { + let view = new DataView(buffer); + + /* The file is too short to contain at least the headers and empty + sections */ + if(view.byteLength < 31) { + console.error("Search data too short"); + return false; + } + + if(view.getUint8(0) != 'M'.charCodeAt(0) || + view.getUint8(1) != 'C'.charCodeAt(0) || + view.getUint8(2) != 'S'.charCodeAt(0)) { + console.error("Invalid search data signature"); + return false; + } + + if(view.getUint8(3) != this.formatVersion) { + console.error("Invalid search data version"); + return false; + } + + /* Fetch type sizes. The only value that can fail is result ID byte + count, where value of 3 has no assigned meaning. */ + let typeSizes = view.getUint8(4, true); + if((typeSizes & 0x01) >> 0 == 0) { + this.fileOffsetBytes = 3; + this.fileOffsetMask = 0x00ffffff; + this.lookaheadBarrierMask = 0x00800000; + } else /* (typeSizes & 0x01) >> 0 == 1 */ { + this.fileOffsetBytes = 4; + this.fileOffsetMask = 0xffffffff; + this.lookaheadBarrierMask = 0x80000000; + } + if((typeSizes & 0x06) >> 1 == 0) { + this.resultIdBytes = 2; + this.resultIdMask = 0x0000ffff; + } else if((typeSizes & 0x06) >> 1 == 1) { + this.resultIdBytes = 3; + this.resultIdMask = 0x00ffffff; + } else if((typeSizes & 0x06) >> 1 == 2) { + this.resultIdBytes = 4; + this.resultIdMask = 0xffffffff; + } else /* (typeSizes & 0x06) >> 1 == 3 */ { + console.error("Invalid search data result ID byte value"); + return false; + } + if((typeSizes & 0x08) >> 3 == 0) { + this.nameSizeBytes = 1; + this.nameSizeMask = 0x00ff; + } else /* (typeSizes & 0x08) >> 3 == 1 */ { + this.nameSizeBytes = 2; + this.nameSizeMask = 0xffff; + } + + /* Separate the data into the trie and the result / type map. Because + we're reading larger values than there might be and then masking out + the high bytes, keep extra 1/2 byte padding at the end to avoid + OOB errors. */ + let mapOffset = view.getUint32(12, true); + let typeMapOffset = view.getUint32(16, true); + /* There may be a 3-byte file offset at the end of the trie which we'll + read as 32-bit, add one safety byte in that case */ + this.trie = new DataView(buffer, 20, mapOffset - 20 + (4 - this.fileOffsetBytes)); + /* There may be a 3-byte file size (for zero results) which we'll read + as 32-bit, add one safety byte in that case */ + this.map = new DataView(buffer, mapOffset, typeMapOffset - mapOffset + (4 - this.fileOffsetBytes)); + /* No variable-size types in the type map at the moment */ + this.typeMap = new DataView(buffer, typeMapOffset); + + /* Offset of the first result map item is after N + 1 offsets and N + flags, calculate flag offset from that */ + this.mapFlagsOffset = this.fileOffsetBytes*(((this.map.getUint32(0, true) & this.fileOffsetMask) - this.fileOffsetBytes)/(this.fileOffsetBytes + 1) + 1); + + /* Set initial properties */ + this.dataSize = buffer.byteLength; + this.symbolCount = view.getUint32(8, true) + " symbols (" + Math.round(this.dataSize/102.4)/10 + " kB)"; + this.maxResults = maxResults ? maxResults : 100; + this.searchString = ''; + this.searchStack = [this.trie.getUint32(0, true)]; + + /* istanbul ignore if */ + if(typeof document !== 'undefined') { + document.getElementById('search-symbolcount').innerHTML = this.symbolCount; + document.getElementById('search-input').disabled = false; + document.getElementById('search-input').placeholder = "Type something here …"; + document.getElementById('search-input').focus(); + + /* Search for the input value (there might be something already, + for example when going back in the browser) */ + let value = document.getElementById('search-input').value; + + /* Otherwise check the GET parameters for `q` and fill the input + with that */ + if(!value.length) { + var args = decodeURIComponent(window.location.search.substr(1)).trim().split('&'); + for(var i = 0; i != args.length; ++i) { + if(args[i].substring(0, 2) != 'q=') continue; + + value = document.getElementById('search-input').value = args[i].substring(2); + break; + } + } + + if(value.length) Search.searchAndRender(value); + } + + return true; + }, + + download: /* istanbul ignore next */ function(url) { + var req = window.XDomainRequest ? new XDomainRequest() : new XMLHttpRequest(); + if(!req) return; + + req.open("GET", url, true); + req.responseType = 'arraybuffer'; + req.onreadystatechange = function() { + if(req.readyState != 4) return; + + Search.init(req.response); + } + req.send(); + }, + + base85decode: function(base85string) { + function charValue(char) { + if(char >= 48 && char < 58) /* 0-9 -> 0-9 */ + return char - 48 + 0; + if(char >= 65 && char < 91) /* A-Z -> 10-35 */ + return char - 65 + 10; + if(char >= 97 && char < 123) /* a-z -> 36-61 */ + return char - 97 + 36; + if(char == 33) /* ! -> 62 */ + return 62; + /* skipping 34 (') */ + if(char >= 35 && char < 39) /* #-& -> 63-66 */ + return char - 35 + 63; + /* skipping 39 (") */ + if(char >= 40 && char < 44) /* (-+ -> 67-70 */ + return char - 40 + 67; + /* skipping 44 (,) */ + if(char == 45) /* - -> 71 */ + return 71; + if(char >= 59 && char < 65) /* ;-@ -> 72-77 */ + return char - 59 + 72; + if(char >= 94 && char < 97) /* ^-` -> 78-80 */ + return char - 94 + 78; + if(char >= 123 && char < 127) /* {-~ -> 81-84 */ + return char - 123 + 81; + + return 0; /* Interpret padding values as zeros */ + } + + /* Pad the string for easier decode later. We don't read past the file + end, so it doesn't matter what garbage is there. */ + if(base85string.length % 5) { + console.log("Expected properly padded base85 data"); + return; + } + + let buffer = new ArrayBuffer(base85string.length*4/5); + let data8 = new DataView(buffer); + for(let i = 0; i < base85string.length; i += 5) { + let char1 = charValue(base85string.charCodeAt(i + 0)); + let char2 = charValue(base85string.charCodeAt(i + 1)); + let char3 = charValue(base85string.charCodeAt(i + 2)); + let char4 = charValue(base85string.charCodeAt(i + 3)); + let char5 = charValue(base85string.charCodeAt(i + 4)); + + data8.setUint32(i*4/5, char5 + + char4*85 + + char3*85*85 + + char2*85*85*85 + + char1*85*85*85*85, false); /* BE, yes */ + } + + return buffer; + }, + + load: function(base85string) { + return this.init(this.base85decode(base85string)); + }, + + /* http://ecmanaut.blogspot.com/2006/07/encoding-decoding-utf8-in-javascript.html */ + toUtf8: function(string) { return unescape(encodeURIComponent(string)); }, + fromUtf8: function(string) { return decodeURIComponent(escape(string)); }, + + autocompletedCharsToUtf8: function(chars) { + /* Strip incomplete UTF-8 chars from the autocompletion end */ + for(let i = chars.length - 1; i >= 0; --i) { + let c = chars[i]; + + /* We're safe, finish */ + if( + /* ASCII value at the end */ + (c < 128 && i + 1 == chars.length) || + + /* Full two-byte character at the end */ + ((c & 0xe0) == 0xc0 && i + 2 == chars.length) || + + /* Full three-byte character at the end */ + ((c & 0xf0) == 0xe0 && i + 3 == chars.length) || + + /* Full four-byte character at the end */ + ((c & 0xf8) == 0xf0 && i + 4 == chars.length) + ) break; + + /* Continuing UTF-8 character, go further back */ + if((c & 0xc0) == 0x80) continue; + + /* Otherwise the character is not complete, drop it from the end */ + chars.length = i; + break; + } + + /* Convert the autocompleted UTF-8 sequence to a string */ + let suggestedTabAutocompletionString = ''; + for(let i = 0; i != chars.length; ++i) + suggestedTabAutocompletionString += String.fromCharCode(chars[i]); + return suggestedTabAutocompletionString; + }, + + /* Returns the values in UTF-8, but input is in whatever shitty 16bit + encoding JS has */ + search: function(searchString) { + /* Normalize the search string first, convert to UTF-8 and trim spaces + from the left. From the right they're trimmed only if nothing is + found, see below. */ + searchString = this.toUtf8(searchString.toLowerCase().replace(/^\s+/,'')); + + /* TODO: maybe i could make use of InputEvent.data and others here */ + + /* Find longest common prefix of previous and current value so we don't + need to needlessly search again */ + let max = Math.min(searchString.length, this.searchString.length); + let commonPrefix = 0; + for(; commonPrefix != max; ++commonPrefix) + if(searchString[commonPrefix] != this.searchString[commonPrefix]) break; + + /* Drop items off the stack if it has has more than is needed for the + common prefix (it needs to have at least one item, though) */ + if(commonPrefix + 1 < this.searchStack.length) + this.searchStack.splice(commonPrefix + 1, this.searchStack.length - commonPrefix - 1); + + /* Add new characters from the search string */ + let foundPrefix = commonPrefix; + for(; foundPrefix != searchString.length; ++foundPrefix) { + /* Calculate offset and count of children */ + let offset = this.searchStack[this.searchStack.length - 1]; + + /* If there's a lot of results, the result count is a 16bit BE value + instead */ + let resultCount = this.trie.getUint8(offset); + let resultCountSize = 1; + if(resultCount & 0x80) { + resultCount = this.trie.getUint16(offset, false) & ~0x8000; + ++resultCountSize; + } + + let childCount = this.trie.getUint8(offset + resultCountSize); + + /* Go through all children and find the next offset */ + let childOffset = offset + resultCountSize + 1 + resultCount*this.resultIdBytes; + let found = false; + for(let j = 0; j != childCount; ++j) { + if(String.fromCharCode(this.trie.getUint8(childOffset + j)) != searchString[foundPrefix]) + continue; + + this.searchStack.push(this.trie.getUint32(childOffset + childCount + j*this.fileOffsetBytes, true) & this.fileOffsetMask & ~this.lookaheadBarrierMask); + found = true; + break; + } + + /* Character not found */ + if(!found) { + /* If we found everything except spaces at the end, pretend the + spaces aren't there. On the other hand, we *do* want to + try searching with the spaces first -- it can narrow down + the result list for page names or show subpages (which are + after a lookahead barrier that's a space). */ + if(!searchString.substr(foundPrefix).trim().length) + searchString = searchString.substr(0, foundPrefix); + + break; + } + } + + /* Save the whole found prefix for next time */ + this.searchString = searchString.substr(0, foundPrefix); + + /* If the whole thing was not found, return an empty result and offer + external search */ + if(foundPrefix != searchString.length) { + /* istanbul ignore if */ + if(typeof document !== 'undefined') { + let link = document.getElementById('search-external'); + if(link) + link.href = link.dataset.searchEngine.replace('{query}', encodeURIComponent(searchString)); + } + return [[], '']; + } + + /* Otherwise gather the results */ + let suggestedTabAutocompletionChars = []; + let results = []; + let leaves = [[this.searchStack[this.searchStack.length - 1], 0]]; + while(leaves.length) { + /* Pop offset from the queue */ + let current = leaves.shift(); + let offset = current[0]; + let suffixLength = current[1]; + + /* Calculate child count. If there's a lot of results, the count + "leaks over" to the child count storage. */ + /* TODO: hmmm. this is helluvalot duplicated code. hmm. */ + let resultCount = this.trie.getUint8(offset); + let resultCountSize = 1; + if(resultCount & 0x80) { + resultCount = this.trie.getUint16(offset, false) & ~0x8000; + ++resultCountSize; + } + + let childCount = this.trie.getUint8(offset + resultCountSize); + + /* Populate the results with all values associated with this node */ + for(let i = 0; i != resultCount; ++i) { + let index = this.trie.getUint32(offset + resultCountSize + 1 + i*this.resultIdBytes, true) & this.resultIdMask; + results.push(this.gatherResult(index, suffixLength, 0xffffff)); /* should be enough haha */ + + /* 'nuff said. */ + if(results.length >= this.maxResults) + return [results, this.autocompletedCharsToUtf8(suggestedTabAutocompletionChars)]; + } + + /* Dig deeper */ + let childOffset = offset + resultCountSize + 1 + resultCount*this.resultIdBytes; + for(let j = 0; j != childCount; ++j) { + let offsetBarrier = this.trie.getUint32(childOffset + childCount + j*this.fileOffsetBytes, true) & this.fileOffsetMask; + + /* Lookahead barrier, don't dig deeper */ + if(offsetBarrier & this.lookaheadBarrierMask) continue; + + /* Append to the queue */ + leaves.push([offsetBarrier & ~this.lookaheadBarrierMask, suffixLength + 1]); + + /* We don't have anything yet and this is the only path + forward, add the char to suggested Tab autocompletion. Can't + extract it from the leftmost 8 bits of offsetBarrier because + that would make it negative, have to load as Uint8 instead. + Also can't use String.fromCharCode(), because later doing + str.charCodeAt() would give me back UTF-16 values, which is + absolutely unwanted when all I want is check for truncated + UTF-8. */ + if(!results.length && leaves.length == 1 && childCount == 1) + suggestedTabAutocompletionChars.push(this.trie.getUint8(childOffset + j)); + } + } + + return [results, this.autocompletedCharsToUtf8(suggestedTabAutocompletionChars)]; + }, + + gatherResult: function(index, suffixLength, maxUrlPrefix) { + let flags = this.map.getUint8(this.mapFlagsOffset + index); + let resultOffset = this.map.getUint32(index*this.fileOffsetBytes, true) & this.fileOffsetMask; + + /* The result is an alias, parse the aliased prefix */ + let aliasedIndex = null; + if((flags & 0xf0) == 0x00) { + aliasedIndex = this.map.getUint32(resultOffset, true) & this.resultIdMask; + resultOffset += this.resultIdBytes; + } + + /* The result has a prefix, parse that first, recursively */ + let name = ''; + let url = ''; + if(flags & (1 << 3)) { + let prefixIndex = this.map.getUint32(resultOffset, true) & this.resultIdMask; + let prefixUrlPrefixLength = Math.min(this.map.getUint16(resultOffset + this.resultIdBytes, true) & this.nameSizeMask, maxUrlPrefix); + + let prefix = this.gatherResult(prefixIndex, 0 /*ignored*/, prefixUrlPrefixLength); + name = prefix.name; + url = prefix.url; + + resultOffset += this.resultIdBytes + this.nameSizeBytes; + } + + /* The result has a suffix, extract its length */ + let resultSuffixLength = 0; + if(flags & (1 << 0)) { + resultSuffixLength = this.map.getUint16(resultOffset, true) & this.nameSizeMask; + resultOffset += this.nameSizeBytes; + } + + let nextResultOffset = this.map.getUint32((index + 1)*this.fileOffsetBytes, true) & this.fileOffsetMask; + + /* Extract name */ + let j = resultOffset; + for(; j != nextResultOffset; ++j) { + let c = this.map.getUint8(j); + + /* End of null-delimited name */ + if(!c) { + ++j; + break; /* null-delimited */ + } + + name += String.fromCharCode(c); /* eheh. IS THIS FAST?! */ + } + + /* The result is an alias and we're not deep inside resolving a prefix, + extract the aliased name and URL */ + /* TODO: this abuses 0xffffff to guess how the call stack is deep and + that's just wrong, fix! */ + if(aliasedIndex != null && maxUrlPrefix == 0xffffff) { + let alias = this.gatherResult(aliasedIndex, 0 /* ignored */, 0xffffff); /* should be enough haha */ + + /* Keeping in UTF-8, as we need that for proper slicing (and concatenating) */ + return {name: name, + alias: alias.name, + url: alias.url, + flags: alias.flags, + cssClass: alias.cssClass, + typeName: alias.typeName, + suffixLength: suffixLength + resultSuffixLength}; + } + + /* Otherwise extract URL from here */ + let max = Math.min(j + maxUrlPrefix - url.length, nextResultOffset); + for(; j != max; ++j) { + url += String.fromCharCode(this.map.getUint8(j)); + } + + /* This is an alias, return what we have, without parsed CSS class and + type name as those are retrieved from the final target type */ + if(!(flags >> 4)) + return {name: name, + url: url, + flags: flags & 0x0f, + suffixLength: suffixLength + resultSuffixLength}; + + /* Otherwise, get CSS class and type name for the result label */ + let typeMapIndex = (flags >> 4) - 1; + let cssClass = [ + /* Keep in sync with _search.py */ + 'm-default', + 'm-primary', + 'm-success', + 'm-warning', + 'm-danger', + 'm-info', + 'm-dim' + ][this.typeMap.getUint8(typeMapIndex*2)]; + let typeNameOffset = this.typeMap.getUint8(typeMapIndex*2 + 1); + let nextTypeNameOffset = this.typeMap.getUint8((typeMapIndex + 1)*2 + 1); + let typeName = ''; + for(let j = typeNameOffset; j != nextTypeNameOffset; ++j) + typeName += String.fromCharCode(this.typeMap.getUint8(j)); + + /* Keeping in UTF-8, as we need that for proper slicing (and + concatenating). Strip the type from the flags, as it's now expressed + directly. */ + return {name: name, + url: url, + flags: flags & 0x0f, + cssClass: cssClass, + typeName: typeName, + suffixLength: suffixLength + resultSuffixLength}; + }, + + escape: function(name) { + return name.replace(/[\"&<>]/g, function (a) { + return { '"': '"', '&': '&', '<': '<', '>': '>' }[a]; + }); + }, + escapeForRtl: function(name) { + /* Besides the obvious escaping of HTML entities we also need + to escape punctuation, because due to the RTL hack to cut + text off on left side the punctuation characters get + reordered (of course). Prepending ‎ works for most + characters, parentheses we need to *soak* in it. But only + the right ones. And that for some reason needs to be also for &. + Huh. https://en.wikipedia.org/wiki/Right-to-left_mark */ + return this.escape(name).replace(/[:=]/g, '‎$&').replace(/(\)|>|&|\/)/g, '‎$&‎'); + }, + + renderResults: /* istanbul ignore next */ function(resultsSuggestedTabAutocompletion) { + if(!this.searchString.length) { + document.getElementById('search-help').style.display = 'block'; + document.getElementById('search-results').style.display = 'none'; + document.getElementById('search-notfound').style.display = 'none'; + return; + } + + document.getElementById('search-help').style.display = 'none'; + + /* Results found */ + if(resultsSuggestedTabAutocompletion[0].length) { + let results = resultsSuggestedTabAutocompletion[0]; + + document.getElementById('search-results').style.display = 'block'; + document.getElementById('search-notfound').style.display = 'none'; + + let list = ''; + for(let i = 0; i != results.length; ++i) { + /* Labels + */ + list += '
' + results[i].typeName + '
' + (results[i].flags & 2 ? '
deprecated
' : '') + (results[i].flags & 4 ? '
deleted
' : ''); + + /* Render the alias (cut off from the right) */ + if(results[i].alias) { + list += '
' + this.escape(results[i].name.substr(0, results[i].name.length - this.searchString.length - results[i].suffixLength)) + '' + this.escape(results[i].name.substr(results[i].name.length - this.searchString.length - results[i].suffixLength, this.searchString.length)) + '' + this.escapeForRtl(results[i].name.substr(results[i].name.length - results[i].suffixLength)) + ': ' + this.escape(results[i].alias) + ''; + + /* Render the normal thing (cut off from the left, have to + escape for RTL) */ + } else { + list += '
' + this.escapeForRtl(results[i].name.substr(0, results[i].name.length - this.searchString.length - results[i].suffixLength)) + '' + this.escapeForRtl(results[i].name.substr(results[i].name.length - this.searchString.length - results[i].suffixLength, this.searchString.length)) + '' + this.escapeForRtl(results[i].name.substr(results[i].name.length - results[i].suffixLength)); + } + + /* The closing */ + list += '
'; + } + document.getElementById('search-results').innerHTML = this.fromUtf8(list); + document.getElementById('search-current').scrollIntoView(true); + + /* Append the suggested tab autocompletion, if any, and if the user + didn't just delete it */ + let searchInput = document.getElementById('search-input'); + if(this.autocompleteNextInputEvent && resultsSuggestedTabAutocompletion[1].length && searchInput.selectionEnd == searchInput.value.length) { + let suggestedTabAutocompletion = this.fromUtf8(resultsSuggestedTabAutocompletion[1]); + + let lengthBefore = searchInput.value.length; + searchInput.value += suggestedTabAutocompletion; + searchInput.setSelectionRange(lengthBefore, searchInput.value.length); + } + + /* Nothing found */ + } else { + document.getElementById('search-results').innerHTML = ''; + document.getElementById('search-results').style.display = 'none'; + document.getElementById('search-notfound').style.display = 'block'; + } + + /* Don't allow things to be selected just by motionless mouse cursor + suddenly appearing over a search result */ + this.mouseMovedSinceLastRender = false; + + /* Reset autocompletion, if it was allowed. It'll get whitelisted next + time a character gets inserted. */ + this.autocompleteNextInputEvent = false; + }, + + searchAndRender: /* istanbul ignore next */ function(value) { + let prev = performance.now(); + let results = this.search(value); + let after = performance.now(); + this.renderResults(results); + if(this.searchString.length) { + document.getElementById('search-symbolcount').innerHTML = + results[0].length + (results[0].length >= this.maxResults ? '+' : '') + " results (" + Math.round((after - prev)*10)/10 + " ms)"; + } else + document.getElementById('search-symbolcount').innerHTML = this.symbolCount; + }, +}; + +/* istanbul ignore next */ +function selectResult(event) { + if(!Search.mouseMovedSinceLastRender) return; + + if(event.currentTarget.parentNode.id == 'search-current') return; + + let current = document.getElementById('search-current'); + current.removeAttribute('id'); + event.currentTarget.parentNode.id = 'search-current'; +} + +/* This is separated from showSearch() because we need non-destructive behavior + when appearing directly on a URL with #search */ /* istanbul ignore next */ +function updateForSearchVisible() { + /* Prevent accidental scrolling of the body, prevent page layout jumps */ + let scrolledBodyWidth = document.body.offsetWidth; + document.body.style.overflow = 'hidden'; + document.body.style.paddingRight = (document.body.offsetWidth - scrolledBodyWidth) + 'px'; + + document.getElementById('search-input').value = ''; + document.getElementById('search-input').focus(); + document.getElementById('search-results').style.display = 'none'; + document.getElementById('search-notfound').style.display = 'none'; + document.getElementById('search-help').style.display = 'block'; +} + +/* istanbul ignore next */ +function showSearch() { + window.location.hash = '#search'; + Search.canGoBackToHideSearch = true; + + updateForSearchVisible(); + document.getElementById('search-symbolcount').innerHTML = Search.symbolCount; + return false; +} + +/* istanbul ignore next */ +function hideSearch() { + /* If the search box was opened using showSearch(), we can go back in the + history. Otherwise (for example when we landed to #search from a + bookmark or another server), going back would not do the right thing and + in that case we simply replace the current history state. */ + if(Search.canGoBackToHideSearch) { + Search.canGoBackToHideSearch = false; + window.history.back(); + } else { + window.location.hash = '#!'; + window.history.replaceState('', '', window.location.pathname); + } + + /* Restore scrollbar, prevent page layout jumps */ + document.body.style.overflow = 'auto'; + document.body.style.paddingRight = '0'; + + return false; +} + +/* istanbul ignore next */ +function copyToKeyboard(text) { + /* Append to the popup, appending to document.body would cause it to + scroll when focused */ + let searchPopup = document.getElementsByClassName('m-doc-search')[0]; + let textarea = document.createElement("textarea"); + textarea.value = text; + searchPopup.appendChild(textarea); + textarea.focus(); + textarea.select(); + + document.execCommand('copy'); + + searchPopup.removeChild(textarea); + document.getElementById('search-input').focus(); +} + +/* Only in case we're running in a browser. Why a simple if(document) doesn't + work is beyond me. */ /* istanbul ignore if */ +if(typeof document !== 'undefined') { + document.getElementById('search-input').oninput = function(event) { + Search.searchAndRender(document.getElementById('search-input').value); + }; + + document.onkeydown = function(event) { + /* Search shown */ + if(window.location.hash == '#search') { + /* Close the search */ + if(event.key == 'Escape') { + hideSearch(); + + /* Focus the search input, if not already, using T or Tab */ + } else if((!document.activeElement || document.activeElement.id != 'search-input') && (event.key.toLowerCase() == 't' || event.key == 'Tab') && !event.shiftKey && !event.ctrlKey && !event.altKey && !event.metaKey) { + document.getElementById('search-input').focus(); + return false; /* so T doesn't get entered into the box */ + + /* Fill in the autocompleted selection */ + } else if(event.key == 'Tab' && !event.shiftKey && !event.ctrlKey && !event.altKey && !event.metaKey) { + /* But only if the input has selection at the end */ + let input = document.getElementById('search-input'); + if(input.selectionEnd == input.value.length && input.selectionStart != input.selectionEnd) { + input.setSelectionRange(input.value.length, input.value.length); + return false; /* so input won't lose focus */ + } + + /* Select next item */ + } else if(event.key == 'ArrowDown') { + let current = document.getElementById('search-current'); + if(current) { + let next = current.nextSibling; + if(next) { + current.id = ''; + next.id = 'search-current'; + next.scrollIntoView(false); + } + } + return false; /* so the keypress doesn't affect input cursor */ + + /* Select prev item */ + } else if(event.key == 'ArrowUp') { + let current = document.getElementById('search-current'); + if(current) { + let prev = current.previousSibling; + if(prev) { + current.id = ''; + prev.id = 'search-current'; + prev.scrollIntoView(false); + } + } + return false; /* so the keypress doesn't affect input cursor */ + + /* Go to result (if any) */ + } else if(event.key == 'Enter') { + let result = document.getElementById('search-current'); + if(result) { + result.firstElementChild.click(); + + /* We might be staying on the same page, so restore scrollbar, + and prevent page layout jumps */ + document.body.style.overflow = 'auto'; + document.body.style.paddingRight = '0'; + } + return false; /* so the form doesn't get sent */ + + /* Copy (Markdown) link to keyboard */ + } else if((event.key.toLowerCase() == 'l' || event.key.toLowerCase() == 'm') && event.metaKey) { + let result = document.getElementById('search-current'); + if(result) { + let plain = event.key.toLowerCase() == 'l'; + let link = plain ? result.firstElementChild.href : + '[' + result.firstElementChild.dataset.mdLinkTitle + '](' + result.firstElementChild.href + ')'; + + copyToKeyboard(link); + + /* Add CSS class to the element for visual feedback (this + will get removed on keyup), but only if it's not already + there (in case of key repeat, e.g.) */ + if(result.className.indexOf('m-doc-search-copied') == -1) + result.className += ' m-doc-search-copied'; + console.log("Copied " + (plain ? "link" : "Markdown link") + " to " + result.firstElementChild.dataset.mdLinkTitle); + } + + return false; /* so L doesn't get entered into the box */ + + /* Looks like the user is inserting some text (and not cutting, + copying or whatever), allow autocompletion for the new + character. The oninput event resets this back to false, so this + basically whitelists only keyboard input, including Shift-key + and special chars using right Alt (or equivalent on Mac), but + excluding Ctrl-key, which is usually not for text input. In the + worst case the autocompletion won't be allowed ever, which is + much more acceptable behavior than having no ability to disable + it and annoying the users. */ + } else if(event.key != 'Backspace' && event.key != 'Delete' && !event.metaKey && (!event.ctrlKey || event.altKey) + /* Don't ever attempt autocompletion with Android virtual + keyboards, as those report all `event.key`s as + `Unidentified` (on Chrome) or `Process` (on Firefox) with + `event.code` 229 and thus we have no way to tell if a text + is entered or deleted. See this WONTFIX bug for details: + https://bugs.chromium.org/p/chromium/issues/detail?id=118639 + Couldn't find any similar bugreport for Firefox, but I + assume the virtual keyboard is to blame. + + An alternative is to hook into inputEvent, which has the + data, but ... there's more cursed issues right after that: + + - setSelectionRange() in Chrome on Android only renders + stuff, but doesn't actually act as such. Pressing + Backspace will only remove the highlight, but the text + stays here. Only delay-calling it through a timeout will + work as intended. Possibly related SO suggestion (back + then not even the rendering worked properly): + https://stackoverflow.com/a/13235951 + Possibly related Chrome bug: + https://bugs.chromium.org/p/chromium/issues/detail?id=32865 + + - On Firefox Mobile, programmatically changing an input + value (for the autocompletion highlight) will trigger an + input event, leading to search *and* autocompletion being + triggered again. Ultimately that results in newly typed + characters not replacing the autocompletion but rather + inserting before it, corrupting the searched string. This + event has to be explicitly ignored. + + - On Firefox Mobile, deleting a highlight with the + backspace key will result in *three* input events instead + of one: + 1. `deleteContentBackward` removing the selection (same + as Chrome or desktop Firefox) + 2. `deleteContentBackward` removing *the whole word* + that contained the selection (or the whole text if + it's just one word) + 3. `insertCompositionText`, adding the word back in, + resulting in the same state as (1). + I have no idea WHY it has to do this (possibly some + REALLY NASTY workaround to trigger correct font shaping?) + but ultimately it results in the autocompletion being + added again right after it got deleted, making this whole + thing VERY annoying to use. + + I attempted to work around the above, but it resulted in a + huge amount of browser-specific code that achieves only 90% + of the goal, with certain corner cases still being rather + broken (such as autocompletion randomly triggering when + erasing the text, even though it shouldn't). So disabling + autocompletion on this HELLISH BROKEN PLATFORM is the best + option at the moment. */ + && event.key != 'Unidentified' && event.key != 'Process' + ) { + Search.autocompleteNextInputEvent = true; + /* Otherwise reset the flag, because when the user would press e.g. + the 'a' key and then e.g. ArrowRight (which doesn't trigger + oninput), a Backspace after would still result in + autocompleteNextInputEvent, because nothing reset it back. */ + } else { + Search.autocompleteNextInputEvent = false; + } + + /* Search hidden */ + } else { + /* Open the search on the T or Tab key */ + if((event.key.toLowerCase() == 't' || event.key == 'Tab') && !event.shiftKey && !event.ctrlKey && !event.altKey && !event.metaKey) { + showSearch(); + return false; /* so T doesn't get entered into the box */ + } + } + }; + + document.onkeyup = function(event) { + /* Remove highlight after key is released after a link copy */ + if((event.key.toLowerCase() == 'l' || event.key.toLowerCase() == 'm') && event.metaKey) { + let result = document.getElementById('search-current'); + if(result) result.className = result.className.replace(' m-doc-search-copied', ''); + } + }; + + /* Allow selecting items by mouse hover only after it moves once the + results are populated. This prevents a random item getting selected if + the cursor is left motionless over the result area. */ + document.getElementById('search-results').onmousemove = function() { + Search.mouseMovedSinceLastRender = true; + }; + + /* If #search is already present in the URL, hide the scrollbar etc. for a + consistent experience */ + if(window.location.hash == '#search') updateForSearchVisible(); +} + +/* For Node.js testing */ /* istanbul ignore else */ +if(typeof module !== 'undefined') { module.exports = { Search: Search }; } diff --git a/docs-preview/pr-1032/searchdata-v2.js b/docs-preview/pr-1032/searchdata-v2.js new file mode 100644 index 000000000..7ec3f80ef --- /dev/null +++ b/docs-preview/pr-1032/searchdata-v2.js @@ -0,0 +1,2 @@ +/* Generated by https://mcss.mosra.cz/documentation/doxygen/. Do not edit. */ +Search.load('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�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�Cv5>Hq)%bEN7300DEV>Hq)%Ww7c100DBg>Hq)&YjBk60KDn|00BC}>Hq-&y#zYU>VNHq)%W#H-n00DO9>Hq)&cV&d?0PN}j00DXO>Hq)%W&G*@0RXK500DFe>i_@&Wen>800DCn>i_@&W*F-L00Cwm>i_@&ZzSsg00BBG>i_`(t^qnQ>wo|ObT;b%00C}3>i_@&Wkl-$00DMN>i_@&Wl-w?00C@P>i_@&Y+UOA00D1e>i_@&a%k%S00Coe>i_`&$^rlZZhGqg00D1)>i_@&X@u(l00DH0>i_@&X^`sx00DEB>i_@&Z=CA@00D5K>i_@&I;iUa0RhVbIi_@&ZoKON00Cvf>i_@&cF5}h00Cvr>i_@&Wz_2c00DN|>i_@&Z{X_y0RV;w00D07>i_@&Z}95?00DIN>i_@&bo}c800DIZ>;M4(hX?=xWDe{A00CtZ>;M1(a~SLZ00DCz>;M1(WhCqX00D9;>;M1)VsHrT05I$T00BBS>;M4)hzL4B?0^6PbVlp|00C}J>;M1(WmN0{00DMd>;M1(Wnk<800C}h>;M1(Z*1%U00DGz>;M1(ba?Cl00DJ=>;M1*b8TXD>j38K0EFxS00Cu+>;M1(bC~P^0RXxO00DEP>;M1(a;WS800CvL>;M1(X|(JB00CyY>;M1(X~66N00Csi>;M1(Z_Mlf00C{%>;M1(I@s(00Rg)QI^OJn00DI5>;M1(ZtUy;00Cw4>;M1(cKGZ700CwG>;M1(a|G=G00D9e?EnA)Wf1KE00C(h?EnA)W*qGR00C(t?EnA*b!49G04VJM00D0I47*Dc0=(0Ria*DBA6S00DF0?EnA*Wogju0O;)i00DUJ?EnD)=mY=(DgNyM0RiU(C<5+)00CqO?f?J*Wf1NF00DCr?f?J*a~$pf00Ctp?f?J*awzTq00UxSaK`Nb`0W5L?f?J*IyCM80Rig-IzsM%00Cu4?f?J*bWrX900CiE?f?J*bX@KL0RRjJ00CrZ?f?J*VQlUI00D4v?f?J*Wq9rY00C`&?f?J*VTA4g0RRmK00Cr>?f?J*Wt8p!00DHG?f?J*W1#K;00CvD?f?J*ZmjMA00C~Y?f?J*Z@BIN00L)YitYfu?f?J*I>hb(0RavMI?nEZ00DH=?f?J*Zrttw00Cv00Cu2?*IS+ZA|X~00CiA?*IV+j0FGzcV6!R00D1e?*IS+a%k@W0RWT*00Cum?*IS+dU)>u00C)!?*IS+bA;~z00Cu+?*IS+a**!;00C^4?*IS-a%^tz0G#gt0RW8!00C{R?*IS+VX*H200CvT?*IS+V!ZDF0RWB#00DEz?*IS+bIk7m00D2(?*IS+a@g+x0RWE$00Cs=?*IS+Zs_j-00Cj{?*IV+kOcq%W%};`00Dab?*IS+X$0^900DCf@Bjb-Wf1TH00D9q@Bjb-cO38l0RWK&00Ctv@Bjb-dMxk&00C(-@Bjb-b2#t-00Ct_@Bjb-azyX|0RWN(00CuC@Bjb-dQ|WL00C)Q@Bjb-b71fQ00CuY@Bjb-a%}Jb00Cuk@Bjb-b9nFo0RWQ)00Cu$@Bjb-dWi4<00C)^@Bjb-bCmD^00Cv1@Bjb-a-i@400DQV@Bjb-bFA@c;k;bVTt000DDK@c;k;I#BTd0Rfi&Iu@Z^MC*WWq$Jj00Co$^8f$=X^is#00DNA^8f$=Wtj5-00Cs4^8f$=a-{PB00CvH^8f$=WU%u900C~c^8f$=WxVqM0RYnp00Ak;^8f(>(g`Tc^MC*WWzzEi00Da1^8f$=Y2fn!00DF6^8f$=a_sW}00Cw4^8f$=X87{}00CzH^8f$=bp-SP00CkO^Z)<>Wf1fL00C_l^Z)<>VI1@T00D9$^Z)?>)d>IrDK7K?0RhwrC^Gbb00Ct<^Z)<>Y(Vq?00Ch}^Z)<>V@&h_00DDS^Z)<>bXfEN00C}Z^Z)<>Wn}aK00DGr^Z)<>ZgBJf0RZC(00Aj{^Z)??;t42#^nd^Xa)$H(00D1~^Z)<>bCmP|00DBE^Z)<>b)fVB00CpB^Z)<>Wvui700DHe^Z)<>VYu`F00Cvb^Z)?>Z`||%00DF2^Z)<>a_IB`0s!d==LrA-DfILJ0s-g=<_ReJ^nd^XWB~O500D9e^#A|?VG#8I00D0n^#A|?VjT4V00D3!^#A|?X(;so00eJxb!>L@0L1hF?(_gI^#B0?*$DsvDMs}G0Rh+vC`$E!00CuC^#A|?ZCLdH00C)U^#B3@-3i+X00Aj#^#B3^+zHwVC~)j?k>DXR4V0Rid>D6aK@00DEf^#A|?a=i5b00Cvf^#A|?X~^{e00Cys^#A|?Y1H)q00MPnr1b#W^#A|?Z{YO+0RZ0#00AlR^#B0@-U%r5^?(2YZu<2A00D0T_5c6@X$bZJ00DFk_5c6@X%zMV00DCv_5c6@Zy@#n00D3&_5c6@Wi0jp00DC{_5c6@bvX6_00D14_5c6@ZAA6}00DGL_5c9@?+E|_DOUCX0Rip_C|dS_00CuS_5c6@bZGVf00Cic_5c6@baeIr00DD)_5c6@WPtVn00Ci!_5c6@aE$f<00Cu^_5c6@ZJ71|00L!UQ1$?x_5c6~aC35IV{~n2K=J@$^8mv004VeTH1z;v^#JPi0HpQ+00BC#_5c9^@(DW7_J9BZch>d*00D2__5c6@WaRb$00D05_5c6@Y4G*{00DRQ_5c6@W&HL400DCX_W%F^VF>pC0RV;z00DFq_W%F^ZW#9f00C(p_W%F^ZzT5s00D3+_W%F^Wia;u00Cq+_W%F^Z#?$^00Cn{_W%F^I!N~b0Re{#I!^b100DGV_W%F^Zd~^O00CuU_W%F^c4+qi00Cug_W%F^baeLs00DS<_W%F^Wq|hp00(Pra%W>=bOP%DIPCzQ?EqNs0DSQP4)*|t_W%F^I*j)K0RgBAI;!`800D2X_W%I^4gvrHWWM(R00C^m_W%F^Wytpc00C*v_W%I^4*~!IW!m=u00DL0_W%F^Y~=R<00Cj@_W%F_W_Hx~0Pyz!00BDo_W%I_5CS>?_<#TbbO!hU00DIl_y7O_a1{6e00DFw_y7O_bs+cv00D0%_y7O_IxP4A00BBO_<#Tbaya+^00D14_y7O_bVT?700Ci2_y7O_a!~jH00CuI_y7O_bX@oV00C)Y_y7O_I%xO+00BB~_<#TbcXapw00Cus_y7O_X@K|u00DM}_y7O_bd2}_00DE7_y7O_ZkYH000D2F_y7R_TLS@DYW?j0s)x?n*}Jk`G5ccbinxl00C*r`2YX`VbJ*i00DB=`2YX`blmv>0RW~200AlJ`2Ya|r3G^+;`spV`G5ccWb*j{00C_N`2YX`Wd!;F00C(V`Tzm|qy?Y_00Ai$`Tzm}qXnM@C>;8L00Cqo`Tzg{Y%KZ!00Ct(`Tzg{X*l`-00Cw``Tzg{Xhiw|00DGL`Tzg{X;AtA0RX5400Ajn`Tzj|rv)fr`hWldZf5!b00C)k`Tzg{XLR}i00Cus`Tzj{ss#W6DTew00RgE6D2n=k00Cu?`Tzg{dYJkE00C*9`Tzm|tOc$G00Akg`Tzj{y9fXQWVZSM00C^e`Tzg{Wx)CX00C*n`Tzj{ya)gRWzzZp00DK@`Tzg{Y~1<)00Cj*`Tzg|W_HZ_0Oz`+xuecWnCr00Cus`v3p|X@L6x0RXTC00AkC`v3s}uLUTO`+xueWS08?00C~E`v3q4V_{}@Vsmz7r1$`?`2Z0509N_{fcgNW`T&Oe0Hpf>00BCx`v3s}u?0HJ`+xuebkh3(00C**`v3p|Vc`1!00DC5`v3p|bnN>800DFI`v3p|Wcd3400C_N`v3p|Wd!^H00C(V`~U#}5dr`Kc^3Qt00Cth`~U#}5&{4LWhVRp00DI>`~Uy}Y%u%)00Ch(`~Uy~Yjz;~06hEv00BBe`~U#~69PI+{D1%fc~blU00DAZ`~Uy}bYT1d00C}h`~Uy}Wo-Na00BC3`~Uy}I(Ynm00DA-`~Uy}Z-o2+00DH0`~Uy}VUYX)00DBA`~Uy}Wt{u~00DHO`~Uy}X{h`F00BC#`~U&~VGd&s00Akw`~U(1U=CsqIw-XKfWZ8K00DQ#`~Uy}Wz_rt0RUeP00AlB`~U#~UJfYa{D1%fW$OF@00D6F`~Uy}dHDPQ0Rcr0bpHGR00CtL{Qv*~bqxIg00C?g{Qv+0X<^#@02uuM0RRUB00DU@{Qv*~Wi0&w0RRXC00Ct<{Qv*~bv*q500C@5{Qv*~VMzS|00L`vGW`Hf{Qv*~I#m4t0RagEI$r&N00DVq{Qv*~a%}wo00DGz{Qv*~Zg~9w00Cuw{Qv*~I)wcI00BCR{eS=ga*+K100D27{Qv*~be#PF00Cj5{Qv*~a;W_P00CvL{Qv*~bhP~d00C*b{Qv*~I>7w^00BD2{eS=gcg+0&00Cvv{Qv*~Y1sV$00DO1{Qv*~bmaX200DFA{Qv*~Zt(p800D3I{Qv;~KMnu^XafEK00DFc{r~_0XAJ%T00C|i{r~_0Wf=Yd0RTV_00C|!{r~_0X(;{x00Cz%{r~_0Wi0RT}B00AlJ{r~|1P!1^U{(t}hW%B+200DOT{r~_0Zvg)Q00U%WZNB~h;{E^z{{R31bPWFh00D9u{{R31Wg!0m00DC*{{R31ZY=)*0RU4D00AjD{{R62QVu9Q|9}7iWkUY|00DDK{{R31VNm}700DAV{{R32X=O7109^k700DGj{{R32bY+PC0BrvN0RUYN00Aj{{{R62Tn;FJ|9}7iWrqI%00D50{{R31d6fSE0Rcn~bejJF00DWR{{R31WvKrE0RTo000DHg{{R31Y`Fgb00DKr{{R31VZ{Fc00Cyo{{R31Wzhcs0RTr100DX2{{R31aNz#{00D32{{R61NDcr2W%B<300DOP{{R31Z~XrN00U%WZPxz)?Ee4)00962bO-00962azp?D0RT%500Ajb00993N)9Mg0D%AjbXoub00C)Y00962VQ2sW00DAt00962baVg#00DV=00962a)1B<00Ci!00962Zj1l{00D2300962X_x>300DHK00962W268900C*L00992RSp0FDYgIs0RdDFD7pZF00DHs00962Y{&os00DK*00962VblNt00Cy&00962W#9k-0RUGH00AlN00993Rt_le0D%AjdG-JS00D6R00962Zv+7W0RUMJ00Aiw0RaI4SPm!@0f7JkWf}ni00DL)0RaF3Zzur)00U%WZRP+03IPEw0RaF3bTk1000DAB0RaF3Wk>-500DDO0RaF3Zd3sQ0RUSL00Ajr0RaI4S`H{=0f7JkWoiKd00DDy0RaF3VR!)n00DA-0RaF4X=Pdg0fYeo00DD~0RaF3VUz&@01S3xY+`0%b8Bg3WN04!0Q~&`9{vD2{s2(^0C@fYa{mCX{{Suk0ZIS?umAy?0RaF3I-mgo0RdzVI?@4w00DH^0RaF3Y2X0?00Cj<0RaF3a_j*C00DIJ0RaF3dH4YV00DCT0RaF3VFUsJ00C|a0s#O4Zx8|j00C(h0s#O4bQ}T!00Cnn0s#O4X($2#0RS=s00C$;0s#O4bT|S500Cz{0s#O4ZbSkB00Cu60s#R4GXnqtW>x|L00D1W0s#O4b6^4i00DDm0s#O4Wo!Zg00DAx0s#O4WOxDr0RTAz00Ak40s#R5I0Gn%0)YSlbdCZ600C*10s#O4VVnX100DBM0s#O4bf^LW00DWf0s#O4VYC7P00DBk0s#O5WO9B20l)$Q0RS`u00DH+0s#O4Y}5h)00DK{0s#O4Vc-G*00Cy^0s#O4W$Xe00RS}v00DXU0s#O4aQp%R00D0T0|5a5HUj_wWex)Y00DLq0|5X5Zx{ms00U%WZSn#E2m=8g0|5X5bR+`-00D9`0|5X5WjF%?00DD80|5X5ZbSnC0RT4x00CuC0|5X5b5sKX00CiI0|5a5O#=V{DP{u!0Rc<{C~5(DG~$$0RcV(C>8{P00Ctj1OWg6b|eG=00D0*1OWg8WMggU0|5*K0Wbss00DG11OWg6azq3H00Cu61OWg6b5H~U00C}R1OWj6K?48*DPjZx0Rcb*C}sqK00Cue1OWg6b94j&00Cio1OWg6a)1N@00L=cTm%7z1OWg6bc_T600Cu|1OWj6LjwQ-DWU`c0Rch-D5eB~00DHY1OWg6Y_tRc00DKn1OWg6VZa0d00Cyk1OWg6Wy}Nt0RTk<00Al31OWj7L<1G0RTq>00Ald1OWj7Mgu4S1%UtoWd;QS00DLm1pxp7ZxjUq00U%WZPEk*_5=YM1pxp7bRY!*00D9?1pxp7Wi$l=00DD41pxp7Za@VA0RTw@00AjX1pxs8NCPNP1%UtoWmW|N00DDe1pxp7VPpjX00DAp1pxs7O9KD_DRu<`0Rc(_D0&5f00Cuy1pxp7dWZ!900C)^1pxp7bCd-E00Cv11pxp9X=QRo1p#mc0iXo|00DER1pxp7VYCGS0sv0~Q3C)0DZm8*0s&3~Py;B&1%UtocgzI=00Cvz1pxp7Y1{{C~^jY00DD&1_1#8`2zp}DTW3C0Ri{}D2fJw00C%_1_1y8beIMK00C*91_1#8`vU+0DXInm0Rj30D6R&900DEf1_1y8VY~(b0Ra6200Ak;1_1#9`~xV=27v$pbkYU^00Cv%1_1#8{{sL4Ddq+N0RjF4DC!1*00BMl1_1y8J@^Iz00DCT1_1y8Zv+Pc00DFg2LS*9VGsua00D9q2LS*9WgG_q00D3!2LS;90R#X6DJ};A0RaF6C^83u00Ct<2LS*9bU+6I00Ch}2LS*9WlRSF00DAR2LS;90|Wp8DP9Kw0RaL8C}IbJ00DVu2LS*9Z*T_z00DA#2LS*9bbJQ^00DD?2LS*9Wrzm>00?ercW7sCV`OLs0e}Vpqy_=P1_9s(0VoFnSO)=)2LS*9I+OX-00Aky2LS^CNC-p-MhGax2Y~qf00C|e2mt^AX%q+n00Chd2mt^AbRY-;00C|$2mt^AZ!8D_0RT}500AjD2mt{BPzWeI2!Q|rbV3LL0RU4700Ajb2mt{BQV1wi2!Q|rWm*UU00DYp2mt^AX=n%m0RUA900Aj<2mt{BR0t?|2!Q|rZhi;>00C)+2mt^AXN(8|00Cu^2mt{AR|o(BDV_)c0RdJBD53~~00CsE2mt^AZm}5D1Oz&Awg-U-2>}2BWey1e00D3s2>}2Bc_0Y^0RUtO00D9=2>}2BWiSZ=00DG12>}2Bb36$F0RVdl00AjT2>}5CdI%^?34s6sXHp3P00C}V2>}2BX}2BbZiL$00DDy2>}2CWp6?W0eA@k0RUwP00DA{2>}2BWsC^{00DH82>}2BbeIVN0RVXj00Aka2>}5CcnBz{34s6sWv&SU00DZo2>}2CWoe!X0lWzT0sv}2BVdx0~00DCD2>}2Bbo2=U00C|K2>}5Be+U2pDFzAw0RespC<+RJ00MPn015#R3IPBCZWsyy0RU?V00Ai|3IPEDY6vJS3V{FtbTSG700C|~3IPBCVL%E200C)63IPBCa!d*V00CiA3IPBCc327l00CrP3IPECa|i$dDQXG<0ReIdC~gXY00LxmWC{Uv3IPHDZwPG&00Ak63IPHEZU}4$D2xh$00DH83IPBCZk!4M00Cj53IPBCX{ZVT00DBY3IPBCVYCVX00DNo3IPBCXut{q00DHy3IPBCY0L@%0RV9b00Al33IPEDa0n>e3V{FtbK(jC00D053IPBCY48dG00Ck43IPBCbo>ed00C|S3jqKDZwLzk0RVLf00Ai!3jqNEbO3jqNDcL)FhDM||g0ReUhC{7E300C}P3jqKDX3jqKDX^aa200DB63jqKDbeIbP00DEJ3jqKDZKMkU00D2R3jqKDa^DV7WY0Rfo^D4Gm`00DHM3;_TEX{ZbV00CjH3;_TEas{I00U`rZcGdTkPHFp3;_TEI`9ku0Rf)~I{plS00DFa4FLcFX$%bk00ChV4FLcFau^K(00DF!4FLcFWh4y&00C?&4FLcFVlWK>00Ch(4FLcFY&;DC00C@54FLcFbw~{X0RW&000Ajf4FLfGp9v^f4S@gwa$XGq0RW;200Aj%4FLfHp$TOuW(@&w4S@gwWOfY!00C@*4FLcFX^0I000DK54FLfFqzM24DVhxd0Rf{4D4q?000DBO4FLcFZ>$Xg00DHe4FLcFW4H|g00DKr4FLcFa>NY*00DH$4FLcFbI=U|00C~+4FLcFZ`=(500Cp-4FLcFbm$EM00C_74FLcFb@UAZ00Ck84FLcFW&jQW00CtN4gmoGrU?K6DH09=0Rg26C>9QZ00D9w4gmlGZzK)@00DF=4gmlGV=xW@00DJ24gmlGay$+J00DGD4gmlGb4U&W00C}J4gmlGZ&VHe00CoK4gmlGd0-9!00D4j4gmlGZ)^?$0RX5800Aj@4gmoHrwJ&04uJpxa)J&400D1`4gmlGbdU}K00Co`4gmlGb({_X00DBM4gmlGbf^vi00DEZ4gmlGZnO>o00D2h4gmlGW55mp00Cvj4gmlGcFYa|00D2(4gmoGstEuADc%kN0RgEADB=!*00DF84gmlGa_|lT00D3I4gmlGbo>qh00CnH4*>uHbqEgu00D9i4*>uHbQBK(00DCv4*>uHZXgc<00D0%4*>uHV=NB=00Cn%4*>uHX*dr700DD84*>uHVMGrB00d-XZDI@#0dfuj*bV_o4*>uHXiyIU00DGj4*>uHX=o1t00LrnlnnuH4*>uHI&=>K0RgKCI(`p<00DA@4*>uHWsDC200Cr@4*>uHY?u!L00C*94*>uHb)*jg0RTJ<00DBa4*>xHQw#tBDY_2<0RmDCZz!}60lp7`00DHw4*>uHW6%!)00DK@4*>uHa@-FA00DI34*>xHJq!Q=a_$cS0RUAD00AlZ4*>xJR19w@@(%(04}kyybOI0o00CnT5CH%IbrcW*00D9u5CH%IbRZA`00DC*5CH%IZY&T100D0@5CH%IV>l2200DG95CH%IY(x+N00DJM5CH%IVNehO00MJn=nnx_5CH%IWn2&e0RTP>00DAr5CH)IR}26FDRvM60RmPGZzymO0eTRD00DG>5CH%IV~h|100DK95CH%Ia+nYS00DHK5CH%IbEFUf00C~Q5CH%IZ?F&n00CpR5CH%IdAtw-0RTY^00Ak;5CH)JKny6%5P<*zbkYz300C**5CH%IVc-w}00DC55CH%IbnFlT00Cw45CH%IZ1@lX00CnD5CH%IX#^1g00DFg5di=JV-OJm00DIt5di=JavTu>00DF&5di=Jb0`r300MAs!Vm#25di=JZ!{4B0RTS?00DAD5di@JSquOHDNYdq0RmVIZzxC+0a6ix00DGZ5di=JV`LEl00DJs5di=Ja&Qp=00DG%5di=Jb9@m200C}-5di=JZ-@~A00Co;5di=JWt0&C00DNI5di=JZ=ewY0RTe`00Aki5di@KLJTOd5rF^!a<&lx00D2l5di=Jbi@$>00Cpl5di=Jb5`h2#axM}900D0{5&-}KbUYFP00Cn{5&-}Kbx0Bc00DAN5&-}KbW{=n00DDa5&-}KZeS7t00D1i5&-}KV{8%u00DV&5&-}KaCi~{00D1)5&;1KM+^V~DT)#S0Rct~D2@_=00DB85&-}KZ=4bV00DHO5&-}KW2h1V00DKb5&-}Ka69E7LV~7(000DK569E7La+DJR00DHG69E7LbD$Fe00C~M69E7LZ>$pm00CpN69E7Lbhr}%00C^i69E7Lb;J_^00Cjj69E7LX3!G>00Cvz69EALPYeJ7DdH0W0Rc`7DCQG^00DID69E7LWAqaN00DLS69E7LasU(o00DFc6afGMa|{##00C|i6afGMZx|E-00Cnj6afGMc_b7800D3+6afGMZ!i=A0RT}900AjH6afJNPz)$Q6oCK%bVd{b00Co86afGMbyO4q00DAZ6afGMbYK(#00DDm6afGMZfq0*00D1u6afGMV|Ww+00Cuw6afGMc7zlG00D1`6afGOWMggI69G090gw~{00DEB6afGMVWboR0RUSJ00Akm6afJNS_~+(6oCK%WV#dq00Cvf6afGMaL5z^00DW<6afGUVq{}&cXMHAbgB;lW)J~B5do$V0SXfVE)xN869K9e0n`)$00BDM6afJNTnst@6@dT&bOsdx00C(Z6#)PNVH6bs00D9u6#)PNbRZQ000Ctt6#)PNY%CQ400Ck$6#)PNX*d-D00DG96#)PNV?-4J00DJM6#)PNa!?fk00DGX6#)PNb6gbx0RRUI00Ajz6#)SO1_~%_6@dT&WpWh(00DA(6#)PNVSp6@00D4@6#)POZf#-}0gM#^00D236#)SNxd{LPbfOgj00CpB6#)PNWvmqe00C^W6#)PNX1Emr00Cvb6#)SN;R*l&a>^9}00Cvr6#)PNbkr3A00DE_6#)PNW#AP70RZ9(00DCB6#)PNW$+aN00DIN6#)PNbo>~p7J&c(WfB$v00DX$76AYPWoZHy0U#Cu0RZC)00D9^76AYOWi%E600DA376AYOVL%oE00Cu276AbO?+O3`DN+^z0Rip`C{`AM00DDc76AYOZe$h#00C)g76AYOVQ>}!00DG%76AYOZhRI200L}pOcnux76AePTb6#*s|0f-g>(iQ;}7XeZi0elw$q!$6g7XbhPI>;9R0Rj99I_?*N00DIL7XbhPY5W%f00ChF7y$qQatIg!00DFk7y$qQYZMp(00DCv7y$qQVIUX*0RWf`00Aj17y$wSlMI&(C@>g-00D0{7y$qQbU+vZ00C}B7y$tQnhXE|DN+~#0s)i^nG7ga7=Zu*ZCn@u00D1i7y$qQa%>m@0RWZ^00Aj@7y$tRl?*6+7=Zu*bb=TG00C)=7y$qQVUQRB00DBA7y$qQbetFg00C~I7y$qQZ>Sgn00C*P7y$qQbF>%%00DBk7y$qQWxyB#00DN!7y$qQZp;_~00D2(7y$qQW7rr000C#-7y$qQZsZsN00C+07y$qQa_|@d00DIN7y$qSX=Zaw7y)t^0sI&N00BAz836$Sn+!S-8G!%+bQT!_00C(p836zRVI&y=00D9;836zRbTAnK00C|`836zRZ#)?R00C)2836zRb4VEh00DAN836zRWmFjf00DMd836zRZeSS!00D1i836zRV{91#00C!m836zRZg?3100C)!836zRa)cQH00DH0836zaW@KS>Wo~0~ZF3O(04@RnL}`m0Zt78oD~7Y6#*s~0gxF100BCd836$S2nssD8G!%+ZpIk_00D2#836zRY1A1300DH`836zRW8fJ900Cv@836zRZ0s2U00Cz5836zRW%wBZ0|2lHvxP`H2`*t0FcN4R?h&$9036UNCW@@bdnqa00DBA9033UZ=4(f00D5K9033Ucc>fz00CvL9033UX|x;x0RXuR00Cvd9033UW5gT*00C*r9033UcF-IF00Cvz9033UWZWD900DC19033UW#}9M00Cs~9033UZuA@h00CwC9033UasV9x0sy-Uy$b*VDGVI}0s*=UybCB29f1G=au^)}00Ctp9RUCVawr`E00Ct#9RUCVWHcQC00C|~9RUCVWk4MP00DAF9RUCVWlS9b00DDS9RUCVVOSjj0RX=X00Ajv9RUFWz6&U59f1G=WNsY+00Cik9RUCVZ+smA00C@*9RUCVaEKiN0RX`Z00AkK9RUFWzzZmt9f1G=Wu6@Y00DHS9RUCVbgUf#00CvP9RUCVY`7f(00CjX9RUCVaKs$}00DH$9RUFV#R~udDb^hU0RhAdDB2x?00Cv-9RUCVdgvVi00L!c&>aEp9RUFV!wUcbDgGS+0Rh4bC;}dV00CtP9svLWdJrA~00C(h9svOW#|r=fDIy*L0RhGfC?+0(00D9=9svLWWi%cE00Cq=9svLXb8Z|S0YDxB00Cu29svOW$qN7hDOMf<0RhMhC|VwY00DDg9svLWaA+O@0RYPj00Aj<9svOX$_prX9)SP>Wquw300DZ29svLWX^b8L0RYVl00AkO9svOX%nK--9)SP>a-tpq00CvH9svLWWUw9q00MJvk{$uJ9svLWWxO5%00DBw9svLWZpX>d00Ai?AOQja=m6#bC@3I-00DC@AOQdYc{m^e00Ct_AOQj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�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V*=J=0uy8c7i0oVWCBlQ0)=D(h-3oBWCF@$0s>_M24w<9WdcfN0+eL}m}LUoWdh)30uE*Z5oQ8VW&%`Z0-0t4on`{fW&+S=0tjaU3}*s2X97EC0&r&nbY}vsX9BTj0_SG}>t_NeXaZYk0*7b0zz&AY;FRUZUVq=0_$!97;geaZvt^|0-|pM&Tj(zZvrfE0$y+eif{tTa01S70tRsc3ULBMaRNti0)BA0{(FV0&)UFaso$k0)uh_hjIeEast3|0`+nN`Emj_a{@YZ0(^40ws3>S$6`7cLKO~0`7MLG;)e0@!&1+<5{!dICRs0-1UOoq7W5dIIix0v~$66#>w5wkd;&&%0&#o-o_qq+d;$f10yljEWPJkBeFD{e0v&z=A$|g5egbEH0;zrit$qUKegf%!0xEw3E`I`Se*$oS000)~kKiirZxi2~D!0vCz`8;Sy7iUMPb0;q}ttcn8kiURnG0z!)dMvDT9ivo^|0@;fK-HQSti~=Q$0&$E2b&LYbi~`S$0wIk8C5-|)jRL%l0>F&|^Nj)+jslmC0-KHk%#H#lj{+-?0&z5j{>TX0@;rO+>ZhnkOCZ#0x^&RNEmo{c&VwWsi~={si~={si~-`si~={si~={si~={sYpnesi~={si>)_si{bqnCR$O=;-L^=ve6Jsi|10si~={sYsYe7^$f^n1Gmg=;*1asi~={si~={si~={SeOu)h{!0Isi~=`NSJ`==;-L^=vb+#si~=`si~={si~={si~={si~={si~={NQj7-h)`si>)`si>)`si{avD43Y3si~+)si~={si~={NU5l)si~={si~={si~={sHv%`si~<*80hHe=;-L^=vWY#Sm@~Jsi~={NLYxN=va7oczAfJsHv%`si~={si~={si~={si~={si~-`si~={si~={si~<*=;-L^=;-L^SeS?yh^eTlsi~={si~={sHv%`si~={si~<*n3$NDm=Kt$sW^xjn3$O8=vb+!si~={si~={si>)`si>)_Na$Fpsi~={si~={sYqCenAq6Z*vP4ERsi~={si~={si~={si~={si~={si~={si~={si~={si~={si~={si~<*nCR%}=ve4jsi~={si~={NSLXpsi~={SgEP0si~={si~={si~={sYt1*IOynDsi`>V=;-L^=vbKO=;-L^=;&DJ=vY{(si~={si~={si~={si~-`si~={si~={si~={sHv$)n5n5an3#BYczAetsi~={si~={si~={si~={si~={si~={si{aP7&w@in3$=lsi{b*si~={si~={si~={si~+)si~={si~={NDvU1nAq6Z$mr)_si>)_si;Vpsi~={si~={si~={si~={Na(4lsi~={si~={si~={si~={si~={si~={si>)_si>)_si>)_si~=`si;Vp=vb+#si~=`si>)_si~={si{bqScvH8si|0)czAetczAetcz7tOsW_>rC>ZFesHv$~=;*1bSeTd?si>)`si~={si~={si~={si~={si~=`NSK)D=;&Cfsi~={si~={sYvKpn3$NUsHv%`si~={si~={si~<*n1~RFNU5nX=vWx&=vbJksi~={si~={si~={si~={si~={si~={si~-`si~-`si~+)80hG!si~=0m{^#psi~-`si~={si~={si~={si~={sHvz(si~=`si>)_NU5nf=;-L^=ve5fsi~={si~={si~={si~={si~=0=&7lxsi~=0si`rIGC827>Jmdsi>)`si{cl=&7lxsi~={si~=0*x1)`si~=`si>)`si{bKc&VtVsi~={si~={sYr;J=;&COn5n3#si~={si~={si~<*si`=rsHv%`si~<*ScoX-=;-KJnCMuT7?`Q4si~=`si>)`si{bq5UHs+n3x!;si~={si~={si~={sYt1*si~={si~={si~={si~=`si~={NU5o*si~={si~={si~={si~={si~={si~={si~-`si~-`si~+)=;&Cfsi~={si~={si~={si~={si~={si~={si~={si~={si~={si~={si~={sYt1*si~={si~={si~={si~={NSGL@si~={si~={s7RQY=ve6J=vX+|*vQD(*x1)_si~={si~=`Na*P3=;-L^SgEP0si~={si~={si~={si~={si~={si~={sHv!_sHv!_sHvz(c)_si>)_si>)_Na*NTsi~={si>)`si~={si~={si~={NZ8oe$ar|Esi~B5jScsUIh^eTlsHv$)h!{9{c&VwWsi~<*7?_Busi~<*SgEP0s7RQpsjaQ8t*NQ0s7RRT=vc_e$jI2p$k^D}$ar|Esi~={si~={si~={sW_OJsi~={IGCxasi~={si~={si~={si~={si{cl=;-L^=vbH-si~={si~={si~={si~={si~={si~={si~={si>)`si>)`si;V)sHv%`si~-`si~-`sHv%`sHv%`sHv%`si~={sHv%`sHv%`si~={si~={si~={si~={si~={si~={si~={si~={si~={si~<*t*xo3si>)`si~={si~={NSK%y=vbJksi~={si~<*n3(A3=vbJTh!}{esHv%`si~={si~<*n3$M|nCR%}=;&BDm{_T)C>WTjsi~+)nCMtosi~=`si>)`si~={si~={si~={si~=`si~={si~={si~={si~={si;VZn5n6$si~={sHv%`si~-`s7R@)DCk(Jsi~={si~-`sHv%`sYsYO=&7lxsi~={si~={si~={si~={si~={si~-`si~<*=;-LFsHv%~t*NQ0si~={si~={si~-`si~={si~={si~={si~={si~={si~={si~={si~={si~={si~={si~={si~={sYsZqsHv#2xv;spxw*Nyxw*NyIGC82=;&Bj=;-KJ=ve4jD42+dsi>)`si~={si~={si{b*sYt1*si~=`si;V)si~={sYvKpn3$=lNSNs8=vbKO=vbJDICyw?si>)`si~={si~={si~={si~={si~=`NEn!@si~={si~-`si~={sYt1*I2g#Osi~-`si~={si~={si~)`si{a)_si>)`si{clsi>)`si~={si~={si~={si~={si~={si~={si~=`si~=`si~=`si~=`Na*P3ScvFYh?tm|FzBhNt*xo4si{a)`si~={si~={si{bam`LbYh^eWmsi~={si~={si~={si~={si~={si~+)si>)_NSLXqsi~={si~=`si>)`si~={si~={si>)`si~=`si~={si~={si{bai0J6(SgEP0si~={si~={si~={si~<*IG9+NnAq6Z*x1)`si~={si~={si~={si;VJczAetczAetczCI)si~={si~={si~={si~={si~={si~={NQfvH=;-L^=vbJTNLZMusW|B9=ve6JSQwb-=;-L^=;&C8xVX5uxVX5mvAMCivAMCivAMCivAMCivAMCivAMCivAHm*sW=#^sW_>rsi~=`si>)`NG=8dIyyvUaCB%>bY*U1X>3z;VRU5xV{Bn_b7OU4Z*yNUUom5Ea%EpJUomHFUo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'); diff --git a/docs-preview/pr-1032/ser_2serializer_8hpp.html b/docs-preview/pr-1032/ser_2serializer_8hpp.html new file mode 100644 index 000000000..c894ca8f7 --- /dev/null +++ b/docs-preview/pr-1032/ser_2serializer_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/data/ser/serializer.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/settings_8hpp.html b/docs-preview/pr-1032/settings_8hpp.html new file mode 100644 index 000000000..0baace5fe --- /dev/null +++ b/docs-preview/pr-1032/settings_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/settings/settings.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/solver_8hpp.html b/docs-preview/pr-1032/solver_8hpp.html new file mode 100644 index 000000000..942b80fd0 --- /dev/null +++ b/docs-preview/pr-1032/solver_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/physics/solver/solver.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/sparse__relation_2registry_8hpp.html b/docs-preview/pr-1032/sparse__relation_2registry_8hpp.html new file mode 100644 index 000000000..334f95263 --- /dev/null +++ b/docs-preview/pr-1032/sparse__relation_2registry_8hpp.html @@ -0,0 +1,138 @@ + + + + + core/ecs/table/sparse_relation/registry.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/ecs/table/sparse_relation/registry.hpp file +

+

Class cubos::core::ecs::SparseRelationTableRegistry.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::ecs
+
ECS module.
+
+
+
+

Classes

+
+
+ class cubos::core::ecs::SparseRelationTableRegistry +
+
Stores all of the sparse relation tables.
+
+ class cubos::core::ecs::SparseRelationTableRegistry::TypeIndex +
+
Stores the ids of tables of a given type.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/sparse__relation_2table_8hpp.html b/docs-preview/pr-1032/sparse__relation_2table_8hpp.html new file mode 100644 index 000000000..566e33e96 --- /dev/null +++ b/docs-preview/pr-1032/sparse__relation_2table_8hpp.html @@ -0,0 +1,142 @@ + + + + + core/ecs/table/sparse_relation/table.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/ecs/table/sparse_relation/table.hpp file +

+

Class cubos::core::ecs::SparseRelationTable.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::ecs
+
ECS module.
+
+
+
+

Classes

+
+
+ class cubos::core::ecs::SparseRelationTable +
+
A table which stores relations. Allows for quick insertion, deletion and iteration.
+
+ struct cubos::core::ecs::SparseRelationTable::Iterator::Output +
+
Output structure for the iterator.
+
+ struct cubos::core::ecs::SparseRelationTable::View::Iterator::Output +
+
Output structure for the iterator.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/spot__light_8hpp.html b/docs-preview/pr-1032/spot__light_8hpp.html new file mode 100644 index 000000000..37aff38ca --- /dev/null +++ b/docs-preview/pr-1032/spot__light_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/renderer/spot_light.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/standard__archive_8hpp.html b/docs-preview/pr-1032/standard__archive_8hpp.html new file mode 100644 index 000000000..4aa8ff531 --- /dev/null +++ b/docs-preview/pr-1032/standard__archive_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/data/fs/standard_archive.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/standard__stream_8hpp.html b/docs-preview/pr-1032/standard__stream_8hpp.html new file mode 100644 index 000000000..4e82d1535 --- /dev/null +++ b/docs-preview/pr-1032/standard__stream_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/memory/standard_stream.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/stream_8hpp.html b/docs-preview/pr-1032/stream_8hpp.html new file mode 100644 index 000000000..fa855ad96 --- /dev/null +++ b/docs-preview/pr-1032/stream_8hpp.html @@ -0,0 +1,146 @@ + + + + + core/memory/stream.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/memory/stream.hpp file +

+

Class cubos::core::memory::Stream.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::memory
+
Memory module.
+
+
+
+

Classes

+
+
+ class cubos::core::memory::Stream +
+
Interface class for memory streams. Abstracts away sources or destinations of data.
+
+
+
+

Enums

+
+
+ enum class SeekOrigin { Begin, + Current, + End } +
+
Stream seek origin.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/string_8hpp.html b/docs-preview/pr-1032/string_8hpp.html new file mode 100644 index 000000000..8c95f3f7b --- /dev/null +++ b/docs-preview/pr-1032/string_8hpp.html @@ -0,0 +1,102 @@ + + + + + core/reflection/external/string.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/string__conversion_8hpp.html b/docs-preview/pr-1032/string__conversion_8hpp.html new file mode 100644 index 000000000..9503c189d --- /dev/null +++ b/docs-preview/pr-1032/string__conversion_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/reflection/traits/string_conversion.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/string__view_8hpp.html b/docs-preview/pr-1032/string__view_8hpp.html new file mode 100644 index 000000000..90821371e --- /dev/null +++ b/docs-preview/pr-1032/string__view_8hpp.html @@ -0,0 +1,102 @@ + + + + + core/reflection/external/string_view.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/reflection/external/string_view.hpp file +

+

Reflection declaration for std::string_view.

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1Logger_1_1Entry.html b/docs-preview/pr-1032/structcubos_1_1core_1_1Logger_1_1Entry.html new file mode 100644 index 000000000..330956ded --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1Logger_1_1Entry.html @@ -0,0 +1,135 @@ + + + + + cubos::core::Logger::Entry struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1Logger_1_1Location.html b/docs-preview/pr-1032/structcubos_1_1core_1_1Logger_1_1Location.html new file mode 100644 index 000000000..63ce86abd --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1Logger_1_1Location.html @@ -0,0 +1,158 @@ + + + + + cubos::core::Logger::Location struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::Logger::Location struct + +

+

Identifies a location in the code.

+ +
+

Public functions

+
+
+ auto string() const -> std::string +
+
Returns a string representation for the location.
+
+
+
+

Public variables

+
+
+ std::string function +
+
Function name.
+
+ std::string file +
+
File name.
+
+ int line +
+
Line number.
+
+
+
+

Function documentation

+
+

+ std::string cubos::core::Logger::Location::string() const +

+

Returns a string representation for the location.

+ + + + + + + +
ReturnsString representation.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1Logger_1_1Timestamp.html b/docs-preview/pr-1032/structcubos_1_1core_1_1Logger_1_1Timestamp.html new file mode 100644 index 000000000..84a205550 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1Logger_1_1Timestamp.html @@ -0,0 +1,174 @@ + + + + + cubos::core::Logger::Timestamp struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::Logger::Timestamp struct + +

+

A timestamp used to identify when a logging message was written.

+ +
+

Public static functions

+
+
+ static auto now() -> Timestamp +
+
Returns a timestamp with the current time.
+
+
+
+

Public functions

+
+
+ auto string() const -> std::string +
+
Returns a string representation for the timestamp, containing hours, minutes, seconds and milliseconds.
+
+
+
+

Public variables

+
+
+ int64_t timestamp +
+
Milliseconds since the UNIX epoch.
+
+
+
+

Function documentation

+
+

+ static Timestamp cubos::core::Logger::Timestamp::now() +

+

Returns a timestamp with the current time.

+ + + + + + + +
ReturnsTimestamp.
+
+
+

+ std::string cubos::core::Logger::Timestamp::string() const +

+

Returns a string representation for the timestamp, containing hours, minutes, seconds and milliseconds.

+ + + + + + + +
ReturnsString representation.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1data_1_1EmbeddedArchive_1_1Data.html b/docs-preview/pr-1032/structcubos_1_1core_1_1data_1_1EmbeddedArchive_1_1Data.html new file mode 100644 index 000000000..cf8dd4a33 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1data_1_1EmbeddedArchive_1_1Data.html @@ -0,0 +1,137 @@ + + + + + cubos::core::data::EmbeddedArchive::Data struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1data_1_1EmbeddedArchive_1_1Data_1_1Entry.html b/docs-preview/pr-1032/structcubos_1_1core_1_1data_1_1EmbeddedArchive_1_1Data_1_1Entry.html new file mode 100644 index 000000000..193915ff5 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1data_1_1EmbeddedArchive_1_1Data_1_1Entry.html @@ -0,0 +1,147 @@ + + + + + cubos::core::data::EmbeddedArchive::Data::Entry struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::data::EmbeddedArchive::Data::Entry struct + +

+

Describes a file entry in the embedded data.

+ +
+

Public variables

+
+
+ const char* name +
+
Name of the file entry.
+
+ bool isDirectory +
+
Whether the entry is a directory.
+
+ std::size_t parent +
+
Index of the parent directory.
+
+ std::size_t sibling +
+
Index of the next sibling.
+
+ std::size_t child +
+
Index of the first child.
+
+ const void* data +
+
Data of the file entry.
+
+ std::size_t size +
+
Size of the data.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1ArchetypeId.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1ArchetypeId.html new file mode 100644 index 000000000..77b9b6832 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1ArchetypeId.html @@ -0,0 +1,173 @@ + + + + + cubos::core::ecs::ArchetypeId struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::ArchetypeId struct + +

+

Identifies an archetype.

+ +
+

Public static variables

+
+
+ static const ArchetypeId Empty +
+
Empty archetype identifier.
+
+ static const ArchetypeId Invalid +
+
Invalid archetype identifier.
+
+
+
+

Public functions

+
+
+ auto operator==(const ArchetypeId& other) const -> bool defaulted +
+
Compares two archetype identifiers for equality.
+
+
+
+

Public variables

+
+
+ std::size_t inner +
+
Archetype identifier.
+
+
+
+

Function documentation

+
+

+ bool cubos::core::ecs::ArchetypeId::operator==(const ArchetypeId& other) const defaulted +

+

Compares two archetype identifiers for equality.

+ + + + + + + + + + + + + + + + +
Parameters
otherOther archetype identifier.
ReturnsWhether the two archetype identifiers are equal.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1ArchetypeIdHash.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1ArchetypeIdHash.html new file mode 100644 index 000000000..e7103cdc1 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1ArchetypeIdHash.html @@ -0,0 +1,103 @@ + + + + + cubos::core::ecs::ArchetypeIdHash struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Arguments.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Arguments.html new file mode 100644 index 000000000..ce25aca11 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Arguments.html @@ -0,0 +1,124 @@ + + + + + cubos::core::ecs::Arguments struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1ColumnId.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1ColumnId.html new file mode 100644 index 000000000..108f602e8 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1ColumnId.html @@ -0,0 +1,271 @@ + + + + + cubos::core::ecs::ColumnId struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::ColumnId struct + +

+

Identifies a data column type.

+ +
+

Public static variables

+
+
+ static const ColumnId Invalid +
+
Invalid column type identifier.
+
+
+
+

Public static functions

+
+
+ static auto make(DataTypeId id) -> ColumnId +
+
Creates a column type identifier from a data type identifier.
+
+ static auto make(DataTypeId id, + uint32_t index) -> ColumnId +
+
Creates a column type identifier from a data type identifier and an index.
+
+
+
+

Public functions

+
+
+ auto dataType() const -> DataTypeId +
+
Returns the data type identifier of this column type.
+
+ auto index() const -> uint32_t +
+
Returns the index of this column type.
+
+ auto operator==(const ColumnId& other) const -> bool defaulted +
+
Compares two column type identifiers for equality.
+
+
+
+

Public variables

+
+
+ uint64_t inner +
+
Column type identifier.
+
+
+
+

Function documentation

+
+

+ static ColumnId cubos::core::ecs::ColumnId::make(DataTypeId id) +

+

Creates a column type identifier from a data type identifier.

+ + + + + + + + + + + + + + + + +
Parameters
idData type identifier.
ReturnsColumn type identifier.
+
+
+

+ static ColumnId cubos::core::ecs::ColumnId::make(DataTypeId id, + uint32_t index) +

+

Creates a column type identifier from a data type identifier and an index.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
idData type identifier.
indexIndex.
ReturnsColumn type identifier.
+
+
+

+ DataTypeId cubos::core::ecs::ColumnId::dataType() const +

+

Returns the data type identifier of this column type.

+ + + + + + + +
ReturnsData type identifier.
+
+
+

+ uint32_t cubos::core::ecs::ColumnId::index() const +

+

Returns the index of this column type.

+ + + + + + + +
ReturnsIndex.
+
+
+

+ bool cubos::core::ecs::ColumnId::operator==(const ColumnId& other) const defaulted +

+

Compares two column type identifiers for equality.

+ + + + + + + + + + + + + + + + +
Parameters
otherOther column type identifier.
ReturnsWhether the two column type identifiers are equal.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1DataTypeId.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1DataTypeId.html new file mode 100644 index 000000000..dd24e61a1 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1DataTypeId.html @@ -0,0 +1,169 @@ + + + + + cubos::core::ecs::DataTypeId struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::DataTypeId struct + +

+

Identifies a data type registered in the world.

+ +
+

Public static variables

+
+
+ static const DataTypeId Invalid +
+
Invalid data type identifier.
+
+
+
+

Public functions

+
+
+ auto operator==(const DataTypeId& other) const -> bool defaulted +
+
Compares two data type identifiers for equality.
+
+
+
+

Public variables

+
+
+ uint32_t inner +
+
Data type identifier.
+
+
+
+

Function documentation

+
+

+ bool cubos::core::ecs::DataTypeId::operator==(const DataTypeId& other) const defaulted +

+

Compares two data type identifiers for equality.

+ + + + + + + + + + + + + + + + +
Parameters
otherOther data type identifier.
ReturnsWhether the two data type identifiers are equal.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1DataTypeIdHash.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1DataTypeIdHash.html new file mode 100644 index 000000000..1bdb40c2a --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1DataTypeIdHash.html @@ -0,0 +1,103 @@ + + + + + cubos::core::ecs::DataTypeIdHash struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1DeltaTime.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1DeltaTime.html new file mode 100644 index 000000000..ec66f78c3 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1DeltaTime.html @@ -0,0 +1,128 @@ + + + + + cubos::core::ecs::DeltaTime struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::DeltaTime struct + +

+

Resource which stores the time since the last iteration of the main loop started.

+ +

This resource is added and updated by the Cubos class.

+
+

Public variables

+
+
+ float value +
+
Time in seconds.
+
+ float multiplier +
+
Multiplier which will be used when updating the value field.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Dispatcher_1_1Dependency.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Dispatcher_1_1Dependency.html new file mode 100644 index 000000000..d74b52e9e --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Dispatcher_1_1Dependency.html @@ -0,0 +1,103 @@ + + + + + cubos::core::ecs::Dispatcher::Dependency struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Dispatcher_1_1System.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Dispatcher_1_1System.html new file mode 100644 index 000000000..5d96c72b7 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Dispatcher_1_1System.html @@ -0,0 +1,103 @@ + + + + + cubos::core::ecs::Dispatcher::System struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Dispatcher_1_1SystemSettings.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Dispatcher_1_1SystemSettings.html new file mode 100644 index 000000000..2cac2a1f2 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Dispatcher_1_1SystemSettings.html @@ -0,0 +1,103 @@ + + + + + cubos::core::ecs::Dispatcher::SystemSettings struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Entity.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Entity.html new file mode 100644 index 000000000..9281bf647 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Entity.html @@ -0,0 +1,315 @@ + + + + + cubos::core::ecs::Entity struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::Entity struct + +

+

Identifies an entity.

+ +

When serializing/deserializing, if there's a data::old::SerializationMap<Entity, std::string, EntityHash> in the context, it will be used to (de)serialize strings representing the entities. Otherwise, the identifiers will be (de)serialized as objects with two fields: their index and their generation.

+
+

Public types

+
+
+ using Mask = std::bitset<CUBOS_CORE_ECS_MAX_COMPONENTS+1> +
+
Type used to store which components an entity has.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ Entity() +
+
Constructs a null entity.
+
+ Entity(uint32_t index, + uint32_t generation) +
+
Constructs an entity from an index and a generation.
+
+ Entity(const Entity& entity) defaulted +
+
Copy constructs.
+
+
+
+

Public functions

+
+
+ auto operator=(const Entity& entity) -> Entity& defaulted +
+
Copy assigns.
+
+ auto operator==(const Entity& entity) const -> bool defaulted +
+
Checks if the entity is equal to another.
+
+ auto operator!=(const Entity& entity) const -> bool defaulted +
+
Checks if the entity is not equal to another.
+
+ auto isNull() const -> bool +
+
Checks if the entity is null, a special value returned on errors.
+
+
+
+

Public variables

+
+
+ uint32_t index +
+
Identifies the entity among the living entities in a world.
+
+ uint32_t generation +
+
Counts how many entities with the same index have previously been destroyed.
+
+
+
+

Function documentation

+
+

+ cubos::core::ecs::Entity::Entity(uint32_t index, + uint32_t generation) +

+

Constructs an entity from an index and a generation.

+ + + + + + + + + + + + + + +
Parameters
indexEntity index.
generationEntity generation.
+
+
+

+ cubos::core::ecs::Entity::Entity(const Entity& entity) defaulted +

+

Copy constructs.

+ + + + + + + + + + +
Parameters
entityEntity to copy.
+
+
+

+ Entity& cubos::core::ecs::Entity::operator=(const Entity& entity) defaulted +

+

Copy assigns.

+ + + + + + + + + + +
Parameters
entityEntity to copy.
+
+
+

+ bool cubos::core::ecs::Entity::operator==(const Entity& entity) const defaulted +

+

Checks if the entity is equal to another.

+ + + + + + + + + + + + + + + + +
Parameters
entityEntity to compare to.
ReturnsWhether the entities are equal.
+
+
+

+ bool cubos::core::ecs::Entity::operator!=(const Entity& entity) const defaulted +

+

Checks if the entity is not equal to another.

+ + + + + + + + + + + + + + + + +
Parameters
entityEntity to compare to.
ReturnsWhether the entities are not equal.
+
+
+

+ bool cubos::core::ecs::Entity::isNull() const +

+

Checks if the entity is null, a special value returned on errors.

+ + + + + + + +
ReturnsWhether the entity is null.
+
+
+
+

Variable documentation

+
+

+ uint32_t cubos::core::ecs::Entity::index +

+

Identifies the entity among the living entities in a world.

+

While this is unique at a given time, it may be reused after the entity is destroyed.

+
+
+

+ uint32_t cubos::core::ecs::Entity::generation +

+

Counts how many entities with the same index have previously been destroyed.

+

Allows us to detect when an entity has been destroyed by comparing its generation with the current generation of the entity with the same index.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1EntityHash.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1EntityHash.html new file mode 100644 index 000000000..1b678f4d2 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1EntityHash.html @@ -0,0 +1,104 @@ + + + + + cubos::core::ecs::EntityHash struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1EphemeralTrait.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1EphemeralTrait.html new file mode 100644 index 000000000..cb99496cb --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1EphemeralTrait.html @@ -0,0 +1,103 @@ + + + + + cubos::core::ecs::EphemeralTrait struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Name.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Name.html new file mode 100644 index 000000000..de26c7427 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1Name.html @@ -0,0 +1,123 @@ + + + + + cubos::core::ecs::Name struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1QueryFilter_1_1View_1_1Iterator_1_1Match.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1QueryFilter_1_1View_1_1Iterator_1_1Match.html new file mode 100644 index 000000000..f4907a89f --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1QueryFilter_1_1View_1_1Iterator_1_1Match.html @@ -0,0 +1,123 @@ + + + + + cubos::core::ecs::QueryFilter::View::Iterator::Match struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1QueryTerm.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1QueryTerm.html new file mode 100644 index 000000000..919f54592 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1QueryTerm.html @@ -0,0 +1,532 @@ + + + + + cubos::core::ecs::QueryTerm struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::QueryTerm struct + +

+

Describes a term in a query.

+ +

Terms are the building blocks used to build queries. Each term adds some restriction to what the query will match. There are three kinds of terms:

  • Component terms, which allow filtering match entities by those which have or don't have a given component.
  • Relation terms, which allow filtering match entities by some relation between them.
  • Entity terms, which don't filter the results but allow accessing one of the matched entities.
+
+

Public types

+
+
+ struct Component +
+
Stores component term data.
+
+ struct Entity +
+
Stores entity term data.
+
+ struct Relation +
+
Stores relation term data.
+
+
+
+

Public static functions

+
+
+ static auto makeEntity(int target) -> QueryTerm +
+
Returns a new entity term for the given target.
+
+ static auto makeWithComponent(DataTypeId type, + int target) -> QueryTerm +
+
Returns a new component term for the given component and target.
+
+ static auto makeWithoutComponent(DataTypeId type, + int target) -> QueryTerm +
+
Returns a new negated component term for the given component and target.
+
+ static auto makeOptComponent(DataTypeId type, + int target) -> QueryTerm +
+
Returns a new optional component term for the given component and target.
+
+ static auto makeRelation(DataTypeId type, + int fromTarget, + int toTarget, + Traversal traversal = Traversal::Random) -> QueryTerm +
+
Returns a new relation term for the given relation and targets.
+
+ static auto resolve(const Types& types, + const std::vector<QueryTerm>& baseTerms, + std::vector<QueryTerm>& otherTerms) -> std::vector<QueryTerm> +
+
Merges a vector of terms with another, joining pairs of them if possible.
+
+ static auto toString(const Types& types, + const std::vector<QueryTerm>& terms) -> std::string +
+
Gets a string representation of vector of query terms.
+
+
+
+

Public functions

+
+
+ auto isEntity() const -> bool +
+
Checks if the term is an entity term.
+
+ auto isComponent(const Types& types) const -> bool +
+
Checks if the term is a component term.
+
+ auto isRelation(const Types& types) const -> bool +
+
Checks if the term is a relation term.
+
+ auto compare(const Types& types, + const QueryTerm& other) const -> bool +
+
Compares two terms.
+
+
+
+

Public variables

+
+
+ DataTypeId type +
+
Type of the data matched by the term.
+
+ Entity entity +
+
Entity term data.
+
+ Component component +
+
Component term data.
+
+ Relation relation +
+
Relation term data.
+
+
+
+

Function documentation

+
+

+ static QueryTerm cubos::core::ecs::QueryTerm::makeEntity(int target) +

+

Returns a new entity term for the given target.

+ + + + + + + + + + + + + + + + +
Parameters
targetIndex of the target which will be accessed.
ReturnsEntity term.
+
+
+

+ static QueryTerm cubos::core::ecs::QueryTerm::makeWithComponent(DataTypeId type, + int target) +

+

Returns a new component term for the given component and target.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
typeComponent type.
targetIndex of the target which must have the component.
ReturnsComponent term.
+ +
+
+

+ static QueryTerm cubos::core::ecs::QueryTerm::makeWithoutComponent(DataTypeId type, + int target) +

+

Returns a new negated component term for the given component and target.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
typeComponent type.
targetIndex of the target which must not have the component.
ReturnsComponent term.
+ +
+
+

+ static QueryTerm cubos::core::ecs::QueryTerm::makeOptComponent(DataTypeId type, + int target) +

+

Returns a new optional component term for the given component and target.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
typeComponent type.
targetIndex of the target which may have the component.
ReturnsComponent term.
+ +
+
+

+ static QueryTerm cubos::core::ecs::QueryTerm::makeRelation(DataTypeId type, + int fromTarget, + int toTarget, + Traversal traversal = Traversal::Random) +

+

Returns a new relation term for the given relation and targets.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
typeRelation type.
fromTargetIndex of the target which must have the 'from' side of the relation.
toTargetIndex of the target which must have the 'to' side of the relation.
traversalTraversal order for the relation.
ReturnsRelation term.
+ +
+
+

+ static std::vector<QueryTerm> cubos::core::ecs::QueryTerm::resolve(const Types& types, + const std::vector<QueryTerm>& baseTerms, + std::vector<QueryTerm>& otherTerms) +

+

Merges a vector of terms with another, joining pairs of them if possible.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
typesType registry.
baseTermsBase vector of terms.
otherTerms in/outVector of terms to merge into the base. Targets will be modified, if set to -1.
ReturnsResult of merging the two vectors.
+

This function is mainly used to merge terms specified manually for a query with terms obtained from its argument types. For example, if we have a query of the form Query<A&, A&>, we will obtain the terms makeWithComponent(A, -1) and makeWithComponent(A, -1). Those term would be passed into other. If we passed to base the terms makeWithComponent(A, 0) and makeWithComponent(A, 1), then, the base wouldn't be modified, and the other vector would have its targets updated so that it matches the base.

Any targets found set to -1 will be set to the current default target. The default target is initially 0, and always changes to the last seen non -1 target. If a relation term has one of the targets undefined, the default target is incremented.

Another example would be to have an empty base vector, and the query Query<A&, B&>. The other vector would be {makeWithComponent(A, -1), makeWithComponent(B, -1)}, and the returned vector would be {makeWithComponent(A, 0), makeWithComponent(B, 0)}.

+
+
+

+ static std::string cubos::core::ecs::QueryTerm::toString(const Types& types, + const std::vector<QueryTerm>& terms) +

+

Gets a string representation of vector of query terms.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
typesType registry.
termsVector of terms.
ReturnsString representation.
+
+
+

+ bool cubos::core::ecs::QueryTerm::isEntity() const +

+

Checks if the term is an entity term.

+ + + + + + + +
ReturnsWhether it's an entity term.
+
+
+

+ bool cubos::core::ecs::QueryTerm::isComponent(const Types& types) const +

+

Checks if the term is a component term.

+ + + + + + + + + + + + + + + + +
Parameters
typesTypes registry.
ReturnsWhether it's a component term.
+
+
+

+ bool cubos::core::ecs::QueryTerm::isRelation(const Types& types) const +

+

Checks if the term is a relation term.

+ + + + + + + + + + + + + + + + +
Parameters
typesTypes registry.
ReturnsWhether it's a relation term.
+
+
+

+ bool cubos::core::ecs::QueryTerm::compare(const Types& types, + const QueryTerm& other) const +

+

Compares two terms.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
typesTypes registry.
otherOther term.
ReturnsWhether they're equal.
+
+
+
+

Variable documentation

+
+

+ DataTypeId cubos::core::ecs::QueryTerm::type +

+

Type of the data matched by the term.

+

If this is set to DataTypeId::Invalid, then the term is an entity term. Otherwise, the term can either be a component or relation term depending on this type.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1QueryTerm_1_1Component.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1QueryTerm_1_1Component.html new file mode 100644 index 000000000..2180b6a9d --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1QueryTerm_1_1Component.html @@ -0,0 +1,131 @@ + + + + + cubos::core::ecs::QueryTerm::Component struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1QueryTerm_1_1Entity.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1QueryTerm_1_1Entity.html new file mode 100644 index 000000000..c55301b4f --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1QueryTerm_1_1Entity.html @@ -0,0 +1,123 @@ + + + + + cubos::core::ecs::QueryTerm::Entity struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1QueryTerm_1_1Relation.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1QueryTerm_1_1Relation.html new file mode 100644 index 000000000..5bd0ab0af --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1QueryTerm_1_1Relation.html @@ -0,0 +1,131 @@ + + + + + cubos::core::ecs::QueryTerm::Relation struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1ShouldQuit.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1ShouldQuit.html new file mode 100644 index 000000000..8187adc9c --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1ShouldQuit.html @@ -0,0 +1,124 @@ + + + + + cubos::core::ecs::ShouldQuit struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::ShouldQuit struct + +

+

Resource used as a flag to indicate whether the main loop should stop running.

+ +

This resource is added by the Cubos class, initially set to true.

+
+

Public variables

+
+
+ bool value +
+
Whether the main loop should stop running.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SparseRelationTableId.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SparseRelationTableId.html new file mode 100644 index 000000000..7b7f5aea4 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SparseRelationTableId.html @@ -0,0 +1,198 @@ + + + + + cubos::core::ecs::SparseRelationTableId struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::SparseRelationTableId struct + +

+

Identifies a sparse relation table.

+ +
+

Constructors, destructors, conversion operators

+
+
+ SparseRelationTableId() defaulted +
+
Default constructor.
+
+ SparseRelationTableId(DataTypeId dataType, + ArchetypeId from, + ArchetypeId to, + int depth = 0) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ auto operator==(const SparseRelationTableId& other) const -> bool defaulted +
+
Compares with another identifier.
+
+
+
+

Function documentation

+
+

+ cubos::core::ecs::SparseRelationTableId::SparseRelationTableId(DataTypeId dataType, + ArchetypeId from, + ArchetypeId to, + int depth = 0) +

+

Constructs.

+ + + + + + + + + + + + + + + + + + + + + + +
Parameters
dataTypeRelation data type.
fromFrom archetype identifier.
toTo archetype identifier.
depthDepth of the relation. Used in tree relations, always 0 for others.
+
+
+

+ bool cubos::core::ecs::SparseRelationTableId::operator==(const SparseRelationTableId& other) const defaulted +

+

Compares with another identifier.

+ + + + + + + + + + + + + + + + +
Parameters
otherIdentifier.
ReturnsWhether they're equal.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SparseRelationTableIdHash.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SparseRelationTableIdHash.html new file mode 100644 index 000000000..c603cbef0 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SparseRelationTableIdHash.html @@ -0,0 +1,103 @@ + + + + + cubos::core::ecs::SparseRelationTableIdHash struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SparseRelationTable_1_1Iterator_1_1Output.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SparseRelationTable_1_1Iterator_1_1Output.html new file mode 100644 index 000000000..8dfd2980f --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SparseRelationTable_1_1Iterator_1_1Output.html @@ -0,0 +1,131 @@ + + + + + cubos::core::ecs::SparseRelationTable::Iterator::Output struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SparseRelationTable_1_1View_1_1Iterator_1_1Output.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SparseRelationTable_1_1View_1_1Iterator_1_1Output.html new file mode 100644 index 000000000..189ee8e8d --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SparseRelationTable_1_1View_1_1Iterator_1_1Output.html @@ -0,0 +1,131 @@ + + + + + cubos::core::ecs::SparseRelationTable::View::Iterator::Output struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SymmetricTrait.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SymmetricTrait.html new file mode 100644 index 000000000..565d19f71 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SymmetricTrait.html @@ -0,0 +1,104 @@ + + + + + cubos::core::ecs::SymmetricTrait struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::SymmetricTrait struct + +

+

Trait used to identify symmetric relations.

+

Symmetric relations are relations where the order of the entities does not matter.

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SystemAccess.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SystemAccess.html new file mode 100644 index 000000000..5e6b9010b --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SystemAccess.html @@ -0,0 +1,164 @@ + + + + + cubos::core::ecs::SystemAccess struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::SystemAccess struct + +

+

Describes the types of data a system accesses.

+ +

Used to determine if systems conflict with each other.

+
+

Public functions

+
+
+ auto intersects(const SystemAccess& other) const -> bool +
+
Checks if this access patterns intersect with the given ones.
+
+
+
+

Public variables

+
+
+ bool usesWorld +
+
Whether the system accesses the world directly.
+
+ std::unordered_set<DataTypeId, DataTypeIdHash> dataTypes +
+
Set of data types accessed by the system.
+
+
+
+

Function documentation

+
+

+ bool cubos::core::ecs::SystemAccess::intersects(const SystemAccess& other) const +

+

Checks if this access patterns intersect with the given ones.

+ + + + + + + + + + + + + + + + +
Parameters
otherOther system access patterns.
ReturnsWhether they intersect.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SystemOptions.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SystemOptions.html new file mode 100644 index 000000000..3e224781f --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1SystemOptions.html @@ -0,0 +1,123 @@ + + + + + cubos::core::ecs::SystemOptions struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1TreeTrait.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1TreeTrait.html new file mode 100644 index 000000000..1ceb5e6fa --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1TreeTrait.html @@ -0,0 +1,104 @@ + + + + + cubos::core::ecs::TreeTrait struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::TreeTrait struct + +

+

Trait used to identify tree relations.

+

Tree relations are relations which form trees. Each entity must have at most one target entity for a given tree relation type. These can be used to represent parent-child relationships.

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1World_1_1Components_1_1Iterator_1_1Component.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1World_1_1Components_1_1Iterator_1_1Component.html new file mode 100644 index 000000000..918c31fdd --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1World_1_1Components_1_1Iterator_1_1Component.html @@ -0,0 +1,127 @@ + + + + + cubos::core::ecs::World::Components::Iterator::Component struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1World_1_1ConstComponents_1_1Iterator_1_1Component.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1World_1_1ConstComponents_1_1Iterator_1_1Component.html new file mode 100644 index 000000000..e2928891f --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1World_1_1ConstComponents_1_1Iterator_1_1Component.html @@ -0,0 +1,127 @@ + + + + + cubos::core::ecs::World::ConstComponents::Iterator::Component struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1World_1_1ConstRelations_1_1Iterator_1_1Relation.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1World_1_1ConstRelations_1_1Iterator_1_1Relation.html new file mode 100644 index 000000000..f75b38e34 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1World_1_1ConstRelations_1_1Iterator_1_1Relation.html @@ -0,0 +1,131 @@ + + + + + cubos::core::ecs::World::ConstRelations::Iterator::Relation struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1World_1_1Relations_1_1Iterator_1_1Relation.html b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1World_1_1Relations_1_1Iterator_1_1Relation.html new file mode 100644 index 000000000..1577fc317 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1ecs_1_1World_1_1Relations_1_1Iterator_1_1Relation.html @@ -0,0 +1,131 @@ + + + + + cubos::core::ecs::World::Relations::Iterator::Relation struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1geom_1_1AABB.html b/docs-preview/pr-1032/structcubos_1_1core_1_1geom_1_1AABB.html new file mode 100644 index 000000000..ae83df5a9 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1geom_1_1AABB.html @@ -0,0 +1,354 @@ + + + + + cubos::core::geom::AABB struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::geom::AABB struct + +

+

Represents an axis-aligned bounding box.

+ +
+

Public functions

+
+
+ auto min() const -> glm::vec3 +
+
Minimum point of the AABB.
+
+ auto max() const -> glm::vec3 +
+
Maximum point of the AABB.
+
+ void min(const glm::vec3& min) +
+
Sets the minimum point of the AABB.
+
+ void max(const glm::vec3& max) +
+
Sets the maximum point of the AABB.
+
+ auto box() const -> Box +
+
Gets a Box representation of the AABB.
+
+ auto center() const -> glm::vec3 +
+
Gets the center of the AABB.
+
+ auto overlapsX(const AABB& other) const -> bool +
+
Checks if the AABB overlaps with another AABB on the X axis.
+
+ auto overlapsY(const AABB& other) const -> bool +
+
Checks if the AABB overlaps with another AABB on the Y axis.
+
+ auto overlapsZ(const AABB& other) const -> bool +
+
Checks if the AABB overlaps with another AABB on the Z axis.
+
+ auto overlaps(const AABB& other) const -> bool +
+
Checks if the AABB overlaps with another AABB.
+
+
+
+

Public variables

+
+
+ glm::vec3 diag +
+
Diagonal of the AABB.
+
+
+
+

Function documentation

+
+

+ glm::vec3 cubos::core::geom::AABB::min() const +

+

Minimum point of the AABB.

+ + + + + + + +
ReturnsMinimum point of the AABB.
+
+
+

+ glm::vec3 cubos::core::geom::AABB::max() const +

+

Maximum point of the AABB.

+ + + + + + + +
ReturnsMaximum point of the AABB.
+
+
+

+ void cubos::core::geom::AABB::min(const glm::vec3& min) +

+

Sets the minimum point of the AABB.

+ + + + + + + + + + +
Parameters
minMinimum point of the AABB.
+
+
+

+ void cubos::core::geom::AABB::max(const glm::vec3& max) +

+

Sets the maximum point of the AABB.

+ + + + + + + + + + +
Parameters
maxMaximum point of the AABB.
+
+
+

+ Box cubos::core::geom::AABB::box() const +

+

Gets a Box representation of the AABB.

+ + + + + + + +
ReturnsBox representation.
+
+
+

+ glm::vec3 cubos::core::geom::AABB::center() const +

+

Gets the center of the AABB.

+ + + + + + + +
ReturnsCenter of the AABB.
+
+
+

+ bool cubos::core::geom::AABB::overlapsX(const AABB& other) const +

+

Checks if the AABB overlaps with another AABB on the X axis.

+ + + + + + + + + + + + + + + + +
Parameters
otherOther AABB.
ReturnsWhether the AABBs overlap.
+
+
+

+ bool cubos::core::geom::AABB::overlapsY(const AABB& other) const +

+

Checks if the AABB overlaps with another AABB on the Y axis.

+ + + + + + + + + + + + + + + + +
Parameters
otherOther AABB.
ReturnsWhether the AABBs overlap.
+
+
+

+ bool cubos::core::geom::AABB::overlapsZ(const AABB& other) const +

+

Checks if the AABB overlaps with another AABB on the Z axis.

+ + + + + + + + + + + + + + + + +
Parameters
otherOther AABB.
ReturnsWhether the AABBs overlap.
+
+
+

+ bool cubos::core::geom::AABB::overlaps(const AABB& other) const +

+

Checks if the AABB overlaps with another AABB.

+ + + + + + + + + + + + + + + + +
Parameters
otherOther AABB.
ReturnsWhether the AABBs overlap.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1geom_1_1Box.html b/docs-preview/pr-1032/structcubos_1_1core_1_1geom_1_1Box.html new file mode 100644 index 000000000..0207cd938 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1geom_1_1Box.html @@ -0,0 +1,195 @@ + + + + + cubos::core::geom::Box struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::geom::Box struct + +

+

Represents a box shape.

+ +
+

Public functions

+
+
+ void diag(glm::vec3 corners[2]) const +
+
Computes two opposite corners of the box on the major diagonal.
+
+ void corners4(glm::vec3 corners[4]) const +
+
Computes four corners of the box, one for each diagonal.
+
+ void corners(glm::vec3 corners[8]) const +
+
Computes the eight corners of the box, opposite corners are adjacent in the array.
+
+
+
+

Public variables

+
+
+ glm::vec3 halfSize +
+
Half size of the box.
+
+
+
+

Function documentation

+
+

+ void cubos::core::geom::Box::diag(glm::vec3 corners[2]) const +

+

Computes two opposite corners of the box on the major diagonal.

+ + + + + + + + + + +
Parameters
cornersArray to store the two corners in.
+
+
+

+ void cubos::core::geom::Box::corners4(glm::vec3 corners[4]) const +

+

Computes four corners of the box, one for each diagonal.

+ + + + + + + + + + +
Parameters
cornersArray to store the three corners in.
+
+
+

+ void cubos::core::geom::Box::corners(glm::vec3 corners[8]) const +

+

Computes the eight corners of the box, opposite corners are adjacent in the array.

+ + + + + + + + + + +
Parameters
cornersArray to store the eight corners in.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1geom_1_1Capsule.html b/docs-preview/pr-1032/structcubos_1_1core_1_1geom_1_1Capsule.html new file mode 100644 index 000000000..d605f7c5c --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1geom_1_1Capsule.html @@ -0,0 +1,205 @@ + + + + + cubos::core::geom::Capsule struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::geom::Capsule struct + +

+

Represents a capsule or sphere shape.

+ +
+

Public static functions

+
+
+ static auto sphere(float radius) -> Capsule +
+
Constructs a sphere.
+
+
+
+

Public functions

+
+
+ auto height() const -> float +
+
Gets the height of the capsule.
+
+ auto aabb() const -> AABB +
+
Computes the local AABB of the capsule.
+
+
+
+

Public variables

+
+
+ float radius +
+
Radius of the capsule.
+
+ float length +
+
Length of the capsule.
+
+
+
+

Function documentation

+
+

+ static Capsule cubos::core::geom::Capsule::sphere(float radius) +

+

Constructs a sphere.

+ + + + + + + + + + + + + + + + +
Parameters
radiusSphere radius.
ReturnsSphere shape.
+
+
+

+ float cubos::core::geom::Capsule::height() const +

+

Gets the height of the capsule.

+ + + + + + + +
ReturnsHeight of the capsule.
+
+
+

+ AABB cubos::core::geom::Capsule::aabb() const +

+

Computes the local AABB of the capsule.

+ + + + + + + +
ReturnsLocal AABB of the capsule.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1geom_1_1Intersection.html b/docs-preview/pr-1032/structcubos_1_1core_1_1geom_1_1Intersection.html new file mode 100644 index 000000000..a55728d16 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1geom_1_1Intersection.html @@ -0,0 +1,131 @@ + + + + + cubos::core::geom::Intersection struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1BlendStateDesc.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1BlendStateDesc.html new file mode 100644 index 000000000..578948737 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1BlendStateDesc.html @@ -0,0 +1,167 @@ + + + + + cubos::core::gl::BlendStateDesc struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::BlendStateDesc struct + +

+

Describes a blend state.

+ +
+

Public variables

+
+
+ bool blendEnabled +
+
Enable blending?
+
+ BlendFactor src +
+
Color blend source factor.
+
+ BlendFactor dst +
+
Color blend destination factor.
+
+ BlendOp op +
+
Color blend operation.
+
+ struct cubos::core::gl::BlendStateDesc::@5 color +
+
Color blend state.
+
+ struct cubos::core::gl::BlendStateDesc::@6 alpha +
+
Alpha blend state.
+
+
+
+

Variable documentation

+
+

+ BlendFactor cubos::core::gl::BlendStateDesc::src +

+

Color blend source factor.

+

Alpha blend source factor.

+
+
+

+ BlendFactor cubos::core::gl::BlendStateDesc::dst +

+

Color blend destination factor.

+

Alpha blend destination factor.

+
+
+

+ BlendOp cubos::core::gl::BlendStateDesc::op +

+

Color blend operation.

+

Alpha blend operation.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1ConstantBufferElement.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1ConstantBufferElement.html new file mode 100644 index 000000000..adee5929d --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1ConstantBufferElement.html @@ -0,0 +1,135 @@ + + + + + cubos::core::gl::ConstantBufferElement struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::ConstantBufferElement struct + +

+

Describes an element in a constant buffer.

+ +
+

Public variables

+
+
+ char name +
+
Element name.
+
+ std::size_t offset +
+
Offset of the element in the buffer.
+
+ std::size_t size +
+
Number of values in the element if it is an array. If it isn't, this is set to 1.
+
+ std::size_t stride +
+
Stride between each element in the array, if the element is an array.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1ConstantBufferStructure.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1ConstantBufferStructure.html new file mode 100644 index 000000000..934fe6b84 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1ConstantBufferStructure.html @@ -0,0 +1,131 @@ + + + + + cubos::core::gl::ConstantBufferStructure struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1CubeMapArrayDesc.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1CubeMapArrayDesc.html new file mode 100644 index 000000000..8e2f01aab --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1CubeMapArrayDesc.html @@ -0,0 +1,147 @@ + + + + + cubos::core::gl::CubeMapArrayDesc struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::CubeMapArrayDesc struct + +

+

Describes a cube map array.

+ +
+

Public variables

+
+
+ const void* data +
+
Optional initial cube map data, indexed using CubeFace.
+
+ std::size_t mipLevelCount +
+
Number of mip levels.
+
+ std::size_t width +
+
Cube map face width.
+
+ std::size_t height +
+
Cube map face height.
+
+ std::size_t size +
+
Number of cube maps contained in the array.
+
+ Usage usage +
+
Texture usage mode.
+
+ TextureFormat format +
+
Texture format.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1CubeMapDesc.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1CubeMapDesc.html new file mode 100644 index 000000000..4baf62299 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1CubeMapDesc.html @@ -0,0 +1,143 @@ + + + + + cubos::core::gl::CubeMapDesc struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::CubeMapDesc struct + +

+

Describes a cube map.

+ +
+

Public variables

+
+
+ const void* data +
+
Optional initial cube map data, indexed using CubeFace.
+
+ std::size_t mipLevelCount +
+
Number of mip levels.
+
+ std::size_t width +
+
Cube map face width.
+
+ std::size_t height +
+
Cube map face height.
+
+ Usage usage +
+
Texture usage mode.
+
+ TextureFormat format +
+
Texture format.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc.html new file mode 100644 index 000000000..6f1950682 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc.html @@ -0,0 +1,141 @@ + + + + + cubos::core::gl::DepthStencilStateDesc struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Depth.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Depth.html new file mode 100644 index 000000000..3e054f344 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Depth.html @@ -0,0 +1,139 @@ + + + + + cubos::core::gl::DepthStencilStateDesc::Depth struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Stencil.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Stencil.html new file mode 100644 index 000000000..44c49077c --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Stencil.html @@ -0,0 +1,153 @@ + + + + + cubos::core::gl::DepthStencilStateDesc::Stencil struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::DepthStencilStateDesc::Stencil struct + +

+

Describes a stencil state.

+ +
+

Public types

+
+
+ struct Face +
+
Decribes a stencil face.
+
+
+
+

Public variables

+
+
+ bool enabled +
+
Is stencil enabled?
+
+ uint32_t ref +
+
Stencil ref value used on stencil comparison functions.
+
+ uint8_t readMask +
+
Stencil read mask.
+
+ uint8_t writeMask +
+
Stencil write mask.
+
+ Face backFace +
+
Stencil back face options.
+
+ Face frontFace +
+
Stencil front face options.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Stencil_1_1Face.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Stencil_1_1Face.html new file mode 100644 index 000000000..081c24d2f --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Stencil_1_1Face.html @@ -0,0 +1,135 @@ + + + + + cubos::core::gl::DepthStencilStateDesc::Stencil::Face struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc.html new file mode 100644 index 000000000..4626d282d --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc.html @@ -0,0 +1,164 @@ + + + + + cubos::core::gl::FramebufferDesc struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::FramebufferDesc struct + +

+

Describes a framebuffer.

+ +
+

Public types

+
+
+ struct CubeMapArrayTarget +
+
Describes a cube map array target.
+
+ struct CubeMapTarget +
+
Describes a cube map target.
+
+ struct FramebufferTarget +
+
Describes a framebuffer target.
+
+ struct Texture2DArrayTarget +
+
Describes a 2D texture array target.
+
+ struct Texture2DTarget +
+
Describes a 2D texture target.
+
+ enum class TargetType { CubeMap, + Texture2D, + CubeMapArray, + Texture2DArray } +
+
Possible types of targets.
+
+
+
+

Public variables

+
+
+ struct cubos::core::gl::FramebufferDesc::FramebufferTarget targets +
+
Render targets.
+
+ uint32_t targetCount +
+
Number of render targets.
+
+ FramebufferTarget depthStencil +
+
Optional depth stencil target.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1CubeMapArrayTarget.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1CubeMapArrayTarget.html new file mode 100644 index 000000000..adde9a572 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1CubeMapArrayTarget.html @@ -0,0 +1,123 @@ + + + + + cubos::core::gl::FramebufferDesc::CubeMapArrayTarget struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1CubeMapTarget.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1CubeMapTarget.html new file mode 100644 index 000000000..d093d1192 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1CubeMapTarget.html @@ -0,0 +1,127 @@ + + + + + cubos::core::gl::FramebufferDesc::CubeMapTarget struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1FramebufferTarget.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1FramebufferTarget.html new file mode 100644 index 000000000..457dd8645 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1FramebufferTarget.html @@ -0,0 +1,123 @@ + + + + + cubos::core::gl::FramebufferDesc::FramebufferTarget struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1Texture2DArrayTarget.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1Texture2DArrayTarget.html new file mode 100644 index 000000000..07ac680c9 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1Texture2DArrayTarget.html @@ -0,0 +1,123 @@ + + + + + cubos::core::gl::FramebufferDesc::Texture2DArrayTarget struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1Texture2DTarget.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1Texture2DTarget.html new file mode 100644 index 000000000..8cb284137 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1Texture2DTarget.html @@ -0,0 +1,123 @@ + + + + + cubos::core::gl::FramebufferDesc::Texture2DTarget struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1RasterStateDesc.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1RasterStateDesc.html new file mode 100644 index 000000000..b4fb67322 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1RasterStateDesc.html @@ -0,0 +1,139 @@ + + + + + cubos::core::gl::RasterStateDesc struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1SamplerDesc.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1SamplerDesc.html new file mode 100644 index 000000000..b14ea439e --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1SamplerDesc.html @@ -0,0 +1,151 @@ + + + + + cubos::core::gl::SamplerDesc struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::SamplerDesc struct + +

+

Describes a sampler.

+ +
+

Public variables

+
+
+ float borderColor +
+
Border color applied when the address mode is AddressMode::Border.
+
+ TextureFilter minFilter +
+
Minifying filter.
+
+ TextureFilter magFilter +
+
Magnifying filter.
+
+ TextureFilter mipmapFilter +
+
Set to None to disable mipmapping.
+
+ AddressMode addressU +
+
Texture adress mode on coordinate U.
+
+ AddressMode addressV +
+
Texture adress mode on coordinate V.
+
+ AddressMode addressW +
+
Texture adress mode on coordinate W.
+
+ std::size_t maxAnisotropy +
+
Max anisotropy for filtering. Limited to Property::MaxAnisotropy.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1Texture1DDesc.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1Texture1DDesc.html new file mode 100644 index 000000000..8aca2223a --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1Texture1DDesc.html @@ -0,0 +1,139 @@ + + + + + cubos::core::gl::Texture1DDesc struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1Texture2DArrayDesc.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1Texture2DArrayDesc.html new file mode 100644 index 000000000..04ef310a4 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1Texture2DArrayDesc.html @@ -0,0 +1,147 @@ + + + + + cubos::core::gl::Texture2DArrayDesc struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::Texture2DArrayDesc struct + +

+

Describes a 2D texture array.

+ +
+

Public variables

+
+
+ const void* data +
+
Optional initial texture data.
+
+ std::size_t mipLevelCount +
+
Number of mip levels.
+
+ std::size_t width +
+
Texture width.
+
+ std::size_t height +
+
Texture height.
+
+ std::size_t size +
+
Number of 2D Textures contained in the array.
+
+ Usage usage +
+
Texture usage mode.
+
+ TextureFormat format +
+
Texture format.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1Texture2DDesc.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1Texture2DDesc.html new file mode 100644 index 000000000..70a834773 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1Texture2DDesc.html @@ -0,0 +1,143 @@ + + + + + cubos::core::gl::Texture2DDesc struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1Texture3DDesc.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1Texture3DDesc.html new file mode 100644 index 000000000..b8f3dd743 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1Texture3DDesc.html @@ -0,0 +1,147 @@ + + + + + cubos::core::gl::Texture3DDesc struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::Texture3DDesc struct + +

+

Describes a 3D texture.

+ +
+

Public variables

+
+
+ const void* data +
+
Optional initial texture data.
+
+ std::size_t mipLevelCount +
+
Number of mip levels.
+
+ std::size_t width +
+
Texture width.
+
+ std::size_t height +
+
Texture height.
+
+ std::size_t depth +
+
Texture depth.
+
+ Usage usage +
+
Texture usage mode.
+
+ TextureFormat format +
+
Texture format.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1VertexArrayDesc.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1VertexArrayDesc.html new file mode 100644 index 000000000..d58e837f3 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1VertexArrayDesc.html @@ -0,0 +1,135 @@ + + + + + cubos::core::gl::VertexArrayDesc struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1VertexElement.html b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1VertexElement.html new file mode 100644 index 000000000..b1c6f2922 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1gl_1_1VertexElement.html @@ -0,0 +1,147 @@ + + + + + cubos::core::gl::VertexElement struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::VertexElement struct + +

+

Describes a vertex element.

+ +
+

Public variables

+
+
+ const char* name +
+
Element name.
+
+ Type type +
+
Element type.
+
+ std::size_t size +
+
Number of components in the vertex element (1, 2, 3 or 4).
+
+ std::size_t stride +
+
Stride between each element in memory.
+
+ std::size_t offset +
+
Offset of the first element in the buffer.
+
+ std::size_t index +
+
Index of the vertex buffer where the element is stored.
+
+ struct cubos::core::gl::VertexElement::@7 buffer +
+
Vertex buffer description.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1GamepadConnectionEvent.html b/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1GamepadConnectionEvent.html new file mode 100644 index 000000000..056a0f106 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1GamepadConnectionEvent.html @@ -0,0 +1,127 @@ + + + + + cubos::core::io::GamepadConnectionEvent struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1GamepadState.html b/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1GamepadState.html new file mode 100644 index 000000000..7f86fd11a --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1GamepadState.html @@ -0,0 +1,190 @@ + + + + + cubos::core::io::GamepadState struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::core::io::GamepadState struct + +

+

Holds the state of a gamepad.

+ +
+

Public functions

+
+
+ auto pressed(GamepadButton button) const -> bool +
+
Checks if a button is pressed.
+
+ auto axis(GamepadAxis axis) const -> float +
+
Gets the value of an axis.
+
+
+
+

Public variables

+
+
+ bool buttons +
+
Which buttons are pressed, indexed by GamepadButton.
+
+ float axes +
+
Values of the axes, indexed by GamepadAxis.
+
+
+
+

Function documentation

+
+

+ bool cubos::core::io::GamepadState::pressed(GamepadButton button) const +

+

Checks if a button is pressed.

+ + + + + + + + + + + + + + + + +
Parameters
buttonButton to check.
ReturnsWhether it is pressed or not.
+
+
+

+ float cubos::core::io::GamepadState::axis(GamepadAxis axis) const +

+

Gets the value of an axis.

+ + + + + + + + + + + + + + + + +
Parameters
axisAxis to get the value of.
ReturnsValue of the axis.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1KeyEvent.html b/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1KeyEvent.html new file mode 100644 index 000000000..f2fce3fc7 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1KeyEvent.html @@ -0,0 +1,127 @@ + + + + + cubos::core::io::KeyEvent struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1KeyWithModifiers.html b/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1KeyWithModifiers.html new file mode 100644 index 000000000..3c2481e02 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1KeyWithModifiers.html @@ -0,0 +1,103 @@ + + + + + cubos::core::io::KeyWithModifiers struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1ModifiersEvent.html b/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1ModifiersEvent.html new file mode 100644 index 000000000..c6c1d0b97 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1ModifiersEvent.html @@ -0,0 +1,123 @@ + + + + + cubos::core::io::ModifiersEvent struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1MouseButtonEvent.html b/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1MouseButtonEvent.html new file mode 100644 index 000000000..6d14fb474 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1MouseButtonEvent.html @@ -0,0 +1,127 @@ + + + + + cubos::core::io::MouseButtonEvent struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1MouseMoveEvent.html b/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1MouseMoveEvent.html new file mode 100644 index 000000000..f6f2400c7 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1MouseMoveEvent.html @@ -0,0 +1,123 @@ + + + + + cubos::core::io::MouseMoveEvent struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1MouseScrollEvent.html b/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1MouseScrollEvent.html new file mode 100644 index 000000000..eadc81149 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1MouseScrollEvent.html @@ -0,0 +1,123 @@ + + + + + cubos::core::io::MouseScrollEvent struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1ResizeEvent.html b/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1ResizeEvent.html new file mode 100644 index 000000000..820a4ee75 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1ResizeEvent.html @@ -0,0 +1,123 @@ + + + + + cubos::core::io::ResizeEvent struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1TextEvent.html b/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1TextEvent.html new file mode 100644 index 000000000..4235d48eb --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1io_1_1TextEvent.html @@ -0,0 +1,123 @@ + + + + + cubos::core::io::TextEvent struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1memory_1_1IsLValueReference.html b/docs-preview/pr-1032/structcubos_1_1core_1_1memory_1_1IsLValueReference.html new file mode 100644 index 000000000..33b44f78e --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1memory_1_1IsLValueReference.html @@ -0,0 +1,115 @@ + + + + + cubos::core::memory::IsLValueReference struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::memory::IsLValueReference struct +

+

Used to check if a type is an rvalue reference.

+ + + + + + + + + + +
Template parameters
TType.
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1memory_1_1RemoveReference.html b/docs-preview/pr-1032/structcubos_1_1core_1_1memory_1_1RemoveReference.html new file mode 100644 index 000000000..65702f55e --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1memory_1_1RemoveReference.html @@ -0,0 +1,136 @@ + + + + + cubos::core::memory::RemoveReference struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::memory::RemoveReference struct +

+

Provides a type which is the same as the given type, but without any references.

+ + + + + + + + + + +
Template parameters
TType.
+ + +
+

Public types

+
+
+ using Type = T +
+
Type without references.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1reflection_1_1DictionaryTrait_1_1ConstView_1_1Iterator_1_1Entry.html b/docs-preview/pr-1032/structcubos_1_1core_1_1reflection_1_1DictionaryTrait_1_1ConstView_1_1Iterator_1_1Entry.html new file mode 100644 index 000000000..278710c61 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1reflection_1_1DictionaryTrait_1_1ConstView_1_1Iterator_1_1Entry.html @@ -0,0 +1,127 @@ + + + + + cubos::core::reflection::DictionaryTrait::ConstView::Iterator::Entry struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1reflection_1_1DictionaryTrait_1_1View_1_1Iterator_1_1Entry.html b/docs-preview/pr-1032/structcubos_1_1core_1_1reflection_1_1DictionaryTrait_1_1View_1_1Iterator_1_1Entry.html new file mode 100644 index 000000000..cd372d660 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1reflection_1_1DictionaryTrait_1_1View_1_1Iterator_1_1Entry.html @@ -0,0 +1,127 @@ + + + + + cubos::core::reflection::DictionaryTrait::View::Iterator::Entry struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1reflection_1_1FieldsTrait_1_1ConstView_1_1Iterator_1_1Output.html b/docs-preview/pr-1032/structcubos_1_1core_1_1reflection_1_1FieldsTrait_1_1ConstView_1_1Iterator_1_1Output.html new file mode 100644 index 000000000..126206567 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1reflection_1_1FieldsTrait_1_1ConstView_1_1Iterator_1_1Output.html @@ -0,0 +1,127 @@ + + + + + cubos::core::reflection::FieldsTrait::ConstView::Iterator::Output struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1reflection_1_1FieldsTrait_1_1View_1_1Iterator_1_1Output.html b/docs-preview/pr-1032/structcubos_1_1core_1_1reflection_1_1FieldsTrait_1_1View_1_1Iterator_1_1Output.html new file mode 100644 index 000000000..62f7a8b26 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1reflection_1_1FieldsTrait_1_1View_1_1Iterator_1_1Output.html @@ -0,0 +1,127 @@ + + + + + cubos::core::reflection::FieldsTrait::View::Iterator::Output struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1core_1_1reflection_1_1Reflect.html b/docs-preview/pr-1032/structcubos_1_1core_1_1reflection_1_1Reflect.html new file mode 100644 index 000000000..98bc2fc0b --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1core_1_1reflection_1_1Reflect.html @@ -0,0 +1,116 @@ + + + + + cubos::core::reflection::Reflect struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::reflection::Reflect struct +

+

Defines the reflection function for the given type T.

+ + + + + + + + + + +
Template parameters
TType to reflect.
+

By default, this function calls the static member function reflect of the type, which should return a pointer to an instance of Type.

To implement reflection for your type, you should either:

  • Define a static member function reflect with return type const Type& on your type.
  • Specialize this struct for your type.

The first option is preferred, as it is less verbose. However, when handling external types, to which member functions cannot be added, the second option is necessary.

Both options can and should be shortened by using the macros:

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1AccumulatedCorrection.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1AccumulatedCorrection.html new file mode 100644 index 000000000..3c347d878 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1AccumulatedCorrection.html @@ -0,0 +1,123 @@ + + + + + cubos::engine::AccumulatedCorrection struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1ActiveCameras.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1ActiveCameras.html new file mode 100644 index 000000000..5fedb6088 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1ActiveCameras.html @@ -0,0 +1,133 @@ + + + + + cubos::engine::ActiveCameras struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::ActiveCameras struct + +

+

Resource which identifies the camera entities to be used by the renderer.

+ +
+

Public variables

+
+
+ core::ecs::Entity entities +
+
Entities which represent the current active cameras. If more than one is set, the screen is split. At most, 4 cameras are supported at the same time.
+
+
+
+

Variable documentation

+
+

+ core::ecs::Entity cubos::engine::ActiveCameras::entities +

+

Entities which represent the current active cameras. If more than one is set, the screen is split. At most, 4 cameras are supported at the same time.

+ +
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1ActiveVoxelPalette.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1ActiveVoxelPalette.html new file mode 100644 index 000000000..3c8dfb56a --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1ActiveVoxelPalette.html @@ -0,0 +1,127 @@ + + + + + cubos::engine::ActiveVoxelPalette struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1AssetMeta_1_1Exclude.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1AssetMeta_1_1Exclude.html new file mode 100644 index 000000000..15970f9e0 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1AssetMeta_1_1Exclude.html @@ -0,0 +1,123 @@ + + + + + cubos::engine::AssetMeta::Exclude struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1BaseRenderer_1_1Viewport.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1BaseRenderer_1_1Viewport.html new file mode 100644 index 000000000..9c75d1367 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1BaseRenderer_1_1Viewport.html @@ -0,0 +1,103 @@ + + + + + cubos::engine::BaseRenderer::Viewport struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1BoxCollisionShape.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1BoxCollisionShape.html new file mode 100644 index 000000000..b0ca581dc --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1BoxCollisionShape.html @@ -0,0 +1,123 @@ + + + + + cubos::engine::BoxCollisionShape struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1Camera.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1Camera.html new file mode 100644 index 000000000..1bf0bfc68 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1Camera.html @@ -0,0 +1,132 @@ + + + + + cubos::engine::Camera struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1CapsuleCollisionShape.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1CapsuleCollisionShape.html new file mode 100644 index 000000000..f52653abc --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1CapsuleCollisionShape.html @@ -0,0 +1,123 @@ + + + + + cubos::engine::CapsuleCollisionShape struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1ChildOf.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1ChildOf.html new file mode 100644 index 000000000..65482f719 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1ChildOf.html @@ -0,0 +1,103 @@ + + + + + cubos::engine::ChildOf struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1Collider.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1Collider.html new file mode 100644 index 000000000..f5ffd835a --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1Collider.html @@ -0,0 +1,149 @@ + + + + + cubos::engine::Collider struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::Collider struct + +

+

Component which adds a collider to an entity.

+ +
+

Public variables

+
+
+ glm::mat4 transform +
+
Transform of the collider.
+
+ core::geom::AABB localAABB +
+
Local space AABB of the collider.
+
+ core::geom::AABB worldAABB +
+
World space AABB of the collider.
+
+ float margin +
+
Margin of the collider.
+
+ int fresh +
+
This is an hack and should be done in ECS.
+
+
+
+

Variable documentation

+
+

+ float cubos::engine::Collider::margin +

+

Margin of the collider.

+

When the collider shape has sharp edges, a margin is needed. The plugin will set it based on the shape associated with the collider.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1CollidingWith.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1CollidingWith.html new file mode 100644 index 000000000..a47bc4dfb --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1CollidingWith.html @@ -0,0 +1,135 @@ + + + + + cubos::engine::CollidingWith struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::CollidingWith struct + +

+

Relation which represents a collision.

+ +
+

Public variables

+
+
+ cubos::core::ecs::Entity entity +
+
Entity to which the normal is relative to.
+
+ float penetration +
+
Penetration depth of the collision.
+
+ glm::vec3 position +
+
Position of contact on the surface of the entity.
+
+ glm::vec3 normal +
+
Normal of contact on the surface of the entity.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1CollisionEvent.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1CollisionEvent.html new file mode 100644 index 000000000..a5e57e438 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1CollisionEvent.html @@ -0,0 +1,139 @@ + + + + + cubos::engine::CollisionEvent struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::CollisionEvent struct + +

+

Represents a collision event.

+ +
+

Public variables

+
+
+ cubos::core::ecs::Entity entity +
+
Entity involved in the collision.
+
+ cubos::core::ecs::Entity other +
+
Other entity involved in the collision.
+
+ float penetration +
+
Penetration depth of the collision.
+
+ glm::vec3 position +
+
Position of contact on the surface of the entity.
+
+ glm::vec3 normal +
+
Normal of contact on the surface of the entity.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1Damping.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1Damping.html new file mode 100644 index 000000000..0c542d798 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1Damping.html @@ -0,0 +1,103 @@ + + + + + cubos::engine::Damping struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1DirectionalLight.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1DirectionalLight.html new file mode 100644 index 000000000..54d45fd54 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1DirectionalLight.html @@ -0,0 +1,128 @@ + + + + + cubos::engine::DirectionalLight struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1FixedDeltaTime.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1FixedDeltaTime.html new file mode 100644 index 000000000..d27c85c7e --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1FixedDeltaTime.html @@ -0,0 +1,103 @@ + + + + + cubos::engine::FixedDeltaTime struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1Force.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1Force.html new file mode 100644 index 000000000..757ffd814 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1Force.html @@ -0,0 +1,104 @@ + + + + + cubos::engine::Force struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1FreeCameraController.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1FreeCameraController.html new file mode 100644 index 000000000..b32f8477a --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1FreeCameraController.html @@ -0,0 +1,151 @@ + + + + + cubos::engine::FreeCameraController struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::FreeCameraController struct + +

+

Component which moves the camera.

+ +
+

Public variables

+
+
+ bool enabled +
+
Whether the controller is enabled. Mouse is only captured when enabled.
+
+ std::string lateral +
+
Action used to move the camera laterally (positive is right).
+
+ std::string vertical +
+
Action used to move the camera vertically (positive is up).
+
+ std::string longitudinal +
+
Action used to move the camera longitudinally (positive is forward).
+
+ float speed +
+
Speed at which the camera moves.
+
+ float sens +
+
Sensitivity of the camera rotation, i.e,, how fast the camera rotates.
+
+ float phi +
+
Inclination of the camera.
+
+ float theta +
+
Azimuth of the camera.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1Gravity.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1Gravity.html new file mode 100644 index 000000000..df2814ed5 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1Gravity.html @@ -0,0 +1,103 @@ + + + + + cubos::engine::Gravity struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1Impulse.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1Impulse.html new file mode 100644 index 000000000..87feff337 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1Impulse.html @@ -0,0 +1,104 @@ + + + + + cubos::engine::Impulse struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1LocalToParent.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1LocalToParent.html new file mode 100644 index 000000000..03d13451e --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1LocalToParent.html @@ -0,0 +1,124 @@ + + + + + cubos::engine::LocalToParent struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::LocalToParent struct + +

+

Component which stores the transformation matrix of an entity, from local to parent space.

+ + +
+

Public variables

+
+
+ glm::mat4 mat +
+
Local to parent space matrix.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1LocalToWorld.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1LocalToWorld.html new file mode 100644 index 000000000..46bd2cdb5 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1LocalToWorld.html @@ -0,0 +1,124 @@ + + + + + cubos::engine::LocalToWorld struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::LocalToWorld struct + +

+

Component which stores the transformation matrix of an entity, from local to world space.

+ + +
+

Public variables

+
+
+ glm::mat4 mat +
+
Local to world space matrix.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1Mass.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1Mass.html new file mode 100644 index 000000000..796c629a0 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1Mass.html @@ -0,0 +1,103 @@ + + + + + cubos::engine::Mass struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1PhysicsBundle.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1PhysicsBundle.html new file mode 100644 index 000000000..1e3c5cfa6 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1PhysicsBundle.html @@ -0,0 +1,103 @@ + + + + + cubos::engine::PhysicsBundle struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1PointLight.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1PointLight.html new file mode 100644 index 000000000..0ae3d1973 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1PointLight.html @@ -0,0 +1,132 @@ + + + + + cubos::engine::PointLight struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1Position.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1Position.html new file mode 100644 index 000000000..3b8d550a2 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1Position.html @@ -0,0 +1,124 @@ + + + + + cubos::engine::Position struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1PreviousPosition.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1PreviousPosition.html new file mode 100644 index 000000000..cf98b733c --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1PreviousPosition.html @@ -0,0 +1,123 @@ + + + + + cubos::engine::PreviousPosition struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1RenderableGrid.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1RenderableGrid.html new file mode 100644 index 000000000..21eb5f29e --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1RenderableGrid.html @@ -0,0 +1,132 @@ + + + + + cubos::engine::RenderableGrid struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::RenderableGrid struct + +

+

Component which makes a voxel grid be rendered by the renderer plugin.

+ + +
+

Public variables

+
+
+ Asset<VoxelGrid> asset +
+
Handle to the grid asset to be rendered.
+
+ glm::vec3 offset +
+
Translation applied to the voxel grid before any other.
+
+ RendererGrid handle +
+
Handle to the uploaded grid - set automatically.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1RendererEnvironment.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1RendererEnvironment.html new file mode 100644 index 000000000..88766f24b --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1RendererEnvironment.html @@ -0,0 +1,127 @@ + + + + + cubos::engine::RendererEnvironment struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1RendererFrame_1_1DrawCmd.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1RendererFrame_1_1DrawCmd.html new file mode 100644 index 000000000..02e39b20d --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1RendererFrame_1_1DrawCmd.html @@ -0,0 +1,131 @@ + + + + + cubos::engine::RendererFrame::DrawCmd struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1Rotation.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1Rotation.html new file mode 100644 index 000000000..eb64a5156 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1Rotation.html @@ -0,0 +1,124 @@ + + + + + cubos::engine::Rotation struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1Scale.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1Scale.html new file mode 100644 index 000000000..2178ca4b6 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1Scale.html @@ -0,0 +1,124 @@ + + + + + cubos::engine::Scale struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1Scene.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1Scene.html new file mode 100644 index 000000000..1bbcab88f --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1Scene.html @@ -0,0 +1,128 @@ + + + + + cubos::engine::Scene struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::Scene struct + +

+

Asset equivalent to ECS blueprints - a bundle of entities and their components.

+ +

Scene assets produce a blueprint when loaded which can be used to spawn them. Entity names in the resulting blueprint follow the format "foo", "import1.bar", "import1.import2.baz", etc.

+
+

Public variables

+
+
+ core::ecs::Blueprint blueprint +
+
Resulting blueprint which contains all the entities of the scene and its imported scenes. If you want to spawn the scene, use this blueprint.
+
+ std::unordered_map<std::string, Asset<Scene>> imports +
+
Handles to other scenes that are imported by this scene, mapped by their import names. Imports of imports ar not included in this map.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1SpotLight.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1SpotLight.html new file mode 100644 index 000000000..732342c49 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1SpotLight.html @@ -0,0 +1,140 @@ + + + + + cubos::engine::SpotLight struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::SpotLight struct + +

+

Component which makes an entity emit a spot light.

+ + +
+

Public variables

+
+
+ glm::vec3 color +
+
Color of the light.
+
+ float intensity +
+
Intensity of the light.
+
+ float range +
+
Range of the light.
+
+ float spotAngle +
+
Angle of the spot light in degrees.
+
+ float innerSpotAngle +
+
Angle of the spot light in degrees.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1Substeps.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1Substeps.html new file mode 100644 index 000000000..1ce0cb1da --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1Substeps.html @@ -0,0 +1,103 @@ + + + + + cubos::engine::Substeps struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1Velocity.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1Velocity.html new file mode 100644 index 000000000..b5cd8f826 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1Velocity.html @@ -0,0 +1,104 @@ + + + + + cubos::engine::Velocity struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1Viewport.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1Viewport.html new file mode 100644 index 000000000..76ff07b0e --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1Viewport.html @@ -0,0 +1,104 @@ + + + + + cubos::engine::Viewport struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::Viewport struct + +

+

Component which defines parameters of a viewport, the actual screen space that will be used by the camera it is attached to. Useful for having multiple camera views shown on screen.

+ +
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1VoxelMaterial.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1VoxelMaterial.html new file mode 100644 index 000000000..96beb4720 --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1VoxelMaterial.html @@ -0,0 +1,170 @@ + + + + + cubos::engine::VoxelMaterial struct | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ cubos::engine::VoxelMaterial struct + +

+

Describes a voxel material.

+ +
+

Public static variables

+
+
+ static const VoxelMaterial Empty +
+
Empty material, used for voxels with index 0.
+
+
+
+

Public functions

+
+
+ auto similarity(const VoxelMaterial& other) const -> float +
+
Compares this material with another and returns a number which indicates how similar they are.
+
+
+
+

Public variables

+
+
+ glm::vec4 color +
+
Color of the material.
+
+
+
+

Function documentation

+
+

+ float cubos::engine::VoxelMaterial::similarity(const VoxelMaterial& other) const +

+

Compares this material with another and returns a number which indicates how similar they are.

+ + + + + + + + + + + + + + + + +
Parameters
otherOther material to compare with.
ReturnsSimilarity between the two materials.
+

The number is in the range [0, 1], where 0 means they are completely different and 1 means they are exactly the same.

+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structcubos_1_1engine_1_1VoxelVertex.html b/docs-preview/pr-1032/structcubos_1_1engine_1_1VoxelVertex.html new file mode 100644 index 000000000..f35e21c2e --- /dev/null +++ b/docs-preview/pr-1032/structcubos_1_1engine_1_1VoxelVertex.html @@ -0,0 +1,131 @@ + + + + + cubos::engine::VoxelVertex struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structtesseratos_1_1AssetSelectedEvent.html b/docs-preview/pr-1032/structtesseratos_1_1AssetSelectedEvent.html new file mode 100644 index 000000000..b1a522a07 --- /dev/null +++ b/docs-preview/pr-1032/structtesseratos_1_1AssetSelectedEvent.html @@ -0,0 +1,123 @@ + + + + + tesseratos::AssetSelectedEvent struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/structtesseratos_1_1EntitySelector.html b/docs-preview/pr-1032/structtesseratos_1_1EntitySelector.html new file mode 100644 index 000000000..5050ebded --- /dev/null +++ b/docs-preview/pr-1032/structtesseratos_1_1EntitySelector.html @@ -0,0 +1,127 @@ + + + + + tesseratos::EntitySelector struct | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/substeps_8hpp.html b/docs-preview/pr-1032/substeps_8hpp.html new file mode 100644 index 000000000..59e15cde1 --- /dev/null +++ b/docs-preview/pr-1032/substeps_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/physics/resources/substeps.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/system_2arguments_2world_8hpp.html b/docs-preview/pr-1032/system_2arguments_2world_8hpp.html new file mode 100644 index 000000000..fa521f3f1 --- /dev/null +++ b/docs-preview/pr-1032/system_2arguments_2world_8hpp.html @@ -0,0 +1,124 @@ + + + + + core/ecs/system/arguments/world.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/system_2fetcher_8hpp.html b/docs-preview/pr-1032/system_2fetcher_8hpp.html new file mode 100644 index 000000000..13f299413 --- /dev/null +++ b/docs-preview/pr-1032/system_2fetcher_8hpp.html @@ -0,0 +1,135 @@ + + + + + core/ecs/system/fetcher.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/ecs/system/fetcher.hpp file +

+

Class cubos::core::ecs::SystemFetcher.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::ecs
+
ECS module.
+
+
+
+

Classes

+
+
+
template<typename T>
+ class cubos::core::ecs::SystemFetcher +
+
Type meant to be specialized which implements for each argument type the necessary logic to extract it from the world.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/system_8hpp.html b/docs-preview/pr-1032/system_8hpp.html new file mode 100644 index 000000000..811cdf7d6 --- /dev/null +++ b/docs-preview/pr-1032/system_8hpp.html @@ -0,0 +1,135 @@ + + + + + core/ecs/system/system.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/tables_8hpp.html b/docs-preview/pr-1032/tables_8hpp.html new file mode 100644 index 000000000..9dcb888b9 --- /dev/null +++ b/docs-preview/pr-1032/tables_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/ecs/table/tables.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/term_8hpp.html b/docs-preview/pr-1032/term_8hpp.html new file mode 100644 index 000000000..7f9b1a341 --- /dev/null +++ b/docs-preview/pr-1032/term_8hpp.html @@ -0,0 +1,158 @@ + + + + + core/ecs/query/term.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/ecs/query/term.hpp file +

+

Struct cubos::core::ecs::QueryTerm.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::ecs
+
ECS module.
+
+
+
+

Classes

+
+
+ struct cubos::core::ecs::QueryTerm +
+
Describes a term in a query.
+
+ struct cubos::core::ecs::QueryTerm::Entity +
+
Stores entity term data.
+
+ struct cubos::core::ecs::QueryTerm::Component +
+
Stores component term data.
+
+ struct cubos::core::ecs::QueryTerm::Relation +
+
Stores relation term data.
+
+
+
+

Enums

+
+
+ enum class Traversal { Random, + Down, + Up } +
+
Possible traversal types for tree relation terms.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/thread__pool_8hpp.html b/docs-preview/pr-1032/thread__pool_8hpp.html new file mode 100644 index 000000000..214e7339b --- /dev/null +++ b/docs-preview/pr-1032/thread__pool_8hpp.html @@ -0,0 +1,132 @@ + + + + + core/thread_pool.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2asset__explorer_2plugin_8hpp.html b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2asset__explorer_2plugin_8hpp.html new file mode 100644 index 000000000..0d923ff1c --- /dev/null +++ b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2asset__explorer_2plugin_8hpp.html @@ -0,0 +1,140 @@ + + + + + tesseratos/asset_explorer/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2collider__gizmos_2plugin_8hpp.html b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2collider__gizmos_2plugin_8hpp.html new file mode 100644 index 000000000..587ba0ed3 --- /dev/null +++ b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2collider__gizmos_2plugin_8hpp.html @@ -0,0 +1,130 @@ + + + + + tesseratos/collider_gizmos/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2debug__camera_2plugin_8hpp.html b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2debug__camera_2plugin_8hpp.html new file mode 100644 index 000000000..7e760f56d --- /dev/null +++ b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2debug__camera_2plugin_8hpp.html @@ -0,0 +1,130 @@ + + + + + tesseratos/debug_camera/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2ecs__statistics_2plugin_8hpp.html b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2ecs__statistics_2plugin_8hpp.html new file mode 100644 index 000000000..56644577b --- /dev/null +++ b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2ecs__statistics_2plugin_8hpp.html @@ -0,0 +1,130 @@ + + + + + tesseratos/ecs_statistics/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2entity__inspector_2plugin_8hpp.html b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2entity__inspector_2plugin_8hpp.html new file mode 100644 index 000000000..5b0d1aaa8 --- /dev/null +++ b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2entity__inspector_2plugin_8hpp.html @@ -0,0 +1,130 @@ + + + + + tesseratos/entity_inspector/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2entity__selector_2plugin_8hpp.html b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2entity__selector_2plugin_8hpp.html new file mode 100644 index 000000000..9ca4b9cd3 --- /dev/null +++ b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2entity__selector_2plugin_8hpp.html @@ -0,0 +1,140 @@ + + + + + tesseratos/entity_selector/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2metrics__panel_2plugin_8hpp.html b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2metrics__panel_2plugin_8hpp.html new file mode 100644 index 000000000..c500335f5 --- /dev/null +++ b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2metrics__panel_2plugin_8hpp.html @@ -0,0 +1,130 @@ + + + + + tesseratos/metrics_panel/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2play__pause_2plugin_8hpp.html b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2play__pause_2plugin_8hpp.html new file mode 100644 index 000000000..62218cad6 --- /dev/null +++ b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2play__pause_2plugin_8hpp.html @@ -0,0 +1,130 @@ + + + + + tesseratos/play_pause/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2plugin_8hpp.html b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2plugin_8hpp.html new file mode 100644 index 000000000..19b5cd87a --- /dev/null +++ b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2plugin_8hpp.html @@ -0,0 +1,130 @@ + + + + + tesseratos/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2scene__editor_2plugin_8hpp.html b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2scene__editor_2plugin_8hpp.html new file mode 100644 index 000000000..bb641eefc --- /dev/null +++ b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2scene__editor_2plugin_8hpp.html @@ -0,0 +1,130 @@ + + + + + tesseratos/scene_editor/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2settings__inspector_2plugin_8hpp.html b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2settings__inspector_2plugin_8hpp.html new file mode 100644 index 000000000..01171d965 --- /dev/null +++ b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2settings__inspector_2plugin_8hpp.html @@ -0,0 +1,130 @@ + + + + + tesseratos/settings_inspector/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2toolbox_2plugin_8hpp.html b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2toolbox_2plugin_8hpp.html new file mode 100644 index 000000000..49d404f8a --- /dev/null +++ b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2toolbox_2plugin_8hpp.html @@ -0,0 +1,140 @@ + + + + + tesseratos/toolbox/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2transform__gizmo_2plugin_8hpp.html b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2transform__gizmo_2plugin_8hpp.html new file mode 100644 index 000000000..29e6914f4 --- /dev/null +++ b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2transform__gizmo_2plugin_8hpp.html @@ -0,0 +1,130 @@ + + + + + tesseratos/transform_gizmo/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2voxel__palette__editor_2plugin_8hpp.html b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2voxel__palette__editor_2plugin_8hpp.html new file mode 100644 index 000000000..02321de3a --- /dev/null +++ b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2voxel__palette__editor_2plugin_8hpp.html @@ -0,0 +1,130 @@ + + + + + tesseratos/voxel_palette_editor/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2world__inspector_2plugin_8hpp.html b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2world__inspector_2plugin_8hpp.html new file mode 100644 index 000000000..9c699d89d --- /dev/null +++ b/docs-preview/pr-1032/tools_2tesseratos_2include_2tesseratos_2world__inspector_2plugin_8hpp.html @@ -0,0 +1,130 @@ + + + + + tesseratos/world_inspector/plugin.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/type_8hpp.html b/docs-preview/pr-1032/type_8hpp.html new file mode 100644 index 000000000..4ebbdd321 --- /dev/null +++ b/docs-preview/pr-1032/type_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/reflection/type.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/type__map_8hpp.html b/docs-preview/pr-1032/type__map_8hpp.html new file mode 100644 index 000000000..7c4fede93 --- /dev/null +++ b/docs-preview/pr-1032/type__map_8hpp.html @@ -0,0 +1,135 @@ + + + + + core/memory/type_map.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/type__registry_8hpp.html b/docs-preview/pr-1032/type__registry_8hpp.html new file mode 100644 index 000000000..64aa6c237 --- /dev/null +++ b/docs-preview/pr-1032/type__registry_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/reflection/type_registry.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/types_8hpp.html b/docs-preview/pr-1032/types_8hpp.html new file mode 100644 index 000000000..99aa2a1cb --- /dev/null +++ b/docs-preview/pr-1032/types_8hpp.html @@ -0,0 +1,142 @@ + + + + + core/ecs/types.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/ecs/types.hpp file +

+

Class cubos::core::ecs::Types.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::ecs
+
ECS module.
+
+
+
+

Classes

+
+
+ struct cubos::core::ecs::DataTypeId +
+
Identifies a data type registered in the world.
+
+ struct cubos::core::ecs::DataTypeIdHash +
+
Hash functor for DataTypeId.
+
+ class cubos::core::ecs::Types +
+
Registry of all data types used in an ECS world.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/unordered__bimap_8hpp.html b/docs-preview/pr-1032/unordered__bimap_8hpp.html new file mode 100644 index 000000000..88d4c4339 --- /dev/null +++ b/docs-preview/pr-1032/unordered__bimap_8hpp.html @@ -0,0 +1,135 @@ + + + + + core/memory/unordered_bimap.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/memory/unordered_bimap.hpp file +

+

Class cubos::core::memory::UnorderedBimap.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::memory
+
Memory module.
+
+
+
+

Classes

+
+
+
template<typename L, typename R, typename LHash = std::hash<L>, typename RHash = std::hash<R>>
+ class cubos::core::memory::UnorderedBimap +
+
A bidirectional hash table.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/unordered__map_8hpp.html b/docs-preview/pr-1032/unordered__map_8hpp.html new file mode 100644 index 000000000..8524b16f1 --- /dev/null +++ b/docs-preview/pr-1032/unordered__map_8hpp.html @@ -0,0 +1,102 @@ + + + + + core/reflection/external/unordered_map.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/reflection/external/unordered_map.hpp file +

+

Reflection declaration for std::unordered_map.

+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/util_8hpp.html b/docs-preview/pr-1032/util_8hpp.html new file mode 100644 index 000000000..a2e8ee8ec --- /dev/null +++ b/docs-preview/pr-1032/util_8hpp.html @@ -0,0 +1,136 @@ + + + + + core/gl/util.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/gl/util.hpp file +

+

Function cubos::core::gl::generateScreenQuad.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::gl
+
Graphics module.
+
+
+
+

Functions

+
+
+ void generateScreenQuad(RenderDevice& renderDevice, + const ShaderPipeline& pipeline, + VertexArray& va) +
+
Creates the resources required to draw a quad that fills the screen and returns its VertexArray.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/uuid_8hpp.html b/docs-preview/pr-1032/uuid_8hpp.html new file mode 100644 index 000000000..1e9d4658d --- /dev/null +++ b/docs-preview/pr-1032/uuid_8hpp.html @@ -0,0 +1,102 @@ + + + + + core/reflection/external/uuid.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/vector_8hpp.html b/docs-preview/pr-1032/vector_8hpp.html new file mode 100644 index 000000000..8638a4f9d --- /dev/null +++ b/docs-preview/pr-1032/vector_8hpp.html @@ -0,0 +1,102 @@ + + + + + core/reflection/external/vector.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/velocity_8hpp.html b/docs-preview/pr-1032/velocity_8hpp.html new file mode 100644 index 000000000..864200066 --- /dev/null +++ b/docs-preview/pr-1032/velocity_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/physics/components/velocity.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/vertex_8hpp.html b/docs-preview/pr-1032/vertex_8hpp.html new file mode 100644 index 000000000..b867dad55 --- /dev/null +++ b/docs-preview/pr-1032/vertex_8hpp.html @@ -0,0 +1,148 @@ + + + + + engine/renderer/vertex.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ engine/renderer/vertex.hpp file +

+

Class cubos::engine::VoxelVertex and function cubos::engine::triangulate.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::engine
+
Engine module.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::data
+
Data module.
+
+
+
+

Classes

+
+
+ struct cubos::engine::VoxelVertex +
+
Represents a voxel vertex.
+
+
+
+

Functions

+
+
+ void triangulate(const VoxelGrid& grid, + std::vector<VoxelVertex>& vertices, + std::vector<uint32_t>& indices) +
+
Triangulates a grid of voxels into an indexed mesh.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/viewport_8hpp.html b/docs-preview/pr-1032/viewport_8hpp.html new file mode 100644 index 000000000..38f1d0cea --- /dev/null +++ b/docs-preview/pr-1032/viewport_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/renderer/viewport.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ engine/renderer/viewport.hpp file +

+

Component cubos::engine::Viewport.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::engine
+
Engine module.
+
+
+
+

Classes

+
+
+ struct cubos::engine::Viewport +
+
Component which defines parameters of a viewport, the actual screen space that will be used by the camera it is attached to. Useful for having multiple camera views shown on screen.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/voxels_output.png b/docs-preview/pr-1032/voxels_output.png new file mode 100644 index 0000000000000000000000000000000000000000..73a8bd9a3e8f499644a5351076b8c3b312463b5b GIT binary patch literal 6828 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 + + + + core/io/window.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/io/window.hpp file +

+

Class cubos::core::io::Window and related types.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::gl
+
Graphics module.
+
namespace cubos::core::io
+
Input and output module.
+
+
+
+

Classes

+
+
+ struct cubos::core::io::KeyEvent +
+
Event sent when a key is pressed or released.
+
+ struct cubos::core::io::ModifiersEvent +
+
Event sent when the modifiers change.
+
+ struct cubos::core::io::MouseButtonEvent +
+
Event sent when a mouse button state changes.
+
+ struct cubos::core::io::MouseMoveEvent +
+
Event sent when the mouse cursor moves.
+
+ struct cubos::core::io::MouseScrollEvent +
+
Event sent when the mouse wheel is scrolled.
+
+ struct cubos::core::io::ResizeEvent +
+
Event sent when the window framebuffer is resized.
+
+ struct cubos::core::io::TextEvent +
+
Event sent when a unicode character is input.
+
+ struct cubos::core::io::GamepadConnectionEvent +
+
Event sent when a gamepad is connected or disconnected.
+
+ class cubos::core::io::BaseWindow +
+
Interface used to wrap low-level window API implementations.
+
+
+
+

Enums

+
+
+ enum class MouseButton { Invalid = -1, + Left, + Right, + Middle, + Extra1, + Extra2 } +
+
Mouse buttons enum.
+
+ enum class MouseAxis { X, + Y, + Scroll } +
+
Mouse axes enums.
+
+ enum class MouseState { Default, + Locked, + Hidden } +
+
Possible mouse states.
+
+
+
+

Typedefs

+
+
+ using WindowEvent = std::variant<KeyEvent, ModifiersEvent, MouseButtonEvent, MouseMoveEvent, MouseScrollEvent, ResizeEvent, TextEvent, GamepadConnectionEvent> +
+
Variant that can hold any of the window events.
+
+ using Window = std::shared_ptr<BaseWindow> +
+
Handle to a window.
+
+
+
+

Functions

+
+
+ auto openWindow(const std::string& title = "CUBOS.", + const glm::ivec2& size = {800, 600}) -> Window +
+
Opens a new window.
+
+ auto mouseButtonToString(MouseButton button) -> std::string +
+
Converts a MouseButton enum to a string.
+
+ auto stringToMouseButton(const std::string& str) -> MouseButton +
+
Convert a string to a MouseButton enum.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/world_8hpp.html b/docs-preview/pr-1032/world_8hpp.html new file mode 100644 index 000000000..f8d0dd9ac --- /dev/null +++ b/docs-preview/pr-1032/world_8hpp.html @@ -0,0 +1,150 @@ + + + + + core/ecs/world.hpp file | CUBOS. Docs + + + + + + + +
+
+
+
+
+

+ core/ecs/world.hpp file +

+

Class cubos::core::ecs::World.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::ecs
+
ECS module.
+
+
+
+

Classes

+
+
+ class cubos::core::ecs::World +
+
Holds entities, their components and resources.
+
+ struct cubos::core::ecs::World::Components::Iterator::Component +
+
Output structure for the iterator.
+
+ struct cubos::core::ecs::World::ConstComponents::Iterator::Component +
+
Output structure for the iterator.
+
+ struct cubos::core::ecs::World::Relations::Iterator::Relation +
+
Output structure for the iterator.
+
+ struct cubos::core::ecs::World::ConstRelations::Iterator::Relation +
+
Output structure for the iterator.
+
+
+
+
+
+
+ + + +
+ + diff --git a/docs-preview/pr-1032/writer_8hpp.html b/docs-preview/pr-1032/writer_8hpp.html new file mode 100644 index 000000000..c899d3a82 --- /dev/null +++ b/docs-preview/pr-1032/writer_8hpp.html @@ -0,0 +1,135 @@ + + + + + core/ecs/system/arguments/event/writer.hpp file | CUBOS. Docs + + + + + + + +
+
+ + + +
+ +