From d019c7765bae08a7a94e67c93209775cf342e9b2 Mon Sep 17 00:00:00 2001 From: luishfonseca Date: Mon, 25 Sep 2023 23:10:07 +0000 Subject: [PATCH] =?UTF-8?q?Deploy=20preview=20for=20PR=20589=20?= =?UTF-8?q?=F0=9F=9B=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pr-preview/pr-589/CubosLogo.png | Bin 0 -> 18999 bytes pr-preview/pr-589/aabb_8hpp.html | 134 + pr-preview/pr-589/accessors_8hpp.html | 148 + pr-preview/pr-589/action_8hpp.html | 130 + pr-preview/pr-589/annotated.html | 522 +++ pr-preview/pr-589/archive_8hpp.html | 132 + pr-preview/pr-589/asset_8hpp.html | 139 + pr-preview/pr-589/assets_2bridge_8hpp.html | 130 + pr-preview/pr-589/assets_2plugin_8hpp.html | 130 + pr-preview/pr-589/assets_8hpp.html | 154 + pr-preview/pr-589/audio__device_8hpp.html | 169 + pr-preview/pr-589/axis_8hpp.html | 130 + pr-preview/pr-589/binary_8hpp.html | 131 + pr-preview/pr-589/bindings_8hpp.html | 130 + pr-preview/pr-589/bloom_8hpp.html | 130 + pr-preview/pr-589/blueprint_8hpp.html | 132 + .../pr-589/broad__phase__collisions_8hpp.html | 138 + pr-preview/pr-589/buffer__stream_8hpp.html | 132 + pr-preview/pr-589/camera_8hpp.html | 132 + pr-preview/pr-589/classTextBridge.html | 159 + .../classcubos_1_1core_1_1ThreadPool.html | 181 + ...asscubos_1_1core_1_1al_1_1AudioDevice.html | 290 ++ ...cubos_1_1core_1_1al_1_1impl_1_1Buffer.html | 159 + ...cubos_1_1core_1_1al_1_1impl_1_1Source.html | 377 +++ ...classcubos_1_1core_1_1data_1_1Archive.html | 396 +++ ...1_1core_1_1data_1_1BinaryDeserializer.html | 489 +++ ...s_1_1core_1_1data_1_1BinarySerializer.html | 572 ++++ ...classcubos_1_1core_1_1data_1_1Context.html | 246 ++ ...os_1_1core_1_1data_1_1DebugSerializer.html | 578 ++++ ...cubos_1_1core_1_1data_1_1Deserializer.html | 555 ++++ ...os_1_1core_1_1data_1_1EmbeddedArchive.html | 464 +++ .../classcubos_1_1core_1_1data_1_1File.html | 494 +++ ...sscubos_1_1core_1_1data_1_1FileStream.html | 350 ++ ...sscubos_1_1core_1_1data_1_1FileSystem.html | 325 ++ ...s_1_1core_1_1data_1_1JSONDeserializer.html | 483 +++ ...bos_1_1core_1_1data_1_1JSONSerializer.html | 572 ++++ ...classcubos_1_1core_1_1data_1_1Package.html | 847 +++++ ...s_1_1core_1_1data_1_1SerializationMap.html | 367 +++ ...sscubos_1_1core_1_1data_1_1Serializer.html | 654 ++++ ...os_1_1core_1_1data_1_1StandardArchive.html | 432 +++ ...sscubos_1_1core_1_1data_1_1Unpackager.html | 483 +++ ...s_1_1core_1_1data_1_1impl_1_1Packager.html | 540 +++ ...os_1_1core_1_1ecs_1_1AnySystemWrapper.html | 245 ++ ...lasscubos_1_1core_1_1ecs_1_1Blueprint.html | 330 ++ ...os_1_1core_1_1ecs_1_1BlueprintBuilder.html | 236 ++ ...cubos_1_1core_1_1ecs_1_1CommandBuffer.html | 317 ++ ...classcubos_1_1core_1_1ecs_1_1Commands.html | 314 ++ ...os_1_1core_1_1ecs_1_1ComponentManager.html | 522 +++ ...asscubos_1_1core_1_1ecs_1_1Dispatcher.html | 407 +++ .../classcubos_1_1core_1_1ecs_1_1Entity.html | 196 ++ ...cubos_1_1core_1_1ecs_1_1EntityBuilder.html | 209 ++ ...cubos_1_1core_1_1ecs_1_1EntityManager.html | 378 +++ ...e_1_1ecs_1_1EntityManager_1_1Iterator.html | 101 + ...lasscubos_1_1core_1_1ecs_1_1EventPipe.html | 297 ++ ...sscubos_1_1core_1_1ecs_1_1EventReader.html | 247 ++ ...ore_1_1ecs_1_1EventReader_1_1Iterator.html | 101 + ...sscubos_1_1core_1_1ecs_1_1EventWriter.html | 193 ++ ...classcubos_1_1core_1_1ecs_1_1IStorage.html | 243 ++ ...asscubos_1_1core_1_1ecs_1_1MapStorage.html | 257 ++ ...sscubos_1_1core_1_1ecs_1_1NullStorage.html | 257 ++ .../classcubos_1_1core_1_1ecs_1_1OptRead.html | 225 ++ ...classcubos_1_1core_1_1ecs_1_1OptWrite.html | 226 ++ .../classcubos_1_1core_1_1ecs_1_1Query.html | 272 ++ ...s_1_1core_1_1ecs_1_1Query_1_1Iterator.html | 138 + .../classcubos_1_1core_1_1ecs_1_1Read.html | 205 ++ ...scubos_1_1core_1_1ecs_1_1ReadResource.html | 183 ++ ...sscubos_1_1core_1_1ecs_1_1ReadStorage.html | 183 ++ ...classcubos_1_1core_1_1ecs_1_1Registry.html | 295 ++ ...bos_1_1core_1_1ecs_1_1ResourceManager.html | 222 ++ .../classcubos_1_1core_1_1ecs_1_1Storage.html | 362 ++ ...cubos_1_1core_1_1ecs_1_1SystemWrapper.html | 235 ++ ...asscubos_1_1core_1_1ecs_1_1VecStorage.html | 257 ++ .../classcubos_1_1core_1_1ecs_1_1World.html | 592 ++++ .../classcubos_1_1core_1_1ecs_1_1Write.html | 205 ++ ...cubos_1_1core_1_1ecs_1_1WriteResource.html | 183 ++ ...scubos_1_1core_1_1ecs_1_1WriteStorage.html | 183 ++ .../classcubos_1_1core_1_1gl_1_1Debug.html | 373 +++ .../classcubos_1_1core_1_1gl_1_1Grid.html | 365 ++ .../classcubos_1_1core_1_1gl_1_1Palette.html | 332 ++ ...sscubos_1_1core_1_1gl_1_1RenderDevice.html | 1259 +++++++ ...s_1_1core_1_1gl_1_1impl_1_1BlendState.html | 101 + ...1core_1_1gl_1_1impl_1_1ConstantBuffer.html | 142 + ...ubos_1_1core_1_1gl_1_1impl_1_1CubeMap.html | 181 + ...1_1core_1_1gl_1_1impl_1_1CubeMapArray.html | 187 ++ ...re_1_1gl_1_1impl_1_1DepthStencilState.html | 101 + ..._1_1core_1_1gl_1_1impl_1_1Framebuffer.html | 101 + ..._1_1core_1_1gl_1_1impl_1_1IndexBuffer.html | 142 + ..._1_1core_1_1gl_1_1impl_1_1RasterState.html | 101 + ...ubos_1_1core_1_1gl_1_1impl_1_1Sampler.html | 101 + ...e_1_1gl_1_1impl_1_1ShaderBindingPoint.html | 622 ++++ ...1core_1_1gl_1_1impl_1_1ShaderPipeline.html | 138 + ..._1_1core_1_1gl_1_1impl_1_1ShaderStage.html | 138 + ...os_1_1core_1_1gl_1_1impl_1_1Texture1D.html | 163 + ...os_1_1core_1_1gl_1_1impl_1_1Texture2D.html | 175 + ...1core_1_1gl_1_1impl_1_1Texture2DArray.html | 181 + ...os_1_1core_1_1gl_1_1impl_1_1Texture3D.html | 187 ++ ..._1_1core_1_1gl_1_1impl_1_1VertexArray.html | 101 + ...1_1core_1_1gl_1_1impl_1_1VertexBuffer.html | 142 + ...lasscubos_1_1core_1_1io_1_1BaseWindow.html | 475 +++ .../classcubos_1_1core_1_1io_1_1Cursor.html | 204 ++ ...bos_1_1core_1_1memory_1_1BufferStream.html | 424 +++ ...scubos_1_1core_1_1memory_1_1ReadGuard.html | 261 ++ ...s_1_1core_1_1memory_1_1StandardStream.html | 331 ++ ...lasscubos_1_1core_1_1memory_1_1Stream.html | 1010 ++++++ ...asscubos_1_1core_1_1memory_1_1TypeMap.html | 452 +++ ...cubos_1_1core_1_1memory_1_1WriteGuard.html | 324 ++ ...e_1_1reflection_1_1ConstructibleTrait.html | 458 +++ ...tion_1_1ConstructibleTrait_1_1Builder.html | 215 ++ ...sscubos_1_1core_1_1reflection_1_1Type.html | 328 ++ .../classcubos_1_1engine_1_1AnyAsset.html | 380 +++ .../pr-589/classcubos_1_1engine_1_1Asset.html | 330 ++ .../classcubos_1_1engine_1_1AssetBridge.html | 248 ++ .../classcubos_1_1engine_1_1AssetMeta.html | 242 ++ .../classcubos_1_1engine_1_1Assets.html | 674 ++++ .../classcubos_1_1engine_1_1BaseRenderer.html | 385 +++ .../classcubos_1_1engine_1_1BinaryBridge.html | 257 ++ .../pr-589/classcubos_1_1engine_1_1Cubos.html | 435 +++ ...sscubos_1_1engine_1_1DeferredRenderer.html | 280 ++ .../classcubos_1_1engine_1_1FileBridge.html | 330 ++ .../pr-589/classcubos_1_1engine_1_1Input.html | 442 +++ .../classcubos_1_1engine_1_1InputAction.html | 269 ++ .../classcubos_1_1engine_1_1InputAxis.html | 311 ++ ...classcubos_1_1engine_1_1InputBindings.html | 193 ++ .../classcubos_1_1engine_1_1JSONBridge.html | 258 ++ ...ubos_1_1engine_1_1PostProcessingBloom.html | 391 +++ ...cubos_1_1engine_1_1PostProcessingCopy.html | 219 ++ ...os_1_1engine_1_1PostProcessingManager.html | 294 ++ ...cubos_1_1engine_1_1PostProcessingPass.html | 231 ++ ...classcubos_1_1engine_1_1RendererFrame.html | 408 +++ .../classcubos_1_1engine_1_1SceneBridge.html | 225 ++ .../classcubos_1_1engine_1_1Settings.html | 434 +++ ...classcubos_1_1engine_1_1SystemBuilder.html | 274 ++ .../classcubos_1_1engine_1_1TagBuilder.html | 244 ++ ...bos_1_1engine_1_1impl_1_1RendererGrid.html | 101 + .../pr-589/collisions_2plugin_8hpp.html | 130 + pr-preview/pr-589/commands_8hpp.html | 144 + .../pr-589/component__manager_8hpp.html | 157 + pr-preview/pr-589/constructible_8hpp.html | 137 + .../pr-589/constructible__utils_8hpp.html | 134 + pr-preview/pr-589/contribution.html | 112 + pr-preview/pr-589/copy__pass_8hpp.html | 130 + ...ude_2cubos_2core_2data_2fs_2file_8hpp.html | 132 + ...2include_2cubos_2core_2geom_2box_8hpp.html | 134 + ...lude_2cubos_2core_2geom_2capsule_8hpp.html | 134 + ...nclude_2cubos_2core_2geom_2plane_8hpp.html | 134 + ...lude_2cubos_2core_2geom_2simplex_8hpp.html | 134 + ...ata_2fs_2embedded__archive_2main_8cpp.html | 101 + pr-preview/pr-589/cubos_8hpp.html | 150 + pr-preview/pr-589/cursor_8hpp.html | 132 + pr-preview/pr-589/debug_8hpp.html | 132 + .../pr-589/deferred__renderer_8hpp.html | 130 + .../dir_0835e003fa277f66ce5cf543d578f6a2.html | 134 + .../dir_2a3f20446d92cb0b384d0cf4f4d26d60.html | 118 + .../dir_3733897ca737f1fa8773f329655abd67.html | 118 + .../dir_38e9fb064544086d3594e70a41f6b257.html | 122 + .../dir_3a267dbab794906b09058daa283b3fee.html | 124 + .../dir_459dda10180a6131eb62bc74e02d0b6e.html | 118 + .../dir_5f701044e65d6c264a6c1dc66b1052c2.html | 126 + .../dir_672562f1eb3ea0be7f3aa3e89e72ecd2.html | 124 + .../dir_6c897dd97bedf3914ee8a4d9f7f6549c.html | 144 + .../dir_7376bacbd9e6243f425bd4c56d48edd9.html | 124 + .../dir_73cd920be1d9b25db5feb4d2a202c641.html | 118 + .../dir_764b6913e5a035b506325f3918f13ed7.html | 118 + .../dir_79f402fdd7bbb1d73f9fd1aa85f618da.html | 128 + .../dir_85f1b5bc6fb8e602e74068211760bfae.html | 120 + .../dir_8711f680e2d25dedddc79c2be2b1fda2.html | 120 + .../dir_87a7847ee77970235330560d79c37ce0.html | 140 + .../dir_8b12085945cef5a7cea7b856ed1ac7f6.html | 118 + .../dir_8e5f84d20b1aa89c94160461e78e26c4.html | 126 + .../dir_95549d37735ad5b142799f042eef0d37.html | 118 + .../dir_9b04cf786b414c0d644db09287f665e6.html | 118 + .../dir_9bdaf8f561be1ffd03f616379797b70b.html | 130 + .../dir_b6daa990b896c2c0c53126427e4d978d.html | 152 + .../dir_bafb7af0e03e95b24a45ff63060ab57b.html | 146 + .../dir_bd9be39c2ccf4132268583193b02b48c.html | 122 + .../dir_c185369e92e3603c6d00fa8343148da7.html | 128 + .../dir_c1deef5baf41393ad8a994c3fd53e62f.html | 124 + .../dir_c396301357880712663814927d68a432.html | 118 + .../dir_c4311188e9cc606330f5e3e0b9dd5059.html | 132 + .../dir_d0ac2003a3c19c21d7ab7ff2f06fbec3.html | 118 + .../dir_db86702e1371d7558db3699dd3786a14.html | 130 + .../dir_e42c9d7813efab99826f1cb60398c3fa.html | 118 + .../dir_f4414684a5bb1e1b8e9ba236e8bdb594.html | 130 + .../dir_f556bbe30cd07922836d0e9d7f5fa0a5.html | 122 + .../dir_f6f65ff657bd34b22e5078310628f4e7.html | 118 + .../pr-589/directional__light_8hpp.html | 130 + pr-preview/pr-589/dispatcher_8hpp.html | 132 + pr-preview/pr-589/ecs_8hpp.html | 139 + pr-preview/pr-589/embedded__archive_8hpp.html | 140 + pr-preview/pr-589/endianness_8hpp.html | 157 + ...s_2engine_2assets_2bridges_2file_8hpp.html | 130 + ...gine_2collisions_2colliders_2box_8hpp.html | 130 + ..._2collisions_2colliders_2capsule_8hpp.html | 130 + ...ne_2collisions_2colliders_2plane_8hpp.html | 130 + ..._2collisions_2colliders_2simplex_8hpp.html | 130 + pr-preview/pr-589/entity__manager_8hpp.html | 140 + pr-preview/pr-589/environment_8hpp.html | 130 + pr-preview/pr-589/event__pipe_8hpp.html | 133 + pr-preview/pr-589/event__reader_8hpp.html | 137 + pr-preview/pr-589/event__writer_8hpp.html | 133 + pr-preview/pr-589/examples-core-logging.html | 116 + .../examples-core-reflection-basic.html | 136 + ...-core-reflection-traits-constructible.html | 131 + .../pr-589/examples-core-reflection.html | 103 + pr-preview/pr-589/examples-core.html | 102 + .../pr-589/examples-engine-assets-bridge.html | 146 + .../pr-589/examples-engine-assets-json.html | 135 + .../pr-589/examples-engine-assets-saving.html | 115 + pr-preview/pr-589/examples-engine-assets.html | 103 + pr-preview/pr-589/examples-engine-events.html | 151 + .../pr-589/examples-engine-renderer.html | 150 + pr-preview/pr-589/examples-engine-scene.html | 134 + .../pr-589/examples-engine-settings.html | 112 + pr-preview/pr-589/examples-engine.html | 102 + pr-preview/pr-589/examples.html | 101 + pr-preview/pr-589/favicon-dark.png | Bin 0 -> 380 bytes pr-preview/pr-589/features-ecs.html | 172 + pr-preview/pr-589/features-plugins.html | 142 + pr-preview/pr-589/features-quadrados.html | 121 + pr-preview/pr-589/features.html | 100 + pr-preview/pr-589/file__stream_8hpp.html | 133 + pr-preview/pr-589/file__system_8hpp.html | 132 + pr-preview/pr-589/files.html | 395 +++ pr-preview/pr-589/frame_8hpp.html | 134 + pr-preview/pr-589/gamepad_8hpp.html | 191 ++ pr-preview/pr-589/getting-started.html | 101 + pr-preview/pr-589/grid_8hpp.html | 134 + .../group__asset-explorer-tool-plugin.html | 153 + pr-preview/pr-589/group__assets-plugin.html | 294 ++ .../pr-589/group__collisions-plugin.html | 197 ++ pr-preview/pr-589/group__core-al.html | 151 + pr-preview/pr-589/group__core-data-fs.html | 160 + pr-preview/pr-589/group__core-data.html | 118 + pr-preview/pr-589/group__core-ecs.html | 404 +++ pr-preview/pr-589/group__core-geom.html | 146 + pr-preview/pr-589/group__core-gl.html | 1320 ++++++++ pr-preview/pr-589/group__core-io.html | 753 +++++ pr-preview/pr-589/group__core-memory.html | 460 +++ pr-preview/pr-589/group__core-reflection.html | 419 +++ pr-preview/pr-589/group__core-ui.html | 444 +++ pr-preview/pr-589/group__core.html | 528 +++ pr-preview/pr-589/group__engine.html | 182 + .../group__entity-inspector-tool-plugin.html | 152 + .../group__entity-selector-tool-plugin.html | 152 + pr-preview/pr-589/group__imgui-plugin.html | 153 + pr-preview/pr-589/group__input-plugin.html | 185 ++ pr-preview/pr-589/group__renderer-plugin.html | 316 ++ .../group__scene-editor-tool-plugin.html | 152 + pr-preview/pr-589/group__scene-plugin.html | 170 + ...group__settings-inspector-tool-plugin.html | 152 + pr-preview/pr-589/group__settings-plugin.html | 153 + pr-preview/pr-589/group__tool-plugins.html | 128 + .../pr-589/group__transform-plugin.html | 182 + pr-preview/pr-589/group__voxels-plugin.html | 152 + pr-preview/pr-589/group__window-plugin.html | 156 + .../group__world-inspector-tool-plugin.html | 152 + pr-preview/pr-589/guards_8hpp.html | 138 + pr-preview/pr-589/imgui_2plugin_8hpp.html | 130 + pr-preview/pr-589/imgui_8hpp.html | 148 + pr-preview/pr-589/index.html | 100 + pr-preview/pr-589/input_2plugin_8hpp.html | 130 + pr-preview/pr-589/input_8hpp.html | 130 + pr-preview/pr-589/json_8hpp.html | 131 + pr-preview/pr-589/keyboard_8hpp.html | 261 ++ pr-preview/pr-589/local__to__world_8hpp.html | 130 + pr-preview/pr-589/log_8hpp.html | 214 ++ .../pr-589/m-dark+documentation.compiled.css | 2925 +++++++++++++++++ pr-preview/pr-589/manager_8hpp.html | 142 + pr-preview/pr-589/map__storage_8hpp.html | 133 + pr-preview/pr-589/material_8hpp.html | 134 + pr-preview/pr-589/meta_8hpp.html | 134 + pr-preview/pr-589/modules.html | 160 + pr-preview/pr-589/move_8hpp.html | 144 + pr-preview/pr-589/namespacecubos.html | 120 + pr-preview/pr-589/namespacecubos_1_1core.html | 158 + .../pr-589/namespacecubos_1_1core_1_1al.html | 165 + .../namespacecubos_1_1core_1_1al_1_1impl.html | 124 + .../namespacecubos_1_1core_1_1data.html | 792 +++++ ...amespacecubos_1_1core_1_1data_1_1impl.html | 120 + .../pr-589/namespacecubos_1_1core_1_1ecs.html | 289 ++ ...namespacecubos_1_1core_1_1ecs_1_1impl.html | 137 + .../namespacecubos_1_1core_1_1geom.html | 132 + .../pr-589/namespacecubos_1_1core_1_1gl.html | 520 +++ .../namespacecubos_1_1core_1_1gl_1_1impl.html | 188 ++ .../pr-589/namespacecubos_1_1core_1_1io.html | 386 +++ .../namespacecubos_1_1core_1_1memory.html | 200 ++ .../namespacecubos_1_1core_1_1reflection.html | 145 + .../pr-589/namespacecubos_1_1core_1_1ui.html | 169 + .../pr-589/namespacecubos_1_1engine.html | 399 +++ .../namespacecubos_1_1engine_1_1impl.html | 120 + .../namespacecubos_1_1engine_1_1tools.html | 154 + pr-preview/pr-589/namespaces.html | 161 + pr-preview/pr-589/null__storage_8hpp.html | 133 + pr-preview/pr-589/output.png | Bin 0 -> 118782 bytes pr-preview/pr-589/pages.html | 160 + pr-preview/pr-589/palette_8hpp.html | 134 + pr-preview/pr-589/pass_8hpp.html | 130 + pr-preview/pr-589/point__light_8hpp.html | 130 + pr-preview/pr-589/position_8hpp.html | 130 + pr-preview/pr-589/primitives_8hpp.html | 100 + pr-preview/pr-589/query_8hpp.html | 149 + pr-preview/pr-589/reflect_8hpp.html | 180 + pr-preview/pr-589/registry_8hpp.html | 144 + pr-preview/pr-589/render__device_8hpp.html | 594 ++++ pr-preview/pr-589/renderer_2plugin_8hpp.html | 148 + pr-preview/pr-589/renderer_8hpp.html | 150 + pr-preview/pr-589/resource__manager_8hpp.html | 142 + pr-preview/pr-589/rotation_8hpp.html | 130 + pr-preview/pr-589/scale_8hpp.html | 130 + pr-preview/pr-589/scene_2bridge_8hpp.html | 130 + pr-preview/pr-589/scene_2plugin_8hpp.html | 130 + pr-preview/pr-589/scene_8hpp.html | 130 + pr-preview/pr-589/search-v2.js | 897 +++++ pr-preview/pr-589/searchdata-v2.js | 2 + pr-preview/pr-589/serialization_8hpp.html | 150 + pr-preview/pr-589/settings_2plugin_8hpp.html | 130 + pr-preview/pr-589/settings_8hpp.html | 130 + pr-preview/pr-589/spot__light_8hpp.html | 130 + pr-preview/pr-589/standard__archive_8hpp.html | 132 + pr-preview/pr-589/standard__stream_8hpp.html | 132 + pr-preview/pr-589/storage_8hpp.html | 137 + pr-preview/pr-589/stream_8hpp.html | 144 + pr-preview/pr-589/structColorTrait.html | 101 + pr-preview/pr-589/structIntegerAsset.html | 100 + pr-preview/pr-589/structMyEvent.html | 100 + pr-preview/pr-589/structPerson.html | 100 + pr-preview/pr-589/structPosition.html | 101 + pr-preview/pr-589/structScale.html | 100 + pr-preview/pr-589/structState.html | 100 + pr-preview/pr-589/structStrings.html | 100 + .../structcubos_1_1core_1_1data_1_1Debug.html | 154 + ...re_1_1data_1_1EmbeddedArchive_1_1Data.html | 135 + ...a_1_1EmbeddedArchive_1_1Data_1_1Entry.html | 145 + ...ructcubos_1_1core_1_1data_1_1QBMatrix.html | 128 + ...ructcubos_1_1core_1_1ecs_1_1QueryInfo.html | 125 + ...uctcubos_1_1core_1_1ecs_1_1SystemInfo.html | 197 ++ ...cubos_1_1core_1_1ecs_1_1impl_1_1Index.html | 118 + ..._1core_1_1ecs_1_1impl_1_1QueryFetcher.html | 114 + ...1core_1_1ecs_1_1impl_1_1SystemFetcher.html | 268 ++ ..._1core_1_1ecs_1_1impl_1_1SystemTraits.html | 102 + .../structcubos_1_1core_1_1geom_1_1Box.html | 193 ++ ...tructcubos_1_1core_1_1geom_1_1Capsule.html | 185 ++ .../structcubos_1_1core_1_1geom_1_1Plane.html | 121 + ...tructcubos_1_1core_1_1geom_1_1Simplex.html | 292 ++ ...cubos_1_1core_1_1gl_1_1BlendStateDesc.html | 165 + .../structcubos_1_1core_1_1gl_1_1Camera.html | 141 + ..._1core_1_1gl_1_1ConstantBufferElement.html | 133 + ...core_1_1gl_1_1ConstantBufferStructure.html | 129 + ...bos_1_1core_1_1gl_1_1CubeMapArrayDesc.html | 145 + ...uctcubos_1_1core_1_1gl_1_1CubeMapDesc.html | 141 + ..._1core_1_1gl_1_1DepthStencilStateDesc.html | 139 + ...1gl_1_1DepthStencilStateDesc_1_1Depth.html | 137 + ...l_1_1DepthStencilStateDesc_1_1Stencil.html | 151 + ...thStencilStateDesc_1_1Stencil_1_1Face.html | 133 + ...ubos_1_1core_1_1gl_1_1FramebufferDesc.html | 162 + ...FramebufferDesc_1_1CubeMapArrayTarget.html | 121 + ...l_1_1FramebufferDesc_1_1CubeMapTarget.html | 125 + ...1FramebufferDesc_1_1FramebufferTarget.html | 121 + ...amebufferDesc_1_1Texture2DArrayTarget.html | 121 + ...1_1FramebufferDesc_1_1Texture2DTarget.html | 121 + ...structcubos_1_1core_1_1gl_1_1Material.html | 168 + ...ubos_1_1core_1_1gl_1_1RasterStateDesc.html | 137 + ...uctcubos_1_1core_1_1gl_1_1SamplerDesc.html | 149 + ...tcubos_1_1core_1_1gl_1_1Texture1DDesc.html | 137 + ...s_1_1core_1_1gl_1_1Texture2DArrayDesc.html | 145 + ...tcubos_1_1core_1_1gl_1_1Texture2DDesc.html | 141 + ...tcubos_1_1core_1_1gl_1_1Texture3DDesc.html | 145 + .../structcubos_1_1core_1_1gl_1_1Vertex.html | 129 + ...ubos_1_1core_1_1gl_1_1VertexArrayDesc.html | 133 + ...tcubos_1_1core_1_1gl_1_1VertexElement.html | 145 + ...1core_1_1io_1_1GamepadConnectionEvent.html | 125 + ...ctcubos_1_1core_1_1io_1_1GamepadState.html | 188 ++ ...structcubos_1_1core_1_1io_1_1KeyEvent.html | 125 + ...cubos_1_1core_1_1io_1_1ModifiersEvent.html | 121 + ...bos_1_1core_1_1io_1_1MouseButtonEvent.html | 125 + ...cubos_1_1core_1_1io_1_1MouseMoveEvent.html | 121 + ...bos_1_1core_1_1io_1_1MouseScrollEvent.html | 121 + ...uctcubos_1_1core_1_1io_1_1ResizeEvent.html | 121 + ...tructcubos_1_1core_1_1io_1_1TextEvent.html | 121 + ..._1_1core_1_1memory_1_1RemoveReference.html | 134 + ...ubos_1_1core_1_1reflection_1_1Reflect.html | 114 + ...tructcubos_1_1engine_1_1ActiveCameras.html | 131 + .../structcubos_1_1engine_1_1Arguments.html | 102 + ...bos_1_1engine_1_1AssetMeta_1_1Exclude.html | 121 + .../structcubos_1_1engine_1_1BoxCollider.html | 140 + ...bos_1_1engine_1_1BroadPhaseCollisions.html | 358 ++ ...BroadPhaseCollisions_1_1CandidateHash.html | 101 + ..._1BroadPhaseCollisions_1_1SweepMarker.html | 125 + .../structcubos_1_1engine_1_1Camera.html | 130 + ...uctcubos_1_1engine_1_1CapsuleCollider.html | 126 + ...structcubos_1_1engine_1_1ColliderAABB.html | 278 ++ .../structcubos_1_1engine_1_1DeltaTime.html | 102 + ...ctcubos_1_1engine_1_1DirectionalLight.html | 102 + ...structcubos_1_1engine_1_1LocalToWorld.html | 122 + ...tructcubos_1_1engine_1_1PlaneCollider.html | 140 + .../structcubos_1_1engine_1_1PointLight.html | 102 + .../structcubos_1_1engine_1_1Position.html | 122 + ...ructcubos_1_1engine_1_1RenderableGrid.html | 130 + ...ubos_1_1engine_1_1RendererEnvironment.html | 125 + ...1_1engine_1_1RendererFrame_1_1DrawCmd.html | 125 + .../structcubos_1_1engine_1_1Rotation.html | 122 + .../structcubos_1_1engine_1_1Scale.html | 122 + .../structcubos_1_1engine_1_1Scene.html | 126 + .../structcubos_1_1engine_1_1ShouldQuit.html | 102 + ...uctcubos_1_1engine_1_1SimplexCollider.html | 140 + .../structcubos_1_1engine_1_1SpotLight.html | 102 + ...engine_1_1tools_1_1AssetSelectedEvent.html | 121 + ..._1_1engine_1_1tools_1_1EntitySelector.html | 121 + pr-preview/pr-589/system_8hpp.html | 155 + pr-preview/pr-589/thread__pool_8hpp.html | 130 + .../tools_2asset__explorer_2plugin_8hpp.html | 142 + ...tools_2entity__inspector_2plugin_8hpp.html | 132 + .../tools_2entity__selector_2plugin_8hpp.html | 142 + .../tools_2scene__editor_2plugin_8hpp.html | 132 + ...ols_2settings__inspector_2plugin_8hpp.html | 132 + .../tools_2world__inspector_2plugin_8hpp.html | 132 + pr-preview/pr-589/transform_2plugin_8hpp.html | 130 + pr-preview/pr-589/type_8hpp.html | 132 + pr-preview/pr-589/type__map_8hpp.html | 133 + pr-preview/pr-589/util_8hpp.html | 134 + pr-preview/pr-589/vec__storage_8hpp.html | 133 + pr-preview/pr-589/vertex_8hpp.html | 146 + pr-preview/pr-589/voxels_2plugin_8hpp.html | 130 + pr-preview/pr-589/window_2plugin_8hpp.html | 130 + pr-preview/pr-589/window_8hpp.html | 218 ++ pr-preview/pr-589/world_8hpp.html | 134 + 426 files changed, 88645 insertions(+) create mode 100644 pr-preview/pr-589/CubosLogo.png create mode 100644 pr-preview/pr-589/aabb_8hpp.html create mode 100644 pr-preview/pr-589/accessors_8hpp.html create mode 100644 pr-preview/pr-589/action_8hpp.html create mode 100644 pr-preview/pr-589/annotated.html create mode 100644 pr-preview/pr-589/archive_8hpp.html create mode 100644 pr-preview/pr-589/asset_8hpp.html create mode 100644 pr-preview/pr-589/assets_2bridge_8hpp.html create mode 100644 pr-preview/pr-589/assets_2plugin_8hpp.html create mode 100644 pr-preview/pr-589/assets_8hpp.html create mode 100644 pr-preview/pr-589/audio__device_8hpp.html create mode 100644 pr-preview/pr-589/axis_8hpp.html create mode 100644 pr-preview/pr-589/binary_8hpp.html create mode 100644 pr-preview/pr-589/bindings_8hpp.html create mode 100644 pr-preview/pr-589/bloom_8hpp.html create mode 100644 pr-preview/pr-589/blueprint_8hpp.html create mode 100644 pr-preview/pr-589/broad__phase__collisions_8hpp.html create mode 100644 pr-preview/pr-589/buffer__stream_8hpp.html create mode 100644 pr-preview/pr-589/camera_8hpp.html create mode 100644 pr-preview/pr-589/classTextBridge.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ThreadPool.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1al_1_1AudioDevice.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1al_1_1impl_1_1Buffer.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1al_1_1impl_1_1Source.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Archive.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1data_1_1BinaryDeserializer.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1data_1_1BinarySerializer.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Context.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1data_1_1DebugSerializer.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Deserializer.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1data_1_1EmbeddedArchive.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1data_1_1File.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1data_1_1FileStream.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1data_1_1FileSystem.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1data_1_1JSONDeserializer.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1data_1_1JSONSerializer.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Package.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1data_1_1SerializationMap.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Serializer.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1data_1_1StandardArchive.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Unpackager.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1data_1_1impl_1_1Packager.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1AnySystemWrapper.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Blueprint.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1BlueprintBuilder.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1CommandBuffer.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Commands.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1ComponentManager.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Dispatcher.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Entity.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EntityBuilder.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EntityManager.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EntityManager_1_1Iterator.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EventPipe.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EventReader.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EventReader_1_1Iterator.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EventWriter.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1IStorage.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1MapStorage.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1NullStorage.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1OptRead.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1OptWrite.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Query.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Query_1_1Iterator.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Read.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1ReadResource.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1ReadStorage.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Registry.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1ResourceManager.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Storage.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1SystemWrapper.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1VecStorage.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1World.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Write.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1WriteResource.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1WriteStorage.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1Debug.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1Grid.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1Palette.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1RenderDevice.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1BlendState.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1ConstantBuffer.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1CubeMap.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1CubeMapArray.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1DepthStencilState.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Framebuffer.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1IndexBuffer.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1RasterState.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Sampler.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderBindingPoint.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderPipeline.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderStage.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Texture1D.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Texture2D.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Texture2DArray.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Texture3D.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1VertexArray.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1VertexBuffer.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1io_1_1BaseWindow.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1io_1_1Cursor.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1BufferStream.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1ReadGuard.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1StandardStream.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1Stream.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1TypeMap.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1WriteGuard.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1reflection_1_1ConstructibleTrait.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1reflection_1_1ConstructibleTrait_1_1Builder.html create mode 100644 pr-preview/pr-589/classcubos_1_1core_1_1reflection_1_1Type.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1AnyAsset.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1Asset.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1AssetBridge.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1AssetMeta.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1Assets.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1BaseRenderer.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1BinaryBridge.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1Cubos.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1DeferredRenderer.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1FileBridge.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1Input.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1InputAction.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1InputAxis.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1InputBindings.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1JSONBridge.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1PostProcessingBloom.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1PostProcessingCopy.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1PostProcessingManager.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1PostProcessingPass.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1RendererFrame.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1SceneBridge.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1Settings.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1SystemBuilder.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1TagBuilder.html create mode 100644 pr-preview/pr-589/classcubos_1_1engine_1_1impl_1_1RendererGrid.html create mode 100644 pr-preview/pr-589/collisions_2plugin_8hpp.html create mode 100644 pr-preview/pr-589/commands_8hpp.html create mode 100644 pr-preview/pr-589/component__manager_8hpp.html create mode 100644 pr-preview/pr-589/constructible_8hpp.html create mode 100644 pr-preview/pr-589/constructible__utils_8hpp.html create mode 100644 pr-preview/pr-589/contribution.html create mode 100644 pr-preview/pr-589/copy__pass_8hpp.html create mode 100644 pr-preview/pr-589/core_2include_2cubos_2core_2data_2fs_2file_8hpp.html create mode 100644 pr-preview/pr-589/core_2include_2cubos_2core_2geom_2box_8hpp.html create mode 100644 pr-preview/pr-589/core_2include_2cubos_2core_2geom_2capsule_8hpp.html create mode 100644 pr-preview/pr-589/core_2include_2cubos_2core_2geom_2plane_8hpp.html create mode 100644 pr-preview/pr-589/core_2include_2cubos_2core_2geom_2simplex_8hpp.html create mode 100644 pr-preview/pr-589/core_2samples_2data_2fs_2embedded__archive_2main_8cpp.html create mode 100644 pr-preview/pr-589/cubos_8hpp.html create mode 100644 pr-preview/pr-589/cursor_8hpp.html create mode 100644 pr-preview/pr-589/debug_8hpp.html create mode 100644 pr-preview/pr-589/deferred__renderer_8hpp.html create mode 100644 pr-preview/pr-589/dir_0835e003fa277f66ce5cf543d578f6a2.html create mode 100644 pr-preview/pr-589/dir_2a3f20446d92cb0b384d0cf4f4d26d60.html create mode 100644 pr-preview/pr-589/dir_3733897ca737f1fa8773f329655abd67.html create mode 100644 pr-preview/pr-589/dir_38e9fb064544086d3594e70a41f6b257.html create mode 100644 pr-preview/pr-589/dir_3a267dbab794906b09058daa283b3fee.html create mode 100644 pr-preview/pr-589/dir_459dda10180a6131eb62bc74e02d0b6e.html create mode 100644 pr-preview/pr-589/dir_5f701044e65d6c264a6c1dc66b1052c2.html create mode 100644 pr-preview/pr-589/dir_672562f1eb3ea0be7f3aa3e89e72ecd2.html create mode 100644 pr-preview/pr-589/dir_6c897dd97bedf3914ee8a4d9f7f6549c.html create mode 100644 pr-preview/pr-589/dir_7376bacbd9e6243f425bd4c56d48edd9.html create mode 100644 pr-preview/pr-589/dir_73cd920be1d9b25db5feb4d2a202c641.html create mode 100644 pr-preview/pr-589/dir_764b6913e5a035b506325f3918f13ed7.html create mode 100644 pr-preview/pr-589/dir_79f402fdd7bbb1d73f9fd1aa85f618da.html create mode 100644 pr-preview/pr-589/dir_85f1b5bc6fb8e602e74068211760bfae.html create mode 100644 pr-preview/pr-589/dir_8711f680e2d25dedddc79c2be2b1fda2.html create mode 100644 pr-preview/pr-589/dir_87a7847ee77970235330560d79c37ce0.html create mode 100644 pr-preview/pr-589/dir_8b12085945cef5a7cea7b856ed1ac7f6.html create mode 100644 pr-preview/pr-589/dir_8e5f84d20b1aa89c94160461e78e26c4.html create mode 100644 pr-preview/pr-589/dir_95549d37735ad5b142799f042eef0d37.html create mode 100644 pr-preview/pr-589/dir_9b04cf786b414c0d644db09287f665e6.html create mode 100644 pr-preview/pr-589/dir_9bdaf8f561be1ffd03f616379797b70b.html create mode 100644 pr-preview/pr-589/dir_b6daa990b896c2c0c53126427e4d978d.html create mode 100644 pr-preview/pr-589/dir_bafb7af0e03e95b24a45ff63060ab57b.html create mode 100644 pr-preview/pr-589/dir_bd9be39c2ccf4132268583193b02b48c.html create mode 100644 pr-preview/pr-589/dir_c185369e92e3603c6d00fa8343148da7.html create mode 100644 pr-preview/pr-589/dir_c1deef5baf41393ad8a994c3fd53e62f.html create mode 100644 pr-preview/pr-589/dir_c396301357880712663814927d68a432.html create mode 100644 pr-preview/pr-589/dir_c4311188e9cc606330f5e3e0b9dd5059.html create mode 100644 pr-preview/pr-589/dir_d0ac2003a3c19c21d7ab7ff2f06fbec3.html create mode 100644 pr-preview/pr-589/dir_db86702e1371d7558db3699dd3786a14.html create mode 100644 pr-preview/pr-589/dir_e42c9d7813efab99826f1cb60398c3fa.html create mode 100644 pr-preview/pr-589/dir_f4414684a5bb1e1b8e9ba236e8bdb594.html create mode 100644 pr-preview/pr-589/dir_f556bbe30cd07922836d0e9d7f5fa0a5.html create mode 100644 pr-preview/pr-589/dir_f6f65ff657bd34b22e5078310628f4e7.html create mode 100644 pr-preview/pr-589/directional__light_8hpp.html create mode 100644 pr-preview/pr-589/dispatcher_8hpp.html create mode 100644 pr-preview/pr-589/ecs_8hpp.html create mode 100644 pr-preview/pr-589/embedded__archive_8hpp.html create mode 100644 pr-preview/pr-589/endianness_8hpp.html create mode 100644 pr-preview/pr-589/engine_2include_2cubos_2engine_2assets_2bridges_2file_8hpp.html create mode 100644 pr-preview/pr-589/engine_2include_2cubos_2engine_2collisions_2colliders_2box_8hpp.html create mode 100644 pr-preview/pr-589/engine_2include_2cubos_2engine_2collisions_2colliders_2capsule_8hpp.html create mode 100644 pr-preview/pr-589/engine_2include_2cubos_2engine_2collisions_2colliders_2plane_8hpp.html create mode 100644 pr-preview/pr-589/engine_2include_2cubos_2engine_2collisions_2colliders_2simplex_8hpp.html create mode 100644 pr-preview/pr-589/entity__manager_8hpp.html create mode 100644 pr-preview/pr-589/environment_8hpp.html create mode 100644 pr-preview/pr-589/event__pipe_8hpp.html create mode 100644 pr-preview/pr-589/event__reader_8hpp.html create mode 100644 pr-preview/pr-589/event__writer_8hpp.html create mode 100644 pr-preview/pr-589/examples-core-logging.html create mode 100644 pr-preview/pr-589/examples-core-reflection-basic.html create mode 100644 pr-preview/pr-589/examples-core-reflection-traits-constructible.html create mode 100644 pr-preview/pr-589/examples-core-reflection.html create mode 100644 pr-preview/pr-589/examples-core.html create mode 100644 pr-preview/pr-589/examples-engine-assets-bridge.html create mode 100644 pr-preview/pr-589/examples-engine-assets-json.html create mode 100644 pr-preview/pr-589/examples-engine-assets-saving.html create mode 100644 pr-preview/pr-589/examples-engine-assets.html create mode 100644 pr-preview/pr-589/examples-engine-events.html create mode 100644 pr-preview/pr-589/examples-engine-renderer.html create mode 100644 pr-preview/pr-589/examples-engine-scene.html create mode 100644 pr-preview/pr-589/examples-engine-settings.html create mode 100644 pr-preview/pr-589/examples-engine.html create mode 100644 pr-preview/pr-589/examples.html create mode 100644 pr-preview/pr-589/favicon-dark.png create mode 100644 pr-preview/pr-589/features-ecs.html create mode 100644 pr-preview/pr-589/features-plugins.html create mode 100644 pr-preview/pr-589/features-quadrados.html create mode 100644 pr-preview/pr-589/features.html create mode 100644 pr-preview/pr-589/file__stream_8hpp.html create mode 100644 pr-preview/pr-589/file__system_8hpp.html create mode 100644 pr-preview/pr-589/files.html create mode 100644 pr-preview/pr-589/frame_8hpp.html create mode 100644 pr-preview/pr-589/gamepad_8hpp.html create mode 100644 pr-preview/pr-589/getting-started.html create mode 100644 pr-preview/pr-589/grid_8hpp.html create mode 100644 pr-preview/pr-589/group__asset-explorer-tool-plugin.html create mode 100644 pr-preview/pr-589/group__assets-plugin.html create mode 100644 pr-preview/pr-589/group__collisions-plugin.html create mode 100644 pr-preview/pr-589/group__core-al.html create mode 100644 pr-preview/pr-589/group__core-data-fs.html create mode 100644 pr-preview/pr-589/group__core-data.html create mode 100644 pr-preview/pr-589/group__core-ecs.html create mode 100644 pr-preview/pr-589/group__core-geom.html create mode 100644 pr-preview/pr-589/group__core-gl.html create mode 100644 pr-preview/pr-589/group__core-io.html create mode 100644 pr-preview/pr-589/group__core-memory.html create mode 100644 pr-preview/pr-589/group__core-reflection.html create mode 100644 pr-preview/pr-589/group__core-ui.html create mode 100644 pr-preview/pr-589/group__core.html create mode 100644 pr-preview/pr-589/group__engine.html create mode 100644 pr-preview/pr-589/group__entity-inspector-tool-plugin.html create mode 100644 pr-preview/pr-589/group__entity-selector-tool-plugin.html create mode 100644 pr-preview/pr-589/group__imgui-plugin.html create mode 100644 pr-preview/pr-589/group__input-plugin.html create mode 100644 pr-preview/pr-589/group__renderer-plugin.html create mode 100644 pr-preview/pr-589/group__scene-editor-tool-plugin.html create mode 100644 pr-preview/pr-589/group__scene-plugin.html create mode 100644 pr-preview/pr-589/group__settings-inspector-tool-plugin.html create mode 100644 pr-preview/pr-589/group__settings-plugin.html create mode 100644 pr-preview/pr-589/group__tool-plugins.html create mode 100644 pr-preview/pr-589/group__transform-plugin.html create mode 100644 pr-preview/pr-589/group__voxels-plugin.html create mode 100644 pr-preview/pr-589/group__window-plugin.html create mode 100644 pr-preview/pr-589/group__world-inspector-tool-plugin.html create mode 100644 pr-preview/pr-589/guards_8hpp.html create mode 100644 pr-preview/pr-589/imgui_2plugin_8hpp.html create mode 100644 pr-preview/pr-589/imgui_8hpp.html create mode 100644 pr-preview/pr-589/index.html create mode 100644 pr-preview/pr-589/input_2plugin_8hpp.html create mode 100644 pr-preview/pr-589/input_8hpp.html create mode 100644 pr-preview/pr-589/json_8hpp.html create mode 100644 pr-preview/pr-589/keyboard_8hpp.html create mode 100644 pr-preview/pr-589/local__to__world_8hpp.html create mode 100644 pr-preview/pr-589/log_8hpp.html create mode 100644 pr-preview/pr-589/m-dark+documentation.compiled.css create mode 100644 pr-preview/pr-589/manager_8hpp.html create mode 100644 pr-preview/pr-589/map__storage_8hpp.html create mode 100644 pr-preview/pr-589/material_8hpp.html create mode 100644 pr-preview/pr-589/meta_8hpp.html create mode 100644 pr-preview/pr-589/modules.html create mode 100644 pr-preview/pr-589/move_8hpp.html create mode 100644 pr-preview/pr-589/namespacecubos.html create mode 100644 pr-preview/pr-589/namespacecubos_1_1core.html create mode 100644 pr-preview/pr-589/namespacecubos_1_1core_1_1al.html create mode 100644 pr-preview/pr-589/namespacecubos_1_1core_1_1al_1_1impl.html create mode 100644 pr-preview/pr-589/namespacecubos_1_1core_1_1data.html create mode 100644 pr-preview/pr-589/namespacecubos_1_1core_1_1data_1_1impl.html create mode 100644 pr-preview/pr-589/namespacecubos_1_1core_1_1ecs.html create mode 100644 pr-preview/pr-589/namespacecubos_1_1core_1_1ecs_1_1impl.html create mode 100644 pr-preview/pr-589/namespacecubos_1_1core_1_1geom.html create mode 100644 pr-preview/pr-589/namespacecubos_1_1core_1_1gl.html create mode 100644 pr-preview/pr-589/namespacecubos_1_1core_1_1gl_1_1impl.html create mode 100644 pr-preview/pr-589/namespacecubos_1_1core_1_1io.html create mode 100644 pr-preview/pr-589/namespacecubos_1_1core_1_1memory.html create mode 100644 pr-preview/pr-589/namespacecubos_1_1core_1_1reflection.html create mode 100644 pr-preview/pr-589/namespacecubos_1_1core_1_1ui.html create mode 100644 pr-preview/pr-589/namespacecubos_1_1engine.html create mode 100644 pr-preview/pr-589/namespacecubos_1_1engine_1_1impl.html create mode 100644 pr-preview/pr-589/namespacecubos_1_1engine_1_1tools.html create mode 100644 pr-preview/pr-589/namespaces.html create mode 100644 pr-preview/pr-589/null__storage_8hpp.html create mode 100644 pr-preview/pr-589/output.png create mode 100644 pr-preview/pr-589/pages.html create mode 100644 pr-preview/pr-589/palette_8hpp.html create mode 100644 pr-preview/pr-589/pass_8hpp.html create mode 100644 pr-preview/pr-589/point__light_8hpp.html create mode 100644 pr-preview/pr-589/position_8hpp.html create mode 100644 pr-preview/pr-589/primitives_8hpp.html create mode 100644 pr-preview/pr-589/query_8hpp.html create mode 100644 pr-preview/pr-589/reflect_8hpp.html create mode 100644 pr-preview/pr-589/registry_8hpp.html create mode 100644 pr-preview/pr-589/render__device_8hpp.html create mode 100644 pr-preview/pr-589/renderer_2plugin_8hpp.html create mode 100644 pr-preview/pr-589/renderer_8hpp.html create mode 100644 pr-preview/pr-589/resource__manager_8hpp.html create mode 100644 pr-preview/pr-589/rotation_8hpp.html create mode 100644 pr-preview/pr-589/scale_8hpp.html create mode 100644 pr-preview/pr-589/scene_2bridge_8hpp.html create mode 100644 pr-preview/pr-589/scene_2plugin_8hpp.html create mode 100644 pr-preview/pr-589/scene_8hpp.html create mode 100644 pr-preview/pr-589/search-v2.js create mode 100644 pr-preview/pr-589/searchdata-v2.js create mode 100644 pr-preview/pr-589/serialization_8hpp.html create mode 100644 pr-preview/pr-589/settings_2plugin_8hpp.html create mode 100644 pr-preview/pr-589/settings_8hpp.html create mode 100644 pr-preview/pr-589/spot__light_8hpp.html create mode 100644 pr-preview/pr-589/standard__archive_8hpp.html create mode 100644 pr-preview/pr-589/standard__stream_8hpp.html create mode 100644 pr-preview/pr-589/storage_8hpp.html create mode 100644 pr-preview/pr-589/stream_8hpp.html create mode 100644 pr-preview/pr-589/structColorTrait.html create mode 100644 pr-preview/pr-589/structIntegerAsset.html create mode 100644 pr-preview/pr-589/structMyEvent.html create mode 100644 pr-preview/pr-589/structPerson.html create mode 100644 pr-preview/pr-589/structPosition.html create mode 100644 pr-preview/pr-589/structScale.html create mode 100644 pr-preview/pr-589/structState.html create mode 100644 pr-preview/pr-589/structStrings.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1data_1_1Debug.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1data_1_1EmbeddedArchive_1_1Data.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1data_1_1EmbeddedArchive_1_1Data_1_1Entry.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1data_1_1QBMatrix.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1QueryInfo.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1SystemInfo.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1impl_1_1Index.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1impl_1_1QueryFetcher.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1impl_1_1SystemFetcher.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1impl_1_1SystemTraits.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1geom_1_1Box.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1geom_1_1Capsule.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1geom_1_1Plane.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1geom_1_1Simplex.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1BlendStateDesc.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Camera.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1ConstantBufferElement.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1ConstantBufferStructure.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1CubeMapArrayDesc.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1CubeMapDesc.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Depth.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Stencil.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Stencil_1_1Face.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1CubeMapArrayTarget.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1CubeMapTarget.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1FramebufferTarget.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1Texture2DArrayTarget.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1Texture2DTarget.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Material.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1RasterStateDesc.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1SamplerDesc.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Texture1DDesc.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Texture2DArrayDesc.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Texture2DDesc.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Texture3DDesc.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Vertex.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1VertexArrayDesc.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1VertexElement.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1io_1_1GamepadConnectionEvent.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1io_1_1GamepadState.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1io_1_1KeyEvent.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1io_1_1ModifiersEvent.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1io_1_1MouseButtonEvent.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1io_1_1MouseMoveEvent.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1io_1_1MouseScrollEvent.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1io_1_1ResizeEvent.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1io_1_1TextEvent.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1memory_1_1RemoveReference.html create mode 100644 pr-preview/pr-589/structcubos_1_1core_1_1reflection_1_1Reflect.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1ActiveCameras.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1Arguments.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1AssetMeta_1_1Exclude.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1BoxCollider.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1BroadPhaseCollisions.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1BroadPhaseCollisions_1_1CandidateHash.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1BroadPhaseCollisions_1_1SweepMarker.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1Camera.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1CapsuleCollider.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1ColliderAABB.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1DeltaTime.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1DirectionalLight.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1LocalToWorld.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1PlaneCollider.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1PointLight.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1Position.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1RenderableGrid.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1RendererEnvironment.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1RendererFrame_1_1DrawCmd.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1Rotation.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1Scale.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1Scene.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1ShouldQuit.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1SimplexCollider.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1SpotLight.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1tools_1_1AssetSelectedEvent.html create mode 100644 pr-preview/pr-589/structcubos_1_1engine_1_1tools_1_1EntitySelector.html create mode 100644 pr-preview/pr-589/system_8hpp.html create mode 100644 pr-preview/pr-589/thread__pool_8hpp.html create mode 100644 pr-preview/pr-589/tools_2asset__explorer_2plugin_8hpp.html create mode 100644 pr-preview/pr-589/tools_2entity__inspector_2plugin_8hpp.html create mode 100644 pr-preview/pr-589/tools_2entity__selector_2plugin_8hpp.html create mode 100644 pr-preview/pr-589/tools_2scene__editor_2plugin_8hpp.html create mode 100644 pr-preview/pr-589/tools_2settings__inspector_2plugin_8hpp.html create mode 100644 pr-preview/pr-589/tools_2world__inspector_2plugin_8hpp.html create mode 100644 pr-preview/pr-589/transform_2plugin_8hpp.html create mode 100644 pr-preview/pr-589/type_8hpp.html create mode 100644 pr-preview/pr-589/type__map_8hpp.html create mode 100644 pr-preview/pr-589/util_8hpp.html create mode 100644 pr-preview/pr-589/vec__storage_8hpp.html create mode 100644 pr-preview/pr-589/vertex_8hpp.html create mode 100644 pr-preview/pr-589/voxels_2plugin_8hpp.html create mode 100644 pr-preview/pr-589/window_2plugin_8hpp.html create mode 100644 pr-preview/pr-589/window_8hpp.html create mode 100644 pr-preview/pr-589/world_8hpp.html diff --git a/pr-preview/pr-589/CubosLogo.png b/pr-preview/pr-589/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/pr-preview/pr-589/aabb_8hpp.html b/pr-preview/pr-589/aabb_8hpp.html new file mode 100644 index 000000000..f167f0271 --- /dev/null +++ b/pr-preview/pr-589/aabb_8hpp.html @@ -0,0 +1,134 @@ + + + + + engine/collisions/aabb.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/accessors_8hpp.html b/pr-preview/pr-589/accessors_8hpp.html new file mode 100644 index 000000000..33d292623 --- /dev/null +++ b/pr-preview/pr-589/accessors_8hpp.html @@ -0,0 +1,148 @@ + + + + + core/ecs/accessors.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/ecs/accessors.hpp file +

+

Class cubos::core::ecs::Read 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::Read +
+
System argument which provides read access to the resource T, or query argument which provides read access to the component T.
+
+
template<typename T>
+ class cubos::core::ecs::Write +
+
System argument which provides write access to the resource T, or query argument which provides write access to the component T.
+
+
template<typename T>
+ class cubos::core::ecs::OptRead +
+
System argument which provides read access to the resource T if it exists, or query argument which provides read access to the component T if it exists.
+
+
template<typename T>
+ class cubos::core::ecs::OptWrite +
+
System argument which provides write access to the resource T if it exists, or query argument which provides write access to the component T if it exists.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/action_8hpp.html b/pr-preview/pr-589/action_8hpp.html new file mode 100644 index 000000000..5b630a583 --- /dev/null +++ b/pr-preview/pr-589/action_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/input/action.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/annotated.html b/pr-preview/pr-589/annotated.html new file mode 100644 index 000000000..d25acbf67 --- /dev/null +++ b/pr-preview/pr-589/annotated.html @@ -0,0 +1,522 @@ + + + + + CUBOS. + + + + + + + +
+
+
+
+
+

Classes

+
    +
  • + namespace cubos CUBOS. libraries namespace. +
      + + +
    +
  • +
  • struct ColorTrait [Position definition]
  • +
  • struct IntegerAsset [Asset type]
  • +
  • struct MyEvent [Event struct]
  • +
  • struct Person [Person definition]
  • +
  • struct Position [Person reflection]
  • +
  • struct Scale [Scale declaration]
  • +
  • struct State [Event struct]
  • +
  • struct Strings
  • +
  • class TextBridge
  • +
+ +
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/archive_8hpp.html b/pr-preview/pr-589/archive_8hpp.html new file mode 100644 index 000000000..ed49773aa --- /dev/null +++ b/pr-preview/pr-589/archive_8hpp.html @@ -0,0 +1,132 @@ + + + + + core/data/fs/archive.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/asset_8hpp.html b/pr-preview/pr-589/asset_8hpp.html new file mode 100644 index 000000000..361fa7582 --- /dev/null +++ b/pr-preview/pr-589/asset_8hpp.html @@ -0,0 +1,139 @@ + + + + + engine/assets/asset.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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<typename T>
+ class cubos::engine::Asset +
+
Handle to an asset of a specific type.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/assets_2bridge_8hpp.html b/pr-preview/pr-589/assets_2bridge_8hpp.html new file mode 100644 index 000000000..32733210e --- /dev/null +++ b/pr-preview/pr-589/assets_2bridge_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/assets/bridge.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/assets_2plugin_8hpp.html b/pr-preview/pr-589/assets_2plugin_8hpp.html new file mode 100644 index 000000000..c7016afa3 --- /dev/null +++ b/pr-preview/pr-589/assets_2plugin_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/assets/plugin.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/assets_8hpp.html b/pr-preview/pr-589/assets_8hpp.html new file mode 100644 index 000000000..64b26c639 --- /dev/null +++ b/pr-preview/pr-589/assets_8hpp.html @@ -0,0 +1,154 @@ + + + + + engine/assets/assets.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/audio__device_8hpp.html b/pr-preview/pr-589/audio__device_8hpp.html new file mode 100644 index 000000000..35ef6a93a --- /dev/null +++ b/pr-preview/pr-589/audio__device_8hpp.html @@ -0,0 +1,169 @@ + + + + + core/al/audio_device.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/axis_8hpp.html b/pr-preview/pr-589/axis_8hpp.html new file mode 100644 index 000000000..9bc9907b6 --- /dev/null +++ b/pr-preview/pr-589/axis_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/input/axis.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/binary_8hpp.html b/pr-preview/pr-589/binary_8hpp.html new file mode 100644 index 000000000..6779e5292 --- /dev/null +++ b/pr-preview/pr-589/binary_8hpp.html @@ -0,0 +1,131 @@ + + + + + engine/assets/bridges/binary.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/bindings_8hpp.html b/pr-preview/pr-589/bindings_8hpp.html new file mode 100644 index 000000000..378747964 --- /dev/null +++ b/pr-preview/pr-589/bindings_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/input/bindings.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/bloom_8hpp.html b/pr-preview/pr-589/bloom_8hpp.html new file mode 100644 index 000000000..bc4dc23f4 --- /dev/null +++ b/pr-preview/pr-589/bloom_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/renderer/pps/bloom.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/blueprint_8hpp.html b/pr-preview/pr-589/blueprint_8hpp.html new file mode 100644 index 000000000..a2cf79882 --- /dev/null +++ b/pr-preview/pr-589/blueprint_8hpp.html @@ -0,0 +1,132 @@ + + + + + core/ecs/blueprint.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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 +
+
Stores a bundle of entities and their respective components, which can be easily spawned into a world. This is in a way the 'Prefab' of CUBOS., but lower level.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/broad__phase__collisions_8hpp.html b/pr-preview/pr-589/broad__phase__collisions_8hpp.html new file mode 100644 index 000000000..d4e1974be --- /dev/null +++ b/pr-preview/pr-589/broad__phase__collisions_8hpp.html @@ -0,0 +1,138 @@ + + + + + engine/collisions/broad_phase_collisions.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ engine/collisions/broad_phase_collisions.hpp file +

+

Resource cubos::engine::BroadPhaseCollisions.

+ +
+

Namespaces

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

Classes

+
+
+ struct cubos::engine::BroadPhaseCollisions +
+
Resource which stores data used in broad phase collision detection.
+
+ struct cubos::engine::BroadPhaseCollisions::CandidateHash +
+
Hash function to allow Candidates to be used as keys in an unordered_set.
+
+ struct cubos::engine::BroadPhaseCollisions::SweepMarker +
+
Marker used for sweep and prune.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/buffer__stream_8hpp.html b/pr-preview/pr-589/buffer__stream_8hpp.html new file mode 100644 index 000000000..5a88913d4 --- /dev/null +++ b/pr-preview/pr-589/buffer__stream_8hpp.html @@ -0,0 +1,132 @@ + + + + + core/memory/buffer_stream.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/camera_8hpp.html b/pr-preview/pr-589/camera_8hpp.html new file mode 100644 index 000000000..360ce5242 --- /dev/null +++ b/pr-preview/pr-589/camera_8hpp.html @@ -0,0 +1,132 @@ + + + + + core/gl/camera.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classTextBridge.html b/pr-preview/pr-589/classTextBridge.html new file mode 100644 index 000000000..b56a7923a --- /dev/null +++ b/pr-preview/pr-589/classTextBridge.html @@ -0,0 +1,159 @@ + + + + + TextBridge class | CUBOS. + + + + + + + +
+
+
+
+
+

+ TextBridge class +

+ +

[TextBridge] This bridge inherits from the FileBridge, since it will be loading/saving assets from/to single files.

+
+

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.
+
+
+
+

Public functions

+
+
+ auto loadFromFile(Assets& assets, + const AnyAsset& handle, + Stream& stream) -> bool override +
+
[TextBridge]
+
+ auto saveToFile(const Assets& assets, + const AnyAsset& handle, + Stream& stream) -> bool override +
+
[TextBridge::loadFromFile]
+
+
+
+

Function documentation

+
+

+ bool TextBridge::loadFromFile(Assets& assets, + const AnyAsset& handle, + Stream& stream) override +

+

[TextBridge]

+

[TextBridge::loadFromFile]

+
+
+

+ bool TextBridge::saveToFile(const Assets& assets, + const AnyAsset& handle, + Stream& stream) override +

+

[TextBridge::loadFromFile]

+

[TextBridge::saveToFile]

+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ThreadPool.html b/pr-preview/pr-589/classcubos_1_1core_1_1ThreadPool.html new file mode 100644 index 000000000..8c9dc5c64 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ThreadPool.html @@ -0,0 +1,181 @@ + + + + + cubos::core::ThreadPool class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1al_1_1AudioDevice.html b/pr-preview/pr-589/classcubos_1_1core_1_1al_1_1AudioDevice.html new file mode 100644 index 000000000..f2f287c75 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1al_1_1AudioDevice.html @@ -0,0 +1,290 @@ + + + + + cubos::core::al::AudioDevice class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1al_1_1impl_1_1Buffer.html b/pr-preview/pr-589/classcubos_1_1core_1_1al_1_1impl_1_1Buffer.html new file mode 100644 index 000000000..631f83fda --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1al_1_1impl_1_1Buffer.html @@ -0,0 +1,159 @@ + + + + + cubos::core::al::impl::Buffer class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1al_1_1impl_1_1Source.html b/pr-preview/pr-589/classcubos_1_1core_1_1al_1_1impl_1_1Source.html new file mode 100644 index 000000000..cc30314f4 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1al_1_1impl_1_1Source.html @@ -0,0 +1,377 @@ + + + + + cubos::core::al::impl::Source class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Archive.html b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Archive.html new file mode 100644 index 000000000..0dd525580 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Archive.html @@ -0,0 +1,396 @@ + + + + + cubos::core::data::Archive class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1BinaryDeserializer.html b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1BinaryDeserializer.html new file mode 100644 index 000000000..52a1d8698 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1BinaryDeserializer.html @@ -0,0 +1,489 @@ + + + + + cubos::core::data::BinaryDeserializer class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::data::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::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::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::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::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::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::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::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::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::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::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::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::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::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::BinaryDeserializer::beginObject() override +

+

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

+
+
+

+ void cubos::core::data::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::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::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::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::BinaryDeserializer::endDictionary() override +

+

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

+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1BinarySerializer.html b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1BinarySerializer.html new file mode 100644 index 000000000..27afffb0d --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1BinarySerializer.html @@ -0,0 +1,572 @@ + + + + + cubos::core::data::BinarySerializer class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::data::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Context.html b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Context.html new file mode 100644 index 000000000..9dc13036a --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Context.html @@ -0,0 +1,246 @@ + + + + + cubos::core::data::Context class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::data::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::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::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::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::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::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/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1DebugSerializer.html b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1DebugSerializer.html new file mode 100644 index 000000000..a35066af8 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1DebugSerializer.html @@ -0,0 +1,578 @@ + + + + + cubos::core::data::DebugSerializer class | CUBOS. + + + + + + + +
+
+
+
+
+

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

+ +

Implementation of the abstract Serializer class for debugging purposes. This class is used internally by the logging functions.

+
+

Base classes

+
+
+ class Serializer +
+
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ DebugSerializer(memory::Stream& stream, + bool pretty = false, + bool typeNames = false) +
+
+
+
+
+

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::DebugSerializer::DebugSerializer(memory::Stream& stream, + bool pretty = false, + bool typeNames = false) +

+ + + + + + + + + + + + + + + + + + +
Parameters
streamThe stream to serialize to.
prettyWhether to pretty-print the output.
typeNamesWhether to print the type names.
+
+
+

+ void cubos::core::data::DebugSerializer::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::DebugSerializer::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::DebugSerializer::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::DebugSerializer::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::DebugSerializer::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::DebugSerializer::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::DebugSerializer::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::DebugSerializer::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::DebugSerializer::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::DebugSerializer::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::DebugSerializer::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::DebugSerializer::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::DebugSerializer::beginObject(const char* name) override +

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

Indicates that a object is currently being serialized.

+
+
+

+ void cubos::core::data::DebugSerializer::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::DebugSerializer::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/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Deserializer.html b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Deserializer.html new file mode 100644 index 000000000..71d2b03ca --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Deserializer.html @@ -0,0 +1,555 @@ + + + + + cubos::core::data::Deserializer class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::data::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::deserialize function:

struct MyType
+{
+    int32_t a;
+};
+
+// In the corresponding .cpp file.
+void cubos::core::data::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::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::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::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::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::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::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::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::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::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::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::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::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::Deserializer::read(T& obj) +

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

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

+
+
+

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

+

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

+
+
+

+ void cubos::core::data::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::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::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::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::Deserializer::endDictionary() pure virtual +

+

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

+
+
+

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

+ + + + + + + +
ReturnsThe context of the serializer.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1EmbeddedArchive.html b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1EmbeddedArchive.html new file mode 100644 index 000000000..35f61967e --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1EmbeddedArchive.html @@ -0,0 +1,464 @@ + + + + + cubos::core::data::EmbeddedArchive class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1File.html b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1File.html new file mode 100644 index 000000000..3ed45f214 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1File.html @@ -0,0 +1,494 @@ + + + + + cubos::core::data::File class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1FileStream.html b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1FileStream.html new file mode 100644 index 000000000..c95f83f28 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1FileStream.html @@ -0,0 +1,350 @@ + + + + + cubos::core::data::FileStream class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
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/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1FileSystem.html b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1FileSystem.html new file mode 100644 index 000000000..5e51c9501 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1FileSystem.html @@ -0,0 +1,325 @@ + + + + + cubos::core::data::FileSystem class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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.
+
+
+
+

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.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1JSONDeserializer.html b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1JSONDeserializer.html new file mode 100644 index 000000000..08c981c33 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1JSONDeserializer.html @@ -0,0 +1,483 @@ + + + + + cubos::core::data::JSONDeserializer class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::data::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::JSONDeserializer::JSONDeserializer(const std::string& src) +

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

+ void cubos::core::data::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::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::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::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::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::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::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::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::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::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::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::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::JSONDeserializer::beginObject() override +

+

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

+
+
+

+ void cubos::core::data::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::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::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::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::JSONDeserializer::endDictionary() override +

+

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

+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1JSONSerializer.html b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1JSONSerializer.html new file mode 100644 index 000000000..5e0be7f6f --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1JSONSerializer.html @@ -0,0 +1,572 @@ + + + + + cubos::core::data::JSONSerializer class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::data::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Package.html b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Package.html new file mode 100644 index 000000000..41133312f --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Package.html @@ -0,0 +1,847 @@ + + + + + cubos::core::data::Package class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::data::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::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::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::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::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::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::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::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::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::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::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::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::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::Package::type() const +

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

+ std::size_t cubos::core::data::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::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::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::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::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::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::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::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::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::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::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/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1SerializationMap.html b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1SerializationMap.html new file mode 100644 index 000000000..c6a2df600 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1SerializationMap.html @@ -0,0 +1,367 @@ + + + + + cubos::core::data::SerializationMap class | CUBOS. + + + + + + + +
+
+
+
+
+

+
template<typename R, typename I>
+ cubos::core::data::SerializationMap class final +

+ + + + + + + + + + + + + + +
Template parameters
RReference type.
ISerialized identifier 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> +
+
Returns the internal map that maps references to IDs.
+
+
+
+

Function documentation

+
+

+
+ template<typename R, typename I> +
+ cubos::core::data::SerializationMap<R, I>::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> +
+ void cubos::core::data::SerializationMap<R, I>::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> +
+ bool cubos::core::data::SerializationMap<R, I>::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> +
+ bool cubos::core::data::SerializationMap<R, I>::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> +
+ R cubos::core::data::SerializationMap<R, I>::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> +
+ I cubos::core::data::SerializationMap<R, I>::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> +
+ std::size_t cubos::core::data::SerializationMap<R, I>::size() const +

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

Gets the number of mapped references.

+
+
+

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

+

Returns the internal map that maps references to IDs.

+ + + + + + + +
ReturnsMap of references and Ids.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Serializer.html b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Serializer.html new file mode 100644 index 000000000..9f0347d60 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Serializer.html @@ -0,0 +1,654 @@ + + + + + cubos::core::data::Serializer class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::data::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::serialize function:

struct MyType
+{
+    int32_t a;
+};
+
+// In the corresponding .cpp file.
+void cubos::core::data::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 DebugSerializer +
+
+
+ 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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::serialize function must be implemented for the given type.

+
+
+

+ void cubos::core::data::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::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::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::Serializer::context() +

+ + + + + + + +
ReturnsThe context of the serializer.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1StandardArchive.html b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1StandardArchive.html new file mode 100644 index 000000000..e4ec55298 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1StandardArchive.html @@ -0,0 +1,432 @@ + + + + + cubos::core::data::StandardArchive class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Unpackager.html b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Unpackager.html new file mode 100644 index 000000000..63b660656 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1Unpackager.html @@ -0,0 +1,483 @@ + + + + + cubos::core::data::Unpackager class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::data::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::Unpackager::Unpackager(const Package& pkg) +

+ + + + + + + + + + +
Parameters
pkgThe package to read from.
+
+
+

+ void cubos::core::data::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::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::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::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::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::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::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::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::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::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::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::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::Unpackager::beginObject() override +

+

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

+
+
+

+ void cubos::core::data::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::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::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::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::Unpackager::endDictionary() override +

+

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

+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1impl_1_1Packager.html b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1impl_1_1Packager.html new file mode 100644 index 000000000..2889d38a6 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1data_1_1impl_1_1Packager.html @@ -0,0 +1,540 @@ + + + + + cubos::core::data::impl::Packager class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::data::impl::Packager class +

+ +

Responsible for serializing types into packages. Should never be used directly.

+
+

Base classes

+
+
+ class cubos::core::data::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1AnySystemWrapper.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1AnySystemWrapper.html new file mode 100644 index 000000000..b46dd8c63 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1AnySystemWrapper.html @@ -0,0 +1,245 @@ + + + + + cubos::core::ecs::AnySystemWrapper class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
template<typename R>
+ cubos::core::ecs::AnySystemWrapper class +

+

Base class for system wrappers.

+ + + + + + + + + + +
Template parameters
RReturn type of the wrapped system.
+ +
+

Constructors, destructors, conversion operators

+
+
+ AnySystemWrapper(SystemInfo&& info) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ void prepare(World& world) pure virtual +
+
Prepares the system for being executed on the given world.
+
+ auto call(World& world, + CommandBuffer& commands) -> R pure virtual +
+
Calls the wrapped system with parameters taken from the given world.
+
+ auto info() const -> const SystemInfo& +
+
Gets information about the requirements of the system.
+
+
+
+

Function documentation

+
+

+
+ template<typename R> +
+ cubos::core::ecs::AnySystemWrapper<R>::AnySystemWrapper(SystemInfo&& info) +

+

Constructs.

+ + + + + + + + + + +
Parameters
infoInformation about the wrapped system.
+
+
+

+
+ template<typename R> +
+ void cubos::core::ecs::AnySystemWrapper<R>::prepare(World& world) pure virtual +

+

Prepares the system for being executed on the given world.

+ + + + + + + + + + +
Parameters
worldWorld to prepare the system for.
+

Requires exclusive access to the world and must be called before calling the system.

+
+
+

+
+ template<typename R> +
+ R cubos::core::ecs::AnySystemWrapper<R>::call(World& world, + CommandBuffer& commands) pure virtual +

+

Calls the wrapped system with parameters taken from the given world.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
worldWorld used by the system.
commandsBuffer where commands can be submitted to.
ReturnsReturn value of the system.
+

Can only be called after calling prepare() on the same world.

+
+
+

+
+ template<typename R> +
+ const SystemInfo& cubos::core::ecs::AnySystemWrapper<R>::info() const +

+

Gets information about the requirements of the system.

+ + + + + + + +
ReturnsInformation about the system.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Blueprint.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Blueprint.html new file mode 100644 index 000000000..bcc529cff --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Blueprint.html @@ -0,0 +1,330 @@ + + + + + cubos::core::ecs::Blueprint class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::Blueprint class final + +

+

Stores a bundle of entities and their respective components, which can be easily spawned into a world. This is in a way the 'Prefab' of CUBOS., but lower level.

+ +
+

Constructors, destructors, conversion operators

+
+
+ Blueprint() defaulted +
+
Constructs an empty blueprint.
+
+ Blueprint(Blueprint&&) defaulted +
+
Move constructs.
+
+
+
+

Public functions

+
+
+
template<typename... ComponentTypes>
+ auto create(const std::string& name, + const ComponentTypes&... components) -> Entity +
+
Creates a new entity and returns its identifier.
+
+
template<typename... ComponentTypes>
+ void add(Entity entity, + const ComponentTypes&... components) +
+
Adds components to an entity.
+
+ auto addFromDeserializer(Entity entity, + const std::string& name, + data::Deserializer& deserializer) -> bool +
+
Deserializes a component and adds it to an entity.
+
+ auto entity(const std::string& name) const -> Entity +
+
Returns an entity from its name.
+
+ void merge(const std::string& prefix, + const Blueprint& other) +
+
Merges another blueprint into this one.
+
+ void clear() +
+
Clears the blueprint, removing any added entities and components.
+
+ auto getMap() const -> std::unordered_map<Entity, std::string> +
+
Returns the internal map that maps entities to their names.
+
+
+
+

Function documentation

+
+

+
+ template<typename... ComponentTypes> +
+ Entity cubos::core::ecs::Blueprint::create(const std::string& name, + const ComponentTypes&... components) +

+

Creates a new entity and returns its identifier.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
ComponentTypesComponent types.
Parameters
nameEntity name.
componentsComponents to add.
ReturnsEntity identifier.
+
+
+

+
+ template<typename... ComponentTypes> +
+ void cubos::core::ecs::Blueprint::add(Entity entity, + const ComponentTypes&... components) +

+

Adds components to an entity.

+ + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
ComponentTypesComponent types.
Parameters
entityEntity identifier.
componentsComponents to add.
+
+
+

+ bool cubos::core::ecs::Blueprint::addFromDeserializer(Entity entity, + const std::string& name, + data::Deserializer& deserializer) +

+

Deserializes a component and adds it to an entity.

+ + + + + + + + + + + + + + + + + + +
Parameters
entityEntity identifier.
nameComponent type name.
deserializerDdeserializer to deserialize from.
+
+
+

+ Entity cubos::core::ecs::Blueprint::entity(const std::string& name) const +

+

Returns an entity from its name.

+ + + + + + + + + + + + + + + + +
Parameters
nameEntity name.
ReturnsEntity identifier, or null entity if not found.
+
+
+

+ 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.
otherOther blueprint to merge.
+ +
+
+

+ std::unordered_map<Entity, std::string> cubos::core::ecs::Blueprint::getMap() const +

+

Returns the internal map that maps entities to their names.

+ + + + + + + +
ReturnsMap of entities and names.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1BlueprintBuilder.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1BlueprintBuilder.html new file mode 100644 index 000000000..0f68737c8 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1BlueprintBuilder.html @@ -0,0 +1,236 @@ + + + + + cubos::core::ecs::BlueprintBuilder class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::BlueprintBuilder class final + +

+

Used to edit a blueprint spawned by a Commands object.

+ +
+

Public functions

+
+
+ auto entity(const std::string& name) const -> Entity +
+
Gets an entity of the spawned blueprint.
+
+
template<typename ComponentType>
+ auto get(const std::string& name) -> ComponentType& +
+
Gets a reference to a component of an entity of the spawned blueprint.
+
+
template<typename... ComponentTypes>
+ auto add(const std::string& name, + ComponentTypes && ... components) -> BlueprintBuilder& +
+
Adds components to the blueprint.
+
+
+
+

Function documentation

+
+

+ Entity cubos::core::ecs::BlueprintBuilder::entity(const std::string& name) const +

+

Gets an entity of the spawned blueprint.

+ + + + + + + + + + + + + + + + +
Parameters
nameEntity name.
ReturnsEntity identifier.
+

Aborts if the name does not match any entity of the blueprint.

+
+
+

+
+ template<typename ComponentType> +
+ ComponentType& cubos::core::ecs::BlueprintBuilder::get(const std::string& name) +

+

Gets a reference to a component of an entity of the spawned blueprint.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
ComponentTypeComponent type.
Parameters
nameEntity name.
ReturnsReference to the component.
+

Aborts if name does not match any entity of the blueprint.

+
+
+

+
+ template<typename... ComponentTypes> +
+ BlueprintBuilder& cubos::core::ecs::BlueprintBuilder::add(const std::string& name, + ComponentTypes && ... components) +

+

Adds components to the blueprint.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
ComponentTypesComponent types.
Parameters
nameEntity name.
componentsComponents to add.
ReturnsReference to this builder, for chaining.
+

Aborts if name does not match any entity of the blueprint.

+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1CommandBuffer.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1CommandBuffer.html new file mode 100644 index 000000000..11fd170b2 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1CommandBuffer.html @@ -0,0 +1,317 @@ + + + + + cubos::core::ecs::CommandBuffer class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::CommandBuffer class final + +

+

Stores commands to execute them later.

+ +
+

Constructors, destructors, conversion operators

+
+
+ CommandBuffer(World& world) +
+
Constructs.
+
+
+
+

Public functions

+
+
+
template<typename... ComponentTypes>
+ void add(Entity entity, + ComponentTypes && ... components) +
+
Adds components to an entity.
+
+
template<typename... ComponentTypes>
+ void remove(Entity entity) +
+
Removes components from an entity.
+
+
template<typename... ComponentTypes>
+ auto create(ComponentTypes && ... components) -> EntityBuilder +
+
Creates a new entity with the given components.
+
+ void destroy(Entity entity) +
+
Destroys an entity.
+
+ auto spawn(const Blueprint& blueprint) -> BlueprintBuilder +
+
Spawns a blueprint into the world.
+
+ void abort() +
+
Aborts the commands, rolling back any changes made.
+
+ 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.
+
+
+

+
+ template<typename... ComponentTypes> +
+ void cubos::core::ecs::CommandBuffer::add(Entity entity, + ComponentTypes && ... components) +

+

Adds components to an entity.

+ + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
ComponentTypesComponent types.
Parameters
entityEntity identifier.
componentsComponents to add.
+
+
+

+
+ template<typename... ComponentTypes> +
+ void cubos::core::ecs::CommandBuffer::remove(Entity entity) +

+

Removes components from an entity.

+ + + + + + + + + + + + + + + + + + + +
Template parameters
ComponentTypesComponent types.
Parameters
entityEntity identifier.
+
+
+

+
+ template<typename... ComponentTypes> +
+ EntityBuilder cubos::core::ecs::CommandBuffer::create(ComponentTypes && ... components) +

+

Creates a new entity with the given components.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
ComponentTypesComponent types.
Parameters
componentsComponents to create with.
ReturnsEntity identifier.
+
+
+

+ void cubos::core::ecs::CommandBuffer::destroy(Entity entity) +

+

Destroys an entity.

+ + + + + + + + + + +
Parameters
entityEntity identifier.
+
+
+

+ BlueprintBuilder cubos::core::ecs::CommandBuffer::spawn(const Blueprint& blueprint) +

+

Spawns a blueprint into the world.

+ + + + + + + + + + + + + + + + +
Parameters
blueprintBlueprint to spawn.
ReturnsBlueprint builder.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Commands.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Commands.html new file mode 100644 index 000000000..318e4087a --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Commands.html @@ -0,0 +1,314 @@ + + + + + cubos::core::ecs::Commands class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::Commands class final + +

+

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

+
+
+
template<typename... ComponentTypes>
+ void add(Entity entity, + ComponentTypes && ... components) +
+
Adds components to an entity.
+
+
template<typename... ComponentTypes>
+ void remove(Entity entity) +
+
Removes components from an entity.
+
+
template<typename... ComponentTypes>
+ auto create(ComponentTypes && ... components) -> EntityBuilder +
+
Creates a new entity with the given components.
+
+ void destroy(Entity entity) +
+
Destroys an entity.
+
+ auto spawn(const Blueprint& blueprint) -> BlueprintBuilder +
+
Spawns a blueprint into the world.
+
+
+
+

Function documentation

+
+

+ cubos::core::ecs::Commands::Commands(CommandBuffer& buffer) +

+

Constructs.

+ + + + + + + + + + +
Parameters
bufferCommand buffer to write to.
+
+
+

+
+ template<typename... ComponentTypes> +
+ void cubos::core::ecs::Commands::add(Entity entity, + ComponentTypes && ... components) +

+

Adds components to an entity.

+ + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
ComponentTypesComponent types.
Parameters
entityEntity identifier.
componentsComponents to add.
+
+
+

+
+ template<typename... ComponentTypes> +
+ void cubos::core::ecs::Commands::remove(Entity entity) +

+

Removes components from an entity.

+ + + + + + + + + + + + + + + + + + + +
Template parameters
ComponentTypesComponent types.
Parameters
entityEntity identifier.
+
+
+

+
+ template<typename... ComponentTypes> +
+ EntityBuilder cubos::core::ecs::Commands::create(ComponentTypes && ... components) +

+

Creates a new entity with the given components.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
ComponentTypesComponent types.
Parameters
componentsComponents to create with.
ReturnsEntity identifier.
+
+
+

+ void cubos::core::ecs::Commands::destroy(Entity entity) +

+

Destroys an entity.

+ + + + + + + + + + +
Parameters
entityEntity identifier.
+
+
+

+ BlueprintBuilder cubos::core::ecs::Commands::spawn(const Blueprint& blueprint) +

+

Spawns a blueprint into the world.

+ + + + + + + + + + + + + + + + +
Parameters
blueprintBlueprint to spawn.
ReturnsBlueprint builder.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1ComponentManager.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1ComponentManager.html new file mode 100644 index 000000000..ff9ccb5dc --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1ComponentManager.html @@ -0,0 +1,522 @@ + + + + + cubos::core::ecs::ComponentManager class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::ComponentManager class final + +

+

Holds and manages components.

+ +

Used internally by World.

+
+

Public functions

+
+
+
template<typename T>
+ void registerComponent() +
+
Registers a new component type with the component manager.
+
+ void registerComponent(std::type_index type) +
+
Registers a new component type with the component manager.
+
+ auto getIDFromIndex(std::type_index type) const -> std::size_t +
+
Gets the identifier of a registered component type.
+
+
template<typename T>
+ auto getID() const -> std::size_t +
+
Gets the identifier of a registered component type.
+
+ auto getType(std::size_t id) const -> std::type_index +
+
Gets the type of a component from its identifier.
+
+
template<typename T>
+ auto read() const -> ReadStorage<T> +
+
Locks a storage for reading and returns it.
+
+
template<typename T>
+ auto write() const -> WriteStorage<T> +
+
Locks a storage for writing and returns it.
+
+
template<typename T>
+ void add(uint32_t id, + T value) +
+
Adds a component to an entity.
+
+
template<typename T>
+ void remove(uint32_t id) +
+
Removes a component from an entity.
+
+ void remove(uint32_t id, + std::size_t componentId) +
+
Removes a component from an entity.
+
+ void removeAll(uint32_t id) +
+
Removes all components from an entity.
+
+ auto pack(uint32_t id, + std::size_t componentId, + data::Context* context) const -> data::Package +
+
Creates a package from a component of an entity.
+
+ auto unpack(uint32_t id, + std::size_t componentId, + const data::Package& package, + data::Context* context) -> bool +
+
Inserts a component into an entity, by unpacking a package.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ void cubos::core::ecs::ComponentManager::registerComponent() +

+

Registers a new component type with the component manager.

+ + + + + + + + + + +
Template parameters
TType of the component.
+

Must be called before any component of this type is used in any way.

+
+
+

+ void cubos::core::ecs::ComponentManager::registerComponent(std::type_index type) +

+

Registers a new component type with the component manager.

+ + + + + + + + + + +
Parameters
typeType of the component.
+

Must be called before any component of this type is used in any way.

+
+
+

+ std::size_t cubos::core::ecs::ComponentManager::getIDFromIndex(std::type_index type) const +

+

Gets the identifier of a registered component type.

+ + + + + + + + + + + + + + + + +
Parameters
typeComponent type.
ReturnsComponent identifier.
+
+
+

+
+ template<typename T> +
+ std::size_t cubos::core::ecs::ComponentManager::getID() const +

+

Gets the identifier of a registered component type.

+ + + + + + + + + + + + + + + + +
Template parameters
TComponent type.
ReturnsComponent identifier.
+
+
+

+ std::type_index cubos::core::ecs::ComponentManager::getType(std::size_t id) const +

+

Gets the type of a component from its identifier.

+ + + + + + + + + + + + + + + + +
Parameters
idComponent identifier.
ReturnsComponent type index.
+
+
+

+
+ template<typename T> +
+ ReadStorage<T> cubos::core::ecs::ComponentManager::read() const +

+

Locks a storage for reading and returns it.

+ + + + + + + + + + + + + + + + +
Template parameters
TComponent type.
ReturnsStorage lock.
+
+
+

+
+ template<typename T> +
+ WriteStorage<T> cubos::core::ecs::ComponentManager::write() const +

+

Locks a storage for writing and returns it.

+ + + + + + + + + + + + + + + + +
Template parameters
TComponent type.
ReturnsStorage lock.
+
+
+

+
+ template<typename T> +
+ void cubos::core::ecs::ComponentManager::add(uint32_t id, + T value) +

+

Adds a component to an entity.

+ + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TComponent type.
Parameters
idEntity index.
valueInitial component value.
+
+
+

+
+ template<typename T> +
+ void cubos::core::ecs::ComponentManager::remove(uint32_t id) +

+

Removes a component from an entity.

+ + + + + + + + + + + + + + + + + + + +
Template parameters
TComponent type.
Parameters
idEntity index.
+
+
+

+ void cubos::core::ecs::ComponentManager::remove(uint32_t id, + std::size_t componentId) +

+

Removes a component from an entity.

+ + + + + + + + + + + + + + +
Parameters
idEntity index.
componentIdComponent identifier.
+
+
+

+ void cubos::core::ecs::ComponentManager::removeAll(uint32_t id) +

+

Removes all components from an entity.

+ + + + + + + + + + +
Parameters
idEntity index.
+
+
+

+ data::Package cubos::core::ecs::ComponentManager::pack(uint32_t id, + std::size_t componentId, + data::Context* context) const +

+

Creates a package from a component of an entity.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
idEntity index.
componentIdComponent identifier.
contextOptional context to use for serialization.
ReturnsPackage containing the component.
+
+
+

+ bool cubos::core::ecs::ComponentManager::unpack(uint32_t id, + std::size_t componentId, + const data::Package& package, + data::Context* context) +

+

Inserts a component into an entity, by unpacking a package.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
idEntity index.
componentIdComponent identifier.
packagePackage to unpack.
contextOptional context to use for deserialization.
ReturnsWhether the unpacking was successful.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Dispatcher.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Dispatcher.html new file mode 100644 index 000000000..b74666050 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Dispatcher.html @@ -0,0 +1,407 @@ + + + + + cubos::core::ecs::Dispatcher class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::Dispatcher class + +

+

Used to add systems and relations between them and then dispatch them all at once.

+ +
+

Public functions

+
+
+ void addTag(const std::string& tag) +
+
Adds a tag, and sets it as the current 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.
+
+
template<typename F>
+ void tagAddCondition(F func) +
+
Adds a condition to the current tag.
+
+
template<typename F>
+ void addSystem(F func) +
+
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 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.
+
+
template<typename F>
+ void systemAddCondition(F func) +
+
Adds a condition to the current system.
+
+ void compileChain() +
+
Compiles the call chain. Required before callSystems() can be called.
+
+ void callSystems(World& world, + 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::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.
+
+
+

+
+ template<typename F> +
+ void cubos::core::ecs::Dispatcher::tagAddCondition(F func) +

+

Adds a condition to the current tag.

+ + + + + + + + + + + + + + + + + + + +
Template parameters
FCondition type.
Parameters
funcCondition to add.
+
+
+

+
+ template<typename F> +
+ void cubos::core::ecs::Dispatcher::addSystem(F func) +

+

Adds a system, and sets it as the current system for further configuration.

+ + + + + + + + + + + + + + + + + + + +
Template parameters
FSystem type.
Parameters
funcSystem 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::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.
+
+
+

+
+ template<typename F> +
+ void cubos::core::ecs::Dispatcher::systemAddCondition(F func) +

+

Adds a condition to the current system.

+ + + + + + + + + + + + + + + + + + + +
Template parameters
FCondition type.
Parameters
funcCondition.
+
+
+

+ 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(World& world, + CommandBuffer& cmds) +

+

Calls all systems in the compiled call chain. compileChain() must be called prior to this.

+ + + + + + + + + + + + + + +
Parameters
worldWorld to call the systems in.
cmdsCommand buffer.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Entity.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Entity.html new file mode 100644 index 000000000..441279403 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Entity.html @@ -0,0 +1,196 @@ + + + + + cubos::core::ecs::Entity class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::Entity class + +

+

Identifies an entity.

+ +

When serializing/deserializing, if there's a data::SerializationMap<Entity, std::string> 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(uint32_t index, + uint32_t generation) +
+
Constructs an entity from an index and a generation.
+
+
+
+

Public functions

+
+
+ auto isNull() const -> bool +
+
Checks if the entity is null, a special value returned on errors.
+
+
+
+

Public variables

+
+
+ uint32_t index +
+
Index in storages.
+
+ uint32_t generation +
+
Allows us to detect if the entity has been removed.
+
+
+
+

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.
+
+
+

+ bool cubos::core::ecs::Entity::isNull() const +

+

Checks if the entity is null, a special value returned on errors.

+ + + + + + + +
ReturnsWhether the entity is null.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EntityBuilder.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EntityBuilder.html new file mode 100644 index 000000000..08c0aa2d1 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EntityBuilder.html @@ -0,0 +1,209 @@ + + + + + cubos::core::ecs::EntityBuilder class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::EntityBuilder class final + +

+

Allows editing an entity created by a Commands object.

+ +
+

Public functions

+
+
+ auto entity() const -> Entity +
+
Gets the entity this builder is editing.
+
+
template<typename ComponentType>
+ auto get() -> ComponentType& +
+
Gets a reference to a component of the entity.
+
+
template<typename... ComponentTypes>
+ auto add(ComponentTypes && ... components) -> EntityBuilder& +
+
Adds components to the entity.
+
+
+
+

Function documentation

+
+

+ Entity cubos::core::ecs::EntityBuilder::entity() const +

+

Gets the entity this builder is editing.

+ + + + + + + +
ReturnsEntity identifier.
+
+
+

+
+ template<typename ComponentType> +
+ ComponentType& cubos::core::ecs::EntityBuilder::get() +

+

Gets a reference to a component of the entity.

+ + + + + + + + + + + + + + + + +
Template parameters
ComponentTypeComponent type.
ReturnsReference to the component.
+
+
+

+
+ template<typename... ComponentTypes> +
+ EntityBuilder& cubos::core::ecs::EntityBuilder::add(ComponentTypes && ... components) +

+

Adds components to the entity.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
ComponentTypesComponent types.
Parameters
componentsComponents to add.
ReturnsReference to this builder, for chaining.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EntityManager.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EntityManager.html new file mode 100644 index 000000000..7813cffcf --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EntityManager.html @@ -0,0 +1,378 @@ + + + + + cubos::core::ecs::EntityManager class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::EntityManager class final + +

+

Holds and manages entities and their component masks.

+ +

Used internally by World.

+
+

Public types

+
+
+ class Iterator +
+
Used to iterate over all entities in a manager with a certain component mask.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ EntityManager(std::size_t initialCapacity) +
+
Constructs with a certain initial entity capacity.
+
+
+
+

Public functions

+
+
+ auto create(Entity::Mask mask) -> Entity +
+
Creates a new entity with a certain component mask.
+
+ void destroy(Entity entity) +
+
Removes an entity from the world.
+
+ void setMask(Entity entity, + Entity::Mask mask) +
+
Sets the component mask of an entity.
+
+ auto getMask(Entity entity) const -> const Entity::Mask& +
+
Gets the component mask of an entity.
+
+ auto isValid(Entity entity) const -> bool +
+
Checks if an entity is still valid.
+
+ auto isAlive(Entity entity) const -> bool +
+
Checks if an entity is alive.
+
+ auto begin() const -> Iterator +
+
Returns an iterator over all entities.
+
+ auto withMask(Entity::Mask mask) const -> Iterator +
+
Returns an iterator over all entities with a certain mask of components.
+
+ auto end() const -> Iterator +
+
Returns an iterator which points to the end of the entity manager.
+
+
+
+

Function documentation

+
+

+ cubos::core::ecs::EntityManager::EntityManager(std::size_t initialCapacity) +

+

Constructs with a certain initial entity capacity.

+ + + + + + + + + + +
Parameters
initialCapacityInitial capacity of the entity manager.
+
+
+

+ Entity cubos::core::ecs::EntityManager::create(Entity::Mask mask) +

+

Creates a new entity with a certain component mask.

+ + + + + + + + + + + + + + + + +
Parameters
maskComponent mask of the entity.
ReturnsEntity handle.
+
+
+

+ void cubos::core::ecs::EntityManager::destroy(Entity entity) +

+

Removes an entity from the world.

+ + + + + + + + + + +
Parameters
entityEntity to remove.
+
+
+

+ void cubos::core::ecs::EntityManager::setMask(Entity entity, + Entity::Mask mask) +

+

Sets the component mask of an entity.

+ + + + + + + + + + + + + + +
Parameters
entityEntity to set the mask of.
maskMask to set.
+
+
+

+ const Entity::Mask& cubos::core::ecs::EntityManager::getMask(Entity entity) const +

+

Gets the component mask of an entity.

+ + + + + + + + + + + + + + + + +
Parameters
entityEntity to get the mask of.
ReturnsComponent mask of the entity.
+
+
+

+ bool cubos::core::ecs::EntityManager::isValid(Entity entity) const +

+

Checks if an entity is still valid.

+ + + + + + + + + + + + + + + + +
Parameters
entityEntity to check.
ReturnsWhether the entity is valid.
+

Different from isAlive, as it will return true for entities which still have not been commited.

+
+
+

+ bool cubos::core::ecs::EntityManager::isAlive(Entity entity) const +

+

Checks if an entity is alive.

+ + + + + + + + + + + + + + + + +
Parameters
entityEntity to check.
ReturnsWhether the entity is alive.
+
+
+

+ Iterator cubos::core::ecs::EntityManager::begin() const +

+

Returns an iterator over all entities.

+ + + + + + + +
ReturnsIterator over all entities.
+
+
+

+ Iterator cubos::core::ecs::EntityManager::withMask(Entity::Mask mask) const +

+

Returns an iterator over all entities with a certain mask of components.

+ + + + + + + + + + + + + + + + +
Parameters
maskMask of the components to be iterated.
ReturnsIterator over all entities with the given component mask.
+
+
+

+ Iterator cubos::core::ecs::EntityManager::end() const +

+

Returns an iterator which points to the end of the entity manager.

+ + + + + + + +
ReturnsIterator which points to the end of the entity manager.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EntityManager_1_1Iterator.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EntityManager_1_1Iterator.html new file mode 100644 index 000000000..851430d66 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EntityManager_1_1Iterator.html @@ -0,0 +1,101 @@ + + + + + cubos::core::ecs::EntityManager::Iterator class | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EventPipe.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EventPipe.html new file mode 100644 index 000000000..06c77a1c6 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EventPipe.html @@ -0,0 +1,297 @@ + + + + + cubos::core::ecs::EventPipe class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
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/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EventReader.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EventReader.html new file mode 100644 index 000000000..4a235ec98 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EventReader.html @@ -0,0 +1,247 @@ + + + + + cubos::core::ecs::EventReader class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
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() -> std::optional<std::reference_wrapper<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> +
+ std::optional<std::reference_wrapper<const T>> cubos::core::ecs::EventReader<T, M>::read() +

+

Returns a reference to current event, and advances.

+ + + + + + + +
ReturnsReference to current event, or std::nullopt 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/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EventReader_1_1Iterator.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EventReader_1_1Iterator.html new file mode 100644 index 000000000..d718dda87 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EventReader_1_1Iterator.html @@ -0,0 +1,101 @@ + + + + + cubos::core::ecs::EventReader::Iterator class | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EventWriter.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EventWriter.html new file mode 100644 index 000000000..49e621855 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1EventWriter.html @@ -0,0 +1,193 @@ + + + + + cubos::core::ecs::EventWriter class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
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/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1IStorage.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1IStorage.html new file mode 100644 index 000000000..fcc66bdcd --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1IStorage.html @@ -0,0 +1,243 @@ + + + + + cubos::core::ecs::IStorage class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::IStorage class + +

+

Abstract parent class for all storages.

+ +

Necessary to provide a type-erased interface for erasing and packaging/unpackaging components.

+
+

Derived classes

+
+
+
template<typename T>
+ class Storage +
+
Abstract container for a component type T.
+
+
+
+

Public functions

+
+
+ void erase(uint32_t index) pure virtual +
+
Remove a value from the storage.
+
+ auto pack(uint32_t index, + data::Context* context) const -> data::Package pure virtual +
+
Packages a value. If the value doesn't exist, undefined behavior will occur.
+
+ auto unpack(uint32_t index, + const data::Package& package, + data::Context* context) -> bool pure virtual +
+
Unpackages a value.
+
+ auto type() const -> std::type_index pure virtual +
+
Gets the type the components being stored here.
+
+
+
+

Function documentation

+
+

+ void cubos::core::ecs::IStorage::erase(uint32_t index) pure virtual +

+

Remove a value from the storage.

+ + + + + + + + + + +
Parameters
indexIndex of the value to be removed.
+
+
+

+ data::Package cubos::core::ecs::IStorage::pack(uint32_t index, + data::Context* context) const pure virtual +

+

Packages a value. If the value doesn't exist, undefined behavior will occur.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
indexIndex of the value to package.
contextOptional context used for serialization.
ReturnsPackaged value.
+
+
+

+ bool cubos::core::ecs::IStorage::unpack(uint32_t index, + const data::Package& package, + data::Context* context) pure virtual +

+

Unpackages a value.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
indexIndex of the value to unpackage.
packagePackage to unpackage.
contextOptional context used for deserialization.
ReturnsWhether the unpackaging was successful.
+
+
+

+ std::type_index cubos::core::ecs::IStorage::type() const pure virtual +

+

Gets the type the components being stored here.

+ + + + + + + +
ReturnsComponent type.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1MapStorage.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1MapStorage.html new file mode 100644 index 000000000..58d3068b6 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1MapStorage.html @@ -0,0 +1,257 @@ + + + + + cubos::core::ecs::MapStorage class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::ecs::MapStorage class +

+

Storage implementation that uses an std::unordered_map.

+ + + + + + + + + + +
Template parameters
TComponent type.
+ +
+

Base classes

+
+
+
template<typename T>
+ class Storage<T> +
+
Abstract container for a component type T.
+
+
+
+

Public functions

+
+
+ auto insert(uint32_t index, + T value) -> T* override +
+
Inserts a value into the storage.
+
+ auto get(uint32_t index) -> T* override +
+
Gets a value from the storage.
+
+ auto get(uint32_t index) const -> const T* override +
+
Gets a value from the storage.
+
+ void erase(uint32_t index) override +
+
Remove a value from the storage.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ T* cubos::core::ecs::MapStorage<T>::insert(uint32_t index, + T value) override +

+

Inserts a value into the storage.

+ + + + + + + + + + + + + + +
Parameters
indexIndex where to insert the value.
valueValue to be inserted.
+
+
+

+
+ template<typename T> +
+ T* cubos::core::ecs::MapStorage<T>::get(uint32_t index) override +

+

Gets a value from the storage.

+ + + + + + + + + + + + + + + + +
Parameters
indexIndex of the value to be retrieved.
ReturnsPointer to the value.
+
+
+

+
+ template<typename T> +
+ const T* cubos::core::ecs::MapStorage<T>::get(uint32_t index) const override +

+

Gets a value from the storage.

+ + + + + + + + + + + + + + + + +
Parameters
indexIndex of the value to be retrieved.
ReturnsPointer to the value.
+
+
+

+
+ template<typename T> +
+ void cubos::core::ecs::MapStorage<T>::erase(uint32_t index) override +

+

Remove a value from the storage.

+ + + + + + + + + + +
Parameters
indexIndex of the value to be removed.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1NullStorage.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1NullStorage.html new file mode 100644 index 000000000..24847b043 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1NullStorage.html @@ -0,0 +1,257 @@ + + + + + cubos::core::ecs::NullStorage class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::ecs::NullStorage class +

+

Storage implementation that doesn't keep any data, made for zero-sized components.

+ + + + + + + + + + +
Template parameters
TComponent type.
+ +
+

Base classes

+
+
+
template<typename T>
+ class Storage<T> +
+
Abstract container for a component type T.
+
+
+
+

Public functions

+
+
+ auto insert(uint32_t index, + T value) -> T* override +
+
Inserts a value into the storage.
+
+ auto get(uint32_t index) -> T* override +
+
Gets a value from the storage.
+
+ auto get(uint32_t index) const -> const T* override +
+
Gets a value from the storage.
+
+ void erase(uint32_t index) override +
+
Remove a value from the storage.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ T* cubos::core::ecs::NullStorage<T>::insert(uint32_t index, + T value) override +

+

Inserts a value into the storage.

+ + + + + + + + + + + + + + +
Parameters
indexIndex where to insert the value.
valueValue to be inserted.
+
+
+

+
+ template<typename T> +
+ T* cubos::core::ecs::NullStorage<T>::get(uint32_t index) override +

+

Gets a value from the storage.

+ + + + + + + + + + + + + + + + +
Parameters
indexIndex of the value to be retrieved.
ReturnsPointer to the value.
+
+
+

+
+ template<typename T> +
+ const T* cubos::core::ecs::NullStorage<T>::get(uint32_t index) const override +

+

Gets a value from the storage.

+ + + + + + + + + + + + + + + + +
Parameters
indexIndex of the value to be retrieved.
ReturnsPointer to the value.
+
+
+

+
+ template<typename T> +
+ void cubos::core::ecs::NullStorage<T>::erase(uint32_t index) override +

+

Remove a value from the storage.

+ + + + + + + + + + +
Parameters
indexIndex of the value to be removed.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1OptRead.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1OptRead.html new file mode 100644 index 000000000..d46ab5a22 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1OptRead.html @@ -0,0 +1,225 @@ + + + + + cubos::core::ecs::OptRead class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::ecs::OptRead class +

+

System argument which provides read access to the resource T if it exists, or query argument which provides read access to the component T if it exists.

+ + + + + + + + + + +
Template parameters
TResource or component type.
+ +

While the Read demands that the resource or component exists, this argument does not. Can be used as a pointer with both the -> and * operators.

+
+

Constructors, destructors, conversion operators

+
+
+ OptRead(const T* ptr) +
+
Creates a new optional read argument. ptr should be null if the resource or component does not exist.
+
+ operator bool() const +
+
Checks if the resource or component exists.
+
+
+
+

Public functions

+
+
+ auto operator->() const -> const T* +
+
Accesses the resource or component, aborting if it does not exist.
+
+ auto operator*() const -> const T& +
+
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ cubos::core::ecs::OptRead<T>::OptRead(const T* ptr) +

+

Creates a new optional read argument. ptr should be null if the resource or component does not exist.

+ + + + + + + + + + +
Parameters
ptrPointer to the resource or component.
+
+
+

+
+ template<typename T> +
+ cubos::core::ecs::OptRead<T>::operator bool() const +

+

Checks if the resource or component exists.

+ + + + + + + +
ReturnsWhether the resource or component exists.
+
+
+

+
+ template<typename T> +
+ const T* cubos::core::ecs::OptRead<T>::operator->() const +

+

Accesses the resource or component, aborting if it does not exist.

+ + + + + + + +
ReturnsReference to the resource or component.
+
+
+

+
+ template<typename T> +
+ const T& cubos::core::ecs::OptRead<T>::operator*() const +

+ + + + + + + +
ReturnsReference to the resource or component, aborting if it does not exist.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1OptWrite.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1OptWrite.html new file mode 100644 index 000000000..506214950 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1OptWrite.html @@ -0,0 +1,226 @@ + + + + + cubos::core::ecs::OptWrite class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::ecs::OptWrite class +

+

System argument which provides write access to the resource T if it exists, or query argument which provides write access to the component T if it exists.

+ + + + + + + + + + +
Template parameters
TResource or component type.
+ +

While the Write demands that the resource or component exists, this argument does not. Can be used as a pointer with both the -> and * operators.

+
+

Constructors, destructors, conversion operators

+
+
+ OptWrite(T* ptr) +
+
Creates a new optional write argument. ptr should be null if the resource or component does not exist.
+
+ operator bool() const +
+
Checks if the resource or component exists.
+
+
+
+

Public functions

+
+
+ auto operator->() -> T* +
+
Accesses the resource or component, aborting if it does not exist.
+
+ auto operator*() -> T& +
+
Accesses the resource or component, aborting if it does not exist.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ cubos::core::ecs::OptWrite<T>::OptWrite(T* ptr) +

+

Creates a new optional write argument. ptr should be null if the resource or component does not exist.

+ + + + + + + + + + +
Parameters
ptrPointer to the resource or component.
+
+
+

+
+ template<typename T> +
+ cubos::core::ecs::OptWrite<T>::operator bool() const +

+

Checks if the resource or component exists.

+ + + + + + + +
ReturnsWhether the resource or component exists.
+
+
+

+
+ template<typename T> +
+ T* cubos::core::ecs::OptWrite<T>::operator->() +

+

Accesses the resource or component, aborting if it does not exist.

+ + + + + + + +
ReturnsReference to the resource or component.
+
+
+

+
+ template<typename T> +
+ T& cubos::core::ecs::OptWrite<T>::operator*() +

+

Accesses the resource or component, aborting if it does not exist.

+ + + + + + + +
ReturnsReference to the resource or component.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Query.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Query.html new file mode 100644 index 000000000..45557e019 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Query.html @@ -0,0 +1,272 @@ + + + + + cubos::core::ecs::Query class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
template<typename... ComponentTypes>
+ cubos::core::ecs::Query class +

+

Holds the result of a query over all entities in world which match the given arguments.

+ + + + + + + + + + +
Template parameters
ComponentTypesComponent accessor types to be queried.
+ +

An example of a valid query is:

Query<Write<Position>, Read<Velocity>, OptWrite<Rotation>, OptRead<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, Read/OptRead should be used.

+
+

Public types

+
+
+ class Iterator +
+
Used to iterate over the results of a query.
+
+
+
+

Public static functions

+
+
+ static auto info() -> QueryInfo +
+
Gets information about the query.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ Query(const World& world) +
+
Constructs a query over the given world.
+
+
+
+

Public functions

+
+
+ auto begin() -> Iterator +
+
Gets an iterator to the first entity which matches the query.
+
+ auto end() -> Iterator +
+
Gets an iterator to the end of the query.
+
+ auto operator[](Entity entity) -> std::optional<std::tuple<ComponentTypes...>> +
+
Accesses an entity's components directly, without iterating over the query.
+
+
+
+

Function documentation

+
+

+
+ template<typename... ComponentTypes> +
+ static QueryInfo cubos::core::ecs::Query<ComponentTypes>::info() +

+

Gets information about the query.

+ + + + + + + +
ReturnsQuery information.
+
+
+

+
+ template<typename... ComponentTypes> +
+ cubos::core::ecs::Query<ComponentTypes>::Query(const World& world) +

+

Constructs a query over the given world.

+ + + + + + + + + + +
Parameters
worldWorld to query.
+
+
+

+
+ template<typename... ComponentTypes> +
+ Iterator cubos::core::ecs::Query<ComponentTypes>::begin() +

+

Gets an iterator to the first entity which matches the query.

+ + + + + + + +
ReturnsIterator.
+
+
+

+
+ template<typename... ComponentTypes> +
+ Iterator cubos::core::ecs::Query<ComponentTypes>::end() +

+

Gets an iterator to the end of the query.

+ + + + + + + +
ReturnsIterator.
+
+
+

+
+ template<typename... ComponentTypes> +
+ std::optional<std::tuple<ComponentTypes...>> cubos::core::ecs::Query<ComponentTypes>::operator[](Entity entity) +

+

Accesses an entity's components directly, without iterating over the query.

+ + + + + + + + + + + + + + + + +
Parameters
entityEntity to access.
ReturnsRequested components, or std::nullopt if the entity does not match the query.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Query_1_1Iterator.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Query_1_1Iterator.html new file mode 100644 index 000000000..2980571d7 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Query_1_1Iterator.html @@ -0,0 +1,138 @@ + + + + + cubos::core::ecs::Query::Iterator class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::Query::Iterator class + +

+

Used to iterate over the results of a query.

+ +
+

Public functions

+
+
+ auto operator*() const -> std::tuple<Entity, ComponentTypes...> +
+
Dereferences to a tuple containing the queried entity and its components.
+
+
+
+

Function documentation

+
+

+ std::tuple<Entity, ComponentTypes...> cubos::core::ecs::Query::Iterator::operator*() const +

+

Dereferences to a tuple containing the queried entity and its components.

+ + + + + + + +
ReturnsTuple containing the entity and its components.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Read.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Read.html new file mode 100644 index 000000000..217ca00b7 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Read.html @@ -0,0 +1,205 @@ + + + + + cubos::core::ecs::Read class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::ecs::Read class +

+

System argument which provides read access to the resource T, or query argument which provides read access to the component T.

+ + + + + + + + + + +
Template parameters
TResource or component type.
+ +

Can be used as a pointer with both the -> and * operators.

+
+

Constructors, destructors, conversion operators

+
+
+ Read(const T& ref) +
+
Creates a new read argument.
+
+
+
+

Public functions

+
+
+ auto operator->() const -> const T* +
+
Accesses the resource or component.
+
+ auto operator*() const -> const T& +
+
Accesses the resource or component.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ cubos::core::ecs::Read<T>::Read(const T& ref) +

+

Creates a new read argument.

+ + + + + + + + + + +
Parameters
refReference to the resource or component.
+
+
+

+
+ template<typename T> +
+ const T* cubos::core::ecs::Read<T>::operator->() const +

+

Accesses the resource or component.

+ + + + + + + +
ReturnsPointer to the resource or component.
+
+
+

+
+ template<typename T> +
+ const T& cubos::core::ecs::Read<T>::operator*() const +

+

Accesses the resource or component.

+ + + + + + + +
ReturnsReference to the resource or component.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1ReadResource.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1ReadResource.html new file mode 100644 index 000000000..4f4e86d32 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1ReadResource.html @@ -0,0 +1,183 @@ + + + + + cubos::core::ecs::ReadResource class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
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/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1ReadStorage.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1ReadStorage.html new file mode 100644 index 000000000..6090dc6fa --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1ReadStorage.html @@ -0,0 +1,183 @@ + + + + + cubos::core::ecs::ReadStorage class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::ecs::ReadStorage class +

+

Utility struct used to reference a storage of component type T for reading.

+ + + + + + + + + + +
Template parameters
TComponent type.
+ +
+

Constructors, destructors, conversion operators

+
+
+ ReadStorage(ReadStorage&& other) noexcept +
+
Move constructor.
+
+
+
+

Public functions

+
+
+ auto get() const -> const Storage<T>& +
+
Gets the underlying storage reference.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ cubos::core::ecs::ReadStorage<T>::ReadStorage(ReadStorage&& other) noexcept +

+

Move constructor.

+ + + + + + + + + + +
Parameters
otherOther instance to move from.
+
+
+

+
+ template<typename T> +
+ const Storage<T>& cubos::core::ecs::ReadStorage<T>::get() const +

+

Gets the underlying storage reference.

+ + + + + + + +
ReturnsUnderlying storage reference.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Registry.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Registry.html new file mode 100644 index 000000000..c6f96d5d0 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Registry.html @@ -0,0 +1,295 @@ + + + + + cubos::core::ecs::Registry class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::Registry class final + +

+

Singleton which holds a global registry for all component types.

+ +

It stores information regarding the components so that they can be handled in a type-erased manner.

+
+

Public static functions

+
+
+ static auto create(std::string_view name, + data::Deserializer& des, + Blueprint& blueprint, + Entity id) -> bool +
+
Instantiates a component with the given name from a deserializer into a blueprint.
+
+ static auto createStorage(std::type_index type) -> std::unique_ptr<IStorage> +
+
Instantiates a component storage for the given component type.
+
+
template<typename T, typename S>
+ static void add(std::string_view name) +
+
Registers a new component type.
+
+ static auto name(std::type_index type) -> std::optional<std::string_view> +
+
Gets the name of a component type.
+
+ static auto type(std::string_view name) -> std::optional<std::type_index> +
+
Gets the type index of a component type.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ Registry() deleted +
+
Deleted constructor.
+
+
+
+

Function documentation

+
+

+ static bool cubos::core::ecs::Registry::create(std::string_view name, + data::Deserializer& des, + Blueprint& blueprint, + Entity id) +

+

Instantiates a component with the given name from a deserializer into a blueprint.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
nameName of the component.
desDeserializer to read the component data from.
blueprintBlueprint to instantiate the component into.
idBlueprint entity to add the component to.
ReturnsWhether the instantiation was successful.
+
+
+

+ static std::unique_ptr<IStorage> cubos::core::ecs::Registry::createStorage(std::type_index type) +

+

Instantiates a component storage for the given component type.

+ + + + + + + + + + + + + + + + +
Parameters
typeType index of the component.
ReturnsSmart pointer to the storage, or nullptr if the component type was not found.
+
+
+

+
+ template<typename T, typename S> +
+ static void cubos::core::ecs::Registry::add(std::string_view name) +

+

Registers a new component type.

+ + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TComponent type to register.
SStorage type to use for the component.
Parameters
nameName of the component.
+
+
+

+ static std::optional<std::string_view> cubos::core::ecs::Registry::name(std::type_index type) +

+

Gets the name of a component type.

+ + + + + + + + + + + + + + + + +
Parameters
typeType index of the component.
ReturnsName of the component, or std::nullopt if the component type was not found.
+
+
+

+ static std::optional<std::type_index> cubos::core::ecs::Registry::type(std::string_view name) +

+

Gets the type index of a component type.

+ + + + + + + + + + + + + + + + +
Parameters
nameName of the component.
ReturnsType index of the component, or std::nullopt if the component type was not found.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1ResourceManager.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1ResourceManager.html new file mode 100644 index 000000000..efe14abf0 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1ResourceManager.html @@ -0,0 +1,222 @@ + + + + + cubos::core::ecs::ResourceManager class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Storage.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Storage.html new file mode 100644 index 000000000..70c2a4583 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Storage.html @@ -0,0 +1,362 @@ + + + + + cubos::core::ecs::Storage class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::ecs::Storage class +

+

Abstract container for a component type T.

+ + + + + + + + + + +
Template parameters
TComponent type.
+ +
+

Base classes

+
+
+ class IStorage +
+
Abstract parent class for all storages.
+
+
+
+

Derived classes

+
+
+
template<typename T>
+ class MapStorage +
+
Storage implementation that uses an std::unordered_map.
+
+
template<typename T>
+ class NullStorage +
+
Storage implementation that doesn't keep any data, made for zero-sized components.
+
+
template<typename T>
+ class VecStorage +
+
Storage implementation that uses a std::vector.
+
+
+
+

Public types

+
+
+ using Type = T +
+
Component type.
+
+
+
+

Public functions

+
+
+ auto insert(uint32_t index, + T value) -> T* pure virtual +
+
Inserts a value into the storage.
+
+ auto get(uint32_t index) -> T* pure virtual +
+
Gets a value from the storage.
+
+ auto get(uint32_t index) const -> const T* pure virtual +
+
Gets a value from the storage.
+
+ auto pack(uint32_t index, + data::Context* context) const -> data::Package override +
+
Packages a value. If the value doesn't exist, undefined behavior will occur.
+
+ auto unpack(uint32_t index, + const data::Package& package, + data::Context* context) -> bool override +
+
Unpackages a value.
+
+ auto type() const -> std::type_index override +
+
Gets the type the components being stored here.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ T* cubos::core::ecs::Storage<T>::insert(uint32_t index, + T value) pure virtual +

+

Inserts a value into the storage.

+ + + + + + + + + + + + + + +
Parameters
indexIndex where to insert the value.
valueValue to be inserted.
+
+
+

+
+ template<typename T> +
+ T* cubos::core::ecs::Storage<T>::get(uint32_t index) pure virtual +

+

Gets a value from the storage.

+ + + + + + + + + + + + + + + + +
Parameters
indexIndex of the value to be retrieved.
ReturnsPointer to the value.
+
+
+

+
+ template<typename T> +
+ const T* cubos::core::ecs::Storage<T>::get(uint32_t index) const pure virtual +

+

Gets a value from the storage.

+ + + + + + + + + + + + + + + + +
Parameters
indexIndex of the value to be retrieved.
ReturnsPointer to the value.
+
+
+

+
+ template<typename T> +
+ data::Package cubos::core::ecs::Storage<T>::pack(uint32_t index, + data::Context* context) const override +

+

Packages a value. If the value doesn't exist, undefined behavior will occur.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
indexIndex of the value to package.
contextOptional context used for serialization.
ReturnsPackaged value.
+
+
+

+
+ template<typename T> +
+ bool cubos::core::ecs::Storage<T>::unpack(uint32_t index, + const data::Package& package, + data::Context* context) override +

+

Unpackages a value.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
indexIndex of the value to unpackage.
packagePackage to unpackage.
contextOptional context used for deserialization.
ReturnsWhether the unpackaging was successful.
+
+
+

+
+ template<typename T> +
+ std::type_index cubos::core::ecs::Storage<T>::type() const override +

+

Gets the type the components being stored here.

+ + + + + + + +
ReturnsComponent type.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1SystemWrapper.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1SystemWrapper.html new file mode 100644 index 000000000..9ad613f0b --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1SystemWrapper.html @@ -0,0 +1,235 @@ + + + + + cubos::core::ecs::SystemWrapper class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
template<typename F>
+ cubos::core::ecs::SystemWrapper class final +

+

Wrapper for a system of type F.

+ + + + + + + + + + +
Template parameters
FType of the system function/method/lambda.
+ +
+

Base classes

+
+
+
template<typename R>
+ class AnySystemWrapper<impl::SystemTraits<F>::Return> +
+
Base class for system wrappers.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ SystemWrapper(F system) +
+
Constructs.
+
+
+
+

Public functions

+
+
+ void prepare(World& world) override +
+
Prepares the system for being executed on the given world.
+
+ auto call(World& world, + CommandBuffer& commands) -> impl::SystemTraits<F>::Return override +
+
Calls the wrapped system with parameters taken from the given world.
+
+
+
+

Function documentation

+
+

+
+ template<typename F> +
+ cubos::core::ecs::SystemWrapper<F>::SystemWrapper(F system) +

+

Constructs.

+ + + + + + + + + + +
Parameters
systemSystem to wrap.
+
+
+

+
+ template<typename F> +
+ void cubos::core::ecs::SystemWrapper<F>::prepare(World& world) override +

+

Prepares the system for being executed on the given world.

+ + + + + + + + + + +
Parameters
worldWorld to prepare the system for.
+

Requires exclusive access to the world and must be called before calling the system.

+
+
+

+
+ template<typename F> +
+ impl::SystemTraits<F>::Return cubos::core::ecs::SystemWrapper<F>::call(World& world, + CommandBuffer& commands) override +

+

Calls the wrapped system with parameters taken from the given world.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
worldWorld used by the system.
commandsBuffer where commands can be submitted to.
ReturnsReturn value of the system.
+

Can only be called after calling prepare() on the same world.

+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1VecStorage.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1VecStorage.html new file mode 100644 index 000000000..58562386b --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1VecStorage.html @@ -0,0 +1,257 @@ + + + + + cubos::core::ecs::VecStorage class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::ecs::VecStorage class +

+

Storage implementation that uses a std::vector.

+ + + + + + + + + + +
Template parameters
TComponent type.
+ +
+

Base classes

+
+
+
template<typename T>
+ class Storage<T> +
+
Abstract container for a component type T.
+
+
+
+

Public functions

+
+
+ auto insert(uint32_t index, + T value) -> T* override +
+
Inserts a value into the storage.
+
+ auto get(uint32_t index) -> T* override +
+
Gets a value from the storage.
+
+ auto get(uint32_t index) const -> const T* override +
+
Gets a value from the storage.
+
+ void erase(uint32_t index) override +
+
Remove a value from the storage.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ T* cubos::core::ecs::VecStorage<T>::insert(uint32_t index, + T value) override +

+

Inserts a value into the storage.

+ + + + + + + + + + + + + + +
Parameters
indexIndex where to insert the value.
valueValue to be inserted.
+
+
+

+
+ template<typename T> +
+ T* cubos::core::ecs::VecStorage<T>::get(uint32_t index) override +

+

Gets a value from the storage.

+ + + + + + + + + + + + + + + + +
Parameters
indexIndex of the value to be retrieved.
ReturnsPointer to the value.
+
+
+

+
+ template<typename T> +
+ const T* cubos::core::ecs::VecStorage<T>::get(uint32_t index) const override +

+

Gets a value from the storage.

+ + + + + + + + + + + + + + + + +
Parameters
indexIndex of the value to be retrieved.
ReturnsPointer to the value.
+
+
+

+
+ template<typename T> +
+ void cubos::core::ecs::VecStorage<T>::erase(uint32_t index) override +

+

Remove a value from the storage.

+ + + + + + + + + + +
Parameters
indexIndex of the value to be removed.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1World.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1World.html new file mode 100644 index 000000000..1cbabd1cd --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1World.html @@ -0,0 +1,592 @@ + + + + + cubos::core::ecs::World class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::World class + +

+

Holds entities, their components and resources.

+ + +
+

Public types

+
+
+ using Iterator = EntityManager::Iterator +
+
Used to iterate over all entities in a world.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ World(std::size_t initialCapacity = 1024) +
+
Constructs with the given initialCapacity.
+
+
+
+

Public functions

+
+
+
template<typename T, typename... TArgs>
+ void registerResource(TArgs... args) +
+
Registers and inserts a new resource type.
+
+
template<typename T>
+ void registerComponent() +
+
Registers a component type.
+
+
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.
+
+
template<typename... ComponentTypes>
+ auto create(ComponentTypes... components) -> Entity +
+
Creates a new entity with the given components.
+
+ void destroy(Entity entity) +
+
Destroys an entity and its components.
+
+ auto isAlive(Entity entity) const -> bool +
+
Checks if an entity is still alive.
+
+
template<typename... ComponentTypes>
+ void add(Entity entity, + ComponentTypes && ... components) +
+
Adds components to an entity.
+
+
template<typename... ComponentTypes>
+ void remove(Entity entity) +
+
Removes components from an entity.
+
+
template<typename T>
+ auto has(Entity entity) const -> bool +
+
Checks if an entity has a component.
+
+ auto pack(Entity entity, + data::Context* context = nullptr) const -> data::Package +
+
Creates a package from the components of an entity.
+
+ auto unpack(Entity entity, + const data::Package& package, + data::Context* context = nullptr) -> bool +
+
Unpacks components specified in a package into an entity.
+
+ auto begin() const -> Iterator +
+
Returns an iterator which points to the first entity of the world.
+
+ auto end() const -> Iterator +
+
Returns an iterator which points to the end of the world.
+
+
+
+

Function documentation

+
+

+ cubos::core::ecs::World::World(std::size_t initialCapacity = 1024) +

+

Constructs with the given initialCapacity.

+ + + + + + + + + + +
Parameters
initialCapacityHow many entities to reserve space for.
+
+
+

+
+ 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.
+ +
+
+

+
+ template<typename T> +
+ void cubos::core::ecs::World::registerComponent() +

+

Registers a component type.

+ + + + + + + + + + +
Template parameters
TComponent type.
+ +
+
+

+
+ 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.
+
+
+

+
+ template<typename... ComponentTypes> +
+ Entity cubos::core::ecs::World::create(ComponentTypes... components) +

+

Creates a new entity with the given components.

+ + + + + + + + + + + + + + + + + + + +
Template parameters
ComponentTypesTypes of the components.
Parameters
componentsInitial values for the components.
+
+
+

+ void cubos::core::ecs::World::destroy(Entity entity) +

+

Destroys an entity and its components.

+ + + + + + + + + + +
Parameters
entityEntity identifier.
+
+
+

+ bool cubos::core::ecs::World::isAlive(Entity entity) const +

+

Checks if an entity is still alive.

+ + + + + + + + + + + + + + + + +
Parameters
entityEntity identifier.
ReturnsWhether the entity is alive.
+
+
+

+
+ template<typename... ComponentTypes> +
+ void cubos::core::ecs::World::add(Entity entity, + ComponentTypes && ... components) +

+

Adds components to an entity.

+ + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
ComponentTypesTypes of the components.
Parameters
entityEntity identifier.
componentsInitial values for the components.
+

If the entity already has one of the components, it is overwritten.

+
+
+

+
+ template<typename... ComponentTypes> +
+ void cubos::core::ecs::World::remove(Entity entity) +

+

Removes components from an entity.

+ + + + + + + + + + + + + + + + + + + +
Template parameters
ComponentTypesTypes of the components.
Parameters
entityEntity identifier.
+

If the entity doesn't have one of the components, nothing happens.

+
+
+

+
+ template<typename T> +
+ bool cubos::core::ecs::World::has(Entity entity) const +

+

Checks if an entity has a component.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TComponent type.
Parameters
entityEntity identifier.
ReturnsWhether the entity has the component.
+
+
+

+ data::Package cubos::core::ecs::World::pack(Entity entity, + data::Context* context = nullptr) const +

+

Creates a package from the components of an entity.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
entityEntity identifier.
contextOptional context for serializing the components.
ReturnsPackage containing the components of the entity.
+
+
+

+ bool cubos::core::ecs::World::unpack(Entity entity, + const data::Package& package, + data::Context* context = nullptr) +

+

Unpacks components specified in a package into an entity.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
entityEntity identifier.
packagePackage to unpack.
contextOptional context for deserializing the components.
ReturnsWhether the package was unpacked successfully.
+

Removes any components that are already present in the entity.

+
+
+

+ Iterator cubos::core::ecs::World::begin() const +

+

Returns an iterator which points to the first entity of the world.

+ + + + + + + +
ReturnsIterator.
+
+
+

+ Iterator cubos::core::ecs::World::end() const +

+

Returns an iterator which points to the end of the world.

+ + + + + + + +
ReturnsIterator.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Write.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Write.html new file mode 100644 index 000000000..38a5d43f5 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1Write.html @@ -0,0 +1,205 @@ + + + + + cubos::core::ecs::Write class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::ecs::Write class +

+

System argument which provides write access to the resource T, or query argument which provides write access to the component T.

+ + + + + + + + + + +
Template parameters
TResource or component type.
+ +

Can be used as a pointer with both the -> and * operators.

+
+

Constructors, destructors, conversion operators

+
+
+ Write(T& ref) +
+
Creates a new write argument.
+
+
+
+

Public functions

+
+
+ auto operator->() -> T* +
+
Accesses the resource or component.
+
+ auto operator*() -> T& +
+
Accesses the resource or component.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ cubos::core::ecs::Write<T>::Write(T& ref) +

+

Creates a new write argument.

+ + + + + + + + + + +
Parameters
refReference to the resource or component.
+
+
+

+
+ template<typename T> +
+ T* cubos::core::ecs::Write<T>::operator->() +

+

Accesses the resource or component.

+ + + + + + + +
ReturnsPointer to the resource or component.
+
+
+

+
+ template<typename T> +
+ T& cubos::core::ecs::Write<T>::operator*() +

+

Accesses the resource or component.

+ + + + + + + +
ReturnsReference to the resource or component.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1WriteResource.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1WriteResource.html new file mode 100644 index 000000000..91cac38fa --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1WriteResource.html @@ -0,0 +1,183 @@ + + + + + cubos::core::ecs::WriteResource class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
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/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1WriteStorage.html b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1WriteStorage.html new file mode 100644 index 000000000..d58d97cb3 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1ecs_1_1WriteStorage.html @@ -0,0 +1,183 @@ + + + + + cubos::core::ecs::WriteStorage class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::ecs::WriteStorage class +

+

Utility struct used to reference a storage of component type T for writing.

+ + + + + + + + + + +
Template parameters
TComponent type.
+ +
+

Constructors, destructors, conversion operators

+
+
+ WriteStorage(WriteStorage&& other) noexcept +
+
Move constructor.
+
+
+
+

Public functions

+
+
+ auto get() const -> Storage<T>& +
+
Gets the underlying storage reference.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ cubos::core::ecs::WriteStorage<T>::WriteStorage(WriteStorage&& other) noexcept +

+

Move constructor.

+ + + + + + + + + + +
Parameters
otherOther instance to move from.
+
+
+

+
+ template<typename T> +
+ Storage<T>& cubos::core::ecs::WriteStorage<T>::get() const +

+

Gets the underlying storage reference.

+ + + + + + + +
ReturnsUnderlying storage reference.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1Debug.html b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1Debug.html new file mode 100644 index 000000000..88830ff85 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1Debug.html @@ -0,0 +1,373 @@ + + + + + cubos::core::gl::Debug class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1Grid.html b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1Grid.html new file mode 100644 index 000000000..fd7148d6b --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1Grid.html @@ -0,0 +1,365 @@ + + + + + cubos::core::gl::Grid class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::Grid class final + +

+

Represents a voxel object using a 3D grid.

+ + +
+

Constructors, destructors, conversion operators

+
+
+ Grid() +
+
Constructs an empty single-voxel grid.
+
+ Grid(const glm::uvec3& size) +
+
Constructs an empty grid with the given size.
+
+ Grid(const glm::uvec3& size, + const std::vector<uint16_t>& indices) +
+
Constructs a grid with the given size and initial data.
+
+ Grid(Grid&& other) noexcept +
+
Move constructs.
+
+
+
+

Public functions

+
+
+ auto operator=(const Grid& rhs) -> Grid& +
+
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 Palette& src, + const Palette& dst, + float minSimilarity) -> bool +
+
Converts the material indices of this grid from one palette to another.
+
+
+
+

Function documentation

+
+

+ cubos::core::gl::Grid::Grid(const glm::uvec3& size) +

+

Constructs an empty grid with the given size.

+ + + + + + + + + + +
Parameters
sizeSize of the grid.
+
+
+

+ cubos::core::gl::Grid::Grid(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::core::gl::Grid::Grid(Grid&& other) noexcept +

+

Move constructs.

+ + + + + + + + + + +
Parameters
otherOther grid.
+
+
+

+ Grid& cubos::core::gl::Grid::operator=(const Grid& rhs) +

+

Makes this grid a copy of another grid.

+ + + + + + + + + + + + + + + + +
Parameters
rhsOther grid.
ReturnsThis grid, for chaining.
+
+
+

+ void cubos::core::gl::Grid::setSize(const glm::uvec3& size) +

+

Resizes the grid. New voxels are initialized to 0.

+ + + + + + + + + + +
Parameters
sizeNew size of the grid.
+
+
+

+ const glm::uvec3& cubos::core::gl::Grid::size() const +

+

Gets the size of the grid.

+ + + + + + + +
ReturnsSize of the grid.
+
+
+

+ void cubos::core::gl::Grid::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::core::gl::Grid::get(const glm::ivec3& position) const +

+

Gets the material index of a voxel.

+ + + + + + + + + + + + + + + + +
Parameters
positionVoxel coordinates.
ReturnsMaterial index of the voxel.
+
+
+

+ bool cubos::core::gl::Grid::convert(const Palette& src, + const Palette& 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/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1Palette.html b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1Palette.html new file mode 100644 index 000000000..5a4aec9ae --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1Palette.html @@ -0,0 +1,332 @@ + + + + + cubos::core::gl::Palette class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::Palette 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.

+
+

Constructors, destructors, conversion operators

+
+
+ Palette(std::vector<Material>&& materials) +
+
Constructs a palette with the given materials.
+
+ Palette() defaulted +
+
Constructs an empty palette.
+
+
+
+

Public functions

+
+
+ auto data() const -> const Material* +
+
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 Material& +
+
Gets the material with the given index.
+
+ void set(uint16_t index, + const Material& material) +
+
Sets the material at the given index.
+
+ auto find(const Material& material) const -> uint16_t +
+
Searches for the index of the material most similar with the given material.
+
+ auto add(const Material& material, + float similarity = 1.0F) -> uint16_t +
+
Adds a material to the palette, if one not similar enough already exists.
+
+ void merge(const Palette& palette, + float similarity = 1.0F) +
+
Merges another palette into this one.
+
+
+
+

Function documentation

+
+

+ cubos::core::gl::Palette::Palette(std::vector<Material>&& materials) +

+

Constructs a palette with the given materials.

+ + + + + + + + + + +
Parameters
materialsMaterials to add to the palette.
+
+
+

+ const Material* cubos::core::gl::Palette::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::core::gl::Palette::size() const +

+

Gets the number of materials in the palette, excluding the empty material.

+ + + + + + + +
ReturnsNumber of materials in the palette.
+
+
+

+ const Material& cubos::core::gl::Palette::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::core::gl::Palette::set(uint16_t index, + const Material& 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::core::gl::Palette::find(const Material& 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::core::gl::Palette::add(const Material& 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).
+ +
+
+

+ void cubos::core::gl::Palette::merge(const Palette& palette, + float similarity = 1.0F) +

+

Merges another palette into this one.

+ + + + + + + + + + + + + + +
Parameters
palettePalette to merge.
similarityMinimum similarity for two materials to be merged.
+ +
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1RenderDevice.html b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1RenderDevice.html new file mode 100644 index 000000000..1507da199 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1RenderDevice.html @@ -0,0 +1,1259 @@ + + + + + cubos::core::gl::RenderDevice class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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 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::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/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1BlendState.html b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1BlendState.html new file mode 100644 index 000000000..59a04ad5c --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1BlendState.html @@ -0,0 +1,101 @@ + + + + + cubos::core::gl::impl::BlendState class | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1ConstantBuffer.html b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1ConstantBuffer.html new file mode 100644 index 000000000..3929921d3 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1ConstantBuffer.html @@ -0,0 +1,142 @@ + + + + + cubos::core::gl::impl::ConstantBuffer class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1CubeMap.html b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1CubeMap.html new file mode 100644 index 000000000..6cf631e2d --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1CubeMap.html @@ -0,0 +1,181 @@ + + + + + cubos::core::gl::impl::CubeMap class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1CubeMapArray.html b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1CubeMapArray.html new file mode 100644 index 000000000..93f9833bb --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1CubeMapArray.html @@ -0,0 +1,187 @@ + + + + + cubos::core::gl::impl::CubeMapArray class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1DepthStencilState.html b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1DepthStencilState.html new file mode 100644 index 000000000..5d3e3eb42 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1DepthStencilState.html @@ -0,0 +1,101 @@ + + + + + cubos::core::gl::impl::DepthStencilState class | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Framebuffer.html b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Framebuffer.html new file mode 100644 index 000000000..34392800b --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Framebuffer.html @@ -0,0 +1,101 @@ + + + + + cubos::core::gl::impl::Framebuffer class | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1IndexBuffer.html b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1IndexBuffer.html new file mode 100644 index 000000000..d0295348a --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1IndexBuffer.html @@ -0,0 +1,142 @@ + + + + + cubos::core::gl::impl::IndexBuffer class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1RasterState.html b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1RasterState.html new file mode 100644 index 000000000..7e424012d --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1RasterState.html @@ -0,0 +1,101 @@ + + + + + cubos::core::gl::impl::RasterState class | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Sampler.html b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Sampler.html new file mode 100644 index 000000000..e9cbecc9f --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Sampler.html @@ -0,0 +1,101 @@ + + + + + cubos::core::gl::impl::Sampler class | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderBindingPoint.html b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderBindingPoint.html new file mode 100644 index 000000000..c66675312 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderBindingPoint.html @@ -0,0 +1,622 @@ + + + + + cubos::core::gl::impl::ShaderBindingPoint class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderPipeline.html b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderPipeline.html new file mode 100644 index 000000000..72467c2c7 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderPipeline.html @@ -0,0 +1,138 @@ + + + + + cubos::core::gl::impl::ShaderPipeline class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderStage.html b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderStage.html new file mode 100644 index 000000000..9dc01f959 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1ShaderStage.html @@ -0,0 +1,138 @@ + + + + + cubos::core::gl::impl::ShaderStage class | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Texture1D.html b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Texture1D.html new file mode 100644 index 000000000..49761a784 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Texture1D.html @@ -0,0 +1,163 @@ + + + + + cubos::core::gl::impl::Texture1D class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Texture2D.html b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Texture2D.html new file mode 100644 index 000000000..f97e24a4d --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Texture2D.html @@ -0,0 +1,175 @@ + + + + + cubos::core::gl::impl::Texture2D class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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 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.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Texture2DArray.html b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Texture2DArray.html new file mode 100644 index 000000000..b23610106 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Texture2DArray.html @@ -0,0 +1,181 @@ + + + + + cubos::core::gl::impl::Texture2DArray class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Texture3D.html b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Texture3D.html new file mode 100644 index 000000000..8729c8c7c --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1Texture3D.html @@ -0,0 +1,187 @@ + + + + + cubos::core::gl::impl::Texture3D class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1VertexArray.html b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1VertexArray.html new file mode 100644 index 000000000..d50bb9849 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1VertexArray.html @@ -0,0 +1,101 @@ + + + + + cubos::core::gl::impl::VertexArray class | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1VertexBuffer.html b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1VertexBuffer.html new file mode 100644 index 000000000..6ec8883ba --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1gl_1_1impl_1_1VertexBuffer.html @@ -0,0 +1,142 @@ + + + + + cubos::core::gl::impl::VertexBuffer class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1io_1_1BaseWindow.html b/pr-preview/pr-589/classcubos_1_1core_1_1io_1_1BaseWindow.html new file mode 100644 index 000000000..3bc538d24 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1io_1_1BaseWindow.html @@ -0,0 +1,475 @@ + + + + + cubos::core::io::BaseWindow class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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 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 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.
+
+
+

+ 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.
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1io_1_1Cursor.html b/pr-preview/pr-589/classcubos_1_1core_1_1io_1_1Cursor.html new file mode 100644 index 000000000..196c59bde --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1io_1_1Cursor.html @@ -0,0 +1,204 @@ + + + + + cubos::core::io::Cursor class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1BufferStream.html b/pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1BufferStream.html new file mode 100644 index 000000000..56620746b --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1BufferStream.html @@ -0,0 +1,424 @@ + + + + + cubos::core::memory::BufferStream class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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 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::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/pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1ReadGuard.html b/pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1ReadGuard.html new file mode 100644 index 000000000..ac1b29946 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1ReadGuard.html @@ -0,0 +1,261 @@ + + + + + cubos::core::memory::ReadGuard class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
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/pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1StandardStream.html b/pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1StandardStream.html new file mode 100644 index 000000000..76d41e54b --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1StandardStream.html @@ -0,0 +1,331 @@ + + + + + cubos::core::memory::StandardStream class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1Stream.html b/pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1Stream.html new file mode 100644 index 000000000..0bcdb0646 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1Stream.html @@ -0,0 +1,1010 @@ + + + + + cubos::core::memory::Stream class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1TypeMap.html b/pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1TypeMap.html new file mode 100644 index 000000000..0fe134605 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1TypeMap.html @@ -0,0 +1,452 @@ + + + + + cubos::core::memory::TypeMap class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
template<typename V>
+ cubos::core::memory::TypeMap class +

+

A map that stores values of type V, using types as keys.

+ + + + + + + + + + +
Template parameters
VValues type.
+ +
+

Constructors, destructors, conversion operators

+
+
+ TypeMap() defaulted +
+
Constructs an empty map.
+
+ TypeMap(TypeMap&&) defaulted noexcept +
+
Move constructs.
+
+
+
+

Public functions

+
+
+ void set(std::type_index key, + V value) +
+
Sets the value associated to the given type.
+
+ auto at(std::type_index key) -> V* +
+
Gets the value associated to the given type.
+
+ auto at(std::type_index key) const -> const V* +
+
Gets the value associated to the given type.
+
+
template<typename K>
+ void set(V value) +
+
Sets the value associated to the given type.
+
+
template<typename K>
+ auto at() -> V* +
+
Gets the value associated to the given type.
+
+
template<typename K>
+ auto at() const -> const V* +
+
Gets the value associated to the given type.
+
+ void clear() +
+
Removes all values from the map.
+
+ void erase(std::type_index key) +
+
Removes the value with the given key from the map.
+
+
template<typename K>
+ void erase() +
+
Removes the value with the given key from the map.
+
+ auto size() const -> std::size_t +
+
Gets the number of values in 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>::set(std::type_index key, + V value) +

+

Sets the value associated to the given type.

+ + + + + + + + + + + + + + +
Parameters
keyIndex of the type to use as a key.
valueValue to store.
+
+
+

+
+ template<typename V> +
+ V* cubos::core::memory::TypeMap<V>::at(std::type_index key) +

+

Gets the value associated to the given type.

+ + + + + + + + + + + + + + + + +
Parameters
keyIndex of the type to use as a key.
ReturnsPointer to the value or null if it isn't stored.
+
+
+

+
+ template<typename V> +
+ const V* cubos::core::memory::TypeMap<V>::at(std::type_index key) const +

+

Gets the value associated to the given type.

+ + + + + + + + + + + + + + + + +
Parameters
keyIndex of the type to use as a key.
ReturnsPointer to the value or null if it isn't stored.
+
+
+

+
+ template<typename V> + template<typename K> +
+ void cubos::core::memory::TypeMap<V>::set(V value) +

+

Sets the value associated to the given type.

+ + + + + + + + + + + + + + + + + + + +
Template parameters
KType to use as a key.
Parameters
valueValue to store.
+
+
+

+
+ template<typename V> + template<typename K> +
+ V* cubos::core::memory::TypeMap<V>::at() +

+

Gets the value associated to the given type.

+ + + + + + + + + + + + + + + + +
Template parameters
KType to use as a key.
ReturnsPointer to the value or null if it isn't stored.
+
+
+

+
+ template<typename V> + template<typename K> +
+ const V* cubos::core::memory::TypeMap<V>::at() const +

+

Gets the value associated to the given type.

+ + + + + + + + + + + + + + + + +
Template parameters
KType to use as a key.
ReturnsPointer to the value or null if it isn't stored.
+
+
+

+
+ template<typename V> +
+ void cubos::core::memory::TypeMap<V>::erase(std::type_index key) +

+

Removes the value with the given key from the map.

+ + + + + + + + + + +
Parameters
keyIndex of the type to use as a key.
+
+
+

+
+ template<typename V> + template<typename K> +
+ void cubos::core::memory::TypeMap<V>::erase() +

+

Removes the value with the given key from the map.

+ + + + + + + + + + +
Template parameters
KType to use as a key.
+
+
+

+
+ template<typename V> +
+ std::size_t cubos::core::memory::TypeMap<V>::size() const +

+

Gets the number of values in the map.

+ + + + + + + +
ReturnsNumber of values in the map.
+
+
+

+
+ template<typename V> +
+ auto cubos::core::memory::TypeMap<V>::begin() const +

+

Gets an iterator to the beginning of the map.

+ + + + + + + +
ReturnsIterator to the beginning of the map.
+
+
+

+
+ template<typename V> +
+ auto cubos::core::memory::TypeMap<V>::end() const +

+

Gets an iterator to the end of the map.

+ + + + + + + +
ReturnsIterator to the end of the map.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1WriteGuard.html b/pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1WriteGuard.html new file mode 100644 index 000000000..fe285f8e2 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1memory_1_1WriteGuard.html @@ -0,0 +1,324 @@ + + + + + cubos::core::memory::WriteGuard class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
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/pr-preview/pr-589/classcubos_1_1core_1_1reflection_1_1ConstructibleTrait.html b/pr-preview/pr-589/classcubos_1_1core_1_1reflection_1_1ConstructibleTrait.html new file mode 100644 index 000000000..342878028 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1reflection_1_1ConstructibleTrait.html @@ -0,0 +1,458 @@ + + + + + cubos::core::reflection::ConstructibleTrait class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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.
+
+ void destruct(void* instance) const +
+
Destructs an instance of the type.
+
+ auto defaultConstruct(void* instance) const -> bool +
+
Default constructs an instance of the type.
+
+ auto copyConstruct(void* instance, + const void* other) const -> bool +
+
Copy constructs an instance of the type.
+
+ auto moveConstruct(void* instance, + void* other) const -> bool +
+
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.
+
+
+

+ void cubos::core::reflection::ConstructibleTrait::destruct(void* instance) const +

+

Destructs an instance of the type.

+ + + + + + + + + + +
Parameters
instancePointer to the instance to destruct.
+
+
+

+ bool 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.
ReturnsWhether default construction is supported.
+
+
+

+ bool 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.
ReturnsWhether copy construction is supported.
+
+
+

+ bool 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.
ReturnsWhether move construction is supported.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1reflection_1_1ConstructibleTrait_1_1Builder.html b/pr-preview/pr-589/classcubos_1_1core_1_1reflection_1_1ConstructibleTrait_1_1Builder.html new file mode 100644 index 000000000..2141ab645 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1reflection_1_1ConstructibleTrait_1_1Builder.html @@ -0,0 +1,215 @@ + + + + + cubos::core::reflection::ConstructibleTrait::Builder class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
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 copy constructor of the type.
+
+ auto withCopyConstructor() && -> Builder&& +
+
Sets the copy constructor of the type.
+
+ auto withMoveConstructor() && -> Builder&& +
+
Sets the move constructor 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 copy 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.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1core_1_1reflection_1_1Type.html b/pr-preview/pr-589/classcubos_1_1core_1_1reflection_1_1Type.html new file mode 100644 index 000000000..4db47ebb9 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1core_1_1reflection_1_1Type.html @@ -0,0 +1,328 @@ + + + + + cubos::core::reflection::Type class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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.
+
+
+
+

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.

+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1engine_1_1AnyAsset.html b/pr-preview/pr-589/classcubos_1_1engine_1_1AnyAsset.html new file mode 100644 index 000000000..286da24e4 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1AnyAsset.html @@ -0,0 +1,380 @@ + + + + + cubos::engine::AnyAsset class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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<typename T>
+ class Asset +
+
Handle to an asset of a specific type.
+
+
template<typename 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<typename 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 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.
+
+
+
+

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<typename 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.
+
+
+

+ 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.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1engine_1_1Asset.html b/pr-preview/pr-589/classcubos_1_1engine_1_1Asset.html new file mode 100644 index 000000000..0b5afdae9 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1Asset.html @@ -0,0 +1,330 @@ + + + + + cubos::engine::Asset class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
template<typename 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<typename T> +
+ cubos::engine::Asset<T>::AnyAsset(uuids::uuid id) +

+

Constructs a weak handle.

+ + + + + + + + + + +
Parameters
idUUID of the asset.
+
+
+

+
+ template<typename 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<typename T> +
+ cubos::engine::Asset<T>::AnyAsset(const AnyAsset& other) +

+

Constructs a copy of the given handle.

+ + + + + + + + + + +
Parameters
otherHandle to copy.
+
+
+

+
+ template<typename T> +
+ cubos::engine::Asset<T>::AnyAsset(AnyAsset&& other) noexcept +

+

Constructs a handle from the given handle.

+ + + + + + + + + + +
Parameters
otherHandle to move.
+
+
+

+
+ template<typename T> +
+ AnyAsset cubos::engine::Asset<T>::toAny() const +

+

Constructs a generic handle version of this handle.

+ + + + + + + +
ReturnsGeneric handle to the same asset.
+
+
+

+
+ template<typename 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<typename 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/pr-preview/pr-589/classcubos_1_1engine_1_1AssetBridge.html b/pr-preview/pr-589/classcubos_1_1engine_1_1AssetBridge.html new file mode 100644 index 000000000..9d02177a1 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1AssetBridge.html @@ -0,0 +1,248 @@ + + + + + cubos::engine::AssetBridge class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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.
+
+ class SceneBridge +
+
Bridge which loads and saves Scene assets.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ AssetBridge(std::type_index index) 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 -> std::type_index +
+
Gets the type of the assets the bridge loads.
+
+
+
+

Function documentation

+
+

+ cubos::engine::AssetBridge::AssetBridge(std::type_index index) explicit +

+

Constructs a bridge.

+ + + + + + + + + + +
Parameters
indexType 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.

+
+
+

+ std::type_index cubos::engine::AssetBridge::assetType() const +

+

Gets the type of the assets the bridge loads.

+ + + + + + + +
ReturnsType of the asset.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1engine_1_1AssetMeta.html b/pr-preview/pr-589/classcubos_1_1engine_1_1AssetMeta.html new file mode 100644 index 000000000..7846057ca --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1AssetMeta.html @@ -0,0 +1,242 @@ + + + + + cubos::engine::AssetMeta class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1engine_1_1Assets.html b/pr-preview/pr-589/classcubos_1_1engine_1_1Assets.html new file mode 100644 index 000000000..8b2c5af58 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1Assets.html @@ -0,0 +1,674 @@ + + + + + cubos::engine::Assets class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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.
+
+ 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 -> std::type_index +
+
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.

+
+
+

+ 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.
+
+
+

+ std::type_index 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/pr-preview/pr-589/classcubos_1_1engine_1_1BaseRenderer.html b/pr-preview/pr-589/classcubos_1_1engine_1_1BaseRenderer.html new file mode 100644 index 000000000..4047cd3a6 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1BaseRenderer.html @@ -0,0 +1,385 @@ + + + + + cubos::engine::BaseRenderer class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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.
+
+
+
+

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 core::gl::Grid& grid) -> RendererGrid pure virtual +
+
Uploads a grid to the GPU and returns an handle which can be used to draw it.
+
+ void setPalette(const core::gl::Palette& 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 core::gl::Camera& camera, + const RendererFrame& frame, + 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 core::gl::Camera& camera, + const RendererFrame& frame, + core::gl::Framebuffer target) 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 core::gl::Grid& 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 core::gl::Palette& 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 core::gl::Camera& camera, + const RendererFrame& frame, + bool usePostProcessing = true, + const core::gl::Framebuffer& target = nullptr) +

+

Draws a frame.

+ + + + + + + + + + + + + + + + + + + + + + +
Parameters
cameraCamera to use.
frameFrame to draw.
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 core::gl::Camera& camera, + const RendererFrame& frame, + core::gl::Framebuffer target) pure virtual protected +

+

Called when render() is called, before applying post processing effects.

+ + + + + + + + + + + + + + + + + + +
Parameters
cameraCamera to use.
frameFrame to draw.
targetTarget 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/pr-preview/pr-589/classcubos_1_1engine_1_1BinaryBridge.html b/pr-preview/pr-589/classcubos_1_1engine_1_1BinaryBridge.html new file mode 100644 index 000000000..198daa0b5 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1BinaryBridge.html @@ -0,0 +1,257 @@ + + + + + cubos::engine::BinaryBridge class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
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/pr-preview/pr-589/classcubos_1_1engine_1_1Cubos.html b/pr-preview/pr-589/classcubos_1_1engine_1_1Cubos.html new file mode 100644 index 000000000..a88a8dd74 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1Cubos.html @@ -0,0 +1,435 @@ + + + + + cubos::engine::Cubos class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::engine::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 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 given tag.
+
+ auto startupTag(const std::string& tag) -> TagBuilder +
+
Returns a TagBuilder to configure the given startup tag.
+
+
template<typename F>
+ auto system(F func) -> SystemBuilder +
+
Adds a new system to the engine, which will be executed at every iteration of the main loop.
+
+
template<typename F>
+ auto startupSystem(F func) -> SystemBuilder +
+
Adds a new startup system to the engine, which will be executed only once, before the main loop starts.
+
+ void run() +
+
Runs the engine.
+
+
+
+

Function documentation

+
+

+ cubos::engine::Cubos::Cubos(int argc, + char** argv) +

+

Constructs an empty application with arguments.

+ + + + + + + + + + + + + + +
Parameters
argcArgument count.
argvArgument array.
+
+
+

+ Cubos& cubos::engine::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::engine::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::engine::Cubos::addComponent() +

+

Adds a new component type to the engine.

+ + + + + + + + + + + + + + + + +
Template parameters
CType of the component.
ReturnsReference to this object, for chaining.
+
+
+

+
+ template<typename E> +
+ Cubos& cubos::engine::Cubos::addEvent() +

+

Adds a new event type to the engine.

+ + + + + + + + + + + + + + + + +
Template parameters
EType of the event.
ReturnsReference to this object, for chaining.
+
+
+

+ TagBuilder cubos::engine::Cubos::tag(const std::string& tag) +

+

Returns a TagBuilder to configure the given tag.

+ + + + + + + + + + + + + + + + +
Parameters
tagTag to configure.
ReturnsTagBuilder used to configure the tag.
+
+
+

+ TagBuilder cubos::engine::Cubos::startupTag(const std::string& tag) +

+

Returns a TagBuilder to configure the given startup tag.

+ + + + + + + + + + + + + + + + +
Parameters
tagTag to configure.
ReturnsTagBuilder used to configure the tag.
+
+
+

+
+ template<typename F> +
+ SystemBuilder cubos::engine::Cubos::system(F func) +

+

Adds a new system to the engine, which will be executed at every iteration of the main loop.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
FType of the system function.
Parameters
funcSystem function.
ReturnsSystemBuilder used to configure the system.
+
+
+

+
+ template<typename F> +
+ SystemBuilder cubos::engine::Cubos::startupSystem(F func) +

+

Adds a new startup system to the engine, which will be executed only once, before the main loop starts.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
FType of the system function.
Parameters
funcSystem function.
ReturnsSystemBuilder used to configure the system.
+
+
+

+ void cubos::engine::Cubos::run() +

+

Runs the engine.

+

Initially, dispatches all of the startup systems. Then, while ShouldQuit is false, dispatches all other systems.

+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1engine_1_1DeferredRenderer.html b/pr-preview/pr-589/classcubos_1_1engine_1_1DeferredRenderer.html new file mode 100644 index 000000000..ec7d11cc2 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1DeferredRenderer.html @@ -0,0 +1,280 @@ + + + + + cubos::engine::DeferredRenderer class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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 core::gl::Grid& grid) -> RendererGrid override +
+
Uploads a grid to the GPU and returns an handle which can be used to draw it.
+
+ void setPalette(const core::gl::Palette& 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 core::gl::Camera& camera, + const RendererFrame& frame, + core::gl::Framebuffer target) 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 core::gl::Grid& 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 core::gl::Palette& 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 core::gl::Camera& camera, + const RendererFrame& frame, + core::gl::Framebuffer target) override protected +

+

Called when render() is called, before applying post processing effects.

+ + + + + + + + + + + + + + + + + + +
Parameters
cameraCamera to use.
frameFrame to draw.
targetTarget 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/pr-preview/pr-589/classcubos_1_1engine_1_1FileBridge.html b/pr-preview/pr-589/classcubos_1_1engine_1_1FileBridge.html new file mode 100644 index 000000000..cec05d8cd --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1FileBridge.html @@ -0,0 +1,330 @@ + + + + + cubos::engine::FileBridge class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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

+
+
+ class TextBridge +
+
+
+
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.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ FileBridge(std::type_index index) 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(std::type_index index) explicit +

+

Constructs a bridge.

+ + + + + + + + + + +
Parameters
indexType 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/pr-preview/pr-589/classcubos_1_1engine_1_1Input.html b/pr-preview/pr-589/classcubos_1_1engine_1_1Input.html new file mode 100644 index 000000000..6c6e3f396 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1Input.html @@ -0,0 +1,442 @@ + + + + + cubos::engine::Input class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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.
+
+
+
+

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 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::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/pr-preview/pr-589/classcubos_1_1engine_1_1InputAction.html b/pr-preview/pr-589/classcubos_1_1engine_1_1InputAction.html new file mode 100644 index 000000000..10ea8a42e --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1InputAction.html @@ -0,0 +1,269 @@ + + + + + cubos::engine::InputAction class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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<std::pair<core::io::Key, core::io::Modifiers>> keys, + std::vector<core::io::GamepadButton> gamepadButtons) +
+
Constructs with existing bindings.
+
+
+
+

Public functions

+
+
+ auto keys() const -> const std::vector<std::pair<core::io::Key, core::io::Modifiers>>& +
+
Gets the key bindings.
+
+ auto keys() -> std::vector<std::pair<core::io::Key, core::io::Modifiers>>& +
+
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 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<std::pair<core::io::Key, core::io::Modifiers>> keys, + std::vector<core::io::GamepadButton> gamepadButtons) +

+

Constructs with existing bindings.

+ + + + + + + + + + + + + + +
Parameters
keysKey bindings.
gamepadButtonsGamepad button bindings.
+
+
+

+ const std::vector<std::pair<core::io::Key, core::io::Modifiers>>& cubos::engine::InputAction::keys() const +

+

Gets the key bindings.

+ + + + + + + +
ReturnsVector of keys.
+
+
+

+ std::vector<std::pair<core::io::Key, core::io::Modifiers>>& 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.
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1engine_1_1InputAxis.html b/pr-preview/pr-589/classcubos_1_1engine_1_1InputAxis.html new file mode 100644 index 000000000..d8dd9ef4e --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1InputAxis.html @@ -0,0 +1,311 @@ + + + + + cubos::engine::InputAxis class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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<std::pair<core::io::Key, core::io::Modifiers>> positive, + std::vector<std::pair<core::io::Key, core::io::Modifiers>> negative, + std::vector<core::io::GamepadAxis> gamepadAxes) +
+
Constructs with existing bindings.
+
+
+
+

Public functions

+
+
+ auto positive() const -> const std::vector<std::pair<core::io::Key, core::io::Modifiers>>& +
+
Gets the positive key bindings.
+
+ auto negative() const -> const std::vector<std::pair<core::io::Key, core::io::Modifiers>>& +
+
Gets the negative key bindings.
+
+ auto gamepadAxes() const -> const std::vector<core::io::GamepadAxis>& +
+
Gets the gamepad axis bindings.
+
+ auto positive() -> std::vector<std::pair<core::io::Key, core::io::Modifiers>>& +
+
Gets the positive key bindings.
+
+ auto negative() -> std::vector<std::pair<core::io::Key, core::io::Modifiers>>& +
+
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<std::pair<core::io::Key, core::io::Modifiers>> positive, + std::vector<std::pair<core::io::Key, core::io::Modifiers>> negative, + std::vector<core::io::GamepadAxis> gamepadAxes) +

+

Constructs with existing bindings.

+ + + + + + + + + + + + + + + + + + +
Parameters
positivePositive key bindings.
negativeNegative key bindings.
gamepadAxesGamepad axis bindings.
+
+
+

+ const std::vector<std::pair<core::io::Key, core::io::Modifiers>>& cubos::engine::InputAxis::positive() const +

+

Gets the positive key bindings.

+ + + + + + + +
ReturnsVector of positive keys.
+
+
+

+ const std::vector<std::pair<core::io::Key, core::io::Modifiers>>& 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<std::pair<core::io::Key, core::io::Modifiers>>& cubos::engine::InputAxis::positive() +

+

Gets the positive key bindings.

+ + + + + + + +
ReturnsVector of positive keys.
+
+
+

+ std::vector<std::pair<core::io::Key, core::io::Modifiers>>& 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/pr-preview/pr-589/classcubos_1_1engine_1_1InputBindings.html b/pr-preview/pr-589/classcubos_1_1engine_1_1InputBindings.html new file mode 100644 index 000000000..5a861a815 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1InputBindings.html @@ -0,0 +1,193 @@ + + + + + cubos::engine::InputBindings class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1engine_1_1JSONBridge.html b/pr-preview/pr-589/classcubos_1_1engine_1_1JSONBridge.html new file mode 100644 index 000000000..9b98e3c94 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1JSONBridge.html @@ -0,0 +1,258 @@ + + + + + cubos::engine::JSONBridge class | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
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(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::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::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/pr-preview/pr-589/classcubos_1_1engine_1_1PostProcessingBloom.html b/pr-preview/pr-589/classcubos_1_1engine_1_1PostProcessingBloom.html new file mode 100644 index 000000000..6e675a76f --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1PostProcessingBloom.html @@ -0,0 +1,391 @@ + + + + + cubos::engine::PostProcessingBloom class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1engine_1_1PostProcessingCopy.html b/pr-preview/pr-589/classcubos_1_1engine_1_1PostProcessingCopy.html new file mode 100644 index 000000000..45d19ccfb --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1PostProcessingCopy.html @@ -0,0 +1,219 @@ + + + + + cubos::engine::PostProcessingCopy class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1engine_1_1PostProcessingManager.html b/pr-preview/pr-589/classcubos_1_1engine_1_1PostProcessingManager.html new file mode 100644 index 000000000..8ae0929ef --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1PostProcessingManager.html @@ -0,0 +1,294 @@ + + + + + cubos::engine::PostProcessingManager class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1engine_1_1PostProcessingPass.html b/pr-preview/pr-589/classcubos_1_1engine_1_1PostProcessingPass.html new file mode 100644 index 000000000..5b2a9b435 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1PostProcessingPass.html @@ -0,0 +1,231 @@ + + + + + cubos::engine::PostProcessingPass class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1engine_1_1RendererFrame.html b/pr-preview/pr-589/classcubos_1_1engine_1_1RendererFrame.html new file mode 100644 index 000000000..f80ebbc90 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1RendererFrame.html @@ -0,0 +1,408 @@ + + + + + cubos::engine::RendererFrame class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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) +
+
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) +

+

Submits a draw command.

+ + + + + + + + + + + + + + +
Parameters
gridHandle of the grid to draw.
modelMatModel matrix of the grid, used for applying transformations.
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1engine_1_1SceneBridge.html b/pr-preview/pr-589/classcubos_1_1engine_1_1SceneBridge.html new file mode 100644 index 000000000..46fc0ba1c --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1SceneBridge.html @@ -0,0 +1,225 @@ + + + + + cubos::engine::SceneBridge class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/position": {
+                "x": 1,
+                "y": 2,
+                "z": 3
+            }
+        },
+        "foo.bar": {
+            "cubos/parent": "baz",
+        }
+    }
+}

This scene will import the subscene 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 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.
+
+
+
+

Constructors, destructors, conversion operators

+
+
+ SceneBridge() +
+
Constructs a bridge.
+
+
+
+

Public functions

+
+
+ auto load(Assets& assets, + const AnyAsset& handle) -> bool override +
+
Loads an asset.
+
+ auto save(const Assets& assets, + const AnyAsset& handle) -> bool override +
+
Saves an asset.
+
+
+
+

Function documentation

+
+

+ bool cubos::engine::SceneBridge::load(Assets& assets, + const AnyAsset& handle) override +

+

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::SceneBridge::save(const Assets& assets, + const AnyAsset& handle) override +

+

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.

+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1engine_1_1Settings.html b/pr-preview/pr-589/classcubos_1_1engine_1_1Settings.html new file mode 100644 index 000000000..29a14e9f5 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1Settings.html @@ -0,0 +1,434 @@ + + + + + cubos::engine::Settings class | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/classcubos_1_1engine_1_1SystemBuilder.html b/pr-preview/pr-589/classcubos_1_1engine_1_1SystemBuilder.html new file mode 100644 index 000000000..613e56494 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1SystemBuilder.html @@ -0,0 +1,274 @@ + + + + + cubos::engine::SystemBuilder class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::engine::SystemBuilder class + +

+

Used to chain configurations related to systems.

+ +
+

Constructors, destructors, conversion operators

+
+
+ SystemBuilder(core::ecs::Dispatcher& dispatcher, + std::vector<std::string>& tags) +
+
Construct.
+
+
+
+

Public functions

+
+
+ auto tagged(const std::string& tag) -> SystemBuilder& +
+
Sets the current system's tag.
+
+ auto before(const std::string& tag) -> SystemBuilder& +
+
Sets the current system to be executed before another tag.
+
+ auto after(const std::string& tag) -> SystemBuilder& +
+
Sets the current system to be executed after another tag.
+
+
template<typename F>
+ auto runIf(F func) -> SystemBuilder& +
+
Adds a condition to the current system. If this condition returns false, the system will not be executed. For a system to run, all conditions must return true.
+
+
+
+

Function documentation

+
+

+ cubos::engine::SystemBuilder::SystemBuilder(core::ecs::Dispatcher& dispatcher, + std::vector<std::string>& tags) +

+

Construct.

+ + + + + + + + + + + + + + +
Parameters
dispatcherDispatcher being configured.
tagsVector which stores the tags for this dispatcher.
+
+
+

+ SystemBuilder& cubos::engine::SystemBuilder::tagged(const std::string& tag) +

+

Sets the current system's tag.

+ + + + + + + + + + + + + + + + +
Parameters
tagTag to be set.
ReturnsReference to this object, for chaining.
+
+
+

+ SystemBuilder& cubos::engine::SystemBuilder::before(const std::string& tag) +

+

Sets the current system to be executed before another tag.

+ + + + + + + + + + + + + + + + +
Parameters
tagTag to be executed before.
ReturnsReference to this object, for chaining.
+
+
+

+ SystemBuilder& cubos::engine::SystemBuilder::after(const std::string& tag) +

+

Sets the current system to be executed after another tag.

+ + + + + + + + + + + + + + + + +
Parameters
tagTag to be executed after.
ReturnsReference to this object, for chaining.
+
+
+

+
+ template<typename F> +
+ SystemBuilder& cubos::engine::SystemBuilder::runIf(F func) +

+

Adds a condition to the current system. If this condition returns false, the system will not be executed. For a system to run, all conditions must return true.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
FCondition system type.
Parameters
funcCondition system.
ReturnsReference to this object, for chaining.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1engine_1_1TagBuilder.html b/pr-preview/pr-589/classcubos_1_1engine_1_1TagBuilder.html new file mode 100644 index 000000000..478bbc00a --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1TagBuilder.html @@ -0,0 +1,244 @@ + + + + + cubos::engine::TagBuilder class | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::engine::TagBuilder class + +

+

Used to chain configurations related to tags.

+ +
+

Constructors, destructors, conversion operators

+
+
+ TagBuilder(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.
+
+
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.
+
+
+
+

Function documentation

+
+

+ cubos::engine::TagBuilder::TagBuilder(core::ecs::Dispatcher& dispatcher, + std::vector<std::string>& tags) +

+

Construct.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
dispatcherDispatcher being configured
tagsVector which stores the tags for this dispatcher.
ReturnsReference to this object, for chaining.
+
+
+

+ TagBuilder& cubos::engine::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::engine::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.
+
+
+

+
+ template<typename F> +
+ TagBuilder& cubos::engine::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.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/classcubos_1_1engine_1_1impl_1_1RendererGrid.html b/pr-preview/pr-589/classcubos_1_1engine_1_1impl_1_1RendererGrid.html new file mode 100644 index 000000000..6a01e12f2 --- /dev/null +++ b/pr-preview/pr-589/classcubos_1_1engine_1_1impl_1_1RendererGrid.html @@ -0,0 +1,101 @@ + + + + + cubos::engine::impl::RendererGrid class | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/collisions_2plugin_8hpp.html b/pr-preview/pr-589/collisions_2plugin_8hpp.html new file mode 100644 index 000000000..e81375808 --- /dev/null +++ b/pr-preview/pr-589/collisions_2plugin_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/collisions/plugin.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/commands_8hpp.html b/pr-preview/pr-589/commands_8hpp.html new file mode 100644 index 000000000..9de221f9a --- /dev/null +++ b/pr-preview/pr-589/commands_8hpp.html @@ -0,0 +1,144 @@ + + + + + core/ecs/commands.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/ecs/commands.hpp file +

+

Class cubos::core::ecs::Commands and related types.

+ +
+

Namespaces

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

Classes

+
+
+ class cubos::core::ecs::EntityBuilder +
+
Allows editing an entity created by a Commands object.
+
+ class cubos::core::ecs::BlueprintBuilder +
+
Used to edit a blueprint spawned by a Commands object.
+
+ class cubos::core::ecs::Commands +
+
Used to write ECS commands and execute them at a later time.
+
+ class cubos::core::ecs::CommandBuffer +
+
Stores commands to execute them later.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/component__manager_8hpp.html b/pr-preview/pr-589/component__manager_8hpp.html new file mode 100644 index 000000000..7435159e7 --- /dev/null +++ b/pr-preview/pr-589/component__manager_8hpp.html @@ -0,0 +1,157 @@ + + + + + core/ecs/component_manager.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/ecs/component_manager.hpp file +

+

Class cubos::core::ecs::ComponentManager 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::ReadStorage +
+
Utility struct used to reference a storage of component type T for reading.
+
+
template<typename T>
+ class cubos::core::ecs::WriteStorage +
+
Utility struct used to reference a storage of component type T for writing.
+
+ class cubos::core::ecs::ComponentManager +
+
Holds and manages components.
+
+
+
+

Functions

+
+
+
template<typename T>
+ auto getComponentName() -> std::optional<std::string_view> +
+
Gets the registered name of a component type.
+
+ auto getComponentName(std::type_index type) -> std::optional<std::string_view> +
+
Gets the registered name of a component type.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/constructible_8hpp.html b/pr-preview/pr-589/constructible_8hpp.html new file mode 100644 index 000000000..28d870082 --- /dev/null +++ b/pr-preview/pr-589/constructible_8hpp.html @@ -0,0 +1,137 @@ + + + + + core/reflection/traits/constructible.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/constructible__utils_8hpp.html b/pr-preview/pr-589/constructible__utils_8hpp.html new file mode 100644 index 000000000..e5aaa7388 --- /dev/null +++ b/pr-preview/pr-589/constructible__utils_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/reflection/traits/constructible_utils.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/contribution.html b/pr-preview/pr-589/contribution.html new file mode 100644 index 000000000..f606bd09d --- /dev/null +++ b/pr-preview/pr-589/contribution.html @@ -0,0 +1,112 @@ + + + + + Contribution guidelines | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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. We use the scopes core, engine and tools. When making a commit which affects more than one of these scopes, 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/pr-preview/pr-589/copy__pass_8hpp.html b/pr-preview/pr-589/copy__pass_8hpp.html new file mode 100644 index 000000000..bbbf69fe3 --- /dev/null +++ b/pr-preview/pr-589/copy__pass_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/renderer/pps/copy_pass.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/core_2include_2cubos_2core_2data_2fs_2file_8hpp.html b/pr-preview/pr-589/core_2include_2cubos_2core_2data_2fs_2file_8hpp.html new file mode 100644 index 000000000..ed1596ec5 --- /dev/null +++ b/pr-preview/pr-589/core_2include_2cubos_2core_2data_2fs_2file_8hpp.html @@ -0,0 +1,132 @@ + + + + + core/data/fs/file.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/core_2include_2cubos_2core_2geom_2box_8hpp.html b/pr-preview/pr-589/core_2include_2cubos_2core_2geom_2box_8hpp.html new file mode 100644 index 000000000..c85ad9eaf --- /dev/null +++ b/pr-preview/pr-589/core_2include_2cubos_2core_2geom_2box_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/geom/box.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/core_2include_2cubos_2core_2geom_2capsule_8hpp.html b/pr-preview/pr-589/core_2include_2cubos_2core_2geom_2capsule_8hpp.html new file mode 100644 index 000000000..f160db3c6 --- /dev/null +++ b/pr-preview/pr-589/core_2include_2cubos_2core_2geom_2capsule_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/geom/capsule.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/core_2include_2cubos_2core_2geom_2plane_8hpp.html b/pr-preview/pr-589/core_2include_2cubos_2core_2geom_2plane_8hpp.html new file mode 100644 index 000000000..2fecf5af5 --- /dev/null +++ b/pr-preview/pr-589/core_2include_2cubos_2core_2geom_2plane_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/geom/plane.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/core_2include_2cubos_2core_2geom_2simplex_8hpp.html b/pr-preview/pr-589/core_2include_2cubos_2core_2geom_2simplex_8hpp.html new file mode 100644 index 000000000..886ce74d4 --- /dev/null +++ b/pr-preview/pr-589/core_2include_2cubos_2core_2geom_2simplex_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/geom/simplex.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/geom/simplex.hpp file +

+

Class cubos::core::geom::Simplex.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::geom
+
Geometry module.
+
namespace cubos::core::data
+
Data module.
+
+
+
+

Classes

+
+
+ struct cubos::core::geom::Simplex +
+
Represents a simplex shape, which may either be empty, a point, a line, a triangle or a tetrahedron.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/core_2samples_2data_2fs_2embedded__archive_2main_8cpp.html b/pr-preview/pr-589/core_2samples_2data_2fs_2embedded__archive_2main_8cpp.html new file mode 100644 index 000000000..d5d815a1c --- /dev/null +++ b/pr-preview/pr-589/core_2samples_2data_2fs_2embedded__archive_2main_8cpp.html @@ -0,0 +1,101 @@ + + + + + data/fs/embedded_archive/main.cpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ data/fs/embedded_archive/main.cpp file +

+

Sample which showcases how the EmbeddedArchive class can be used.

+

The assets directory on the same directory as this file was embedded into embed.cpp using the command quadrados embed -r assets > embed.cpp. Since no further options were specified, quadrados registered the data with the name of the embedded file - assets.

+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/cubos_8hpp.html b/pr-preview/pr-589/cubos_8hpp.html new file mode 100644 index 000000000..81e977ac4 --- /dev/null +++ b/pr-preview/pr-589/cubos_8hpp.html @@ -0,0 +1,150 @@ + + + + + engine/cubos.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ engine/cubos.hpp file +

+

Class cubos::engine::Cubos.

+ +
+

Namespaces

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

Classes

+
+
+ struct cubos::engine::DeltaTime +
+
Resource which stores the time since the last iteration of the main loop started.
+
+ struct cubos::engine::ShouldQuit +
+
Resource used as a flag to indicate whether the main loop should stop running.
+
+ struct cubos::engine::Arguments +
+
Resource which stores the command-line arguments.
+
+ class cubos::engine::TagBuilder +
+
Used to chain configurations related to tags.
+
+ class cubos::engine::SystemBuilder +
+
Used to chain configurations related to systems.
+
+ class cubos::engine::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/pr-preview/pr-589/cursor_8hpp.html b/pr-preview/pr-589/cursor_8hpp.html new file mode 100644 index 000000000..673da2595 --- /dev/null +++ b/pr-preview/pr-589/cursor_8hpp.html @@ -0,0 +1,132 @@ + + + + + core/io/cursor.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/debug_8hpp.html b/pr-preview/pr-589/debug_8hpp.html new file mode 100644 index 000000000..c01ee55d4 --- /dev/null +++ b/pr-preview/pr-589/debug_8hpp.html @@ -0,0 +1,132 @@ + + + + + core/gl/debug.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/deferred__renderer_8hpp.html b/pr-preview/pr-589/deferred__renderer_8hpp.html new file mode 100644 index 000000000..491c8d973 --- /dev/null +++ b/pr-preview/pr-589/deferred__renderer_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/renderer/deferred_renderer.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_0835e003fa277f66ce5cf543d578f6a2.html b/pr-preview/pr-589/dir_0835e003fa277f66ce5cf543d578f6a2.html new file mode 100644 index 000000000..48aea1cff --- /dev/null +++ b/pr-preview/pr-589/dir_0835e003fa277f66ce5cf543d578f6a2.html @@ -0,0 +1,134 @@ + + + + + engine/assets/ directory | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/dir_2a3f20446d92cb0b384d0cf4f4d26d60.html b/pr-preview/pr-589/dir_2a3f20446d92cb0b384d0cf4f4d26d60.html new file mode 100644 index 000000000..9774e0b55 --- /dev/null +++ b/pr-preview/pr-589/dir_2a3f20446d92cb0b384d0cf4f4d26d60.html @@ -0,0 +1,118 @@ + + + + + engine/window/ directory | CUBOS. + + + + + + + +
+
+
+
+
+

+ engine/window/ directory +

+

Window plugin directory.

+ +
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_3733897ca737f1fa8773f329655abd67.html b/pr-preview/pr-589/dir_3733897ca737f1fa8773f329655abd67.html new file mode 100644 index 000000000..5595f7f84 --- /dev/null +++ b/pr-preview/pr-589/dir_3733897ca737f1fa8773f329655abd67.html @@ -0,0 +1,118 @@ + + + + + engine/tools/entity_selector/ directory | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_38e9fb064544086d3594e70a41f6b257.html b/pr-preview/pr-589/dir_38e9fb064544086d3594e70a41f6b257.html new file mode 100644 index 000000000..0213d5d7d --- /dev/null +++ b/pr-preview/pr-589/dir_38e9fb064544086d3594e70a41f6b257.html @@ -0,0 +1,122 @@ + + + + + engine/scene/ directory | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_3a267dbab794906b09058daa283b3fee.html b/pr-preview/pr-589/dir_3a267dbab794906b09058daa283b3fee.html new file mode 100644 index 000000000..3015902e4 --- /dev/null +++ b/pr-preview/pr-589/dir_3a267dbab794906b09058daa283b3fee.html @@ -0,0 +1,124 @@ + + + + + engine/collisions/colliders/ directory | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_459dda10180a6131eb62bc74e02d0b6e.html b/pr-preview/pr-589/dir_459dda10180a6131eb62bc74e02d0b6e.html new file mode 100644 index 000000000..b1c81a2b1 --- /dev/null +++ b/pr-preview/pr-589/dir_459dda10180a6131eb62bc74e02d0b6e.html @@ -0,0 +1,118 @@ + + + + + engine/imgui/ directory | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_5f701044e65d6c264a6c1dc66b1052c2.html b/pr-preview/pr-589/dir_5f701044e65d6c264a6c1dc66b1052c2.html new file mode 100644 index 000000000..2b8e53ec8 --- /dev/null +++ b/pr-preview/pr-589/dir_5f701044e65d6c264a6c1dc66b1052c2.html @@ -0,0 +1,126 @@ + + + + + engine/transform/ directory | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_672562f1eb3ea0be7f3aa3e89e72ecd2.html b/pr-preview/pr-589/dir_672562f1eb3ea0be7f3aa3e89e72ecd2.html new file mode 100644 index 000000000..8527c5381 --- /dev/null +++ b/pr-preview/pr-589/dir_672562f1eb3ea0be7f3aa3e89e72ecd2.html @@ -0,0 +1,124 @@ + + + + + engine/renderer/pps/ directory | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_6c897dd97bedf3914ee8a4d9f7f6549c.html b/pr-preview/pr-589/dir_6c897dd97bedf3914ee8a4d9f7f6549c.html new file mode 100644 index 000000000..cd70e3bda --- /dev/null +++ b/pr-preview/pr-589/dir_6c897dd97bedf3914ee8a4d9f7f6549c.html @@ -0,0 +1,144 @@ + + + + + core/ directory | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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.
+
directory ui/
+
User Interface module.
+
+
+
+

Files

+
+
file log.hpp
+
Logging and assertion macros.
+
file thread_pool.hpp
+
Class cubos::core::ThreadPool.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_7376bacbd9e6243f425bd4c56d48edd9.html b/pr-preview/pr-589/dir_7376bacbd9e6243f425bd4c56d48edd9.html new file mode 100644 index 000000000..d2ad75490 --- /dev/null +++ b/pr-preview/pr-589/dir_7376bacbd9e6243f425bd4c56d48edd9.html @@ -0,0 +1,124 @@ + + + + + core/io/ directory | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_73cd920be1d9b25db5feb4d2a202c641.html b/pr-preview/pr-589/dir_73cd920be1d9b25db5feb4d2a202c641.html new file mode 100644 index 000000000..b2b48488e --- /dev/null +++ b/pr-preview/pr-589/dir_73cd920be1d9b25db5feb4d2a202c641.html @@ -0,0 +1,118 @@ + + + + + core/reflection/external/ directory | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/reflection/external/ directory +

+

Reflection declarations for external types.

+ +
+

Files

+
+
file primitives.hpp
+
Reflection declarations for primitive types.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_764b6913e5a035b506325f3918f13ed7.html b/pr-preview/pr-589/dir_764b6913e5a035b506325f3918f13ed7.html new file mode 100644 index 000000000..77ef6d94a --- /dev/null +++ b/pr-preview/pr-589/dir_764b6913e5a035b506325f3918f13ed7.html @@ -0,0 +1,118 @@ + + + + + engine/tools/world_inspector/ directory | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_79f402fdd7bbb1d73f9fd1aa85f618da.html b/pr-preview/pr-589/dir_79f402fdd7bbb1d73f9fd1aa85f618da.html new file mode 100644 index 000000000..653213c4c --- /dev/null +++ b/pr-preview/pr-589/dir_79f402fdd7bbb1d73f9fd1aa85f618da.html @@ -0,0 +1,128 @@ + + + + + core/data/fs/ directory | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/dir_85f1b5bc6fb8e602e74068211760bfae.html b/pr-preview/pr-589/dir_85f1b5bc6fb8e602e74068211760bfae.html new file mode 100644 index 000000000..d27f361b8 --- /dev/null +++ b/pr-preview/pr-589/dir_85f1b5bc6fb8e602e74068211760bfae.html @@ -0,0 +1,120 @@ + + + + + core/reflection/traits/ directory | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_8711f680e2d25dedddc79c2be2b1fda2.html b/pr-preview/pr-589/dir_8711f680e2d25dedddc79c2be2b1fda2.html new file mode 100644 index 000000000..32eea7d1a --- /dev/null +++ b/pr-preview/pr-589/dir_8711f680e2d25dedddc79c2be2b1fda2.html @@ -0,0 +1,120 @@ + + + + + engine/settings/ directory | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_87a7847ee77970235330560d79c37ce0.html b/pr-preview/pr-589/dir_87a7847ee77970235330560d79c37ce0.html new file mode 100644 index 000000000..d844788e3 --- /dev/null +++ b/pr-preview/pr-589/dir_87a7847ee77970235330560d79c37ce0.html @@ -0,0 +1,140 @@ + + + + + engine/renderer/ directory | CUBOS. + + + + + + + +
+
+
+
+
+

+ engine/renderer/ directory +

+

Renderer plugin directory.

+ +
+

Directories

+
+
directory pps/
+
Post processing directory.
+
+
+
+

Files

+
+
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.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_8b12085945cef5a7cea7b856ed1ac7f6.html b/pr-preview/pr-589/dir_8b12085945cef5a7cea7b856ed1ac7f6.html new file mode 100644 index 000000000..4195173ff --- /dev/null +++ b/pr-preview/pr-589/dir_8b12085945cef5a7cea7b856ed1ac7f6.html @@ -0,0 +1,118 @@ + + + + + engine/tools/scene_editor/ directory | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_8e5f84d20b1aa89c94160461e78e26c4.html b/pr-preview/pr-589/dir_8e5f84d20b1aa89c94160461e78e26c4.html new file mode 100644 index 000000000..1e6b28fb7 --- /dev/null +++ b/pr-preview/pr-589/dir_8e5f84d20b1aa89c94160461e78e26c4.html @@ -0,0 +1,126 @@ + + + + + engine/input/ directory | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_95549d37735ad5b142799f042eef0d37.html b/pr-preview/pr-589/dir_95549d37735ad5b142799f042eef0d37.html new file mode 100644 index 000000000..92f6310fa --- /dev/null +++ b/pr-preview/pr-589/dir_95549d37735ad5b142799f042eef0d37.html @@ -0,0 +1,118 @@ + + + + + core/data/ directory | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/data/ directory +

+

Data module.

+ +
+

Directories

+
+
directory fs/
+
Filesystem utilities directory.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_9b04cf786b414c0d644db09287f665e6.html b/pr-preview/pr-589/dir_9b04cf786b414c0d644db09287f665e6.html new file mode 100644 index 000000000..27879f035 --- /dev/null +++ b/pr-preview/pr-589/dir_9b04cf786b414c0d644db09287f665e6.html @@ -0,0 +1,118 @@ + + + + + engine/voxels/ directory | CUBOS. + + + + + + + +
+
+
+
+
+

+ engine/voxels/ directory +

+

Voxels plugin directory.

+ +
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_9bdaf8f561be1ffd03f616379797b70b.html b/pr-preview/pr-589/dir_9bdaf8f561be1ffd03f616379797b70b.html new file mode 100644 index 000000000..255655a31 --- /dev/null +++ b/pr-preview/pr-589/dir_9bdaf8f561be1ffd03f616379797b70b.html @@ -0,0 +1,130 @@ + + + + + core/memory/ directory | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/memory/ directory +

+

Memory module.

+ +
+

Files

+
+
file buffer_stream.hpp
+
Class cubos::core::memory::BufferStream.
+
file endianness.hpp
+
Endianness utility functions.
+
file guards.hpp
+
Classes cubos::core::memory::ReadGuard and cubos::core::memory::WriteGuard.
+
file move.hpp
+
Function cubos::core::memory::move.
+
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.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_b6daa990b896c2c0c53126427e4d978d.html b/pr-preview/pr-589/dir_b6daa990b896c2c0c53126427e4d978d.html new file mode 100644 index 000000000..d934b8412 --- /dev/null +++ b/pr-preview/pr-589/dir_b6daa990b896c2c0c53126427e4d978d.html @@ -0,0 +1,152 @@ + + + + + core/ecs/ directory | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/ecs/ directory +

+

ECS module.

+ +
+

Files

+
+
file accessors.hpp
+
Class cubos::core::ecs::Read and related types.
+
file blueprint.hpp
+
Class cubos::core::ecs::Blueprint.
+
file commands.hpp
+
Class cubos::core::ecs::Commands and related types.
+
file component_manager.hpp
+
Class cubos::core::ecs::ComponentManager and related types.
+
file dispatcher.hpp
+
Class cubos::core::ecs::Dispatcher.
+
file entity_manager.hpp
+
Class cubos::core::ecs::EntityManager and related types.
+
file event_pipe.hpp
+
Resource cubos::core::ecs::EventPipe.
+
file event_reader.hpp
+
Class cubos::core::ecs::EventReader.
+
file event_writer.hpp
+
Class cubos::core::ecs::EventWriter.
+
file map_storage.hpp
+
Class cubos::core::ecs::MapStorage.
+
file null_storage.hpp
+
Class cubos::core::ecs::NullStorage.
+
file query.hpp
+
Class cubos::core::ecs::Query and related types.
+
file registry.hpp
+
Class cubos::core::ecs::Registry and registration macro.
+
file resource_manager.hpp
+
Class cubos::core::ecs::ResourceManager and related types.
+
file storage.hpp
+
Class cubos::core::ecs::Storage and related types.
+
file system.hpp
+
Class cubos::core::ecs::SystemWrapper and related types.
+
file vec_storage.hpp
+
Class cubos::core::ecs::VecStorage.
+
file world.hpp
+
Class cubos::core::ecs::World.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_bafb7af0e03e95b24a45ff63060ab57b.html b/pr-preview/pr-589/dir_bafb7af0e03e95b24a45ff63060ab57b.html new file mode 100644 index 000000000..c84d8c68d --- /dev/null +++ b/pr-preview/pr-589/dir_bafb7af0e03e95b24a45ff63060ab57b.html @@ -0,0 +1,146 @@ + + + + + engine/ directory | CUBOS. + + + + + + + +
+
+
+
+
+

+ engine/ directory +

+

Engine module.

+ +
+

Directories

+
+
directory assets/
+
Assets plugin directory.
+
directory collisions/
+
Collisions plugin directory.
+
directory imgui/
+
ImGui integration ImGui plugin directory.
+
directory input/
+
Input plugin directory.
+
directory renderer/
+
Renderer plugin directory.
+
directory scene/
+
Scene plugin directory.
+
directory settings/
+
Settings plugin directory.
+
directory tools/
+
Tools plugins directory.
+
directory transform/
+
Transform plugin directory.
+
directory voxels/
+
Voxels plugin directory.
+
directory window/
+
Window plugin directory.
+
+
+
+

Files

+
+
file cubos.hpp
+
Class cubos::engine::Cubos.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_bd9be39c2ccf4132268583193b02b48c.html b/pr-preview/pr-589/dir_bd9be39c2ccf4132268583193b02b48c.html new file mode 100644 index 000000000..9e37c155c --- /dev/null +++ b/pr-preview/pr-589/dir_bd9be39c2ccf4132268583193b02b48c.html @@ -0,0 +1,122 @@ + + + + + engine/assets/bridges/ directory | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_c185369e92e3603c6d00fa8343148da7.html b/pr-preview/pr-589/dir_c185369e92e3603c6d00fa8343148da7.html new file mode 100644 index 000000000..2b1a29bcb --- /dev/null +++ b/pr-preview/pr-589/dir_c185369e92e3603c6d00fa8343148da7.html @@ -0,0 +1,128 @@ + + + + + engine/tools/ directory | CUBOS. + + + + + + + +
+
+
+
+
+

+ engine/tools/ directory +

+

Tools plugins directory.

+ +
+

Directories

+
+
directory asset_explorer/
+
Asset explorer plugin directory.
+
directory entity_inspector/
+
Entity inspector plugin directory.
+
directory entity_selector/
+
Entity selector plugin directory.
+
directory scene_editor/
+
Scene editor plugin directory.
+
directory settings_inspector/
+
Settings inspector plugin directory.
+
directory world_inspector/
+
World inspector plugin directory.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_c1deef5baf41393ad8a994c3fd53e62f.html b/pr-preview/pr-589/dir_c1deef5baf41393ad8a994c3fd53e62f.html new file mode 100644 index 000000000..5b393d166 --- /dev/null +++ b/pr-preview/pr-589/dir_c1deef5baf41393ad8a994c3fd53e62f.html @@ -0,0 +1,124 @@ + + + + + core/geom/ directory | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_c396301357880712663814927d68a432.html b/pr-preview/pr-589/dir_c396301357880712663814927d68a432.html new file mode 100644 index 000000000..bf1dab929 --- /dev/null +++ b/pr-preview/pr-589/dir_c396301357880712663814927d68a432.html @@ -0,0 +1,118 @@ + + + + + engine/tools/asset_explorer/ directory | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_c4311188e9cc606330f5e3e0b9dd5059.html b/pr-preview/pr-589/dir_c4311188e9cc606330f5e3e0b9dd5059.html new file mode 100644 index 000000000..8a96ee4a6 --- /dev/null +++ b/pr-preview/pr-589/dir_c4311188e9cc606330f5e3e0b9dd5059.html @@ -0,0 +1,132 @@ + + + + + core/gl/ directory | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/gl/ directory +

+

Graphics module.

+ +
+

Files

+
+
file camera.hpp
+
Class cubos::core::gl::Camera.
+
file debug.hpp
+
Class cubos::core::gl::Debug.
+
file grid.hpp
+
Class cubos::core::gl::Grid.
+
file material.hpp
+
Class cubos::core::gl::Material.
+
file palette.hpp
+
Class cubos::core::gl::Palette.
+
file render_device.hpp
+
Class cubos::core::gl::RenderDevice and related types.
+
file util.hpp
+
Function cubos::core::gl::generateScreenQuad.
+
file vertex.hpp
+
Class cubos::core::gl::Vertex and function cubos::core::gl::triangulate.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_d0ac2003a3c19c21d7ab7ff2f06fbec3.html b/pr-preview/pr-589/dir_d0ac2003a3c19c21d7ab7ff2f06fbec3.html new file mode 100644 index 000000000..abf658077 --- /dev/null +++ b/pr-preview/pr-589/dir_d0ac2003a3c19c21d7ab7ff2f06fbec3.html @@ -0,0 +1,118 @@ + + + + + engine/tools/entity_inspector/ directory | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_db86702e1371d7558db3699dd3786a14.html b/pr-preview/pr-589/dir_db86702e1371d7558db3699dd3786a14.html new file mode 100644 index 000000000..5f39d61d2 --- /dev/null +++ b/pr-preview/pr-589/dir_db86702e1371d7558db3699dd3786a14.html @@ -0,0 +1,130 @@ + + + + + engine/collisions/ directory | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_e42c9d7813efab99826f1cb60398c3fa.html b/pr-preview/pr-589/dir_e42c9d7813efab99826f1cb60398c3fa.html new file mode 100644 index 000000000..d31748b3a --- /dev/null +++ b/pr-preview/pr-589/dir_e42c9d7813efab99826f1cb60398c3fa.html @@ -0,0 +1,118 @@ + + + + + engine/tools/settings_inspector/ directory | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_f4414684a5bb1e1b8e9ba236e8bdb594.html b/pr-preview/pr-589/dir_f4414684a5bb1e1b8e9ba236e8bdb594.html new file mode 100644 index 000000000..04fd3c77a --- /dev/null +++ b/pr-preview/pr-589/dir_f4414684a5bb1e1b8e9ba236e8bdb594.html @@ -0,0 +1,130 @@ + + + + + core/reflection/ directory | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_f556bbe30cd07922836d0e9d7f5fa0a5.html b/pr-preview/pr-589/dir_f556bbe30cd07922836d0e9d7f5fa0a5.html new file mode 100644 index 000000000..0a880aa67 --- /dev/null +++ b/pr-preview/pr-589/dir_f556bbe30cd07922836d0e9d7f5fa0a5.html @@ -0,0 +1,122 @@ + + + + + core/ui/ directory | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dir_f6f65ff657bd34b22e5078310628f4e7.html b/pr-preview/pr-589/dir_f6f65ff657bd34b22e5078310628f4e7.html new file mode 100644 index 000000000..a792ae5d3 --- /dev/null +++ b/pr-preview/pr-589/dir_f6f65ff657bd34b22e5078310628f4e7.html @@ -0,0 +1,118 @@ + + + + + core/al/ directory | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/directional__light_8hpp.html b/pr-preview/pr-589/directional__light_8hpp.html new file mode 100644 index 000000000..9335f66e1 --- /dev/null +++ b/pr-preview/pr-589/directional__light_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/renderer/directional_light.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/dispatcher_8hpp.html b/pr-preview/pr-589/dispatcher_8hpp.html new file mode 100644 index 000000000..ea18e0c50 --- /dev/null +++ b/pr-preview/pr-589/dispatcher_8hpp.html @@ -0,0 +1,132 @@ + + + + + core/ecs/dispatcher.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/ecs_8hpp.html b/pr-preview/pr-589/ecs_8hpp.html new file mode 100644 index 000000000..ec97c4850 --- /dev/null +++ b/pr-preview/pr-589/ecs_8hpp.html @@ -0,0 +1,139 @@ + + + + + core/ui/ecs.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/ui/ecs.hpp file +

+

Functions cubos::core::ui::showWorld and cubos::core::ui::editWorld.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::ui
+
User Interface module.
+
+
+
+

Functions

+
+
+ void showWorld(const ecs::World& world, + data::Context* context = nullptr) +
+
Adds a ImGui window which allows the user to inspect the entities and components in a ecs::World.
+
+ void editWorld(ecs::World& world, + data::Context* serContext = nullptr, + data::Context* desContext = nullptr) +
+
Adds a ImGui window which allows the user to edit the entities and components in a ecs::World.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/embedded__archive_8hpp.html b/pr-preview/pr-589/embedded__archive_8hpp.html new file mode 100644 index 000000000..015d48060 --- /dev/null +++ b/pr-preview/pr-589/embedded__archive_8hpp.html @@ -0,0 +1,140 @@ + + + + + core/data/fs/embedded_archive.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/endianness_8hpp.html b/pr-preview/pr-589/endianness_8hpp.html new file mode 100644 index 000000000..3bff84ecc --- /dev/null +++ b/pr-preview/pr-589/endianness_8hpp.html @@ -0,0 +1,157 @@ + + + + + core/memory/endianness.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/engine_2include_2cubos_2engine_2assets_2bridges_2file_8hpp.html b/pr-preview/pr-589/engine_2include_2cubos_2engine_2assets_2bridges_2file_8hpp.html new file mode 100644 index 000000000..c17480299 --- /dev/null +++ b/pr-preview/pr-589/engine_2include_2cubos_2engine_2assets_2bridges_2file_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/assets/bridges/file.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/engine_2include_2cubos_2engine_2collisions_2colliders_2box_8hpp.html b/pr-preview/pr-589/engine_2include_2cubos_2engine_2collisions_2colliders_2box_8hpp.html new file mode 100644 index 000000000..8f68bab3e --- /dev/null +++ b/pr-preview/pr-589/engine_2include_2cubos_2engine_2collisions_2colliders_2box_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/collisions/colliders/box.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/engine_2include_2cubos_2engine_2collisions_2colliders_2capsule_8hpp.html b/pr-preview/pr-589/engine_2include_2cubos_2engine_2collisions_2colliders_2capsule_8hpp.html new file mode 100644 index 000000000..e917e5e49 --- /dev/null +++ b/pr-preview/pr-589/engine_2include_2cubos_2engine_2collisions_2colliders_2capsule_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/collisions/colliders/capsule.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/engine_2include_2cubos_2engine_2collisions_2colliders_2plane_8hpp.html b/pr-preview/pr-589/engine_2include_2cubos_2engine_2collisions_2colliders_2plane_8hpp.html new file mode 100644 index 000000000..856093954 --- /dev/null +++ b/pr-preview/pr-589/engine_2include_2cubos_2engine_2collisions_2colliders_2plane_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/collisions/colliders/plane.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/engine_2include_2cubos_2engine_2collisions_2colliders_2simplex_8hpp.html b/pr-preview/pr-589/engine_2include_2cubos_2engine_2collisions_2colliders_2simplex_8hpp.html new file mode 100644 index 000000000..274937d9a --- /dev/null +++ b/pr-preview/pr-589/engine_2include_2cubos_2engine_2collisions_2colliders_2simplex_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/collisions/colliders/simplex.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/entity__manager_8hpp.html b/pr-preview/pr-589/entity__manager_8hpp.html new file mode 100644 index 000000000..aa5594f79 --- /dev/null +++ b/pr-preview/pr-589/entity__manager_8hpp.html @@ -0,0 +1,140 @@ + + + + + core/ecs/entity_manager.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/ecs/entity_manager.hpp file +

+

Class cubos::core::ecs::EntityManager and related types.

+ +
+

Namespaces

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

Classes

+
+
+ class cubos::core::ecs::Entity +
+
Identifies an entity.
+
+ class cubos::core::ecs::EntityManager +
+
Holds and manages entities and their component masks.
+
+ class cubos::core::ecs::EntityManager::Iterator +
+
Used to iterate over all entities in a manager with a certain component mask.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/environment_8hpp.html b/pr-preview/pr-589/environment_8hpp.html new file mode 100644 index 000000000..a682ce836 --- /dev/null +++ b/pr-preview/pr-589/environment_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/renderer/environment.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/event__pipe_8hpp.html b/pr-preview/pr-589/event__pipe_8hpp.html new file mode 100644 index 000000000..7f66c0e4f --- /dev/null +++ b/pr-preview/pr-589/event__pipe_8hpp.html @@ -0,0 +1,133 @@ + + + + + core/ecs/event_pipe.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/event__reader_8hpp.html b/pr-preview/pr-589/event__reader_8hpp.html new file mode 100644 index 000000000..125d85698 --- /dev/null +++ b/pr-preview/pr-589/event__reader_8hpp.html @@ -0,0 +1,137 @@ + + + + + core/ecs/event_reader.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/ecs/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/pr-preview/pr-589/event__writer_8hpp.html b/pr-preview/pr-589/event__writer_8hpp.html new file mode 100644 index 000000000..704725b78 --- /dev/null +++ b/pr-preview/pr-589/event__writer_8hpp.html @@ -0,0 +1,133 @@ + + + + + core/ecs/event_writer.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/examples-core-logging.html b/pr-preview/pr-589/examples-core-logging.html new file mode 100644 index 000000000..a1582a1bc --- /dev/null +++ b/pr-preview/pr-589/examples-core-logging.html @@ -0,0 +1,116 @@ + + + + + Examples » Core » Logging | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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>

Before any logging is done, the logger must be initialized. This usually happens right at the beginning of the program.

int main()
+{
+    cubos::core::initializeLogger();

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");

These macros can also take arguments:

    CUBOS_ERROR("Error message with {} argument", 1);

Serializable types can also be logged, using cubos::core::data::Debug.

#include <cubos/core/data/debug_serializer.hpp>
+
+using namespace cubos::core::data;

By wrapping the value in cubos::core::data::Debug, the type is serialized using the cubos::core::data::DebugSerializer, and the result is logged.

    CUBOS_INFO("Serializable type: {}", Debug(glm::vec3(0.0F, 1.0F, 2.0F)));
+    CUBOS_INFO("Again, but with type information: {:t}", Debug(glm::vec3(0.0F, 1.0F, 2.0F)));
+    CUBOS_INFO("Since unordered maps are serializable, we can do this: {}",
+               Debug((std::unordered_map<int, const char*>{{1, "one"}, {2, "two"}})));
+}
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/examples-core-reflection-basic.html b/pr-preview/pr-589/examples-core-reflection-basic.html new file mode 100644 index 000000000..636d720ce --- /dev/null +++ b/pr-preview/pr-589/examples-core-reflection-basic.html @@ -0,0 +1,136 @@ + + + + + Examples » Core » Reflection » Basic Usage | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/examples-core-reflection-traits-constructible.html b/pr-preview/pr-589/examples-core-reflection-traits-constructible.html new file mode 100644 index 000000000..211fe2c2e --- /dev/null +++ b/pr-preview/pr-589/examples-core-reflection-traits-constructible.html @@ -0,0 +1,131 @@ + + + + + Examples » Core » Reflection » Constructible Trait | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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());
+    CUBOS_ASSERT(constructible.defaultConstruct(instance));
+    CUBOS_ASSERT(static_cast<Scale*>(instance)->value == 1.0F);

The defaultConstruct method returns a boolean which indicates if the type has a default constructor or not. In this case, since we added the default constructor to the trait, it will return true.

This could be useful, for example, to fallback from using moveConstruct to copyConstruct, if the first isn't available.

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/pr-preview/pr-589/examples-core-reflection.html b/pr-preview/pr-589/examples-core-reflection.html new file mode 100644 index 000000000..dd8459b8f --- /dev/null +++ b/pr-preview/pr-589/examples-core-reflection.html @@ -0,0 +1,103 @@ + + + + + Examples » Core » Reflection | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/examples-core.html b/pr-preview/pr-589/examples-core.html new file mode 100644 index 000000000..885df1aa3 --- /dev/null +++ b/pr-preview/pr-589/examples-core.html @@ -0,0 +1,102 @@ + + + + + Examples » Core | CUBOS. + + + + + + + +
+
+
+
+
+

+ Examples » + Core +

+

Showcases features of the Core library.

+

The following examples have fully documented tutorials:

+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/examples-engine-assets-bridge.html b/pr-preview/pr-589/examples-engine-assets-bridge.html new file mode 100644 index 000000000..79bb36bf0 --- /dev/null +++ b/pr-preview/pr-589/examples-engine-assets-bridge.html @@ -0,0 +1,146 @@ + + + + + Examples » Engine » Assets » Introducion and Custom Bridges | CUBOS. + + + + + + + +
+
+
+
+
+

+ Examples » + Engine » + Assets » + Introducion 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(typeid(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.

static void bridgeSystem(Write<Assets> assets)
+{
+    // Add a custom bridge to load .txt files.
+    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");
+
+static void loadSystem(Read<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.

    cubos.addPlugin(assetsPlugin);
+    cubos.startupSystem(bridgeSystem).tagged("cubos.assets.bridge");
+    cubos.startupSystem(loadSystem).tagged("cubos.assets");
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/examples-engine-assets-json.html b/pr-preview/pr-589/examples-engine-assets-json.html new file mode 100644 index 000000000..3a5401d36 --- /dev/null +++ b/pr-preview/pr-589/examples-engine-assets-json.html @@ -0,0 +1,135 @@ + + + + + Examples » Engine » Assets » Loading Serializable Assets | CUBOS. + + + + + + + +
+
+
+
+
+

+ Examples » + Engine » + Assets » + Loading Serializable Assets +

+

Loading serializable assets from JSON.

+

We'll use the following type as an example:

struct Strings
+{
+    std::vector<std::string> strings;
+};

We can make it serializable by implementing the following specializations:

template <>
+void cubos::core::data::serialize<Strings>(Serializer& ser, const Strings& obj, const char* name)
+{
+    ser.beginObject(name);
+    ser.write(obj.strings, "strings");
+    ser.endObject();
+}
+
+template <>
+void cubos::core::data::deserialize<Strings>(Deserializer& des, Strings& obj)
+{
+    des.beginObject();
+    des.read(obj.strings);
+    des.endObject();
+}

Then, we must register a bridge for this type. We provide JSONBridge for easily loading and saving serializable assets as JSON.

static void bridgeSystem(Write<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");
+
+static void loadSystem(Write<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 Introducion and Custom Bridges.

    cubos.addPlugin(assetsPlugin);
+    cubos.startupSystem(bridgeSystem).tagged("cubos.assets.bridge");
+    cubos.startupSystem(loadSystem).tagged("cubos.assets");
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/examples-engine-assets-saving.html b/pr-preview/pr-589/examples-engine-assets-saving.html new file mode 100644 index 000000000..9b063697f --- /dev/null +++ b/pr-preview/pr-589/examples-engine-assets-saving.html @@ -0,0 +1,115 @@ + + + + + Examples » Engine » Assets » Creating and Saving | CUBOS. + + + + + + + +
+
+
+
+
+

+ Examples » + Engine » + Assets » + Creating and Saving +

+

Creating and saving assets.

+

This example demonstrates how a new asset 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:

static void configSystem(Write<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
+{
+    int value;
+};

First, we'll create an asset of this type:

static void saveSystem(Write<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. Its 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.

Finally, the engine is configured the following way:

    cubos.addPlugin(assetsPlugin);
+    cubos.startupSystem(saveSystem).tagged("cubos.assets");

Try running the sample yourself to see the files being created!

+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/examples-engine-assets.html b/pr-preview/pr-589/examples-engine-assets.html new file mode 100644 index 000000000..b7d76fc7c --- /dev/null +++ b/pr-preview/pr-589/examples-engine-assets.html @@ -0,0 +1,103 @@ + + + + + Examples » Engine » Assets | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/examples-engine-events.html b/pr-preview/pr-589/examples-engine-events.html new file mode 100644 index 000000000..126ab7d93 --- /dev/null +++ b/pr-preview/pr-589/examples-engine-events.html @@ -0,0 +1,151 @@ + + + + + Examples » Engine » Events | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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.

For convinience, we introduce these names in our scope with using-declarations.

using cubos::core::ecs::EventReader;
+using cubos::core::ecs::EventWriter;

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).

static void firstSystem(EventReader<MyEvent> reader) 
+{
+    for (const auto& event : reader)
+    {
+        CUBOS_INFO("A 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.

static void secondSystem(EventWriter<MyEvent> writer, Write<State> state, Write<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");
+    }
+}

Lastly, let's set the order we want these system to execute in.

    cubos.system(firstSystem).tagged("A").before("B");
+    cubos.system(secondSystem).tagged("B");
+    cubos.system(thirdSystem).tagged("C").after("B");
+    cubos.system(fourthSystem).tagged("D").after("C");

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/pr-preview/pr-589/examples-engine-renderer.html b/pr-preview/pr-589/examples-engine-renderer.html new file mode 100644 index 000000000..62b8818e9 --- /dev/null +++ b/pr-preview/pr-589/examples-engine-renderer.html @@ -0,0 +1,150 @@ + + + + + Examples » Engine » Renderer | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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.

    cubos.addPlugin(rendererPlugin);

The first thing we're going to worry about is setting the Palette the renderer will use. This palette would usually be loaded from a file, but for this example we'll just create it manually.

static void setPaletteSystem(Write<Renderer> renderer)
+{
+    using cubos::core::gl::Palette;
+
+    // Create a simple palette with 3 materials (red, green and blue).
+    (*renderer)->setPalette(Palette{{
+        {{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.

static void spawnVoxelGridSystem(Commands commands, Write<Assets> assets)
+{
+    using cubos::core::gl::Grid;
+
+    // Create a 2x2x2 grid whose voxels alternate between the materials defined in the palette.
+    auto gridAsset = assets->create(Grid{{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(RenderableGrid{gridAsset, {-1.0F, 0.0F, -1.0F}}, LocalToWorld{});
+}

If we don't add any lights, the scene will be completely dark. Lets add a simple PointLight.

static void spawnLightSystem(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.

static void setEnvironmentSystem(Write<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.

static void spawnCamerasSystem(Commands commands, Write<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();
+
+    // Add two other viewports using the same camera, which splits the screen in three.
+    camera->entities[1] = camera->entities[0];
+    camera->entities[2] = camera->entities[0];
+}

Then, its just a matter of adding these systems to the engine. The only one which requires special attention is the setPaletteSystem. This system accesses the Renderer resource, which is only initialized on the tag cubos.renderer.init.

    cubos.startupSystem(setPaletteSystem).after("cubos.renderer.init");
+    cubos.startupSystem(spawnVoxelGridSystem);
+    cubos.startupSystem(spawnLightSystem);
+    cubos.startupSystem(setEnvironmentSystem);
+    cubos.startupSystem(spawnCamerasSystem);
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/examples-engine-scene.html b/pr-preview/pr-589/examples-engine-scene.html new file mode 100644 index 000000000..f932f941f --- /dev/null +++ b/pr-preview/pr-589/examples-engine-scene.html @@ -0,0 +1,134 @@ + + + + + Examples » Engine » Scene | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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,
+      "parent": "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 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 has two components, a parent and a num. 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.

{
+  "imports": {
+    "sub1": "cd007ba2-ee0d-44fd-bf36-85c829dbe66f",
+    "sub2": "cd007ba2-ee0d-44fd-bf36-85c829dbe66f"
+  },
+  "entities": {
+    "main": {
+      "num": 0
+    },
+    "sub1.root": {
+      "parent": "main"
+    },
+    "sub2.root": {
+      "parent": "main"
+    }
+  }
+}

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.

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 parent 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.

static void spawnScene(Commands commands, Read<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(spawnScene).tagged("spawn").tagged("cubos.assets");

This sample will output the list of every entity in the scene, so you can check that everything is working as expected. If you run it, it should give you a list that has:

  • an entity with num set to 0, with no parent. This is the main entity.
  • two entities with num set to 1, with same parent, who has num set to 0. These are the root entities of each instance of the subscene.
  • two entities with num set to 2, with different parents, but both of them having num set to 1. These are the child entities of each instance of the subscene.
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/examples-engine-settings.html b/pr-preview/pr-589/examples-engine-settings.html new file mode 100644 index 000000000..3f037c3ae --- /dev/null +++ b/pr-preview/pr-589/examples-engine-settings.html @@ -0,0 +1,112 @@ + + + + + Examples » Engine » Settings | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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.

Accesing the settings is straightforward:

static void checkSettings(Write<Settings> settings)
+{
+    CUBOS_INFO("{}", settings->getString("greeting", "Hello!"));
+}

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.

We want this system to run after the settings have been loaded, so we run it after the tag cubos.settings. 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.

int main(int argc, char** argv)
+{
+    Cubos cubos{argc, argv};
+    cubos.addPlugin(settingsPlugin);
+    cubos.startupSystem(checkSettings).after("cubos.settings");
+    cubos.run();
+}
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/examples-engine.html b/pr-preview/pr-589/examples-engine.html new file mode 100644 index 000000000..f88d7407a --- /dev/null +++ b/pr-preview/pr-589/examples-engine.html @@ -0,0 +1,102 @@ + + + + + Examples » Engine | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/examples.html b/pr-preview/pr-589/examples.html new file mode 100644 index 000000000..f4c814145 --- /dev/null +++ b/pr-preview/pr-589/examples.html @@ -0,0 +1,101 @@ + + + + + Examples | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/favicon-dark.png b/pr-preview/pr-589/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/pr-preview/pr-589/features-ecs.html b/pr-preview/pr-589/features-ecs.html new file mode 100644 index 000000000..87e9440f5 --- /dev/null +++ b/pr-preview/pr-589/features-ecs.html @@ -0,0 +1,172 @@ + + + + + Feature Guide » ECS | CUBOS. + + + + + + + + +
+
+
+
+
+

+ 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:

  • 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).
  • 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.
  • Dispatcher - decides when each system is called and knows which systems are independent from each other so they can be called at the same time (parallel computing).

On the engine side, the Dispatcher is not exposed. Instead, the Cubos class is used to add systems and specify when they should be called.

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 [[cubos::component("position")]] Position
+{
+    glm::vec3 vec = { 0.0f, 0.0f, 0.0f };
+};
+
+struct [[cubos::component("velocity")]] Velocity
+{
+    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, we use the Read and Write arguments. In this case, we won't be modifying the delta time, so we will use Read<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<Write<Position>, Read<Velocity>>.

void velocitySystem(
+    Read<DeltaTime> dt,
+    Query<Write<Position>, Read<Velocity>> query)
+{
+    for (auto [entity, 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 resources and components

Before components 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.addComponent<Velocity>();
+cubos.addResource<DeltaTime>();

Commands

When you have direct access to the World, you can manipulate entities directly:

auto entity = world.create(Position {}, Velocity {});
+world.removeComponent<Velocity>(entity);
+world.addComponent(entity, Dead {});
+world.destroy(entity);

If necessary, you can access the world in a system through the arguments Read<World> or Write<World>. However, this is not recommended, since it becomes impossible for the dispatcher to know what the system is accessing, and thus it 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:

void spawnerSystem(
+    Commands commands,
+    Query<Read<Spawner>, Read<Position>> spawners)
+{
+    for (auto [entity, spawner, position] : spawners)
+    {
+        commands.create(
+            Position { position->vec },
+            Velocity { glm::vec3(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.

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", Position{...}, ...);
+motorbike.create("front_wheel", Parent{body}, ...);
+motorbike.create("back_wheel", Parent{body}, ...);

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/pr-preview/pr-589/features-plugins.html b/pr-preview/pr-589/features-plugins.html new file mode 100644 index 000000000..ef6c8393e --- /dev/null +++ b/pr-preview/pr-589/features-plugins.html @@ -0,0 +1,142 @@ + + + + + Feature Guide » Plugins | CUBOS. + + + + + + + + + +
+
+
+
+
+

+ 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::engine::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/cubos.hpp>
+
+#include <iostream>
+
+using Cubos = cubos::engine::Cubos;
+
+void helloWorld()
+{
+    std::cout << "Hello World!" << std::endl;
+}
+
+int main()
+{
+    Cubos cubos;
+    cubos.startupSystem(helloWorld);
+    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/cubos.hpp>
+
+#include <iostream>
+
+using Cubos = cubos::engine::Cubos;
+
+void helloWorld()
+{
+    std::cout << "Hello World!" << std::endl;
+}
+
+void helloWorldPlugin(Cubos& cubos)
+{
+    cubos.startupSystem(helloWorld);
+}
+
+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/pr-preview/pr-589/features-quadrados.html b/pr-preview/pr-589/features-quadrados.html new file mode 100644 index 000000000..a42a181ca --- /dev/null +++ b/pr-preview/pr-589/features-quadrados.html @@ -0,0 +1,121 @@ + + + + + Feature Guide » Quadrados | CUBOS. + + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/features.html b/pr-preview/pr-589/features.html new file mode 100644 index 000000000..4eb7a1b43 --- /dev/null +++ b/pr-preview/pr-589/features.html @@ -0,0 +1,100 @@ + + + + + Feature Guide | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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.
  • 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/pr-preview/pr-589/file__stream_8hpp.html b/pr-preview/pr-589/file__stream_8hpp.html new file mode 100644 index 000000000..f4391be04 --- /dev/null +++ b/pr-preview/pr-589/file__stream_8hpp.html @@ -0,0 +1,133 @@ + + + + + core/data/fs/file_stream.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/file__system_8hpp.html b/pr-preview/pr-589/file__system_8hpp.html new file mode 100644 index 000000000..a2dfcbba7 --- /dev/null +++ b/pr-preview/pr-589/file__system_8hpp.html @@ -0,0 +1,132 @@ + + + + + core/data/fs/file_system.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/files.html b/pr-preview/pr-589/files.html new file mode 100644 index 000000000..cd42d9d72 --- /dev/null +++ b/pr-preview/pr-589/files.html @@ -0,0 +1,395 @@ + + + + + CUBOS. + + + + + + + +
+
+
+
+
+

Files

+ + +
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/frame_8hpp.html b/pr-preview/pr-589/frame_8hpp.html new file mode 100644 index 000000000..2c8c6952d --- /dev/null +++ b/pr-preview/pr-589/frame_8hpp.html @@ -0,0 +1,134 @@ + + + + + engine/renderer/frame.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/gamepad_8hpp.html b/pr-preview/pr-589/gamepad_8hpp.html new file mode 100644 index 000000000..9955f3e38 --- /dev/null +++ b/pr-preview/pr-589/gamepad_8hpp.html @@ -0,0 +1,191 @@ + + + + + core/io/gamepad.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/io/gamepad.hpp file +

+

Struct Gref 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/pr-preview/pr-589/getting-started.html b/pr-preview/pr-589/getting-started.html new file mode 100644 index 000000000..15f3dd0ab --- /dev/null +++ b/pr-preview/pr-589/getting-started.html @@ -0,0 +1,101 @@ + + + + + Getting started | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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 Separately
CMakeEssential-Yes
jsonEssential-No
gladEssential-No
glfwEssentialcore/lib/glfwOptionally
glmEssentialcore/lib/glmOptionally
fmtEssentialcore/lib/fmtOptionally
spdlogEssentialcore/lib/spdlogOptionally
stduuidEssentialcore/lib/stduuidNo
doctestRequired for testscore/lib/doctestOptionally

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

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?
SPDLOG_USE_SUBMODULECompile spdlog from source?
FMT_USE_SUBMODULECompile fmt 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/pr-preview/pr-589/grid_8hpp.html b/pr-preview/pr-589/grid_8hpp.html new file mode 100644 index 000000000..efe38bfd7 --- /dev/null +++ b/pr-preview/pr-589/grid_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/gl/grid.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/group__asset-explorer-tool-plugin.html b/pr-preview/pr-589/group__asset-explorer-tool-plugin.html new file mode 100644 index 000000000..ed76f1327 --- /dev/null +++ b/pr-preview/pr-589/group__asset-explorer-tool-plugin.html @@ -0,0 +1,153 @@ + + + + + Engine » Tools » Asset explorer module | CUBOS. + + + + + + + +
+
+
+
+
+

+ Engine » + Tools » + 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& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void assetExplorerPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/group__assets-plugin.html b/pr-preview/pr-589/group__assets-plugin.html new file mode 100644 index 000000000..093f34222 --- /dev/null +++ b/pr-preview/pr-589/group__assets-plugin.html @@ -0,0 +1,294 @@ + + + + + Engine » Assets module | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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 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<typename 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.
+
+ 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/pr-preview/pr-589/group__collisions-plugin.html b/pr-preview/pr-589/group__collisions-plugin.html new file mode 100644 index 000000000..e1b49d9d6 --- /dev/null +++ b/pr-preview/pr-589/group__collisions-plugin.html @@ -0,0 +1,197 @@ + + + + + Engine » Collisions module | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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.

Resources

Tags

  • cubos.collisions.aabb.missing - missing aabb colliders are added.
  • cubos.collisions.aabb - collider aabbs are updated.
  • cubos.collisions.broad.markers - sweep markers are updated.
  • cubos.collisions.broad.sweep - sweep is performed.
  • cubos.collisions.broad - broad phase collision detection.
  • cubos.collisions - collisions are resolved.

Dependencies

+
+

Files

+
+
file aabb.hpp
+
Component cubos::engine::ColliderAABB.
+
file broad_phase_collisions.hpp
+
Resource cubos::engine::BroadPhaseCollisions.
+
file box.hpp
+
Component cubos::engine::BoxCollider.
+
file capsule.hpp
+
Component cubos::engine::CapsuleCollider.
+
file plane.hpp
+
Component cubos::engine::PlaneCollider.
+
file simplex.hpp
+
Component cubos::engine::SimplexCollider.
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Classes

+
+
+ struct cubos::engine::ColliderAABB +
+
Component which stores the AABB of an entity with a collider component.
+
+ struct cubos::engine::BroadPhaseCollisions +
+
Resource which stores data used in broad phase collision detection.
+
+ struct cubos::engine::BoxCollider +
+
Component which adds a box collider to an entity.
+
+ struct cubos::engine::CapsuleCollider +
+
Component which adds a capsule collider to an entity.
+
+ struct cubos::engine::PlaneCollider +
+
Component which adds a plane collider to an entity.
+
+ struct cubos::engine::SimplexCollider +
+
Component which adds a simplex collider to an entity.
+
+
+
+

Functions

+
+
+ void collisionsPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void collisionsPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/group__core-al.html b/pr-preview/pr-589/group__core-al.html new file mode 100644 index 000000000..ba4ed02ba --- /dev/null +++ b/pr-preview/pr-589/group__core-al.html @@ -0,0 +1,151 @@ + + + + + Core » Audio module | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/group__core-data-fs.html b/pr-preview/pr-589/group__core-data-fs.html new file mode 100644 index 000000000..125dfdb60 --- /dev/null +++ b/pr-preview/pr-589/group__core-data-fs.html @@ -0,0 +1,160 @@ + + + + + Core » Data » Filesystem module | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/group__core-data.html b/pr-preview/pr-589/group__core-data.html new file mode 100644 index 000000000..82798189f --- /dev/null +++ b/pr-preview/pr-589/group__core-data.html @@ -0,0 +1,118 @@ + + + + + Core » Data module | CUBOS. + + + + + + + +
+
+
+
+
+

+ Core » + Data module

+

Provides filesystem and serialization utilities.

+ +
+

Modules

+
+
module Filesystem
+
Provides filesystem utilities.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/group__core-ecs.html b/pr-preview/pr-589/group__core-ecs.html new file mode 100644 index 000000000..08c58be31 --- /dev/null +++ b/pr-preview/pr-589/group__core-ecs.html @@ -0,0 +1,404 @@ + + + + + Core » ECS module | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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

  • Read<R> - used to read resource data of type R.
  • Write<R> - used to write resource data of type R.
  • Read<World> - used to read the world directly (not recommended, ruins parallelism, prefer Commands).
  • Write<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

  • Read<C> - matches entities with the component C, read-only access.
  • Write<C> - matches entities with the component C, write access.
  • OptRead<C> - matches all entities, read-only access when the component C is present.
  • OptWrite<C> - matches all entities, write access when the component C is present.
+
+

Files

+
+
file accessors.hpp
+
Class cubos::core::ecs::Read and related types.
+
file blueprint.hpp
+
Class cubos::core::ecs::Blueprint.
+
file commands.hpp
+
Class cubos::core::ecs::Commands and related types.
+
file component_manager.hpp
+
Class cubos::core::ecs::ComponentManager and related types.
+
file dispatcher.hpp
+
Class cubos::core::ecs::Dispatcher.
+
file entity_manager.hpp
+
Class cubos::core::ecs::EntityManager and related types.
+
file event_pipe.hpp
+
Resource cubos::core::ecs::EventPipe.
+
file event_reader.hpp
+
Class cubos::core::ecs::EventReader.
+
file event_writer.hpp
+
Class cubos::core::ecs::EventWriter.
+
file map_storage.hpp
+
Class cubos::core::ecs::MapStorage.
+
file null_storage.hpp
+
Class cubos::core::ecs::NullStorage.
+
file query.hpp
+
Class cubos::core::ecs::Query and related types.
+
file registry.hpp
+
Class cubos::core::ecs::Registry and registration macro.
+
file resource_manager.hpp
+
Class cubos::core::ecs::ResourceManager and related types.
+
file storage.hpp
+
Class cubos::core::ecs::Storage and related types.
+
file system.hpp
+
Class cubos::core::ecs::SystemWrapper and related types.
+
file vec_storage.hpp
+
Class cubos::core::ecs::VecStorage.
+
file world.hpp
+
Class cubos::core::ecs::World.
+
+
+
+

Classes

+
+
+
template<typename T>
+ class cubos::core::ecs::Read +
+
System argument which provides read access to the resource T, or query argument which provides read access to the component T.
+
+
template<typename T>
+ class cubos::core::ecs::Write +
+
System argument which provides write access to the resource T, or query argument which provides write access to the component T.
+
+
template<typename T>
+ class cubos::core::ecs::OptRead +
+
System argument which provides read access to the resource T if it exists, or query argument which provides read access to the component T if it exists.
+
+
template<typename T>
+ class cubos::core::ecs::OptWrite +
+
System argument which provides write access to the resource T if it exists, or query argument which provides write access to the component T if it exists.
+
+ class cubos::core::ecs::EntityBuilder +
+
Allows editing an entity created by a Commands object.
+
+ class cubos::core::ecs::BlueprintBuilder +
+
Used to edit a blueprint spawned by a Commands object.
+
+ class cubos::core::ecs::Commands +
+
Used to write ECS commands and execute them at a later time.
+
+ class cubos::core::ecs::CommandBuffer +
+
Stores commands to execute them later.
+
+
template<typename T>
+ class cubos::core::ecs::ReadStorage +
+
Utility struct used to reference a storage of component type T for reading.
+
+
template<typename T>
+ class cubos::core::ecs::WriteStorage +
+
Utility struct used to reference a storage of component type T for writing.
+
+ class cubos::core::ecs::ComponentManager +
+
Holds and manages components.
+
+ class cubos::core::ecs::Dispatcher +
+
Used to add systems and relations between them and then dispatch them all at once.
+
+ class cubos::core::ecs::Entity +
+
Identifies an entity.
+
+ class cubos::core::ecs::EntityManager +
+
Holds and manages entities and their component masks.
+
+
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 T>
+ class cubos::core::ecs::MapStorage +
+
Storage implementation that uses an std::unordered_map.
+
+
template<typename T>
+ class cubos::core::ecs::NullStorage +
+
Storage implementation that doesn't keep any data, made for zero-sized components.
+
+ struct cubos::core::ecs::QueryInfo +
+
Describes a query.
+
+
template<typename... ComponentTypes>
+ class cubos::core::ecs::Query +
+
Holds the result of a query over all entities in world which match the given arguments.
+
+ class cubos::core::ecs::Registry +
+
Singleton which holds a global registry for all component types.
+
+
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.
+
+ class cubos::core::ecs::IStorage +
+
Abstract parent class for all storages.
+
+
template<typename T>
+ class cubos::core::ecs::Storage +
+
Abstract container for a component type T.
+
+ struct cubos::core::ecs::SystemInfo +
+
Describes a system.
+
+
template<typename R>
+ class cubos::core::ecs::AnySystemWrapper +
+
Base class for system wrappers.
+
+
template<typename F>
+ class cubos::core::ecs::SystemWrapper +
+
Wrapper for a system of type F.
+
+
template<typename T>
+ class cubos::core::ecs::VecStorage +
+
Storage implementation that uses a std::vector.
+
+ class cubos::core::ecs::World +
+
Holds entities, their components and resources.
+
+
+
+

Functions

+
+
+
template<typename T>
+ auto getComponentName() -> std::optional<std::string_view> +
+
Gets the registered name of a component type.
+
+ auto getComponentName(std::type_index type) -> std::optional<std::string_view> +
+
Gets the registered name of a component type.
+
+
+
+

Defines

+
+
+ #define CUBOS_REGISTER_COMPONENT(type, + storageType, + name) +
+
Macro used to register a component type as an alternative to calling cubos::core::ecs::Registry::add() manually.
+
+
+
+

Function documentation

+
+

+ +
+ template<typename T> +
+ std::optional<std::string_view> getComponentName() +

+

Gets the registered name of a component type.

+ + + + + + + + + + + + + + + + +
Template parameters
TComponent type.
ReturnsRegistered name of the component type.
+

If the component type is not registered, aborts the program.

+
+
+

+ std::optional<std::string_view> getComponentName(std::type_index type) + +

+

Gets the registered name of a component type.

+ + + + + + + + + + + + + + + + +
Parameters
typeComponent type.
ReturnsRegistered name of the component type.
+

If the component type is not registered, aborts the program.

+
+
+
+

Define documentation

+
+

+ #define CUBOS_REGISTER_COMPONENT(type, + storageType, + name) + +

+

Macro used to register a component type as an alternative to calling cubos::core::ecs::Registry::add() manually.

+ +
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/group__core-geom.html b/pr-preview/pr-589/group__core-geom.html new file mode 100644 index 000000000..b046d975c --- /dev/null +++ b/pr-preview/pr-589/group__core-geom.html @@ -0,0 +1,146 @@ + + + + + Core » Geometry module | CUBOS. + + + + + + + +
+
+
+
+
+

+ Core » + Geometry module

+

Provides geometry utilities.

+ +
+

Files

+
+
file box.hpp
+
Class cubos::core::geom::Box.
+
file capsule.hpp
+
Class cubos::core::geom::Capsule.
+
file plane.hpp
+
Class cubos::core::geom::Plane.
+
file simplex.hpp
+
Class cubos::core::geom::Simplex.
+
+
+
+

Classes

+
+
+ struct cubos::core::geom::Box +
+
Represents a box shape.
+
+ struct cubos::core::geom::Capsule +
+
Represents a capsule or sphere shape.
+
+ struct cubos::core::geom::Plane +
+
Represents a plane shape.
+
+ struct cubos::core::geom::Simplex +
+
Represents a simplex shape, which may either be empty, a point, a line, a triangle or a tetrahedron.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/group__core-gl.html b/pr-preview/pr-589/group__core-gl.html new file mode 100644 index 000000000..bb721785b --- /dev/null +++ b/pr-preview/pr-589/group__core-gl.html @@ -0,0 +1,1320 @@ + + + + + Core » Graphics module | CUBOS. + + + + + + + +
+
+
+
+
+

+ Core » + Graphics module

+

Provides a graphics API abstraction and some voxel utilities.

+ +
+

Files

+
+
file camera.hpp
+
Class cubos::core::gl::Camera.
+
file debug.hpp
+
Class cubos::core::gl::Debug.
+
file grid.hpp
+
Class cubos::core::gl::Grid.
+
file material.hpp
+
Class cubos::core::gl::Material.
+
file palette.hpp
+
Class cubos::core::gl::Palette.
+
file render_device.hpp
+
Class cubos::core::gl::RenderDevice and related types.
+
file util.hpp
+
Function cubos::core::gl::generateScreenQuad.
+
file vertex.hpp
+
Class cubos::core::gl::Vertex and function cubos::core::gl::triangulate.
+
+
+
+

Classes

+
+
+ struct cubos::core::gl::Camera +
+
Describes a camera.
+
+ class cubos::core::gl::Debug +
+
Singleton with static methods used to draw primitive objects on screen for debugging purposes.
+
+ class cubos::core::gl::Grid +
+
Represents a voxel object using a 3D grid.
+
+ struct cubos::core::gl::Material +
+
Describes a voxel material.
+
+ class cubos::core::gl::Palette +
+
Holds a palette of materials. Supports up to 65535 materials.
+
+ 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.
+
+ struct cubos::core::gl::Vertex +
+
Represents a voxel vertex.
+
+
+
+

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 triangulate(const Grid& grid, + std::vector<Vertex>& vertices, + std::vector<uint32_t>& indices) +
+
Triangulates a grid of voxels into an indexed mesh.
+
+
+
+

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.

+ +
+
+
+

Function documentation

+
+

+ void triangulate(const Grid& grid, + std::vector<Vertex>& 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.
+
+
+
+

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/pr-preview/pr-589/group__core-io.html b/pr-preview/pr-589/group__core-io.html new file mode 100644 index 000000000..9682e00c2 --- /dev/null +++ b/pr-preview/pr-589/group__core-io.html @@ -0,0 +1,753 @@ + + + + + Core » Input and output module | CUBOS. + + + + + + + +
+
+
+
+
+

+ Core » + Input and output module

+

Provides a window API abstraction.

+ +
+

Files

+
+
file cursor.hpp
+
Class cubos::core::io::Cursor.
+
file gamepad.hpp
+
Struct Gref 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::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 modifiersToString(Modifiers modifiers) -> std::string +
+
Converts a Modifiers enum to a string.
+
+ auto stringToModifiers(const std::string& str) -> Modifiers +
+
Converts a string to a Modifiers enum.
+
+ auto keyToString(Key key) -> std::string +
+
Converts a Key enum to a string.
+
+ auto stringToKey(const std::string& str) -> Key +
+
Convert a string to a Key enum.
+
+ auto openWindow(const std::string& title = "CUBOS.", + const glm::ivec2& size = {800, 600}) -> Window +
+
Opens a new window.
+
+
+
+

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.
+
+
+

+ std::string modifiersToString(Modifiers modifiers) + +

+

Converts a Modifiers enum to a string.

+ + + + + + + + + + + + + + + + +
Parameters
modifiersModifiers.
ReturnsString representation.
+
+
+

+ Modifiers stringToModifiers(const std::string& str) + +

+

Converts a string to a Modifiers enum.

+ + + + + + + + + + + + + + + + +
Parameters
strString to convert.
ReturnsModifiers.
+
+
+

+ std::string keyToString(Key key) + +

+

Converts a Key enum to a string.

+ + + + + + + + + + + + + + + + +
Parameters
keyKey to convert.
ReturnsString representation.
+
+
+

+ Key stringToKey(const std::string& str) + +

+

Convert a string to a Key enum.

+ + + + + + + + + + + + + + + + +
Parameters
strThe string to convert.
ReturnsKey.
+
+
+

+ 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.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/group__core-memory.html b/pr-preview/pr-589/group__core-memory.html new file mode 100644 index 000000000..de06b15b5 --- /dev/null +++ b/pr-preview/pr-589/group__core-memory.html @@ -0,0 +1,460 @@ + + + + + Core » Memory module | CUBOS. + + + + + + + +
+
+
+
+
+

+ Core » + Memory module

+

Provides a stream library and memory utilities.

+ +
+

Files

+
+
file buffer_stream.hpp
+
Class cubos::core::memory::BufferStream.
+
file endianness.hpp
+
Endianness utility functions.
+
file guards.hpp
+
Classes cubos::core::memory::ReadGuard and cubos::core::memory::WriteGuard.
+
file move.hpp
+
Function cubos::core::memory::move.
+
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.
+
+
+
+

Classes

+
+
+ class cubos::core::memory::BufferStream +
+
Stream implementation which writes to/reads from a buffer.
+
+
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 types as keys.
+
+
+
+

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&& +
+
Returns an R-value reference to the given value.
+
+
+
+

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) +

+

Returns an R-value reference to the given value.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TValue type.
Parameters
valueValue to move.
ReturnsMoved value.
+ +
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/group__core-reflection.html b/pr-preview/pr-589/group__core-reflection.html new file mode 100644 index 000000000..b58c09335 --- /dev/null +++ b/pr-preview/pr-589/group__core-reflection.html @@ -0,0 +1,419 @@ + + + + + Core » Reflection module | CUBOS. + + + + + + + +
+
+
+
+
+

+ Core » + Reflection module

+

Provides utilities useful for handling type-erased data.

+ + +
+

Files

+
+
file primitives.hpp
+
Reflection declarations for primitive types.
+
file reflect.hpp
+
Function cubos::core::reflection::reflect and related macros.
+
file constructible.hpp
+
Class cubos::core::reflection::ConstructibleTrait.
+
file constructible_utils.hpp
+
Utilities for cubos::core::reflection::ConstructibleTrait.
+
file type.hpp
+
Class cubos::core::reflection::Type.
+
+
+
+

Classes

+
+
+
template<typename T>
+ struct cubos::core::reflection::Reflect +
+
Defines the reflection function for the given type T.
+
+ class cubos::core::reflection::ConstructibleTrait +
+
Describes how a reflected type may be constructed and destructed.
+
+ class cubos::core::reflection::Type +
+
Describes a reflected type.
+
+
+
+

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/pr-preview/pr-589/group__core-ui.html b/pr-preview/pr-589/group__core-ui.html new file mode 100644 index 000000000..a8b3de2fa --- /dev/null +++ b/pr-preview/pr-589/group__core-ui.html @@ -0,0 +1,444 @@ + + + + + Core » User Interface module | CUBOS. + + + + + + + +
+
+
+
+
+

+ Core » + User Interface module

+

Provides ImGui integration and general UI utilities.

+ + +
+

Files

+
+
file ecs.hpp
+
Functions cubos::core::ui::showWorld and cubos::core::ui::editWorld.
+
file imgui.hpp
+
Functions for initializing and using ImGui.
+
file serialization.hpp
+
Functions for showing and editing serializable objects in the UI.
+
+
+
+

Functions

+
+
+ void showWorld(const ecs::World& world, + data::Context* context = nullptr) +
+
Adds a ImGui window which allows the user to inspect the entities and components in a ecs::World.
+
+ void editWorld(ecs::World& world, + data::Context* serContext = nullptr, + data::Context* desContext = nullptr) +
+
Adds a ImGui window which allows the user to edit the entities and components in a ecs::World.
+
+ void initialize(io::Window window) +
+
Initializes ImGui for use with the given window.
+
+ void terminate() +
+
Shuts down ImGui.
+
+ void beginFrame() +
+
Begins a new ImGui frame. ImGui calls should be made between this and endFrame().
+
+ void endFrame(const gl::Framebuffer& target = nullptr) +
+
Ends the current ImGui frame, and renders the ImGui draw data to the target framebuffer, or the default framebuffer if target is null.
+
+ auto handleEvent(const io::WindowEvent& event) -> bool +
+
Passes a window event to ImGui.
+
+ void showPackage(const data::Package& pkg, + const std::string& name) +
+
Shows a packaged object's properties in the UI. Should be called inside a ImGui::BeginTable(2) and ImGui::EndTable() block.
+
+ auto editPackage(data::Package& pkg, + const std::string& name) -> bool +
+
Shows a packaged object's properties in the UI, allowing the user to edit the object. Should be called inside a ImGui::BeginTable(3) and ImGui::EndTable() block.
+
+
template<typename T>
+ void show(const T& object, + const std::string& name) +
+
Shows a serializable object's properties in the UI. Should be called inside a ImGui::BeginTable(2) and ImGui::EndTable() block.
+
+
template<typename T>
+ auto edit(T& object, + const std::string& name) -> bool +
+
Shows a serializable object's properties in the UI. Should be called inside a ImGui::BeginTable(3) and ImGui::EndTable() block.
+
+
+
+

Function documentation

+
+

+ void showWorld(const ecs::World& world, + data::Context* context = nullptr) + +

+

Adds a ImGui window which allows the user to inspect the entities and components in a ecs::World.

+ + + + + + + + + + + + + + +
Parameters
worldWorld to show.
contextOptional context for serializing the world.
+
+
+

+ void editWorld(ecs::World& world, + data::Context* serContext = nullptr, + data::Context* desContext = nullptr) + +

+

Adds a ImGui window which allows the user to edit the entities and components in a ecs::World.

+ + + + + + + + + + + + + + + + + + +
Parameters
worldWorld to edit.
serContextOptional context for serializing the world.
desContextOptional context for deserializing the world.
+
+
+

+ void initialize(io::Window window) + +

+

Initializes ImGui for use with the given window.

+ + + + + + + + + + +
Parameters
windowThe window to use.
+ +
+
+

+ void terminate() + +

+

Shuts down ImGui.

+ +
+
+

+ void beginFrame() + +

+

Begins a new ImGui frame. ImGui calls should be made between this and endFrame().

+
+
+

+ void endFrame(const gl::Framebuffer& target = nullptr) + +

+

Ends the current ImGui frame, and renders the ImGui draw data to the target framebuffer, or the default framebuffer if target is null.

+ + + + + + + + + + +
Parameters
targetFramebuffer to render to.
+
+
+

+ bool handleEvent(const io::WindowEvent& event) + +

+

Passes a window event to ImGui.

+ + + + + + + + + + + + + + + + +
Parameters
eventEvent to pass.
ReturnsTrue if the event was handled by ImGui, false otherwise.
+
+
+

+ void showPackage(const data::Package& pkg, + const std::string& name) + +

+

Shows a packaged object's properties in the UI. Should be called inside a ImGui::BeginTable(2) and ImGui::EndTable() block.

+ + + + + + + + + + + + + + +
Parameters
pkgPackaged object to show.
nameName of the object.
+

The first column displays the name of the package and the second column displays the value of the package.

+
+
+

+ bool editPackage(data::Package& pkg, + const std::string& name) + +

+

Shows a packaged object's properties in the UI, allowing the user to edit the object. Should be called inside a ImGui::BeginTable(3) and ImGui::EndTable() block.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
pkgPackaged object to edit.
nameName of the object.
ReturnsTrue if the object was modified, false otherwise.
+

The first column displays the name of the package, the second column displays the value of the package and the third column is used for remove buttons in the case of arrays and dictionaries.

+
+
+

+ +
+ template<typename T> +
+ void show(const T& object, + const std::string& name) +

+

Shows a serializable object's properties in the UI. Should be called inside a ImGui::BeginTable(2) and ImGui::EndTable() block.

+ + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TType of the serializable object.
Parameters
objectObject to show.
nameName of the object.
+

Internally packages the object and calls showPackage().

+
+
+

+ +
+ template<typename T> +
+ bool edit(T& object, + const std::string& name) +

+

Shows a serializable object's properties in the UI. Should be called inside a ImGui::BeginTable(3) and ImGui::EndTable() block.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TType of the serializable object.
Parameters
objectObject to edit.
nameName of the object.
ReturnsTrue if the object was edited, false otherwise.
+

Internally packages the object, calls editPackage() and then unpackages the object, if it was modified.

+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/group__core.html b/pr-preview/pr-589/group__core.html new file mode 100644 index 000000000..ead8e3a95 --- /dev/null +++ b/pr-preview/pr-589/group__core.html @@ -0,0 +1,528 @@ + + + + + Core module | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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 and some voxel utilities.
+
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 User Interface
+
Provides ImGui integration and general UI utilities.
+
+
+
+

Files

+
+
file log.hpp
+
Logging and assertion macros.
+
file thread_pool.hpp
+
Class cubos::core::ThreadPool.
+
+
+
+

Classes

+
+
+ class cubos::core::ThreadPool +
+
Manages a pool of threads, to which tasks can be submitted.
+
+
+
+

Functions

+
+
+ void initializeLogger() +
+
Must be called before any logging is done.
+
+ void disableLogging() +
+
Disables all logging except for critical errors.
+
+
+
+

Defines

+
+
+ #define CUBOS_LOG_LEVEL +
+
Log level to compile in.
+
+ #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_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_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_ASSERT(cond, + ...) +
+
Asserts that a condition 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.
+
+
+
+

Function documentation

+
+

+ void initializeLogger() + +

+

Must be called before any logging is done.

+
+
+

+ void disableLogging() + +

+

Disables all logging except for critical errors.

+
+
+
+

Define documentation

+
+

+ #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_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_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_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_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_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/pr-preview/pr-589/group__engine.html b/pr-preview/pr-589/group__engine.html new file mode 100644 index 000000000..7441edbc6 --- /dev/null +++ b/pr-preview/pr-589/group__engine.html @@ -0,0 +1,182 @@ + + + + + Engine module | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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 the main loop, 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 ImGui integration
+
Initializes and configures ImGui for CUBOS.
+
module Input
+
Adds input handling to CUBOS.
+
module Renderer
+
Creates and handles the lifecycle of a renderer.
+
module Scene
+
Adds scenes to CUBOS.
+
module Settings
+
Adds and manages settings.
+
module Tools
+
Plugins which add debug and development tooling to CUBOS.
+
module Transform
+
Adds transform components which assign positions, rotations and scaling to entities.
+
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

+
+
+ struct cubos::engine::DeltaTime +
+
Resource which stores the time since the last iteration of the main loop started.
+
+ struct cubos::engine::ShouldQuit +
+
Resource used as a flag to indicate whether the main loop should stop running.
+
+ struct cubos::engine::Arguments +
+
Resource which stores the command-line arguments.
+
+ class cubos::engine::TagBuilder +
+
Used to chain configurations related to tags.
+
+ class cubos::engine::SystemBuilder +
+
Used to chain configurations related to systems.
+
+ class cubos::engine::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 cubos::engine::Settings +
+
Stores settings as key-value pairs and provides methods to retrieve them.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/group__entity-inspector-tool-plugin.html b/pr-preview/pr-589/group__entity-inspector-tool-plugin.html new file mode 100644 index 000000000..8d0cd35fe --- /dev/null +++ b/pr-preview/pr-589/group__entity-inspector-tool-plugin.html @@ -0,0 +1,152 @@ + + + + + Engine » Tools » Entity inspector module | CUBOS. + + + + + + + +
+
+
+
+
+

+ Engine » + Tools » + 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& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void entityInspectorPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/group__entity-selector-tool-plugin.html b/pr-preview/pr-589/group__entity-selector-tool-plugin.html new file mode 100644 index 000000000..604848038 --- /dev/null +++ b/pr-preview/pr-589/group__entity-selector-tool-plugin.html @@ -0,0 +1,152 @@ + + + + + Engine » Tools » Entity selector module | CUBOS. + + + + + + + +
+
+
+
+
+

+ Engine » + Tools » + 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

+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Functions

+
+
+ void entitySelectorPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void entitySelectorPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/group__imgui-plugin.html b/pr-preview/pr-589/group__imgui-plugin.html new file mode 100644 index 000000000..cc4eb0d93 --- /dev/null +++ b/pr-preview/pr-589/group__imgui-plugin.html @@ -0,0 +1,153 @@ + + + + + Engine » ImGui integration module | CUBOS. + + + + + + + +
+
+
+
+
+

+ Engine » + ImGui integration module

+

Initializes and configures ImGui for CUBOS.

+ +

Startup tags

  • cubos.imgui.init - ImGui is initialized, after cubos.window.init.

Tags

  • cubos.imgui.begin - the ImGui frame begins (after cubos.window.poll).
  • cubos.imgui.end - the ImGui frame ends (before cubos.window.render).
  • cubos.imgui - runs between the previous two tags.

Dependencies

+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Functions

+
+
+ void imguiPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void imguiPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/group__input-plugin.html b/pr-preview/pr-589/group__input-plugin.html new file mode 100644 index 000000000..f36429ddb --- /dev/null +++ b/pr-preview/pr-589/group__input-plugin.html @@ -0,0 +1,185 @@ + + + + + Engine » Input module | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/group__renderer-plugin.html b/pr-preview/pr-589/group__renderer-plugin.html new file mode 100644 index 000000000..bf40956d5 --- /dev/null +++ b/pr-preview/pr-589/group__renderer-plugin.html @@ -0,0 +1,316 @@ + + + + + Engine » Renderer module | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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 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.
+
+
+
+

Classes

+
+
+ 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::Camera +
+
Component which defines parameters of a camera used to render the world.
+
+ struct cubos::engine::ActiveCameras +
+
Resource which identifies the camera entities to be used by the renderer.
+
+ 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.
+
+
+
+

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.
+
+
+
+

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
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/group__scene-editor-tool-plugin.html b/pr-preview/pr-589/group__scene-editor-tool-plugin.html new file mode 100644 index 000000000..7bf722f18 --- /dev/null +++ b/pr-preview/pr-589/group__scene-editor-tool-plugin.html @@ -0,0 +1,152 @@ + + + + + Engine » Tools » Scene editor module | CUBOS. + + + + + + + +
+
+
+
+
+

+ Engine » + Tools » + 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& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void sceneEditorPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/group__scene-plugin.html b/pr-preview/pr-589/group__scene-plugin.html new file mode 100644 index 000000000..d7df6e018 --- /dev/null +++ b/pr-preview/pr-589/group__scene-plugin.html @@ -0,0 +1,170 @@ + + + + + Engine » Scene module | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/group__settings-inspector-tool-plugin.html b/pr-preview/pr-589/group__settings-inspector-tool-plugin.html new file mode 100644 index 000000000..95f6041da --- /dev/null +++ b/pr-preview/pr-589/group__settings-inspector-tool-plugin.html @@ -0,0 +1,152 @@ + + + + + Engine » Tools » Settings inspector module | CUBOS. + + + + + + + +
+
+
+
+
+

+ Engine » + Tools » + 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& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void settingsInspectorPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/group__settings-plugin.html b/pr-preview/pr-589/group__settings-plugin.html new file mode 100644 index 000000000..b80f18377 --- /dev/null +++ b/pr-preview/pr-589/group__settings-plugin.html @@ -0,0 +1,153 @@ + + + + + Engine » Settings module | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/group__tool-plugins.html b/pr-preview/pr-589/group__tool-plugins.html new file mode 100644 index 000000000..351d9a6de --- /dev/null +++ b/pr-preview/pr-589/group__tool-plugins.html @@ -0,0 +1,128 @@ + + + + + Engine » Tools module | CUBOS. + + + + + + + +
+
+
+
+
+

+ Engine » + Tools module

+

Plugins which add debug and development tooling to CUBOS.

+ +
+

Modules

+
+
module Asset explorer
+
Allows viewing and selecting assets through a ImGui window.
+
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 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 World inspector
+
Shows all of the entities in the world through a ImGui window, and allows selecting them.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/group__transform-plugin.html b/pr-preview/pr-589/group__transform-plugin.html new file mode 100644 index 000000000..3b3aa793a --- /dev/null +++ b/pr-preview/pr-589/group__transform-plugin.html @@ -0,0 +1,182 @@ + + + + + Engine » Transform module | CUBOS. + + + + + + + +
+
+
+
+
+

+ Engine » + Transform module

+

Adds transform components which assign positions, rotations and scaling to entities.

+ +

This plugin operates on entities with a LocalToWorld component 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

  • 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.

Tags

+
+

Files

+
+
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::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/pr-preview/pr-589/group__voxels-plugin.html b/pr-preview/pr-589/group__voxels-plugin.html new file mode 100644 index 000000000..a5aa5c3ee --- /dev/null +++ b/pr-preview/pr-589/group__voxels-plugin.html @@ -0,0 +1,152 @@ + + + + + Engine » Voxels module | CUBOS. + + + + + + + +
+
+
+
+
+

+ Engine » + Voxels module

+

Adds grid and palette assets to CUBOS.

+ +

Bridges

Dependencies

+
+

Files

+
+
file plugin.hpp
+
Plugin entry point.
+
+
+
+

Functions

+
+
+ void voxelsPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void voxelsPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/group__window-plugin.html b/pr-preview/pr-589/group__window-plugin.html new file mode 100644 index 000000000..1bec15907 --- /dev/null +++ b/pr-preview/pr-589/group__window-plugin.html @@ -0,0 +1,156 @@ + + + + + Engine » Window module | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/group__world-inspector-tool-plugin.html b/pr-preview/pr-589/group__world-inspector-tool-plugin.html new file mode 100644 index 000000000..a91ebf249 --- /dev/null +++ b/pr-preview/pr-589/group__world-inspector-tool-plugin.html @@ -0,0 +1,152 @@ + + + + + Engine » Tools » World inspector module | CUBOS. + + + + + + + +
+
+
+
+
+

+ Engine » + Tools » + 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& cubos) +
+
Plugin entry function.
+
+
+
+

Function documentation

+
+

+ void worldInspectorPlugin(Cubos& cubos) + +

+

Plugin entry function.

+ + + + + + + + + + +
Parameters
cubosCUBOS. main class
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/guards_8hpp.html b/pr-preview/pr-589/guards_8hpp.html new file mode 100644 index 000000000..fce581a46 --- /dev/null +++ b/pr-preview/pr-589/guards_8hpp.html @@ -0,0 +1,138 @@ + + + + + core/memory/guards.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/imgui_2plugin_8hpp.html b/pr-preview/pr-589/imgui_2plugin_8hpp.html new file mode 100644 index 000000000..ba19a9ef5 --- /dev/null +++ b/pr-preview/pr-589/imgui_2plugin_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/imgui/plugin.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/imgui_8hpp.html b/pr-preview/pr-589/imgui_8hpp.html new file mode 100644 index 000000000..53befbc33 --- /dev/null +++ b/pr-preview/pr-589/imgui_8hpp.html @@ -0,0 +1,148 @@ + + + + + core/ui/imgui.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/ui/imgui.hpp file +

+

Functions for initializing and using ImGui.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::ui
+
User Interface module.
+
+
+
+

Functions

+
+
+ void initialize(io::Window window) +
+
Initializes ImGui for use with the given window.
+
+ void terminate() +
+
Shuts down ImGui.
+
+ void beginFrame() +
+
Begins a new ImGui frame. ImGui calls should be made between this and endFrame().
+
+ void endFrame(const gl::Framebuffer& target = nullptr) +
+
Ends the current ImGui frame, and renders the ImGui draw data to the target framebuffer, or the default framebuffer if target is null.
+
+ auto handleEvent(const io::WindowEvent& event) -> bool +
+
Passes a window event to ImGui.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/index.html b/pr-preview/pr-589/index.html new file mode 100644 index 000000000..5a6f2e718 --- /dev/null +++ b/pr-preview/pr-589/index.html @@ -0,0 +1,100 @@ + + + + + Introduction | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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 C++ 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/pr-preview/pr-589/input_2plugin_8hpp.html b/pr-preview/pr-589/input_2plugin_8hpp.html new file mode 100644 index 000000000..c84eb8bbb --- /dev/null +++ b/pr-preview/pr-589/input_2plugin_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/input/plugin.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/input_8hpp.html b/pr-preview/pr-589/input_8hpp.html new file mode 100644 index 000000000..8f06d62e1 --- /dev/null +++ b/pr-preview/pr-589/input_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/input/input.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/json_8hpp.html b/pr-preview/pr-589/json_8hpp.html new file mode 100644 index 000000000..ff6cbcc62 --- /dev/null +++ b/pr-preview/pr-589/json_8hpp.html @@ -0,0 +1,131 @@ + + + + + engine/assets/bridges/json.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/keyboard_8hpp.html b/pr-preview/pr-589/keyboard_8hpp.html new file mode 100644 index 000000000..1ede28d4c --- /dev/null +++ b/pr-preview/pr-589/keyboard_8hpp.html @@ -0,0 +1,261 @@ + + + + + core/io/keyboard.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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.
+
+
+
+

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.
+
+
+
+

Functions

+
+
+ auto modifiersToString(Modifiers modifiers) -> std::string +
+
Converts a Modifiers enum to a string.
+
+ auto stringToModifiers(const std::string& str) -> Modifiers +
+
Converts a string to a Modifiers enum.
+
+ auto keyToString(Key key) -> std::string +
+
Converts a Key enum to a string.
+
+ auto stringToKey(const std::string& str) -> Key +
+
Convert a string to a Key enum.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/local__to__world_8hpp.html b/pr-preview/pr-589/local__to__world_8hpp.html new file mode 100644 index 000000000..f31030a09 --- /dev/null +++ b/pr-preview/pr-589/local__to__world_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/transform/local_to_world.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/log_8hpp.html b/pr-preview/pr-589/log_8hpp.html new file mode 100644 index 000000000..dcbcf027c --- /dev/null +++ b/pr-preview/pr-589/log_8hpp.html @@ -0,0 +1,214 @@ + + + + + core/log.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/log.hpp file +

+

Logging and assertion macros.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
+
+
+

Functions

+
+
+ void initializeLogger() +
+
Must be called before any logging is done.
+
+ void disableLogging() +
+
Disables all logging except for critical errors.
+
+
+
+

Defines

+
+
+ #define CUBOS_LOG_LEVEL +
+
Log level to compile in.
+
+ #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_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_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_ASSERT(cond, + ...) +
+
Asserts that a condition 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/pr-preview/pr-589/m-dark+documentation.compiled.css b/pr-preview/pr-589/m-dark+documentation.compiled.css new file mode 100644 index 000000000..7d091c2fa --- /dev/null +++ b/pr-preview/pr-589/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/pr-preview/pr-589/manager_8hpp.html b/pr-preview/pr-589/manager_8hpp.html new file mode 100644 index 000000000..bdb0a357c --- /dev/null +++ b/pr-preview/pr-589/manager_8hpp.html @@ -0,0 +1,142 @@ + + + + + engine/renderer/pps/manager.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/map__storage_8hpp.html b/pr-preview/pr-589/map__storage_8hpp.html new file mode 100644 index 000000000..f81b52bc1 --- /dev/null +++ b/pr-preview/pr-589/map__storage_8hpp.html @@ -0,0 +1,133 @@ + + + + + core/ecs/map_storage.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/material_8hpp.html b/pr-preview/pr-589/material_8hpp.html new file mode 100644 index 000000000..b9e926da3 --- /dev/null +++ b/pr-preview/pr-589/material_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/gl/material.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/meta_8hpp.html b/pr-preview/pr-589/meta_8hpp.html new file mode 100644 index 000000000..3b03a0481 --- /dev/null +++ b/pr-preview/pr-589/meta_8hpp.html @@ -0,0 +1,134 @@ + + + + + engine/assets/meta.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/modules.html b/pr-preview/pr-589/modules.html new file mode 100644 index 000000000..7c9f6c7ee --- /dev/null +++ b/pr-preview/pr-589/modules.html @@ -0,0 +1,160 @@ + + + + + CUBOS. + + + + + + + +
+
+
+
+
+

Modules

+
    +
  • + module Core CUBOS. core library. +
      +
    • module Audio Provides audio functionality.
    • +
    • + module Data Provides filesystem and serialization utilities. +
        +
      • module Filesystem Provides filesystem utilities.
      • +
      +
    • +
    • module ECS Entity Component System library.
    • +
    • module Geometry Provides geometry utilities.
    • +
    • module Graphics Provides a graphics API abstraction and some voxel utilities.
    • +
    • 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 User Interface Provides ImGui integration and general UI utilities.
    • +
    +
  • +
  • + module Engine CUBOS. engine library. +
      +
    • module Assets Adds asset management to CUBOS.
    • +
    • module Collisions Adds collision detection to CUBOS.
    • +
    • module ImGui integration Initializes and configures ImGui for CUBOS.
    • +
    • module Input Adds input handling to CUBOS.
    • +
    • module Renderer Creates and handles the lifecycle of a renderer.
    • +
    • module Scene Adds scenes to CUBOS.
    • +
    • module Settings Adds and manages settings.
    • +
    • + module Tools Plugins which add debug and development tooling to CUBOS. +
        +
      • module Asset explorer Allows viewing and selecting assets through a ImGui window.
      • +
      • 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 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 World inspector Shows all of the entities in the world through a ImGui window, and allows selecting them.
      • +
      +
    • +
    • module Transform Adds transform components which assign positions, rotations and scaling to entities.
    • +
    • module Voxels Adds grid and palette assets to CUBOS.
    • +
    • module Window Creates and handles the lifecycle of a window.
    • +
    +
  • +
+ +
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/move_8hpp.html b/pr-preview/pr-589/move_8hpp.html new file mode 100644 index 000000000..378a29ef2 --- /dev/null +++ b/pr-preview/pr-589/move_8hpp.html @@ -0,0 +1,144 @@ + + + + + core/memory/move.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/memory/move.hpp file +

+

Function cubos::core::memory::move.

+ +
+

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.
+
+
+
+

Functions

+
+
+
template<typename T>
+ auto move(T&& value) -> RemoveReference<T>::Type&& +
+
Returns an R-value reference to the given value.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/namespacecubos.html b/pr-preview/pr-589/namespacecubos.html new file mode 100644 index 000000000..d087267c1 --- /dev/null +++ b/pr-preview/pr-589/namespacecubos.html @@ -0,0 +1,120 @@ + + + + + cubos namespace | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos namespace +

+

CUBOS. libraries namespace.

+ +
+

Namespaces

+
+
namespace core
+
Core namespace.
+
namespace engine
+
Engine module.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/namespacecubos_1_1core.html b/pr-preview/pr-589/namespacecubos_1_1core.html new file mode 100644 index 000000000..5d24b14b1 --- /dev/null +++ b/pr-preview/pr-589/namespacecubos_1_1core.html @@ -0,0 +1,158 @@ + + + + + cubos::core namespace | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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.
+
namespace ui
+
User Interface module.
+
+
+
+

Classes

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

Functions

+
+
+ void initializeLogger() +
+
Must be called before any logging is done.
+
+ void disableLogging() +
+
Disables all logging except for critical errors.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/namespacecubos_1_1core_1_1al.html b/pr-preview/pr-589/namespacecubos_1_1core_1_1al.html new file mode 100644 index 000000000..34890a678 --- /dev/null +++ b/pr-preview/pr-589/namespacecubos_1_1core_1_1al.html @@ -0,0 +1,165 @@ + + + + + cubos::core::al namespace | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/namespacecubos_1_1core_1_1al_1_1impl.html b/pr-preview/pr-589/namespacecubos_1_1core_1_1al_1_1impl.html new file mode 100644 index 000000000..748d3016f --- /dev/null +++ b/pr-preview/pr-589/namespacecubos_1_1core_1_1al_1_1impl.html @@ -0,0 +1,124 @@ + + + + + cubos::core::al::impl namespace | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/namespacecubos_1_1core_1_1data.html b/pr-preview/pr-589/namespacecubos_1_1core_1_1data.html new file mode 100644 index 000000000..993848907 --- /dev/null +++ b/pr-preview/pr-589/namespacecubos_1_1core_1_1data.html @@ -0,0 +1,792 @@ + + + + + cubos::core::data namespace | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::data namespace +

+

Data module.

+ +
+

Namespaces

+
+
namespace impl
+
+
+
+
+

Classes

+
+
+ class BinaryDeserializer +
+
+
+ class BinarySerializer +
+
+
+ class Context +
+
+
+
template<typename T>
+ struct Debug +
+
+
+ class DebugSerializer +
+
+
+ class Deserializer +
+
+
+ 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 JSONDeserializer +
+
Implementation of the abstract Deserializer class for deserializing from JSON.
+
+ class JSONSerializer +
+
+
+ class Package +
+
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.
+
+ class Unpackager +
+
Responsible for deserializing packages into types.
+
+ struct QBMatrix +
+
Represents the data read from a matrix in a QB file.
+
+
template<typename R, typename I>
+ class SerializationMap +
+
+
+ class Serializer +
+
+
+
+
+

Functions

+
+
+
template<typename T>
+ void deserialize(Deserializer& des, + T& obj) +
+
Overload the serialize function for types which define a serialize method.
+
+
template<typename T>
+ auto deserialize(Deserializer& des, + T& obj) -> requires HasDeserializeMethod<T> void +
+
Overload the serialize function for types which define a serialize method.
+
+ void deserialize(Deserializer& des, + std::vector<bool>::reference obj) +
+
+
+
template<typename T>
+ void deserialize(Deserializer& des, + std::vector<T>& obj) +
+
+
+
template<typename K, typename V>
+ void deserialize(Deserializer& des, + std::unordered_map<K, V>& obj) +
+
+
+
template<typename T, typename U>
+ void deserialize(Deserializer& des, + std::pair<T, U>& obj) +
+
+
+ auto parseQB(std::vector<QBMatrix>& matrices, + memory::Stream& stream) -> bool +
+
+
+
template<typename T>
+ void serialize(Serializer& ser, + const T& obj, + const char* name) +
+
Overload the serialize function for types which define a serialize method.
+
+
template<typename T>
+ auto serialize(Serializer& ser, + const T& obj, + const char* name) -> requires HasSerializeMethod<T> void +
+
Overload the serialize function for types which define a serialize method.
+
+ void serialize(Serializer& ser, + std::vector<bool>::const_reference obj, + const char* name) +
+
+
+
template<std::size_t N>
+ void serialize(Serializer& ser, + char const (&obj)[N], + const char* name) +
+
+
+
template<typename T>
+ void serialize(Serializer& ser, + const std::vector<T>& obj, + const char* name) +
+
+
+
template<typename K, typename V>
+ void serialize(Serializer& ser, + const std::unordered_map<K, V>& obj, + const char* name) +
+
+
+
template<typename T, typename U>
+ void serialize(Serializer& ser, + const std::pair<T, U>& obj, + const char* name) +
+
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ void cubos::core::data::deserialize(Deserializer& des, + T& obj) +

+

Overload the serialize function for types which define a serialize method.

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

Deserializes the given object using the given deserializer. Deserializable objects must implement a specialization (or overload) of this function. An implementation for types with a deserialize method is provided.

+
+
+

+
+ template<typename T> +
+ requires HasDeserializeMethod<T> void cubos::core::data::deserialize(Deserializer& des, + T& obj) +

+

Overload the serialize function for types which define a serialize method.

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

Deserializes the given object using the given deserializer. Deserializable objects must implement a specialization (or overload) of this function. An implementation for types with a deserialize method is provided.

+
+
+

+ void cubos::core::data::deserialize(Deserializer& des, + std::vector<bool>::reference obj) +

+ + + + + + + + + + + + + + +
Parameters
desThe deserializer.
objThe value to deserialize.
+

Overload for deserializing std::vector<bool>::reference. This is a special case because std::vector<bool> are stored as arrays of bits, and therefore need special handling.

+
+
+

+
+ template<typename T> +
+ void cubos::core::data::deserialize(Deserializer& des, + std::vector<T>& obj) +

+ + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TThe type of the vector.
Parameters
desThe deserializer.
objThe vector to deserialize.
+

Overload for deserializing std::vector.

+
+
+

+
+ template<typename K, typename V> +
+ void cubos::core::data::deserialize(Deserializer& des, + std::unordered_map<K, V>& obj) +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
KThe key type of the map.
VThe value type of the map.
Parameters
desThe deserializer.
objThe map to deserialize.
+

Overload for deserializing std::unordered_map.

+
+
+

+
+ template<typename T, typename U> +
+ void cubos::core::data::deserialize(Deserializer& des, + std::pair<T, U>& obj) +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TThe type of the first value.
UThe type of the second value.
Parameters
desThe deserializer.
objThe pair to deserialize.
+

Overload for serializing std::pair.

+
+
+

+ bool cubos::core::data::parseQB(std::vector<QBMatrix>& matrices, + memory::Stream& stream) +

+ + + + + + + + + + + + + + + + + + + + +
Parameters
matricesThe matrices to output.
streamThe stream to read from.
ReturnsTrue if the file was parsed successfully, otherwise false.
+

Parses a Qubicle file (.qb), pushing every matrix found in the file to the passed vector.

+
+
+

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

+

Overload the serialize function for types which define a serialize method.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TThe type of the object to serialize.
Parameters
serThe serializer to use.
objThe object to serialize.
nameThe name of the object.
+

Serializes the given object using the given serializer. Serializable objects must implement a specialization (or overload) of this function. An implementation for types with a serialize method is provided.

+
+
+

+
+ template<typename T> +
+ requires HasSerializeMethod<T> void cubos::core::data::serialize(Serializer& ser, + const T& obj, + const char* name) +

+

Overload the serialize function for types which define a serialize method.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TThe type of the object to serialize.
Parameters
serThe serializer to use.
objThe object to serialize.
nameThe name of the object.
+

Serializes the given object using the given serializer. Serializable objects must implement a specialization (or overload) of this function. An implementation for types with a serialize method is provided.

+
+
+

+ void cubos::core::data::serialize(Serializer& ser, + std::vector<bool>::const_reference obj, + const char* name) +

+ + + + + + + + + + + + + + + + + + +
Parameters
serThe serializer.
objThe value to serialize.
nameThe name of the value (optional).
+

Overload for serializing std::vector<bool>::const_reference. This is a special case because std::vector<bool> are stored as arrays of bits, and therefore need special handling.

+
+
+

+
+ template<std::size_t N> +
+ void cubos::core::data::serialize(Serializer& ser, + char const (&obj)[N], + const char* name) +

+ + + + + + + + + + + + + + + + + + +
Parameters
serThe serializer.
objThe string to serialize.
nameThe name of the string (optional).
+

Overload for serializing char arrays. Necessary because literal strings are treated as char arrays by the compiler. Without this overload, the linker would fail.

+
+
+

+
+ template<typename T> +
+ void cubos::core::data::serialize(Serializer& ser, + const std::vector<T>& obj, + const char* name) +

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

Overload for serializing std::vector.

+
+
+

+
+ template<typename K, typename V> +
+ void cubos::core::data::serialize(Serializer& ser, + const std::unordered_map<K, V>& obj, + const char* name) +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
KThe type of the key.
VThe type of the value.
Parameters
serThe serializer.
objThe map to serialize.
nameThe name of the map (optional).
+

Overload for serializing std::unordered_map.

+
+
+

+
+ template<typename T, typename U> +
+ void cubos::core::data::serialize(Serializer& ser, + const std::pair<T, U>& obj, + const char* name) +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Template parameters
TThe type of the first value.
UThe type of the second value.
Parameters
serThe serializer.
objThe pair to serialize.
nameThe name of the pair (optional).
+

Overload for serializing std::pair.

+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/namespacecubos_1_1core_1_1data_1_1impl.html b/pr-preview/pr-589/namespacecubos_1_1core_1_1data_1_1impl.html new file mode 100644 index 000000000..0de6962d6 --- /dev/null +++ b/pr-preview/pr-589/namespacecubos_1_1core_1_1data_1_1impl.html @@ -0,0 +1,120 @@ + + + + + cubos::core::data::impl namespace | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::data::impl namespace +

+ +

Implementation specific classes for the above functions are hidden in this namespace.

+
+

Classes

+
+
+ class Packager +
+
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/namespacecubos_1_1core_1_1ecs.html b/pr-preview/pr-589/namespacecubos_1_1core_1_1ecs.html new file mode 100644 index 000000000..2a2de030f --- /dev/null +++ b/pr-preview/pr-589/namespacecubos_1_1core_1_1ecs.html @@ -0,0 +1,289 @@ + + + + + cubos::core::ecs namespace | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs namespace +

+

ECS module.

+ +
+

Namespaces

+
+
namespace impl
+
Contains functions used internally by the implementation of the ECS.
+
+
+
+

Classes

+
+
+
template<typename T>
+ class Read +
+
System argument which provides read access to the resource T, or query argument which provides read access to the component T.
+
+
template<typename T>
+ class Write +
+
System argument which provides write access to the resource T, or query argument which provides write access to the component T.
+
+
template<typename T>
+ class OptRead +
+
System argument which provides read access to the resource T if it exists, or query argument which provides read access to the component T if it exists.
+
+
template<typename T>
+ class OptWrite +
+
System argument which provides write access to the resource T if it exists, or query argument which provides write access to the component T if it exists.
+
+ class Blueprint +
+
Stores a bundle of entities and their respective components, which can be easily spawned into a world. This is in a way the 'Prefab' of CUBOS., but lower level.
+
+ class EntityBuilder +
+
Allows editing an entity created by a Commands object.
+
+ class BlueprintBuilder +
+
Used to edit a blueprint spawned by a Commands object.
+
+ class Commands +
+
Used to write ECS commands and execute them at a later time.
+
+ class CommandBuffer +
+
Stores commands to execute them later.
+
+
template<typename T>
+ class ReadStorage +
+
Utility struct used to reference a storage of component type T for reading.
+
+
template<typename T>
+ class WriteStorage +
+
Utility struct used to reference a storage of component type T for writing.
+
+ class ComponentManager +
+
Holds and manages components.
+
+ class Dispatcher +
+
Used to add systems and relations between them and then dispatch them all at once.
+
+ class Entity +
+
Identifies an entity.
+
+ class EntityManager +
+
Holds and manages entities and their component masks.
+
+
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 T>
+ class MapStorage +
+
Storage implementation that uses an std::unordered_map.
+
+
template<typename T>
+ class NullStorage +
+
Storage implementation that doesn't keep any data, made for zero-sized components.
+
+ struct QueryInfo +
+
Describes a query.
+
+
template<typename... ComponentTypes>
+ class Query +
+
Holds the result of a query over all entities in world which match the given arguments.
+
+ class Registry +
+
Singleton which holds a global registry for all component 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.
+
+ class IStorage +
+
Abstract parent class for all storages.
+
+
template<typename T>
+ class Storage +
+
Abstract container for a component type T.
+
+ struct SystemInfo +
+
Describes a system.
+
+
template<typename R>
+ class AnySystemWrapper +
+
Base class for system wrappers.
+
+
template<typename F>
+ class SystemWrapper +
+
Wrapper for a system of type F.
+
+
template<typename T>
+ class VecStorage +
+
Storage implementation that uses a std::vector.
+
+ class World +
+
Holds entities, their components and resources.
+
+
+
+

Functions

+
+
+
template<typename T>
+ auto getComponentName() -> std::optional<std::string_view> +
+
Gets the registered name of a component type.
+
+ auto getComponentName(std::type_index type) -> std::optional<std::string_view> +
+
Gets the registered name of a component type.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/namespacecubos_1_1core_1_1ecs_1_1impl.html b/pr-preview/pr-589/namespacecubos_1_1core_1_1ecs_1_1impl.html new file mode 100644 index 000000000..436fe39a3 --- /dev/null +++ b/pr-preview/pr-589/namespacecubos_1_1core_1_1ecs_1_1impl.html @@ -0,0 +1,137 @@ + + + + + cubos::core::ecs::impl namespace | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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.

+
+

Classes

+
+
+
template<typename T>
+ struct QueryFetcher +
+
Fetches the requested data from a world.
+
+
template<typename T>
+ struct SystemFetcher +
+
Fetches the requested data from a world.
+
+
template<typename F>
+ struct SystemTraits +
+
Template magic used to inspect the arguments of a system.
+
+
template<class T, class Tuple>
+ struct Index +
+
Used to get the index of a type in a tuple.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/namespacecubos_1_1core_1_1geom.html b/pr-preview/pr-589/namespacecubos_1_1core_1_1geom.html new file mode 100644 index 000000000..f0b1803bf --- /dev/null +++ b/pr-preview/pr-589/namespacecubos_1_1core_1_1geom.html @@ -0,0 +1,132 @@ + + + + + cubos::core::geom namespace | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::geom namespace +

+

Geometry module.

+ +
+

Classes

+
+
+ struct Box +
+
Represents a box shape.
+
+ struct Capsule +
+
Represents a capsule or sphere shape.
+
+ struct Plane +
+
Represents a plane shape.
+
+ struct Simplex +
+
Represents a simplex shape, which may either be empty, a point, a line, a triangle or a tetrahedron.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/namespacecubos_1_1core_1_1gl.html b/pr-preview/pr-589/namespacecubos_1_1core_1_1gl.html new file mode 100644 index 000000000..8c14fd889 --- /dev/null +++ b/pr-preview/pr-589/namespacecubos_1_1core_1_1gl.html @@ -0,0 +1,520 @@ + + + + + cubos::core::gl namespace | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::gl namespace +

+

Graphics module.

+ +
+

Namespaces

+
+
namespace impl
+
Namespace to store the abstract types implemented by the render device implementations.
+
+
+
+

Classes

+
+
+ struct Camera +
+
Describes a camera.
+
+ class Debug +
+
Singleton with static methods used to draw primitive objects on screen for debugging purposes.
+
+ class Grid +
+
Represents a voxel object using a 3D grid.
+
+ struct Material +
+
Describes a voxel material.
+
+ class Palette +
+
Holds a palette of materials. Supports up to 65535 materials.
+
+ 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.
+
+ struct Vertex +
+
Represents a voxel vertex.
+
+
+
+

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.
+
+ void triangulate(const Grid& grid, + std::vector<Vertex>& vertices, + std::vector<uint32_t>& indices) +
+
Triangulates a grid of voxels into an indexed mesh.
+
+
+
+

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/pr-preview/pr-589/namespacecubos_1_1core_1_1gl_1_1impl.html b/pr-preview/pr-589/namespacecubos_1_1core_1_1gl_1_1impl.html new file mode 100644 index 000000000..3debc0e80 --- /dev/null +++ b/pr-preview/pr-589/namespacecubos_1_1core_1_1gl_1_1impl.html @@ -0,0 +1,188 @@ + + + + + cubos::core::gl::impl namespace | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/namespacecubos_1_1core_1_1io.html b/pr-preview/pr-589/namespacecubos_1_1core_1_1io.html new file mode 100644 index 000000000..37f7fca5b --- /dev/null +++ b/pr-preview/pr-589/namespacecubos_1_1core_1_1io.html @@ -0,0 +1,386 @@ + + + + + cubos::core::io namespace | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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 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 modifiersToString(Modifiers modifiers) -> std::string +
+
Converts a Modifiers enum to a string.
+
+ auto stringToModifiers(const std::string& str) -> Modifiers +
+
Converts a string to a Modifiers enum.
+
+ auto keyToString(Key key) -> std::string +
+
Converts a Key enum to a string.
+
+ auto stringToKey(const std::string& str) -> Key +
+
Convert a string to a Key enum.
+
+ auto openWindow(const std::string& title = "CUBOS.", + const glm::ivec2& size = {800, 600}) -> Window +
+
Opens a new window.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/namespacecubos_1_1core_1_1memory.html b/pr-preview/pr-589/namespacecubos_1_1core_1_1memory.html new file mode 100644 index 000000000..2fb1d3965 --- /dev/null +++ b/pr-preview/pr-589/namespacecubos_1_1core_1_1memory.html @@ -0,0 +1,200 @@ + + + + + cubos::core::memory namespace | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::memory namespace +

+

Memory module.

+ +
+

Classes

+
+
+ class BufferStream +
+
Stream implementation which writes to/reads from a buffer.
+
+
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.
+
+ 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 types as keys.
+
+
+
+

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&& +
+
Returns an R-value reference to the given value.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/namespacecubos_1_1core_1_1reflection.html b/pr-preview/pr-589/namespacecubos_1_1core_1_1reflection.html new file mode 100644 index 000000000..ff9815b51 --- /dev/null +++ b/pr-preview/pr-589/namespacecubos_1_1core_1_1reflection.html @@ -0,0 +1,145 @@ + + + + + cubos::core::reflection namespace | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::reflection namespace +

+

Reflection module.

+ +
+

Classes

+
+
+
template<typename T>
+ struct Reflect +
+
Defines the reflection function for the given type T.
+
+ class ConstructibleTrait +
+
Describes how a reflected type may be constructed and destructed.
+
+ class Type +
+
Describes a reflected type.
+
+
+
+

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.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/namespacecubos_1_1core_1_1ui.html b/pr-preview/pr-589/namespacecubos_1_1core_1_1ui.html new file mode 100644 index 000000000..9c424fa0c --- /dev/null +++ b/pr-preview/pr-589/namespacecubos_1_1core_1_1ui.html @@ -0,0 +1,169 @@ + + + + + cubos::core::ui namespace | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::ui namespace +

+

User Interface module.

+ +
+

Functions

+
+
+ void showWorld(const ecs::World& world, + data::Context* context = nullptr) +
+
Adds a ImGui window which allows the user to inspect the entities and components in a ecs::World.
+
+ void editWorld(ecs::World& world, + data::Context* serContext = nullptr, + data::Context* desContext = nullptr) +
+
Adds a ImGui window which allows the user to edit the entities and components in a ecs::World.
+
+ void initialize(io::Window window) +
+
Initializes ImGui for use with the given window.
+
+ void terminate() +
+
Shuts down ImGui.
+
+ void beginFrame() +
+
Begins a new ImGui frame. ImGui calls should be made between this and endFrame().
+
+ void endFrame(const gl::Framebuffer& target = nullptr) +
+
Ends the current ImGui frame, and renders the ImGui draw data to the target framebuffer, or the default framebuffer if target is null.
+
+ auto handleEvent(const io::WindowEvent& event) -> bool +
+
Passes a window event to ImGui.
+
+ void showPackage(const data::Package& pkg, + const std::string& name) +
+
Shows a packaged object's properties in the UI. Should be called inside a ImGui::BeginTable(2) and ImGui::EndTable() block.
+
+ auto editPackage(data::Package& pkg, + const std::string& name) -> bool +
+
Shows a packaged object's properties in the UI, allowing the user to edit the object. Should be called inside a ImGui::BeginTable(3) and ImGui::EndTable() block.
+
+
template<typename T>
+ void show(const T& object, + const std::string& name) +
+
Shows a serializable object's properties in the UI. Should be called inside a ImGui::BeginTable(2) and ImGui::EndTable() block.
+
+
template<typename T>
+ auto edit(T& object, + const std::string& name) -> bool +
+
Shows a serializable object's properties in the UI. Should be called inside a ImGui::BeginTable(3) and ImGui::EndTable() block.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/namespacecubos_1_1engine.html b/pr-preview/pr-589/namespacecubos_1_1engine.html new file mode 100644 index 000000000..e81314e90 --- /dev/null +++ b/pr-preview/pr-589/namespacecubos_1_1engine.html @@ -0,0 +1,399 @@ + + + + + cubos::engine namespace | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::engine namespace +

+

Engine module.

+ +
+

Namespaces

+
+
namespace impl
+
Namespace to store the abstract types implemented by the renderer implementations.
+
namespace tools
+
Namespace for tool plugins.
+
+
+
+

Classes

+
+
+
template<typename 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 ColliderAABB +
+
Component which stores the AABB of an entity with a collider component.
+
+ struct BroadPhaseCollisions +
+
Resource which stores data used in broad phase collision detection.
+
+ struct BoxCollider +
+
Component which adds a box collider to an entity.
+
+ struct CapsuleCollider +
+
Component which adds a capsule collider to an entity.
+
+ struct PlaneCollider +
+
Component which adds a plane collider to an entity.
+
+ struct SimplexCollider +
+
Component which adds a simplex collider to an entity.
+
+ 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 SystemBuilder +
+
Used to chain configurations related to systems.
+
+ 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 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.
+
+ 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 Camera +
+
Component which defines parameters of a camera used to render the world.
+
+ struct ActiveCameras +
+
Resource which identifies the camera entities to be used by the renderer.
+
+ 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.
+
+ class SceneBridge +
+
Bridge which loads and saves Scene assets.
+
+ struct Scene +
+
Asset equivalent to ECS blueprints - a bundle of entities and their components.
+
+ class Settings +
+
Stores settings as key-value pairs and provides methods to retrieve them.
+
+ 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.
+
+
+
+

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 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 imguiPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void inputPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void rendererPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void scenePlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void settingsPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void transformPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void voxelsPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void windowPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/namespacecubos_1_1engine_1_1impl.html b/pr-preview/pr-589/namespacecubos_1_1engine_1_1impl.html new file mode 100644 index 000000000..166608720 --- /dev/null +++ b/pr-preview/pr-589/namespacecubos_1_1engine_1_1impl.html @@ -0,0 +1,120 @@ + + + + + cubos::engine::impl namespace | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/namespacecubos_1_1engine_1_1tools.html b/pr-preview/pr-589/namespacecubos_1_1engine_1_1tools.html new file mode 100644 index 000000000..06a16fbb5 --- /dev/null +++ b/pr-preview/pr-589/namespacecubos_1_1engine_1_1tools.html @@ -0,0 +1,154 @@ + + + + + cubos::engine::tools namespace | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::engine::tools namespace +

+

Namespace for tool plugins.

+ +
+

Classes

+
+
+ struct AssetSelectedEvent +
+
Event sent when an asset is selected.
+
+ struct EntitySelector +
+
Resource which identifies the currently selected entity.
+
+
+
+

Functions

+
+
+ void assetExplorerPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void entityInspectorPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void entitySelectorPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void sceneEditorPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void settingsInspectorPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+ void worldInspectorPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/namespaces.html b/pr-preview/pr-589/namespaces.html new file mode 100644 index 000000000..4cbc57049 --- /dev/null +++ b/pr-preview/pr-589/namespaces.html @@ -0,0 +1,161 @@ + + + + + CUBOS. + + + + + + + +
+
+
+
+
+

Namespaces

+ + +
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/null__storage_8hpp.html b/pr-preview/pr-589/null__storage_8hpp.html new file mode 100644 index 000000000..919eb3f31 --- /dev/null +++ b/pr-preview/pr-589/null__storage_8hpp.html @@ -0,0 +1,133 @@ + + + + + core/ecs/null_storage.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/output.png b/pr-preview/pr-589/output.png new file mode 100644 index 0000000000000000000000000000000000000000..1867409f1acdefc1e9144c8491d1babf9227dcc0 GIT binary patch literal 118782 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 + + + + CUBOS. + + + + + + + + +
+
+
+
+

Pages

+ + +
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/palette_8hpp.html b/pr-preview/pr-589/palette_8hpp.html new file mode 100644 index 000000000..243e5394e --- /dev/null +++ b/pr-preview/pr-589/palette_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/gl/palette.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/pass_8hpp.html b/pr-preview/pr-589/pass_8hpp.html new file mode 100644 index 000000000..9a54137b4 --- /dev/null +++ b/pr-preview/pr-589/pass_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/renderer/pps/pass.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/point__light_8hpp.html b/pr-preview/pr-589/point__light_8hpp.html new file mode 100644 index 000000000..2b6ec7dd9 --- /dev/null +++ b/pr-preview/pr-589/point__light_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/renderer/point_light.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/position_8hpp.html b/pr-preview/pr-589/position_8hpp.html new file mode 100644 index 000000000..2d5f46b62 --- /dev/null +++ b/pr-preview/pr-589/position_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/transform/position.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/primitives_8hpp.html b/pr-preview/pr-589/primitives_8hpp.html new file mode 100644 index 000000000..93f0a8d85 --- /dev/null +++ b/pr-preview/pr-589/primitives_8hpp.html @@ -0,0 +1,100 @@ + + + + + core/reflection/external/primitives.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/reflection/external/primitives.hpp file +

+

Reflection declarations for primitive types.

+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/query_8hpp.html b/pr-preview/pr-589/query_8hpp.html new file mode 100644 index 000000000..b8cc42569 --- /dev/null +++ b/pr-preview/pr-589/query_8hpp.html @@ -0,0 +1,149 @@ + + + + + core/ecs/query.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/ecs/query.hpp file +

+

Class cubos::core::ecs::Query and related types.

+ +

This file is a bit scary, but it's not as bad as it looks. It's mostly template specializations to handle the different types of arguments a query can take.

+
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::ecs
+
ECS module.
+
namespace cubos::core::ecs::impl
+
Contains functions used internally by the implementation of the ECS.
+
+
+
+

Classes

+
+
+ struct cubos::core::ecs::QueryInfo +
+
Describes a query.
+
+
template<typename T>
+ struct cubos::core::ecs::impl::QueryFetcher +
+
Fetches the requested data from a world.
+
+
template<typename... ComponentTypes>
+ class cubos::core::ecs::Query +
+
Holds the result of a query over all entities in world which match the given arguments.
+
+ class cubos::core::ecs::Query::Iterator +
+
Used to iterate over the results of a query.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/reflect_8hpp.html b/pr-preview/pr-589/reflect_8hpp.html new file mode 100644 index 000000000..656703360 --- /dev/null +++ b/pr-preview/pr-589/reflect_8hpp.html @@ -0,0 +1,180 @@ + + + + + core/reflection/reflect.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/registry_8hpp.html b/pr-preview/pr-589/registry_8hpp.html new file mode 100644 index 000000000..c1dcb16e3 --- /dev/null +++ b/pr-preview/pr-589/registry_8hpp.html @@ -0,0 +1,144 @@ + + + + + core/ecs/registry.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/ecs/registry.hpp file +

+

Class cubos::core::ecs::Registry and registration macro.

+ +
+

Namespaces

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

Classes

+
+
+ class cubos::core::ecs::Registry +
+
Singleton which holds a global registry for all component types.
+
+
+
+

Defines

+
+
+ #define CUBOS_REGISTER_COMPONENT(type, + storageType, + name) +
+
Macro used to register a component type as an alternative to calling cubos::core::ecs::Registry::add() manually.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/render__device_8hpp.html b/pr-preview/pr-589/render__device_8hpp.html new file mode 100644 index 000000000..a050dbd26 --- /dev/null +++ b/pr-preview/pr-589/render__device_8hpp.html @@ -0,0 +1,594 @@ + + + + + core/gl/render_device.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/renderer_2plugin_8hpp.html b/pr-preview/pr-589/renderer_2plugin_8hpp.html new file mode 100644 index 000000000..8c46dd6db --- /dev/null +++ b/pr-preview/pr-589/renderer_2plugin_8hpp.html @@ -0,0 +1,148 @@ + + + + + engine/renderer/plugin.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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::Camera +
+
Component which defines parameters of a camera used to render the world.
+
+ struct cubos::engine::ActiveCameras +
+
Resource which identifies the camera entities to be used by the renderer.
+
+
+
+

Functions

+
+
+ void rendererPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/renderer_8hpp.html b/pr-preview/pr-589/renderer_8hpp.html new file mode 100644 index 000000000..a16a12824 --- /dev/null +++ b/pr-preview/pr-589/renderer_8hpp.html @@ -0,0 +1,150 @@ + + + + + engine/renderer/renderer.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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.
+
+ 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/pr-preview/pr-589/resource__manager_8hpp.html b/pr-preview/pr-589/resource__manager_8hpp.html new file mode 100644 index 000000000..8bb32e97d --- /dev/null +++ b/pr-preview/pr-589/resource__manager_8hpp.html @@ -0,0 +1,142 @@ + + + + + core/ecs/resource_manager.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/rotation_8hpp.html b/pr-preview/pr-589/rotation_8hpp.html new file mode 100644 index 000000000..ed6bb4ec4 --- /dev/null +++ b/pr-preview/pr-589/rotation_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/transform/rotation.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/scale_8hpp.html b/pr-preview/pr-589/scale_8hpp.html new file mode 100644 index 000000000..bcaa68b57 --- /dev/null +++ b/pr-preview/pr-589/scale_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/transform/scale.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/scene_2bridge_8hpp.html b/pr-preview/pr-589/scene_2bridge_8hpp.html new file mode 100644 index 000000000..ffe2aacb3 --- /dev/null +++ b/pr-preview/pr-589/scene_2bridge_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/scene/bridge.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/scene_2plugin_8hpp.html b/pr-preview/pr-589/scene_2plugin_8hpp.html new file mode 100644 index 000000000..b86fe2ef1 --- /dev/null +++ b/pr-preview/pr-589/scene_2plugin_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/scene/plugin.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/scene_8hpp.html b/pr-preview/pr-589/scene_8hpp.html new file mode 100644 index 000000000..57218fbc5 --- /dev/null +++ b/pr-preview/pr-589/scene_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/scene/scene.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/search-v2.js b/pr-preview/pr-589/search-v2.js new file mode 100644 index 000000000..1fb71e1f8 --- /dev/null +++ b/pr-preview/pr-589/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/pr-preview/pr-589/searchdata-v2.js b/pr-preview/pr-589/searchdata-v2.js new file mode 100644 index 000000000..3e5a727e6 --- /dev/null +++ b/pr-preview/pr-589/searchdata-v2.js @@ -0,0 +1,2 @@ +/* Generated by https://mcss.mosra.cz/documentation/doxygen/. Do not edit. */ +Search.load('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vy00C?c6aWALa1;~(00D9u6aWALZy*!^00DF+6aWALV=NQ^00Ct(6aWALa5xkI00DD86aWALZbTFS00C)A6aWALWKa|U00C@P6aWALa$FPu00D1e6aWALcW4v<00BB~6aWALI&>6(00DA(6aWALZ-5j400DG{6aWALV~i9400Cu^6aWALaF`ST00DEJ6aWALZln|d00C*L6aWALAg~kw00CsS6aWALY`hcz00DBs6aWALZ^#q?0RYkg00Ak~6aWDM(E%vf6o3E$Zr&6C00C*{6aWALXY3RJ00DLK6aWALZ1@xa00D6R6aWALas(9s00D0b6#xJMbPyE)00Cnb6#xJMWgHa%00C?w6#xJMWhfN@00DC@6#xJMc{CLO00DG56#xJMX+RYK00DGH6#xJMZcG&b00CuE6#xJMI#?9|00BB)6@UN%a%2?%00D1m6#xJMbZ`{_00Com6#xJMWqcI?00C@*6#xJMWr!630RW2#00AkK6#xMNiU=r}6@UN%Zk`nY00C*H6#xJMXRH+f00DKf6#xJMY`7Hw00D5m6#xJMa>Nw?00D2x6#xJMbkG$500Cpx6#xJMW!x1200D5~6#xJMbLbTS00D096#xJMY4jBU00DXW6#xJMbO06r00C(R761SNbPN^%00C|i761SNWf&F!00BB4761SNIwTf=00D9;761SNZ!i`B00DG1761SNV>}iB00Ct}761SNa7Y#a00DDO761SNZd4Wk00MJqjuik}761VNTm=9DZfX_)00D1q761SNX>=9<00DG*761SNV}KR_00Cu&761SNY>XBF00Cu^761SNbC?zY00BCl761VOT?IO%7JvW&a;g>p00D2Z761SNbhs7(00CpZ761SNWyBT$00C^u761SNWzZG?00JO$U={$@761SNdE6EN00DI7761SNY3vpN00DIJ761SNZuk}e0RZ^}00DFa7XSbOWe67l00DCj7XSbOa}*Z<00Chd7XSbOIv^JS0Rj30Iwlu@00DF?7XSbOZZsDF00Ct>7XSbOc0d;Z00Cu27XSbOWK0(T00CuE7XSbObXXSv00CoO7XSbOWn>os00C@j7XSbOWpEb&0RTA$00Aj{7XSePI0h(y7k~f(ZiW{C00C)^7XSbOXOtHJ00DKH7XSbOY@ina00D5O7XSbOa;z5s00CvP7XSbOa<~@&00D2l7XSbOY{VA;00D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�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�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=u0gBxLj@<#)-2npL0WjVHT;2hS-T~a+0VUr7Dc=EU-vMpk0mR<{$ln3q-vK1x0Vv=BZ{PuQ-~qtk0mR?|{@?)u;Q<%n0ZZWlPT>KK;Q^810q)@e^5FqM;sHeB0kPr%wc-K(;sFBV0aoJyTH^tV;{lE10mS10$m0P5)`si~={si~={si`=aNQg+7n5n6$si~={si~={si~={sYvMPScvFYsi~={si~={si~={si{bqn5n6$si~-`s7M&8sW|B9SeTelsi{b*sW@2Z=;-L^=;&CfsW_O}*x1)`si~={si>)`si>)`si~={NSNs8=vb+#si~={si{bqAn54msi>)`t*xo4si~={si~={si~=`si~={si~={si~={si~={si~={si~={si~={si~={si~={si~={si~={si~={si{a<=;-L^=;*1bsi|0)nCMu@=;-KJn26};si~={si~={si~={SWu~`si;VZsi|0)D2S=4si~={si~={si~={si{bqm>8+4si>)_si~=`Na*NTsi~={si~={NSNs8=;-KJh=`b}sYp1Oh*+4ZsHv%`si~={si~-`sHv!_si~<*n5n6$sHv!_si~={si~={si~={si~={si~={si~={si~={s7R@)IG7lin5n6$si~={si~={si~={si~={si~={si~={sHv%`sHv%`s7UDO=;-L^=vb+#si;Wk=;&Bjsi~={si~={si~={si~={si~={si~=`si{b*si~+)si`>VSct8ysi>)_si~={si~={si{bam{_T(si~={si~={si~={NU5o*sYn=@D5V=ve5fsi~={si~={si~={si~={si~={si~={si~-`sHv!_sHv!_sHv%`sHvz(m{^#Ysi~={si~={si~={si>)`si~={si~={si{b*si~={si~={si~={si~={sHv%`sYoa==;*1bsi|10sHv%`si~-`si~-`si~<*SeQtdn3#y@=;-L^=;&C8si~=`NSK%q=vWw-80hF&D46Kzsi|10sHv%`sYt1*si>)_si{cl=vb+#si~={NU5o*si~={si~={si~={si~={si~={sYt1*si~={si~={si~={si~={si~={si~={si~=`si~=`si~=`NSG*ysi~={si>)_si{avD5#!si~={si~={ScvH8=;&DJSgENvsi~={si~={si~={si>)`si{cl=;&C0=;-L^SgEL~si~={si~={si~={si~={si~={s7Oeusi~<*kSM9Csi~={NSK(2si>)`si~={si~={si>)`si>)`si>)`si~={Na(4lsi~={SeV$@*x1OasI9H7t*NQ0sHv%`si~={si~={si~={si~={si~={si~={si~<*si~=`si~={si~={si~={si{bqh?tnEsHv&3xj3n*t*x!Csi~=`Na$Fpsi~={si~={si~={sHvz($f>ERsHv%`si~={si~)_NJyBesi~={sYt1*si~={si~={Na*P3SgENvsi~={si~={NSLXqsi~={si~={NU5kuP^qanD42M7czCI)si~={si~={si~={si~={si~=`NQkMasi~={si>)`si~={NLbj|*vNQzsi`=asi~={NSLjysi~={si~={si~={si~={si~={si~={si~={si~={si~={si~={si~={si~={si~={si~={si~={si~={si~={si~={si~={si{cl=;&Bb80e{~t*xo4si~={si~={si>)`si{bSsi~={si~={si;U;n3yP-si>)`si~={si~={si~=`si~={si{bq=vb+#si~={si~={si~={si~={si~={si~={si~=`si~=`si~=`NU5o*si~-`sHv!_si~={sYvMP=vav8=vWx&=;-L^=;&Cfsi~={sYn>;=;-L^=;&COD440KD43Xtm>8H4nCMs-si~={NU5nf*x1;}c&VwWsi~={si~-`si~={si~={si~={si~={sYsX*nCMuksi~={si~={si~={sYoc;$av`J=;*1bsi~=`si~={si;_(si>)_u(-ImxVX5uvAMCivAMCivAMCivAMCivAMCiFqnv#*x1O(*x1)`NO-BKsi~={si{~HnCPjgt*xo4si{cl=ve6Jsi~={SQv)`si~={si~={si~={si~={si~={si~={si~=`si~=`si~=`si~=`NSLXpsi?8Ju(`Rpxw*Nyxw*MGn3x!tczAetsi`=rsi~={si~={si~={si~={si~<*m>3v%si~={si>)`si~={si~={si~={si~={si~={si{bKcsQx4si~={si~={si~={si~={si~={si~=`NEn!@si~={si~={si~={si~={si~={si~={si~={si~={si~={si~=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'); diff --git a/pr-preview/pr-589/serialization_8hpp.html b/pr-preview/pr-589/serialization_8hpp.html new file mode 100644 index 000000000..c60e9ce8a --- /dev/null +++ b/pr-preview/pr-589/serialization_8hpp.html @@ -0,0 +1,150 @@ + + + + + core/ui/serialization.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/ui/serialization.hpp file +

+

Functions for showing and editing serializable objects in the UI.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::ui
+
User Interface module.
+
+
+
+

Functions

+
+
+ void showPackage(const data::Package& pkg, + const std::string& name) +
+
Shows a packaged object's properties in the UI. Should be called inside a ImGui::BeginTable(2) and ImGui::EndTable() block.
+
+ auto editPackage(data::Package& pkg, + const std::string& name) -> bool +
+
Shows a packaged object's properties in the UI, allowing the user to edit the object. Should be called inside a ImGui::BeginTable(3) and ImGui::EndTable() block.
+
+
template<typename T>
+ void show(const T& object, + const std::string& name) +
+
Shows a serializable object's properties in the UI. Should be called inside a ImGui::BeginTable(2) and ImGui::EndTable() block.
+
+
template<typename T>
+ auto edit(T& object, + const std::string& name) -> bool +
+
Shows a serializable object's properties in the UI. Should be called inside a ImGui::BeginTable(3) and ImGui::EndTable() block.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/settings_2plugin_8hpp.html b/pr-preview/pr-589/settings_2plugin_8hpp.html new file mode 100644 index 000000000..bf1f9a2bf --- /dev/null +++ b/pr-preview/pr-589/settings_2plugin_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/settings/plugin.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/settings_8hpp.html b/pr-preview/pr-589/settings_8hpp.html new file mode 100644 index 000000000..914b9e33f --- /dev/null +++ b/pr-preview/pr-589/settings_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/settings/settings.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/spot__light_8hpp.html b/pr-preview/pr-589/spot__light_8hpp.html new file mode 100644 index 000000000..2047a9dee --- /dev/null +++ b/pr-preview/pr-589/spot__light_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/renderer/spot_light.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/standard__archive_8hpp.html b/pr-preview/pr-589/standard__archive_8hpp.html new file mode 100644 index 000000000..fa6ff6565 --- /dev/null +++ b/pr-preview/pr-589/standard__archive_8hpp.html @@ -0,0 +1,132 @@ + + + + + core/data/fs/standard_archive.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/standard__stream_8hpp.html b/pr-preview/pr-589/standard__stream_8hpp.html new file mode 100644 index 000000000..e8bce49e5 --- /dev/null +++ b/pr-preview/pr-589/standard__stream_8hpp.html @@ -0,0 +1,132 @@ + + + + + core/memory/standard_stream.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/storage_8hpp.html b/pr-preview/pr-589/storage_8hpp.html new file mode 100644 index 000000000..1b629b521 --- /dev/null +++ b/pr-preview/pr-589/storage_8hpp.html @@ -0,0 +1,137 @@ + + + + + core/ecs/storage.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/ecs/storage.hpp file +

+

Class cubos::core::ecs::Storage and related types.

+ +
+

Namespaces

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

Classes

+
+
+ class cubos::core::ecs::IStorage +
+
Abstract parent class for all storages.
+
+
template<typename T>
+ class cubos::core::ecs::Storage +
+
Abstract container for a component type T.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/stream_8hpp.html b/pr-preview/pr-589/stream_8hpp.html new file mode 100644 index 000000000..7127bb402 --- /dev/null +++ b/pr-preview/pr-589/stream_8hpp.html @@ -0,0 +1,144 @@ + + + + + core/memory/stream.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/structColorTrait.html b/pr-preview/pr-589/structColorTrait.html new file mode 100644 index 000000000..321d22849 --- /dev/null +++ b/pr-preview/pr-589/structColorTrait.html @@ -0,0 +1,101 @@ + + + + + ColorTrait struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ ColorTrait struct +

+

[Position definition]

+

[Your own trait]

+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structIntegerAsset.html b/pr-preview/pr-589/structIntegerAsset.html new file mode 100644 index 000000000..5737190fa --- /dev/null +++ b/pr-preview/pr-589/structIntegerAsset.html @@ -0,0 +1,100 @@ + + + + + IntegerAsset struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ IntegerAsset struct +

+

[Asset type]

+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structMyEvent.html b/pr-preview/pr-589/structMyEvent.html new file mode 100644 index 000000000..659ac227c --- /dev/null +++ b/pr-preview/pr-589/structMyEvent.html @@ -0,0 +1,100 @@ + + + + + MyEvent struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ MyEvent struct +

+

[Event struct]

+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structPerson.html b/pr-preview/pr-589/structPerson.html new file mode 100644 index 000000000..c17e20b23 --- /dev/null +++ b/pr-preview/pr-589/structPerson.html @@ -0,0 +1,100 @@ + + + + + Person struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ Person struct +

+

[Person definition]

+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structPosition.html b/pr-preview/pr-589/structPosition.html new file mode 100644 index 000000000..5bf47c456 --- /dev/null +++ b/pr-preview/pr-589/structPosition.html @@ -0,0 +1,101 @@ + + + + + Position struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ Position struct +

+

[Person reflection]

+

[Position definition]

+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structScale.html b/pr-preview/pr-589/structScale.html new file mode 100644 index 000000000..9dacf694a --- /dev/null +++ b/pr-preview/pr-589/structScale.html @@ -0,0 +1,100 @@ + + + + + Scale struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ Scale struct +

+

[Scale declaration]

+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structState.html b/pr-preview/pr-589/structState.html new file mode 100644 index 000000000..90de54d33 --- /dev/null +++ b/pr-preview/pr-589/structState.html @@ -0,0 +1,100 @@ + + + + + State struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ State struct +

+

[Event struct]

+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structStrings.html b/pr-preview/pr-589/structStrings.html new file mode 100644 index 000000000..51bc5745c --- /dev/null +++ b/pr-preview/pr-589/structStrings.html @@ -0,0 +1,100 @@ + + + + + Strings struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ Strings struct +

+

[Asset type] A simple serializable type which we will be saving and loading.

+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1data_1_1Debug.html b/pr-preview/pr-589/structcubos_1_1core_1_1data_1_1Debug.html new file mode 100644 index 000000000..3b8fb4a95 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1data_1_1Debug.html @@ -0,0 +1,154 @@ + + + + + cubos::core::data::Debug struct | CUBOS. + + + + + + + +
+
+
+
+
+

+
template<typename T>
+ cubos::core::data::Debug struct +

+ + + + + + + + + + +
Template parameters
TThe type of the value to wrap.
+ +

Used to wrap a value to be printed using the debug serializer. Can be pretty-printed using the p option. Types can be printed using the t option.

Example usage:

CUBOS_ERROR("Cool debug serialized object: {}", Debug(mySerializableObj)); CUBOS_INFO("Pretty printed: {:p}", Debug(mySerializableObj)); CUBOS_INFO("With types too: {:pt}", Debug(mySerializableObj));

+
+

Constructors, destructors, conversion operators

+
+
+ Debug(const T& value) +
+
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ cubos::core::data::Debug<T>::Debug(const T& value) +

+ + + + + + + + + + +
Parameters
valueThe value to debug.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1data_1_1EmbeddedArchive_1_1Data.html b/pr-preview/pr-589/structcubos_1_1core_1_1data_1_1EmbeddedArchive_1_1Data.html new file mode 100644 index 000000000..07e7d871d --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1data_1_1EmbeddedArchive_1_1Data.html @@ -0,0 +1,135 @@ + + + + + cubos::core::data::EmbeddedArchive::Data struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1data_1_1EmbeddedArchive_1_1Data_1_1Entry.html b/pr-preview/pr-589/structcubos_1_1core_1_1data_1_1EmbeddedArchive_1_1Data_1_1Entry.html new file mode 100644 index 000000000..253c11438 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1data_1_1EmbeddedArchive_1_1Data_1_1Entry.html @@ -0,0 +1,145 @@ + + + + + cubos::core::data::EmbeddedArchive::Data::Entry struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/structcubos_1_1core_1_1data_1_1QBMatrix.html b/pr-preview/pr-589/structcubos_1_1core_1_1data_1_1QBMatrix.html new file mode 100644 index 000000000..3b9afc4ae --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1data_1_1QBMatrix.html @@ -0,0 +1,128 @@ + + + + + cubos::core::data::QBMatrix struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1QueryInfo.html b/pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1QueryInfo.html new file mode 100644 index 000000000..5a1f7def1 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1QueryInfo.html @@ -0,0 +1,125 @@ + + + + + cubos::core::ecs::QueryInfo struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1SystemInfo.html b/pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1SystemInfo.html new file mode 100644 index 000000000..721d9b4fe --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1SystemInfo.html @@ -0,0 +1,197 @@ + + + + + cubos::core::ecs::SystemInfo struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::ecs::SystemInfo struct + +

+

Describes a system.

+ +
+

Public functions

+
+
+ auto valid() const -> bool +
+
Checks if this system is valid.
+
+ auto compatible(const SystemInfo& other) const -> bool +
+
Checks if this system is compatible with another system.
+
+
+
+

Public variables

+
+
+ bool usesCommands +
+
Whether the system uses commands or not.
+
+ bool usesWorld +
+
Whether the system uses the world directly.
+
+ std::unordered_set<std::type_index> resourcesRead +
+
Set of resources the system reads.
+
+ std::unordered_set<std::type_index> resourcesWritten +
+
Set of resources the system writes.
+
+ std::unordered_set<std::type_index> componentsRead +
+
Set of components the system reads.
+
+ std::unordered_set<std::type_index> componentsWritten +
+
Set of components the system writes.
+
+
+
+

Function documentation

+
+

+ bool cubos::core::ecs::SystemInfo::valid() const +

+

Checks if this system is valid.

+ + + + + + + +
ReturnsWhether the system is valid.
+

A system may be invalid, if, for example, it both reads and writes the same resource.

+
+
+

+ bool cubos::core::ecs::SystemInfo::compatible(const SystemInfo& other) const +

+

Checks if this system is compatible with another system.

+ + + + + + + + + + + + + + + + +
Parameters
otherOther system.
ReturnsWhether the systems are compatible.
+

Two systems are compatible if they can be executed in parallel. This means that they must not, for example, write to the same resource or component.

+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1impl_1_1Index.html b/pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1impl_1_1Index.html new file mode 100644 index 000000000..04619fd10 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1impl_1_1Index.html @@ -0,0 +1,118 @@ + + + + + cubos::core::ecs::impl::Index struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1impl_1_1QueryFetcher.html b/pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1impl_1_1QueryFetcher.html new file mode 100644 index 000000000..c206f50ce --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1impl_1_1QueryFetcher.html @@ -0,0 +1,114 @@ + + + + + cubos::core::ecs::impl::QueryFetcher struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::ecs::impl::QueryFetcher struct +

+

Fetches the requested data from a world.

+ + + + + + + + + + +
Template parameters
TQuery argument type.
+

Each possible accessor type is specialized to provide the correct data.

+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1impl_1_1SystemFetcher.html b/pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1impl_1_1SystemFetcher.html new file mode 100644 index 000000000..a8b02a6e5 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1impl_1_1SystemFetcher.html @@ -0,0 +1,268 @@ + + + + + cubos::core::ecs::impl::SystemFetcher struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
template<typename T>
+ cubos::core::ecs::impl::SystemFetcher struct +

+

Fetches the requested data from a world.

+ + + + + + + + + + +
Template parameters
TSystem argument type.
+ +
+

Public types

+
+
+ using Type = char +
+
Type of the fetched data.
+
+
+
+

Public static functions

+
+
+ static void add(SystemInfo& info) +
+
Adds the argument T to the given info.
+
+ static auto prepare(World& world) -> State +
+
Prepares the argument for being executed on the given world.
+
+ static auto fetch(World& world, + CommandBuffer& commands, + State& state) -> Type +
+
Fetches the data from the given world.
+
+ static auto arg(Type&& fetched) -> T +
+
Converts the fetched data into the actual desired argument.
+
+
+
+

Function documentation

+
+

+
+ template<typename T> +
+ static void cubos::core::ecs::impl::SystemFetcher<T>::add(SystemInfo& info) +

+

Adds the argument T to the given info.

+ + + + + + + + + + +
Parameters
info outSystem information.
+
+
+

+
+ template<typename T> +
+ static State cubos::core::ecs::impl::SystemFetcher<T>::prepare(World& world) +

+

Prepares the argument for being executed on the given world.

+ + + + + + + + + + + + + + + + +
Parameters
worldWorld to prepare the argument for.
ReturnsState of the argument.
+
+
+

+
+ template<typename T> +
+ static Type cubos::core::ecs::impl::SystemFetcher<T>::fetch(World& world, + CommandBuffer& commands, + State& state) +

+

Fetches the data from the given world.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
worldWorld to fetch the data from.
commandsBuffer where commands can be submitted to.
stateState of the argument.
ReturnsFetched data.
+
+
+

+
+ template<typename T> +
+ static T cubos::core::ecs::impl::SystemFetcher<T>::arg(Type&& fetched) +

+

Converts the fetched data into the actual desired argument.

+ + + + + + + + + + + + + + + + +
Parameters
fetchedFetched data.
ReturnsActual argument.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1impl_1_1SystemTraits.html b/pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1impl_1_1SystemTraits.html new file mode 100644 index 000000000..4336fb18d --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1ecs_1_1impl_1_1SystemTraits.html @@ -0,0 +1,102 @@ + + + + + cubos::core::ecs::impl::SystemTraits struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1geom_1_1Box.html b/pr-preview/pr-589/structcubos_1_1core_1_1geom_1_1Box.html new file mode 100644 index 000000000..0101ec344 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1geom_1_1Box.html @@ -0,0 +1,193 @@ + + + + + cubos::core::geom::Box struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/structcubos_1_1core_1_1geom_1_1Capsule.html b/pr-preview/pr-589/structcubos_1_1core_1_1geom_1_1Capsule.html new file mode 100644 index 000000000..e872cfe8b --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1geom_1_1Capsule.html @@ -0,0 +1,185 @@ + + + + + cubos::core::geom::Capsule struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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.
+
+
+
+

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.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1geom_1_1Plane.html b/pr-preview/pr-589/structcubos_1_1core_1_1geom_1_1Plane.html new file mode 100644 index 000000000..3fcd26a12 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1geom_1_1Plane.html @@ -0,0 +1,121 @@ + + + + + cubos::core::geom::Plane struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1geom_1_1Simplex.html b/pr-preview/pr-589/structcubos_1_1core_1_1geom_1_1Simplex.html new file mode 100644 index 000000000..a80c6c545 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1geom_1_1Simplex.html @@ -0,0 +1,292 @@ + + + + + cubos::core::geom::Simplex struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::geom::Simplex struct + +

+

Represents a simplex shape, which may either be empty, a point, a line, a triangle or a tetrahedron.

+ +
+

Public static functions

+
+
+ static auto empty() -> Simplex +
+
Constructs an empty simplex.
+
+ static auto point(const glm::vec3& p) -> Simplex +
+
Constructs a point simplex.
+
+ static auto line(const glm::vec3& p1, + const glm::vec3& p2) -> Simplex +
+
Constructs a line simplex.
+
+ static auto triangle(const glm::vec3& p1, + const glm::vec3& p2, + const glm::vec3& p3) -> Simplex +
+
Constructs a triangle simplex.
+
+ static auto tetrahedron(const glm::vec3& p1, + const glm::vec3& p2, + const glm::vec3& p3, + const glm::vec3& p4) -> Simplex +
+
Constructs a tetrahedron simplex.
+
+
+
+

Public variables

+
+
+ std::vector<glm::vec3> points +
+
Points of the simplex.
+
+
+
+

Function documentation

+
+

+ static Simplex cubos::core::geom::Simplex::empty() +

+

Constructs an empty simplex.

+ + + + + + + +
ReturnsEmpty simplex.
+
+
+

+ static Simplex cubos::core::geom::Simplex::point(const glm::vec3& p) +

+

Constructs a point simplex.

+ + + + + + + + + + + + + + + + +
Parameters
pPoint.
ReturnsPoint simplex.
+
+
+

+ static Simplex cubos::core::geom::Simplex::line(const glm::vec3& p1, + const glm::vec3& p2) +

+

Constructs a line simplex.

+ + + + + + + + + + + + + + + + + + + + +
Parameters
p1First point.
p2Second point.
ReturnsLine simplex.
+
+
+

+ static Simplex cubos::core::geom::Simplex::triangle(const glm::vec3& p1, + const glm::vec3& p2, + const glm::vec3& p3) +

+

Constructs a triangle simplex.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
p1First point.
p2Second point.
p3Third point.
ReturnsTriangle simplex.
+
+
+

+ static Simplex cubos::core::geom::Simplex::tetrahedron(const glm::vec3& p1, + const glm::vec3& p2, + const glm::vec3& p3, + const glm::vec3& p4) +

+

Constructs a tetrahedron simplex.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Parameters
p1First point.
p2Second point.
p3Third point.
p4Fourth point.
ReturnsTetrahedron simplex.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1BlendStateDesc.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1BlendStateDesc.html new file mode 100644 index 000000000..3f4dd28ec --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1BlendStateDesc.html @@ -0,0 +1,165 @@ + + + + + cubos::core::gl::BlendStateDesc struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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::@1 color +
+
Color blend state.
+
+ struct cubos::core::gl::BlendStateDesc::@2 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/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Camera.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Camera.html new file mode 100644 index 000000000..82f7e784d --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Camera.html @@ -0,0 +1,141 @@ + + + + + cubos::core::gl::Camera struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1ConstantBufferElement.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1ConstantBufferElement.html new file mode 100644 index 000000000..86d2330cc --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1ConstantBufferElement.html @@ -0,0 +1,133 @@ + + + + + cubos::core::gl::ConstantBufferElement struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1ConstantBufferStructure.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1ConstantBufferStructure.html new file mode 100644 index 000000000..6eb1d3976 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1ConstantBufferStructure.html @@ -0,0 +1,129 @@ + + + + + cubos::core::gl::ConstantBufferStructure struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1CubeMapArrayDesc.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1CubeMapArrayDesc.html new file mode 100644 index 000000000..9ba77a23b --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1CubeMapArrayDesc.html @@ -0,0 +1,145 @@ + + + + + cubos::core::gl::CubeMapArrayDesc struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1CubeMapDesc.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1CubeMapDesc.html new file mode 100644 index 000000000..554c28ba4 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1CubeMapDesc.html @@ -0,0 +1,141 @@ + + + + + cubos::core::gl::CubeMapDesc struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc.html new file mode 100644 index 000000000..0a49830fc --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc.html @@ -0,0 +1,139 @@ + + + + + cubos::core::gl::DepthStencilStateDesc struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Depth.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Depth.html new file mode 100644 index 000000000..04041d3ad --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Depth.html @@ -0,0 +1,137 @@ + + + + + cubos::core::gl::DepthStencilStateDesc::Depth struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Stencil.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Stencil.html new file mode 100644 index 000000000..1debfed87 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Stencil.html @@ -0,0 +1,151 @@ + + + + + cubos::core::gl::DepthStencilStateDesc::Stencil struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Stencil_1_1Face.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Stencil_1_1Face.html new file mode 100644 index 000000000..8b86ed52a --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1DepthStencilStateDesc_1_1Stencil_1_1Face.html @@ -0,0 +1,133 @@ + + + + + cubos::core::gl::DepthStencilStateDesc::Stencil::Face struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc.html new file mode 100644 index 000000000..e525c4640 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc.html @@ -0,0 +1,162 @@ + + + + + cubos::core::gl::FramebufferDesc struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1CubeMapArrayTarget.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1CubeMapArrayTarget.html new file mode 100644 index 000000000..b7972a915 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1CubeMapArrayTarget.html @@ -0,0 +1,121 @@ + + + + + cubos::core::gl::FramebufferDesc::CubeMapArrayTarget struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1CubeMapTarget.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1CubeMapTarget.html new file mode 100644 index 000000000..80a2d99ed --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1CubeMapTarget.html @@ -0,0 +1,125 @@ + + + + + cubos::core::gl::FramebufferDesc::CubeMapTarget struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1FramebufferTarget.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1FramebufferTarget.html new file mode 100644 index 000000000..d5d92dbe1 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1FramebufferTarget.html @@ -0,0 +1,121 @@ + + + + + cubos::core::gl::FramebufferDesc::FramebufferTarget struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1Texture2DArrayTarget.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1Texture2DArrayTarget.html new file mode 100644 index 000000000..8caacee98 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1Texture2DArrayTarget.html @@ -0,0 +1,121 @@ + + + + + cubos::core::gl::FramebufferDesc::Texture2DArrayTarget struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1Texture2DTarget.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1Texture2DTarget.html new file mode 100644 index 000000000..170f5125b --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1FramebufferDesc_1_1Texture2DTarget.html @@ -0,0 +1,121 @@ + + + + + cubos::core::gl::FramebufferDesc::Texture2DTarget struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Material.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Material.html new file mode 100644 index 000000000..e47b89c34 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Material.html @@ -0,0 +1,168 @@ + + + + + cubos::core::gl::Material struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::core::gl::Material struct + +

+

Describes a voxel material.

+ +
+

Public static variables

+
+
+ static const Material Empty +
+
Empty material, used for voxels with index 0.
+
+
+
+

Public functions

+
+
+ auto similarity(const Material& 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::core::gl::Material::similarity(const Material& 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/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1RasterStateDesc.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1RasterStateDesc.html new file mode 100644 index 000000000..9adf52c96 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1RasterStateDesc.html @@ -0,0 +1,137 @@ + + + + + cubos::core::gl::RasterStateDesc struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1SamplerDesc.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1SamplerDesc.html new file mode 100644 index 000000000..9ae31660c --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1SamplerDesc.html @@ -0,0 +1,149 @@ + + + + + cubos::core::gl::SamplerDesc struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Texture1DDesc.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Texture1DDesc.html new file mode 100644 index 000000000..48ea16175 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Texture1DDesc.html @@ -0,0 +1,137 @@ + + + + + cubos::core::gl::Texture1DDesc struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Texture2DArrayDesc.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Texture2DArrayDesc.html new file mode 100644 index 000000000..4f12eab9b --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Texture2DArrayDesc.html @@ -0,0 +1,145 @@ + + + + + cubos::core::gl::Texture2DArrayDesc struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Texture2DDesc.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Texture2DDesc.html new file mode 100644 index 000000000..d88c02c95 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Texture2DDesc.html @@ -0,0 +1,141 @@ + + + + + cubos::core::gl::Texture2DDesc struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Texture3DDesc.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Texture3DDesc.html new file mode 100644 index 000000000..7657c704c --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Texture3DDesc.html @@ -0,0 +1,145 @@ + + + + + cubos::core::gl::Texture3DDesc struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Vertex.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Vertex.html new file mode 100644 index 000000000..a104bd809 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1Vertex.html @@ -0,0 +1,129 @@ + + + + + cubos::core::gl::Vertex struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1VertexArrayDesc.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1VertexArrayDesc.html new file mode 100644 index 000000000..2d9e5dee8 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1VertexArrayDesc.html @@ -0,0 +1,133 @@ + + + + + cubos::core::gl::VertexArrayDesc struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1VertexElement.html b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1VertexElement.html new file mode 100644 index 000000000..c591be670 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1gl_1_1VertexElement.html @@ -0,0 +1,145 @@ + + + + + cubos::core::gl::VertexElement struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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::@3 buffer +
+
Vertex buffer description.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1GamepadConnectionEvent.html b/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1GamepadConnectionEvent.html new file mode 100644 index 000000000..e1444f34b --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1GamepadConnectionEvent.html @@ -0,0 +1,125 @@ + + + + + cubos::core::io::GamepadConnectionEvent struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1GamepadState.html b/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1GamepadState.html new file mode 100644 index 000000000..17179b5d0 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1GamepadState.html @@ -0,0 +1,188 @@ + + + + + cubos::core::io::GamepadState struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1KeyEvent.html b/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1KeyEvent.html new file mode 100644 index 000000000..ad9734d4f --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1KeyEvent.html @@ -0,0 +1,125 @@ + + + + + cubos::core::io::KeyEvent struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1ModifiersEvent.html b/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1ModifiersEvent.html new file mode 100644 index 000000000..9ce7bd2e8 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1ModifiersEvent.html @@ -0,0 +1,121 @@ + + + + + cubos::core::io::ModifiersEvent struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1MouseButtonEvent.html b/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1MouseButtonEvent.html new file mode 100644 index 000000000..07654b474 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1MouseButtonEvent.html @@ -0,0 +1,125 @@ + + + + + cubos::core::io::MouseButtonEvent struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1MouseMoveEvent.html b/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1MouseMoveEvent.html new file mode 100644 index 000000000..5fe5eb9ae --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1MouseMoveEvent.html @@ -0,0 +1,121 @@ + + + + + cubos::core::io::MouseMoveEvent struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1MouseScrollEvent.html b/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1MouseScrollEvent.html new file mode 100644 index 000000000..b5ecd2c23 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1MouseScrollEvent.html @@ -0,0 +1,121 @@ + + + + + cubos::core::io::MouseScrollEvent struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1ResizeEvent.html b/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1ResizeEvent.html new file mode 100644 index 000000000..bae024839 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1ResizeEvent.html @@ -0,0 +1,121 @@ + + + + + cubos::core::io::ResizeEvent struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1TextEvent.html b/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1TextEvent.html new file mode 100644 index 000000000..38f452e9a --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1io_1_1TextEvent.html @@ -0,0 +1,121 @@ + + + + + cubos::core::io::TextEvent struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1memory_1_1RemoveReference.html b/pr-preview/pr-589/structcubos_1_1core_1_1memory_1_1RemoveReference.html new file mode 100644 index 000000000..45d63ed0c --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1memory_1_1RemoveReference.html @@ -0,0 +1,134 @@ + + + + + cubos::core::memory::RemoveReference struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
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
T
+ + +
+

Public types

+
+
+ using Type = T +
+
Type without references.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1core_1_1reflection_1_1Reflect.html b/pr-preview/pr-589/structcubos_1_1core_1_1reflection_1_1Reflect.html new file mode 100644 index 000000000..9c68d9265 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1core_1_1reflection_1_1Reflect.html @@ -0,0 +1,114 @@ + + + + + cubos::core::reflection::Reflect struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ +
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/pr-preview/pr-589/structcubos_1_1engine_1_1ActiveCameras.html b/pr-preview/pr-589/structcubos_1_1engine_1_1ActiveCameras.html new file mode 100644 index 000000000..be9f7b8b2 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1ActiveCameras.html @@ -0,0 +1,131 @@ + + + + + cubos::engine::ActiveCameras struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/structcubos_1_1engine_1_1Arguments.html b/pr-preview/pr-589/structcubos_1_1engine_1_1Arguments.html new file mode 100644 index 000000000..f50a815ba --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1Arguments.html @@ -0,0 +1,102 @@ + + + + + cubos::engine::Arguments struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::engine::Arguments struct + +

+

Resource which stores the command-line arguments.

+

This resource is added by the Cubos class.

+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1engine_1_1AssetMeta_1_1Exclude.html b/pr-preview/pr-589/structcubos_1_1engine_1_1AssetMeta_1_1Exclude.html new file mode 100644 index 000000000..edeee668c --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1AssetMeta_1_1Exclude.html @@ -0,0 +1,121 @@ + + + + + cubos::engine::AssetMeta::Exclude struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1engine_1_1BoxCollider.html b/pr-preview/pr-589/structcubos_1_1engine_1_1BoxCollider.html new file mode 100644 index 000000000..3c0dd735a --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1BoxCollider.html @@ -0,0 +1,140 @@ + + + + + cubos::engine::BoxCollider struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::engine::BoxCollider struct + +

+

Component which adds a box collider to an entity.

+ +
  • Convex: For any 2 points inside the shape, the line segment connecting those points lies inside the shape.
  • Positive margin: Requires a positive margin to round off sharp corners. Defined in physics-space units.
+
+

Public variables

+
+
+ glm::mat4 transform +
+
Transform of the collider.
+
+ cubos::core::geom::Box shape +
+
Box shape of the collider.
+
+ float margin +
+
Margin of the collider. Needed for collision stability.
+
+
+
+

Variable documentation

+
+

+ float cubos::engine::BoxCollider::margin +

+

Margin of the collider. Needed for collision stability.

+

The collider margin avoids collision errors by rounding off sharp corners. It is absolute so the collider's transform won't affect it. Shouldn't be changed without good reason, as it's preferable to scale down the collider to account for it.

+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1engine_1_1BroadPhaseCollisions.html b/pr-preview/pr-589/structcubos_1_1engine_1_1BroadPhaseCollisions.html new file mode 100644 index 000000000..52fdd12c3 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1BroadPhaseCollisions.html @@ -0,0 +1,358 @@ + + + + + cubos::engine::BroadPhaseCollisions struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::engine::BroadPhaseCollisions struct + +

+

Resource which stores data used in broad phase collision detection.

+ +
+

Public types

+
+
+ struct CandidateHash +
+
Hash function to allow Candidates to be used as keys in an unordered_set.
+
+ struct SweepMarker +
+
Marker used for sweep and prune.
+
+ enum class CollisionType { BoxBox = 0, + BoxCapsule, + BoxPlane, + BoxSimplex, + CapsuleCapsule, + CapsulePlane, + CapsuleSimplex, + PlanePlane, + PlaneSimplex, + SimplexSimplex, + Count } +
+
Collision type for each pair of colliders.
+
+ using Candidate = std::pair<Entity, Entity> +
+
Pair of entities that may collide.
+
+
+
+

Public functions

+
+
+ void addEntity(Entity entity) +
+
Adds an entity to the list of entities tracked by sweep and prune.
+
+ void removeEntity(Entity entity) +
+
Removes an entity from the list of entities tracked by sweep and prune.
+
+ void clearEntities() +
+
Clears the list of entities tracked by sweep and prune.
+
+ void addCandidate(CollisionType type, + Candidate candidate) +
+
Adds a collision candidate to the list of candidates for a specific collision type.
+
+ auto candidates(CollisionType type) const -> const std::unordered_set<Candidate, CandidateHash>& +
+
Gets the collision candidates for a specific collision type.
+
+ void clearCandidates() +
+
Clears the list of collision candidates.
+
+
+
+

Public variables

+
+
+ std::vector<SweepMarker> markersPerAxis +
+
List of ordered sweep markers for each axis. Stores the index of the marker in mMarkers.
+
+ std::unordered_map<Entity, std::vector<Entity>> sweepOverlapMaps +
+
Maps of overlapping entities for each axis calculated by sweep and prune.
+
+ std::unordered_set<Entity> activePerAxis +
+
Set of active entities during sweep for each axis.
+
+ std::unordered_set<Candidate, CandidateHash> candidatesPerType +
+
Sets of collision candidates for each collision type. The index of the array is the collision type.
+
+
+
+

Enum documentation

+
+

+ enum class cubos::engine::BroadPhaseCollisions::CollisionType +

+

Collision type for each pair of colliders.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Enumerators
BoxBox +
BoxCapsule +
BoxPlane +
BoxSimplex +
CapsuleCapsule +
CapsulePlane +
CapsuleSimplex +
PlanePlane +
PlaneSimplex +
SimplexSimplex +
Count +

Number of collision types.

+
+
+
+
+

Function documentation

+
+

+ void cubos::engine::BroadPhaseCollisions::addEntity(Entity entity) +

+

Adds an entity to the list of entities tracked by sweep and prune.

+ + + + + + + + + + +
Parameters
entityEntity to add.
+
+
+

+ void cubos::engine::BroadPhaseCollisions::removeEntity(Entity entity) +

+

Removes an entity from the list of entities tracked by sweep and prune.

+ + + + + + + + + + +
Parameters
entityEntity to remove.
+
+
+

+ void cubos::engine::BroadPhaseCollisions::addCandidate(CollisionType type, + Candidate candidate) +

+

Adds a collision candidate to the list of candidates for a specific collision type.

+ + + + + + + + + + + + + + +
Parameters
typeCollision type.
candidateCollision candidate.
+
+
+

+ const std::unordered_set<Candidate, CandidateHash>& cubos::engine::BroadPhaseCollisions::candidates(CollisionType type) const +

+

Gets the collision candidates for a specific collision type.

+ + + + + + + + + + + + + + + + +
Parameters
typeCollision type.
ReturnsCollision candidates.
+
+
+
+

Variable documentation

+
+

+ std::unordered_map<Entity, std::vector<Entity>> cubos::engine::BroadPhaseCollisions::sweepOverlapMaps +

+

Maps of overlapping entities for each axis calculated by sweep and prune.

+

For each each map, the key is an entity and the value is a list of entities that overlap with the key. Symmetrical pairs are not stored.

+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1engine_1_1BroadPhaseCollisions_1_1CandidateHash.html b/pr-preview/pr-589/structcubos_1_1engine_1_1BroadPhaseCollisions_1_1CandidateHash.html new file mode 100644 index 000000000..ef810df4f --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1BroadPhaseCollisions_1_1CandidateHash.html @@ -0,0 +1,101 @@ + + + + + cubos::engine::BroadPhaseCollisions::CandidateHash struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1engine_1_1BroadPhaseCollisions_1_1SweepMarker.html b/pr-preview/pr-589/structcubos_1_1engine_1_1BroadPhaseCollisions_1_1SweepMarker.html new file mode 100644 index 000000000..b7665f32a --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1BroadPhaseCollisions_1_1SweepMarker.html @@ -0,0 +1,125 @@ + + + + + cubos::engine::BroadPhaseCollisions::SweepMarker struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1engine_1_1Camera.html b/pr-preview/pr-589/structcubos_1_1engine_1_1Camera.html new file mode 100644 index 000000000..6b7a97465 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1Camera.html @@ -0,0 +1,130 @@ + + + + + cubos::engine::Camera struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1engine_1_1CapsuleCollider.html b/pr-preview/pr-589/structcubos_1_1engine_1_1CapsuleCollider.html new file mode 100644 index 000000000..72d528243 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1CapsuleCollider.html @@ -0,0 +1,126 @@ + + + + + cubos::engine::CapsuleCollider struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::engine::CapsuleCollider struct + +

+

Component which adds a capsule collider to an entity.

+ +
  • Convex: For any 2 points inside the shape, the line segment connecting those points lies inside the shape.
  • Zero margin: No margin is needed, since the shape has no sharp corners.
+
+

Public variables

+
+
+ glm::mat4 transform +
+
Transform of the collider.
+
+ cubos::core::geom::Capsule shape +
+
Capsule shape of the collider.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1engine_1_1ColliderAABB.html b/pr-preview/pr-589/structcubos_1_1engine_1_1ColliderAABB.html new file mode 100644 index 000000000..5dcd2649e --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1ColliderAABB.html @@ -0,0 +1,278 @@ + + + + + cubos::engine::ColliderAABB struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::engine::ColliderAABB struct + +

+

Component which stores the AABB of an entity with a collider component.

+ +
+

Public functions

+
+
+ auto box() const -> core::geom::Box +
+
Gets a core::geom::Box representation of the AABB.
+
+ auto center() const -> glm::vec3 +
+
Gets the center of the AABB.
+
+ auto overlapsX(const ColliderAABB& other) const -> bool +
+
Checks if the AABB overlaps with another AABB on the X axis.
+
+ auto overlapsY(const ColliderAABB& other) const -> bool +
+
Checks if the AABB overlaps with another AABB on the Y axis.
+
+ auto overlapsZ(const ColliderAABB& other) const -> bool +
+
Checks if the AABB overlaps with another AABB on the Z axis.
+
+ auto overlaps(const ColliderAABB& other) const -> bool +
+
Checks if the AABB overlaps with another AABB.
+
+
+
+

Public variables

+
+
+ glm::vec3 min +
+
Minimum point of the diagonal of the AABB.
+
+ glm::vec3 max +
+
Maximum point of the diagonal of the AABB.
+
+
+
+

Function documentation

+
+

+ core::geom::Box cubos::engine::ColliderAABB::box() const +

+

Gets a core::geom::Box representation of the AABB.

+ + + + + + + +
Returnscore::geom::Box representation.
+
+
+

+ glm::vec3 cubos::engine::ColliderAABB::center() const +

+

Gets the center of the AABB.

+ + + + + + + +
ReturnsCenter of the AABB.
+
+
+

+ bool cubos::engine::ColliderAABB::overlapsX(const ColliderAABB& other) const +

+

Checks if the AABB overlaps with another AABB on the X axis.

+ + + + + + + + + + + + + + + + +
Parameters
otherOther AABB.
ReturnsWhether the AABBs overlap.
+
+
+

+ bool cubos::engine::ColliderAABB::overlapsY(const ColliderAABB& other) const +

+

Checks if the AABB overlaps with another AABB on the Y axis.

+ + + + + + + + + + + + + + + + +
Parameters
otherOther AABB.
ReturnsWhether the AABBs overlap.
+
+
+

+ bool cubos::engine::ColliderAABB::overlapsZ(const ColliderAABB& other) const +

+

Checks if the AABB overlaps with another AABB on the Z axis.

+ + + + + + + + + + + + + + + + +
Parameters
otherOther AABB.
ReturnsWhether the AABBs overlap.
+
+
+

+ bool cubos::engine::ColliderAABB::overlaps(const ColliderAABB& other) const +

+

Checks if the AABB overlaps with another AABB.

+ + + + + + + + + + + + + + + + +
Parameters
otherOther AABB.
ReturnsWhether the AABBs overlap.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1engine_1_1DeltaTime.html b/pr-preview/pr-589/structcubos_1_1engine_1_1DeltaTime.html new file mode 100644 index 000000000..c7fbd31f3 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1DeltaTime.html @@ -0,0 +1,102 @@ + + + + + cubos::engine::DeltaTime struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::engine::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.

+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1engine_1_1DirectionalLight.html b/pr-preview/pr-589/structcubos_1_1engine_1_1DirectionalLight.html new file mode 100644 index 000000000..1cc444390 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1DirectionalLight.html @@ -0,0 +1,102 @@ + + + + + cubos::engine::DirectionalLight struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1engine_1_1LocalToWorld.html b/pr-preview/pr-589/structcubos_1_1engine_1_1LocalToWorld.html new file mode 100644 index 000000000..5df2028a4 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1LocalToWorld.html @@ -0,0 +1,122 @@ + + + + + cubos::engine::LocalToWorld struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/structcubos_1_1engine_1_1PlaneCollider.html b/pr-preview/pr-589/structcubos_1_1engine_1_1PlaneCollider.html new file mode 100644 index 000000000..d19aef7bb --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1PlaneCollider.html @@ -0,0 +1,140 @@ + + + + + cubos::engine::PlaneCollider struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::engine::PlaneCollider struct + +

+

Component which adds a plane collider to an entity.

+ +
  • Zero thickness: Not suitable for dynamic objects, but can be used for static objects.
  • Positive margin: Requires a positive margin. Defined in physics-space units.
+
+

Public variables

+
+
+ glm::vec3 offset +
+
Offset of the collider.
+
+ cubos::core::geom::Plane shape +
+
Plane shape of the collider.
+
+ float margin +
+
Margin of the collider. Needed for creating the AABB.
+
+
+
+

Variable documentation

+
+

+ float cubos::engine::PlaneCollider::margin +

+

Margin of the collider. Needed for creating the AABB.

+

The collider margin is absolute so the collider's transform won't affect it. Shouldn't be changed without good reason.

+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1engine_1_1PointLight.html b/pr-preview/pr-589/structcubos_1_1engine_1_1PointLight.html new file mode 100644 index 000000000..d7803df4e --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1PointLight.html @@ -0,0 +1,102 @@ + + + + + cubos::engine::PointLight struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1engine_1_1Position.html b/pr-preview/pr-589/structcubos_1_1engine_1_1Position.html new file mode 100644 index 000000000..941e9ad04 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1Position.html @@ -0,0 +1,122 @@ + + + + + cubos::engine::Position struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1engine_1_1RenderableGrid.html b/pr-preview/pr-589/structcubos_1_1engine_1_1RenderableGrid.html new file mode 100644 index 000000000..a23fdf8ba --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1RenderableGrid.html @@ -0,0 +1,130 @@ + + + + + cubos::engine::RenderableGrid struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::engine::RenderableGrid struct + +

+

Component which makes a voxel grid be rendered by the renderer plugin.

+ + +
+

Public variables

+
+
+ Asset<core::gl::Grid> 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/pr-preview/pr-589/structcubos_1_1engine_1_1RendererEnvironment.html b/pr-preview/pr-589/structcubos_1_1engine_1_1RendererEnvironment.html new file mode 100644 index 000000000..dfc76f5bf --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1RendererEnvironment.html @@ -0,0 +1,125 @@ + + + + + cubos::engine::RendererEnvironment struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1engine_1_1RendererFrame_1_1DrawCmd.html b/pr-preview/pr-589/structcubos_1_1engine_1_1RendererFrame_1_1DrawCmd.html new file mode 100644 index 000000000..850369e72 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1RendererFrame_1_1DrawCmd.html @@ -0,0 +1,125 @@ + + + + + cubos::engine::RendererFrame::DrawCmd struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1engine_1_1Rotation.html b/pr-preview/pr-589/structcubos_1_1engine_1_1Rotation.html new file mode 100644 index 000000000..e5ae28046 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1Rotation.html @@ -0,0 +1,122 @@ + + + + + cubos::engine::Rotation struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1engine_1_1Scale.html b/pr-preview/pr-589/structcubos_1_1engine_1_1Scale.html new file mode 100644 index 000000000..188b3b2ea --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1Scale.html @@ -0,0 +1,122 @@ + + + + + cubos::engine::Scale struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1engine_1_1Scene.html b/pr-preview/pr-589/structcubos_1_1engine_1_1Scene.html new file mode 100644 index 000000000..d751827b2 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1Scene.html @@ -0,0 +1,126 @@ + + + + + cubos::engine::Scene struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/structcubos_1_1engine_1_1ShouldQuit.html b/pr-preview/pr-589/structcubos_1_1engine_1_1ShouldQuit.html new file mode 100644 index 000000000..a1c2b34be --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1ShouldQuit.html @@ -0,0 +1,102 @@ + + + + + cubos::engine::ShouldQuit struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::engine::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.

+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1engine_1_1SimplexCollider.html b/pr-preview/pr-589/structcubos_1_1engine_1_1SimplexCollider.html new file mode 100644 index 000000000..69fca3aa0 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1SimplexCollider.html @@ -0,0 +1,140 @@ + + + + + cubos::engine::SimplexCollider struct | CUBOS. + + + + + + + +
+
+
+
+
+

+ cubos::engine::SimplexCollider struct + +

+

Component which adds a simplex collider to an entity.

+ +
  • Convex: For any 2 points inside the shape, the line segment connecting those points lies inside the shape.
  • Positive margin: Requires a positive margin to round off sharp corners. Defined in physics-space units.
  • Zero thickness (up to 3 points): Not suitable for dynamic objects, but can be used for static objects.
+
+

Public variables

+
+
+ glm::vec3 offset +
+
Offset of the collider.
+
+ cubos::core::geom::Simplex shape +
+
Simplex shape of the collider.
+
+ float margin +
+
Margin of the collider. Needed for collision stability.
+
+
+
+

Variable documentation

+
+

+ float cubos::engine::SimplexCollider::margin +

+

Margin of the collider. Needed for collision stability.

+

The collider margin avoids collision errors by rounding off sharp corners. Shouldn't be changed without good reason, it's preferable to move the simplex corners to account for it.

+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1engine_1_1SpotLight.html b/pr-preview/pr-589/structcubos_1_1engine_1_1SpotLight.html new file mode 100644 index 000000000..b47478f71 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1SpotLight.html @@ -0,0 +1,102 @@ + + + + + cubos::engine::SpotLight struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1engine_1_1tools_1_1AssetSelectedEvent.html b/pr-preview/pr-589/structcubos_1_1engine_1_1tools_1_1AssetSelectedEvent.html new file mode 100644 index 000000000..7d8cee594 --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1tools_1_1AssetSelectedEvent.html @@ -0,0 +1,121 @@ + + + + + cubos::engine::tools::AssetSelectedEvent struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/structcubos_1_1engine_1_1tools_1_1EntitySelector.html b/pr-preview/pr-589/structcubos_1_1engine_1_1tools_1_1EntitySelector.html new file mode 100644 index 000000000..5d4fee6ba --- /dev/null +++ b/pr-preview/pr-589/structcubos_1_1engine_1_1tools_1_1EntitySelector.html @@ -0,0 +1,121 @@ + + + + + cubos::engine::tools::EntitySelector struct | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/system_8hpp.html b/pr-preview/pr-589/system_8hpp.html new file mode 100644 index 000000000..f2ddbae6f --- /dev/null +++ b/pr-preview/pr-589/system_8hpp.html @@ -0,0 +1,155 @@ + + + + + core/ecs/system.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/ecs/system.hpp file +

+

Class cubos::core::ecs::SystemWrapper and related types.

+ +

This file is a bit scary, but it's not as bad as it looks. It's mostly template specializations to handle the different types of arguments a system can take.

+
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::ecs
+
ECS module.
+
namespace cubos::core::ecs::impl
+
Contains functions used internally by the implementation of the ECS.
+
+
+
+

Classes

+
+
+ struct cubos::core::ecs::SystemInfo +
+
Describes a system.
+
+
template<typename R>
+ class cubos::core::ecs::AnySystemWrapper +
+
Base class for system wrappers.
+
+
template<typename T>
+ struct cubos::core::ecs::impl::SystemFetcher +
+
Fetches the requested data from a world.
+
+
template<typename F>
+ struct cubos::core::ecs::impl::SystemTraits +
+
Template magic used to inspect the arguments of a system.
+
+
template<typename F>
+ class cubos::core::ecs::SystemWrapper +
+
Wrapper for a system of type F.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/thread__pool_8hpp.html b/pr-preview/pr-589/thread__pool_8hpp.html new file mode 100644 index 000000000..a5d2d0f8d --- /dev/null +++ b/pr-preview/pr-589/thread__pool_8hpp.html @@ -0,0 +1,130 @@ + + + + + core/thread_pool.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/tools_2asset__explorer_2plugin_8hpp.html b/pr-preview/pr-589/tools_2asset__explorer_2plugin_8hpp.html new file mode 100644 index 000000000..cacf7f372 --- /dev/null +++ b/pr-preview/pr-589/tools_2asset__explorer_2plugin_8hpp.html @@ -0,0 +1,142 @@ + + + + + engine/tools/asset_explorer/plugin.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ engine/tools/asset_explorer/plugin.hpp file +

+

Plugin entry point.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::engine
+
Engine module.
+
namespace cubos::engine::tools
+
Namespace for tool plugins.
+
+
+
+

Classes

+
+
+ struct cubos::engine::tools::AssetSelectedEvent +
+
Event sent when an asset is selected.
+
+
+
+

Functions

+
+
+ void assetExplorerPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/tools_2entity__inspector_2plugin_8hpp.html b/pr-preview/pr-589/tools_2entity__inspector_2plugin_8hpp.html new file mode 100644 index 000000000..0d74523cb --- /dev/null +++ b/pr-preview/pr-589/tools_2entity__inspector_2plugin_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/tools/entity_inspector/plugin.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/tools_2entity__selector_2plugin_8hpp.html b/pr-preview/pr-589/tools_2entity__selector_2plugin_8hpp.html new file mode 100644 index 000000000..fc3ad016f --- /dev/null +++ b/pr-preview/pr-589/tools_2entity__selector_2plugin_8hpp.html @@ -0,0 +1,142 @@ + + + + + engine/tools/entity_selector/plugin.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ engine/tools/entity_selector/plugin.hpp file +

+

Plugin entry point.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::engine
+
Engine module.
+
namespace cubos::engine::tools
+
Namespace for tool plugins.
+
+
+
+

Classes

+
+
+ struct cubos::engine::tools::EntitySelector +
+
Resource which identifies the currently selected entity.
+
+
+
+

Functions

+
+
+ void entitySelectorPlugin(Cubos& cubos) +
+
Plugin entry function.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/tools_2scene__editor_2plugin_8hpp.html b/pr-preview/pr-589/tools_2scene__editor_2plugin_8hpp.html new file mode 100644 index 000000000..b20f19d56 --- /dev/null +++ b/pr-preview/pr-589/tools_2scene__editor_2plugin_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/tools/scene_editor/plugin.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/tools_2settings__inspector_2plugin_8hpp.html b/pr-preview/pr-589/tools_2settings__inspector_2plugin_8hpp.html new file mode 100644 index 000000000..4fd8e7e5d --- /dev/null +++ b/pr-preview/pr-589/tools_2settings__inspector_2plugin_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/tools/settings_inspector/plugin.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/tools_2world__inspector_2plugin_8hpp.html b/pr-preview/pr-589/tools_2world__inspector_2plugin_8hpp.html new file mode 100644 index 000000000..49deea16e --- /dev/null +++ b/pr-preview/pr-589/tools_2world__inspector_2plugin_8hpp.html @@ -0,0 +1,132 @@ + + + + + engine/tools/world_inspector/plugin.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/transform_2plugin_8hpp.html b/pr-preview/pr-589/transform_2plugin_8hpp.html new file mode 100644 index 000000000..afaf7ea18 --- /dev/null +++ b/pr-preview/pr-589/transform_2plugin_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/transform/plugin.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/type_8hpp.html b/pr-preview/pr-589/type_8hpp.html new file mode 100644 index 000000000..0df04595e --- /dev/null +++ b/pr-preview/pr-589/type_8hpp.html @@ -0,0 +1,132 @@ + + + + + core/reflection/type.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/type__map_8hpp.html b/pr-preview/pr-589/type__map_8hpp.html new file mode 100644 index 000000000..e2cf68e4f --- /dev/null +++ b/pr-preview/pr-589/type__map_8hpp.html @@ -0,0 +1,133 @@ + + + + + core/memory/type_map.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/util_8hpp.html b/pr-preview/pr-589/util_8hpp.html new file mode 100644 index 000000000..f3c1afa79 --- /dev/null +++ b/pr-preview/pr-589/util_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/gl/util.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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/pr-preview/pr-589/vec__storage_8hpp.html b/pr-preview/pr-589/vec__storage_8hpp.html new file mode 100644 index 000000000..a35d1795a --- /dev/null +++ b/pr-preview/pr-589/vec__storage_8hpp.html @@ -0,0 +1,133 @@ + + + + + core/ecs/vec_storage.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/vertex_8hpp.html b/pr-preview/pr-589/vertex_8hpp.html new file mode 100644 index 000000000..591c75136 --- /dev/null +++ b/pr-preview/pr-589/vertex_8hpp.html @@ -0,0 +1,146 @@ + + + + + core/gl/vertex.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ core/gl/vertex.hpp file +

+

Class cubos::core::gl::Vertex and function cubos::core::gl::triangulate.

+ +
+

Namespaces

+
+
namespace cubos
+
CUBOS. libraries namespace.
+
namespace cubos::core
+
Core namespace.
+
namespace cubos::core::gl
+
Graphics module.
+
namespace cubos::core::data
+
Data module.
+
+
+
+

Classes

+
+
+ struct cubos::core::gl::Vertex +
+
Represents a voxel vertex.
+
+
+
+

Functions

+
+
+ void triangulate(const Grid& grid, + std::vector<Vertex>& vertices, + std::vector<uint32_t>& indices) +
+
Triangulates a grid of voxels into an indexed mesh.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/voxels_2plugin_8hpp.html b/pr-preview/pr-589/voxels_2plugin_8hpp.html new file mode 100644 index 000000000..5a6728dc9 --- /dev/null +++ b/pr-preview/pr-589/voxels_2plugin_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/voxels/plugin.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/window_2plugin_8hpp.html b/pr-preview/pr-589/window_2plugin_8hpp.html new file mode 100644 index 000000000..c1b14e39a --- /dev/null +++ b/pr-preview/pr-589/window_2plugin_8hpp.html @@ -0,0 +1,130 @@ + + + + + engine/window/plugin.hpp file | CUBOS. + + + + + + + +
+
+ + + +
+ + diff --git a/pr-preview/pr-589/window_8hpp.html b/pr-preview/pr-589/window_8hpp.html new file mode 100644 index 000000000..cc4dd4a73 --- /dev/null +++ b/pr-preview/pr-589/window_8hpp.html @@ -0,0 +1,218 @@ + + + + + core/io/window.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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.
+
+
+
+
+
+
+ + + +
+ + diff --git a/pr-preview/pr-589/world_8hpp.html b/pr-preview/pr-589/world_8hpp.html new file mode 100644 index 000000000..b6d66e1e6 --- /dev/null +++ b/pr-preview/pr-589/world_8hpp.html @@ -0,0 +1,134 @@ + + + + + core/ecs/world.hpp file | CUBOS. + + + + + + + +
+
+
+
+
+

+ 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.
+
namespace cubos::core::ecs::impl
+
Contains functions used internally by the implementation of the ECS.
+
+
+
+

Classes

+
+
+ class cubos::core::ecs::World +
+
Holds entities, their components and resources.
+
+
+
+
+
+
+ + + +
+ +