feat(kotlin-compose): design system + 33 components + gallery_kt + e2e android emulator + scaffolder fixes
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Vendored
+43
@@ -0,0 +1,43 @@
|
||||
# miniaudio vendoring
|
||||
|
||||
- **Source**: https://github.com/mackron/miniaudio
|
||||
- **Version pinned**: see `cpp/vendor/miniaudio/.version` (0.11.25 at vendoring time)
|
||||
- **License**: Public domain / MIT-0 dual (`cpp/vendor/miniaudio/LICENSE`)
|
||||
- **Header**: `cpp/vendor/miniaudio/miniaudio.h` (~4 MB texto, ~200 KB compilado strippable)
|
||||
|
||||
## Vendoring command
|
||||
|
||||
```
|
||||
mkdir -p cpp/vendor/miniaudio && cd cpp/vendor/miniaudio && \
|
||||
TAG=$(curl -s https://api.github.com/repos/mackron/miniaudio/releases/latest | grep -m1 '"tag_name"' | cut -d'"' -f4) && \
|
||||
curl -fsSL "https://raw.githubusercontent.com/mackron/miniaudio/$TAG/miniaudio.h" -o miniaudio.h && \
|
||||
curl -fsSL "https://raw.githubusercontent.com/mackron/miniaudio/$TAG/LICENSE" -o LICENSE && \
|
||||
echo "$TAG" > .version
|
||||
```
|
||||
|
||||
## Por qué miniaudio
|
||||
|
||||
- Single-header. Encaja con cultura del registry.
|
||||
- Cubre TODAS las plataformas del stack gamedev (issue 0072): Win (WASAPI/DirectSound), Mac (CoreAudio), Linux (PulseAudio/ALSA/JACK), Android (AAudio/OpenSL ES), iOS (CoreAudio), Emscripten (Web Audio).
|
||||
- Sin dependencias externas.
|
||||
- API C limpia, facil de wrappear como funciones del registry.
|
||||
- Decode wav/flac nativo. mp3 + ogg vorbis vienen via dependencias single-header opcionales (`stb_vorbis.c`, `dr_mp3.h`) o se enchufan como callback custom.
|
||||
|
||||
## Compilacion
|
||||
|
||||
`miniaudio.h` se incluye con `#define MINIAUDIO_IMPLEMENTATION` exactamente en UNA TU. Para apps que solo quieran la API, incluir sin el define.
|
||||
|
||||
Convencion del registry: la funcion `audio_init_cpp_gamedev` define `MINIAUDIO_IMPLEMENTATION` en su `.cpp`. Otras funciones del registry y consumidores solo incluyen `miniaudio.h` sin el define.
|
||||
|
||||
## Backends en WASM
|
||||
|
||||
Bajo emscripten, miniaudio usa Web Audio API. Requiere user gesture para arrancar (`navigator.userActivation`). Documentar en `cpp/GAMEDEV.md`: el primer click del usuario activa el audio context.
|
||||
|
||||
## Upgrade
|
||||
|
||||
```
|
||||
cd cpp/vendor/miniaudio
|
||||
TAG=$(curl -s https://api.github.com/repos/mackron/miniaudio/releases/latest | grep -m1 '"tag_name"' | cut -d'"' -f4)
|
||||
curl -fsSL "https://raw.githubusercontent.com/mackron/miniaudio/$TAG/miniaudio.h" -o miniaudio.h
|
||||
echo "$TAG" > .version
|
||||
```
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
0.11.25
|
||||
Vendored
+47
@@ -0,0 +1,47 @@
|
||||
This software is available as a choice of the following licenses. Choose
|
||||
whichever you prefer.
|
||||
|
||||
===============================================================================
|
||||
ALTERNATIVE 1 - Public Domain (www.unlicense.org)
|
||||
===============================================================================
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
commercial or non-commercial, and by any means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
this software under copyright law.
|
||||
|
||||
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 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.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
|
||||
===============================================================================
|
||||
ALTERNATIVE 2 - MIT No Attribution
|
||||
===============================================================================
|
||||
Copyright 2025 David Reid
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
Vendored
+95864
File diff suppressed because it is too large
Load Diff
+1
Submodule cpp/vendor/sdl3 added at d9d5536704
Vendored
+25
@@ -0,0 +1,25 @@
|
||||
# SDL3 vendoring
|
||||
|
||||
- **Source**: https://github.com/libsdl-org/SDL
|
||||
- **Tag**: `release-3.4.8` (May 2026)
|
||||
- **License**: Zlib (`cpp/vendor/sdl3/LICENSE.txt`)
|
||||
- **Vendoring command**:
|
||||
```
|
||||
cd cpp/vendor && git clone --depth 1 --branch release-3.4.8 \
|
||||
https://github.com/libsdl-org/SDL.git sdl3
|
||||
```
|
||||
- **Build**: SDL3 trae su propio `CMakeLists.txt`. Se incluye via `add_subdirectory(vendor/sdl3)` en apps que lo usen y se enlaza target `SDL3::SDL3` o `SDL3::SDL3-static`.
|
||||
- **Tamaño en disco**: ~71 MB (incluye plataform-specifics que NO necesitamos en Linux/Web). Si crece excesivo, considerar mover a submodulo o purgar `Xcode/`, `VisualC*/`, `android-project/` cuando esten cubiertos por sus apps mobile.
|
||||
|
||||
## Por qué SDL3 (no SDL2 ni GLFW)
|
||||
|
||||
- Cubre todas las plataformas objetivo del stack gamedev: Win, Lin, Mac, Android, iOS, Emscripten.
|
||||
- API oficial estable desde finales 2024.
|
||||
- Touch input + virtual gamepad nativos.
|
||||
- Audio integrado.
|
||||
- ImGui ya tiene backend `imgui_impl_sdl3.{h,cpp}` en `cpp/vendor/imgui/backends/`.
|
||||
- Compatible con sokol_gfx (manual GL context creation).
|
||||
|
||||
## Upgrade
|
||||
|
||||
Re-clonar con nuevo tag. SDL3 sigue semver, breaking changes solo entre majors.
|
||||
Vendored
+54
@@ -0,0 +1,54 @@
|
||||
# sokol vendoring
|
||||
|
||||
- **Source**: https://github.com/floooh/sokol
|
||||
- **Commit pinned**: `5cc3e913258fb63d87c7728569f14005f638e315` (ver `cpp/vendor/sokol/.commit-sha`)
|
||||
- **License**: Zlib (`cpp/vendor/sokol/LICENSE`)
|
||||
- **Headers vendoreados** (single-header):
|
||||
- `sokol_gfx.h` — graphics abstraction (GL/GLES/WebGL2/Metal/D3D11)
|
||||
- `sokol_log.h` — logger callback
|
||||
- `sokol_glue.h` — helpers para integracion contexto
|
||||
- `sokol_app.h` — windowing/input. **NO se usa**: usamos SDL3 para windowing. Vendoreado por si una app standalone lo quiere.
|
||||
- **Vendoring command**:
|
||||
```
|
||||
mkdir -p cpp/vendor/sokol && cd cpp/vendor/sokol && \
|
||||
SHA=$(curl -s https://api.github.com/repos/floooh/sokol/commits/master | \
|
||||
grep -m1 '"sha"' | cut -d'"' -f4) && \
|
||||
for f in sokol_gfx.h sokol_log.h sokol_glue.h sokol_app.h LICENSE; do
|
||||
curl -fsSL "https://raw.githubusercontent.com/floooh/sokol/$SHA/$f" -o "$f"
|
||||
done && echo "$SHA" > .commit-sha
|
||||
```
|
||||
|
||||
## Por qué sokol_gfx
|
||||
|
||||
- Single-header, ~1.2 MB texto, ~50 KB compilado strippable.
|
||||
- Backends: GL 3.3, GLES3, WebGL2, Metal, D3D11. **Cubre las 4 plataformas + web** del stack gamedev (issue 0072).
|
||||
- Sin dependencias externas.
|
||||
- Determinista, sin estado global oculto.
|
||||
- Encaja con cultura "single-file function" del registry.
|
||||
|
||||
## Compile-time backend selection
|
||||
|
||||
El backend se elige con macros:
|
||||
|
||||
| Macro | Backend |
|
||||
|---|---|
|
||||
| `SOKOL_GLCORE` | OpenGL 3.3 desktop |
|
||||
| `SOKOL_GLES3` | OpenGL ES 3.0 (Android, iOS sin Metal) |
|
||||
| `SOKOL_METAL` | Metal (iOS/macOS) |
|
||||
| `SOKOL_D3D11` | D3D11 (Windows) |
|
||||
| `SOKOL_WGPU` | WebGPU (alpha, no usar aun) |
|
||||
|
||||
Para WASM con `-sUSE_WEBGL2=1`: definir `SOKOL_GLES3`.
|
||||
|
||||
## Sokol_app NO se usa
|
||||
|
||||
Mantenemos `sokol_app.h` vendoreado por completitud pero el stack usa **SDL3** para windowing/input. Sokol_app duplicaria la responsabilidad y limita acceso a APIs SDL (audio, gamepad, WalletConnect deep links).
|
||||
|
||||
## Upgrade
|
||||
|
||||
```
|
||||
cd cpp/vendor/sokol
|
||||
SHA=$(curl -s https://api.github.com/repos/floooh/sokol/commits/master | grep -m1 '"sha"' | cut -d'"' -f4)
|
||||
# Repetir el for loop del vendoring command
|
||||
echo "$SHA" > .commit-sha
|
||||
```
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
5cc3e913258fb63d87c7728569f14005f638e315
|
||||
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
zlib/libpng license
|
||||
|
||||
Copyright (c) 2018 Andre Weissflog
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the
|
||||
use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software in a
|
||||
product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not
|
||||
be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
Vendored
+14493
File diff suppressed because it is too large
Load Diff
Vendored
+26796
File diff suppressed because it is too large
Load Diff
Vendored
+207
@@ -0,0 +1,207 @@
|
||||
#if defined(SOKOL_IMPL) && !defined(SOKOL_GLUE_IMPL)
|
||||
#define SOKOL_GLUE_IMPL
|
||||
#endif
|
||||
#ifndef SOKOL_GLUE_INCLUDED
|
||||
/*
|
||||
sokol_glue.h -- glue helper functions for sokol headers
|
||||
|
||||
Project URL: https://github.com/floooh/sokol
|
||||
|
||||
Do this:
|
||||
#define SOKOL_IMPL or
|
||||
#define SOKOL_GLUE_IMPL
|
||||
before you include this file in *one* C or C++ file to create the
|
||||
implementation.
|
||||
|
||||
...optionally provide the following macros to override defaults:
|
||||
|
||||
SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
|
||||
SOKOL_GLUE_API_DECL - public function declaration prefix (default: extern)
|
||||
SOKOL_API_DECL - same as SOKOL_GLUE_API_DECL
|
||||
SOKOL_API_IMPL - public function implementation prefix (default: -)
|
||||
|
||||
If sokol_glue.h is compiled as a DLL, define the following before
|
||||
including the declaration or implementation:
|
||||
|
||||
SOKOL_DLL
|
||||
|
||||
On Windows, SOKOL_DLL will define SOKOL_GLUE_API_DECL as __declspec(dllexport)
|
||||
or __declspec(dllimport) as needed.
|
||||
|
||||
OVERVIEW
|
||||
========
|
||||
sokol_glue.h provides glue helper functions between sokol_gfx.h and sokol_app.h,
|
||||
so that sokol_gfx.h doesn't need to depend on sokol_app.h but can be
|
||||
used with different window system glue libraries.
|
||||
|
||||
PROVIDED FUNCTIONS
|
||||
==================
|
||||
|
||||
sg_environment sglue_environment(void)
|
||||
|
||||
Returns an sg_environment struct initialized by calling sokol_app.h
|
||||
functions. Use this in the sg_setup() call like this:
|
||||
|
||||
sg_setup(&(sg_desc){
|
||||
.environment = sglue_environment(),
|
||||
...
|
||||
});
|
||||
|
||||
sg_swapchain sglue_swapchain(void)
|
||||
|
||||
Returns an sg_swapchain struct initialized by calling sokol_app.h
|
||||
functions. Use this in sg_begin_pass() for a 'swapchain pass' like
|
||||
this:
|
||||
|
||||
sg_begin_pass(&(sg_pass){ .swapchain = sglue_swapchain(), ... });
|
||||
|
||||
LICENSE
|
||||
=======
|
||||
zlib/libpng license
|
||||
|
||||
Copyright (c) 2018 Andre Weissflog
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the
|
||||
use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software in a
|
||||
product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not
|
||||
be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
#define SOKOL_GLUE_INCLUDED
|
||||
|
||||
#if defined(SOKOL_API_DECL) && !defined(SOKOL_GLUE_API_DECL)
|
||||
#define SOKOL_GLUE_API_DECL SOKOL_API_DECL
|
||||
#endif
|
||||
#ifndef SOKOL_GLUE_API_DECL
|
||||
#if defined(_WIN32) && defined(SOKOL_DLL) && defined(SOKOL_GLUE_IMPL)
|
||||
#define SOKOL_GLUE_API_DECL __declspec(dllexport)
|
||||
#elif defined(_WIN32) && defined(SOKOL_DLL)
|
||||
#define SOKOL_GLUE_API_DECL __declspec(dllimport)
|
||||
#else
|
||||
#define SOKOL_GLUE_API_DECL extern
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SOKOL_GFX_INCLUDED
|
||||
#error "Please include sokol_gfx.h before sokol_glue.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
SOKOL_GLUE_API_DECL sg_environment sglue_environment(void);
|
||||
SOKOL_GLUE_API_DECL sg_swapchain sglue_swapchain(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
#endif /* SOKOL_GLUE_INCLUDED */
|
||||
|
||||
/*-- IMPLEMENTATION ----------------------------------------------------------*/
|
||||
#ifdef SOKOL_GLUE_IMPL
|
||||
#define SOKOL_GLUE_IMPL_INCLUDED (1)
|
||||
#include <string.h> /* memset */
|
||||
|
||||
#ifndef SOKOL_APP_INCLUDED
|
||||
#error "Please include sokol_app.h before the sokol_glue.h implementation"
|
||||
#endif
|
||||
|
||||
#ifndef SOKOL_API_IMPL
|
||||
#define SOKOL_API_IMPL
|
||||
#endif
|
||||
|
||||
#ifndef _SOKOL_PRIVATE
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define _SOKOL_PRIVATE __attribute__((unused)) static
|
||||
#else
|
||||
#define _SOKOL_PRIVATE static
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SOKOL_ASSERT
|
||||
#include <assert.h>
|
||||
#define SOKOL_ASSERT(c) assert(c)
|
||||
#endif
|
||||
#ifndef SOKOL_UNREACHABLE
|
||||
#define SOKOL_UNREACHABLE SOKOL_ASSERT(false)
|
||||
#endif
|
||||
|
||||
_SOKOL_PRIVATE sg_pixel_format _sglue_to_sgpixelformat(sapp_pixel_format fmt) {
|
||||
switch (fmt) {
|
||||
case SAPP_PIXELFORMAT_NONE: return SG_PIXELFORMAT_NONE;
|
||||
case SAPP_PIXELFORMAT_RGBA8: return SG_PIXELFORMAT_RGBA8;
|
||||
case SAPP_PIXELFORMAT_SRGB8A8: return SG_PIXELFORMAT_SRGB8A8;
|
||||
case SAPP_PIXELFORMAT_BGRA8: return SG_PIXELFORMAT_BGRA8;
|
||||
case SAPP_PIXELFORMAT_DEPTH_STENCIL: return SG_PIXELFORMAT_DEPTH_STENCIL;
|
||||
case SAPP_PIXELFORMAT_DEPTH: return SG_PIXELFORMAT_DEPTH;
|
||||
case SAPP_PIXELFORMAT_SBGRA8: // FIXME!
|
||||
default:
|
||||
SOKOL_UNREACHABLE;
|
||||
return SG_PIXELFORMAT_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL sg_environment sglue_environment(void) {
|
||||
sg_environment res;
|
||||
memset(&res, 0, sizeof(res));
|
||||
const sapp_environment env = sapp_get_environment();
|
||||
res.defaults.color_format = _sglue_to_sgpixelformat(env.defaults.color_format);
|
||||
res.defaults.depth_format = _sglue_to_sgpixelformat(env.defaults.depth_format);
|
||||
res.defaults.sample_count = env.defaults.sample_count;
|
||||
res.metal.device = env.metal.device;
|
||||
res.d3d11.device = env.d3d11.device;
|
||||
res.d3d11.device_context = env.d3d11.device_context;
|
||||
res.wgpu.device = env.wgpu.device;
|
||||
res.vulkan.instance = env.vulkan.instance;
|
||||
res.vulkan.physical_device = env.vulkan.physical_device;
|
||||
res.vulkan.device = env.vulkan.device;
|
||||
res.vulkan.queue = env.vulkan.queue;
|
||||
res.vulkan.queue_family_index = env.vulkan.queue_family_index;
|
||||
return res;
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL sg_swapchain sglue_swapchain(void) {
|
||||
sg_swapchain res;
|
||||
memset(&res, 0, sizeof(res));
|
||||
const sapp_swapchain sc = sapp_get_swapchain();
|
||||
res.width = sc.width;
|
||||
res.height = sc.height;
|
||||
res.sample_count = sc.sample_count;
|
||||
res.color_format = _sglue_to_sgpixelformat(sc.color_format);
|
||||
res.depth_format = _sglue_to_sgpixelformat(sc.depth_format);
|
||||
res.metal.current_drawable = sc.metal.current_drawable;
|
||||
res.metal.depth_stencil_texture = sc.metal.depth_stencil_texture;
|
||||
res.metal.msaa_color_texture = sc.metal.msaa_color_texture;
|
||||
res.d3d11.render_view = sc.d3d11.render_view;
|
||||
res.d3d11.resolve_view = sc.d3d11.resolve_view;
|
||||
res.d3d11.depth_stencil_view = sc.d3d11.depth_stencil_view;
|
||||
res.wgpu.render_view = sc.wgpu.render_view;
|
||||
res.wgpu.resolve_view = sc.wgpu.resolve_view;
|
||||
res.wgpu.depth_stencil_view = sc.wgpu.depth_stencil_view;
|
||||
res.vulkan.render_image = sc.vulkan.render_image;
|
||||
res.vulkan.render_view = sc.vulkan.render_view;
|
||||
res.vulkan.resolve_image = sc.vulkan.resolve_image;
|
||||
res.vulkan.resolve_view = sc.vulkan.resolve_view;
|
||||
res.vulkan.depth_stencil_image = sc.vulkan.depth_stencil_image;
|
||||
res.vulkan.depth_stencil_view = sc.vulkan.depth_stencil_view;
|
||||
res.vulkan.render_finished_semaphore = sc.vulkan.render_finished_semaphore;
|
||||
res.vulkan.present_complete_semaphore = sc.vulkan.present_complete_semaphore;
|
||||
res.gl.framebuffer = sc.gl.framebuffer;
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* SOKOL_GLUE_IMPL */
|
||||
Vendored
+334
@@ -0,0 +1,334 @@
|
||||
#if defined(SOKOL_IMPL) && !defined(SOKOL_LOG_IMPL)
|
||||
#define SOKOL_LOG_IMPL
|
||||
#endif
|
||||
#ifndef SOKOL_LOG_INCLUDED
|
||||
/*
|
||||
sokol_log.h -- common logging callback for sokol headers
|
||||
|
||||
Project URL: https://github.com/floooh/sokol
|
||||
|
||||
Example code: https://github.com/floooh/sokol-samples
|
||||
|
||||
Do this:
|
||||
#define SOKOL_IMPL or
|
||||
#define SOKOL_LOG_IMPL
|
||||
before you include this file in *one* C or C++ file to create the
|
||||
implementation.
|
||||
|
||||
Optionally provide the following defines when building the implementation:
|
||||
|
||||
SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
|
||||
SOKOL_UNREACHABLE() - a guard macro for unreachable code (default: assert(false))
|
||||
SOKOL_LOG_API_DECL - public function declaration prefix (default: extern)
|
||||
SOKOL_API_DECL - same as SOKOL_GFX_API_DECL
|
||||
SOKOL_API_IMPL - public function implementation prefix (default: -)
|
||||
|
||||
Optionally define the following for verbose output:
|
||||
|
||||
SOKOL_DEBUG - by default this is defined if NDEBUG is not defined
|
||||
|
||||
|
||||
OVERVIEW
|
||||
========
|
||||
sokol_log.h provides a default logging callback for other sokol headers.
|
||||
|
||||
To use the default log callback, just include sokol_log.h and provide
|
||||
a function pointer to the 'slog_func' function when setting up the
|
||||
sokol library:
|
||||
|
||||
For instance with sokol_audio.h:
|
||||
|
||||
#include "sokol_log.h"
|
||||
...
|
||||
saudio_setup(&(saudio_desc){ .logger.func = slog_func });
|
||||
|
||||
Logging output goes to stderr and/or a platform specific logging subsystem
|
||||
(which means that in some scenarios you might see logging messages duplicated):
|
||||
|
||||
- Windows: stderr + OutputDebugStringA()
|
||||
- macOS/iOS/Linux: stderr + syslog()
|
||||
- Emscripten: console.info()/warn()/error()
|
||||
- Android: __android_log_write()
|
||||
|
||||
On Windows with sokol_app.h also note the runtime config items to make
|
||||
stdout/stderr output visible on the console for WinMain() applications
|
||||
via sapp_desc.win32.console_attach or sapp_desc.win32.console_create,
|
||||
however when running in a debugger on Windows, the logging output should
|
||||
show up on the debug output UI panel.
|
||||
|
||||
In debug mode, a log message might look like this:
|
||||
|
||||
[sspine][error][id:12] /Users/floh/projects/sokol/util/sokol_spine.h:3472:0:
|
||||
SKELETON_DESC_NO_ATLAS: no atlas object provided in sspine_skeleton_desc.atlas
|
||||
|
||||
The source path and line number is formatted like compiler errors, in some IDEs (like VSCode)
|
||||
such error messages are clickable.
|
||||
|
||||
In release mode, logging is less verbose as to not bloat the executable with string data, but you still get
|
||||
enough information to identify the type and location of an error:
|
||||
|
||||
[sspine][error][id:12][line:3472]
|
||||
|
||||
RULES FOR WRITING YOUR OWN LOGGING FUNCTION
|
||||
===========================================
|
||||
- must be re-entrant because it might be called from different threads
|
||||
- must treat **all** provided string pointers as optional (can be null)
|
||||
- don't store the string pointers, copy the string data instead
|
||||
- must not return for log level panic
|
||||
|
||||
LICENSE
|
||||
=======
|
||||
zlib/libpng license
|
||||
|
||||
Copyright (c) 2023 Andre Weissflog
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the
|
||||
use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software in a
|
||||
product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not
|
||||
be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
#define SOKOL_LOG_INCLUDED (1)
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(SOKOL_API_DECL) && !defined(SOKOL_LOG_API_DECL)
|
||||
#define SOKOL_LOG_API_DECL SOKOL_API_DECL
|
||||
#endif
|
||||
#ifndef SOKOL_LOG_API_DECL
|
||||
#if defined(_WIN32) && defined(SOKOL_DLL) && defined(SOKOL_LOG_IMPL)
|
||||
#define SOKOL_LOG_API_DECL __declspec(dllexport)
|
||||
#elif defined(_WIN32) && defined(SOKOL_DLL)
|
||||
#define SOKOL_LOG_API_DECL __declspec(dllimport)
|
||||
#else
|
||||
#define SOKOL_LOG_API_DECL extern
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
Plug this function into the 'logger.func' struct item when initializing any of the sokol
|
||||
headers. For instance for sokol_audio.h it would look like this:
|
||||
|
||||
saudio_setup(&(saudio_desc){
|
||||
.logger = {
|
||||
.func = slog_func
|
||||
}
|
||||
});
|
||||
*/
|
||||
SOKOL_LOG_API_DECL void slog_func(const char* tag, uint32_t log_level, uint32_t log_item, const char* message, uint32_t line_nr, const char* filename, void* user_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
#endif // SOKOL_LOG_INCLUDED
|
||||
|
||||
// ██ ███ ███ ██████ ██ ███████ ███ ███ ███████ ███ ██ ████████ █████ ████████ ██ ██████ ███ ██
|
||||
// ██ ████ ████ ██ ██ ██ ██ ████ ████ ██ ████ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██
|
||||
// ██ ██ ████ ██ ██████ ██ █████ ██ ████ ██ █████ ██ ██ ██ ██ ███████ ██ ██ ██ ██ ██ ██ ██
|
||||
// ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
// ██ ██ ██ ██ ███████ ███████ ██ ██ ███████ ██ ████ ██ ██ ██ ██ ██ ██████ ██ ████
|
||||
//
|
||||
// >>implementation
|
||||
#ifdef SOKOL_LOG_IMPL
|
||||
#define SOKOL_LOG_IMPL_INCLUDED (1)
|
||||
|
||||
#ifndef SOKOL_API_IMPL
|
||||
#define SOKOL_API_IMPL
|
||||
#endif
|
||||
#ifndef SOKOL_DEBUG
|
||||
#ifndef NDEBUG
|
||||
#define SOKOL_DEBUG
|
||||
#endif
|
||||
#endif
|
||||
#ifndef SOKOL_ASSERT
|
||||
#include <assert.h>
|
||||
#define SOKOL_ASSERT(c) assert(c)
|
||||
#endif
|
||||
|
||||
#ifndef _SOKOL_PRIVATE
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define _SOKOL_PRIVATE __attribute__((unused)) static
|
||||
#else
|
||||
#define _SOKOL_PRIVATE static
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef _SOKOL_UNUSED
|
||||
#define _SOKOL_UNUSED(x) (void)(x)
|
||||
#endif
|
||||
|
||||
// platform detection
|
||||
#if defined(__APPLE__)
|
||||
#define _SLOG_APPLE (1)
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
#define _SLOG_EMSCRIPTEN (1)
|
||||
#elif defined(_WIN32)
|
||||
#define _SLOG_WINDOWS (1)
|
||||
#elif defined(__ANDROID__)
|
||||
#define _SLOG_ANDROID (1)
|
||||
#elif defined(__linux__) || defined(__unix__)
|
||||
#define _SLOG_LINUX (1)
|
||||
#else
|
||||
#error "sokol_log.h: unknown platform"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h> // abort
|
||||
#include <stdio.h> // fputs
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
#if defined(_SLOG_EMSCRIPTEN)
|
||||
#include <emscripten/emscripten.h>
|
||||
#elif defined(_SLOG_WINDOWS)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#elif defined(_SLOG_ANDROID)
|
||||
#include <android/log.h>
|
||||
#elif defined(_SLOG_LINUX) || defined(_SLOG_APPLE)
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
|
||||
// size of line buffer (on stack!) in bytes including terminating zero
|
||||
#define _SLOG_LINE_LENGTH (512)
|
||||
|
||||
_SOKOL_PRIVATE char* _slog_append(const char* str, char* dst, char* end) {
|
||||
if (str) {
|
||||
char c;
|
||||
while (((c = *str++) != 0) && (dst < (end - 1))) {
|
||||
*dst++ = c;
|
||||
}
|
||||
}
|
||||
*dst = 0;
|
||||
return dst;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE char* _slog_itoa(uint32_t x, char* buf, size_t buf_size) {
|
||||
const size_t max_digits_and_null = 11;
|
||||
if (buf_size < max_digits_and_null) {
|
||||
return 0;
|
||||
}
|
||||
char* p = buf + max_digits_and_null;
|
||||
*--p = 0;
|
||||
do {
|
||||
*--p = '0' + (x % 10);
|
||||
x /= 10;
|
||||
} while (x != 0);
|
||||
return p;
|
||||
}
|
||||
|
||||
#if defined(_SLOG_EMSCRIPTEN)
|
||||
EM_JS(void, slog_js_log, (uint32_t level, const char* c_str), {
|
||||
const str = UTF8ToString(c_str);
|
||||
switch (level) {
|
||||
case 0: console.error(str); break;
|
||||
case 1: console.error(str); break;
|
||||
case 2: console.warn(str); break;
|
||||
default: console.info(str); break;
|
||||
}
|
||||
})
|
||||
#endif
|
||||
|
||||
SOKOL_API_IMPL void slog_func(const char* tag, uint32_t log_level, uint32_t log_item, const char* message, uint32_t line_nr, const char* filename, void* user_data) {
|
||||
_SOKOL_UNUSED(user_data);
|
||||
|
||||
const char* log_level_str;
|
||||
switch (log_level) {
|
||||
case 0: log_level_str = "panic"; break;
|
||||
case 1: log_level_str = "error"; break;
|
||||
case 2: log_level_str = "warning"; break;
|
||||
default: log_level_str = "info"; break;
|
||||
}
|
||||
|
||||
// build log output line
|
||||
char line_buf[_SLOG_LINE_LENGTH];
|
||||
char* str = line_buf;
|
||||
char* end = line_buf + sizeof(line_buf);
|
||||
char num_buf[32];
|
||||
if (tag) {
|
||||
str = _slog_append("[", str, end);
|
||||
str = _slog_append(tag, str, end);
|
||||
str = _slog_append("]", str, end);
|
||||
}
|
||||
str = _slog_append("[", str, end);
|
||||
str = _slog_append(log_level_str, str, end);
|
||||
str = _slog_append("]", str, end);
|
||||
str = _slog_append("[id:", str, end);
|
||||
str = _slog_append(_slog_itoa(log_item, num_buf, sizeof(num_buf)), str, end);
|
||||
str = _slog_append("]", str, end);
|
||||
// if a filename is provided, build a clickable log message that's compatible with compiler error messages
|
||||
if (filename) {
|
||||
str = _slog_append(" ", str, end);
|
||||
#if defined(_MSC_VER)
|
||||
// MSVC compiler error format
|
||||
str = _slog_append(filename, str, end);
|
||||
str = _slog_append("(", str, end);
|
||||
str = _slog_append(_slog_itoa(line_nr, num_buf, sizeof(num_buf)), str, end);
|
||||
str = _slog_append("): ", str, end);
|
||||
#else
|
||||
// gcc/clang compiler error format
|
||||
str = _slog_append(filename, str, end);
|
||||
str = _slog_append(":", str, end);
|
||||
str = _slog_append(_slog_itoa(line_nr, num_buf, sizeof(num_buf)), str, end);
|
||||
str = _slog_append(":0: ", str, end);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
str = _slog_append("[line:", str, end);
|
||||
str = _slog_append(_slog_itoa(line_nr, num_buf, sizeof(num_buf)), str, end);
|
||||
str = _slog_append("] ", str, end);
|
||||
}
|
||||
if (message) {
|
||||
str = _slog_append("\n\t", str, end);
|
||||
str = _slog_append(message, str, end);
|
||||
}
|
||||
str = _slog_append("\n\n", str, end);
|
||||
if (0 == log_level) {
|
||||
str = _slog_append("ABORTING because of [panic]\n", str, end);
|
||||
(void)str;
|
||||
}
|
||||
|
||||
// print to stderr?
|
||||
#if defined(_SLOG_LINUX) || defined(_SLOG_WINDOWS) || defined(_SLOG_APPLE)
|
||||
fputs(line_buf, stderr);
|
||||
#endif
|
||||
|
||||
// platform specific logging calls
|
||||
#if defined(_SLOG_WINDOWS)
|
||||
OutputDebugStringA(line_buf);
|
||||
#elif defined(_SLOG_ANDROID)
|
||||
int prio;
|
||||
switch (log_level) {
|
||||
case 0: prio = ANDROID_LOG_FATAL; break;
|
||||
case 1: prio = ANDROID_LOG_ERROR; break;
|
||||
case 2: prio = ANDROID_LOG_WARN; break;
|
||||
default: prio = ANDROID_LOG_INFO; break;
|
||||
}
|
||||
__android_log_write(prio, "SOKOL", line_buf);
|
||||
#elif defined(_SLOG_EMSCRIPTEN)
|
||||
slog_js_log(log_level, line_buf);
|
||||
#endif
|
||||
if (0 == log_level) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
#endif // SOKOL_LOG_IMPL
|
||||
Reference in New Issue
Block a user