diff --git a/.github/workflows/build-doc.yml b/.github/workflows/build-doc.yml index 6bc55191d3..c5c1b1621d 100644 --- a/.github/workflows/build-doc.yml +++ b/.github/workflows/build-doc.yml @@ -36,6 +36,7 @@ jobs: - name: Run samples shell: msys2 {0} run: | + export GFX_BACKEND=D3D12 cd docs/samples for i in $(find shards -name '*.edn'); do @@ -135,7 +136,7 @@ jobs: git config --global user.name "Fragcolor bot" git config --global user.email "bot@fragcolor.xyz" mkdocs gh-deploy --force --message "Publish documentation from {sha} - + Using MkDocs {version}." - name: Upload artifact uses: actions/upload-artifact@v2 diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index c1164b5e68..7e3e4b8850 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -195,7 +195,7 @@ jobs: run: | cd build ninja test_gfx - GFX_TEST_PLATFORM_ID="github-windows" ./test_gfx + GFX_BACKEND=D3D12 GFX_TEST_PLATFORM_ID="github-windows" ./test_gfx - name: Upload artifacts uses: actions/upload-artifact@v2 with: @@ -303,6 +303,7 @@ jobs: RUST_BACKTRACE: 1 shell: msys2 {0} run: | + export GFX_BACKEND=D3D12 cd build echo "Running test: gfx_window" ./shards ../src/tests/gfx_window.edn diff --git a/Cargo.lock b/Cargo.lock index e5050c8c65..2daa2bf091 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -192,9 +192,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] name = "bindgen" -version = "0.59.2" +version = "0.60.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bd2a9a458e8f4304c52c43ebb0cfbd520289f8379a52e329a38afda99bf8eb8" +checksum = "062dddbc1ba4aca46de6338e2bf87771414c335f7b2f2036e8f3e9befebf88e6" dependencies = [ "bitflags", "cexpr", @@ -432,17 +432,26 @@ dependencies = [ [[package]] name = "clap" -version = "2.34.0" +version = "3.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +checksum = "5b7b16274bb247b45177db843202209b12191b631a14a9d06e41b3777d6ecf14" dependencies = [ - "ansi_term", "atty", "bitflags", + "clap_lex", + "indexmap", "strsim", + "termcolor", "textwrap", - "unicode-width", - "vec_map", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", ] [[package]] @@ -834,6 +843,17 @@ dependencies = [ "nohash-hasher", ] +[[package]] +name = "egui-gfx" +version = "0.1.0" +dependencies = [ + "bindgen", + "egui", + "epaint", + "gfx-build", + "lazy_static", +] + [[package]] name = "either" version = "1.6.1" @@ -1156,6 +1176,13 @@ dependencies = [ "wasi 0.10.2+wasi-snapshot-preview1", ] +[[package]] +name = "gfx-build" +version = "0.1.0" +dependencies = [ + "bindgen", +] + [[package]] name = "gimli" version = "0.26.1" @@ -1911,6 +1938,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "os_str_bytes" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" + [[package]] name = "owned_ttf_parser" version = "0.15.0" @@ -2743,8 +2776,10 @@ dependencies = [ "ctor", "dlopen", "egui", + "egui-gfx", "ethabi", "ethereum-types", + "gfx-build", "half", "hex", "instant", @@ -3142,9 +3177,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "strsim" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "substrate-bip39" @@ -3249,12 +3284,9 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.11.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "thiserror" @@ -3594,12 +3626,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94" -[[package]] -name = "unicode-width" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" - [[package]] name = "unicode-xid" version = "0.1.0" @@ -3673,12 +3699,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "version_check" version = "0.9.4" diff --git a/cmake/Rust.cmake b/cmake/Rust.cmake index df27c4c685..c29bc25654 100644 --- a/cmake/Rust.cmake +++ b/cmake/Rust.cmake @@ -90,7 +90,7 @@ endmacro() # Need this custom build script to inherit the correct SDK variables from XCode if(IOS) - set(RUST_BUILD_SCRIPT "${CMAKE_SOURCE_DIR}/cmake/osx_rust_build.sh") + set(RUST_BUILD_SCRIPT "${CMAKE_SOURCE_DIR}/cmake/osx_rust_build.sh" ${XCODE_SDK}) endif() # Defines a rust target @@ -108,6 +108,7 @@ function(add_rust_library) FEATURES # (Optional) List of features to pass to rust build ENVIRONMENT # (Optional) Environment variables DEPENDS # (Optional) Extra file-level dependencies + EXCLUDE_DEPENDS # (Optional) Extra file-level dependencies to ignore ) cmake_parse_arguments(RUST "${OPTS}" "${ARGS}" "${MULTI_ARGS}" ${ARGN}) @@ -128,6 +129,9 @@ function(add_rust_library) if(RUST_TEMP_SOURCES) list(REMOVE_ITEM RUST_SOURCES ${RUST_TEMP_SOURCES}) endif() + if(RUST_EXCLUDE_DEPENDS) + list(REMOVE_ITEM RUST_SOURCES ${RUST_EXCLUDE_DEPENDS}) + endif() message(VERBOSE " RUST_SOURCES: ${RUST_SOURCES}") if(RUST_CARGO_TARGET) @@ -156,9 +160,30 @@ function(add_rust_library) set(RUST_CRATE_TYPE_ARG --crate-type staticlib) + # When the compiler can't automatically provide include paths (emscripten): + # pass the sysroot to the bindgen clang arguments + if(EMSCRIPTEN_SYSROOT) + file(TO_CMAKE_PATH "${EMSCRIPTEN_SYSROOT}" TMP_SYSROOT) + list(APPEND EXTRA_CLANG_ARGS "--sysroot=${TMP_SYSROOT}") + endif() + + if(EMSCRIPTEN) + # Required to have some symbols be exported + # https://github.com/rust-lang/rust-bindgen/issues/751 + list(APPEND EXTRA_CLANG_ARGS "-fvisibility=default") + endif() + + if(EXTRA_CLANG_ARGS) + set(BINDGEN_EXTRA_CLANG_ARGS BINDGEN_EXTRA_CLANG_ARGS="${EXTRA_CLANG_ARGS}") + endif() + + if(RUST_TARGET_PATH) + list(APPEND RUST_ENVIRONMENT "CARGO_TARGET_DIR=${RUST_TARGET_PATH}") + endif() + add_custom_command( OUTPUT ${GENERATED_LIB_PATH} - COMMAND ${CMAKE_COMMAND} -E env RUSTFLAGS="${RUST_FLAGS}" ${RUST_ENVIRONMENT} ${RUST_BUILD_SCRIPT} ${CARGO_EXE} ${RUST_CARGO_TOOLCHAIN} rustc ${RUST_CARGO_UNSTABLE_FLAGS} ${RUST_FEATURES_ARG} ${RUST_CRATE_TYPE_ARG} ${RUST_TARGET_ARG} ${RUST_CARGO_FLAGS} + COMMAND ${CMAKE_COMMAND} -E env RUSTFLAGS="${RUST_FLAGS}" ${BINDGEN_EXTRA_CLANG_ARGS} ${RUST_ENVIRONMENT} ${RUST_BUILD_SCRIPT} ${CARGO_EXE} ${RUST_CARGO_TOOLCHAIN} rustc ${RUST_CARGO_UNSTABLE_FLAGS} ${RUST_FEATURES_ARG} ${RUST_CRATE_TYPE_ARG} ${RUST_TARGET_ARG} ${RUST_CARGO_FLAGS} WORKING_DIRECTORY ${RUST_PROJECT_PATH} DEPENDS ${RUST_SOURCES} ${RUST_DEPENDS} USES_TERMINAL @@ -176,4 +201,4 @@ function(add_rust_library) set_target_properties(${RUST_TARGET_NAME} PROPERTIES IMPORTED_LOCATION ${GENERATED_LIB_PATH} ) -endfunction() \ No newline at end of file +endfunction() diff --git a/cmake/osx_rust_build.sh b/cmake/osx_rust_build.sh index c863b35b88..55ecaa1f1d 100755 --- a/cmake/osx_rust_build.sh +++ b/cmake/osx_rust_build.sh @@ -1,3 +1,14 @@ #!/bin/bash +# Script to work around some issues when calling `cargo build`/`cargo rustc` from Xcode for iOS +# +# The SDKROOT needs to be set to the HOST SDKROOT so that build scripts are able to build +# if not, it results in linker errors similar to this issue https://github.com/TimNN/cargo-lipo/issues/41 +# +# Additionally, bindgen needs to be passed the sysroot for the target platform to be able to find the system headers + set -ex -SDKROOT=`xcrun --sdk macosx --show-sdk-path` $@ \ No newline at end of file +TARGET_SDKROOT=`xcrun --sdk $1 --show-sdk-path` +shift +export SDKROOT=`xcrun --sdk macosx --show-sdk-path` +export BINDGEN_EXTRA_CLANG_ARGS="-isysroot $TARGET_SDKROOT -isystem $TARGET_SDKROOT/usr/include/c++/v1 $BINDGEN_EXTRA_CLANG_ARGS" +$@ diff --git a/rust/CMakeLists.txt b/rust/CMakeLists.txt index 698bacf45c..ed0ac0d626 100644 --- a/rust/CMakeLists.txt +++ b/rust/CMakeLists.txt @@ -1,11 +1,14 @@ -set(FEATURES shards run_bindgen) +set(FEATURES shards) if(RUST_SHLISP) list(APPEND FEATURES scripting) endif() # Bindgen dependency -list(APPEND EXTRA_SOURCES ${SHARDS_DIR}/include/shards.h) +list(APPEND EXTRA_SOURCES ${SHARDS_DIR}/src/extra/rust_interop.hpp ${SHARDS_DIR}/include/shards.h) + +# egui integration sources +file(GLOB_RECURSE EXTRA_SOURCES "${SHARDS_DIR}/src/gfx/egui/src/*.rs") if(ANDROID OR LINUX) set(NEED_OPENSSL_SYS ON) diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 58048d2e94..d75620e18d 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -36,6 +36,7 @@ parity-scale-codec = { version = "2.3.1", default-features = false, optional = t chacha20poly1305 = { version = "0.9.0", optional = true } egui = { version = "0.18.1", optional = true } half = { version = "1.8.2" } +egui-gfx = { path = "../src/gfx/egui"} [target.'cfg(not(target_arch="wasm32"))'.dependencies] dlopen = { version = "0.1.8", optional = true } @@ -48,7 +49,8 @@ webbrowser = { version = "0.5.5", optional = true } ctor = "0.1.16" [build-dependencies] -bindgen = { version = "0.59.1", optional = true } +bindgen = { version = "0.60.1" } +gfx-build = { path = "../src/gfx/rust/build" } [features] default = [] @@ -75,8 +77,7 @@ shards = ["reqwest", "chacha20poly1305", "egui"] dllshard = ["dlopen"] -run_bindgen = ["bindgen"] scripting = [] [profile.release] -panic = "abort" \ No newline at end of file +panic = "abort" diff --git a/rust/build.rs b/rust/build.rs index 0e6bbabdf8..45842ecac0 100644 --- a/rust/build.rs +++ b/rust/build.rs @@ -1,40 +1,48 @@ /* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright © 2020 Fragcolor Pte. Ltd. */ -#[cfg(feature = "run_bindgen")] extern crate bindgen; +extern crate gfx_build; +use std::env; +use std::path::PathBuf; -#[cfg(feature = "run_bindgen")] -fn bindgen_it() { +fn generate_shardsc() { use std::env::var; - let shards_dir = var("SHARDS_DIR").unwrap_or("../".to_string()); + let shards_dir = var("SHARDS_DIR").unwrap_or("..".to_string()); + let shards_include_dir = format!("{}/include", shards_dir); + let src_extra_dir = format!("{}/src/extra", shards_dir); + let gfx_path = format!("{}/src/gfx", shards_dir); - println!("cargo:rustc-link-search={}/build", shards_dir); - // Tell cargo to invalidate the built crate whenever the wrapper changes - println!("cargo:rerun-if-changed={}/include/shards.h", shards_dir); + let main_header_path = format!("{}/rust_interop.hpp", src_extra_dir); - let header_path = shards_dir + "/include/shards.h"; + // Tell cargo to regenerate the bindings whenever the headers change + println!("cargo:rerun-if-changed={}/shards.h", shards_include_dir); + println!("cargo:rerun-if-changed={}", main_header_path); - let bindings = bindgen::Builder::default() - .header(header_path) + let builder = gfx_build::setup_bindgen_for_gfx(gfx_path.as_str(), bindgen::Builder::default()); + let bindings = builder + .header(main_header_path) .clang_arg("-DSH_NO_ANON") .clang_arg("-DSH_USE_ENUMS") + .allowlist_type("SH.*") + .allowlist_var("SH.*") + .allowlist_function("SH.*") + .clang_arg(format!("-I{}", shards_include_dir)) + .clang_arg(format!("-I{}/src", shards_dir)) .derive_default(true) .use_core() .generate() .expect("Unable to generate bindings"); + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); bindings - .write_to_file("src/shardsc.rs") + .write_to_file(out_path.join("shardsc.rs")) .expect("Couldn't write bindings!"); println!("Done processing shards.h"); } -#[cfg(not(feature = "run_bindgen"))] -fn bindgen_it() {} - fn main() { - bindgen_it(); + generate_shardsc(); } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index e394908f47..b5f092b7d1 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright © 2020 Fragcolor Pte. Ltd. */ +#![cfg_attr(all(target_os = "windows", target_arch = "x86"), feature(abi_thiscall))] #![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] #![allow(non_snake_case)] diff --git a/rust/src/shard.rs b/rust/src/shard.rs index 4473218fec..325cc6a49b 100644 --- a/rust/src/shard.rs +++ b/rust/src/shard.rs @@ -4,12 +4,15 @@ use crate::core::abortWire; use crate::core::Core; use crate::shardsc::SHContext; +use crate::shardsc::SHError; use crate::shardsc::SHExposedTypesInfo; use crate::shardsc::SHInstanceData; use crate::shardsc::SHOptionalString; use crate::shardsc::SHParameterInfo; use crate::shardsc::SHParametersInfo; use crate::shardsc::SHSeq; +use crate::shardsc::SHShardComposeResult; +use crate::shardsc::SHString; use crate::shardsc::SHTable; use crate::shardsc::SHTypeInfo; use crate::shardsc::SHTypesInfo; @@ -28,9 +31,6 @@ use crate::types::Type; use crate::types::Types; use crate::types::Var; use crate::types::Wire; -use crate::SHError; -use crate::SHShardComposeResult; -use crate::SHString; use core::convert::TryInto; use core::result::Result; use core::slice; diff --git a/rust/src/shards/gui.rs b/rust/src/shards/gui.rs index 872ceaad60..4031163f2b 100644 --- a/rust/src/shards/gui.rs +++ b/rust/src/shards/gui.rs @@ -17,9 +17,9 @@ use crate::types::FRAG_CC; use crate::types::NONE_TYPES; use crate::types::SHARDS_OR_NONE_TYPES; use crate::types::{RawString, Types}; -use egui::RawInput; use egui::containers::panel::{CentralPanel, SidePanel, TopBottomPanel}; use egui::Context as EguiNativeContext; +use egui::RawInput; use egui::Ui; use std::ffi::c_void; use std::ffi::CString; @@ -421,8 +421,9 @@ impl Shard for Panels { } fn activate(&mut self, context: &Context, input: &Var) -> Result { - let gui_ctx= { - let ctx_ptr: &mut EguiNativeContext = Var::from_object_ptr_mut_ref(self.instance.get(), &EGUI_CTX_TYPE)?; + let gui_ctx = { + let ctx_ptr: &mut EguiNativeContext = + Var::from_object_ptr_mut_ref(self.instance.get(), &EGUI_CTX_TYPE)?; &*ctx_ptr }; diff --git a/rust/src/shardsc.rs b/rust/src/shardsc.rs index 84bec71e86..2dd79bbacd 100644 --- a/rust/src/shardsc.rs +++ b/rust/src/shardsc.rs @@ -1,5894 +1 @@ -/* automatically generated by rust-bindgen 0.59.2 */ - -pub const true_: u32 = 1; -pub const false_: u32 = 0; -pub const __bool_true_false_are_defined: u32 = 1; -pub const __MINGW64_VERSION_MAJOR: u32 = 10; -pub const __MINGW64_VERSION_MINOR: u32 = 0; -pub const __MINGW64_VERSION_BUGFIX: u32 = 0; -pub const __MINGW64_VERSION_RC: u32 = 0; -pub const __MINGW64_VERSION_STATE: &[u8; 6usize] = b"alpha\0"; -pub const __MINGW32_MAJOR_VERSION: u32 = 3; -pub const __MINGW32_MINOR_VERSION: u32 = 11; -pub const _M_IX86: u32 = 300; -pub const __MINGW_USE_UNDERSCORE_PREFIX: u32 = 1; -pub const __MINGW_HAVE_ANSI_C99_PRINTF: u32 = 1; -pub const __MINGW_HAVE_WIDE_C99_PRINTF: u32 = 1; -pub const __MINGW_HAVE_ANSI_C99_SCANF: u32 = 1; -pub const __MINGW_HAVE_WIDE_C99_SCANF: u32 = 1; -pub const __MINGW_SEC_WARN_STR: &[u8; 92usize] = - b"This function or variable may be unsafe, use _CRT_SECURE_NO_WARNINGS to disable deprecation\0"; -pub const __MINGW_MSVC2005_DEPREC_STR : & [u8 ; 117usize] = b"This POSIX function is deprecated beginning in Visual C++ 2005, use _CRT_NONSTDC_NO_DEPRECATE to disable deprecation\0" ; -pub const __MINGW_FORTIFY_LEVEL: u32 = 0; -pub const __MINGW_FORTIFY_VA_ARG: u32 = 0; -pub const _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES: u32 = 0; -pub const _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES_MEMORY: u32 = 0; -pub const _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES: u32 = 0; -pub const _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT: u32 = 0; -pub const _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_MEMORY: u32 = 0; -pub const __USE_CRTIMP: u32 = 1; -pub const USE___UUIDOF: u32 = 0; -pub const __CRT__NO_INLINE: u32 = 1; -pub const __MSVCRT_VERSION__: u32 = 1792; -pub const _WIN32_WINNT: u32 = 1537; -pub const MINGW_HAS_SECURE_API: u32 = 1; -pub const __STDC_SECURE_LIB__: u32 = 200411; -pub const __GOT_SECURE_LIB__: u32 = 200411; -pub const MINGW_HAS_DDK_H: u32 = 1; -pub const _CRT_PACKING: u32 = 8; -pub const _SECURECRT_FILL_BUFFER_PATTERN: u32 = 253; -pub const _ARGMAX: u32 = 100; -pub const __USE_MINGW_ANSI_STDIO: u32 = 1; -pub const INT8_MIN: i32 = -128; -pub const INT16_MIN: i32 = -32768; -pub const INT32_MIN: i32 = -2147483648; -pub const INT64_MIN: i64 = -9223372036854775808; -pub const INT8_MAX: u32 = 127; -pub const INT16_MAX: u32 = 32767; -pub const INT32_MAX: u32 = 2147483647; -pub const INT64_MAX: u64 = 9223372036854775807; -pub const UINT8_MAX: u32 = 255; -pub const UINT16_MAX: u32 = 65535; -pub const UINT32_MAX: u32 = 4294967295; -pub const UINT64_MAX: i32 = -1; -pub const INT_LEAST8_MIN: i32 = -128; -pub const INT_LEAST16_MIN: i32 = -32768; -pub const INT_LEAST32_MIN: i32 = -2147483648; -pub const INT_LEAST64_MIN: i64 = -9223372036854775808; -pub const INT_LEAST8_MAX: u32 = 127; -pub const INT_LEAST16_MAX: u32 = 32767; -pub const INT_LEAST32_MAX: u32 = 2147483647; -pub const INT_LEAST64_MAX: u64 = 9223372036854775807; -pub const UINT_LEAST8_MAX: u32 = 255; -pub const UINT_LEAST16_MAX: u32 = 65535; -pub const UINT_LEAST32_MAX: u32 = 4294967295; -pub const UINT_LEAST64_MAX: i32 = -1; -pub const INT_FAST8_MIN: i32 = -128; -pub const INT_FAST16_MIN: i32 = -32768; -pub const INT_FAST32_MIN: i32 = -2147483648; -pub const INT_FAST64_MIN: i64 = -9223372036854775808; -pub const INT_FAST8_MAX: u32 = 127; -pub const INT_FAST16_MAX: u32 = 32767; -pub const INT_FAST32_MAX: u32 = 2147483647; -pub const INT_FAST64_MAX: u64 = 9223372036854775807; -pub const UINT_FAST8_MAX: u32 = 255; -pub const UINT_FAST16_MAX: u32 = 65535; -pub const UINT_FAST32_MAX: u32 = 4294967295; -pub const UINT_FAST64_MAX: i32 = -1; -pub const INTPTR_MIN: i32 = -2147483648; -pub const INTPTR_MAX: u32 = 2147483647; -pub const UINTPTR_MAX: u32 = 4294967295; -pub const INTMAX_MIN: i64 = -9223372036854775808; -pub const INTMAX_MAX: u64 = 9223372036854775807; -pub const UINTMAX_MAX: i32 = -1; -pub const PTRDIFF_MIN: i32 = -2147483648; -pub const PTRDIFF_MAX: u32 = 2147483647; -pub const SIG_ATOMIC_MIN: i32 = -2147483648; -pub const SIG_ATOMIC_MAX: u32 = 2147483647; -pub const SIZE_MAX: u32 = 4294967295; -pub const WCHAR_MIN: u32 = 0; -pub const WCHAR_MAX: u32 = 65535; -pub const WINT_MIN: u32 = 0; -pub const WINT_MAX: u32 = 65535; -pub const SHIMAGE_FLAGS_NONE: u32 = 0; -pub const SHIMAGE_FLAGS_BGRA: u32 = 1; -pub const SHIMAGE_FLAGS_PREMULTIPLIED_ALPHA: u32 = 2; -pub const SHIMAGE_FLAGS_16BITS_INT: u32 = 4; -pub const SHIMAGE_FLAGS_32BITS_FLOAT: u32 = 8; -pub const SHVAR_FLAGS_NONE: u32 = 0; -pub const SHVAR_FLAGS_USES_OBJINFO: u32 = 1; -pub const SHVAR_FLAGS_REF_COUNTED: u32 = 2; -pub const SHVAR_FLAGS_EXTERNAL: u32 = 4; -pub const SHARDS_CURRENT_ABI: u32 = 538968321; -pub const SHARDS_CURRENT_ABI_STR: &[u8; 11usize] = b"0x20200101\0"; -pub const SH_DEBUG_MODE: u32 = 1; -pub type size_t = ::std::os::raw::c_uint; -pub type wchar_t = ::std::os::raw::c_ushort; -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct max_align_t { - pub __clang_max_align_nonce1: ::std::os::raw::c_longlong, - pub __clang_max_align_nonce2: f64, -} -#[test] -fn bindgen_test_layout_max_align_t() { - assert_eq!( - ::core::mem::size_of::(), - 24usize, - concat!("Size of: ", stringify!(max_align_t)) - ); - assert_eq!( - ::core::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(max_align_t)) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).__clang_max_align_nonce1 as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(max_align_t), - "::", - stringify!(__clang_max_align_nonce1) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).__clang_max_align_nonce2 as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(max_align_t), - "::", - stringify!(__clang_max_align_nonce2) - ) - ); -} -pub type __gnuc_va_list = __builtin_va_list; -pub type va_list = __gnuc_va_list; -extern "C" { - pub fn __debugbreak(); -} -extern "C" { - pub fn __mingw_get_crt_info() -> *const ::std::os::raw::c_char; -} -pub type ssize_t = ::std::os::raw::c_int; -pub type rsize_t = size_t; -pub type wint_t = ::std::os::raw::c_ushort; -pub type wctype_t = ::std::os::raw::c_ushort; -pub type errno_t = ::std::os::raw::c_int; -pub type __time32_t = ::std::os::raw::c_long; -pub type __time64_t = ::std::os::raw::c_longlong; -pub type time_t = __time32_t; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct threadmbcinfostruct { - _unused: [u8; 0], -} -pub type pthreadlocinfo = *mut threadlocaleinfostruct; -pub type pthreadmbcinfo = *mut threadmbcinfostruct; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct __lc_time_data { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct localeinfo_struct { - pub locinfo: pthreadlocinfo, - pub mbcinfo: pthreadmbcinfo, -} -#[test] -fn bindgen_test_layout_localeinfo_struct() { - assert_eq!( - ::core::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(localeinfo_struct)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(localeinfo_struct)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).locinfo as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(localeinfo_struct), - "::", - stringify!(locinfo) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).mbcinfo as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(localeinfo_struct), - "::", - stringify!(mbcinfo) - ) - ); -} -impl Default for localeinfo_struct { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -pub type _locale_tstruct = localeinfo_struct; -pub type _locale_t = *mut localeinfo_struct; -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct tagLC_ID { - pub wLanguage: ::std::os::raw::c_ushort, - pub wCountry: ::std::os::raw::c_ushort, - pub wCodePage: ::std::os::raw::c_ushort, -} -#[test] -fn bindgen_test_layout_tagLC_ID() { - assert_eq!( - ::core::mem::size_of::(), - 6usize, - concat!("Size of: ", stringify!(tagLC_ID)) - ); - assert_eq!( - ::core::mem::align_of::(), - 2usize, - concat!("Alignment of ", stringify!(tagLC_ID)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).wLanguage as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(tagLC_ID), - "::", - stringify!(wLanguage) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).wCountry as *const _ as usize }, - 2usize, - concat!( - "Offset of field: ", - stringify!(tagLC_ID), - "::", - stringify!(wCountry) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).wCodePage as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(tagLC_ID), - "::", - stringify!(wCodePage) - ) - ); -} -pub type LC_ID = tagLC_ID; -pub type LPLC_ID = *mut tagLC_ID; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct threadlocaleinfostruct { - pub refcount: ::std::os::raw::c_int, - pub lc_codepage: ::std::os::raw::c_uint, - pub lc_collate_cp: ::std::os::raw::c_uint, - pub lc_handle: [::std::os::raw::c_ulong; 6usize], - pub lc_id: [LC_ID; 6usize], - pub lc_category: [threadlocaleinfostruct__bindgen_ty_1; 6usize], - pub lc_clike: ::std::os::raw::c_int, - pub mb_cur_max: ::std::os::raw::c_int, - pub lconv_intl_refcount: *mut ::std::os::raw::c_int, - pub lconv_num_refcount: *mut ::std::os::raw::c_int, - pub lconv_mon_refcount: *mut ::std::os::raw::c_int, - pub lconv: *mut lconv, - pub ctype1_refcount: *mut ::std::os::raw::c_int, - pub ctype1: *mut ::std::os::raw::c_ushort, - pub pctype: *const ::std::os::raw::c_ushort, - pub pclmap: *const ::std::os::raw::c_uchar, - pub pcumap: *const ::std::os::raw::c_uchar, - pub lc_time_curr: *mut __lc_time_data, -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct threadlocaleinfostruct__bindgen_ty_1 { - pub locale: *mut ::std::os::raw::c_char, - pub wlocale: *mut wchar_t, - pub refcount: *mut ::std::os::raw::c_int, - pub wrefcount: *mut ::std::os::raw::c_int, -} -#[test] -fn bindgen_test_layout_threadlocaleinfostruct__bindgen_ty_1() { - assert_eq!( - ::core::mem::size_of::(), - 16usize, - concat!( - "Size of: ", - stringify!(threadlocaleinfostruct__bindgen_ty_1) - ) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!( - "Alignment of ", - stringify!(threadlocaleinfostruct__bindgen_ty_1) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).locale as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(threadlocaleinfostruct__bindgen_ty_1), - "::", - stringify!(locale) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).wlocale as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(threadlocaleinfostruct__bindgen_ty_1), - "::", - stringify!(wlocale) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).refcount as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(threadlocaleinfostruct__bindgen_ty_1), - "::", - stringify!(refcount) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).wrefcount as *const _ - as usize - }, - 12usize, - concat!( - "Offset of field: ", - stringify!(threadlocaleinfostruct__bindgen_ty_1), - "::", - stringify!(wrefcount) - ) - ); -} -impl Default for threadlocaleinfostruct__bindgen_ty_1 { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[test] -fn bindgen_test_layout_threadlocaleinfostruct() { - assert_eq!( - ::core::mem::size_of::(), - 216usize, - concat!("Size of: ", stringify!(threadlocaleinfostruct)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(threadlocaleinfostruct)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).refcount as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(threadlocaleinfostruct), - "::", - stringify!(refcount) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).lc_codepage as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(threadlocaleinfostruct), - "::", - stringify!(lc_codepage) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).lc_collate_cp as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(threadlocaleinfostruct), - "::", - stringify!(lc_collate_cp) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).lc_handle as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(threadlocaleinfostruct), - "::", - stringify!(lc_handle) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).lc_id as *const _ as usize }, - 36usize, - concat!( - "Offset of field: ", - stringify!(threadlocaleinfostruct), - "::", - stringify!(lc_id) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).lc_category as *const _ as usize }, - 72usize, - concat!( - "Offset of field: ", - stringify!(threadlocaleinfostruct), - "::", - stringify!(lc_category) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).lc_clike as *const _ as usize }, - 168usize, - concat!( - "Offset of field: ", - stringify!(threadlocaleinfostruct), - "::", - stringify!(lc_clike) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).mb_cur_max as *const _ as usize }, - 172usize, - concat!( - "Offset of field: ", - stringify!(threadlocaleinfostruct), - "::", - stringify!(mb_cur_max) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).lconv_intl_refcount as *const _ as usize - }, - 176usize, - concat!( - "Offset of field: ", - stringify!(threadlocaleinfostruct), - "::", - stringify!(lconv_intl_refcount) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).lconv_num_refcount as *const _ as usize - }, - 180usize, - concat!( - "Offset of field: ", - stringify!(threadlocaleinfostruct), - "::", - stringify!(lconv_num_refcount) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).lconv_mon_refcount as *const _ as usize - }, - 184usize, - concat!( - "Offset of field: ", - stringify!(threadlocaleinfostruct), - "::", - stringify!(lconv_mon_refcount) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).lconv as *const _ as usize }, - 188usize, - concat!( - "Offset of field: ", - stringify!(threadlocaleinfostruct), - "::", - stringify!(lconv) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).ctype1_refcount as *const _ as usize - }, - 192usize, - concat!( - "Offset of field: ", - stringify!(threadlocaleinfostruct), - "::", - stringify!(ctype1_refcount) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).ctype1 as *const _ as usize }, - 196usize, - concat!( - "Offset of field: ", - stringify!(threadlocaleinfostruct), - "::", - stringify!(ctype1) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).pctype as *const _ as usize }, - 200usize, - concat!( - "Offset of field: ", - stringify!(threadlocaleinfostruct), - "::", - stringify!(pctype) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).pclmap as *const _ as usize }, - 204usize, - concat!( - "Offset of field: ", - stringify!(threadlocaleinfostruct), - "::", - stringify!(pclmap) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).pcumap as *const _ as usize }, - 208usize, - concat!( - "Offset of field: ", - stringify!(threadlocaleinfostruct), - "::", - stringify!(pcumap) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).lc_time_curr as *const _ as usize - }, - 212usize, - concat!( - "Offset of field: ", - stringify!(threadlocaleinfostruct), - "::", - stringify!(lc_time_curr) - ) - ); -} -impl Default for threadlocaleinfostruct { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -pub type threadlocinfo = threadlocaleinfostruct; -pub type int_least8_t = ::std::os::raw::c_schar; -pub type uint_least8_t = ::std::os::raw::c_uchar; -pub type int_least16_t = ::std::os::raw::c_short; -pub type uint_least16_t = ::std::os::raw::c_ushort; -pub type int_least32_t = ::std::os::raw::c_int; -pub type uint_least32_t = ::std::os::raw::c_uint; -pub type int_least64_t = ::std::os::raw::c_longlong; -pub type uint_least64_t = ::std::os::raw::c_ulonglong; -pub type int_fast8_t = ::std::os::raw::c_schar; -pub type uint_fast8_t = ::std::os::raw::c_uchar; -pub type int_fast16_t = ::std::os::raw::c_short; -pub type uint_fast16_t = ::std::os::raw::c_ushort; -pub type int_fast32_t = ::std::os::raw::c_int; -pub type uint_fast32_t = ::std::os::raw::c_uint; -pub type int_fast64_t = ::std::os::raw::c_longlong; -pub type uint_fast64_t = ::std::os::raw::c_ulonglong; -pub type intmax_t = ::std::os::raw::c_longlong; -pub type uintmax_t = ::std::os::raw::c_ulonglong; -pub const SHType_None: SHType = 0; -pub const SHType_Any: SHType = 1; -pub const SHType_Enum: SHType = 2; -pub const SHType_Bool: SHType = 3; -pub const SHType_Int: SHType = 4; -pub const SHType_Int2: SHType = 5; -pub const SHType_Int3: SHType = 6; -pub const SHType_Int4: SHType = 7; -pub const SHType_Int8: SHType = 8; -pub const SHType_Int16: SHType = 9; -pub const SHType_Float: SHType = 10; -pub const SHType_Float2: SHType = 11; -pub const SHType_Float3: SHType = 12; -pub const SHType_Float4: SHType = 13; -pub const SHType_Color: SHType = 14; -pub const SHType_ShardRef: SHType = 15; -pub const SHType_EndOfBlittableTypes: SHType = 50; -pub const SHType_Bytes: SHType = 51; -pub const SHType_String: SHType = 52; -pub const SHType_Path: SHType = 53; -pub const SHType_ContextVar: SHType = 54; -pub const SHType_Image: SHType = 55; -pub const SHType_Seq: SHType = 56; -pub const SHType_Table: SHType = 57; -pub const SHType_Wire: SHType = 58; -pub const SHType_Object: SHType = 59; -pub const SHType_Array: SHType = 60; -pub const SHType_Set: SHType = 61; -pub const SHType_Audio: SHType = 62; -pub type SHType = u8; -pub const SHWireState_Continue: SHWireState = 0; -pub const SHWireState_Return: SHWireState = 1; -pub const SHWireState_Rebase: SHWireState = 2; -pub const SHWireState_Restart: SHWireState = 3; -pub const SHWireState_Stop: SHWireState = 4; -pub type SHWireState = u8; -pub const SHInlineShards_NotInline: SHInlineShards = 0; -pub const SHInlineShards_NoopShard: SHInlineShards = 1; -pub const SHInlineShards_CoreConst: SHInlineShards = 2; -pub const SHInlineShards_CoreSleep: SHInlineShards = 3; -pub const SHInlineShards_CoreInput: SHInlineShards = 4; -pub const SHInlineShards_CoreForRange: SHInlineShards = 5; -pub const SHInlineShards_CoreRepeat: SHInlineShards = 6; -pub const SHInlineShards_CoreOnce: SHInlineShards = 7; -pub const SHInlineShards_CoreGet: SHInlineShards = 8; -pub const SHInlineShards_CoreSet: SHInlineShards = 9; -pub const SHInlineShards_CoreRefRegular: SHInlineShards = 10; -pub const SHInlineShards_CoreRefTable: SHInlineShards = 11; -pub const SHInlineShards_CoreUpdate: SHInlineShards = 12; -pub const SHInlineShards_CoreSwap: SHInlineShards = 13; -pub const SHInlineShards_CorePush: SHInlineShards = 14; -pub const SHInlineShards_CoreIs: SHInlineShards = 15; -pub const SHInlineShards_CoreIsNot: SHInlineShards = 16; -pub const SHInlineShards_CoreAnd: SHInlineShards = 17; -pub const SHInlineShards_CoreOr: SHInlineShards = 18; -pub const SHInlineShards_CoreNot: SHInlineShards = 19; -pub const SHInlineShards_CoreIsMore: SHInlineShards = 20; -pub const SHInlineShards_CoreIsLess: SHInlineShards = 21; -pub const SHInlineShards_CoreIsMoreEqual: SHInlineShards = 22; -pub const SHInlineShards_CoreIsLessEqual: SHInlineShards = 23; -pub const SHInlineShards_MathAdd: SHInlineShards = 24; -pub const SHInlineShards_MathSubtract: SHInlineShards = 25; -pub const SHInlineShards_MathMultiply: SHInlineShards = 26; -pub const SHInlineShards_MathDivide: SHInlineShards = 27; -pub const SHInlineShards_MathXor: SHInlineShards = 28; -pub const SHInlineShards_MathAnd: SHInlineShards = 29; -pub const SHInlineShards_MathOr: SHInlineShards = 30; -pub const SHInlineShards_MathMod: SHInlineShards = 31; -pub const SHInlineShards_MathLShift: SHInlineShards = 32; -pub const SHInlineShards_MathRShift: SHInlineShards = 33; -pub const SHInlineShards_MathAbs: SHInlineShards = 34; -pub const SHInlineShards_MathExp: SHInlineShards = 35; -pub const SHInlineShards_MathExp2: SHInlineShards = 36; -pub const SHInlineShards_MathExpm1: SHInlineShards = 37; -pub const SHInlineShards_MathLog: SHInlineShards = 38; -pub const SHInlineShards_MathLog10: SHInlineShards = 39; -pub const SHInlineShards_MathLog2: SHInlineShards = 40; -pub const SHInlineShards_MathLog1p: SHInlineShards = 41; -pub const SHInlineShards_MathSqrt: SHInlineShards = 42; -pub const SHInlineShards_MathFastSqrt: SHInlineShards = 43; -pub const SHInlineShards_MathFastInvSqrt: SHInlineShards = 44; -pub const SHInlineShards_MathCbrt: SHInlineShards = 45; -pub const SHInlineShards_MathSin: SHInlineShards = 46; -pub const SHInlineShards_MathCos: SHInlineShards = 47; -pub const SHInlineShards_MathTan: SHInlineShards = 48; -pub const SHInlineShards_MathAsin: SHInlineShards = 49; -pub const SHInlineShards_MathAcos: SHInlineShards = 50; -pub const SHInlineShards_MathAtan: SHInlineShards = 51; -pub const SHInlineShards_MathSinh: SHInlineShards = 52; -pub const SHInlineShards_MathCosh: SHInlineShards = 53; -pub const SHInlineShards_MathTanh: SHInlineShards = 54; -pub const SHInlineShards_MathAsinh: SHInlineShards = 55; -pub const SHInlineShards_MathAcosh: SHInlineShards = 56; -pub const SHInlineShards_MathAtanh: SHInlineShards = 57; -pub const SHInlineShards_MathErf: SHInlineShards = 58; -pub const SHInlineShards_MathErfc: SHInlineShards = 59; -pub const SHInlineShards_MathTGamma: SHInlineShards = 60; -pub const SHInlineShards_MathLGamma: SHInlineShards = 61; -pub const SHInlineShards_MathCeil: SHInlineShards = 62; -pub const SHInlineShards_MathFloor: SHInlineShards = 63; -pub const SHInlineShards_MathTrunc: SHInlineShards = 64; -pub const SHInlineShards_MathRound: SHInlineShards = 65; -pub type SHInlineShards = u32; -pub type SHArray = *mut ::core::ffi::c_void; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHPayloadArray { - pub elements: *mut SHVarPayload, - pub len: u32, - pub cap: u32, -} -#[test] -fn bindgen_test_layout_SHPayloadArray() { - assert_eq!( - ::core::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(SHPayloadArray)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHPayloadArray)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).elements as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHPayloadArray), - "::", - stringify!(elements) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).len as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHPayloadArray), - "::", - stringify!(len) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).cap as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SHPayloadArray), - "::", - stringify!(cap) - ) - ); -} -impl Default for SHPayloadArray { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHSeq { - pub elements: *mut SHVar, - pub len: u32, - pub cap: u32, -} -#[test] -fn bindgen_test_layout_SHSeq() { - assert_eq!( - ::core::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(SHSeq)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHSeq)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).elements as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHSeq), - "::", - stringify!(elements) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).len as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHSeq), - "::", - stringify!(len) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).cap as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SHSeq), - "::", - stringify!(cap) - ) - ); -} -impl Default for SHSeq { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -pub type SHTableIterator = [::std::os::raw::c_char; 64usize]; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHTable { - pub opaque: *mut ::core::ffi::c_void, - pub api: *mut SHTableInterface, -} -#[test] -fn bindgen_test_layout_SHTable() { - assert_eq!( - ::core::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(SHTable)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHTable)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).opaque as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHTable), - "::", - stringify!(opaque) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).api as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHTable), - "::", - stringify!(api) - ) - ); -} -impl Default for SHTable { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -pub type SHSetIterator = [::std::os::raw::c_char; 64usize]; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHSetnterface { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHSet { - pub opaque: *mut ::core::ffi::c_void, - pub api: *mut SHSetInterface, -} -#[test] -fn bindgen_test_layout_SHSet() { - assert_eq!( - ::core::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(SHSet)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHSet)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).opaque as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHSet), - "::", - stringify!(opaque) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).api as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHSet), - "::", - stringify!(api) - ) - ); -} -impl Default for SHSet { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHWire { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHWireRefOpaque { - _unused: [u8; 0], -} -pub type SHWireRef = *mut SHWireRefOpaque; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHContext { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHMesh { - _unused: [u8; 0], -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHMeshRefOpaque { - _unused: [u8; 0], -} -pub type SHMeshRef = *mut SHMeshRefOpaque; -pub type ShardPtr = *mut Shard; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Shards { - pub elements: *mut ShardPtr, - pub len: u32, - pub cap: u32, -} -#[test] -fn bindgen_test_layout_Shards() { - assert_eq!( - ::core::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(Shards)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Shards)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).elements as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Shards), - "::", - stringify!(elements) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).len as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(Shards), - "::", - stringify!(len) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).cap as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(Shards), - "::", - stringify!(cap) - ) - ); -} -impl Default for Shards { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHTypesInfo { - pub elements: *mut SHTypeInfo, - pub len: u32, - pub cap: u32, -} -#[test] -fn bindgen_test_layout_SHTypesInfo() { - assert_eq!( - ::core::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(SHTypesInfo)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHTypesInfo)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).elements as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHTypesInfo), - "::", - stringify!(elements) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).len as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHTypesInfo), - "::", - stringify!(len) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).cap as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SHTypesInfo), - "::", - stringify!(cap) - ) - ); -} -impl Default for SHTypesInfo { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHParametersInfo { - pub elements: *mut SHParameterInfo, - pub len: u32, - pub cap: u32, -} -#[test] -fn bindgen_test_layout_SHParametersInfo() { - assert_eq!( - ::core::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(SHParametersInfo)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHParametersInfo)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).elements as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHParametersInfo), - "::", - stringify!(elements) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).len as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHParametersInfo), - "::", - stringify!(len) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).cap as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SHParametersInfo), - "::", - stringify!(cap) - ) - ); -} -impl Default for SHParametersInfo { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHExposedTypesInfo { - pub elements: *mut SHExposedTypeInfo, - pub len: u32, - pub cap: u32, -} -#[test] -fn bindgen_test_layout_SHExposedTypesInfo() { - assert_eq!( - ::core::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(SHExposedTypesInfo)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHExposedTypesInfo)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).elements as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHExposedTypesInfo), - "::", - stringify!(elements) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).len as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHExposedTypesInfo), - "::", - stringify!(len) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).cap as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SHExposedTypesInfo), - "::", - stringify!(cap) - ) - ); -} -impl Default for SHExposedTypesInfo { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -pub type SHPointer = *mut ::core::ffi::c_void; -pub type SHInt = i64; -pub type SHFloat = f64; -pub type SHBool = bool; -pub type SHEnum = i32; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHEnums { - pub elements: *mut SHEnum, - pub len: u32, - pub cap: u32, -} -#[test] -fn bindgen_test_layout_SHEnums() { - assert_eq!( - ::core::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(SHEnums)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHEnums)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).elements as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHEnums), - "::", - stringify!(elements) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).len as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHEnums), - "::", - stringify!(len) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).cap as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SHEnums), - "::", - stringify!(cap) - ) - ); -} -impl Default for SHEnums { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -pub type SHString = *const ::std::os::raw::c_char; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHStrings { - pub elements: *mut SHString, - pub len: u32, - pub cap: u32, -} -#[test] -fn bindgen_test_layout_SHStrings() { - assert_eq!( - ::core::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(SHStrings)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHStrings)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).elements as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHStrings), - "::", - stringify!(elements) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).len as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHStrings), - "::", - stringify!(len) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).cap as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SHStrings), - "::", - stringify!(cap) - ) - ); -} -impl Default for SHStrings { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct _SHOptionalString { - pub string: SHString, - pub crc: u32, -} -#[test] -fn bindgen_test_layout__SHOptionalString() { - assert_eq!( - ::core::mem::size_of::<_SHOptionalString>(), - 8usize, - concat!("Size of: ", stringify!(_SHOptionalString)) - ); - assert_eq!( - ::core::mem::align_of::<_SHOptionalString>(), - 4usize, - concat!("Alignment of ", stringify!(_SHOptionalString)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHOptionalString>())).string as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_SHOptionalString), - "::", - stringify!(string) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHOptionalString>())).crc as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(_SHOptionalString), - "::", - stringify!(crc) - ) - ); -} -impl Default for _SHOptionalString { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -pub type SHOptionalString = _SHOptionalString; -pub type SHInt2 = [i64; 2usize]; -pub type SHInt3 = [i32; 4usize]; -pub type SHInt4 = [i32; 4usize]; -pub type SHInt8 = [i16; 8usize]; -pub type SHInt16 = [i8; 16usize]; -pub type SHFloat2 = [f64; 2usize]; -pub type SHFloat3 = [f32; 4usize]; -pub type SHFloat4 = [f32; 4usize]; -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct SHColor { - pub r: u8, - pub g: u8, - pub b: u8, - pub a: u8, -} -#[test] -fn bindgen_test_layout_SHColor() { - assert_eq!( - ::core::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(SHColor)) - ); - assert_eq!( - ::core::mem::align_of::(), - 1usize, - concat!("Alignment of ", stringify!(SHColor)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).r as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHColor), - "::", - stringify!(r) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).g as *const _ as usize }, - 1usize, - concat!( - "Offset of field: ", - stringify!(SHColor), - "::", - stringify!(g) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).b as *const _ as usize }, - 2usize, - concat!( - "Offset of field: ", - stringify!(SHColor), - "::", - stringify!(b) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).a as *const _ as usize }, - 3usize, - concat!( - "Offset of field: ", - stringify!(SHColor), - "::", - stringify!(a) - ) - ); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHImage { - pub width: u16, - pub height: u16, - pub channels: u8, - pub flags: u8, - pub data: *mut u8, -} -#[test] -fn bindgen_test_layout_SHImage() { - assert_eq!( - ::core::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(SHImage)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHImage)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).width as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHImage), - "::", - stringify!(width) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).height as *const _ as usize }, - 2usize, - concat!( - "Offset of field: ", - stringify!(SHImage), - "::", - stringify!(height) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).channels as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHImage), - "::", - stringify!(channels) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).flags as *const _ as usize }, - 5usize, - concat!( - "Offset of field: ", - stringify!(SHImage), - "::", - stringify!(flags) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).data as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SHImage), - "::", - stringify!(data) - ) - ); -} -impl Default for SHImage { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHAudio { - pub sampleRate: u32, - pub nsamples: u16, - pub channels: u16, - pub samples: *mut f32, -} -#[test] -fn bindgen_test_layout_SHAudio() { - assert_eq!( - ::core::mem::size_of::(), - 12usize, - concat!("Size of: ", stringify!(SHAudio)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHAudio)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).sampleRate as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHAudio), - "::", - stringify!(sampleRate) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).nsamples as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHAudio), - "::", - stringify!(nsamples) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).channels as *const _ as usize }, - 6usize, - concat!( - "Offset of field: ", - stringify!(SHAudio), - "::", - stringify!(channels) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).samples as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SHAudio), - "::", - stringify!(samples) - ) - ); -} -impl Default for SHAudio { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -pub type SHTableGetIterator = - ::core::option::Option; -pub type SHTableNext = ::core::option::Option< - unsafe extern "C" fn( - table: SHTable, - inIter: *mut SHTableIterator, - outKey: *mut SHString, - outValue: *mut SHVar, - ) -> SHBool, ->; -pub type SHTableSize = ::core::option::Option size_t>; -pub type SHTableContains = - ::core::option::Option SHBool>; -pub type SHTableAt = - ::core::option::Option *mut SHVar>; -pub type SHTableRemove = - ::core::option::Option; -pub type SHTableClear = ::core::option::Option; -pub type SHTableFree = ::core::option::Option; -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct SHTableInterface { - pub tableGetIterator: SHTableGetIterator, - pub tableNext: SHTableNext, - pub tableSize: SHTableSize, - pub tableContains: SHTableContains, - pub tableAt: SHTableAt, - pub tableRemove: SHTableRemove, - pub tableClear: SHTableClear, - pub tableFree: SHTableFree, -} -#[test] -fn bindgen_test_layout_SHTableInterface() { - assert_eq!( - ::core::mem::size_of::(), - 32usize, - concat!("Size of: ", stringify!(SHTableInterface)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHTableInterface)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).tableGetIterator as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHTableInterface), - "::", - stringify!(tableGetIterator) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).tableNext as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHTableInterface), - "::", - stringify!(tableNext) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).tableSize as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SHTableInterface), - "::", - stringify!(tableSize) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).tableContains as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(SHTableInterface), - "::", - stringify!(tableContains) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).tableAt as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(SHTableInterface), - "::", - stringify!(tableAt) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).tableRemove as *const _ as usize }, - 20usize, - concat!( - "Offset of field: ", - stringify!(SHTableInterface), - "::", - stringify!(tableRemove) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).tableClear as *const _ as usize }, - 24usize, - concat!( - "Offset of field: ", - stringify!(SHTableInterface), - "::", - stringify!(tableClear) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).tableFree as *const _ as usize }, - 28usize, - concat!( - "Offset of field: ", - stringify!(SHTableInterface), - "::", - stringify!(tableFree) - ) - ); -} -pub type SHSetGetIterator = - ::core::option::Option; -pub type SHSetNext = ::core::option::Option< - unsafe extern "C" fn(set: SHSet, inIter: *mut SHSetIterator, outValue: *mut SHVar) -> SHBool, ->; -pub type SHSetSize = ::core::option::Option size_t>; -pub type SHSetContains = - ::core::option::Option SHBool>; -pub type SHSetInclude = - ::core::option::Option SHBool>; -pub type SHSetExclude = - ::core::option::Option SHBool>; -pub type SHSetClear = ::core::option::Option; -pub type SHSetFree = ::core::option::Option; -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct SHSetInterface { - pub setGetIterator: SHSetGetIterator, - pub setNext: SHSetNext, - pub setSize: SHSetSize, - pub setContains: SHSetContains, - pub setInclude: SHSetInclude, - pub setExclude: SHSetExclude, - pub setClear: SHSetClear, - pub setFree: SHSetFree, -} -#[test] -fn bindgen_test_layout_SHSetInterface() { - assert_eq!( - ::core::mem::size_of::(), - 32usize, - concat!("Size of: ", stringify!(SHSetInterface)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHSetInterface)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).setGetIterator as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHSetInterface), - "::", - stringify!(setGetIterator) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).setNext as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHSetInterface), - "::", - stringify!(setNext) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).setSize as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SHSetInterface), - "::", - stringify!(setSize) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).setContains as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(SHSetInterface), - "::", - stringify!(setContains) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).setInclude as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(SHSetInterface), - "::", - stringify!(setInclude) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).setExclude as *const _ as usize }, - 20usize, - concat!( - "Offset of field: ", - stringify!(SHSetInterface), - "::", - stringify!(setExclude) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).setClear as *const _ as usize }, - 24usize, - concat!( - "Offset of field: ", - stringify!(SHSetInterface), - "::", - stringify!(setClear) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).setFree as *const _ as usize }, - 28usize, - concat!( - "Offset of field: ", - stringify!(SHSetInterface), - "::", - stringify!(setFree) - ) - ); -} -#[repr(C)] -#[derive(Copy, Clone)] -pub struct SHTypeInfo { - pub basicType: SHType, - pub details: SHTypeInfo_Details, - pub fixedSize: u32, - pub innerType: SHType, - pub recursiveSelf: SHBool, -} -#[repr(C)] -#[derive(Copy, Clone)] -pub union SHTypeInfo_Details { - pub object: SHTypeInfo_Details_Object, - pub enumeration: SHTypeInfo_Details_Enum, - pub seqTypes: SHTypesInfo, - pub setTypes: SHTypesInfo, - pub table: SHTypeInfo_Details_Table, - pub contextVarTypes: SHTypesInfo, - pub path: SHTypeInfo_Details_Path, - pub integers: SHTypeInfo_Details_Integers, - pub real: SHTypeInfo_Details_Real, -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct SHTypeInfo_Details_Object { - pub vendorId: i32, - pub typeId: i32, -} -#[test] -fn bindgen_test_layout_SHTypeInfo_Details_Object() { - assert_eq!( - ::core::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(SHTypeInfo_Details_Object)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHTypeInfo_Details_Object)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).vendorId as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details_Object), - "::", - stringify!(vendorId) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).typeId as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details_Object), - "::", - stringify!(typeId) - ) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct SHTypeInfo_Details_Enum { - pub vendorId: i32, - pub typeId: i32, -} -#[test] -fn bindgen_test_layout_SHTypeInfo_Details_Enum() { - assert_eq!( - ::core::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(SHTypeInfo_Details_Enum)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHTypeInfo_Details_Enum)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).vendorId as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details_Enum), - "::", - stringify!(vendorId) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).typeId as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details_Enum), - "::", - stringify!(typeId) - ) - ); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHTypeInfo_Details_Table { - pub keys: SHStrings, - pub types: SHTypesInfo, -} -#[test] -fn bindgen_test_layout_SHTypeInfo_Details_Table() { - assert_eq!( - ::core::mem::size_of::(), - 24usize, - concat!("Size of: ", stringify!(SHTypeInfo_Details_Table)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHTypeInfo_Details_Table)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).keys as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details_Table), - "::", - stringify!(keys) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).types as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details_Table), - "::", - stringify!(types) - ) - ); -} -impl Default for SHTypeInfo_Details_Table { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHTypeInfo_Details_Path { - pub extensions: SHStrings, - pub isFile: SHBool, - pub existing: SHBool, - pub relative: SHBool, -} -#[test] -fn bindgen_test_layout_SHTypeInfo_Details_Path() { - assert_eq!( - ::core::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(SHTypeInfo_Details_Path)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHTypeInfo_Details_Path)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).extensions as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details_Path), - "::", - stringify!(extensions) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).isFile as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details_Path), - "::", - stringify!(isFile) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).existing as *const _ as usize }, - 13usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details_Path), - "::", - stringify!(existing) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).relative as *const _ as usize }, - 14usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details_Path), - "::", - stringify!(relative) - ) - ); -} -impl Default for SHTypeInfo_Details_Path { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct SHTypeInfo_Details_Integers { - pub min: i64, - pub max: i64, - pub valid: SHBool, -} -#[test] -fn bindgen_test_layout_SHTypeInfo_Details_Integers() { - assert_eq!( - ::core::mem::size_of::(), - 24usize, - concat!("Size of: ", stringify!(SHTypeInfo_Details_Integers)) - ); - assert_eq!( - ::core::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(SHTypeInfo_Details_Integers)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).min as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details_Integers), - "::", - stringify!(min) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).max as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details_Integers), - "::", - stringify!(max) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).valid as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details_Integers), - "::", - stringify!(valid) - ) - ); -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct SHTypeInfo_Details_Real { - pub min: f64, - pub max: f64, - pub valid: SHBool, -} -#[test] -fn bindgen_test_layout_SHTypeInfo_Details_Real() { - assert_eq!( - ::core::mem::size_of::(), - 24usize, - concat!("Size of: ", stringify!(SHTypeInfo_Details_Real)) - ); - assert_eq!( - ::core::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(SHTypeInfo_Details_Real)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).min as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details_Real), - "::", - stringify!(min) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).max as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details_Real), - "::", - stringify!(max) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).valid as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details_Real), - "::", - stringify!(valid) - ) - ); -} -#[test] -fn bindgen_test_layout_SHTypeInfo_Details() { - assert_eq!( - ::core::mem::size_of::(), - 24usize, - concat!("Size of: ", stringify!(SHTypeInfo_Details)) - ); - assert_eq!( - ::core::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(SHTypeInfo_Details)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).object as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details), - "::", - stringify!(object) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).enumeration as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details), - "::", - stringify!(enumeration) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).seqTypes as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details), - "::", - stringify!(seqTypes) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).setTypes as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details), - "::", - stringify!(setTypes) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).table as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details), - "::", - stringify!(table) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).contextVarTypes as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details), - "::", - stringify!(contextVarTypes) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).path as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details), - "::", - stringify!(path) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).integers as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details), - "::", - stringify!(integers) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).real as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo_Details), - "::", - stringify!(real) - ) - ); -} -impl Default for SHTypeInfo_Details { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[test] -fn bindgen_test_layout_SHTypeInfo() { - assert_eq!( - ::core::mem::size_of::(), - 40usize, - concat!("Size of: ", stringify!(SHTypeInfo)) - ); - assert_eq!( - ::core::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(SHTypeInfo)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).basicType as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo), - "::", - stringify!(basicType) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).details as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo), - "::", - stringify!(details) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).fixedSize as *const _ as usize }, - 32usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo), - "::", - stringify!(fixedSize) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).innerType as *const _ as usize }, - 36usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo), - "::", - stringify!(innerType) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).recursiveSelf as *const _ as usize }, - 37usize, - concat!( - "Offset of field: ", - stringify!(SHTypeInfo), - "::", - stringify!(recursiveSelf) - ) - ); -} -impl Default for SHTypeInfo { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -pub type SHObjectSerializer = ::core::option::Option< - unsafe extern "C" fn( - arg1: SHPointer, - outData: *mut *mut u8, - outLen: *mut size_t, - customHandle: *mut SHPointer, - ) -> SHBool, ->; -pub type SHObjectSerializerFree = - ::core::option::Option; -pub type SHObjectDeserializer = - ::core::option::Option SHPointer>; -pub type SHObjectReference = ::core::option::Option; -pub type SHObjectRelease = ::core::option::Option; -pub type SHObjectHash = ::core::option::Option u64>; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHObjectInfo { - pub name: SHString, - pub serialize: SHObjectSerializer, - pub free: SHObjectSerializerFree, - pub deserialize: SHObjectDeserializer, - pub reference: SHObjectReference, - pub release: SHObjectRelease, - pub hash: SHObjectHash, -} -#[test] -fn bindgen_test_layout_SHObjectInfo() { - assert_eq!( - ::core::mem::size_of::(), - 28usize, - concat!("Size of: ", stringify!(SHObjectInfo)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHObjectInfo)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).name as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHObjectInfo), - "::", - stringify!(name) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).serialize as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHObjectInfo), - "::", - stringify!(serialize) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).free as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SHObjectInfo), - "::", - stringify!(free) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).deserialize as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(SHObjectInfo), - "::", - stringify!(deserialize) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).reference as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(SHObjectInfo), - "::", - stringify!(reference) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).release as *const _ as usize }, - 20usize, - concat!( - "Offset of field: ", - stringify!(SHObjectInfo), - "::", - stringify!(release) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).hash as *const _ as usize }, - 24usize, - concat!( - "Offset of field: ", - stringify!(SHObjectInfo), - "::", - stringify!(hash) - ) - ); -} -impl Default for SHObjectInfo { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHEnumInfo { - pub name: SHString, - pub labels: SHStrings, - pub values: SHEnums, -} -#[test] -fn bindgen_test_layout_SHEnumInfo() { - assert_eq!( - ::core::mem::size_of::(), - 28usize, - concat!("Size of: ", stringify!(SHEnumInfo)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHEnumInfo)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).name as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHEnumInfo), - "::", - stringify!(name) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).labels as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHEnumInfo), - "::", - stringify!(labels) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).values as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(SHEnumInfo), - "::", - stringify!(values) - ) - ); -} -impl Default for SHEnumInfo { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHParameterInfo { - pub name: SHString, - pub help: SHOptionalString, - pub valueTypes: SHTypesInfo, -} -#[test] -fn bindgen_test_layout_SHParameterInfo() { - assert_eq!( - ::core::mem::size_of::(), - 24usize, - concat!("Size of: ", stringify!(SHParameterInfo)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHParameterInfo)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).name as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHParameterInfo), - "::", - stringify!(name) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).help as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHParameterInfo), - "::", - stringify!(help) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).valueTypes as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(SHParameterInfo), - "::", - stringify!(valueTypes) - ) - ); -} -impl Default for SHParameterInfo { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[repr(C)] -#[derive(Copy, Clone)] -pub struct SHExposedTypeInfo { - pub name: SHString, - pub help: SHOptionalString, - pub exposedType: SHTypeInfo, - pub isMutable: SHBool, - pub isProtected: SHBool, - pub isTableEntry: SHBool, - pub global: SHBool, - pub scope: *mut SHWire, -} -#[test] -fn bindgen_test_layout_SHExposedTypeInfo() { - assert_eq!( - ::core::mem::size_of::(), - 64usize, - concat!("Size of: ", stringify!(SHExposedTypeInfo)) - ); - assert_eq!( - ::core::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(SHExposedTypeInfo)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).name as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHExposedTypeInfo), - "::", - stringify!(name) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).help as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHExposedTypeInfo), - "::", - stringify!(help) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).exposedType as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(SHExposedTypeInfo), - "::", - stringify!(exposedType) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).isMutable as *const _ as usize }, - 56usize, - concat!( - "Offset of field: ", - stringify!(SHExposedTypeInfo), - "::", - stringify!(isMutable) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).isProtected as *const _ as usize }, - 57usize, - concat!( - "Offset of field: ", - stringify!(SHExposedTypeInfo), - "::", - stringify!(isProtected) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).isTableEntry as *const _ as usize }, - 58usize, - concat!( - "Offset of field: ", - stringify!(SHExposedTypeInfo), - "::", - stringify!(isTableEntry) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).global as *const _ as usize }, - 59usize, - concat!( - "Offset of field: ", - stringify!(SHExposedTypeInfo), - "::", - stringify!(global) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).scope as *const _ as usize }, - 60usize, - concat!( - "Offset of field: ", - stringify!(SHExposedTypeInfo), - "::", - stringify!(scope) - ) - ); -} -impl Default for SHExposedTypeInfo { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHFlow { - pub wire: *mut SHWire, -} -#[test] -fn bindgen_test_layout_SHFlow() { - assert_eq!( - ::core::mem::size_of::(), - 4usize, - concat!("Size of: ", stringify!(SHFlow)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHFlow)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).wire as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHFlow), - "::", - stringify!(wire) - ) - ); -} -impl Default for SHFlow { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[repr(C)] -#[repr(align(16))] -#[derive(Copy, Clone)] -pub struct SHVarPayload { - pub __bindgen_anon_1: SHVarPayload__bindgen_ty_1, -} -#[repr(C)] -#[repr(align(16))] -#[derive(Copy, Clone)] -pub union SHVarPayload__bindgen_ty_1 { - pub boolValue: SHBool, - pub __bindgen_anon_1: SHVarPayload__bindgen_ty_1__bindgen_ty_1, - pub intValue: SHInt, - pub int2Value: SHInt2, - pub int3Value: SHInt3, - pub int4Value: SHInt4, - pub int8Value: SHInt8, - pub int16Value: SHInt16, - pub floatValue: SHFloat, - pub float2Value: SHFloat2, - pub float3Value: SHFloat3, - pub float4Value: SHFloat4, - pub seqValue: SHSeq, - pub tableValue: SHTable, - pub setValue: SHSet, - pub __bindgen_anon_2: SHVarPayload__bindgen_ty_1__bindgen_ty_2, - pub colorValue: SHColor, - pub imageValue: SHImage, - pub audioValue: SHAudio, - pub wireValue: SHWireRef, - pub shardValue: ShardPtr, - pub __bindgen_anon_3: SHVarPayload__bindgen_ty_1__bindgen_ty_3, - pub __bindgen_anon_4: SHVarPayload__bindgen_ty_1__bindgen_ty_4, - pub arrayValue: SHPayloadArray, -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHVarPayload__bindgen_ty_1__bindgen_ty_1 { - pub objectValue: SHPointer, - pub objectVendorId: i32, - pub objectTypeId: i32, -} -#[test] -fn bindgen_test_layout_SHVarPayload__bindgen_ty_1__bindgen_ty_1() { - assert_eq!( - ::core::mem::size_of::(), - 12usize, - concat!( - "Size of: ", - stringify!(SHVarPayload__bindgen_ty_1__bindgen_ty_1) - ) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!( - "Alignment of ", - stringify!(SHVarPayload__bindgen_ty_1__bindgen_ty_1) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).objectValue as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(objectValue) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).objectVendorId - as *const _ as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(objectVendorId) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).objectTypeId as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1__bindgen_ty_1), - "::", - stringify!(objectTypeId) - ) - ); -} -impl Default for SHVarPayload__bindgen_ty_1__bindgen_ty_1 { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHVarPayload__bindgen_ty_1__bindgen_ty_2 { - pub stringValue: SHString, - pub stringLen: u32, - pub stringCapacity: u32, -} -#[test] -fn bindgen_test_layout_SHVarPayload__bindgen_ty_1__bindgen_ty_2() { - assert_eq!( - ::core::mem::size_of::(), - 12usize, - concat!( - "Size of: ", - stringify!(SHVarPayload__bindgen_ty_1__bindgen_ty_2) - ) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!( - "Alignment of ", - stringify!(SHVarPayload__bindgen_ty_1__bindgen_ty_2) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).stringValue as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1__bindgen_ty_2), - "::", - stringify!(stringValue) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).stringLen as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1__bindgen_ty_2), - "::", - stringify!(stringLen) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).stringCapacity - as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1__bindgen_ty_2), - "::", - stringify!(stringCapacity) - ) - ); -} -impl Default for SHVarPayload__bindgen_ty_1__bindgen_ty_2 { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct SHVarPayload__bindgen_ty_1__bindgen_ty_3 { - pub enumValue: SHEnum, - pub enumVendorId: i32, - pub enumTypeId: i32, -} -#[test] -fn bindgen_test_layout_SHVarPayload__bindgen_ty_1__bindgen_ty_3() { - assert_eq!( - ::core::mem::size_of::(), - 12usize, - concat!( - "Size of: ", - stringify!(SHVarPayload__bindgen_ty_1__bindgen_ty_3) - ) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!( - "Alignment of ", - stringify!(SHVarPayload__bindgen_ty_1__bindgen_ty_3) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).enumValue as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1__bindgen_ty_3), - "::", - stringify!(enumValue) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).enumVendorId as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1__bindgen_ty_3), - "::", - stringify!(enumVendorId) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).enumTypeId as *const _ - as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1__bindgen_ty_3), - "::", - stringify!(enumTypeId) - ) - ); -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHVarPayload__bindgen_ty_1__bindgen_ty_4 { - pub bytesValue: *mut u8, - pub bytesSize: u32, - pub bytesCapacity: u32, -} -#[test] -fn bindgen_test_layout_SHVarPayload__bindgen_ty_1__bindgen_ty_4() { - assert_eq!( - ::core::mem::size_of::(), - 12usize, - concat!( - "Size of: ", - stringify!(SHVarPayload__bindgen_ty_1__bindgen_ty_4) - ) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!( - "Alignment of ", - stringify!(SHVarPayload__bindgen_ty_1__bindgen_ty_4) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).bytesValue as *const _ - as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1__bindgen_ty_4), - "::", - stringify!(bytesValue) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).bytesSize as *const _ - as usize - }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1__bindgen_ty_4), - "::", - stringify!(bytesSize) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).bytesCapacity - as *const _ as usize - }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1__bindgen_ty_4), - "::", - stringify!(bytesCapacity) - ) - ); -} -impl Default for SHVarPayload__bindgen_ty_1__bindgen_ty_4 { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[test] -fn bindgen_test_layout_SHVarPayload__bindgen_ty_1() { - assert_eq!( - ::core::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(SHVarPayload__bindgen_ty_1)) - ); - assert_eq!( - ::core::mem::align_of::(), - 16usize, - concat!("Alignment of ", stringify!(SHVarPayload__bindgen_ty_1)) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).boolValue as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1), - "::", - stringify!(boolValue) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).intValue as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1), - "::", - stringify!(intValue) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).int2Value as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1), - "::", - stringify!(int2Value) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).int3Value as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1), - "::", - stringify!(int3Value) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).int4Value as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1), - "::", - stringify!(int4Value) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).int8Value as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1), - "::", - stringify!(int8Value) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).int16Value as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1), - "::", - stringify!(int16Value) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).floatValue as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1), - "::", - stringify!(floatValue) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).float2Value as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1), - "::", - stringify!(float2Value) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).float3Value as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1), - "::", - stringify!(float3Value) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).float4Value as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1), - "::", - stringify!(float4Value) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).seqValue as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1), - "::", - stringify!(seqValue) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).tableValue as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1), - "::", - stringify!(tableValue) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).setValue as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1), - "::", - stringify!(setValue) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).colorValue as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1), - "::", - stringify!(colorValue) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).imageValue as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1), - "::", - stringify!(imageValue) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).audioValue as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1), - "::", - stringify!(audioValue) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).wireValue as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1), - "::", - stringify!(wireValue) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).shardValue as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1), - "::", - stringify!(shardValue) - ) - ); - assert_eq!( - unsafe { - &(*(::core::ptr::null::())).arrayValue as *const _ as usize - }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVarPayload__bindgen_ty_1), - "::", - stringify!(arrayValue) - ) - ); -} -impl Default for SHVarPayload__bindgen_ty_1 { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[test] -fn bindgen_test_layout_SHVarPayload() { - assert_eq!( - ::core::mem::size_of::(), - 16usize, - concat!("Size of: ", stringify!(SHVarPayload)) - ); - assert_eq!( - ::core::mem::align_of::(), - 16usize, - concat!("Alignment of ", stringify!(SHVarPayload)) - ); -} -impl Default for SHVarPayload { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[repr(C)] -#[repr(align(16))] -#[derive(Copy, Clone)] -pub struct SHVar { - pub payload: SHVarPayload, - pub valueType: SHType, - pub innerType: SHType, - pub flags: u16, - pub refcount: u32, - pub objectInfo: *mut SHObjectInfo, - pub _cpu32bits_padding: u32, -} -#[test] -fn bindgen_test_layout_SHVar() { - assert_eq!( - ::core::mem::size_of::(), - 32usize, - concat!("Size of: ", stringify!(SHVar)) - ); - assert_eq!( - ::core::mem::align_of::(), - 16usize, - concat!("Alignment of ", stringify!(SHVar)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).payload as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHVar), - "::", - stringify!(payload) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).valueType as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(SHVar), - "::", - stringify!(valueType) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).innerType as *const _ as usize }, - 17usize, - concat!( - "Offset of field: ", - stringify!(SHVar), - "::", - stringify!(innerType) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).flags as *const _ as usize }, - 18usize, - concat!( - "Offset of field: ", - stringify!(SHVar), - "::", - stringify!(flags) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).refcount as *const _ as usize }, - 20usize, - concat!( - "Offset of field: ", - stringify!(SHVar), - "::", - stringify!(refcount) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).objectInfo as *const _ as usize }, - 24usize, - concat!( - "Offset of field: ", - stringify!(SHVar), - "::", - stringify!(objectInfo) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::()))._cpu32bits_padding as *const _ as usize }, - 28usize, - concat!( - "Offset of field: ", - stringify!(SHVar), - "::", - stringify!(_cpu32bits_padding) - ) - ); -} -impl Default for SHVar { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -pub const SHRunWireOutputState_Running: SHRunWireOutputState = 0; -pub const SHRunWireOutputState_Restarted: SHRunWireOutputState = 1; -pub const SHRunWireOutputState_Stopped: SHRunWireOutputState = 2; -pub const SHRunWireOutputState_Failed: SHRunWireOutputState = 3; -pub type SHRunWireOutputState = ::std::os::raw::c_uint; -#[repr(C)] -#[repr(align(16))] -#[derive(Copy, Clone)] -pub struct SHRunWireOutput { - pub output: SHVar, - pub state: SHRunWireOutputState, -} -#[test] -fn bindgen_test_layout_SHRunWireOutput() { - assert_eq!( - ::core::mem::size_of::(), - 48usize, - concat!("Size of: ", stringify!(SHRunWireOutput)) - ); - assert_eq!( - ::core::mem::align_of::(), - 16usize, - concat!("Alignment of ", stringify!(SHRunWireOutput)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).output as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHRunWireOutput), - "::", - stringify!(output) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).state as *const _ as usize }, - 32usize, - concat!( - "Offset of field: ", - stringify!(SHRunWireOutput), - "::", - stringify!(state) - ) - ); -} -impl Default for SHRunWireOutput { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[repr(C)] -#[repr(align(16))] -#[derive(Copy, Clone)] -pub struct SHComposeResult { - pub outputType: SHTypeInfo, - pub failed: SHBool, - pub __bindgen_padding_0: [u64; 0usize], - pub failureMessage: SHVar, - pub exposedInfo: SHExposedTypesInfo, - pub requiredInfo: SHExposedTypesInfo, - pub flowStopper: bool, -} -#[test] -fn bindgen_test_layout_SHComposeResult() { - assert_eq!( - ::core::mem::size_of::(), - 112usize, - concat!("Size of: ", stringify!(SHComposeResult)) - ); - assert_eq!( - ::core::mem::align_of::(), - 16usize, - concat!("Alignment of ", stringify!(SHComposeResult)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).outputType as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHComposeResult), - "::", - stringify!(outputType) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).failed as *const _ as usize }, - 40usize, - concat!( - "Offset of field: ", - stringify!(SHComposeResult), - "::", - stringify!(failed) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).failureMessage as *const _ as usize }, - 48usize, - concat!( - "Offset of field: ", - stringify!(SHComposeResult), - "::", - stringify!(failureMessage) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).exposedInfo as *const _ as usize }, - 80usize, - concat!( - "Offset of field: ", - stringify!(SHComposeResult), - "::", - stringify!(exposedInfo) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).requiredInfo as *const _ as usize }, - 92usize, - concat!( - "Offset of field: ", - stringify!(SHComposeResult), - "::", - stringify!(requiredInfo) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).flowStopper as *const _ as usize }, - 104usize, - concat!( - "Offset of field: ", - stringify!(SHComposeResult), - "::", - stringify!(flowStopper) - ) - ); -} -impl Default for SHComposeResult { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -pub type SHComposeError = ::core::option::Option< - unsafe extern "C" fn( - privateContext: *mut ::core::ffi::c_void, - errorText: SHString, - warningOnly: SHBool, - ), ->; -#[repr(C)] -#[derive(Copy, Clone)] -pub struct SHInstanceData { - pub shard: *mut Shard, - pub wire: *mut SHWire, - pub inputType: SHTypeInfo, - pub shared: SHExposedTypesInfo, - pub onWorkerThread: bool, - pub outputTypes: SHTypesInfo, - pub reportError: SHComposeError, - pub privateContext: *mut ::core::ffi::c_void, -} -#[test] -fn bindgen_test_layout_SHInstanceData() { - assert_eq!( - ::core::mem::size_of::(), - 88usize, - concat!("Size of: ", stringify!(SHInstanceData)) - ); - assert_eq!( - ::core::mem::align_of::(), - 8usize, - concat!("Alignment of ", stringify!(SHInstanceData)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).shard as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHInstanceData), - "::", - stringify!(shard) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).wire as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHInstanceData), - "::", - stringify!(wire) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).inputType as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SHInstanceData), - "::", - stringify!(inputType) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).shared as *const _ as usize }, - 48usize, - concat!( - "Offset of field: ", - stringify!(SHInstanceData), - "::", - stringify!(shared) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).onWorkerThread as *const _ as usize }, - 60usize, - concat!( - "Offset of field: ", - stringify!(SHInstanceData), - "::", - stringify!(onWorkerThread) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).outputTypes as *const _ as usize }, - 64usize, - concat!( - "Offset of field: ", - stringify!(SHInstanceData), - "::", - stringify!(outputTypes) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).reportError as *const _ as usize }, - 76usize, - concat!( - "Offset of field: ", - stringify!(SHInstanceData), - "::", - stringify!(reportError) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).privateContext as *const _ as usize }, - 80usize, - concat!( - "Offset of field: ", - stringify!(SHInstanceData), - "::", - stringify!(privateContext) - ) - ); -} -impl Default for SHInstanceData { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -pub type SHShardConstructor = ::core::option::Option *mut Shard>; -pub type SHCallback = ::core::option::Option; -pub type SHNameProc = ::core::option::Option SHString>; -pub type SHHashProc = ::core::option::Option u32>; -pub type SHHelpProc = - ::core::option::Option SHOptionalString>; -pub type SHPropertiesProc = - ::core::option::Option *const SHTable>; -pub type SHSetupProc = ::core::option::Option; -pub type SHDestroyProc = ::core::option::Option; -pub type SHInputTypesProc = - ::core::option::Option SHTypesInfo>; -pub type SHOutputTypesProc = - ::core::option::Option SHTypesInfo>; -pub type SHExposedVariablesProc = - ::core::option::Option SHExposedTypesInfo>; -pub type SHRequiredVariablesProc = - ::core::option::Option SHExposedTypesInfo>; -pub type SHParametersProc = - ::core::option::Option SHParametersInfo>; -pub type SHSetParamProc = ::core::option::Option< - unsafe extern "C" fn(arg1: *mut Shard, arg2: ::std::os::raw::c_int, arg3: *const SHVar), ->; -pub type SHGetParamProc = ::core::option::Option< - unsafe extern "C" fn(arg1: *mut Shard, arg2: ::std::os::raw::c_int) -> SHVar, ->; -pub type SHComposeProc = ::core::option::Option< - unsafe extern "C" fn(arg1: *mut Shard, data: SHInstanceData) -> SHTypeInfo, ->; -pub type SHComposedProc = ::core::option::Option< - unsafe extern "C" fn(arg1: *mut Shard, wire: *const SHWire, data: *const SHComposeResult), ->; -pub type SHActivateProc = ::core::option::Option< - unsafe extern "C" fn(arg1: *mut Shard, arg2: *mut SHContext, arg3: *const SHVar) -> SHVar, ->; -pub type SHCleanupProc = ::core::option::Option; -pub type SHWarmupProc = - ::core::option::Option; -pub type SHNextFrameProc = - ::core::option::Option; -pub type SHMutateProc = - ::core::option::Option; -pub type SHCrossoverProc = ::core::option::Option< - unsafe extern "C" fn(arg1: *mut Shard, state0: *const SHVar, state1: *const SHVar), ->; -pub type SHGetStateProc = ::core::option::Option SHVar>; -pub type SHSetStateProc = - ::core::option::Option; -pub type SHResetStateProc = ::core::option::Option; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct Shard { - pub inlineShardId: SHInlineShards, - pub owned: SHBool, - pub name: SHNameProc, - pub hash: SHHashProc, - pub help: SHHelpProc, - pub inputHelp: SHHelpProc, - pub outputHelp: SHHelpProc, - pub properties: SHPropertiesProc, - pub setup: SHSetupProc, - pub destroy: SHDestroyProc, - pub inputTypes: SHInputTypesProc, - pub outputTypes: SHOutputTypesProc, - pub exposedVariables: SHExposedVariablesProc, - pub requiredVariables: SHRequiredVariablesProc, - pub compose: SHComposeProc, - pub composed: SHComposedProc, - pub parameters: SHParametersProc, - pub setParam: SHSetParamProc, - pub getParam: SHGetParamProc, - pub warmup: SHWarmupProc, - pub activate: SHActivateProc, - pub cleanup: SHCleanupProc, - pub nextFrame: SHNextFrameProc, - pub mutate: SHMutateProc, - pub crossover: SHCrossoverProc, - pub getState: SHGetStateProc, - pub setState: SHSetStateProc, - pub resetState: SHResetStateProc, -} -#[test] -fn bindgen_test_layout_Shard() { - assert_eq!( - ::core::mem::size_of::(), - 112usize, - concat!("Size of: ", stringify!(Shard)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(Shard)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).inlineShardId as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(inlineShardId) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).owned as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(owned) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).name as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(name) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).hash as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(hash) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).help as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(help) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).inputHelp as *const _ as usize }, - 20usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(inputHelp) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).outputHelp as *const _ as usize }, - 24usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(outputHelp) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).properties as *const _ as usize }, - 28usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(properties) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).setup as *const _ as usize }, - 32usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(setup) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).destroy as *const _ as usize }, - 36usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(destroy) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).inputTypes as *const _ as usize }, - 40usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(inputTypes) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).outputTypes as *const _ as usize }, - 44usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(outputTypes) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).exposedVariables as *const _ as usize }, - 48usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(exposedVariables) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).requiredVariables as *const _ as usize }, - 52usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(requiredVariables) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).compose as *const _ as usize }, - 56usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(compose) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).composed as *const _ as usize }, - 60usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(composed) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).parameters as *const _ as usize }, - 64usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(parameters) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).setParam as *const _ as usize }, - 68usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(setParam) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).getParam as *const _ as usize }, - 72usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(getParam) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).warmup as *const _ as usize }, - 76usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(warmup) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).activate as *const _ as usize }, - 80usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(activate) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).cleanup as *const _ as usize }, - 84usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(cleanup) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).nextFrame as *const _ as usize }, - 88usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(nextFrame) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).mutate as *const _ as usize }, - 92usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(mutate) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).crossover as *const _ as usize }, - 96usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(crossover) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).getState as *const _ as usize }, - 100usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(getState) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).setState as *const _ as usize }, - 104usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(setState) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).resetState as *const _ as usize }, - 108usize, - concat!( - "Offset of field: ", - stringify!(Shard), - "::", - stringify!(resetState) - ) - ); -} -impl Default for Shard { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHWireProviderUpdate { - pub error: SHString, - pub wire: *mut SHWire, -} -#[test] -fn bindgen_test_layout_SHWireProviderUpdate() { - assert_eq!( - ::core::mem::size_of::(), - 8usize, - concat!("Size of: ", stringify!(SHWireProviderUpdate)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHWireProviderUpdate)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).error as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHWireProviderUpdate), - "::", - stringify!(error) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).wire as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHWireProviderUpdate), - "::", - stringify!(wire) - ) - ); -} -impl Default for SHWireProviderUpdate { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -pub type SHProviderReset = - ::core::option::Option; -pub type SHProviderReady = - ::core::option::Option SHBool>; -pub type SHProviderSetup = ::core::option::Option< - unsafe extern "C" fn(provider: *mut SHWireProvider, path: SHString, data: SHInstanceData), ->; -pub type SHProviderUpdated = - ::core::option::Option SHBool>; -pub type SHProviderAcquire = ::core::option::Option< - unsafe extern "C" fn(provider: *mut SHWireProvider) -> SHWireProviderUpdate, ->; -pub type SHProviderReleaseWire = - ::core::option::Option; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHWireProvider { - pub reset: SHProviderReset, - pub ready: SHProviderReady, - pub setup: SHProviderSetup, - pub updated: SHProviderUpdated, - pub acquire: SHProviderAcquire, - pub release: SHProviderReleaseWire, - pub userData: *mut ::core::ffi::c_void, -} -#[test] -fn bindgen_test_layout_SHWireProvider() { - assert_eq!( - ::core::mem::size_of::(), - 28usize, - concat!("Size of: ", stringify!(SHWireProvider)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHWireProvider)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).reset as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHWireProvider), - "::", - stringify!(reset) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).ready as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHWireProvider), - "::", - stringify!(ready) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).setup as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SHWireProvider), - "::", - stringify!(setup) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).updated as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(SHWireProvider), - "::", - stringify!(updated) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).acquire as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(SHWireProvider), - "::", - stringify!(acquire) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).release as *const _ as usize }, - 20usize, - concat!( - "Offset of field: ", - stringify!(SHWireProvider), - "::", - stringify!(release) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).userData as *const _ as usize }, - 24usize, - concat!( - "Offset of field: ", - stringify!(SHWireProvider), - "::", - stringify!(userData) - ) - ); -} -impl Default for SHWireProvider { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -pub type SHValidationCallback = ::core::option::Option< - unsafe extern "C" fn( - errorShard: *const Shard, - errorTxt: SHString, - nonfatalWarning: SHBool, - userData: *mut ::core::ffi::c_void, - ), ->; -pub type SHRegisterShard = - ::core::option::Option; -pub type SHRegisterObjectType = - ::core::option::Option; -pub type SHRegisterEnumType = - ::core::option::Option; -pub type SHRegisterRunLoopCallback = - ::core::option::Option; -pub type SHRegisterExitCallback = - ::core::option::Option; -pub type SHUnregisterRunLoopCallback = - ::core::option::Option; -pub type SHUnregisterExitCallback = - ::core::option::Option; -pub type SHReferenceVariable = ::core::option::Option< - unsafe extern "C" fn(context: *mut SHContext, name: SHString) -> *mut SHVar, ->; -pub type SHReferenceWireVariable = - ::core::option::Option *mut SHVar>; -pub type SHSetExternalVariable = - ::core::option::Option; -pub type SHRemoveExternalVariable = - ::core::option::Option; -pub type SHAllocExternalVariable = - ::core::option::Option *mut SHVar>; -pub type SHFreeExternalVariable = - ::core::option::Option; -pub type SHReleaseVariable = ::core::option::Option; -pub type SHAbortWire = - ::core::option::Option; -pub type SHSuspend = ::core::option::Option< - unsafe extern "C" fn(context: *mut SHContext, seconds: f64) -> SHWireState, ->; -pub type SHGetState = - ::core::option::Option SHWireState>; -pub type SHCloneVar = - ::core::option::Option; -pub type SHDestroyVar = ::core::option::Option; -pub type SHValidateSetParam = ::core::option::Option< - unsafe extern "C" fn( - shard: *mut Shard, - index: ::std::os::raw::c_int, - param: *const SHVar, - callback: SHValidationCallback, - userData: *mut ::core::ffi::c_void, - ) -> SHBool, ->; -pub type SHComposeShards = ::core::option::Option< - unsafe extern "C" fn( - shards: Shards, - callback: SHValidationCallback, - userData: *mut ::core::ffi::c_void, - data: SHInstanceData, - ) -> SHComposeResult, ->; -pub type SHRunShards = ::core::option::Option< - unsafe extern "C" fn( - shards: Shards, - context: *mut SHContext, - input: *const SHVar, - output: *mut SHVar, - ) -> SHWireState, ->; -pub type SHRunShardsHashed = ::core::option::Option< - unsafe extern "C" fn( - shards: Shards, - context: *mut SHContext, - input: *const SHVar, - output: *mut SHVar, - outHash: *mut SHVar, - ) -> SHWireState, ->; -pub type SHLog = ::core::option::Option; -pub type SHLogLevel = - ::core::option::Option; -pub type SHCreateShard = - ::core::option::Option *mut Shard>; -pub type SHCreateWire = ::core::option::Option SHWireRef>; -pub type SHSetWireName = - ::core::option::Option; -pub type SHSetWireLooped = - ::core::option::Option; -pub type SHSetWireUnsafe = - ::core::option::Option; -pub type SHAddShard = - ::core::option::Option; -pub type SHRemShard = - ::core::option::Option; -pub type SHDestroyWire = ::core::option::Option; -pub type SHStopWire = ::core::option::Option SHVar>; -pub type SHComposeWire = ::core::option::Option< - unsafe extern "C" fn( - wire: SHWireRef, - callback: SHValidationCallback, - userData: *mut ::core::ffi::c_void, - data: SHInstanceData, - ) -> SHComposeResult, ->; -pub type SHRunWire = ::core::option::Option< - unsafe extern "C" fn( - wire: SHWireRef, - context: *mut SHContext, - input: *const SHVar, - ) -> SHRunWireOutput, ->; -pub type SHGetGlobalWire = - ::core::option::Option SHWireRef>; -pub type SHSetGlobalWire = - ::core::option::Option; -pub type SHUnsetGlobalWire = ::core::option::Option; -pub type SHCreateMesh = ::core::option::Option SHMeshRef>; -pub type SHDestroyMesh = ::core::option::Option; -pub type SHSchedule = - ::core::option::Option; -pub type SHTick = ::core::option::Option SHBool>; -pub type SHSleep = ::core::option::Option; -pub type SHSeqFree = ::core::option::Option; -pub type SHSeqPush = - ::core::option::Option; -pub type SHSeqInsert = - ::core::option::Option; -pub type SHSeqPop = ::core::option::Option SHVar>; -pub type SHSeqResize = ::core::option::Option; -pub type SHSeqFastDelete = - ::core::option::Option; -pub type SHSeqSlowDelete = - ::core::option::Option; -pub type SHTypesInfoFree = ::core::option::Option; -pub type SHTypesInfoPush = - ::core::option::Option; -pub type SHTypesInfoInsert = ::core::option::Option< - unsafe extern "C" fn(arg1: *mut SHTypesInfo, arg2: u32, arg3: *const SHTypeInfo), ->; -pub type SHTypesInfoPop = - ::core::option::Option SHTypeInfo>; -pub type SHTypesInfoResize = - ::core::option::Option; -pub type SHTypesInfoFastDelete = - ::core::option::Option; -pub type SHTypesInfoSlowDelete = - ::core::option::Option; -pub type SHParametersInfoFree = - ::core::option::Option; -pub type SHParametersInfoPush = ::core::option::Option< - unsafe extern "C" fn(arg1: *mut SHParametersInfo, arg2: *const SHParameterInfo), ->; -pub type SHParametersInfoInsert = ::core::option::Option< - unsafe extern "C" fn(arg1: *mut SHParametersInfo, arg2: u32, arg3: *const SHParameterInfo), ->; -pub type SHParametersInfoPop = - ::core::option::Option SHParameterInfo>; -pub type SHParametersInfoResize = - ::core::option::Option; -pub type SHParametersInfoFastDelete = - ::core::option::Option; -pub type SHParametersInfoSlowDelete = - ::core::option::Option; -pub type ShardsFree = ::core::option::Option; -pub type ShardsPush = - ::core::option::Option; -pub type ShardsInsert = ::core::option::Option< - unsafe extern "C" fn(arg1: *mut Shards, arg2: u32, arg3: *const ShardPtr), ->; -pub type ShardsPop = ::core::option::Option ShardPtr>; -pub type ShardsResize = - ::core::option::Option; -pub type ShardsFastDelete = - ::core::option::Option; -pub type ShardsSlowDelete = - ::core::option::Option; -pub type SHExposedTypesInfoFree = - ::core::option::Option; -pub type SHExposedTypesInfoPush = ::core::option::Option< - unsafe extern "C" fn(arg1: *mut SHExposedTypesInfo, arg2: *const SHExposedTypeInfo), ->; -pub type SHExposedTypesInfoInsert = ::core::option::Option< - unsafe extern "C" fn(arg1: *mut SHExposedTypesInfo, arg2: u32, arg3: *const SHExposedTypeInfo), ->; -pub type SHExposedTypesInfoPop = - ::core::option::Option SHExposedTypeInfo>; -pub type SHExposedTypesInfoResize = - ::core::option::Option; -pub type SHExposedTypesInfoFastDelete = - ::core::option::Option; -pub type SHExposedTypesInfoSlowDelete = - ::core::option::Option; -pub type SHEnumsFree = ::core::option::Option; -pub type SHEnumsPush = - ::core::option::Option; -pub type SHEnumsInsert = - ::core::option::Option; -pub type SHEnumsPop = ::core::option::Option SHEnum>; -pub type SHEnumsResize = - ::core::option::Option; -pub type SHEnumsFastDelete = - ::core::option::Option; -pub type SHEnumsSlowDelete = - ::core::option::Option; -pub type SHStringsFree = ::core::option::Option; -pub type SHStringsPush = - ::core::option::Option; -pub type SHStringsInsert = ::core::option::Option< - unsafe extern "C" fn(arg1: *mut SHStrings, arg2: u32, arg3: *const SHString), ->; -pub type SHStringsPop = - ::core::option::Option SHString>; -pub type SHStringsResize = - ::core::option::Option; -pub type SHStringsFastDelete = - ::core::option::Option; -pub type SHStringsSlowDelete = - ::core::option::Option; -pub type SHTableNew = ::core::option::Option SHTable>; -pub type SHSetNew = ::core::option::Option SHSet>; -pub type SHGetRootPath = ::core::option::Option SHString>; -pub type SHSetRootPath = ::core::option::Option; -pub type SHAsyncActivateProc = ::core::option::Option< - unsafe extern "C" fn(context: *mut SHContext, userData: *mut ::core::ffi::c_void) -> SHVar, ->; -pub type SHAsyncCancelProc = ::core::option::Option< - unsafe extern "C" fn(context: *mut SHContext, userData: *mut ::core::ffi::c_void), ->; -pub type SHRunAsyncActivate = ::core::option::Option< - unsafe extern "C" fn( - context: *mut SHContext, - userData: *mut ::core::ffi::c_void, - call: SHAsyncActivateProc, - cancel_call: SHAsyncCancelProc, - ) -> SHVar, ->; -pub type SHGetShards = ::core::option::Option SHStrings>; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct SHWireInfo { - pub name: SHString, - pub looped: SHBool, - pub unsafe_: SHBool, - pub wire: *const SHWire, - pub shards: Shards, - pub isRunning: SHBool, - pub failed: SHBool, - pub failureMessage: SHString, - pub finalOutput: *mut SHVar, -} -#[test] -fn bindgen_test_layout_SHWireInfo() { - assert_eq!( - ::core::mem::size_of::(), - 36usize, - concat!("Size of: ", stringify!(SHWireInfo)) - ); - assert_eq!( - ::core::mem::align_of::(), - 4usize, - concat!("Alignment of ", stringify!(SHWireInfo)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).name as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(SHWireInfo), - "::", - stringify!(name) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).looped as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(SHWireInfo), - "::", - stringify!(looped) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).unsafe_ as *const _ as usize }, - 5usize, - concat!( - "Offset of field: ", - stringify!(SHWireInfo), - "::", - stringify!(unsafe_) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).wire as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(SHWireInfo), - "::", - stringify!(wire) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).shards as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(SHWireInfo), - "::", - stringify!(shards) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).isRunning as *const _ as usize }, - 24usize, - concat!( - "Offset of field: ", - stringify!(SHWireInfo), - "::", - stringify!(isRunning) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).failed as *const _ as usize }, - 25usize, - concat!( - "Offset of field: ", - stringify!(SHWireInfo), - "::", - stringify!(failed) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).failureMessage as *const _ as usize }, - 28usize, - concat!( - "Offset of field: ", - stringify!(SHWireInfo), - "::", - stringify!(failureMessage) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::())).finalOutput as *const _ as usize }, - 32usize, - concat!( - "Offset of field: ", - stringify!(SHWireInfo), - "::", - stringify!(finalOutput) - ) - ); -} -impl Default for SHWireInfo { - fn default() -> Self { - let mut s = ::core::mem::MaybeUninit::::uninit(); - unsafe { - ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } -} -pub type SHGetWireInfo = - ::core::option::Option SHWireInfo>; -pub type SHReadCachedString = - ::core::option::Option SHOptionalString>; -pub type SHWriteCachedString = ::core::option::Option< - unsafe extern "C" fn(id: u32, str_: *const ::std::os::raw::c_char) -> SHOptionalString, ->; -pub type SHIsEqualVar = - ::core::option::Option SHBool>; -pub type SHIsEqualType = ::core::option::Option< - unsafe extern "C" fn(t1: *const SHTypeInfo, t2: *const SHTypeInfo) -> SHBool, ->; -pub type SHDeriveTypeInfo = ::core::option::Option< - unsafe extern "C" fn(v: *const SHVar, data: *const SHInstanceData) -> SHTypeInfo, ->; -pub type SHFreeDerivedTypeInfo = ::core::option::Option; -pub type SHAlloc = - ::core::option::Option *mut ::core::ffi::c_void>; -pub type SHFree = ::core::option::Option; -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct _SHCore { - pub alloc: SHAlloc, - pub free: SHFree, - pub tableNew: SHTableNew, - pub setNew: SHSetNew, - pub composeShards: SHComposeShards, - pub runShards: SHRunShards, - pub runShards2: SHRunShards, - pub runShardsHashed: SHRunShardsHashed, - pub runShardsHashed2: SHRunShardsHashed, - pub log: SHLog, - pub logLevel: SHLogLevel, - pub createShard: SHCreateShard, - pub validateSetParam: SHValidateSetParam, - pub createWire: SHCreateWire, - pub setWireName: SHSetWireName, - pub setWireLooped: SHSetWireLooped, - pub setWireUnsafe: SHSetWireUnsafe, - pub addShard: SHAddShard, - pub removeShard: SHRemShard, - pub destroyWire: SHDestroyWire, - pub stopWire: SHStopWire, - pub composeWire: SHComposeWire, - pub runWire: SHRunWire, - pub getWireInfo: SHGetWireInfo, - pub getGlobalWire: SHGetGlobalWire, - pub setGlobalWire: SHSetGlobalWire, - pub unsetGlobalWire: SHUnsetGlobalWire, - pub createMesh: SHCreateMesh, - pub destroyMesh: SHDestroyMesh, - pub schedule: SHSchedule, - pub unschedule: SHSchedule, - pub tick: SHTick, - pub sleep: SHSleep, - pub getRootPath: SHGetRootPath, - pub setRootPath: SHSetRootPath, - pub asyncActivate: SHRunAsyncActivate, - pub getShards: SHGetShards, - pub registerShard: SHRegisterShard, - pub registerObjectType: SHRegisterObjectType, - pub registerEnumType: SHRegisterEnumType, - pub registerRunLoopCallback: SHRegisterRunLoopCallback, - pub unregisterRunLoopCallback: SHUnregisterRunLoopCallback, - pub registerExitCallback: SHRegisterExitCallback, - pub unregisterExitCallback: SHUnregisterExitCallback, - pub referenceVariable: SHReferenceVariable, - pub referenceWireVariable: SHReferenceWireVariable, - pub releaseVariable: SHReleaseVariable, - pub setExternalVariable: SHSetExternalVariable, - pub removeExternalVariable: SHRemoveExternalVariable, - pub allocExternalVariable: SHAllocExternalVariable, - pub freeExternalVariable: SHFreeExternalVariable, - pub suspend: SHSuspend, - pub getState: SHGetState, - pub abortWire: SHAbortWire, - pub cloneVar: SHCloneVar, - pub destroyVar: SHDestroyVar, - pub readCachedString: SHReadCachedString, - pub writeCachedString: SHWriteCachedString, - pub isEqualVar: SHIsEqualVar, - pub isEqualType: SHIsEqualType, - pub deriveTypeInfo: SHDeriveTypeInfo, - pub freeDerivedTypeInfo: SHFreeDerivedTypeInfo, - pub seqFree: SHSeqFree, - pub seqPush: SHSeqPush, - pub seqInsert: SHSeqInsert, - pub seqPop: SHSeqPop, - pub seqResize: SHSeqResize, - pub seqFastDelete: SHSeqFastDelete, - pub seqSlowDelete: SHSeqSlowDelete, - pub typesFree: SHTypesInfoFree, - pub typesPush: SHTypesInfoPush, - pub typesInsert: SHTypesInfoInsert, - pub typesPop: SHTypesInfoPop, - pub typesResize: SHTypesInfoResize, - pub typesFastDelete: SHTypesInfoFastDelete, - pub typesSlowDelete: SHTypesInfoSlowDelete, - pub paramsFree: SHParametersInfoFree, - pub paramsPush: SHParametersInfoPush, - pub paramsInsert: SHParametersInfoInsert, - pub paramsPop: SHParametersInfoPop, - pub paramsResize: SHParametersInfoResize, - pub paramsFastDelete: SHParametersInfoFastDelete, - pub paramsSlowDelete: SHParametersInfoSlowDelete, - pub shardsFree: ShardsFree, - pub shardsPush: ShardsPush, - pub shardsInsert: ShardsInsert, - pub shardsPop: ShardsPop, - pub shardsResize: ShardsResize, - pub shardsFastDelete: ShardsFastDelete, - pub shardsSlowDelete: ShardsSlowDelete, - pub expTypesFree: SHExposedTypesInfoFree, - pub expTypesPush: SHExposedTypesInfoPush, - pub expTypesInsert: SHExposedTypesInfoInsert, - pub expTypesPop: SHExposedTypesInfoPop, - pub expTypesResize: SHExposedTypesInfoResize, - pub expTypesFastDelete: SHExposedTypesInfoFastDelete, - pub expTypesSlowDelete: SHExposedTypesInfoSlowDelete, - pub enumsFree: SHEnumsFree, - pub enumsPush: SHEnumsPush, - pub enumsInsert: SHEnumsInsert, - pub enumsPop: SHEnumsPop, - pub enumsResize: SHEnumsResize, - pub enumsFastDelete: SHEnumsFastDelete, - pub enumsSlowDelete: SHEnumsSlowDelete, - pub stringsFree: SHStringsFree, - pub stringsPush: SHStringsPush, - pub stringsInsert: SHStringsInsert, - pub stringsPop: SHStringsPop, - pub stringsResize: SHStringsResize, - pub stringsFastDelete: SHStringsFastDelete, - pub stringsSlowDelete: SHStringsSlowDelete, -} -#[test] -fn bindgen_test_layout__SHCore() { - assert_eq!( - ::core::mem::size_of::<_SHCore>(), - 444usize, - concat!("Size of: ", stringify!(_SHCore)) - ); - assert_eq!( - ::core::mem::align_of::<_SHCore>(), - 4usize, - concat!("Alignment of ", stringify!(_SHCore)) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).alloc as *const _ as usize }, - 0usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(alloc) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).free as *const _ as usize }, - 4usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(free) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).tableNew as *const _ as usize }, - 8usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(tableNew) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).setNew as *const _ as usize }, - 12usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(setNew) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).composeShards as *const _ as usize }, - 16usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(composeShards) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).runShards as *const _ as usize }, - 20usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(runShards) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).runShards2 as *const _ as usize }, - 24usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(runShards2) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).runShardsHashed as *const _ as usize }, - 28usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(runShardsHashed) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).runShardsHashed2 as *const _ as usize }, - 32usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(runShardsHashed2) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).log as *const _ as usize }, - 36usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(log) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).logLevel as *const _ as usize }, - 40usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(logLevel) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).createShard as *const _ as usize }, - 44usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(createShard) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).validateSetParam as *const _ as usize }, - 48usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(validateSetParam) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).createWire as *const _ as usize }, - 52usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(createWire) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).setWireName as *const _ as usize }, - 56usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(setWireName) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).setWireLooped as *const _ as usize }, - 60usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(setWireLooped) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).setWireUnsafe as *const _ as usize }, - 64usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(setWireUnsafe) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).addShard as *const _ as usize }, - 68usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(addShard) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).removeShard as *const _ as usize }, - 72usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(removeShard) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).destroyWire as *const _ as usize }, - 76usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(destroyWire) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).stopWire as *const _ as usize }, - 80usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(stopWire) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).composeWire as *const _ as usize }, - 84usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(composeWire) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).runWire as *const _ as usize }, - 88usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(runWire) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).getWireInfo as *const _ as usize }, - 92usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(getWireInfo) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).getGlobalWire as *const _ as usize }, - 96usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(getGlobalWire) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).setGlobalWire as *const _ as usize }, - 100usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(setGlobalWire) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).unsetGlobalWire as *const _ as usize }, - 104usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(unsetGlobalWire) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).createMesh as *const _ as usize }, - 108usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(createSHMesh) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).destroyMesh as *const _ as usize }, - 112usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(destroySHMesh) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).schedule as *const _ as usize }, - 116usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(schedule) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).unschedule as *const _ as usize }, - 120usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(unschedule) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).tick as *const _ as usize }, - 124usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(tick) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).sleep as *const _ as usize }, - 128usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(sleep) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).getRootPath as *const _ as usize }, - 132usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(getRootPath) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).setRootPath as *const _ as usize }, - 136usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(setRootPath) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).asyncActivate as *const _ as usize }, - 140usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(asyncActivate) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).getShards as *const _ as usize }, - 144usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(getShards) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).registerShard as *const _ as usize }, - 148usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(registerShard) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).registerObjectType as *const _ as usize }, - 152usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(registerObjectType) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).registerEnumType as *const _ as usize }, - 156usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(registerEnumType) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).registerRunLoopCallback as *const _ as usize }, - 160usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(registerRunLoopCallback) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).unregisterRunLoopCallback as *const _ as usize }, - 164usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(unregisterRunLoopCallback) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).registerExitCallback as *const _ as usize }, - 168usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(registerExitCallback) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).unregisterExitCallback as *const _ as usize }, - 172usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(unregisterExitCallback) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).referenceVariable as *const _ as usize }, - 176usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(referenceVariable) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).referenceWireVariable as *const _ as usize }, - 180usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(referenceWireVariable) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).releaseVariable as *const _ as usize }, - 184usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(releaseVariable) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).setExternalVariable as *const _ as usize }, - 188usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(setExternalVariable) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).removeExternalVariable as *const _ as usize }, - 192usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(removeExternalVariable) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).allocExternalVariable as *const _ as usize }, - 196usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(allocExternalVariable) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).freeExternalVariable as *const _ as usize }, - 200usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(freeExternalVariable) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).suspend as *const _ as usize }, - 204usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(suspend) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).getState as *const _ as usize }, - 208usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(getState) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).abortWire as *const _ as usize }, - 212usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(abortWire) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).cloneVar as *const _ as usize }, - 216usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(cloneVar) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).destroyVar as *const _ as usize }, - 220usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(destroyVar) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).readCachedString as *const _ as usize }, - 224usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(readCachedString) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).writeCachedString as *const _ as usize }, - 228usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(writeCachedString) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).isEqualVar as *const _ as usize }, - 232usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(isEqualVar) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).isEqualType as *const _ as usize }, - 236usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(isEqualType) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).deriveTypeInfo as *const _ as usize }, - 240usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(deriveTypeInfo) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).freeDerivedTypeInfo as *const _ as usize }, - 244usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(freeDerivedTypeInfo) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).seqFree as *const _ as usize }, - 248usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(seqFree) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).seqPush as *const _ as usize }, - 252usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(seqPush) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).seqInsert as *const _ as usize }, - 256usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(seqInsert) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).seqPop as *const _ as usize }, - 260usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(seqPop) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).seqResize as *const _ as usize }, - 264usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(seqResize) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).seqFastDelete as *const _ as usize }, - 268usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(seqFastDelete) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).seqSlowDelete as *const _ as usize }, - 272usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(seqSlowDelete) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).typesFree as *const _ as usize }, - 276usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(typesFree) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).typesPush as *const _ as usize }, - 280usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(typesPush) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).typesInsert as *const _ as usize }, - 284usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(typesInsert) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).typesPop as *const _ as usize }, - 288usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(typesPop) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).typesResize as *const _ as usize }, - 292usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(typesResize) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).typesFastDelete as *const _ as usize }, - 296usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(typesFastDelete) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).typesSlowDelete as *const _ as usize }, - 300usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(typesSlowDelete) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).paramsFree as *const _ as usize }, - 304usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(paramsFree) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).paramsPush as *const _ as usize }, - 308usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(paramsPush) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).paramsInsert as *const _ as usize }, - 312usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(paramsInsert) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).paramsPop as *const _ as usize }, - 316usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(paramsPop) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).paramsResize as *const _ as usize }, - 320usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(paramsResize) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).paramsFastDelete as *const _ as usize }, - 324usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(paramsFastDelete) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).paramsSlowDelete as *const _ as usize }, - 328usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(paramsSlowDelete) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).shardsFree as *const _ as usize }, - 332usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(shardsFree) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).shardsPush as *const _ as usize }, - 336usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(shardsPush) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).shardsInsert as *const _ as usize }, - 340usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(shardsInsert) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).shardsPop as *const _ as usize }, - 344usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(shardsPop) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).shardsResize as *const _ as usize }, - 348usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(shardsResize) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).shardsFastDelete as *const _ as usize }, - 352usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(shardsFastDelete) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).shardsSlowDelete as *const _ as usize }, - 356usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(shardsSlowDelete) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).expTypesFree as *const _ as usize }, - 360usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(expTypesFree) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).expTypesPush as *const _ as usize }, - 364usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(expTypesPush) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).expTypesInsert as *const _ as usize }, - 368usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(expTypesInsert) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).expTypesPop as *const _ as usize }, - 372usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(expTypesPop) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).expTypesResize as *const _ as usize }, - 376usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(expTypesResize) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).expTypesFastDelete as *const _ as usize }, - 380usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(expTypesFastDelete) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).expTypesSlowDelete as *const _ as usize }, - 384usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(expTypesSlowDelete) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).enumsFree as *const _ as usize }, - 388usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(enumsFree) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).enumsPush as *const _ as usize }, - 392usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(enumsPush) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).enumsInsert as *const _ as usize }, - 396usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(enumsInsert) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).enumsPop as *const _ as usize }, - 400usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(enumsPop) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).enumsResize as *const _ as usize }, - 404usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(enumsResize) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).enumsFastDelete as *const _ as usize }, - 408usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(enumsFastDelete) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).enumsSlowDelete as *const _ as usize }, - 412usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(enumsSlowDelete) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).stringsFree as *const _ as usize }, - 416usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(stringsFree) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).stringsPush as *const _ as usize }, - 420usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(stringsPush) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).stringsInsert as *const _ as usize }, - 424usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(stringsInsert) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).stringsPop as *const _ as usize }, - 428usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(stringsPop) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).stringsResize as *const _ as usize }, - 432usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(stringsResize) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).stringsFastDelete as *const _ as usize }, - 436usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(stringsFastDelete) - ) - ); - assert_eq!( - unsafe { &(*(::core::ptr::null::<_SHCore>())).stringsSlowDelete as *const _ as usize }, - 440usize, - concat!( - "Offset of field: ", - stringify!(_SHCore), - "::", - stringify!(stringsSlowDelete) - ) - ); -} -pub type SHCore = _SHCore; -pub type SHShardsInterface = - ::core::option::Option *mut SHCore>; -extern "C" { - pub fn shardsInterface(abi_version: u32) -> *mut SHCore; -} -pub type __builtin_va_list = *mut ::std::os::raw::c_char; -#[repr(C)] -#[derive(Debug, Default, Copy, Clone)] -pub struct lconv { - pub _address: u8, -} +include!(concat!(env!("OUT_DIR"), "/shardsc.rs")); diff --git a/rust/src/types.rs b/rust/src/types.rs index ce47adacdd..7a726ceb1d 100644 --- a/rust/src/types.rs +++ b/rust/src/types.rs @@ -2871,8 +2871,8 @@ impl ShardsVar { } self.shards.clear(); - // clear old results if any - if let Some(compose_result) = self.compose_result { + // clear old results if any + if let Some(compose_result) = self.compose_result { unsafe { (*Core).expTypesFree.unwrap()(&compose_result.exposedInfo as *const _ as *mut _); (*Core).expTypesFree.unwrap()(&compose_result.requiredInfo as *const _ as *mut _); diff --git a/src/extra/CMakeLists.txt b/src/extra/CMakeLists.txt index 898f747092..acb5bc3f37 100644 --- a/src/extra/CMakeLists.txt +++ b/src/extra/CMakeLists.txt @@ -9,6 +9,8 @@ set(extra_SOURCES gfx/shader/translator.cpp gfx/shader/wgsl.cpp gfx/gltf.cpp + gui.cpp + rust_interop.cpp imgui.cpp # xr.cpp # gizmo.cpp @@ -41,7 +43,7 @@ endif() target_link_libraries(shards-extra shards-core - stb gfx gfx_imgui gfx_gltf + stb gfx gfx_imgui gfx_gltf gfx_egui brotlienc-static brotlidec-static brotlicommon-static snappy kissfft miniaudio nlohmann_json diff --git a/src/extra/gfx.cpp b/src/extra/gfx.cpp index cae3b084c3..29b031b8bf 100644 --- a/src/extra/gfx.cpp +++ b/src/extra/gfx.cpp @@ -285,7 +285,7 @@ struct RenderShard : public BaseConsumer { using T = std::decay_t; if constexpr (std::is_same_v) { if (!arg.drawQueue) - arg.drawQueue = getMainWindowGlobals().drawQueue; + arg.drawQueue = getMainWindowGlobals().getDrawQueue(); } }, step); diff --git a/src/extra/gfx.hpp b/src/extra/gfx.hpp index 3c726b1677..07a1f742bc 100644 --- a/src/extra/gfx.hpp +++ b/src/extra/gfx.hpp @@ -25,7 +25,9 @@ struct MainWindowGlobals { std::vector events; // Draw queue used when it's not manually specified - ::gfx::DrawQueuePtr drawQueue; + SHDrawQueue shDrawQueue; + + ::gfx::DrawQueuePtr getDrawQueue() { return shDrawQueue.queue; } }; struct ContextUserData { diff --git a/src/extra/gfx/drawable.cpp b/src/extra/gfx/drawable.cpp index 611df2d2e1..a1ae8f0f8c 100644 --- a/src/extra/gfx/drawable.cpp +++ b/src/extra/gfx/drawable.cpp @@ -251,7 +251,7 @@ struct DrawShard : public BaseConsumer { if (queueVar.payload.objectValue) { return *(reinterpret_cast(queueVar.payload.objectValue))->queue.get(); } else { - return *getMainWindowGlobals().drawQueue.get(); + return *getMainWindowGlobals().getDrawQueue().get(); } } diff --git a/src/extra/gfx/main_window.cpp b/src/extra/gfx/main_window.cpp index e68471ae6e..d9e59ebd4b 100644 --- a/src/extra/gfx/main_window.cpp +++ b/src/extra/gfx/main_window.cpp @@ -141,10 +141,13 @@ struct MainWindow : public Base { globals->renderer = std::make_shared(*globals->context.get()); globals->imgui = std::make_shared(*globals->context.get()); - globals->drawQueue = std::make_shared(); + globals->shDrawQueue = SHDrawQueue{ + .queue = std::make_shared(), + }; _mainWindowGlobalsVar = referenceVariable(context, Base::mainWindowGlobalsVarName); - _mainWindowGlobalsVar->payload.objectTypeId = MainWindowGlobals::TypeId; + _mainWindowGlobalsVar->payload.objectTypeId = SHTypeInfo(MainWindowGlobals::Type).object.typeId; + _mainWindowGlobalsVar->payload.objectVendorId = SHTypeInfo(MainWindowGlobals::Type).object.vendorId; _mainWindowGlobalsVar->payload.objectValue = globals.get(); _mainWindowGlobalsVar->valueType = SHType::Object; @@ -168,7 +171,7 @@ struct MainWindow : public Base { } } - void frameBegan() { globals->drawQueue->clear(); } + void frameBegan() { globals->getDrawQueue()->clear(); } SHVar activate(SHContext *shContext, const SHVar &input) { auto &renderer = globals->renderer; diff --git a/src/extra/gui.cpp b/src/extra/gui.cpp new file mode 100644 index 0000000000..8baf0210d7 --- /dev/null +++ b/src/extra/gui.cpp @@ -0,0 +1,52 @@ +#include "gfx/shards_types.hpp" +#include +#include +#include +#include +#include "gfx/egui/egui_render_pass.hpp" + +using namespace gfx; + +namespace shards { +namespace Gui { +using gfx::Types; + +struct UIPassShard { + + static SHTypesInfo inputTypes() { return CoreInfo::NoneType; } + static SHTypesInfo outputTypes() { return Types::PipelineStep; } + + PARAM_PARAMVAR(_queue, "Queue", "The queue to draw from (Optional). Uses the default queue if not specified", + {CoreInfo::NoneType, Type::VariableOf(Types::DrawQueue)}); + PARAM_IMPL(UIPassShard, PARAM_IMPL_FOR(_queue)); + + PipelineStepPtr *_step{}; + + void cleanup() { + if (_step) { + Types::PipelineStepObjectVar.Release(_step); + _step = nullptr; + } + PARAM_CLEANUP(); + } + + void warmup(SHContext *context) { + _step = Types::PipelineStepObjectVar.New(); + PARAM_WARMUP(context); + } + + SHVar activate(SHContext *context, const SHVar &input) { + Var queueVar(_queue.get()); + if (queueVar.isNone()) + throw ActivationError("Queue is required"); + + SHDrawQueue *shDrawQueue = (reinterpret_cast(queueVar.payload.objectValue)); + + *_step = EguiRenderPass::createPipelineStep(shDrawQueue->queue); + return Types::PipelineStepObjectVar.Get(_step); + } +}; + +void registerShards() { REGISTER_SHARD("GFX.UIPass", UIPassShard); } +} // namespace Gui +} // namespace shards \ No newline at end of file diff --git a/src/extra/runtime.cpp b/src/extra/runtime.cpp index ccdd4cb236..e7fbf1c7bf 100644 --- a/src/extra/runtime.cpp +++ b/src/extra/runtime.cpp @@ -42,6 +42,10 @@ namespace DSP { extern void registerShards(); } +namespace Gui { +extern void registerShards(); +} + void shInitExtras() { #if SHARDS_WITH_RUST_SHARDS registerRustShards(shardsInterface(SHARDS_CURRENT_ABI)); @@ -55,6 +59,7 @@ void shInitExtras() { Inputs::registerShards(); Audio::registerShards(); DSP::registerShards(); + Gui::registerShards(); #ifdef _WIN32 Desktop::registerDesktopShards(); diff --git a/src/extra/rust_interop.cpp b/src/extra/rust_interop.cpp new file mode 100644 index 0000000000..58f16e5f5f --- /dev/null +++ b/src/extra/rust_interop.cpp @@ -0,0 +1,46 @@ +#include "gfx/shards_types.hpp" +#include "gfx.hpp" +#include + +using shards::Var; +namespace gfx { +SHTypeInfo *getMainWindowGlobalsType() { + static SHTypeInfo type = gfx::MainWindowGlobals::Type; + return &type; +} +const char *getMainWindowGlobalsVarName() { return gfx::Base::mainWindowGlobalsVarName; } +SHTypeInfo *getQueueType() { + static SHTypeInfo type = Types::DrawQueue; + return &type; +} + +template T *castChecked(const SHVar &var, const shards::Type &type) { + SHTypeInfo typeInfo(type); + if (var.valueType != SHType::Object) + throw std::logic_error("Invalid type"); + if (var.payload.objectVendorId != typeInfo.object.vendorId) + throw std::logic_error("Invalid object vendor id"); + if (var.payload.objectTypeId != typeInfo.object.typeId) + throw std::logic_error("Invalid object type id"); + return reinterpret_cast(var.payload.objectValue); +} + +SHVar MainWindowGlobals_getDefaultQueue(const SHVar &mainWindowGlobals) { + MainWindowGlobals *globals = castChecked(mainWindowGlobals, MainWindowGlobals::Type); + return Var::Object(&globals->shDrawQueue, SHTypeInfo(Types::DrawQueue).object.vendorId, + SHTypeInfo(Types::DrawQueue).object.typeId); +} +Context *MainWindowGlobals_getContext(const SHVar &mainWindowGlobals) { + MainWindowGlobals *globals = castChecked(mainWindowGlobals, MainWindowGlobals::Type); + return globals->context.get(); +} +Renderer *MainWindowGlobals_getRenderer(const SHVar &mainWindowGlobals) { + MainWindowGlobals *globals = castChecked(mainWindowGlobals, MainWindowGlobals::Type); + return globals->renderer.get(); +} + +DrawQueuePtr *getDrawQueueFromVar(const SHVar &var) { + SHDrawQueue *shDrawQueue = castChecked(var, Types::DrawQueue); + return &shDrawQueue->queue; +} +} // namespace gfx diff --git a/src/extra/rust_interop.hpp b/src/extra/rust_interop.hpp new file mode 100644 index 0000000000..463774d17b --- /dev/null +++ b/src/extra/rust_interop.hpp @@ -0,0 +1,21 @@ +#ifndef E325D8E3_F64E_413D_965B_DF275CF18AC4 +#define E325D8E3_F64E_413D_965B_DF275CF18AC4 + +#include "shards.h" +#include "../gfx/egui/rust_interop.hpp" +#include "gfx/fwd.hpp" + +namespace gfx { +// gfx::MainWindowGlobals::Type +SHTypeInfo *getMainWindowGlobalsType(); +const char *getMainWindowGlobalsVarName(); +SHTypeInfo *getQueueType(); + +SHVar MainWindowGlobals_getDefaultQueue(const SHVar &mainWindowGlobals); +Context *MainWindowGlobals_getContext(const SHVar &mainWindowGlobals); +Renderer *MainWindowGlobals_getRenderer(const SHVar &mainWindowGlobals); + +DrawQueuePtr *getDrawQueueFromVar(const SHVar &var); +} // namespace gfx + +#endif /* E325D8E3_F64E_413D_965B_DF275CF18AC4 */ diff --git a/src/gfx/CMakeLists.txt b/src/gfx/CMakeLists.txt index 4e76ff781f..e6f91be675 100644 --- a/src/gfx/CMakeLists.txt +++ b/src/gfx/CMakeLists.txt @@ -20,6 +20,7 @@ add_library(gfx shader/generator.cpp shader/blocks.cpp shader/types.cpp + rust_interop.cpp # cache_data.cpp ) @@ -52,6 +53,8 @@ target_link_libraries(gfx_imgui imgui imgui_club implot imguizmo ) +add_subdirectory(egui) + option(GFX_USE_DATA_PATH "Uses build tree paths to find data (dev only)" ON) if(NOT EMSCRIPTEN AND (CMAKE_BUILD_TYPE MATCHES Debug)) diff --git a/src/gfx/context.cpp b/src/gfx/context.cpp index 6e9a7a0adc..1fa9fa60f1 100644 --- a/src/gfx/context.cpp +++ b/src/gfx/context.cpp @@ -9,6 +9,8 @@ #include #include +#include + #if GFX_EMSCRIPTEN #include #endif @@ -27,7 +29,10 @@ static inline std::shared_ptr &getLogger() { #ifdef WEBGPU_NATIVE static WGPUBackendType getDefaultWgpuBackendType() { #if GFX_WINDOWS - return WGPUBackendType_D3D12; + // Vulkan is more performant on windows for now, see: + // https://github.com/gfx-rs/wgpu/issues/2719 - Make DX12 the Default API on Windows + // https://github.com/gfx-rs/wgpu/issues/2720 - Suballocate Buffers in DX12 + return WGPUBackendType_Vulkan; #elif GFX_APPLE return WGPUBackendType_Metal; #elif GFX_LINUX || GFX_ANDROID @@ -158,7 +163,7 @@ struct ContextMainOutput { preferredFormat = WGPUTextureFormat_BGRA8UnormSrgb; if (preferredFormat != swapchainFormat) { - getLogger()->debug("swapchain preferred format changed: {}", magic_enum::enum_name(preferredFormat)); + SPDLOG_LOGGER_DEBUG(getLogger(), "swapchain preferred format changed: {}", magic_enum::enum_name(preferredFormat)); swapchainFormat = preferredFormat; } @@ -167,7 +172,7 @@ struct ContextMainOutput { assert(wgpuWindowSurface); assert(swapchainFormat != WGPUTextureFormat_Undefined); - getLogger()->debug("resized width: {} height: {}", newSize.x, newSize.y); + SPDLOG_LOGGER_DEBUG(getLogger(), "resized width: {} height: {}", newSize.x, newSize.y); currentSize = newSize; releaseSwapchain(); @@ -176,7 +181,7 @@ struct ContextMainOutput { swapchainDesc.format = swapchainFormat; swapchainDesc.width = newSize.x; swapchainDesc.height = newSize.y; - swapchainDesc.presentMode = WGPUPresentMode_Fifo; + swapchainDesc.presentMode = WGPUPresentMode_Immediate; swapchainDesc.usage = WGPUTextureUsage_RenderAttachment | WGPUTextureUsage_CopyDst; wgpuSwapchain = wgpuDeviceCreateSwapChain(device, wgpuWindowSurface, &swapchainDesc); if (!wgpuSwapchain) { @@ -205,7 +210,7 @@ void Context::init(const ContextCreationOptions &inOptions) { } void Context::release() { - getLogger()->debug("release"); + SPDLOG_LOGGER_DEBUG(getLogger(), "release"); state = ContextState::Uninitialized; releaseAdapter(); @@ -294,7 +299,19 @@ bool Context::beginFrame() { collectContextData(); if (!isHeadless()) { - if (!mainOutput->requestFrame()) + const int maxAttempts = 2; + bool success = false; + + // Try to request the swapchain texture, automatically recreate swapchain on failure + for (size_t i = 0; !success && i < maxAttempts; i++) { + success = mainOutput->requestFrame(); + if (!success) { + SPDLOG_LOGGER_INFO(getLogger(), "Failed to get current swapchain texture, forcing recreate"); + mainOutput->resizeSwapchain(wgpuDevice, wgpuAdapter, mainOutput->currentSize); + } + } + + if (!success) return false; } @@ -338,7 +355,7 @@ void Context::submit(WGPUCommandBuffer cmdBuffer) { wgpuQueueSubmit(wgpuQueue, 1 void Context::deviceLost() { if (state != ContextState::Incomplete) { - getLogger()->debug("Device lost"); + SPDLOG_LOGGER_DEBUG(getLogger(), "Device lost"); state = ContextState::Incomplete; releaseDevice(); @@ -346,7 +363,7 @@ void Context::deviceLost() { } void Context::tickRequesting() { - getLogger()->debug("tickRequesting"); + SPDLOG_LOGGER_DEBUG(getLogger(), "tickRequesting"); try { if (adapterRequest) { if (adapterRequest->finished) { @@ -382,12 +399,12 @@ void Context::tickRequesting() { void Context::deviceObtained() { state = ContextState::Ok; - getLogger()->debug("wgpuDevice obtained"); + SPDLOG_LOGGER_DEBUG(getLogger(), "wgpuDevice obtained"); auto errorCallback = [](WGPUErrorType type, char const *message, void *userdata) { Context &context = *(Context *)userdata; std::string msgString(message); - getLogger()->error("{} ({})", message, type); + SPDLOG_LOGGER_ERROR(getLogger(), "{} ({})", message, type); if (type == WGPUErrorType_DeviceLost) { context.deviceLost(); } @@ -401,7 +418,7 @@ void Context::deviceObtained() { } WGPUDeviceLostCallback deviceLostCallback = [](WGPUDeviceLostReason reason, char const *message, void *userdata) { - getLogger()->warn("Device lost: {} ()", message, magic_enum::enum_name(reason)); + SPDLOG_LOGGER_WARN(getLogger(), "Device lost: {} ()", message, magic_enum::enum_name(reason)); }; wgpuDeviceSetDeviceLostCallback(wgpuDevice, deviceLostCallback, this); } @@ -431,7 +448,7 @@ void Context::requestDevice() { deviceDesc.nextInChain = &deviceExtras.chain; #endif - getLogger()->debug("Requesting wgpu device"); + SPDLOG_LOGGER_DEBUG(getLogger(), "Requesting wgpu device"); deviceRequest = DeviceRequest::create(wgpuAdapter, deviceDesc); } @@ -466,10 +483,23 @@ void Context::requestAdapter() { WGPUAdapterExtras adapterExtras = {}; requestAdapter.nextInChain = &adapterExtras.chain; adapterExtras.chain.sType = (WGPUSType)WGPUSType_AdapterExtras; - adapterExtras.backend = getDefaultWgpuBackendType(); + + adapterExtras.backend = WGPUBackendType_Null; + if (const char *backendStr = SDL_getenv("GFX_BACKEND")) { + std::string typeStr = std::string("WGPUBackendType_") + backendStr; + auto foundValue = magic_enum::enum_cast(typeStr); + if (foundValue) { + adapterExtras.backend = foundValue.value(); + } + } + + if (adapterExtras.backend == WGPUBackendType_Null) + adapterExtras.backend = getDefaultWgpuBackendType(); + + SPDLOG_LOGGER_INFO(getLogger(), "Using backend {}", magic_enum::enum_name(adapterExtras.backend)); #endif - getLogger()->debug("Requesting wgpu adapter"); + SPDLOG_LOGGER_DEBUG(getLogger(), "Requesting wgpu adapter"); adapterRequest = AdapterRequest::create(wgpuInstance, requestAdapter); } @@ -479,7 +509,7 @@ void Context::releaseAdapter() { } void Context::initCommon() { - getLogger()->debug("initCommon"); + SPDLOG_LOGGER_DEBUG(getLogger(), "initCommon"); assert(!isInitialized()); diff --git a/src/gfx/context.hpp b/src/gfx/context.hpp index c900178cc2..20835fe389 100644 --- a/src/gfx/context.hpp +++ b/src/gfx/context.hpp @@ -16,14 +16,10 @@ namespace gfx { struct ContextCreationOptions { - bool debug = true; + bool debug = false; void *overrideNativeWindowHandle = nullptr; }; -struct CopyBuffer { - std::vector data; -}; - enum class ContextState { Uninitialized, Requesting, @@ -41,6 +37,8 @@ struct ContextData; struct ContextMainOutput; struct DeviceRequest; struct AdapterRequest; + +///
struct Context { private: std::shared_ptr deviceRequest; diff --git a/src/gfx/egui/.gitignore b/src/gfx/egui/.gitignore new file mode 100644 index 0000000000..4470988469 --- /dev/null +++ b/src/gfx/egui/.gitignore @@ -0,0 +1,2 @@ +target/ +Cargo.lock \ No newline at end of file diff --git a/src/gfx/egui/CMakeLists.txt b/src/gfx/egui/CMakeLists.txt new file mode 100644 index 0000000000..c994f16569 --- /dev/null +++ b/src/gfx/egui/CMakeLists.txt @@ -0,0 +1,26 @@ + +set(FEATURES) + +option(BUILD_STANDALONE_EGUI_TEST "Build standalone egui+gfx test" ON) +if(BUILD_STANDALONE_EGUI_TEST) + list(APPEND FEATURES standalone_test) +endif() + +add_library(gfx_egui + egui_types.cpp + renderer.cpp +) +target_link_libraries(gfx_egui gfx) + +add_rust_library( + NAME egui-gfx + FEATURES ${FEATURES} + PROJECT_PATH ${CMAKE_CURRENT_LIST_DIR} + TARGET_PATH ${CMAKE_CURRENT_LIST_DIR}/target + DEPENDS rust_interop.hpp +) + +if(BUILD_STANDALONE_EGUI_TEST) + add_executable(gfx-egui-test test.cpp) + target_link_libraries(gfx-egui-test egui-gfx-rust gfx_egui) +endif() diff --git a/src/gfx/egui/Cargo.toml b/src/gfx/egui/Cargo.toml new file mode 100644 index 0000000000..7ff6338618 --- /dev/null +++ b/src/gfx/egui/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "egui-gfx" +version = "0.1.0" +edition = "2021" + +[dependencies] +egui = { version = "0.18.1" } +epaint = {version = "0.18.1"} +lazy_static = "1.4.0" + +[build-dependencies] +bindgen = "0.60.1" +gfx-build = { path = "../rust/build" } + +[features] +# Enables the test UI code +standalone_test = [] diff --git a/src/gfx/egui/build.rs b/src/gfx/egui/build.rs new file mode 100644 index 0000000000..da552be404 --- /dev/null +++ b/src/gfx/egui/build.rs @@ -0,0 +1,23 @@ +extern crate bindgen; +extern crate gfx_build; + +use std::env; +use std::path::PathBuf; + +fn main() { + let gfx_path = "..".to_string(); + + let builder = gfx_build::setup_bindgen_for_gfx(gfx_path.as_str(), bindgen::Builder::default()); + + let bindings = builder + .header("rust_interop.hpp") + .size_t_is_usize(true) + .layout_tests(false) + .generate() + .expect("Unable to generate bindings"); + + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Couldn't write bindings!"); +} diff --git a/src/gfx/egui/egui_render_pass.hpp b/src/gfx/egui/egui_render_pass.hpp new file mode 100644 index 0000000000..8f319b7eab --- /dev/null +++ b/src/gfx/egui/egui_render_pass.hpp @@ -0,0 +1,67 @@ +#ifndef CC291073_D9DD_4B16_83A4_303777994C40 +#define CC291073_D9DD_4B16_83A4_303777994C40 + +#include "../feature.hpp" +#include "../pipeline_step.hpp" +#include "../shader/blocks.hpp" + +namespace gfx { +struct EguiRenderPass { + static PipelineStepPtr createPipelineStep(DrawQueuePtr queue) { + auto drawableStep = makeDrawablePipelineStep(RenderDrawablesStep{ + .drawQueue = queue, + .features = std::vector{createFeature()}, + .sortMode = SortMode::Queue, + }); + return drawableStep; + } + + static FeaturePtr createFeature() { + using namespace shader::blocks; + auto uiFeature = std::make_shared(); + auto code = makeCompoundBlock(); + + code->append(Header(R"( +fn linear_from_srgb(srgb: vec3) -> vec3 { + let srgb_bytes = srgb * 255.0; + let cutoff = srgb_bytes < vec3(10.31475); + let lower = srgb_bytes / vec3(3294.6); + let higher = pow((srgb_bytes + vec3(14.025)) / vec3(269.025), vec3(2.4)); + return select(higher, lower, cutoff); +})")); + code->appendLine("var vp = ", ReadBuffer("viewport", shader::FieldTypes::Float4, "view")); + code->appendLine("var p1 = ", ReadInput("position"), " * (1.0 / vp.zw)"); + code->appendLine("p1.y = -p1.y;"); + code->appendLine("p1 = p1 * 2.0 + vec2(-1.0, 1.0)"); + code->appendLine("var p4 = vec4(p1.xy, 0.0, 1.0)"); + code->appendLine(WriteOutput("position", shader::FieldTypes::Float4, "p4")); + code->appendLine("var color = ", ReadInput("color")); + code->appendLine(WriteOutput("color", shader::FieldTypes::Float4, "vec4(linear_from_srgb(color.xyz), color.a)")); + + uiFeature->shaderEntryPoints.emplace_back("baseTransform", ProgrammableGraphicsStage::Vertex, std::move(code)); + + shader::FieldType flagsFieldType = shader::FieldType(ShaderFieldBaseType::UInt32, 1); + code = makeCompoundBlock(); + code->appendLine("var color = ", ReadInput("color")); + code->appendLine("var texColor = ", SampleTexture("color")); + code->appendLine("var isFont = ", ReadBuffer("flags", flagsFieldType), " & 1u"); + code->append("if(isFont != 0u) { texColor = vec4(texColor.xxx, texColor.x); }\n"); + code->appendLine(WriteOutput("color", shader::FieldTypes::Float4, "color * texColor")); + uiFeature->shaderEntryPoints.emplace_back("color", ProgrammableGraphicsStage::Fragment, std::move(code)); + + uiFeature->textureParams.emplace_back("color"); + uiFeature->shaderParams.emplace_back("flags", flagsFieldType, uint32_t(0)); + + uiFeature->state.set_depthWrite(false); + uiFeature->state.set_depthCompare(WGPUCompareFunction_Always); + uiFeature->state.set_culling(false); + uiFeature->state.set_blend(BlendState{ + .color = BlendComponent::AlphaPremultiplied, + .alpha = BlendComponent::Opaque, + }); + return uiFeature; + } +}; +} // namespace gfx + +#endif /* CC291073_D9DD_4B16_83A4_303777994C40 */ diff --git a/src/gfx/egui/egui_types.cpp b/src/gfx/egui/egui_types.cpp new file mode 100644 index 0000000000..1c8fd94b42 --- /dev/null +++ b/src/gfx/egui/egui_types.cpp @@ -0,0 +1,13 @@ +#include "rust_interop.hpp" +#include +using namespace gfx; + +namespace egui { +std::vector Vertex::getAttributes() { + return std::vector{ + MeshVertexAttribute("position", 2), + MeshVertexAttribute("texCoord0", 2), + MeshVertexAttribute("color", 4, VertexAttributeType::UNorm8), + }; +} +} // namespace egui diff --git a/src/gfx/egui/egui_types.hpp b/src/gfx/egui/egui_types.hpp new file mode 100644 index 0000000000..f91ba639c1 --- /dev/null +++ b/src/gfx/egui/egui_types.hpp @@ -0,0 +1,79 @@ +#ifndef DBE976AE_DBE6_4455_8698_E341D3B8223F +#define DBE976AE_DBE6_4455_8698_E341D3B8223F + +#include +#include + +#ifndef RUST_BINDGEN +#include +#include "../mesh.hpp" +#endif + +namespace egui { +struct Pos2 { + float x, y; +}; + +struct Rect { + Pos2 min, max; +}; + +struct Color32 { + uint8_t r, g, b, a; +}; + +struct Vertex { + Pos2 pos; + Pos2 uv; + Color32 color; + +#ifndef RUST_BINDGEN + static std::vector getAttributes(); +#endif +}; + +struct Input { + int cursorPosition[2]; + bool mouseButton{}; +}; + +struct TextureId { + uint64_t id; + operator uint64_t() const { return id; } +}; + +enum class TextureFormat : uint8_t { R32F, RGBA8 }; + +struct TextureSet { + TextureId id; + size_t size[2]; + size_t offset[2]; + bool subRegion = false; + const uint8_t *pixels; + TextureFormat format; +}; + +struct TextureUpdates { + const TextureSet *sets; + size_t numSets; + const TextureId *frees; + size_t numFrees; +}; + +struct ClippedPrimitive { + Rect clipRect; + const uint32_t *indices; + size_t numIndices; + const Vertex *vertices; + size_t numVertices; + TextureId textureId; +}; + +struct FullOutput { + TextureUpdates textureUpdates; + const ClippedPrimitive *primitives; + size_t numPrimitives; +}; +} // namespace egui + +#endif /* DBE976AE_DBE6_4455_8698_E341D3B8223F */ diff --git a/src/gfx/egui/renderer.cpp b/src/gfx/egui/renderer.cpp new file mode 100644 index 0000000000..2e2f08c3fc --- /dev/null +++ b/src/gfx/egui/renderer.cpp @@ -0,0 +1,198 @@ +#include "renderer.hpp" +#include "egui_render_pass.hpp" +#include "gfx/params.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace gfx { +struct MeshPoolOps { + size_t getCapacity(MeshPtr &item) const { return item->getNumVertices() * item->getFormat().getVertexSize(); } + void init(MeshPtr &item) const { item = std::make_shared(); } +}; +typedef ResizableItemPool MeshPool; + +struct TextureManager { + std::map textures; + + TexturePtr get(const egui::TextureId &id) const { + auto it = textures.find(id.id); + if (it != textures.end()) + return it->second; + return TexturePtr(); + } + + void imageCopy(WGPUTextureFormat dstFormat, WGPUTextureFormat srcFormat, uint8_t *dst, const uint8_t *src, size_t numPixels) { + switch (srcFormat) { + case WGPUTextureFormat_RGBA8UnormSrgb: + assert(dstFormat == srcFormat); + memcpy(dst, src, numPixels * sizeof(uint32_t)); + break; + case WGPUTextureFormat_R32Float: { + assert(dstFormat == WGPUTextureFormat_R8Unorm); + const float *srcFloat = (float *)src; + for (size_t i = 0; i < numPixels; i++) { + *dst = uint8_t(*srcFloat * 255); + dst++; + srcFloat++; + } + } break; + default: + assert(false); + } + } + + void set(const egui::TextureSet &set) { + auto it = textures.find(set.id); + if (it == textures.end()) { + it = textures.insert_or_assign(set.id.id, std::make_shared()).first; + } + TexturePtr texture = it->second; + + gfx::TextureFormat fmt{}; + WGPUTextureFormat srcFormat; + size_t srcPixelSize; + size_t dstPixelSize; + switch (set.format) { + case egui::TextureFormat::R32F: + // Need to convert, 32-bit float types are not filterable in the WebGPU spec + srcFormat = WGPUTextureFormat_R32Float; + fmt.pixelFormat = WGPUTextureFormat_R8Unorm; + srcPixelSize = sizeof(float); + dstPixelSize = sizeof(uint8_t); + break; + case egui::TextureFormat::RGBA8: + srcFormat = fmt.pixelFormat = WGPUTextureFormat_RGBA8UnormSrgb; + srcPixelSize = dstPixelSize = sizeof(uint32_t); + break; + } + + fmt.type = TextureType::D2; + fmt.flags = TextureFormatFlags::None; + SamplerState sampler{ + .addressModeU = WGPUAddressMode_ClampToEdge, + .addressModeV = WGPUAddressMode_ClampToEdge, + .filterMode = WGPUFilterMode_Linear, + }; + + ImmutableSharedBuffer currentData = texture->getData(); + std::vector imageData; + if (set.subRegion && currentData.getLength() > 0) { + imageData.resize(currentData.getLength()); + memcpy(imageData.data(), currentData.getData(), currentData.getLength()); + } else { + if (set.subRegion) + throw std::logic_error("Can not update a sub-region on a non-existing texture"); + imageData.resize(dstPixelSize * set.size[0] * set.size[1]); + } + + int2 size{}; + if (set.subRegion) { + size = texture->getResolution(); + size_t dstPitch = size.x * dstPixelSize; + size_t srcPitch = set.size[0] * srcPixelSize; + uint8_t *dstBase = imageData.data() + set.offset[0] * dstPixelSize; + for (size_t srcY = 0; srcY < set.size[1]; srcY++) { + size_t dstY = set.offset[1] + srcY; + uint8_t *dstPtr = dstBase + dstPitch * dstY; + const uint8_t *srcPtr = set.pixels + srcPitch * srcY; + imageCopy(fmt.pixelFormat, srcFormat, dstPtr, srcPtr, set.size[0]); + } + } else { // Full image + size.x = set.size[0]; + size.y = set.size[1]; + imageCopy(fmt.pixelFormat, srcFormat, imageData.data(), set.pixels, size.x * size.y); + } + + texture->init(fmt, size, sampler, std::move(imageData)); + } + + void free(egui::TextureId id) { textures.erase(id.id); } +}; + +struct EguiRendererImpl { + MeshPool meshPool; + TextureManager textures; + std::vector pendingTextureFrees; + + MeshFormat meshFormat; + + EguiRendererImpl() { + meshFormat = { + .primitiveType = PrimitiveType::TriangleList, + .windingOrder = WindingOrder::CCW, + .indexFormat = IndexFormat::UInt32, + .vertexAttributes = egui::Vertex::getAttributes(), + }; + } + + void addPendingTextureFree(egui::TextureId id) { pendingTextureFrees.push_back(id); } + + void processPendingTextureFrees() { + for (auto &id : pendingTextureFrees) { + SPDLOG_INFO("textureFree {}", (uint64_t)id.id); + textures.free(id); + } + pendingTextureFrees.clear(); + } +}; + +EguiRenderer::EguiRenderer() { impl = std::make_shared(); } +void EguiRenderer::render(const egui::FullOutput &output, const gfx::DrawQueuePtr &drawQueue) { + impl->meshPool.reset(); + impl->processPendingTextureFrees(); + + // Update textures before render + auto &textureUpdates = output.textureUpdates; + for (size_t i = 0; i < textureUpdates.numSets; i++) { + auto &textureSet = textureUpdates.sets[i]; + SPDLOG_INFO("textureSet {}", (uint64_t)textureSet.id); + impl->textures.set(textureSet); + } + + // Update meshes & generate drawables + for (size_t i = 0; i < output.numPrimitives; i++) { + auto &prim = output.primitives[i]; + + MeshPtr mesh = impl->meshPool.allocateBuffer(prim.numVertices); + mesh->update(impl->meshFormat, prim.vertices, prim.numVertices * sizeof(egui::Vertex), prim.indices, + prim.numIndices * sizeof(uint32_t)); + + DrawablePtr drawable = std::make_shared(mesh); + TexturePtr texture = impl->textures.get(prim.textureId); + if (texture) { + drawable->parameters.set("color", texture); + if (texture->getFormat().pixelFormat == WGPUTextureFormat_R8Unorm) { + drawable->parameters.set("flags", uint32_t(0x1)); + } + } + drawQueue->add(drawable); + } + + // Store texture id's to free + // these are executed at the start the next time render() is called + for (size_t i = 0; i < textureUpdates.numFrees; i++) { + auto &id = textureUpdates.frees[i]; + impl->addPendingTextureFree(id); + } +} + +EguiRenderer *EguiRenderer::create() { return new EguiRenderer(); } +void EguiRenderer::destroy(EguiRenderer *renderer) { delete renderer; } +} // namespace gfx diff --git a/src/gfx/egui/renderer.hpp b/src/gfx/egui/renderer.hpp new file mode 100644 index 0000000000..2dd06b7168 --- /dev/null +++ b/src/gfx/egui/renderer.hpp @@ -0,0 +1,25 @@ +#ifndef D9CD6261_7BAB_402B_BC43_8BC66551E95D +#define D9CD6261_7BAB_402B_BC43_8BC66551E95D + +#include "egui_types.hpp" +#include "../fwd.hpp" +#include + +namespace gfx { +struct EguiRendererImpl; + +///
+struct EguiRenderer { + std::shared_ptr impl; + + EguiRenderer(); + + void render(const egui::FullOutput &output, const gfx::DrawQueuePtr &drawQueue); + + static EguiRenderer *create(); + static void destroy(EguiRenderer *renderer); +}; + +} // namespace gfx + +#endif /* D9CD6261_7BAB_402B_BC43_8BC66551E95D */ diff --git a/src/gfx/egui/rust_interop.hpp b/src/gfx/egui/rust_interop.hpp new file mode 100644 index 0000000000..e71908c3b4 --- /dev/null +++ b/src/gfx/egui/rust_interop.hpp @@ -0,0 +1,8 @@ +#ifndef D51F59C5_BA16_47C5_B59B_0C4D8273CADB +#define D51F59C5_BA16_47C5_B59B_0C4D8273CADB + +#include "../rust_interop.hpp" +#include "egui_types.hpp" +#include "renderer.hpp" + +#endif /* D51F59C5_BA16_47C5_B59B_0C4D8273CADB */ diff --git a/src/gfx/egui/src/color_test.rs b/src/gfx/egui/src/color_test.rs new file mode 100644 index 0000000000..cc26617ea9 --- /dev/null +++ b/src/gfx/egui/src/color_test.rs @@ -0,0 +1,465 @@ +use egui::{color::*, widgets::color_picker::show_color, *}; +use std::collections::HashMap; + +const GRADIENT_SIZE: Vec2 = vec2(256.0, 24.0); + +const BLACK: Color32 = Color32::BLACK; +const GREEN: Color32 = Color32::GREEN; +const RED: Color32 = Color32::RED; +const TRANSPARENT: Color32 = Color32::TRANSPARENT; +const WHITE: Color32 = Color32::WHITE; + +/// A test for sanity-checking and diagnosing egui rendering backends. +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] +pub struct ColorTest { + #[cfg_attr(feature = "serde", serde(skip))] + tex_mngr: TextureManager, + vertex_gradients: bool, + texture_gradients: bool, + srgb: bool, +} + +impl Default for ColorTest { + fn default() -> Self { + Self { + tex_mngr: Default::default(), + vertex_gradients: true, + texture_gradients: true, + srgb: false, + } + } +} + +impl ColorTest { + pub fn ui(&mut self, ui: &mut Ui) { + ui.set_max_width(680.0); + + ui.label("This is made to test that the egui painter backend is set up correctly, so that all colors are interpolated and blended in linear space with premultiplied alpha."); + ui.label("If everything is set up correctly, all groups of gradients will look uniform"); + + ui.checkbox(&mut self.vertex_gradients, "Vertex gradients"); + ui.checkbox(&mut self.texture_gradients, "Texture gradients"); + ui.checkbox(&mut self.srgb, "Show naive sRGBA horror"); + + ui.heading("sRGB color test"); + ui.label("Use a color picker to ensure this color is (255, 165, 0) / #ffa500"); + ui.scope(|ui| { + ui.spacing_mut().item_spacing.y = 0.0; // No spacing between gradients + let g = Gradient::one_color(Color32::from_rgb(255, 165, 0)); + self.vertex_gradient(ui, "orange rgb(255, 165, 0) - vertex", WHITE, &g); + self.tex_gradient(ui, "orange rgb(255, 165, 0) - texture", WHITE, &g); + }); + + ui.separator(); + + ui.label("Test that vertex color times texture color is done in linear space:"); + ui.scope(|ui| { + ui.spacing_mut().item_spacing.y = 0.0; // No spacing between gradients + + let tex_color = Rgba::from_rgb(1.0, 0.25, 0.25); + let vertex_color = Rgba::from_rgb(0.5, 0.75, 0.75); + + ui.horizontal(|ui| { + let color_size = ui.spacing().interact_size; + ui.label("texture"); + show_color(ui, tex_color, color_size); + ui.label(" * "); + show_color(ui, vertex_color, color_size); + ui.label(" vertex color ="); + }); + { + let g = Gradient::one_color(Color32::from(tex_color * vertex_color)); + self.vertex_gradient(ui, "Ground truth (vertices)", WHITE, &g); + self.tex_gradient(ui, "Ground truth (texture)", WHITE, &g); + } + + ui.horizontal(|ui| { + let g = Gradient::one_color(Color32::from(tex_color)); + let tex = self.tex_mngr.get(ui.ctx(), &g); + let texel_offset = 0.5 / (g.0.len() as f32); + let uv = Rect::from_min_max(pos2(texel_offset, 0.0), pos2(1.0 - texel_offset, 1.0)); + ui.add(Image::new(tex, GRADIENT_SIZE).tint(vertex_color).uv(uv)) + .on_hover_text(format!("A texture that is {} texels wide", g.0.len())); + ui.label("GPU result"); + }); + }); + + ui.separator(); + + // TODO(emilk): test color multiplication (image tint), + // to make sure vertex and texture color multiplication is done in linear space. + self.show_gradients(ui, WHITE, (RED, GREEN)); + if self.srgb { + ui.label("Notice the darkening in the center of the naive sRGB interpolation."); + } + + ui.separator(); + + self.show_gradients(ui, RED, (TRANSPARENT, GREEN)); + + ui.separator(); + + self.show_gradients(ui, WHITE, (TRANSPARENT, GREEN)); + if self.srgb { + ui.label( + "Notice how the linear blend stays green while the naive sRGBA interpolation looks gray in the middle.", + ); + } + + ui.separator(); + /* + self.show_gradients(ui, BLACK, (BLACK, WHITE)); + ui.separator(); + self.show_gradients(ui, WHITE, (BLACK, TRANSPARENT)); + ui.separator(); + self.show_gradients(ui, BLACK, (TRANSPARENT, WHITE)); + ui.separator(); + + ui.label("Additive blending: add more and more blue to the red background:"); + self.show_gradients( + ui, + RED, + (TRANSPARENT, Color32::from_rgb_additive(0, 0, 255)), + ); + + ui.separator(); + + pixel_test(ui); + + ui.separator(); + + blending_and_feathering_test(ui); */ + } + + fn show_gradients(&mut self, ui: &mut Ui, bg_fill: Color32, (left, right): (Color32, Color32)) { + let is_opaque = left.is_opaque() && right.is_opaque(); + + ui.horizontal(|ui| { + let color_size = ui.spacing().interact_size; + if !is_opaque { + ui.label("Background:"); + show_color(ui, bg_fill, color_size); + } + ui.label("gradient"); + show_color(ui, left, color_size); + ui.label("-"); + show_color(ui, right, color_size); + }); + + ui.scope(|ui| { + ui.spacing_mut().item_spacing.y = 0.0; // No spacing between gradients + if is_opaque { + let g = Gradient::ground_truth_linear_gradient(left, right); + self.vertex_gradient(ui, "Ground Truth (CPU gradient) - vertices", bg_fill, &g); + self.tex_gradient(ui, "Ground Truth (CPU gradient) - texture", bg_fill, &g); + } else { + let g = Gradient::ground_truth_linear_gradient(left, right).with_bg_fill(bg_fill); + self.vertex_gradient( + ui, + "Ground Truth (CPU gradient, CPU blending) - vertices", + bg_fill, + &g, + ); + self.tex_gradient( + ui, + "Ground Truth (CPU gradient, CPU blending) - texture", + bg_fill, + &g, + ); + let g = Gradient::ground_truth_linear_gradient(left, right); + self.vertex_gradient(ui, "CPU gradient, GPU blending - vertices", bg_fill, &g); + self.tex_gradient(ui, "CPU gradient, GPU blending - texture", bg_fill, &g); + } + + let g = Gradient::texture_gradient(left, right); + self.vertex_gradient( + ui, + "Triangle mesh of width 2 (test vertex decode and interpolation)", + bg_fill, + &g, + ); + self.tex_gradient(ui, "Texture of width 2 (test texture sampler)", bg_fill, &g); + + if self.srgb { + let g = + Gradient::ground_truth_bad_srgba_gradient(left, right).with_bg_fill(bg_fill); + self.vertex_gradient( + ui, + "Triangle mesh with naive sRGBA interpolation (WRONG)", + bg_fill, + &g, + ); + self.tex_gradient(ui, "Naive sRGBA interpolation (WRONG)", bg_fill, &g); + } + }); + } + + fn tex_gradient(&mut self, ui: &mut Ui, label: &str, bg_fill: Color32, gradient: &Gradient) { + if !self.texture_gradients { + return; + } + ui.horizontal(|ui| { + let tex = self.tex_mngr.get(ui.ctx(), gradient); + let texel_offset = 0.5 / (gradient.0.len() as f32); + let uv = Rect::from_min_max(pos2(texel_offset, 0.0), pos2(1.0 - texel_offset, 1.0)); + ui.add(Image::new(tex, GRADIENT_SIZE).bg_fill(bg_fill).uv(uv)) + .on_hover_text(format!( + "A texture that is {} texels wide", + gradient.0.len() + )); + ui.label(label); + }); + } + + fn vertex_gradient(&mut self, ui: &mut Ui, label: &str, bg_fill: Color32, gradient: &Gradient) { + if !self.vertex_gradients { + return; + } + ui.horizontal(|ui| { + vertex_gradient(ui, bg_fill, gradient).on_hover_text(format!( + "A triangle mesh that is {} vertices wide", + gradient.0.len() + )); + ui.label(label); + }); + } +} + +fn vertex_gradient(ui: &mut Ui, bg_fill: Color32, gradient: &Gradient) -> Response { + use egui::epaint::*; + let (rect, response) = ui.allocate_at_least(GRADIENT_SIZE, Sense::hover()); + if bg_fill != Default::default() { + let mut mesh = Mesh::default(); + mesh.add_colored_rect(rect, bg_fill); + ui.painter().add(Shape::mesh(mesh)); + } + { + let n = gradient.0.len(); + assert!(n >= 2); + let mut mesh = Mesh::default(); + for (i, &color) in gradient.0.iter().enumerate() { + let t = i as f32 / (n as f32 - 1.0); + let x = lerp(rect.x_range(), t); + mesh.colored_vertex(pos2(x, rect.top()), color); + mesh.colored_vertex(pos2(x, rect.bottom()), color); + if i < n - 1 { + let i = i as u32; + mesh.add_triangle(2 * i, 2 * i + 1, 2 * i + 2); + mesh.add_triangle(2 * i + 1, 2 * i + 2, 2 * i + 3); + } + } + ui.painter().add(Shape::mesh(mesh)); + } + response +} + +#[derive(Clone, Hash, PartialEq, Eq)] +struct Gradient(pub Vec); + +impl Gradient { + pub fn one_color(srgba: Color32) -> Self { + Self(vec![srgba, srgba]) + } + pub fn texture_gradient(left: Color32, right: Color32) -> Self { + Self(vec![left, right]) + } + pub fn ground_truth_linear_gradient(left: Color32, right: Color32) -> Self { + let left = Rgba::from(left); + let right = Rgba::from(right); + + let n = 255; + Self( + (0..=n) + .map(|i| { + let t = i as f32 / n as f32; + Color32::from(lerp(left..=right, t)) + }) + .collect(), + ) + } + /// This is how a bad person blends `sRGBA` + pub fn ground_truth_bad_srgba_gradient(left: Color32, right: Color32) -> Self { + let n = 255; + Self( + (0..=n) + .map(|i| { + let t = i as f32 / n as f32; + Color32::from_rgba_premultiplied( + lerp((left[0] as f32)..=(right[0] as f32), t).round() as u8, // Don't ever do this please! + lerp((left[1] as f32)..=(right[1] as f32), t).round() as u8, // Don't ever do this please! + lerp((left[2] as f32)..=(right[2] as f32), t).round() as u8, // Don't ever do this please! + lerp((left[3] as f32)..=(right[3] as f32), t).round() as u8, // Don't ever do this please! + ) + }) + .collect(), + ) + } + + /// Do premultiplied alpha-aware blending of the gradient on top of the fill color + pub fn with_bg_fill(self, bg: Color32) -> Self { + let bg = Rgba::from(bg); + Self( + self.0 + .into_iter() + .map(|fg| { + let fg = Rgba::from(fg); + Color32::from(bg * (1.0 - fg.a()) + fg) + }) + .collect(), + ) + } + + pub fn to_pixel_row(&self) -> Vec { + self.0.clone() + } +} + +#[derive(Default)] +struct TextureManager(HashMap); + +impl TextureManager { + fn get(&mut self, ctx: &egui::Context, gradient: &Gradient) -> &TextureHandle { + self.0.entry(gradient.clone()).or_insert_with(|| { + let pixels = gradient.to_pixel_row(); + let width = pixels.len(); + let height = 1; + ctx.load_texture( + "color_test_gradient", + epaint::ColorImage { + size: [width, height], + pixels, + }, + ) + }) + } +} + +fn pixel_test(ui: &mut Ui) { + ui.label("Each subsequent square should be one physical pixel larger than the previous. They should be exactly one physical pixel apart. They should be perfectly aligned to the pixel grid."); + + let color = if ui.style().visuals.dark_mode { + egui::Color32::WHITE + } else { + egui::Color32::BLACK + }; + + let pixels_per_point = ui.ctx().pixels_per_point(); + let num_squares: u32 = 8; + let size_pixels = Vec2::new( + ((num_squares + 1) * (num_squares + 2) / 2) as f32, + num_squares as f32, + ); + let size_points = size_pixels / pixels_per_point + Vec2::splat(2.0); + let (response, painter) = ui.allocate_painter(size_points, Sense::hover()); + + let mut cursor_pixel = Pos2::new( + response.rect.min.x * pixels_per_point, + response.rect.min.y * pixels_per_point, + ) + .ceil(); + for size in 1..=num_squares { + let rect_points = Rect::from_min_size( + Pos2::new( + cursor_pixel.x / pixels_per_point, + cursor_pixel.y / pixels_per_point, + ), + Vec2::splat(size as f32) / pixels_per_point, + ); + painter.rect_filled(rect_points, 0.0, color); + cursor_pixel.x += (1 + size) as f32; + } +} + +fn blending_and_feathering_test(ui: &mut Ui) { + ui.label("Some fine lines for testing anti-aliasing and blending:"); + + let size = Vec2::new(512.0, 512.0); + let (response, painter) = ui.allocate_painter(size, Sense::hover()); + let rect = response.rect; + + let mut top_half = rect; + top_half.set_bottom(top_half.center().y); + painter.rect_filled(top_half, 0.0, Color32::BLACK); + paint_fine_lines_and_text(&painter, top_half, Color32::WHITE); + + let mut bottom_half = rect; + bottom_half.set_top(bottom_half.center().y); + painter.rect_filled(bottom_half, 0.0, Color32::WHITE); + paint_fine_lines_and_text(&painter, bottom_half, Color32::BLACK); +} + +fn paint_fine_lines_and_text(painter: &egui::Painter, mut rect: Rect, color: Color32) { + { + let mut x = 0.0; + for opacity in [1.00, 0.50, 0.25, 0.10, 0.05, 0.02, 0.01, 0.00] { + painter.text( + rect.center_top() + Vec2::new(0.0, x), + Align2::LEFT_TOP, + format!("{:.0}% white", 100.0 * opacity), + FontId::proportional(16.0), + Color32::WHITE.linear_multiply(opacity), + ); + painter.text( + rect.center_top() + Vec2::new(80.0, x), + Align2::LEFT_TOP, + format!("{:.0}% gray", 100.0 * opacity), + FontId::proportional(16.0), + Color32::GRAY.linear_multiply(opacity), + ); + painter.text( + rect.center_top() + Vec2::new(160.0, x), + Align2::LEFT_TOP, + format!("{:.0}% black", 100.0 * opacity), + FontId::proportional(16.0), + Color32::BLACK.linear_multiply(opacity), + ); + x += 20.0; + } + } + + rect.max.x = rect.center().x; + + rect = rect.shrink(12.0); + for width in [0.5, 1.0, 2.0] { + painter.text( + rect.left_top(), + Align2::CENTER_CENTER, + width.to_string(), + FontId::monospace(14.0), + color, + ); + + painter.add(egui::epaint::CubicBezierShape::from_points_stroke( + [ + rect.left_top() + Vec2::new(16.0, 0.0), + rect.right_top(), + rect.right_center(), + rect.right_bottom(), + ], + false, + Color32::TRANSPARENT, + Stroke::new(width, color), + )); + + rect.min.y += 32.0; + rect.max.x -= 32.0; + } + + rect.min.y += 16.0; + painter.text( + rect.left_top(), + Align2::LEFT_CENTER, + "transparent --> opaque", + FontId::monospace(11.0), + color, + ); + rect.min.y += 12.0; + let mut mesh = Mesh::default(); + mesh.colored_vertex(rect.left_bottom(), Color32::TRANSPARENT); + mesh.colored_vertex(rect.left_top(), Color32::TRANSPARENT); + mesh.colored_vertex(rect.right_bottom(), color); + mesh.colored_vertex(rect.right_top(), color); + mesh.add_triangle(0, 1, 2); + mesh.add_triangle(1, 2, 3); + painter.add(mesh); +} diff --git a/src/gfx/egui/src/lib.rs b/src/gfx/egui/src/lib.rs new file mode 100644 index 0000000000..7224079e9e --- /dev/null +++ b/src/gfx/egui/src/lib.rs @@ -0,0 +1,19 @@ +#![cfg_attr(all(target_os = "windows", target_arch = "x86"), feature(abi_thiscall))] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); + +mod renderer; + +#[cfg(feature = "standalone_test")] +#[macro_use] +extern crate lazy_static; + +#[cfg(feature = "standalone_test")] +mod color_test; + +#[cfg(feature = "standalone_test")] +mod standalone_test; + +pub use renderer::*; diff --git a/src/gfx/egui/src/renderer.rs b/src/gfx/egui/src/renderer.rs new file mode 100644 index 0000000000..d784a8db64 --- /dev/null +++ b/src/gfx/egui/src/renderer.rs @@ -0,0 +1,277 @@ +use super::*; +use egui::ClippedPrimitive; +use egui::Context; +use std::ptr; + +pub struct Renderer { + egui_renderer: *mut gfx_EguiRenderer, +} + +unsafe impl Send for Renderer {} +unsafe impl Sync for Renderer {} + +pub enum PixelData { + Color(Vec), + Font(Vec), +} + +pub struct NativeFullOutput { + pub texture_sets: Vec, + pub texture_frees: Vec, + pub clipped_primitives: Vec, + pub vertex_mem: Vec, + pub index_mem: Vec, + pub image_mem: Vec, + pub full_output: egui_FullOutput, +} + +impl From for egui_Pos2 { + fn from(pos: egui::Pos2) -> Self { + Self { x: pos.x, y: pos.y } + } +} + +impl From for egui::Pos2 { + fn from(pos: egui_Pos2) -> Self { + Self { x: pos.x, y: pos.y } + } +} + +impl From for egui_Rect { + fn from(r: egui::Rect) -> Self { + Self { + min: r.min.into(), + max: r.max.into(), + } + } +} + +impl From for egui::Rect { + fn from(r: egui_Rect) -> Self { + Self { + min: r.min.into(), + max: r.max.into(), + } + } +} + +impl From for egui_Color32 { + fn from(c: epaint::Color32) -> Self { + Self { + r: c.r(), + g: c.g(), + b: c.b(), + a: c.a(), + } + } +} + +impl From for egui_Vertex { + fn from(v: epaint::Vertex) -> Self { + Self { + pos: v.pos.into(), + uv: v.uv.into(), + color: v.color.into(), + } + } +} + +impl From for egui_TextureId { + fn from(v: epaint::TextureId) -> Self { + Self { + id: if let epaint::TextureId::Managed(managed) = v { + managed + } else { + 0 + }, + } + } +} + +fn convert_primitive( + clipped_primitive: ClippedPrimitive, + vertex_mem: &mut Vec, + index_mem: &mut Vec, + ui_scale: f32, +) -> Result { + if let epaint::Primitive::Mesh(mesh) = &clipped_primitive.primitive { + let startVertex = vertex_mem.len(); + for vert in &mesh.vertices { + let vert_native = egui_Vertex { + pos: egui_Pos2 { + x: vert.pos.x * ui_scale, + y: vert.pos.y * ui_scale, + }, + color: vert.color.into(), + uv: vert.uv.into(), + }; + vertex_mem.push(vert_native); + } + let numVerts = vertex_mem.len() - startVertex; + let vertsPtr = if numVerts > 0 { + &vertex_mem[startVertex] + } else { + ptr::null() + }; + + let startIndex = index_mem.len(); + for ind in &mesh.indices { + index_mem.push(*ind); + } + let numIndices = index_mem.len() - startIndex; + let indicesPtr = if numIndices > 0 { + &index_mem[startIndex] + } else { + ptr::null() + }; + + Ok(egui_ClippedPrimitive { + clipRect: clipped_primitive.clip_rect.into(), + vertices: vertsPtr, + numVertices: numVerts, + indices: indicesPtr, + numIndices: numIndices, + textureId: mesh.texture_id.into(), + }) + } else { + Err("Only mesh primitives are supported") + } +} + +fn convert_texture_set( + id: epaint::TextureId, + delta: epaint::ImageDelta, + image_data: &mut Vec, +) -> Result { + let (format, ptr, size, pixels) = match delta.image { + epaint::ImageData::Color(color) => { + let ptr = color.pixels.as_ptr(); + let size = color.size.clone(); + ( + egui_TextureFormat_RGBA8, + ptr as *const u8, + size, + PixelData::Color(color.pixels), + ) + } + epaint::ImageData::Font(font) => { + let ptr = font.pixels.as_ptr(); + let size = font.size.clone(); + ( + egui_TextureFormat_R32F, + ptr as *const u8, + size, + PixelData::Font(font.pixels), + ) + } + }; + + image_data.push(pixels); + + let (offset, sub_region) = if let Some(pos) = delta.pos { + (pos, true) + } else { + ([0usize, 0usize], false) + }; + + Ok(egui_TextureSet { + format: format, + pixels: ptr, + id: id.into(), + offset: offset, + subRegion: sub_region, + size: size, + }) +} + +fn make_native_full_output( + ctx: &Context, + input: egui::FullOutput, + draw_scale: f32, +) -> Result { + let primitives = ctx.tessellate(input.shapes); + let mut numVerts = 0; + let mut numIndices = 0; + for prim in primitives.iter() { + if let epaint::Primitive::Mesh(mesh) = &prim.primitive { + numVerts += mesh.vertices.len(); + numIndices += mesh.indices.len(); + } else { + return Err("Only mesh primitives are supported"); + } + } + + let mut vertex_mem: Vec = Vec::with_capacity(numVerts); + let mut index_mem: Vec = Vec::with_capacity(numIndices); + let clipped_primitives: Vec<_> = primitives + .into_iter() + .map(|prim| convert_primitive(prim, &mut vertex_mem, &mut index_mem, draw_scale).unwrap()) + .collect(); + + let mut image_mem: Vec = Vec::new(); + let texture_sets: Vec<_> = input + .textures_delta + .set + .into_iter() + .map(|pair| convert_texture_set(pair.0, pair.1, &mut image_mem).unwrap()) + .collect(); + + let texture_frees: Vec = input + .textures_delta + .free + .into_iter() + .map(|id| id.into()) + .collect(); + + let full_output = egui_FullOutput { + numPrimitives: clipped_primitives.len(), + primitives: clipped_primitives.as_ptr(), + textureUpdates: egui_TextureUpdates { + sets: texture_sets.as_ptr(), + numSets: texture_sets.len(), + frees: texture_frees.as_ptr(), + numFrees: texture_frees.len(), + }, + }; + + Ok(NativeFullOutput { + clipped_primitives: clipped_primitives, + texture_sets: texture_sets, + texture_frees: texture_frees, + vertex_mem: vertex_mem, + index_mem: index_mem, + image_mem: image_mem, + full_output: full_output, + }) +} + +impl Drop for Renderer { + fn drop(&mut self) { + unsafe { + gfx_EguiRenderer_destroy(self.egui_renderer); + } + } +} + +impl Renderer { + pub fn new() -> Self { + unsafe { + Self { + egui_renderer: gfx_EguiRenderer_create(), + } + } + } + + pub fn render( + self: &Self, + ctx: &egui::Context, + egui_output: egui::FullOutput, + queue: *const gfx_DrawQueuePtr, + draw_scale: f32, + ) { + unsafe { + let native_egui_output = make_native_full_output(ctx, egui_output, draw_scale).unwrap(); + gfx_EguiRenderer_render(self.egui_renderer, &native_egui_output.full_output, queue); + } + } +} diff --git a/src/gfx/egui/src/standalone_test.rs b/src/gfx/egui/src/standalone_test.rs new file mode 100644 index 0000000000..d36f20473e --- /dev/null +++ b/src/gfx/egui/src/standalone_test.rs @@ -0,0 +1,74 @@ +use super::*; +use crate::Renderer; +use egui::RichText; +use std::sync::Mutex; + +struct App { + pub ctx: egui::Context, + pub renderer: Renderer, +} + +impl Default for App { + fn default() -> Self { + Self { + ctx: egui::Context::default(), + renderer: Renderer::new(), + } + } +} + +#[derive(Default)] +struct State { + pub color_test: color_test::ColorTest, +} + +lazy_static! { + static ref STATE: Mutex = Mutex::new(State::default()); + static ref APP: Mutex = Mutex::new(App::default()); +} + +#[no_mangle] +pub unsafe extern "C" fn render_egui_test_frame( + context: *mut gfx_Context, + queue: *mut gfx_DrawQueuePtr, + delta_time: f32, +) { + use egui::Color32; + + let app = APP.lock().unwrap(); + let mut input = egui::RawInput::default(); + + let window = gfx_Context_getWindow(context); + let screen_rect_size = gfx_Window_getVirtualDrawableSize_ext(window); + input.screen_rect = Some(egui::Rect { + min: egui::pos2(0.0, 0.0), + max: egui::pos2(screen_rect_size.x, screen_rect_size.y), + }); + + let draw_scale_vec = gfx_Window_getDrawScale_ext(window); + let draw_scale = f32::max(draw_scale_vec.x, draw_scale_vec.y); + input.pixels_per_point = Some(draw_scale); + + let full_output = app.ctx.run(input, |ctx| { + egui::CentralPanel::default().show(ctx, |ui| { + let mut state = STATE.lock().unwrap(); + egui::ScrollArea::both() + .auto_shrink([false; 2]) + .show(ui, |ui| { + let fps = 1.0 / delta_time; + ui.horizontal_wrapped(|ui| { + ui.label(RichText::new("FPS:")); + ui.label(RichText::from(format!("{}", fps)).color(if fps > 110.0 { + Color32::GREEN + } else { + Color32::RED + })); + }); + state.color_test.ui(ui); + }); + }); + }); + + app.renderer + .render(&app.ctx, full_output, queue, draw_scale); +} diff --git a/src/gfx/egui/test.cpp b/src/gfx/egui/test.cpp new file mode 100644 index 0000000000..97f62aa745 --- /dev/null +++ b/src/gfx/egui/test.cpp @@ -0,0 +1,67 @@ +#include +#include +#include +#include +#include +#include +#include "egui_render_pass.hpp" +#include "rust_interop.hpp" + +extern "C" { +void render_egui_test_frame(gfx::Context &context, gfx::DrawQueuePtr &queue, float deltaTime); +} + +using namespace gfx; +int main() { + Window wnd; + wnd.init(); + + Context ctx; + ctx.init(wnd); + + // Just for clearing + Renderer renderer(ctx); + DrawQueuePtr queue = std::make_shared(); + ViewPtr view = std::make_shared(); + + Loop loop; + float deltaTime; + std::vector events; + + egui::Input eguiInput{}; + bool quit = false; + + PipelineSteps pipelineSteps = { + EguiRenderPass::createPipelineStep(queue), + }; + + while (!quit) { + if (loop.beginFrame(1.0f / 120.0f, deltaTime)) { + wnd.pollEvents(events); + for (auto &event : events) { + if (event.type == SDL_MOUSEMOTION) { + eguiInput.cursorPosition[0] = event.motion.x; + eguiInput.cursorPosition[1] = event.motion.y; + } else if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP) { + eguiInput.cursorPosition[0] = event.button.x; + eguiInput.cursorPosition[1] = event.button.y; + if (event.button.state == SDL_PRESSED) + eguiInput.mouseButton |= SDL_BUTTON(event.button.button); + else + eguiInput.mouseButton &= ~SDL_BUTTON(event.button.button); + } else if (event.type == SDL_QUIT) + quit = true; + } + + queue->clear(); + render_egui_test_frame(ctx, queue, deltaTime); + + ctx.resizeMainOutputConditional(wnd.getDrawableSize()); + ctx.beginFrame(); + renderer.beginFrame(); + renderer.render(view, pipelineSteps); + renderer.endFrame(); + ctx.endFrame(); + } + } +} diff --git a/src/gfx/fmt.hpp b/src/gfx/fmt.hpp index bca5f60aa7..8c29610d69 100644 --- a/src/gfx/fmt.hpp +++ b/src/gfx/fmt.hpp @@ -3,6 +3,7 @@ #include "linalg.hpp" #include +#include template struct fmt::formatter> { constexpr auto parse(format_parse_context &ctx) -> decltype(ctx.begin()) { diff --git a/src/gfx/linalg.hpp b/src/gfx/linalg.hpp index 20dfe44d25..69e769dae8 100644 --- a/src/gfx/linalg.hpp +++ b/src/gfx/linalg.hpp @@ -2,6 +2,7 @@ #define GFX_LINALG #include +#include namespace gfx { using namespace linalg::aliases; diff --git a/src/gfx/mesh.hpp b/src/gfx/mesh.hpp index 4bada3e5a1..50bccba8ff 100644 --- a/src/gfx/mesh.hpp +++ b/src/gfx/mesh.hpp @@ -11,6 +11,7 @@ namespace gfx { +///
struct MeshVertexAttribute { std::string name; uint8_t numComponents; @@ -32,6 +33,7 @@ struct MeshVertexAttribute { } }; +///
struct MeshFormat { PrimitiveType primitiveType = PrimitiveType::TriangleList; WindingOrder windingOrder = WindingOrder::CCW; @@ -48,6 +50,7 @@ struct MeshFormat { } }; +///
struct MeshContextData : public ContextData { MeshFormat format; size_t numVertices = 0; @@ -64,6 +67,7 @@ struct MeshContextData : public ContextData { } }; +///
struct Mesh final : public TWithContextData { private: MeshFormat format; diff --git a/src/gfx/params.cpp b/src/gfx/params.cpp index d631ea4e2e..8830e585fc 100644 --- a/src/gfx/params.cpp +++ b/src/gfx/params.cpp @@ -8,43 +8,49 @@ namespace gfx { -size_t packParamVariant(uint8_t *outData, size_t outLength, const ParamVariant &variant) { - struct Visitor { - uint8_t *outData{}; - size_t outLength{}; - size_t operator()(const float &arg) { - size_t len = sizeof(float) * 1; - assert(len <= outLength); - memcpy(outData, &arg, len); - return len; - } - size_t operator()(const float2 &arg) { - size_t len = sizeof(float) * 2; - assert(len <= outLength); - memcpy(outData, &arg.x, len); - return len; - } - size_t operator()(const float3 &arg) { - size_t len = sizeof(float) * 3; - assert(len <= outLength); - memcpy(outData, &arg.x, len); - return len; - } - size_t operator()(const float4 &arg) { - size_t len = sizeof(float) * 4; - assert(len <= outLength); - memcpy(outData, &arg.x, len); - return len; - } - size_t operator()(const float4x4 &arg) { - size_t len = sizeof(float) * 16; - assert(len <= outLength); - packFloat4x4(arg, (float *)outData); - return len; - } - size_t operator()(std::monostate) { return 0; } +struct PackParamVisitor { + uint8_t *outData{}; + size_t outLength{}; + + size_t operator()(const uint32_t &arg) { return packPlain(arg); } + size_t operator()(const float &arg) { return packPlain(arg); } + size_t operator()(const float2 &arg) { + size_t len = sizeof(float) * 2; + assert(len <= outLength); + memcpy(outData, &arg.x, len); + return len; + } + size_t operator()(const float3 &arg) { + size_t len = sizeof(float) * 3; + assert(len <= outLength); + memcpy(outData, &arg.x, len); + return len; + } + size_t operator()(const float4 &arg) { + size_t len = sizeof(float) * 4; + assert(len <= outLength); + memcpy(outData, &arg.x, len); + return len; + } + size_t operator()(const float4x4 &arg) { + size_t len = sizeof(float) * 16; + assert(len <= outLength); + packFloat4x4(arg, (float *)outData); + return len; + } + + template size_t packPlain(const T &val) { + size_t len = sizeof(T); + assert(len <= outLength); + memcpy(outData, &val, len); + return len; + } - } visitor{outData, outLength}; + size_t operator()(std::monostate) { return 0; } +}; + +size_t packParamVariant(uint8_t *outData, size_t outLength, const ParamVariant &variant) { + PackParamVisitor visitor{outData, outLength}; return std::visit(visitor, variant); } @@ -65,6 +71,12 @@ FieldType getParamVariantType(const ParamVariant &variant) { result = FieldType(ShaderFieldBaseType::Float32, 4); } else if constexpr (std::is_same_v) { result = FieldType(ShaderFieldBaseType::Float32, FieldType::Float4x4Components); + } else if constexpr (std::is_same_v) { + result = FieldType(ShaderFieldBaseType::UInt32, 1); + } else if constexpr (std::is_same_v) { + result = FieldType(ShaderFieldBaseType::UInt16, 1); + } else if constexpr (std::is_same_v) { + result = FieldType(ShaderFieldBaseType::UInt8, 1); } else { throw std::logic_error(fmt::format("Type {} not suported by ParamVariant", NAMEOF_TYPE(T))); } diff --git a/src/gfx/params.hpp b/src/gfx/params.hpp index eea18e7e58..44d6312164 100644 --- a/src/gfx/params.hpp +++ b/src/gfx/params.hpp @@ -12,7 +12,7 @@ namespace gfx { -typedef std::variant ParamVariant; +typedef std::variant ParamVariant; struct TextureParameter { TexturePtr texture; diff --git a/src/gfx/pipeline_step.hpp b/src/gfx/pipeline_step.hpp index 1b623f9939..a606d6b9a2 100644 --- a/src/gfx/pipeline_step.hpp +++ b/src/gfx/pipeline_step.hpp @@ -8,6 +8,8 @@ namespace gfx { enum class SortMode { + // Keep queue ordering, + Queue, // Optimal for batching Batch, // For transparent object rendering diff --git a/src/gfx/renderer.cpp b/src/gfx/renderer.cpp index dd7146a614..7a170aece7 100644 --- a/src/gfx/renderer.cpp +++ b/src/gfx/renderer.cpp @@ -296,6 +296,8 @@ struct RendererImpl final : public ContextData { float4x4 projMatrix = viewData.projectionMatrix = viewPtr->getProjectionMatrix(viewSize); viewDrawData.setParam("proj", projMatrix); viewDrawData.setParam("invProj", linalg::inverse(projMatrix)); + viewDrawData.setParam("viewport", + float4(float(viewport.x), float(viewport.y), float(viewport.width), float(viewport.height))); DynamicWGPUBuffer &viewBuffer = viewData.viewBuffers.allocateBuffer(viewBufferLayout.size); viewBuffer.resize(context.wgpuDevice, viewBufferLayout.size, WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst, @@ -425,13 +427,17 @@ struct RendererImpl final : public ContextData { desc.entries = entries.data(); desc.entryCount = entries.size(); desc.layout = layout; - return wgpuDeviceCreateBindGroup(device, &desc); + + WGPUBindGroup result = wgpuDeviceCreateBindGroup(device, &desc); + assert(result); + + return result; } void fillInstanceBuffer(DynamicWGPUBuffer &instanceBuffer, CachedPipeline &cachedPipeline, View *view) { size_t alignedObjectBufferSize = alignToArrayBounds(cachedPipeline.objectBufferLayout.size, cachedPipeline.objectBufferLayout.maxAlignment); - size_t numObjects = cachedPipeline.drawables.size(); + size_t numObjects = cachedPipeline.drawablesSorted.size(); size_t instanceBufferLength = numObjects * alignedObjectBufferSize; instanceBuffer.resize(context.wgpuDevice, instanceBufferLength, WGPUBufferUsage_Storage | WGPUBufferUsage_CopyDst, "objects"); @@ -544,13 +550,22 @@ struct RendererImpl final : public ContextData { // Sort drawables based on mesh/texture bindings for (auto &drawable : cachedPipeline.drawables) { drawable->mesh->createContextDataConditional(context); + + // Filter out empty meshes here + if (drawable->mesh->contextData->numVertices == 0) + continue; + addFrameReference(drawable->mesh->contextData); SortableDrawable sortableDrawable = createSortableDrawable(cachedPipeline, *drawable); - auto comparison = [](const SortableDrawable &left, const SortableDrawable &right) { return left.key < right.key; }; - auto it = std::upper_bound(drawablesSorted.begin(), drawablesSorted.end(), sortableDrawable, comparison); - drawablesSorted.insert(it, sortableDrawable); + if (step.sortMode == SortMode::Queue) { + drawablesSorted.push_back(sortableDrawable); + } else { + auto comparison = [](const SortableDrawable &left, const SortableDrawable &right) { return left.key < right.key; }; + auto it = std::upper_bound(drawablesSorted.begin(), drawablesSorted.end(), sortableDrawable, comparison); + drawablesSorted.insert(it, sortableDrawable); + } } if (step.sortMode == SortMode::BackToFront) { @@ -612,7 +627,11 @@ struct RendererImpl final : public ContextData { textureBindGroupDesc.layout = cachedPipeline.bindGroupLayouts[1]; textureBindGroupDesc.entries = entries.data(); textureBindGroupDesc.entryCount = entries.size(); - return wgpuDeviceCreateBindGroup(context.wgpuDevice, &textureBindGroupDesc); + + WGPUBindGroup result = wgpuDeviceCreateBindGroup(context.wgpuDevice, &textureBindGroupDesc); + assert(result); + + return result; } void renderDrawables(RenderDrawablesStep &step, ViewPtr view, Rect viewport, WGPUBuffer viewBuffer) { @@ -679,12 +698,12 @@ struct RendererImpl final : public ContextData { for (auto &pair : pipelineCache) { CachedPipeline &cachedPipeline = *pair.second.get(); - if (cachedPipeline.drawables.empty()) + if (cachedPipeline.drawablesSorted.empty()) continue; size_t drawBufferLength = alignToArrayBounds(cachedPipeline.objectBufferLayout.size, cachedPipeline.objectBufferLayout.maxAlignment) * - cachedPipeline.drawables.size(); + cachedPipeline.drawablesSorted.size(); DynamicWGPUBuffer &instanceBuffer = cachedPipeline.instanceBufferPool.allocateBuffer(drawBufferLength); fillInstanceBuffer(instanceBuffer, cachedPipeline, view.get()); @@ -706,6 +725,7 @@ struct RendererImpl final : public ContextData { onFrameCleanup([textureBindGroup]() { wgpuBindGroupRelease(textureBindGroup); }); MeshContextData *meshContextData = drawGroup.key.meshData; + assert(meshContextData->vertexBuffer); wgpuRenderPassEncoderSetVertexBuffer(passEncoder, 0, meshContextData->vertexBuffer, 0, meshContextData->vertexBufferLength); @@ -791,9 +811,10 @@ struct RendererImpl final : public ContextData { } } + // Update default texture coordinates based on material if (material) { for (auto &pair : material->parameters.texture) { - textureBindingLayoutBuilder.addOrUpdateSlot(pair.first, pair.second.defaultTexcoordBinding); + textureBindingLayoutBuilder.tryUpdateSlot(pair.first, pair.second.defaultTexcoordBinding); } } @@ -871,6 +892,7 @@ struct RendererImpl final : public ContextData { objectEntry.buffer.hasDynamicOffset = false; WGPUBindGroupLayoutDescriptor bindGroupLayoutDesc = {}; + bindGroupLayoutDesc.label = "batch"; bindGroupLayoutDesc.entries = bindGroupLayoutEntries.data(); bindGroupLayoutDesc.entryCount = bindGroupLayoutEntries.size(); return wgpuDeviceCreateBindGroupLayout(context.wgpuDevice, &bindGroupLayoutDesc); @@ -898,6 +920,7 @@ struct RendererImpl final : public ContextData { } WGPUBindGroupLayoutDescriptor bindGroupLayoutDesc = {}; + bindGroupLayoutDesc.label = "textures"; bindGroupLayoutDesc.entries = bindGroupLayoutEntries.data(); bindGroupLayoutDesc.entryCount = bindGroupLayoutEntries.size(); return wgpuDeviceCreateBindGroupLayout(context.wgpuDevice, &bindGroupLayoutDesc); @@ -1035,6 +1058,8 @@ Renderer::Renderer(Context &context) { impl->initializeContextData(); } +Context &Renderer::getContext() { return impl->context; } + void Renderer::render(std::vector views, const PipelineSteps &pipelineSteps) { impl->renderViews(views, pipelineSteps); } void Renderer::render(ViewPtr view, const PipelineSteps &pipelineSteps) { impl->renderView(view, pipelineSteps); } void Renderer::setMainOutput(const MainOutput &output) { diff --git a/src/gfx/renderer.hpp b/src/gfx/renderer.hpp index 0ff1afde10..f1e04d293d 100644 --- a/src/gfx/renderer.hpp +++ b/src/gfx/renderer.hpp @@ -23,6 +23,9 @@ struct Renderer { public: Renderer(Context &context); + + Context &getContext(); + void render(std::vector views, const PipelineSteps &pipelineSteps); void render(ViewPtr view, const PipelineSteps &pipelineSteps); void setMainOutput(const MainOutput &output); diff --git a/src/gfx/renderer_types.hpp b/src/gfx/renderer_types.hpp index 8bc9101f93..de9e3b581d 100644 --- a/src/gfx/renderer_types.hpp +++ b/src/gfx/renderer_types.hpp @@ -2,6 +2,7 @@ #define GFX_RENDERER_TYPES #include "gfx_wgpu.hpp" +#include "resizable_item_pool.hpp" #include #include @@ -85,53 +86,7 @@ struct DynamicWGPUBuffer { } }; -struct DynamicWGPUBufferPool { - std::vector buffers; - std::vector freeList; - - void reset() { - freeList.clear(); - for (size_t i = 0; i < buffers.size(); i++) { - freeList.push_back(i); - } - } - - DynamicWGPUBuffer &allocateBufferNew() { return buffers.emplace_back(); } - - DynamicWGPUBuffer &allocateBufferAny() { - if (freeList.size() > 0) { - size_t bufferIndex = freeList.back(); - freeList.pop_back(); - return buffers[bufferIndex]; - } else { - return allocateBufferNew(); - } - } - - DynamicWGPUBuffer &allocateBuffer(size_t size) { - int64_t smallestDelta = INT64_MAX; - decltype(freeList)::iterator targetFreeListIt = freeList.end(); - for (auto it = freeList.begin(); it != freeList.end(); ++it) { - size_t bufferIndex = *it; - auto &buffer = buffers[bufferIndex]; - int64_t delta = buffer.getCapacity() - size; - if (delta >= 0) { - if (delta < smallestDelta) { - smallestDelta = delta; - targetFreeListIt = it; - } - } - } - - if (targetFreeListIt != freeList.end()) { - auto bufferIndex = *targetFreeListIt; - freeList.erase(targetFreeListIt); - return buffers[bufferIndex]; - } else { - return allocateBufferNew(); - } - } -}; +typedef ResizableItemPool DynamicWGPUBufferPool; } // namespace gfx diff --git a/src/gfx/resizable_item_pool.hpp b/src/gfx/resizable_item_pool.hpp new file mode 100644 index 0000000000..f49d6b01f1 --- /dev/null +++ b/src/gfx/resizable_item_pool.hpp @@ -0,0 +1,70 @@ +#ifndef B32DBC90_5468_49DD_AFEA_C1D0865FED52 +#define B32DBC90_5468_49DD_AFEA_C1D0865FED52 + +#include + +namespace gfx { + +template struct ResizableItemOps { + size_t getCapacity(T &item) const { return item.getCapacity(); } + void init(T &item) {} +}; + +// Keeps a pool of resizable objects +// When an item with a specific size is requested +// it will try to return the smallest pooled item first +template > struct ResizableItemPool { + static inline TOps ops; + std::vector buffers; + std::vector freeList; + + void reset() { + freeList.clear(); + for (size_t i = 0; i < buffers.size(); i++) { + freeList.push_back(i); + } + } + + T &allocateBufferNew() { + T &item = buffers.emplace_back(); + ops.init(item); + return item; + } + + T &allocateBufferAny() { + if (freeList.size() > 0) { + size_t bufferIndex = freeList.back(); + freeList.pop_back(); + return buffers[bufferIndex]; + } else { + return allocateBufferNew(); + } + } + + T &allocateBuffer(size_t size) { + int64_t smallestDelta = INT64_MAX; + typename decltype(freeList)::iterator targetFreeListIt = freeList.end(); + for (auto it = freeList.begin(); it != freeList.end(); ++it) { + size_t bufferIndex = *it; + auto &buffer = buffers[bufferIndex]; + int64_t delta = ops.getCapacity(buffer) - size; + if (delta >= 0) { + if (delta < smallestDelta) { + smallestDelta = delta; + targetFreeListIt = it; + } + } + } + + if (targetFreeListIt != freeList.end()) { + auto bufferIndex = *targetFreeListIt; + freeList.erase(targetFreeListIt); + return buffers[bufferIndex]; + } else { + return allocateBufferNew(); + } + } +}; +} // namespace gfx + +#endif /* B32DBC90_5468_49DD_AFEA_C1D0865FED52 */ diff --git a/src/gfx/rust/build/.gitignore b/src/gfx/rust/build/.gitignore new file mode 100644 index 0000000000..eb5a316cbd --- /dev/null +++ b/src/gfx/rust/build/.gitignore @@ -0,0 +1 @@ +target diff --git a/src/gfx/rust/build/Cargo.toml b/src/gfx/rust/build/Cargo.toml new file mode 100644 index 0000000000..913f2538da --- /dev/null +++ b/src/gfx/rust/build/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "gfx-build" +version = "0.1.0" +edition = "2021" + +[dependencies] +bindgen = "0.60.1" diff --git a/src/gfx/rust/build/README.md b/src/gfx/rust/build/README.md new file mode 100644 index 0000000000..0a10c12f83 --- /dev/null +++ b/src/gfx/rust/build/README.md @@ -0,0 +1,3 @@ +# gfx-rust-build + +Provides shared rust code to set up bindgen to generate usable bindings to gfx \ No newline at end of file diff --git a/src/gfx/rust/build/src/lib.rs b/src/gfx/rust/build/src/lib.rs new file mode 100644 index 0000000000..48dbdd8348 --- /dev/null +++ b/src/gfx/rust/build/src/lib.rs @@ -0,0 +1,31 @@ +extern crate bindgen; + +pub fn setup_bindgen_for_gfx(gfx_path: &str, builder: bindgen::Builder) -> bindgen::Builder { + let egui_path = format!("{}/egui", gfx_path); + let deps_path = format!("{}/../../deps", gfx_path); + + println!("cargo:rerun-if-changed={}/rust_interop.hpp", gfx_path); + println!("cargo:rerun-if-changed={}/rust_interop.hpp", egui_path); + println!("cargo:rerun-if-changed={}/renderer.hpp", egui_path); + println!("cargo:rerun-if-changed={}/egui_types.hpp", egui_path); + + builder + .allowlist_function("gfx::.*") + .allowlist_function("gfx_.*") + .allowlist_type("gfx::.*") + .blocklist_type("std::.*") + .blocklist_type("__gnu_cxx::new.*") + .opaque_type("std::shared_ptr.*") + .opaque_type("std::weak_ptr.*") + .opaque_type("std::unique_ptr.*") + .opaque_type("std::vector.*") + .opaque_type("std::string.*") + .clang_arg("-DRUST_BINDGEN=1") + .clang_arg("-DWEBGPU_NATIVE=1") + .clang_arg(format!("-I{}", deps_path)) + .clang_arg(format!("-I{}/nameof/include", deps_path)) + .clang_arg(format!("-I{}/wgpu-native/ffi", gfx_path)) + .clang_arg("-std=c++17") + .rust_target(bindgen::RustTarget::Nightly) // Required for thiscall on x86 windows + .size_t_is_usize(true) +} diff --git a/src/gfx/rust_interop.cpp b/src/gfx/rust_interop.cpp new file mode 100644 index 0000000000..65b089a7b3 --- /dev/null +++ b/src/gfx/rust_interop.cpp @@ -0,0 +1,7 @@ +#include "rust_interop.hpp" + +using namespace gfx; +extern "C" { +gfx::float2 gfx_Window_getVirtualDrawableSize_ext(gfx::Window *window) { return window->getVirtualDrawableSize(); } +gfx::float2 gfx_Window_getDrawScale_ext(gfx::Window *window) { return window->getDrawScale(); } +} diff --git a/src/gfx/rust_interop.hpp b/src/gfx/rust_interop.hpp new file mode 100644 index 0000000000..2b42579872 --- /dev/null +++ b/src/gfx/rust_interop.hpp @@ -0,0 +1,57 @@ +#ifndef BFB13E29_4B2D_433E_905E_DAC3525F8FAD +#define BFB13E29_4B2D_433E_905E_DAC3525F8FAD + +#include "linalg.hpp" +#include "context.hpp" +#include "window.hpp" + +namespace gfx { +struct Context; +struct Renderer; +struct Window; + +#ifdef RUST_BINDGEN +///
+struct float2 { + float x, y; + char padding[16]; +}; +///
+struct float3 { + float x, y, z; + char padding[20]; +}; +///
+struct float4 { + float x, y, z, w; + char padding[16]; +}; +///
+struct int2 { + int32_t x, y; + char padding[16]; +}; +///
+struct int3 { + int32_t x, y, z; + char padding[20]; +}; +///
+struct int4 { + int32_t x, y, z, w; + char padding[16]; +}; +#endif +} // namespace gfx + +// External functions to work around an issue where using complex +// return values inside member functions the stack is messed up +extern "C" { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreturn-type-c-linkage" +gfx::float2 gfx_Window_getVirtualDrawableSize_ext(gfx::Window *window); +gfx::float2 gfx_Window_getDrawScale_ext(gfx::Window *window); +#pragma clang diagnostic push +} + +#endif /* BFB13E29_4B2D_433E_905E_DAC3525F8FAD */ diff --git a/src/gfx/shader/block.hpp b/src/gfx/shader/block.hpp index ece10cd475..50a9992029 100644 --- a/src/gfx/shader/block.hpp +++ b/src/gfx/shader/block.hpp @@ -18,6 +18,7 @@ struct Block { }; using BlockPtr = UniquePtr; +// Source block injected directly into the generated shader struct Direct : public Block { String code; @@ -28,6 +29,17 @@ struct Direct : public Block { BlockPtr clone() { return std::make_unique(code); } }; +// Source block applied outside of the function body +struct Header : public Block { + String code; + + Header(const char *code) : code(code) {} + Header(const String &code) : code(code) {} + Header(String &&code) : code(code) {} + void apply(GeneratorContext &context) const; + BlockPtr clone() { return std::make_unique(code); } +}; + struct ConvertibleToBlock { UniquePtr block; ConvertibleToBlock(const char *str) { block = std::make_unique(str); } diff --git a/src/gfx/shader/blocks.cpp b/src/gfx/shader/blocks.cpp index 9c0c1d3488..ce8f3c038c 100644 --- a/src/gfx/shader/blocks.cpp +++ b/src/gfx/shader/blocks.cpp @@ -6,6 +6,7 @@ namespace gfx { namespace shader { namespace blocks { void Direct::apply(GeneratorContext &context) const { context.write(code); } +void Header::apply(GeneratorContext &context) const { context.writeHeader(code); } DefaultInterpolation::DefaultInterpolation() { matchPrefixes = { diff --git a/src/gfx/shader/blocks.hpp b/src/gfx/shader/blocks.hpp index c8299d7fec..d35f579d4e 100644 --- a/src/gfx/shader/blocks.hpp +++ b/src/gfx/shader/blocks.hpp @@ -14,7 +14,10 @@ namespace blocks { struct Compound : public Block { std::vector> children; - template Compound(TArgs... args) { (..., children.push_back(ConvertToBlock{}(std::move(args)))); } + template Compound(TArgs... args) { append(std::forward(args)...); } + + template void append(TArgs... args) { (..., children.push_back(ConvertToBlock{}(std::move(args)))); } + template void appendLine(TArgs... args) { append(std::forward(args)..., ";\n"); } void apply(GeneratorContext &context) const { for (auto &c : children) diff --git a/src/gfx/shader/generator.cpp b/src/gfx/shader/generator.cpp index 16c26addbf..24ca7ea0c8 100644 --- a/src/gfx/shader/generator.cpp +++ b/src/gfx/shader/generator.cpp @@ -18,6 +18,7 @@ template static GeneratorError formatError(const char *forma } void GeneratorContext::write(const StringView &str) { result += str; } +void GeneratorContext::writeHeader(const StringView &str) { header += str; } void GeneratorContext::readGlobal(const char *name) { auto it = globals.find(name); @@ -121,7 +122,6 @@ bool GeneratorContext::hasTexture(const char *name, bool defaultTexcoordRequired const TextureDefinition *GeneratorContext::getTexture(const char *name) { auto it = textures.find(name); if (it == textures.end()) { - pushError(formatError("Texture {} does not exist", name)); return nullptr; } else { return &it->second; @@ -131,6 +131,8 @@ const TextureDefinition *GeneratorContext::getTexture(const char *name) { void GeneratorContext::texture(const char *name) { if (const TextureDefinition *texture = getTexture(name)) { result += texture->variableName; + } else { + pushError(formatError("Texture {} does not exist", name)); } } @@ -435,7 +437,7 @@ struct Stage { } return StageOutput{ - globalsHeader + std::move(context.result), + globalsHeader + std::move(context.header) + std::move(context.result), std::move(context.errors), }; } diff --git a/src/gfx/shader/generator.hpp b/src/gfx/shader/generator.hpp index b690f40385..6720bb66c8 100644 --- a/src/gfx/shader/generator.hpp +++ b/src/gfx/shader/generator.hpp @@ -32,6 +32,7 @@ struct IGeneratorDynamicHandler { struct GeneratorContext { String result; + String header; String inputVariableName; String outputVariableName; String globalsVariableName; @@ -48,6 +49,9 @@ struct GeneratorContext { void write(const StringView &str); + // Writes into a separate buffer that is prepended to the combined output of write and all other generated code + void writeHeader(const StringView &str); + void readGlobal(const char *name); void writeGlobal(const char *name, const FieldType &type); diff --git a/src/gfx/shader/textures.hpp b/src/gfx/shader/textures.hpp index 879907fe53..b6c28f4cdd 100644 --- a/src/gfx/shader/textures.hpp +++ b/src/gfx/shader/textures.hpp @@ -41,6 +41,14 @@ struct TextureBindingLayoutBuilder { binding->defaultTexcoordBinding = defaultTexcoordBinding; } + void tryUpdateSlot(const String &name, size_t defaultTexcoordBinding) { + auto it = mapping.find(name); + if (it != mapping.end()) { + auto &binding = layout.bindings[it->second]; + binding.defaultTexcoordBinding = defaultTexcoordBinding; + } + } + TextureBindingLayout &&finalize() { return std::move(layout); } }; } // namespace shader diff --git a/src/gfx/shader/types.hpp b/src/gfx/shader/types.hpp index 9b05772f16..d21e128a2b 100644 --- a/src/gfx/shader/types.hpp +++ b/src/gfx/shader/types.hpp @@ -46,6 +46,8 @@ struct FieldTypes { static inline FieldType Float3{ShaderFieldBaseType::Float32, 3}; static inline FieldType Float4{ShaderFieldBaseType::Float32, 4}; static inline FieldType Float4x4{ShaderFieldBaseType::Float32, FieldType::Float4x4Components}; + static inline FieldType UInt32{ShaderFieldBaseType::UInt32, 1}; + static inline FieldType Int32{ShaderFieldBaseType::Int32, 1}; }; struct NamedField { diff --git a/src/gfx/texture.hpp b/src/gfx/texture.hpp index c5ad37049e..add547636f 100644 --- a/src/gfx/texture.hpp +++ b/src/gfx/texture.hpp @@ -10,6 +10,7 @@ namespace gfx { enum class TextureFormatFlags : uint8_t { + None = 0x0, AutoGenerateMips = 0x01, }; inline bool TextureFormatFlagsContains(TextureFormatFlags left, TextureFormatFlags right) { @@ -75,6 +76,8 @@ struct Texture final : public TWithContextData { const ImmutableSharedBuffer &data = ImmutableSharedBuffer()); void setSamplerState(const SamplerState &samplerState); + ImmutableSharedBuffer getData() { return data; } + int2 getResolution() const { return resolution; } std::shared_ptr clone(); diff --git a/src/gfx/types.hpp b/src/gfx/types.hpp index 789b1d3b02..a59ed7843e 100644 --- a/src/gfx/types.hpp +++ b/src/gfx/types.hpp @@ -61,6 +61,7 @@ struct Rect { static Rect fromCorners(int x0, int y0, int x1, int y1) { return Rect(x0, y0, x1 - x0, y1 - y0); } }; + } // namespace gfx #endif // GFX_TYPES diff --git a/src/gfx/user_data.hpp b/src/gfx/user_data.hpp index d7ea8592fa..8c24b5a112 100644 --- a/src/gfx/user_data.hpp +++ b/src/gfx/user_data.hpp @@ -10,6 +10,7 @@ namespace gfx { // Container for user data while validating expected type +///
struct TypedUserData { private: void *data; diff --git a/src/gfx/window.cpp b/src/gfx/window.cpp index 19cce5bb4f..d183b79384 100644 --- a/src/gfx/window.cpp +++ b/src/gfx/window.cpp @@ -6,6 +6,7 @@ #include #include #include +#include "fmt.hpp" #if GFX_WINDOWS #include @@ -76,12 +77,6 @@ void *Window::getNativeWindowHandle() { #endif } -float2 Window::getDrawScale() const { - float2 windowSize = float2(getSize()); - float2 drawableSize = float2(getDrawableSize()); - return drawableSize / windowSize; -} - int2 Window::getDrawableSize() const { int2 r; #if GFX_APPLE @@ -102,5 +97,19 @@ int2 Window::getSize() const { return r; } +float2 Window::getDrawScale() const { + // DPI for 100% on windows + const float referenceDpi = 96.0f; + + int displayIndex = SDL_GetWindowDisplayIndex(window); + float2 dpi; + float diagonalDpi; + SDL_GetDisplayDPI(displayIndex, &diagonalDpi, &dpi.x, &dpi.y); + + return dpi / referenceDpi; +} + +float2 Window::getVirtualDrawableSize() { return getDrawableSize() / getDrawScale(); } + Window::~Window() { cleanup(); } } // namespace gfx diff --git a/src/gfx/window.hpp b/src/gfx/window.hpp index a5fd793ad5..e094defb9b 100644 --- a/src/gfx/window.hpp +++ b/src/gfx/window.hpp @@ -8,6 +8,7 @@ struct SDL_Window; typedef union SDL_Event SDL_Event; namespace gfx { +///
struct WindowCreationOptions { int width = 1280; int height = 720; @@ -32,6 +33,9 @@ struct Window { // = draw surface size / window size float2 getDrawScale() const; + // = draw surface size / draw scale + float2 getVirtualDrawableSize(); + ~Window(); }; }; // namespace gfx