├── .github ├── FUNDING.yml └── workflows │ ├── cd.yml │ └── ci.yml ├── .gitignore ├── BevyIosGamecenterRust.xcframework ├── .gitignore ├── Info.plist ├── ios-arm64 │ └── Headers │ │ └── BevyIosGamecenterRust │ │ ├── SwiftBridgeCoreGC.h │ │ ├── bevy_ios_gamecenter.h │ │ └── module.modulemap └── ios-arm64_x86_64-simulator │ └── Headers │ └── BevyIosGamecenterRust │ ├── SwiftBridgeCoreGC.h │ ├── bevy_ios_gamecenter.h │ └── module.modulemap ├── CHANGELOG.md ├── LICENSE-APACHE ├── LICENSE-MIT ├── Package.swift ├── README.md ├── Sources └── bevy_ios_gamecenter │ ├── BevyIosGamecenter.swift │ ├── SwiftBridgeCoreGC.swift │ └── bevy_ios_gamecenter.swift ├── Tests └── bevy_ios_gamecenterTests │ └── bevy_ios_gamecenterTests.swift ├── assets ├── demo.gif ├── framework.png └── xcode-spm.png ├── bevy_ios_gamecenter_egui ├── CHANGELOG.md ├── Cargo.toml ├── README.md └── src │ └── lib.rs ├── crate ├── .gitignore ├── .vscode │ └── settings.json ├── Cargo.toml ├── build-rust-release.sh ├── build-rust.sh ├── build.rs ├── generated │ └── .gitignore └── src │ ├── lib.rs │ ├── methods.rs │ ├── native.rs │ ├── plugin.rs │ └── request.rs └── justfile /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: rustunit -------------------------------------------------------------------------------- /.github/workflows/cd.yml: -------------------------------------------------------------------------------- 1 | name: CD-rust 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'rs-*' 7 | 8 | env: 9 | CARGO_TERM_COLOR: always 10 | 11 | jobs: 12 | build: 13 | permissions: 14 | contents: write 15 | runs-on: macos-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | - uses: dtolnay/rust-toolchain@stable 20 | - uses: extractions/setup-just@v1 21 | 22 | - name: Add iOS targets 23 | run: rustup target add aarch64-apple-ios aarch64-apple-ios-sim x86_64-apple-ios 24 | 25 | - name: Rust Cache 26 | uses: Swatinem/rust-cache@v2 27 | with: 28 | workspaces: "./crate" 29 | 30 | - name: make xcframework archive 31 | run: just zip 32 | 33 | - name: Release 34 | uses: softprops/action-gh-release@v2 35 | if: startsWith(github.ref, 'refs/tags/') 36 | with: 37 | prerelease: ${{ contains(github.ref, 'rc') }} 38 | files: | 39 | ./BevyIosGamecenterRust.xcframework.zip 40 | ./BevyIosGamecenterRust.xcframework.sha256.txt -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI-rust 2 | 3 | on: 4 | push: 5 | 6 | env: 7 | CARGO_TERM_COLOR: always 8 | 9 | jobs: 10 | build: 11 | #TODO: run and test on wasm, win and linux 12 | runs-on: macos-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | - uses: dtolnay/rust-toolchain@stable 17 | 18 | - name: Add iOS targets 19 | run: rustup target add aarch64-apple-ios aarch64-apple-ios-sim x86_64-apple-ios 20 | 21 | - name: Rust Cache 22 | uses: Swatinem/rust-cache@v2 23 | with: 24 | workspaces: "./crate" 25 | 26 | # TODO: enable once https://github.com/rust-lang/rust-bindgen/issues/3181 is released 27 | # - name: Check iOS Sim 28 | # run: | 29 | # cd ./crate/ 30 | # cargo c --target=aarch64-apple-ios-sim 31 | # cargo b --target=aarch64-apple-ios-sim 32 | # cargo clippy --target=aarch64-apple-ios-sim 33 | 34 | - name: Check iOS 35 | run: | 36 | cd ./crate/ 37 | cargo c --target=aarch64-apple-ios 38 | cargo b --target=aarch64-apple-ios 39 | cargo clippy --target=aarch64-apple-ios 40 | 41 | - name: Check MacOs 42 | run: | 43 | cd ./crate/ 44 | cargo c 45 | cargo b 46 | cargo clippy 47 | cargo t 48 | 49 | build_egui: 50 | runs-on: macos-latest 51 | 52 | steps: 53 | - uses: actions/checkout@v4 54 | - uses: dtolnay/rust-toolchain@stable 55 | 56 | - name: Add iOS targets 57 | run: rustup target add aarch64-apple-ios aarch64-apple-ios-sim x86_64-apple-ios 58 | 59 | - name: Rust Cache 60 | uses: Swatinem/rust-cache@v2 61 | with: 62 | workspaces: "./bevy_ios_gamecenter_egui" 63 | 64 | # TODO: enable once https://github.com/rust-lang/rust-bindgen/issues/3181 is released 65 | # - name: Check iOS Sim 66 | # run: | 67 | # cd bevy_ios_gamecenter_egui 68 | # cargo c --target=aarch64-apple-ios-sim 69 | # cargo b --target=aarch64-apple-ios-sim 70 | # cargo clippy --target=aarch64-apple-ios-sim 71 | 72 | - name: Check iOS 73 | run: | 74 | cd bevy_ios_gamecenter_egui 75 | cargo c --target=aarch64-apple-ios 76 | cargo b --target=aarch64-apple-ios 77 | cargo clippy --target=aarch64-apple-ios 78 | 79 | - name: Check MacOs 80 | run: | 81 | cd bevy_ios_gamecenter_egui 82 | cargo c 83 | cargo b 84 | cargo clippy 85 | cargo t 86 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | xcuserdata/ 5 | DerivedData/ 6 | .swiftpm/configuration/registries.json 7 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 8 | .netrc 9 | bevy_ios_gamecenter_egui/target 10 | bevy_ios_gamecenter_egui/Cargo.lock 11 | -------------------------------------------------------------------------------- /BevyIosGamecenterRust.xcframework/.gitignore: -------------------------------------------------------------------------------- 1 | libbevy_ios_*.a -------------------------------------------------------------------------------- /BevyIosGamecenterRust.xcframework/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AvailableLibraries 6 | 7 | 8 | BinaryPath 9 | libbevy_ios_gamecenter.a 10 | HeadersPath 11 | Headers 12 | LibraryIdentifier 13 | ios-arm64_x86_64-simulator 14 | LibraryPath 15 | libbevy_ios_gamecenter.a 16 | SupportedArchitectures 17 | 18 | arm64 19 | x86_64 20 | 21 | SupportedPlatform 22 | ios 23 | SupportedPlatformVariant 24 | simulator 25 | 26 | 27 | BinaryPath 28 | libbevy_ios_gamecenter.a 29 | HeadersPath 30 | Headers 31 | LibraryIdentifier 32 | ios-arm64 33 | LibraryPath 34 | libbevy_ios_gamecenter.a 35 | SupportedArchitectures 36 | 37 | arm64 38 | 39 | SupportedPlatform 40 | ios 41 | 42 | 43 | CFBundlePackageType 44 | XFWK 45 | XCFrameworkFormatVersion 46 | 1.0 47 | 48 | 49 | -------------------------------------------------------------------------------- /BevyIosGamecenterRust.xcframework/ios-arm64/Headers/BevyIosGamecenterRust/SwiftBridgeCoreGC.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | typedef struct RustStr { uint8_t* const start; uintptr_t len; } RustStr; 4 | typedef struct __private__FfiSlice { void* const start; uintptr_t len; } __private__FfiSlice; 5 | void* __swift_bridge__null_pointer(void); 6 | 7 | 8 | typedef struct __private__OptionU8 { uint8_t val; bool is_some; } __private__OptionU8; 9 | typedef struct __private__OptionI8 { int8_t val; bool is_some; } __private__OptionI8; 10 | typedef struct __private__OptionU16 { uint16_t val; bool is_some; } __private__OptionU16; 11 | typedef struct __private__OptionI16 { int16_t val; bool is_some; } __private__OptionI16; 12 | typedef struct __private__OptionU32 { uint32_t val; bool is_some; } __private__OptionU32; 13 | typedef struct __private__OptionI32 { int32_t val; bool is_some; } __private__OptionI32; 14 | typedef struct __private__OptionU64 { uint64_t val; bool is_some; } __private__OptionU64; 15 | typedef struct __private__OptionI64 { int64_t val; bool is_some; } __private__OptionI64; 16 | typedef struct __private__OptionUsize { uintptr_t val; bool is_some; } __private__OptionUsize; 17 | typedef struct __private__OptionIsize { intptr_t val; bool is_some; } __private__OptionIsize; 18 | typedef struct __private__OptionF32 { float val; bool is_some; } __private__OptionF32; 19 | typedef struct __private__OptionF64 { double val; bool is_some; } __private__OptionF64; 20 | typedef struct __private__OptionBool { bool val; bool is_some; } __private__OptionBool; 21 | 22 | void* __swift_bridge__$Vec_u8$new(); 23 | void __swift_bridge__$Vec_u8$_free(void* const vec); 24 | uintptr_t __swift_bridge__$Vec_u8$len(void* const vec); 25 | void __swift_bridge__$Vec_u8$push(void* const vec, uint8_t val); 26 | __private__OptionU8 __swift_bridge__$Vec_u8$pop(void* const vec); 27 | __private__OptionU8 __swift_bridge__$Vec_u8$get(void* const vec, uintptr_t index); 28 | __private__OptionU8 __swift_bridge__$Vec_u8$get_mut(void* const vec, uintptr_t index); 29 | uint8_t const * __swift_bridge__$Vec_u8$as_ptr(void* const vec); 30 | 31 | void* __swift_bridge__$Vec_u16$new(); 32 | void __swift_bridge__$Vec_u16$_free(void* const vec); 33 | uintptr_t __swift_bridge__$Vec_u16$len(void* const vec); 34 | void __swift_bridge__$Vec_u16$push(void* const vec, uint16_t val); 35 | __private__OptionU16 __swift_bridge__$Vec_u16$pop(void* const vec); 36 | __private__OptionU16 __swift_bridge__$Vec_u16$get(void* const vec, uintptr_t index); 37 | __private__OptionU16 __swift_bridge__$Vec_u16$get_mut(void* const vec, uintptr_t index); 38 | uint16_t const * __swift_bridge__$Vec_u16$as_ptr(void* const vec); 39 | 40 | void* __swift_bridge__$Vec_u32$new(); 41 | void __swift_bridge__$Vec_u32$_free(void* const vec); 42 | uintptr_t __swift_bridge__$Vec_u32$len(void* const vec); 43 | void __swift_bridge__$Vec_u32$push(void* const vec, uint32_t val); 44 | __private__OptionU32 __swift_bridge__$Vec_u32$pop(void* const vec); 45 | __private__OptionU32 __swift_bridge__$Vec_u32$get(void* const vec, uintptr_t index); 46 | __private__OptionU32 __swift_bridge__$Vec_u32$get_mut(void* const vec, uintptr_t index); 47 | uint32_t const * __swift_bridge__$Vec_u32$as_ptr(void* const vec); 48 | 49 | void* __swift_bridge__$Vec_u64$new(); 50 | void __swift_bridge__$Vec_u64$_free(void* const vec); 51 | uintptr_t __swift_bridge__$Vec_u64$len(void* const vec); 52 | void __swift_bridge__$Vec_u64$push(void* const vec, uint64_t val); 53 | __private__OptionU64 __swift_bridge__$Vec_u64$pop(void* const vec); 54 | __private__OptionU64 __swift_bridge__$Vec_u64$get(void* const vec, uintptr_t index); 55 | __private__OptionU64 __swift_bridge__$Vec_u64$get_mut(void* const vec, uintptr_t index); 56 | uint64_t const * __swift_bridge__$Vec_u64$as_ptr(void* const vec); 57 | 58 | void* __swift_bridge__$Vec_usize$new(); 59 | void __swift_bridge__$Vec_usize$_free(void* const vec); 60 | uintptr_t __swift_bridge__$Vec_usize$len(void* const vec); 61 | void __swift_bridge__$Vec_usize$push(void* const vec, uintptr_t val); 62 | __private__OptionUsize __swift_bridge__$Vec_usize$pop(void* const vec); 63 | __private__OptionUsize __swift_bridge__$Vec_usize$get(void* const vec, uintptr_t index); 64 | __private__OptionUsize __swift_bridge__$Vec_usize$get_mut(void* const vec, uintptr_t index); 65 | uintptr_t const * __swift_bridge__$Vec_usize$as_ptr(void* const vec); 66 | 67 | void* __swift_bridge__$Vec_i8$new(); 68 | void __swift_bridge__$Vec_i8$_free(void* const vec); 69 | uintptr_t __swift_bridge__$Vec_i8$len(void* const vec); 70 | void __swift_bridge__$Vec_i8$push(void* const vec, int8_t val); 71 | __private__OptionI8 __swift_bridge__$Vec_i8$pop(void* const vec); 72 | __private__OptionI8 __swift_bridge__$Vec_i8$get(void* const vec, uintptr_t index); 73 | __private__OptionI8 __swift_bridge__$Vec_i8$get_mut(void* const vec, uintptr_t index); 74 | int8_t const * __swift_bridge__$Vec_i8$as_ptr(void* const vec); 75 | 76 | void* __swift_bridge__$Vec_i16$new(); 77 | void __swift_bridge__$Vec_i16$_free(void* const vec); 78 | uintptr_t __swift_bridge__$Vec_i16$len(void* const vec); 79 | void __swift_bridge__$Vec_i16$push(void* const vec, int16_t val); 80 | __private__OptionI16 __swift_bridge__$Vec_i16$pop(void* const vec); 81 | __private__OptionI16 __swift_bridge__$Vec_i16$get(void* const vec, uintptr_t index); 82 | __private__OptionI16 __swift_bridge__$Vec_i16$get_mut(void* const vec, uintptr_t index); 83 | int16_t const * __swift_bridge__$Vec_i16$as_ptr(void* const vec); 84 | 85 | void* __swift_bridge__$Vec_i32$new(); 86 | void __swift_bridge__$Vec_i32$_free(void* const vec); 87 | uintptr_t __swift_bridge__$Vec_i32$len(void* const vec); 88 | void __swift_bridge__$Vec_i32$push(void* const vec, int32_t val); 89 | __private__OptionI32 __swift_bridge__$Vec_i32$pop(void* const vec); 90 | __private__OptionI32 __swift_bridge__$Vec_i32$get(void* const vec, uintptr_t index); 91 | __private__OptionI32 __swift_bridge__$Vec_i32$get_mut(void* const vec, uintptr_t index); 92 | int32_t const * __swift_bridge__$Vec_i32$as_ptr(void* const vec); 93 | 94 | void* __swift_bridge__$Vec_i64$new(); 95 | void __swift_bridge__$Vec_i64$_free(void* const vec); 96 | uintptr_t __swift_bridge__$Vec_i64$len(void* const vec); 97 | void __swift_bridge__$Vec_i64$push(void* const vec, int64_t val); 98 | __private__OptionI64 __swift_bridge__$Vec_i64$pop(void* const vec); 99 | __private__OptionI64 __swift_bridge__$Vec_i64$get(void* const vec, uintptr_t index); 100 | __private__OptionI64 __swift_bridge__$Vec_i64$get_mut(void* const vec, uintptr_t index); 101 | int64_t const * __swift_bridge__$Vec_i64$as_ptr(void* const vec); 102 | 103 | void* __swift_bridge__$Vec_isize$new(); 104 | void __swift_bridge__$Vec_isize$_free(void* const vec); 105 | uintptr_t __swift_bridge__$Vec_isize$len(void* const vec); 106 | void __swift_bridge__$Vec_isize$push(void* const vec, intptr_t val); 107 | __private__OptionIsize __swift_bridge__$Vec_isize$pop(void* const vec); 108 | __private__OptionIsize __swift_bridge__$Vec_isize$get(void* const vec, uintptr_t index); 109 | __private__OptionIsize __swift_bridge__$Vec_isize$get_mut(void* const vec, uintptr_t index); 110 | intptr_t const * __swift_bridge__$Vec_isize$as_ptr(void* const vec); 111 | 112 | void* __swift_bridge__$Vec_bool$new(); 113 | void __swift_bridge__$Vec_bool$_free(void* const vec); 114 | uintptr_t __swift_bridge__$Vec_bool$len(void* const vec); 115 | void __swift_bridge__$Vec_bool$push(void* const vec, bool val); 116 | __private__OptionBool __swift_bridge__$Vec_bool$pop(void* const vec); 117 | __private__OptionBool __swift_bridge__$Vec_bool$get(void* const vec, uintptr_t index); 118 | __private__OptionBool __swift_bridge__$Vec_bool$get_mut(void* const vec, uintptr_t index); 119 | bool const * __swift_bridge__$Vec_bool$as_ptr(void* const vec); 120 | 121 | void* __swift_bridge__$Vec_f32$new(); 122 | void __swift_bridge__$Vec_f32$_free(void* const vec); 123 | uintptr_t __swift_bridge__$Vec_f32$len(void* const vec); 124 | void __swift_bridge__$Vec_f32$push(void* const vec, float val); 125 | __private__OptionF32 __swift_bridge__$Vec_f32$pop(void* const vec); 126 | __private__OptionF32 __swift_bridge__$Vec_f32$get(void* const vec, uintptr_t index); 127 | __private__OptionF32 __swift_bridge__$Vec_f32$get_mut(void* const vec, uintptr_t index); 128 | float const * __swift_bridge__$Vec_f32$as_ptr(void* const vec); 129 | 130 | void* __swift_bridge__$Vec_f64$new(); 131 | void __swift_bridge__$Vec_f64$_free(void* const vec); 132 | uintptr_t __swift_bridge__$Vec_f64$len(void* const vec); 133 | void __swift_bridge__$Vec_f64$push(void* const vec, double val); 134 | __private__OptionF64 __swift_bridge__$Vec_f64$pop(void* const vec); 135 | __private__OptionF64 __swift_bridge__$Vec_f64$get(void* const vec, uintptr_t index); 136 | __private__OptionF64 __swift_bridge__$Vec_f64$get_mut(void* const vec, uintptr_t index); 137 | double const * __swift_bridge__$Vec_f64$as_ptr(void* const vec); 138 | 139 | #include 140 | typedef struct RustString RustString; 141 | void __swift_bridge__$RustString$_free(void* self); 142 | 143 | void* __swift_bridge__$Vec_RustString$new(void); 144 | void __swift_bridge__$Vec_RustString$drop(void* vec_ptr); 145 | void __swift_bridge__$Vec_RustString$push(void* vec_ptr, void* item_ptr); 146 | void* __swift_bridge__$Vec_RustString$pop(void* vec_ptr); 147 | void* __swift_bridge__$Vec_RustString$get(void* vec_ptr, uintptr_t index); 148 | void* __swift_bridge__$Vec_RustString$get_mut(void* vec_ptr, uintptr_t index); 149 | uintptr_t __swift_bridge__$Vec_RustString$len(void* vec_ptr); 150 | void* __swift_bridge__$Vec_RustString$as_ptr(void* vec_ptr); 151 | 152 | void* __swift_bridge__$RustString$new(void); 153 | void* __swift_bridge__$RustString$new_with_str(struct RustStr str); 154 | uintptr_t __swift_bridge__$RustString$len(void* self); 155 | struct RustStr __swift_bridge__$RustString$as_str(void* self); 156 | struct RustStr __swift_bridge__$RustString$trim(void* self); 157 | bool __swift_bridge__$RustStr$partial_eq(struct RustStr lhs, struct RustStr rhs); 158 | 159 | 160 | void __swift_bridge__$call_boxed_fn_once_no_args_no_return(void* boxed_fnonce); 161 | void __swift_bridge__$free_boxed_fn_once_no_args_no_return(void* boxed_fnonce); 162 | 163 | 164 | struct __private__ResultPtrAndPtr { bool is_ok; void* ok_or_err; }; 165 | -------------------------------------------------------------------------------- /BevyIosGamecenterRust.xcframework/ios-arm64/Headers/BevyIosGamecenterRust/bevy_ios_gamecenter.h: -------------------------------------------------------------------------------- 1 | // File automatically generated by swift-bridge. 2 | #include 3 | #include 4 | typedef struct IosGCResolvedConflictsResponse IosGCResolvedConflictsResponse; 5 | void __swift_bridge__$IosGCResolvedConflictsResponse$_free(void* self); 6 | 7 | void* __swift_bridge__$Vec_IosGCResolvedConflictsResponse$new(void); 8 | void __swift_bridge__$Vec_IosGCResolvedConflictsResponse$drop(void* vec_ptr); 9 | void __swift_bridge__$Vec_IosGCResolvedConflictsResponse$push(void* vec_ptr, void* item_ptr); 10 | void* __swift_bridge__$Vec_IosGCResolvedConflictsResponse$pop(void* vec_ptr); 11 | void* __swift_bridge__$Vec_IosGCResolvedConflictsResponse$get(void* vec_ptr, uintptr_t index); 12 | void* __swift_bridge__$Vec_IosGCResolvedConflictsResponse$get_mut(void* vec_ptr, uintptr_t index); 13 | uintptr_t __swift_bridge__$Vec_IosGCResolvedConflictsResponse$len(void* vec_ptr); 14 | void* __swift_bridge__$Vec_IosGCResolvedConflictsResponse$as_ptr(void* vec_ptr); 15 | 16 | typedef struct IosGCSaveGames IosGCSaveGames; 17 | void __swift_bridge__$IosGCSaveGames$_free(void* self); 18 | 19 | void* __swift_bridge__$Vec_IosGCSaveGames$new(void); 20 | void __swift_bridge__$Vec_IosGCSaveGames$drop(void* vec_ptr); 21 | void __swift_bridge__$Vec_IosGCSaveGames$push(void* vec_ptr, void* item_ptr); 22 | void* __swift_bridge__$Vec_IosGCSaveGames$pop(void* vec_ptr); 23 | void* __swift_bridge__$Vec_IosGCSaveGames$get(void* vec_ptr, uintptr_t index); 24 | void* __swift_bridge__$Vec_IosGCSaveGames$get_mut(void* vec_ptr, uintptr_t index); 25 | uintptr_t __swift_bridge__$Vec_IosGCSaveGames$len(void* vec_ptr); 26 | void* __swift_bridge__$Vec_IosGCSaveGames$as_ptr(void* vec_ptr); 27 | 28 | typedef struct IosGCFetchItemsForSignatureVerificationResponse IosGCFetchItemsForSignatureVerificationResponse; 29 | void __swift_bridge__$IosGCFetchItemsForSignatureVerificationResponse$_free(void* self); 30 | 31 | void* __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerificationResponse$new(void); 32 | void __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerificationResponse$drop(void* vec_ptr); 33 | void __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerificationResponse$push(void* vec_ptr, void* item_ptr); 34 | void* __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerificationResponse$pop(void* vec_ptr); 35 | void* __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerificationResponse$get(void* vec_ptr, uintptr_t index); 36 | void* __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerificationResponse$get_mut(void* vec_ptr, uintptr_t index); 37 | uintptr_t __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerificationResponse$len(void* vec_ptr); 38 | void* __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerificationResponse$as_ptr(void* vec_ptr); 39 | 40 | typedef struct IosGCFetchItemsForSignatureVerification IosGCFetchItemsForSignatureVerification; 41 | void __swift_bridge__$IosGCFetchItemsForSignatureVerification$_free(void* self); 42 | 43 | void* __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerification$new(void); 44 | void __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerification$drop(void* vec_ptr); 45 | void __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerification$push(void* vec_ptr, void* item_ptr); 46 | void* __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerification$pop(void* vec_ptr); 47 | void* __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerification$get(void* vec_ptr, uintptr_t index); 48 | void* __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerification$get_mut(void* vec_ptr, uintptr_t index); 49 | uintptr_t __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerification$len(void* vec_ptr); 50 | void* __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerification$as_ptr(void* vec_ptr); 51 | 52 | typedef struct IosGCDeleteSaveGameResponse IosGCDeleteSaveGameResponse; 53 | void __swift_bridge__$IosGCDeleteSaveGameResponse$_free(void* self); 54 | 55 | void* __swift_bridge__$Vec_IosGCDeleteSaveGameResponse$new(void); 56 | void __swift_bridge__$Vec_IosGCDeleteSaveGameResponse$drop(void* vec_ptr); 57 | void __swift_bridge__$Vec_IosGCDeleteSaveGameResponse$push(void* vec_ptr, void* item_ptr); 58 | void* __swift_bridge__$Vec_IosGCDeleteSaveGameResponse$pop(void* vec_ptr); 59 | void* __swift_bridge__$Vec_IosGCDeleteSaveGameResponse$get(void* vec_ptr, uintptr_t index); 60 | void* __swift_bridge__$Vec_IosGCDeleteSaveGameResponse$get_mut(void* vec_ptr, uintptr_t index); 61 | uintptr_t __swift_bridge__$Vec_IosGCDeleteSaveGameResponse$len(void* vec_ptr); 62 | void* __swift_bridge__$Vec_IosGCDeleteSaveGameResponse$as_ptr(void* vec_ptr); 63 | 64 | typedef struct IosGCScoreSubmitResponse IosGCScoreSubmitResponse; 65 | void __swift_bridge__$IosGCScoreSubmitResponse$_free(void* self); 66 | 67 | void* __swift_bridge__$Vec_IosGCScoreSubmitResponse$new(void); 68 | void __swift_bridge__$Vec_IosGCScoreSubmitResponse$drop(void* vec_ptr); 69 | void __swift_bridge__$Vec_IosGCScoreSubmitResponse$push(void* vec_ptr, void* item_ptr); 70 | void* __swift_bridge__$Vec_IosGCScoreSubmitResponse$pop(void* vec_ptr); 71 | void* __swift_bridge__$Vec_IosGCScoreSubmitResponse$get(void* vec_ptr, uintptr_t index); 72 | void* __swift_bridge__$Vec_IosGCScoreSubmitResponse$get_mut(void* vec_ptr, uintptr_t index); 73 | uintptr_t __swift_bridge__$Vec_IosGCScoreSubmitResponse$len(void* vec_ptr); 74 | void* __swift_bridge__$Vec_IosGCScoreSubmitResponse$as_ptr(void* vec_ptr); 75 | 76 | typedef struct IosGCAchievementsResetResponse IosGCAchievementsResetResponse; 77 | void __swift_bridge__$IosGCAchievementsResetResponse$_free(void* self); 78 | 79 | void* __swift_bridge__$Vec_IosGCAchievementsResetResponse$new(void); 80 | void __swift_bridge__$Vec_IosGCAchievementsResetResponse$drop(void* vec_ptr); 81 | void __swift_bridge__$Vec_IosGCAchievementsResetResponse$push(void* vec_ptr, void* item_ptr); 82 | void* __swift_bridge__$Vec_IosGCAchievementsResetResponse$pop(void* vec_ptr); 83 | void* __swift_bridge__$Vec_IosGCAchievementsResetResponse$get(void* vec_ptr, uintptr_t index); 84 | void* __swift_bridge__$Vec_IosGCAchievementsResetResponse$get_mut(void* vec_ptr, uintptr_t index); 85 | uintptr_t __swift_bridge__$Vec_IosGCAchievementsResetResponse$len(void* vec_ptr); 86 | void* __swift_bridge__$Vec_IosGCAchievementsResetResponse$as_ptr(void* vec_ptr); 87 | 88 | typedef struct IosGCAchievementProgressResponse IosGCAchievementProgressResponse; 89 | void __swift_bridge__$IosGCAchievementProgressResponse$_free(void* self); 90 | 91 | void* __swift_bridge__$Vec_IosGCAchievementProgressResponse$new(void); 92 | void __swift_bridge__$Vec_IosGCAchievementProgressResponse$drop(void* vec_ptr); 93 | void __swift_bridge__$Vec_IosGCAchievementProgressResponse$push(void* vec_ptr, void* item_ptr); 94 | void* __swift_bridge__$Vec_IosGCAchievementProgressResponse$pop(void* vec_ptr); 95 | void* __swift_bridge__$Vec_IosGCAchievementProgressResponse$get(void* vec_ptr, uintptr_t index); 96 | void* __swift_bridge__$Vec_IosGCAchievementProgressResponse$get_mut(void* vec_ptr, uintptr_t index); 97 | uintptr_t __swift_bridge__$Vec_IosGCAchievementProgressResponse$len(void* vec_ptr); 98 | void* __swift_bridge__$Vec_IosGCAchievementProgressResponse$as_ptr(void* vec_ptr); 99 | 100 | typedef struct IosGCAchievement IosGCAchievement; 101 | void __swift_bridge__$IosGCAchievement$_free(void* self); 102 | 103 | void* __swift_bridge__$Vec_IosGCAchievement$new(void); 104 | void __swift_bridge__$Vec_IosGCAchievement$drop(void* vec_ptr); 105 | void __swift_bridge__$Vec_IosGCAchievement$push(void* vec_ptr, void* item_ptr); 106 | void* __swift_bridge__$Vec_IosGCAchievement$pop(void* vec_ptr); 107 | void* __swift_bridge__$Vec_IosGCAchievement$get(void* vec_ptr, uintptr_t index); 108 | void* __swift_bridge__$Vec_IosGCAchievement$get_mut(void* vec_ptr, uintptr_t index); 109 | uintptr_t __swift_bridge__$Vec_IosGCAchievement$len(void* vec_ptr); 110 | void* __swift_bridge__$Vec_IosGCAchievement$as_ptr(void* vec_ptr); 111 | 112 | typedef struct IosGCLoadGamesResponse IosGCLoadGamesResponse; 113 | void __swift_bridge__$IosGCLoadGamesResponse$_free(void* self); 114 | 115 | void* __swift_bridge__$Vec_IosGCLoadGamesResponse$new(void); 116 | void __swift_bridge__$Vec_IosGCLoadGamesResponse$drop(void* vec_ptr); 117 | void __swift_bridge__$Vec_IosGCLoadGamesResponse$push(void* vec_ptr, void* item_ptr); 118 | void* __swift_bridge__$Vec_IosGCLoadGamesResponse$pop(void* vec_ptr); 119 | void* __swift_bridge__$Vec_IosGCLoadGamesResponse$get(void* vec_ptr, uintptr_t index); 120 | void* __swift_bridge__$Vec_IosGCLoadGamesResponse$get_mut(void* vec_ptr, uintptr_t index); 121 | uintptr_t __swift_bridge__$Vec_IosGCLoadGamesResponse$len(void* vec_ptr); 122 | void* __swift_bridge__$Vec_IosGCLoadGamesResponse$as_ptr(void* vec_ptr); 123 | 124 | typedef struct IosGCSaveGamesResponse IosGCSaveGamesResponse; 125 | void __swift_bridge__$IosGCSaveGamesResponse$_free(void* self); 126 | 127 | void* __swift_bridge__$Vec_IosGCSaveGamesResponse$new(void); 128 | void __swift_bridge__$Vec_IosGCSaveGamesResponse$drop(void* vec_ptr); 129 | void __swift_bridge__$Vec_IosGCSaveGamesResponse$push(void* vec_ptr, void* item_ptr); 130 | void* __swift_bridge__$Vec_IosGCSaveGamesResponse$pop(void* vec_ptr); 131 | void* __swift_bridge__$Vec_IosGCSaveGamesResponse$get(void* vec_ptr, uintptr_t index); 132 | void* __swift_bridge__$Vec_IosGCSaveGamesResponse$get_mut(void* vec_ptr, uintptr_t index); 133 | uintptr_t __swift_bridge__$Vec_IosGCSaveGamesResponse$len(void* vec_ptr); 134 | void* __swift_bridge__$Vec_IosGCSaveGamesResponse$as_ptr(void* vec_ptr); 135 | 136 | typedef struct IosGCSavedGameResponse IosGCSavedGameResponse; 137 | void __swift_bridge__$IosGCSavedGameResponse$_free(void* self); 138 | 139 | void* __swift_bridge__$Vec_IosGCSavedGameResponse$new(void); 140 | void __swift_bridge__$Vec_IosGCSavedGameResponse$drop(void* vec_ptr); 141 | void __swift_bridge__$Vec_IosGCSavedGameResponse$push(void* vec_ptr, void* item_ptr); 142 | void* __swift_bridge__$Vec_IosGCSavedGameResponse$pop(void* vec_ptr); 143 | void* __swift_bridge__$Vec_IosGCSavedGameResponse$get(void* vec_ptr, uintptr_t index); 144 | void* __swift_bridge__$Vec_IosGCSavedGameResponse$get_mut(void* vec_ptr, uintptr_t index); 145 | uintptr_t __swift_bridge__$Vec_IosGCSavedGameResponse$len(void* vec_ptr); 146 | void* __swift_bridge__$Vec_IosGCSavedGameResponse$as_ptr(void* vec_ptr); 147 | 148 | typedef struct IosGCSaveGame IosGCSaveGame; 149 | void __swift_bridge__$IosGCSaveGame$_free(void* self); 150 | 151 | void* __swift_bridge__$Vec_IosGCSaveGame$new(void); 152 | void __swift_bridge__$Vec_IosGCSaveGame$drop(void* vec_ptr); 153 | void __swift_bridge__$Vec_IosGCSaveGame$push(void* vec_ptr, void* item_ptr); 154 | void* __swift_bridge__$Vec_IosGCSaveGame$pop(void* vec_ptr); 155 | void* __swift_bridge__$Vec_IosGCSaveGame$get(void* vec_ptr, uintptr_t index); 156 | void* __swift_bridge__$Vec_IosGCSaveGame$get_mut(void* vec_ptr, uintptr_t index); 157 | uintptr_t __swift_bridge__$Vec_IosGCSaveGame$len(void* vec_ptr); 158 | void* __swift_bridge__$Vec_IosGCSaveGame$as_ptr(void* vec_ptr); 159 | 160 | typedef struct IosGCAuthResult IosGCAuthResult; 161 | void __swift_bridge__$IosGCAuthResult$_free(void* self); 162 | 163 | void* __swift_bridge__$Vec_IosGCAuthResult$new(void); 164 | void __swift_bridge__$Vec_IosGCAuthResult$drop(void* vec_ptr); 165 | void __swift_bridge__$Vec_IosGCAuthResult$push(void* vec_ptr, void* item_ptr); 166 | void* __swift_bridge__$Vec_IosGCAuthResult$pop(void* vec_ptr); 167 | void* __swift_bridge__$Vec_IosGCAuthResult$get(void* vec_ptr, uintptr_t index); 168 | void* __swift_bridge__$Vec_IosGCAuthResult$get_mut(void* vec_ptr, uintptr_t index); 169 | uintptr_t __swift_bridge__$Vec_IosGCAuthResult$len(void* vec_ptr); 170 | void* __swift_bridge__$Vec_IosGCAuthResult$as_ptr(void* vec_ptr); 171 | 172 | typedef struct IosGCPlayer IosGCPlayer; 173 | void __swift_bridge__$IosGCPlayer$_free(void* self); 174 | 175 | void* __swift_bridge__$Vec_IosGCPlayer$new(void); 176 | void __swift_bridge__$Vec_IosGCPlayer$drop(void* vec_ptr); 177 | void __swift_bridge__$Vec_IosGCPlayer$push(void* vec_ptr, void* item_ptr); 178 | void* __swift_bridge__$Vec_IosGCPlayer$pop(void* vec_ptr); 179 | void* __swift_bridge__$Vec_IosGCPlayer$get(void* vec_ptr, uintptr_t index); 180 | void* __swift_bridge__$Vec_IosGCPlayer$get_mut(void* vec_ptr, uintptr_t index); 181 | uintptr_t __swift_bridge__$Vec_IosGCPlayer$len(void* vec_ptr); 182 | void* __swift_bridge__$Vec_IosGCPlayer$as_ptr(void* vec_ptr); 183 | 184 | void* __swift_bridge__$IosGCPlayer$new(void* game_id, void* team_id, bool is_authenticated, void* alias, void* display_name); 185 | void* __swift_bridge__$IosGCAuthResult$authenticated(void); 186 | void* __swift_bridge__$IosGCAuthResult$login_presented(void); 187 | void* __swift_bridge__$IosGCAuthResult$error(void* e); 188 | void* __swift_bridge__$IosGCSaveGame$new(void* name, void* device_name, uint64_t modification_date); 189 | void* __swift_bridge__$IosGCSavedGameResponse$done(void* save); 190 | void* __swift_bridge__$IosGCSavedGameResponse$error(void* e); 191 | bool __swift_bridge__$IosGCSaveGame$equals(void* a, void* b); 192 | void* __swift_bridge__$IosGCSaveGamesResponse$done(void* items); 193 | void* __swift_bridge__$IosGCSaveGamesResponse$error(void* e); 194 | void* __swift_bridge__$IosGCLoadGamesResponse$done(void* save_game, void* data); 195 | void* __swift_bridge__$IosGCLoadGamesResponse$unknown(void* save_game); 196 | void* __swift_bridge__$IosGCLoadGamesResponse$error(void* e); 197 | void* __swift_bridge__$IosGCAchievement$new(void* identifier, double progress, bool is_completed, uint64_t last_reported_date); 198 | void* __swift_bridge__$IosGCAchievementProgressResponse$done(void* a); 199 | void* __swift_bridge__$IosGCAchievementProgressResponse$error(void* e); 200 | void* __swift_bridge__$IosGCAchievementsResetResponse$done(void); 201 | void* __swift_bridge__$IosGCAchievementsResetResponse$error(void* e); 202 | void* __swift_bridge__$IosGCScoreSubmitResponse$done(void); 203 | void* __swift_bridge__$IosGCScoreSubmitResponse$error(void* e); 204 | void* __swift_bridge__$IosGCDeleteSaveGameResponse$done(void* e); 205 | void* __swift_bridge__$IosGCDeleteSaveGameResponse$error(void* e); 206 | void* __swift_bridge__$IosGCFetchItemsForSignatureVerification$new(void* url, void* signature_as_base64, void* salt_as_base64, uint64_t timestamp); 207 | void* __swift_bridge__$IosGCFetchItemsForSignatureVerificationResponse$done(void* items); 208 | void* __swift_bridge__$IosGCFetchItemsForSignatureVerificationResponse$error(void* e); 209 | void* __swift_bridge__$IosGCSaveGames$new(void* items); 210 | bool __swift_bridge__$IosGCSaveGames$contains(void* items, void* item); 211 | void* __swift_bridge__$IosGCResolvedConflictsResponse$done(void* items); 212 | void* __swift_bridge__$IosGCResolvedConflictsResponse$error(void* e); 213 | void __swift_bridge__$receive_authentication(int64_t request, void* result); 214 | void __swift_bridge__$receive_player(int64_t request, void* p); 215 | void __swift_bridge__$receive_load_game(int64_t request, void* response); 216 | void __swift_bridge__$receive_saved_game(int64_t request, void* response); 217 | void __swift_bridge__$receive_save_games(int64_t request, void* response); 218 | void __swift_bridge__$receive_deleted_game(int64_t request, void* response); 219 | void __swift_bridge__$receive_achievement_progress(int64_t request, void* response); 220 | void __swift_bridge__$receive_achievement_reset(int64_t request, void* response); 221 | void __swift_bridge__$receive_leaderboard_score(int64_t request, void* response); 222 | void __swift_bridge__$receive_items_for_signature_verification(int64_t request, void* response); 223 | void __swift_bridge__$receive_resolved_conflicts(int64_t request, void* response); 224 | void __swift_bridge__$receive_conflicting_savegames(void* savegames); 225 | 226 | 227 | -------------------------------------------------------------------------------- /BevyIosGamecenterRust.xcframework/ios-arm64/Headers/BevyIosGamecenterRust/module.modulemap: -------------------------------------------------------------------------------- 1 | module BevyIosGamecenterRust { 2 | header "SwiftBridgeCoreGC.h" 3 | header "bevy_ios_gamecenter.h" 4 | export * 5 | } 6 | -------------------------------------------------------------------------------- /BevyIosGamecenterRust.xcframework/ios-arm64_x86_64-simulator/Headers/BevyIosGamecenterRust/SwiftBridgeCoreGC.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | typedef struct RustStr { uint8_t* const start; uintptr_t len; } RustStr; 4 | typedef struct __private__FfiSlice { void* const start; uintptr_t len; } __private__FfiSlice; 5 | void* __swift_bridge__null_pointer(void); 6 | 7 | 8 | typedef struct __private__OptionU8 { uint8_t val; bool is_some; } __private__OptionU8; 9 | typedef struct __private__OptionI8 { int8_t val; bool is_some; } __private__OptionI8; 10 | typedef struct __private__OptionU16 { uint16_t val; bool is_some; } __private__OptionU16; 11 | typedef struct __private__OptionI16 { int16_t val; bool is_some; } __private__OptionI16; 12 | typedef struct __private__OptionU32 { uint32_t val; bool is_some; } __private__OptionU32; 13 | typedef struct __private__OptionI32 { int32_t val; bool is_some; } __private__OptionI32; 14 | typedef struct __private__OptionU64 { uint64_t val; bool is_some; } __private__OptionU64; 15 | typedef struct __private__OptionI64 { int64_t val; bool is_some; } __private__OptionI64; 16 | typedef struct __private__OptionUsize { uintptr_t val; bool is_some; } __private__OptionUsize; 17 | typedef struct __private__OptionIsize { intptr_t val; bool is_some; } __private__OptionIsize; 18 | typedef struct __private__OptionF32 { float val; bool is_some; } __private__OptionF32; 19 | typedef struct __private__OptionF64 { double val; bool is_some; } __private__OptionF64; 20 | typedef struct __private__OptionBool { bool val; bool is_some; } __private__OptionBool; 21 | 22 | void* __swift_bridge__$Vec_u8$new(); 23 | void __swift_bridge__$Vec_u8$_free(void* const vec); 24 | uintptr_t __swift_bridge__$Vec_u8$len(void* const vec); 25 | void __swift_bridge__$Vec_u8$push(void* const vec, uint8_t val); 26 | __private__OptionU8 __swift_bridge__$Vec_u8$pop(void* const vec); 27 | __private__OptionU8 __swift_bridge__$Vec_u8$get(void* const vec, uintptr_t index); 28 | __private__OptionU8 __swift_bridge__$Vec_u8$get_mut(void* const vec, uintptr_t index); 29 | uint8_t const * __swift_bridge__$Vec_u8$as_ptr(void* const vec); 30 | 31 | void* __swift_bridge__$Vec_u16$new(); 32 | void __swift_bridge__$Vec_u16$_free(void* const vec); 33 | uintptr_t __swift_bridge__$Vec_u16$len(void* const vec); 34 | void __swift_bridge__$Vec_u16$push(void* const vec, uint16_t val); 35 | __private__OptionU16 __swift_bridge__$Vec_u16$pop(void* const vec); 36 | __private__OptionU16 __swift_bridge__$Vec_u16$get(void* const vec, uintptr_t index); 37 | __private__OptionU16 __swift_bridge__$Vec_u16$get_mut(void* const vec, uintptr_t index); 38 | uint16_t const * __swift_bridge__$Vec_u16$as_ptr(void* const vec); 39 | 40 | void* __swift_bridge__$Vec_u32$new(); 41 | void __swift_bridge__$Vec_u32$_free(void* const vec); 42 | uintptr_t __swift_bridge__$Vec_u32$len(void* const vec); 43 | void __swift_bridge__$Vec_u32$push(void* const vec, uint32_t val); 44 | __private__OptionU32 __swift_bridge__$Vec_u32$pop(void* const vec); 45 | __private__OptionU32 __swift_bridge__$Vec_u32$get(void* const vec, uintptr_t index); 46 | __private__OptionU32 __swift_bridge__$Vec_u32$get_mut(void* const vec, uintptr_t index); 47 | uint32_t const * __swift_bridge__$Vec_u32$as_ptr(void* const vec); 48 | 49 | void* __swift_bridge__$Vec_u64$new(); 50 | void __swift_bridge__$Vec_u64$_free(void* const vec); 51 | uintptr_t __swift_bridge__$Vec_u64$len(void* const vec); 52 | void __swift_bridge__$Vec_u64$push(void* const vec, uint64_t val); 53 | __private__OptionU64 __swift_bridge__$Vec_u64$pop(void* const vec); 54 | __private__OptionU64 __swift_bridge__$Vec_u64$get(void* const vec, uintptr_t index); 55 | __private__OptionU64 __swift_bridge__$Vec_u64$get_mut(void* const vec, uintptr_t index); 56 | uint64_t const * __swift_bridge__$Vec_u64$as_ptr(void* const vec); 57 | 58 | void* __swift_bridge__$Vec_usize$new(); 59 | void __swift_bridge__$Vec_usize$_free(void* const vec); 60 | uintptr_t __swift_bridge__$Vec_usize$len(void* const vec); 61 | void __swift_bridge__$Vec_usize$push(void* const vec, uintptr_t val); 62 | __private__OptionUsize __swift_bridge__$Vec_usize$pop(void* const vec); 63 | __private__OptionUsize __swift_bridge__$Vec_usize$get(void* const vec, uintptr_t index); 64 | __private__OptionUsize __swift_bridge__$Vec_usize$get_mut(void* const vec, uintptr_t index); 65 | uintptr_t const * __swift_bridge__$Vec_usize$as_ptr(void* const vec); 66 | 67 | void* __swift_bridge__$Vec_i8$new(); 68 | void __swift_bridge__$Vec_i8$_free(void* const vec); 69 | uintptr_t __swift_bridge__$Vec_i8$len(void* const vec); 70 | void __swift_bridge__$Vec_i8$push(void* const vec, int8_t val); 71 | __private__OptionI8 __swift_bridge__$Vec_i8$pop(void* const vec); 72 | __private__OptionI8 __swift_bridge__$Vec_i8$get(void* const vec, uintptr_t index); 73 | __private__OptionI8 __swift_bridge__$Vec_i8$get_mut(void* const vec, uintptr_t index); 74 | int8_t const * __swift_bridge__$Vec_i8$as_ptr(void* const vec); 75 | 76 | void* __swift_bridge__$Vec_i16$new(); 77 | void __swift_bridge__$Vec_i16$_free(void* const vec); 78 | uintptr_t __swift_bridge__$Vec_i16$len(void* const vec); 79 | void __swift_bridge__$Vec_i16$push(void* const vec, int16_t val); 80 | __private__OptionI16 __swift_bridge__$Vec_i16$pop(void* const vec); 81 | __private__OptionI16 __swift_bridge__$Vec_i16$get(void* const vec, uintptr_t index); 82 | __private__OptionI16 __swift_bridge__$Vec_i16$get_mut(void* const vec, uintptr_t index); 83 | int16_t const * __swift_bridge__$Vec_i16$as_ptr(void* const vec); 84 | 85 | void* __swift_bridge__$Vec_i32$new(); 86 | void __swift_bridge__$Vec_i32$_free(void* const vec); 87 | uintptr_t __swift_bridge__$Vec_i32$len(void* const vec); 88 | void __swift_bridge__$Vec_i32$push(void* const vec, int32_t val); 89 | __private__OptionI32 __swift_bridge__$Vec_i32$pop(void* const vec); 90 | __private__OptionI32 __swift_bridge__$Vec_i32$get(void* const vec, uintptr_t index); 91 | __private__OptionI32 __swift_bridge__$Vec_i32$get_mut(void* const vec, uintptr_t index); 92 | int32_t const * __swift_bridge__$Vec_i32$as_ptr(void* const vec); 93 | 94 | void* __swift_bridge__$Vec_i64$new(); 95 | void __swift_bridge__$Vec_i64$_free(void* const vec); 96 | uintptr_t __swift_bridge__$Vec_i64$len(void* const vec); 97 | void __swift_bridge__$Vec_i64$push(void* const vec, int64_t val); 98 | __private__OptionI64 __swift_bridge__$Vec_i64$pop(void* const vec); 99 | __private__OptionI64 __swift_bridge__$Vec_i64$get(void* const vec, uintptr_t index); 100 | __private__OptionI64 __swift_bridge__$Vec_i64$get_mut(void* const vec, uintptr_t index); 101 | int64_t const * __swift_bridge__$Vec_i64$as_ptr(void* const vec); 102 | 103 | void* __swift_bridge__$Vec_isize$new(); 104 | void __swift_bridge__$Vec_isize$_free(void* const vec); 105 | uintptr_t __swift_bridge__$Vec_isize$len(void* const vec); 106 | void __swift_bridge__$Vec_isize$push(void* const vec, intptr_t val); 107 | __private__OptionIsize __swift_bridge__$Vec_isize$pop(void* const vec); 108 | __private__OptionIsize __swift_bridge__$Vec_isize$get(void* const vec, uintptr_t index); 109 | __private__OptionIsize __swift_bridge__$Vec_isize$get_mut(void* const vec, uintptr_t index); 110 | intptr_t const * __swift_bridge__$Vec_isize$as_ptr(void* const vec); 111 | 112 | void* __swift_bridge__$Vec_bool$new(); 113 | void __swift_bridge__$Vec_bool$_free(void* const vec); 114 | uintptr_t __swift_bridge__$Vec_bool$len(void* const vec); 115 | void __swift_bridge__$Vec_bool$push(void* const vec, bool val); 116 | __private__OptionBool __swift_bridge__$Vec_bool$pop(void* const vec); 117 | __private__OptionBool __swift_bridge__$Vec_bool$get(void* const vec, uintptr_t index); 118 | __private__OptionBool __swift_bridge__$Vec_bool$get_mut(void* const vec, uintptr_t index); 119 | bool const * __swift_bridge__$Vec_bool$as_ptr(void* const vec); 120 | 121 | void* __swift_bridge__$Vec_f32$new(); 122 | void __swift_bridge__$Vec_f32$_free(void* const vec); 123 | uintptr_t __swift_bridge__$Vec_f32$len(void* const vec); 124 | void __swift_bridge__$Vec_f32$push(void* const vec, float val); 125 | __private__OptionF32 __swift_bridge__$Vec_f32$pop(void* const vec); 126 | __private__OptionF32 __swift_bridge__$Vec_f32$get(void* const vec, uintptr_t index); 127 | __private__OptionF32 __swift_bridge__$Vec_f32$get_mut(void* const vec, uintptr_t index); 128 | float const * __swift_bridge__$Vec_f32$as_ptr(void* const vec); 129 | 130 | void* __swift_bridge__$Vec_f64$new(); 131 | void __swift_bridge__$Vec_f64$_free(void* const vec); 132 | uintptr_t __swift_bridge__$Vec_f64$len(void* const vec); 133 | void __swift_bridge__$Vec_f64$push(void* const vec, double val); 134 | __private__OptionF64 __swift_bridge__$Vec_f64$pop(void* const vec); 135 | __private__OptionF64 __swift_bridge__$Vec_f64$get(void* const vec, uintptr_t index); 136 | __private__OptionF64 __swift_bridge__$Vec_f64$get_mut(void* const vec, uintptr_t index); 137 | double const * __swift_bridge__$Vec_f64$as_ptr(void* const vec); 138 | 139 | #include 140 | typedef struct RustString RustString; 141 | void __swift_bridge__$RustString$_free(void* self); 142 | 143 | void* __swift_bridge__$Vec_RustString$new(void); 144 | void __swift_bridge__$Vec_RustString$drop(void* vec_ptr); 145 | void __swift_bridge__$Vec_RustString$push(void* vec_ptr, void* item_ptr); 146 | void* __swift_bridge__$Vec_RustString$pop(void* vec_ptr); 147 | void* __swift_bridge__$Vec_RustString$get(void* vec_ptr, uintptr_t index); 148 | void* __swift_bridge__$Vec_RustString$get_mut(void* vec_ptr, uintptr_t index); 149 | uintptr_t __swift_bridge__$Vec_RustString$len(void* vec_ptr); 150 | void* __swift_bridge__$Vec_RustString$as_ptr(void* vec_ptr); 151 | 152 | void* __swift_bridge__$RustString$new(void); 153 | void* __swift_bridge__$RustString$new_with_str(struct RustStr str); 154 | uintptr_t __swift_bridge__$RustString$len(void* self); 155 | struct RustStr __swift_bridge__$RustString$as_str(void* self); 156 | struct RustStr __swift_bridge__$RustString$trim(void* self); 157 | bool __swift_bridge__$RustStr$partial_eq(struct RustStr lhs, struct RustStr rhs); 158 | 159 | 160 | void __swift_bridge__$call_boxed_fn_once_no_args_no_return(void* boxed_fnonce); 161 | void __swift_bridge__$free_boxed_fn_once_no_args_no_return(void* boxed_fnonce); 162 | 163 | 164 | struct __private__ResultPtrAndPtr { bool is_ok; void* ok_or_err; }; 165 | -------------------------------------------------------------------------------- /BevyIosGamecenterRust.xcframework/ios-arm64_x86_64-simulator/Headers/BevyIosGamecenterRust/bevy_ios_gamecenter.h: -------------------------------------------------------------------------------- 1 | // File automatically generated by swift-bridge. 2 | #include 3 | #include 4 | typedef struct IosGCResolvedConflictsResponse IosGCResolvedConflictsResponse; 5 | void __swift_bridge__$IosGCResolvedConflictsResponse$_free(void* self); 6 | 7 | void* __swift_bridge__$Vec_IosGCResolvedConflictsResponse$new(void); 8 | void __swift_bridge__$Vec_IosGCResolvedConflictsResponse$drop(void* vec_ptr); 9 | void __swift_bridge__$Vec_IosGCResolvedConflictsResponse$push(void* vec_ptr, void* item_ptr); 10 | void* __swift_bridge__$Vec_IosGCResolvedConflictsResponse$pop(void* vec_ptr); 11 | void* __swift_bridge__$Vec_IosGCResolvedConflictsResponse$get(void* vec_ptr, uintptr_t index); 12 | void* __swift_bridge__$Vec_IosGCResolvedConflictsResponse$get_mut(void* vec_ptr, uintptr_t index); 13 | uintptr_t __swift_bridge__$Vec_IosGCResolvedConflictsResponse$len(void* vec_ptr); 14 | void* __swift_bridge__$Vec_IosGCResolvedConflictsResponse$as_ptr(void* vec_ptr); 15 | 16 | typedef struct IosGCSaveGames IosGCSaveGames; 17 | void __swift_bridge__$IosGCSaveGames$_free(void* self); 18 | 19 | void* __swift_bridge__$Vec_IosGCSaveGames$new(void); 20 | void __swift_bridge__$Vec_IosGCSaveGames$drop(void* vec_ptr); 21 | void __swift_bridge__$Vec_IosGCSaveGames$push(void* vec_ptr, void* item_ptr); 22 | void* __swift_bridge__$Vec_IosGCSaveGames$pop(void* vec_ptr); 23 | void* __swift_bridge__$Vec_IosGCSaveGames$get(void* vec_ptr, uintptr_t index); 24 | void* __swift_bridge__$Vec_IosGCSaveGames$get_mut(void* vec_ptr, uintptr_t index); 25 | uintptr_t __swift_bridge__$Vec_IosGCSaveGames$len(void* vec_ptr); 26 | void* __swift_bridge__$Vec_IosGCSaveGames$as_ptr(void* vec_ptr); 27 | 28 | typedef struct IosGCFetchItemsForSignatureVerificationResponse IosGCFetchItemsForSignatureVerificationResponse; 29 | void __swift_bridge__$IosGCFetchItemsForSignatureVerificationResponse$_free(void* self); 30 | 31 | void* __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerificationResponse$new(void); 32 | void __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerificationResponse$drop(void* vec_ptr); 33 | void __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerificationResponse$push(void* vec_ptr, void* item_ptr); 34 | void* __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerificationResponse$pop(void* vec_ptr); 35 | void* __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerificationResponse$get(void* vec_ptr, uintptr_t index); 36 | void* __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerificationResponse$get_mut(void* vec_ptr, uintptr_t index); 37 | uintptr_t __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerificationResponse$len(void* vec_ptr); 38 | void* __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerificationResponse$as_ptr(void* vec_ptr); 39 | 40 | typedef struct IosGCFetchItemsForSignatureVerification IosGCFetchItemsForSignatureVerification; 41 | void __swift_bridge__$IosGCFetchItemsForSignatureVerification$_free(void* self); 42 | 43 | void* __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerification$new(void); 44 | void __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerification$drop(void* vec_ptr); 45 | void __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerification$push(void* vec_ptr, void* item_ptr); 46 | void* __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerification$pop(void* vec_ptr); 47 | void* __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerification$get(void* vec_ptr, uintptr_t index); 48 | void* __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerification$get_mut(void* vec_ptr, uintptr_t index); 49 | uintptr_t __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerification$len(void* vec_ptr); 50 | void* __swift_bridge__$Vec_IosGCFetchItemsForSignatureVerification$as_ptr(void* vec_ptr); 51 | 52 | typedef struct IosGCDeleteSaveGameResponse IosGCDeleteSaveGameResponse; 53 | void __swift_bridge__$IosGCDeleteSaveGameResponse$_free(void* self); 54 | 55 | void* __swift_bridge__$Vec_IosGCDeleteSaveGameResponse$new(void); 56 | void __swift_bridge__$Vec_IosGCDeleteSaveGameResponse$drop(void* vec_ptr); 57 | void __swift_bridge__$Vec_IosGCDeleteSaveGameResponse$push(void* vec_ptr, void* item_ptr); 58 | void* __swift_bridge__$Vec_IosGCDeleteSaveGameResponse$pop(void* vec_ptr); 59 | void* __swift_bridge__$Vec_IosGCDeleteSaveGameResponse$get(void* vec_ptr, uintptr_t index); 60 | void* __swift_bridge__$Vec_IosGCDeleteSaveGameResponse$get_mut(void* vec_ptr, uintptr_t index); 61 | uintptr_t __swift_bridge__$Vec_IosGCDeleteSaveGameResponse$len(void* vec_ptr); 62 | void* __swift_bridge__$Vec_IosGCDeleteSaveGameResponse$as_ptr(void* vec_ptr); 63 | 64 | typedef struct IosGCScoreSubmitResponse IosGCScoreSubmitResponse; 65 | void __swift_bridge__$IosGCScoreSubmitResponse$_free(void* self); 66 | 67 | void* __swift_bridge__$Vec_IosGCScoreSubmitResponse$new(void); 68 | void __swift_bridge__$Vec_IosGCScoreSubmitResponse$drop(void* vec_ptr); 69 | void __swift_bridge__$Vec_IosGCScoreSubmitResponse$push(void* vec_ptr, void* item_ptr); 70 | void* __swift_bridge__$Vec_IosGCScoreSubmitResponse$pop(void* vec_ptr); 71 | void* __swift_bridge__$Vec_IosGCScoreSubmitResponse$get(void* vec_ptr, uintptr_t index); 72 | void* __swift_bridge__$Vec_IosGCScoreSubmitResponse$get_mut(void* vec_ptr, uintptr_t index); 73 | uintptr_t __swift_bridge__$Vec_IosGCScoreSubmitResponse$len(void* vec_ptr); 74 | void* __swift_bridge__$Vec_IosGCScoreSubmitResponse$as_ptr(void* vec_ptr); 75 | 76 | typedef struct IosGCAchievementsResetResponse IosGCAchievementsResetResponse; 77 | void __swift_bridge__$IosGCAchievementsResetResponse$_free(void* self); 78 | 79 | void* __swift_bridge__$Vec_IosGCAchievementsResetResponse$new(void); 80 | void __swift_bridge__$Vec_IosGCAchievementsResetResponse$drop(void* vec_ptr); 81 | void __swift_bridge__$Vec_IosGCAchievementsResetResponse$push(void* vec_ptr, void* item_ptr); 82 | void* __swift_bridge__$Vec_IosGCAchievementsResetResponse$pop(void* vec_ptr); 83 | void* __swift_bridge__$Vec_IosGCAchievementsResetResponse$get(void* vec_ptr, uintptr_t index); 84 | void* __swift_bridge__$Vec_IosGCAchievementsResetResponse$get_mut(void* vec_ptr, uintptr_t index); 85 | uintptr_t __swift_bridge__$Vec_IosGCAchievementsResetResponse$len(void* vec_ptr); 86 | void* __swift_bridge__$Vec_IosGCAchievementsResetResponse$as_ptr(void* vec_ptr); 87 | 88 | typedef struct IosGCAchievementProgressResponse IosGCAchievementProgressResponse; 89 | void __swift_bridge__$IosGCAchievementProgressResponse$_free(void* self); 90 | 91 | void* __swift_bridge__$Vec_IosGCAchievementProgressResponse$new(void); 92 | void __swift_bridge__$Vec_IosGCAchievementProgressResponse$drop(void* vec_ptr); 93 | void __swift_bridge__$Vec_IosGCAchievementProgressResponse$push(void* vec_ptr, void* item_ptr); 94 | void* __swift_bridge__$Vec_IosGCAchievementProgressResponse$pop(void* vec_ptr); 95 | void* __swift_bridge__$Vec_IosGCAchievementProgressResponse$get(void* vec_ptr, uintptr_t index); 96 | void* __swift_bridge__$Vec_IosGCAchievementProgressResponse$get_mut(void* vec_ptr, uintptr_t index); 97 | uintptr_t __swift_bridge__$Vec_IosGCAchievementProgressResponse$len(void* vec_ptr); 98 | void* __swift_bridge__$Vec_IosGCAchievementProgressResponse$as_ptr(void* vec_ptr); 99 | 100 | typedef struct IosGCAchievement IosGCAchievement; 101 | void __swift_bridge__$IosGCAchievement$_free(void* self); 102 | 103 | void* __swift_bridge__$Vec_IosGCAchievement$new(void); 104 | void __swift_bridge__$Vec_IosGCAchievement$drop(void* vec_ptr); 105 | void __swift_bridge__$Vec_IosGCAchievement$push(void* vec_ptr, void* item_ptr); 106 | void* __swift_bridge__$Vec_IosGCAchievement$pop(void* vec_ptr); 107 | void* __swift_bridge__$Vec_IosGCAchievement$get(void* vec_ptr, uintptr_t index); 108 | void* __swift_bridge__$Vec_IosGCAchievement$get_mut(void* vec_ptr, uintptr_t index); 109 | uintptr_t __swift_bridge__$Vec_IosGCAchievement$len(void* vec_ptr); 110 | void* __swift_bridge__$Vec_IosGCAchievement$as_ptr(void* vec_ptr); 111 | 112 | typedef struct IosGCLoadGamesResponse IosGCLoadGamesResponse; 113 | void __swift_bridge__$IosGCLoadGamesResponse$_free(void* self); 114 | 115 | void* __swift_bridge__$Vec_IosGCLoadGamesResponse$new(void); 116 | void __swift_bridge__$Vec_IosGCLoadGamesResponse$drop(void* vec_ptr); 117 | void __swift_bridge__$Vec_IosGCLoadGamesResponse$push(void* vec_ptr, void* item_ptr); 118 | void* __swift_bridge__$Vec_IosGCLoadGamesResponse$pop(void* vec_ptr); 119 | void* __swift_bridge__$Vec_IosGCLoadGamesResponse$get(void* vec_ptr, uintptr_t index); 120 | void* __swift_bridge__$Vec_IosGCLoadGamesResponse$get_mut(void* vec_ptr, uintptr_t index); 121 | uintptr_t __swift_bridge__$Vec_IosGCLoadGamesResponse$len(void* vec_ptr); 122 | void* __swift_bridge__$Vec_IosGCLoadGamesResponse$as_ptr(void* vec_ptr); 123 | 124 | typedef struct IosGCSaveGamesResponse IosGCSaveGamesResponse; 125 | void __swift_bridge__$IosGCSaveGamesResponse$_free(void* self); 126 | 127 | void* __swift_bridge__$Vec_IosGCSaveGamesResponse$new(void); 128 | void __swift_bridge__$Vec_IosGCSaveGamesResponse$drop(void* vec_ptr); 129 | void __swift_bridge__$Vec_IosGCSaveGamesResponse$push(void* vec_ptr, void* item_ptr); 130 | void* __swift_bridge__$Vec_IosGCSaveGamesResponse$pop(void* vec_ptr); 131 | void* __swift_bridge__$Vec_IosGCSaveGamesResponse$get(void* vec_ptr, uintptr_t index); 132 | void* __swift_bridge__$Vec_IosGCSaveGamesResponse$get_mut(void* vec_ptr, uintptr_t index); 133 | uintptr_t __swift_bridge__$Vec_IosGCSaveGamesResponse$len(void* vec_ptr); 134 | void* __swift_bridge__$Vec_IosGCSaveGamesResponse$as_ptr(void* vec_ptr); 135 | 136 | typedef struct IosGCSavedGameResponse IosGCSavedGameResponse; 137 | void __swift_bridge__$IosGCSavedGameResponse$_free(void* self); 138 | 139 | void* __swift_bridge__$Vec_IosGCSavedGameResponse$new(void); 140 | void __swift_bridge__$Vec_IosGCSavedGameResponse$drop(void* vec_ptr); 141 | void __swift_bridge__$Vec_IosGCSavedGameResponse$push(void* vec_ptr, void* item_ptr); 142 | void* __swift_bridge__$Vec_IosGCSavedGameResponse$pop(void* vec_ptr); 143 | void* __swift_bridge__$Vec_IosGCSavedGameResponse$get(void* vec_ptr, uintptr_t index); 144 | void* __swift_bridge__$Vec_IosGCSavedGameResponse$get_mut(void* vec_ptr, uintptr_t index); 145 | uintptr_t __swift_bridge__$Vec_IosGCSavedGameResponse$len(void* vec_ptr); 146 | void* __swift_bridge__$Vec_IosGCSavedGameResponse$as_ptr(void* vec_ptr); 147 | 148 | typedef struct IosGCSaveGame IosGCSaveGame; 149 | void __swift_bridge__$IosGCSaveGame$_free(void* self); 150 | 151 | void* __swift_bridge__$Vec_IosGCSaveGame$new(void); 152 | void __swift_bridge__$Vec_IosGCSaveGame$drop(void* vec_ptr); 153 | void __swift_bridge__$Vec_IosGCSaveGame$push(void* vec_ptr, void* item_ptr); 154 | void* __swift_bridge__$Vec_IosGCSaveGame$pop(void* vec_ptr); 155 | void* __swift_bridge__$Vec_IosGCSaveGame$get(void* vec_ptr, uintptr_t index); 156 | void* __swift_bridge__$Vec_IosGCSaveGame$get_mut(void* vec_ptr, uintptr_t index); 157 | uintptr_t __swift_bridge__$Vec_IosGCSaveGame$len(void* vec_ptr); 158 | void* __swift_bridge__$Vec_IosGCSaveGame$as_ptr(void* vec_ptr); 159 | 160 | typedef struct IosGCAuthResult IosGCAuthResult; 161 | void __swift_bridge__$IosGCAuthResult$_free(void* self); 162 | 163 | void* __swift_bridge__$Vec_IosGCAuthResult$new(void); 164 | void __swift_bridge__$Vec_IosGCAuthResult$drop(void* vec_ptr); 165 | void __swift_bridge__$Vec_IosGCAuthResult$push(void* vec_ptr, void* item_ptr); 166 | void* __swift_bridge__$Vec_IosGCAuthResult$pop(void* vec_ptr); 167 | void* __swift_bridge__$Vec_IosGCAuthResult$get(void* vec_ptr, uintptr_t index); 168 | void* __swift_bridge__$Vec_IosGCAuthResult$get_mut(void* vec_ptr, uintptr_t index); 169 | uintptr_t __swift_bridge__$Vec_IosGCAuthResult$len(void* vec_ptr); 170 | void* __swift_bridge__$Vec_IosGCAuthResult$as_ptr(void* vec_ptr); 171 | 172 | typedef struct IosGCPlayer IosGCPlayer; 173 | void __swift_bridge__$IosGCPlayer$_free(void* self); 174 | 175 | void* __swift_bridge__$Vec_IosGCPlayer$new(void); 176 | void __swift_bridge__$Vec_IosGCPlayer$drop(void* vec_ptr); 177 | void __swift_bridge__$Vec_IosGCPlayer$push(void* vec_ptr, void* item_ptr); 178 | void* __swift_bridge__$Vec_IosGCPlayer$pop(void* vec_ptr); 179 | void* __swift_bridge__$Vec_IosGCPlayer$get(void* vec_ptr, uintptr_t index); 180 | void* __swift_bridge__$Vec_IosGCPlayer$get_mut(void* vec_ptr, uintptr_t index); 181 | uintptr_t __swift_bridge__$Vec_IosGCPlayer$len(void* vec_ptr); 182 | void* __swift_bridge__$Vec_IosGCPlayer$as_ptr(void* vec_ptr); 183 | 184 | void* __swift_bridge__$IosGCPlayer$new(void* game_id, void* team_id, bool is_authenticated, void* alias, void* display_name); 185 | void* __swift_bridge__$IosGCAuthResult$authenticated(void); 186 | void* __swift_bridge__$IosGCAuthResult$login_presented(void); 187 | void* __swift_bridge__$IosGCAuthResult$error(void* e); 188 | void* __swift_bridge__$IosGCSaveGame$new(void* name, void* device_name, uint64_t modification_date); 189 | void* __swift_bridge__$IosGCSavedGameResponse$done(void* save); 190 | void* __swift_bridge__$IosGCSavedGameResponse$error(void* e); 191 | bool __swift_bridge__$IosGCSaveGame$equals(void* a, void* b); 192 | void* __swift_bridge__$IosGCSaveGamesResponse$done(void* items); 193 | void* __swift_bridge__$IosGCSaveGamesResponse$error(void* e); 194 | void* __swift_bridge__$IosGCLoadGamesResponse$done(void* save_game, void* data); 195 | void* __swift_bridge__$IosGCLoadGamesResponse$unknown(void* save_game); 196 | void* __swift_bridge__$IosGCLoadGamesResponse$error(void* e); 197 | void* __swift_bridge__$IosGCAchievement$new(void* identifier, double progress, bool is_completed, uint64_t last_reported_date); 198 | void* __swift_bridge__$IosGCAchievementProgressResponse$done(void* a); 199 | void* __swift_bridge__$IosGCAchievementProgressResponse$error(void* e); 200 | void* __swift_bridge__$IosGCAchievementsResetResponse$done(void); 201 | void* __swift_bridge__$IosGCAchievementsResetResponse$error(void* e); 202 | void* __swift_bridge__$IosGCScoreSubmitResponse$done(void); 203 | void* __swift_bridge__$IosGCScoreSubmitResponse$error(void* e); 204 | void* __swift_bridge__$IosGCDeleteSaveGameResponse$done(void* e); 205 | void* __swift_bridge__$IosGCDeleteSaveGameResponse$error(void* e); 206 | void* __swift_bridge__$IosGCFetchItemsForSignatureVerification$new(void* url, void* signature_as_base64, void* salt_as_base64, uint64_t timestamp); 207 | void* __swift_bridge__$IosGCFetchItemsForSignatureVerificationResponse$done(void* items); 208 | void* __swift_bridge__$IosGCFetchItemsForSignatureVerificationResponse$error(void* e); 209 | void* __swift_bridge__$IosGCSaveGames$new(void* items); 210 | bool __swift_bridge__$IosGCSaveGames$contains(void* items, void* item); 211 | void* __swift_bridge__$IosGCResolvedConflictsResponse$done(void* items); 212 | void* __swift_bridge__$IosGCResolvedConflictsResponse$error(void* e); 213 | void __swift_bridge__$receive_authentication(int64_t request, void* result); 214 | void __swift_bridge__$receive_player(int64_t request, void* p); 215 | void __swift_bridge__$receive_load_game(int64_t request, void* response); 216 | void __swift_bridge__$receive_saved_game(int64_t request, void* response); 217 | void __swift_bridge__$receive_save_games(int64_t request, void* response); 218 | void __swift_bridge__$receive_deleted_game(int64_t request, void* response); 219 | void __swift_bridge__$receive_achievement_progress(int64_t request, void* response); 220 | void __swift_bridge__$receive_achievement_reset(int64_t request, void* response); 221 | void __swift_bridge__$receive_leaderboard_score(int64_t request, void* response); 222 | void __swift_bridge__$receive_items_for_signature_verification(int64_t request, void* response); 223 | void __swift_bridge__$receive_resolved_conflicts(int64_t request, void* response); 224 | void __swift_bridge__$receive_conflicting_savegames(void* savegames); 225 | 226 | 227 | -------------------------------------------------------------------------------- /BevyIosGamecenterRust.xcframework/ios-arm64_x86_64-simulator/Headers/BevyIosGamecenterRust/module.modulemap: -------------------------------------------------------------------------------- 1 | module BevyIosGamecenterRust { 2 | header "SwiftBridgeCoreGC.h" 3 | header "bevy_ios_gamecenter.h" 4 | export * 5 | } 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## Unreleased 9 | 10 | ## [0.4.0] - 2025-04-26 11 | 12 | ### Changed 13 | * update to bevy `0.16` 14 | * temporarily disabled ios-sim support until rust-bindgen [releases](https://github.com/rust-lang/rust-bindgen/issues/3181) 15 | 16 | ## [0.3.1] - 2025-03-29 17 | 18 | ### Changed 19 | * support ios `15.0` 20 | * fix crash on iOS < 17.2 ([#1](https://github.com/rustunit/bevy_ios_gamecenter/pull/11)) 21 | 22 | ## [0.3.0] - 2024-12-02 23 | 24 | ### Added 25 | * upgraded to bevy `0.15` 26 | * new `resolve_conflicting_games` method (#8). 27 | * new `ConflictingSaveGames` and `ResolvedConflicts` events. 28 | * new `BevyIosGamecenter` SystemParam for convenient request response flow based on `Observer` 29 | 30 | ### Changed 31 | * `init` is now explicitly `init_listeners` and is still called automatically (by default). 32 | * `authenticate` was previously implictly done inside `init` this is now an explicit call and response. 33 | * `get_player` is not implicitly called after successful `authenticate` anymore. 34 | * new container type `IosGCSaveGames` now used in `IosGCSaveGamesResponse`. 35 | 36 | ## [0.2.0] - 2024-07-12 37 | 38 | ### Changed 39 | * update to bevy `0.14` 40 | 41 | ## [0.1.8] - 2024-05-11 42 | 43 | *note:* the crate release matches the commit tagged with the `ru-` prefix because we release the swift package after the crate due to its dependency on each other 44 | 45 | ### Added 46 | * added method `delete_savegame` to delete cloud save games 47 | * added method `fetch_signature` to allow server side verification 48 | 49 | ## [0.1.7] - 2024-05-06 50 | 51 | *note:* the crate release matches the commit tagged with the `ru-` prefix because we release the swift package after the crate due to its dependency on each other 52 | 53 | ### Fixed 54 | * linker errors in windows builds using `bevy_ios_gamecenter` crate 55 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 5.10 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "bevy_ios_gamecenter", 8 | platforms: [.iOS("15.0")], 9 | products: [ 10 | // Products define the executables and libraries a package produces, making them visible to other packages. 11 | .library( 12 | name: "bevy_ios_gamecenter", 13 | targets: ["bevy_ios_gamecenter"]) 14 | ], 15 | targets: [ 16 | // Targets are the basic building blocks of a package, defining a module or a test suite. 17 | // Targets can depend on other targets in this package and products from dependencies. 18 | .binaryTarget( 19 | name: "BevyIosGamecenterRust", 20 | //path: "BevyIosGamecenterRust.xcframework"), 21 | url: 22 | "https://github.com/rustunit/bevy_ios_gamecenter/releases/download/rs-0.4.0/BevyIosGamecenterRust.xcframework.zip", 23 | checksum: "ed3a813eedacd6ae8dec050e5966c9e7cbc0b577289abb7525b118e410dbe40a"), 24 | .target( 25 | name: "bevy_ios_gamecenter", 26 | dependencies: ["BevyIosGamecenterRust"]), 27 | .testTarget( 28 | name: "bevy_ios_gamecenterTests", 29 | dependencies: ["bevy_ios_gamecenter"]), 30 | ] 31 | ) 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # bevy_ios_gamecenter 2 | 3 | [![crates.io][sh_crates]][lk_crates] 4 | [![docs.rs][sh_docs]][lk_docs] 5 | [![discord][sh_discord]][lk_discord] 6 | 7 | [sh_crates]: https://img.shields.io/crates/v/bevy_ios_gamecenter.svg 8 | [lk_crates]: https://crates.io/crates/bevy_ios_gamecenter 9 | [sh_docs]: https://img.shields.io/docsrs/bevy_ios_gamecenter 10 | [lk_docs]: https://docs.rs/bevy_ios_iap/latest/bevy_ios_gamecenter/ 11 | [sh_discord]: https://img.shields.io/discord/1176858176897953872?label=discord&color=5561E6 12 | [lk_discord]: https://discord.gg/rQNeEnMhus 13 | 14 | Bevy Plugin and Swift Package to provide access to iOS native GameKit (Gamecenter) from inside Bevy Apps 15 | It uses [Swift-Bridge](https://github.com/chinedufn/swift-bridge) to auto-generate the glue code and transport data types. 16 | 17 | ![demo](./assets/demo.gif) 18 | 19 | > Demo from our game using this crate: [zoolitaire.com](https://zoolitaire.com) 20 | 21 | ## Features 22 | * authentication 23 | * save games (based on iCloud) 24 | * achievements 25 | * leaderboards 26 | * egui based debug ui crate see [bevy_ios_gamecenter_egui folder](./bevy_ios_gamecenter_egui/README.md) 27 | 28 | ## TODOs 29 | * challenges, matchmaking 30 | 31 | ## Instructions 32 | 33 | 1. Add to XCode: Add SPM (Swift Package Manager) dependency 34 | 2. Add Rust dependency 35 | 3. Setup Plugin 36 | 37 | ### 1. Add to XCode 38 | 39 | * Add `GameKit` framework: 40 | ![gamekit](./assets/framework.png) 41 | 42 | * Go to `File` -> `Add Package Dependencies` and paste `https://github.com/rustunit/bevy_ios_gamecenter.git` into the search bar on the top right: 43 | ![xcode](./assets/xcode-spm.png) 44 | 45 | **Note:** 46 | The rust crate used must be exactly the same version as the Swift Package. 47 | I suggest using a specific version (like `0.2.0` in the screenshot) to make sure to always use binary matching versions! 48 | 49 | ### 2. Add Rust dependency 50 | 51 | ``` 52 | cargo add bevy_ios_gamecenter 53 | ``` 54 | 55 | or 56 | 57 | ```toml 58 | # always pin to the same exact version you also of the Swift package 59 | bevy_ios_gamecenter = { version = "=0.4.0" } 60 | ``` 61 | 62 | ### 3. Setup Plugin 63 | 64 | Initialize Bevy Plugin: 65 | 66 | ```rust 67 | // init right on startup 68 | app.add_plugins(IosGamecenterPlugin::new(true)); 69 | ``` 70 | 71 | ```rust 72 | fn bevy_system(mut gc: BevyIosGamecenter) { 73 | 74 | gc.authenticate() 75 | .on_response(|trigger: Trigger| match &trigger.event().0 { 76 | IosGCAuthResult::IsAuthenticated => {}, 77 | IosGCAuthResult::LoginPresented => {}, 78 | IosGCAuthResult::Error(e) => error!("auth error: {e}"), 79 | }); 80 | 81 | // here we request the player info type for the username and more 82 | // Note: all requests via `gc` of type `BevyIosGamecenter` 83 | // allow to attach an observer to listen to the response: 84 | gc.request_player().on_response(on_player_response); 85 | 86 | // update achievement progress, 100 % will complete it 87 | gc.achievement_progress("id".into(),100.); 88 | 89 | // reset all achievements 90 | gc.achievements_reset(); 91 | 92 | // save a game state as a byte slice 93 | gc.save_game("test".into(), vec![1, 2, 3].as_slice()); 94 | 95 | // request list of `IosGCSaveGame` 96 | gc.fetch_save_games().on_response(on_response); 97 | 98 | // based on result of above `fetch_save_games` request 99 | let save_game = IosGCSaveGame {..} 100 | gc.load_game(save_game); 101 | 102 | // update leaderboard score 103 | gc.leaderboards_score( 104 | "raking id".into(), 105 | // score 106 | 1, 107 | // context 108 | 2, 109 | ); 110 | 111 | // open gamecenter view (leaderboard) 112 | gc.trigger_view(view_states::LEADERBOARDS); 113 | } 114 | ``` 115 | 116 | ## Our Other Crates 117 | 118 | - [bevy_debug_log](https://github.com/rustunit/bevy_debug_log) 119 | - [bevy_device_lang](https://github.com/rustunit/bevy_device_lang) 120 | - [bevy_web_popups](https://github.com/rustunit/bevy_web_popups) 121 | - [bevy_libgdx_atlas](https://github.com/rustunit/bevy_libgdx_atlas) 122 | - [bevy_ios_review](https://github.com/rustunit/bevy_ios_review) 123 | - [bevy_ios_iap](https://github.com/rustunit/bevy_ios_iap) 124 | - [bevy_ios_alerts](https://github.com/rustunit/bevy_ios_alerts) 125 | - [bevy_ios_notifications](https://github.com/rustunit/bevy_ios_notifications) 126 | - [bevy_ios_impact](https://github.com/rustunit/bevy_ios_impact) 127 | - [bevy_ios_safearea](https://github.com/rustunit/bevy_ios_safearea) 128 | 129 | ## Bevy version support 130 | 131 | |bevy|bevy\_ios\_gamecenter| 132 | |----|---| 133 | |0.16|0.4,main| 134 | |0.15|0.3| 135 | |0.14|0.2| 136 | |0.13|0.1| 137 | 138 | # License 139 | 140 | All code in this repository is dual-licensed under either: 141 | 142 | - MIT License (LICENSE-MIT or http://opensource.org/licenses/MIT) 143 | - Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0) 144 | 145 | at your option. This means you can select the license you prefer. 146 | 147 | ## Your contributions 148 | Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. 149 | -------------------------------------------------------------------------------- /Sources/bevy_ios_gamecenter/BevyIosGamecenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // 4 | // 5 | // Created by Stephan on 26.04.24. 6 | // 7 | 8 | import GameKit 9 | import Foundation 10 | import BevyIosGamecenterRust 11 | 12 | final class SavedGameListener: NSObject, GKLocalPlayerListener { 13 | 14 | func player(_ player: GKPlayer, hasConflictingSavedGames savedGames: [GKSavedGame]) { 15 | do { 16 | receive_conflicting_savegames(try convert_save_games(savedGames)) 17 | } catch { 18 | print("Error reporting conflicting save games: \(error.localizedDescription)") 19 | } 20 | } 21 | } 22 | 23 | var Listener:SavedGameListener? = nil 24 | 25 | public func init_listeners() { 26 | if Listener == nil { 27 | print("Install saved game listener") 28 | Listener = SavedGameListener() 29 | GKLocalPlayer.local.register(Listener!) 30 | } 31 | } 32 | 33 | public func authenticate(request: Int64) { 34 | Task { 35 | if GKLocalPlayer.local.isAuthenticated { 36 | receive_authentication(request, IosGCAuthResult.authenticated()) 37 | return 38 | } 39 | 40 | GKLocalPlayer.local.authenticateHandler = { gcAuthVC, error in 41 | if GKLocalPlayer.local.isAuthenticated { 42 | receive_authentication(request, IosGCAuthResult.authenticated()) 43 | } else if let vc = gcAuthVC { 44 | UIApplication.shared.keyWindow?.rootViewController?.present(vc, animated: true) 45 | receive_authentication(request, IosGCAuthResult.login_presented()) 46 | } 47 | else { 48 | receive_authentication(request, IosGCAuthResult.error(error!.localizedDescription)) 49 | } 50 | } 51 | } 52 | } 53 | 54 | public func get_player(request: Int64) { 55 | Task { 56 | let p = GKLocalPlayer.local; 57 | 58 | receive_player(request, IosGCPlayer.new(p.gamePlayerID, p.teamPlayerID, p.isAuthenticated, p.alias, p.displayName)) 59 | } 60 | } 61 | 62 | fileprivate func convert_save_game(_ save: GKSavedGame) throws -> IosGCSaveGame { 63 | return IosGCSaveGame.new(save.name!, save.deviceName!, UInt64(try save.modificationDate!.timeIntervalSince1970)) 64 | } 65 | 66 | fileprivate func convert_save_games(_ games: [GKSavedGame]) throws -> IosGCSaveGames { 67 | var result = RustVec() 68 | for game in games { 69 | result.push(value: try convert_save_game(game)) 70 | } 71 | return IosGCSaveGames.new(result) 72 | } 73 | 74 | public func save_game(request: Int64, data: RustString, name: RustString) { 75 | Task{ 76 | do { 77 | let gameData = try Data.init(base64Encoded:data.toString())! 78 | let save : GKSavedGame = try await GKLocalPlayer.local.saveGameData(gameData, withName: name.toString()) 79 | let rust_save = try convert_save_game(save) 80 | 81 | receive_saved_game(request, IosGCSavedGameResponse.done(rust_save)) 82 | } catch { 83 | receive_saved_game(request, IosGCSavedGameResponse.error(error.localizedDescription)) 84 | } 85 | } 86 | } 87 | 88 | public func load_game(request: Int64, save_game: IosGCSaveGame) { 89 | Task{ 90 | do { 91 | let games = await try GKLocalPlayer.local.fetchSavedGames(); 92 | for game in games { 93 | let rust_game = try convert_save_game(game) 94 | if IosGCSaveGame.equals(rust_game,save_game) { 95 | var data = try await game.loadData() 96 | let result = data.base64EncodedString() 97 | receive_load_game(request, IosGCLoadGamesResponse.done(rust_game,result)) 98 | return 99 | } 100 | } 101 | 102 | receive_load_game(request, IosGCLoadGamesResponse.unknown(save_game)) 103 | } catch { 104 | receive_load_game(request, IosGCLoadGamesResponse.error(error.localizedDescription)) 105 | } 106 | } 107 | } 108 | 109 | public func delete_game(request: Int64, name: RustString) { 110 | Task{ 111 | do { 112 | try await GKLocalPlayer.local.deleteSavedGames(withName: name.toString()) 113 | receive_deleted_game(request, IosGCDeleteSaveGameResponse.done(name)) 114 | } catch { 115 | receive_deleted_game(request, IosGCDeleteSaveGameResponse.error(error.localizedDescription)) 116 | } 117 | } 118 | } 119 | 120 | public func resolve_conflicting_games(request: Int64, save_games: IosGCSaveGames, data: RustString) { 121 | Task{ 122 | do { 123 | var found:[GKSavedGame] = [] 124 | let games = try await GKLocalPlayer.local.fetchSavedGames() 125 | 126 | for game in games { 127 | let rust_game = try convert_save_game(game) 128 | if IosGCSaveGames.contains(save_games, rust_game) { 129 | found.append(game) 130 | } 131 | } 132 | 133 | let gameData = try Data.init(base64Encoded:data.toString())! 134 | 135 | let result = try await GKLocalPlayer.local.resolveConflictingSavedGames(found, with: gameData) 136 | 137 | receive_resolved_conflicts(request, IosGCResolvedConflictsResponse.done(try convert_save_games(result))) 138 | } catch { 139 | receive_resolved_conflicts(request, IosGCResolvedConflictsResponse.error(error.localizedDescription)) 140 | } 141 | } 142 | } 143 | 144 | public func fetch_save_games(request: Int64) { 145 | Task{ 146 | do { 147 | let games = try await GKLocalPlayer.local.fetchSavedGames() 148 | 149 | let result = try convert_save_games(games) 150 | 151 | receive_save_games(request, IosGCSaveGamesResponse.done(result)) 152 | } catch { 153 | receive_save_games(request, IosGCSaveGamesResponse.error(error.localizedDescription)) 154 | } 155 | } 156 | } 157 | 158 | fileprivate func convert_achievement(_ a: GKAchievement) throws -> IosGCAchievement { 159 | return IosGCAchievement.new(a.identifier, a.percentComplete, a.isCompleted, UInt64(try a.lastReportedDate.timeIntervalSince1970)) 160 | } 161 | 162 | public func achievement_progress(request: Int64, id: RustString, progress: Double){ 163 | Task { 164 | do{ 165 | var achievement = GKAchievement.init(identifier: id.toString()) 166 | achievement.percentComplete = progress 167 | try await GKAchievement.report([achievement]) 168 | let response = try convert_achievement(achievement) 169 | receive_achievement_progress(request, IosGCAchievementProgressResponse.done(response)) 170 | } catch { 171 | receive_achievement_progress(request, IosGCAchievementProgressResponse.error(error.localizedDescription)) 172 | } 173 | } 174 | } 175 | 176 | public func reset_achievements(request: Int64) { 177 | Task { 178 | do{ 179 | try await GKAchievement.resetAchievements() 180 | receive_achievement_reset(request, IosGCAchievementsResetResponse.done()) 181 | } catch { 182 | receive_achievement_reset(request, IosGCAchievementsResetResponse.error(error.localizedDescription)) 183 | } 184 | } 185 | } 186 | 187 | public func leaderboards_score(request: Int64, id:RustString, score:Int64, context:Int64) { 188 | Task { 189 | do{ 190 | try await GKLeaderboard.submitScore(Int(score), context:Int(context), player:GKLocalPlayer.local, leaderboardIDs: [id.toString()]) 191 | receive_leaderboard_score(request, IosGCScoreSubmitResponse.done()) 192 | } catch { 193 | receive_leaderboard_score(request, IosGCScoreSubmitResponse.error(error.localizedDescription)) 194 | } 195 | } 196 | } 197 | 198 | public func trigger_view(state: Int32) { 199 | GKAccessPoint.shared.trigger(state: GKGameCenterViewControllerState(rawValue: Int(state)) ?? GKGameCenterViewControllerState.default){ 200 | //TODO: no idea why this gets never called 201 | } 202 | } 203 | 204 | public func fetch_signature(request: Int64) { 205 | Task { 206 | do{ 207 | let items = try await GKLocalPlayer.local.fetchItemsForIdentityVerificationSignature() 208 | 209 | let rust_items = IosGCFetchItemsForSignatureVerification.new( 210 | items.0.absoluteString, 211 | items.1.base64EncodedString(), 212 | items.2.base64EncodedString(), 213 | items.3) 214 | 215 | receive_items_for_signature_verification(request, IosGCFetchItemsForSignatureVerificationResponse.done(rust_items)) 216 | } catch { 217 | receive_items_for_signature_verification(request, IosGCFetchItemsForSignatureVerificationResponse.error(error.localizedDescription)) 218 | } 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /Sources/bevy_ios_gamecenter/SwiftBridgeCoreGC.swift: -------------------------------------------------------------------------------- 1 | import BevyIosGamecenterRust 2 | import Foundation 3 | 4 | extension RustString { 5 | public func toString() -> String { 6 | let str = self.as_str() 7 | let string = str.toString() 8 | 9 | return string 10 | } 11 | } 12 | 13 | extension RustStr { 14 | func toBufferPointer() -> UnsafeBufferPointer { 15 | let bytes = UnsafeBufferPointer(start: self.start, count: Int(self.len)) 16 | return bytes 17 | } 18 | 19 | public func toString() -> String { 20 | let bytes = self.toBufferPointer() 21 | return String(bytes: bytes, encoding: .utf8)! 22 | } 23 | } 24 | extension RustStr: Identifiable { 25 | public var id: String { 26 | self.toString() 27 | } 28 | } 29 | extension RustStr: Equatable { 30 | public static func == (lhs: RustStr, rhs: RustStr) -> Bool { 31 | return __swift_bridge__$RustStr$partial_eq(lhs, rhs); 32 | } 33 | } 34 | 35 | public protocol IntoRustString { 36 | func intoRustString() -> RustString; 37 | } 38 | 39 | extension String: IntoRustString { 40 | public func intoRustString() -> RustString { 41 | // TODO: When passing an owned Swift std String to Rust we've being wasteful here in that 42 | // we're creating a RustString (which involves Boxing a Rust std::string::String) 43 | // only to unbox it back into a String once it gets to the Rust side. 44 | // 45 | // A better approach would be to pass a RustStr to the Rust side and then have Rust 46 | // call `.to_string()` on the RustStr. 47 | RustString(self) 48 | } 49 | } 50 | 51 | extension RustString: IntoRustString { 52 | public func intoRustString() -> RustString { 53 | self 54 | } 55 | } 56 | 57 | /// If the String is Some: 58 | /// Safely get a scoped pointer to the String and then call the callback with a RustStr 59 | /// that uses that pointer. 60 | /// 61 | /// If the String is None: 62 | /// Call the callback with a RustStr that has a null pointer. 63 | /// The Rust side will know to treat this as `None`. 64 | func optionalStringIntoRustString(_ string: Optional) -> RustString? { 65 | if let val = string { 66 | return val.intoRustString() 67 | } else { 68 | return nil 69 | } 70 | } 71 | 72 | /// Used to safely get a pointer to a sequence of utf8 bytes, represented as a `RustStr`. 73 | /// 74 | /// For example, the Swift `String` implementation of the `ToRustStr` protocol does the following: 75 | /// 1. Use Swift's `String.utf8.withUnsafeBufferPointer` to get a pointer to the strings underlying 76 | /// utf8 bytes. 77 | /// 2. Construct a `RustStr` that points to these utf8 bytes. This is safe because `withUnsafeBufferPointer` 78 | /// guarantees that the buffer pointer will be valid for the duration of the `withUnsafeBufferPointer` 79 | /// callback. 80 | /// 3. Pass the `RustStr` to the closure that was passed into `RustStr.toRustStr`. 81 | public protocol ToRustStr { 82 | func toRustStr (_ withUnsafeRustStr: (RustStr) -> T) -> T; 83 | } 84 | 85 | extension String: ToRustStr { 86 | /// Safely get a scoped pointer to the String and then call the callback with a RustStr 87 | /// that uses that pointer. 88 | public func toRustStr (_ withUnsafeRustStr: (RustStr) -> T) -> T { 89 | return self.utf8CString.withUnsafeBufferPointer({ bufferPtr in 90 | let rustStr = RustStr( 91 | start: UnsafeMutableRawPointer(mutating: bufferPtr.baseAddress!).assumingMemoryBound(to: UInt8.self), 92 | // Subtract 1 because of the null termination character at the end 93 | len: UInt(bufferPtr.count - 1) 94 | ) 95 | return withUnsafeRustStr(rustStr) 96 | }) 97 | } 98 | } 99 | 100 | extension RustStr: ToRustStr { 101 | public func toRustStr (_ withUnsafeRustStr: (RustStr) -> T) -> T { 102 | return withUnsafeRustStr(self) 103 | } 104 | } 105 | 106 | func optionalRustStrToRustStr(_ str: Optional, _ withUnsafeRustStr: (RustStr) -> T) -> T { 107 | if let val = str { 108 | return val.toRustStr(withUnsafeRustStr) 109 | } else { 110 | return withUnsafeRustStr(RustStr(start: nil, len: 0)) 111 | } 112 | } 113 | public class RustVec { 114 | var ptr: UnsafeMutableRawPointer 115 | var isOwned: Bool = true 116 | 117 | public init(ptr: UnsafeMutableRawPointer) { 118 | self.ptr = ptr 119 | } 120 | 121 | public init() { 122 | ptr = T.vecOfSelfNew() 123 | isOwned = true 124 | } 125 | 126 | public func push (value: T) { 127 | T.vecOfSelfPush(vecPtr: ptr, value: value) 128 | } 129 | 130 | public func pop () -> Optional { 131 | T.vecOfSelfPop(vecPtr: ptr) 132 | } 133 | 134 | public func get(index: UInt) -> Optional { 135 | T.vecOfSelfGet(vecPtr: ptr, index: index) 136 | } 137 | 138 | public func as_ptr() -> UnsafePointer { 139 | UnsafePointer(OpaquePointer(T.vecOfSelfAsPtr(vecPtr: ptr))) 140 | } 141 | 142 | /// Rust returns a UInt, but we cast to an Int because many Swift APIs such as 143 | /// `ForEach(0..rustVec.len())` expect Int. 144 | public func len() -> Int { 145 | Int(T.vecOfSelfLen(vecPtr: ptr)) 146 | } 147 | 148 | deinit { 149 | if isOwned { 150 | T.vecOfSelfFree(vecPtr: ptr) 151 | } 152 | } 153 | } 154 | 155 | extension RustVec: Sequence { 156 | public func makeIterator() -> RustVecIterator { 157 | return RustVecIterator(self) 158 | } 159 | } 160 | 161 | public struct RustVecIterator: IteratorProtocol { 162 | var rustVec: RustVec 163 | var index: UInt = 0 164 | 165 | init (_ rustVec: RustVec) { 166 | self.rustVec = rustVec 167 | } 168 | 169 | public mutating func next() -> T.SelfRef? { 170 | let val = rustVec.get(index: index) 171 | index += 1 172 | return val 173 | } 174 | } 175 | 176 | extension RustVec: Collection { 177 | public typealias Index = Int 178 | 179 | public func index(after i: Int) -> Int { 180 | i + 1 181 | } 182 | 183 | public subscript(position: Int) -> T.SelfRef { 184 | self.get(index: UInt(position))! 185 | } 186 | 187 | public var startIndex: Int { 188 | 0 189 | } 190 | 191 | public var endIndex: Int { 192 | self.len() 193 | } 194 | } 195 | 196 | extension RustVec: RandomAccessCollection {} 197 | 198 | extension UnsafeBufferPointer { 199 | func toFfiSlice () -> __private__FfiSlice { 200 | __private__FfiSlice(start: UnsafeMutablePointer(mutating: self.baseAddress), len: UInt(self.count)) 201 | } 202 | } 203 | 204 | public protocol Vectorizable { 205 | associatedtype SelfRef 206 | associatedtype SelfRefMut 207 | 208 | static func vecOfSelfNew() -> UnsafeMutableRawPointer; 209 | 210 | static func vecOfSelfFree(vecPtr: UnsafeMutableRawPointer) 211 | 212 | static func vecOfSelfPush(vecPtr: UnsafeMutableRawPointer, value: Self) 213 | 214 | static func vecOfSelfPop(vecPtr: UnsafeMutableRawPointer) -> Optional 215 | 216 | static func vecOfSelfGet(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional 217 | 218 | static func vecOfSelfGetMut(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional 219 | 220 | static func vecOfSelfAsPtr(vecPtr: UnsafeMutableRawPointer) -> UnsafePointer 221 | 222 | static func vecOfSelfLen(vecPtr: UnsafeMutableRawPointer) -> UInt 223 | } 224 | 225 | extension UInt8: Vectorizable { 226 | public static func vecOfSelfNew() -> UnsafeMutableRawPointer { 227 | __swift_bridge__$Vec_u8$new() 228 | } 229 | 230 | public static func vecOfSelfFree(vecPtr: UnsafeMutableRawPointer) { 231 | __swift_bridge__$Vec_u8$_free(vecPtr) 232 | } 233 | 234 | public static func vecOfSelfPush(vecPtr: UnsafeMutableRawPointer, value: Self) { 235 | __swift_bridge__$Vec_u8$push(vecPtr, value) 236 | } 237 | 238 | public static func vecOfSelfPop(vecPtr: UnsafeMutableRawPointer) -> Optional { 239 | let val = __swift_bridge__$Vec_u8$pop(vecPtr) 240 | if val.is_some { 241 | return val.val 242 | } else { 243 | return nil 244 | } 245 | } 246 | 247 | public static func vecOfSelfGet(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 248 | let val = __swift_bridge__$Vec_u8$get(vecPtr, index) 249 | if val.is_some { 250 | return val.val 251 | } else { 252 | return nil 253 | } 254 | } 255 | 256 | public static func vecOfSelfGetMut(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 257 | let val = __swift_bridge__$Vec_u8$get_mut(vecPtr, index) 258 | if val.is_some { 259 | return val.val 260 | } else { 261 | return nil 262 | } 263 | } 264 | 265 | public static func vecOfSelfAsPtr(vecPtr: UnsafeMutableRawPointer) -> UnsafePointer { 266 | UnsafePointer(OpaquePointer(__swift_bridge__$Vec_u8$as_ptr(vecPtr))) 267 | } 268 | 269 | public static func vecOfSelfLen(vecPtr: UnsafeMutableRawPointer) -> UInt { 270 | __swift_bridge__$Vec_u8$len(vecPtr) 271 | } 272 | } 273 | 274 | extension UInt16: Vectorizable { 275 | public static func vecOfSelfNew() -> UnsafeMutableRawPointer { 276 | __swift_bridge__$Vec_u16$new() 277 | } 278 | 279 | public static func vecOfSelfFree(vecPtr: UnsafeMutableRawPointer) { 280 | __swift_bridge__$Vec_u16$_free(vecPtr) 281 | } 282 | 283 | public static func vecOfSelfPush(vecPtr: UnsafeMutableRawPointer, value: Self) { 284 | __swift_bridge__$Vec_u16$push(vecPtr, value) 285 | } 286 | 287 | public static func vecOfSelfPop(vecPtr: UnsafeMutableRawPointer) -> Optional { 288 | let val = __swift_bridge__$Vec_u16$pop(vecPtr) 289 | if val.is_some { 290 | return val.val 291 | } else { 292 | return nil 293 | } 294 | } 295 | 296 | public static func vecOfSelfGet(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 297 | let val = __swift_bridge__$Vec_u16$get(vecPtr, index) 298 | if val.is_some { 299 | return val.val 300 | } else { 301 | return nil 302 | } 303 | } 304 | 305 | public static func vecOfSelfGetMut(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 306 | let val = __swift_bridge__$Vec_u16$get_mut(vecPtr, index) 307 | if val.is_some { 308 | return val.val 309 | } else { 310 | return nil 311 | } 312 | } 313 | 314 | public static func vecOfSelfAsPtr(vecPtr: UnsafeMutableRawPointer) -> UnsafePointer { 315 | UnsafePointer(OpaquePointer(__swift_bridge__$Vec_u16$as_ptr(vecPtr))) 316 | } 317 | 318 | public static func vecOfSelfLen(vecPtr: UnsafeMutableRawPointer) -> UInt { 319 | __swift_bridge__$Vec_u16$len(vecPtr) 320 | } 321 | } 322 | 323 | extension UInt32: Vectorizable { 324 | public static func vecOfSelfNew() -> UnsafeMutableRawPointer { 325 | __swift_bridge__$Vec_u32$new() 326 | } 327 | 328 | public static func vecOfSelfFree(vecPtr: UnsafeMutableRawPointer) { 329 | __swift_bridge__$Vec_u32$_free(vecPtr) 330 | } 331 | 332 | public static func vecOfSelfPush(vecPtr: UnsafeMutableRawPointer, value: Self) { 333 | __swift_bridge__$Vec_u32$push(vecPtr, value) 334 | } 335 | 336 | public static func vecOfSelfPop(vecPtr: UnsafeMutableRawPointer) -> Optional { 337 | let val = __swift_bridge__$Vec_u32$pop(vecPtr) 338 | if val.is_some { 339 | return val.val 340 | } else { 341 | return nil 342 | } 343 | } 344 | 345 | public static func vecOfSelfGet(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 346 | let val = __swift_bridge__$Vec_u32$get(vecPtr, index) 347 | if val.is_some { 348 | return val.val 349 | } else { 350 | return nil 351 | } 352 | } 353 | 354 | public static func vecOfSelfGetMut(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 355 | let val = __swift_bridge__$Vec_u32$get_mut(vecPtr, index) 356 | if val.is_some { 357 | return val.val 358 | } else { 359 | return nil 360 | } 361 | } 362 | 363 | public static func vecOfSelfAsPtr(vecPtr: UnsafeMutableRawPointer) -> UnsafePointer { 364 | UnsafePointer(OpaquePointer(__swift_bridge__$Vec_u32$as_ptr(vecPtr))) 365 | } 366 | 367 | public static func vecOfSelfLen(vecPtr: UnsafeMutableRawPointer) -> UInt { 368 | __swift_bridge__$Vec_u32$len(vecPtr) 369 | } 370 | } 371 | 372 | extension UInt64: Vectorizable { 373 | public static func vecOfSelfNew() -> UnsafeMutableRawPointer { 374 | __swift_bridge__$Vec_u64$new() 375 | } 376 | 377 | public static func vecOfSelfFree(vecPtr: UnsafeMutableRawPointer) { 378 | __swift_bridge__$Vec_u64$_free(vecPtr) 379 | } 380 | 381 | public static func vecOfSelfPush(vecPtr: UnsafeMutableRawPointer, value: Self) { 382 | __swift_bridge__$Vec_u64$push(vecPtr, value) 383 | } 384 | 385 | public static func vecOfSelfPop(vecPtr: UnsafeMutableRawPointer) -> Optional { 386 | let val = __swift_bridge__$Vec_u64$pop(vecPtr) 387 | if val.is_some { 388 | return val.val 389 | } else { 390 | return nil 391 | } 392 | } 393 | 394 | public static func vecOfSelfGet(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 395 | let val = __swift_bridge__$Vec_u64$get(vecPtr, index) 396 | if val.is_some { 397 | return val.val 398 | } else { 399 | return nil 400 | } 401 | } 402 | 403 | public static func vecOfSelfGetMut(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 404 | let val = __swift_bridge__$Vec_u64$get_mut(vecPtr, index) 405 | if val.is_some { 406 | return val.val 407 | } else { 408 | return nil 409 | } 410 | } 411 | 412 | public static func vecOfSelfAsPtr(vecPtr: UnsafeMutableRawPointer) -> UnsafePointer { 413 | UnsafePointer(OpaquePointer(__swift_bridge__$Vec_u64$as_ptr(vecPtr))) 414 | } 415 | 416 | public static func vecOfSelfLen(vecPtr: UnsafeMutableRawPointer) -> UInt { 417 | __swift_bridge__$Vec_u64$len(vecPtr) 418 | } 419 | } 420 | 421 | extension UInt: Vectorizable { 422 | public static func vecOfSelfNew() -> UnsafeMutableRawPointer { 423 | __swift_bridge__$Vec_usize$new() 424 | } 425 | 426 | public static func vecOfSelfFree(vecPtr: UnsafeMutableRawPointer) { 427 | __swift_bridge__$Vec_usize$_free(vecPtr) 428 | } 429 | 430 | public static func vecOfSelfPush(vecPtr: UnsafeMutableRawPointer, value: Self) { 431 | __swift_bridge__$Vec_usize$push(vecPtr, value) 432 | } 433 | 434 | public static func vecOfSelfPop(vecPtr: UnsafeMutableRawPointer) -> Optional { 435 | let val = __swift_bridge__$Vec_usize$pop(vecPtr) 436 | if val.is_some { 437 | return val.val 438 | } else { 439 | return nil 440 | } 441 | } 442 | 443 | public static func vecOfSelfGet(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 444 | let val = __swift_bridge__$Vec_usize$get(vecPtr, index) 445 | if val.is_some { 446 | return val.val 447 | } else { 448 | return nil 449 | } 450 | } 451 | 452 | public static func vecOfSelfGetMut(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 453 | let val = __swift_bridge__$Vec_usize$get_mut(vecPtr, index) 454 | if val.is_some { 455 | return val.val 456 | } else { 457 | return nil 458 | } 459 | } 460 | 461 | public static func vecOfSelfAsPtr(vecPtr: UnsafeMutableRawPointer) -> UnsafePointer { 462 | UnsafePointer(OpaquePointer(__swift_bridge__$Vec_usize$as_ptr(vecPtr))) 463 | } 464 | 465 | public static func vecOfSelfLen(vecPtr: UnsafeMutableRawPointer) -> UInt { 466 | __swift_bridge__$Vec_usize$len(vecPtr) 467 | } 468 | } 469 | 470 | extension Int8: Vectorizable { 471 | public static func vecOfSelfNew() -> UnsafeMutableRawPointer { 472 | __swift_bridge__$Vec_i8$new() 473 | } 474 | 475 | public static func vecOfSelfFree(vecPtr: UnsafeMutableRawPointer) { 476 | __swift_bridge__$Vec_i8$_free(vecPtr) 477 | } 478 | 479 | public static func vecOfSelfPush(vecPtr: UnsafeMutableRawPointer, value: Self) { 480 | __swift_bridge__$Vec_i8$push(vecPtr, value) 481 | } 482 | 483 | public static func vecOfSelfPop(vecPtr: UnsafeMutableRawPointer) -> Optional { 484 | let val = __swift_bridge__$Vec_i8$pop(vecPtr) 485 | if val.is_some { 486 | return val.val 487 | } else { 488 | return nil 489 | } 490 | } 491 | 492 | public static func vecOfSelfGet(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 493 | let val = __swift_bridge__$Vec_i8$get(vecPtr, index) 494 | if val.is_some { 495 | return val.val 496 | } else { 497 | return nil 498 | } 499 | } 500 | 501 | public static func vecOfSelfGetMut(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 502 | let val = __swift_bridge__$Vec_i8$get_mut(vecPtr, index) 503 | if val.is_some { 504 | return val.val 505 | } else { 506 | return nil 507 | } 508 | } 509 | 510 | public static func vecOfSelfAsPtr(vecPtr: UnsafeMutableRawPointer) -> UnsafePointer { 511 | UnsafePointer(OpaquePointer(__swift_bridge__$Vec_i8$as_ptr(vecPtr))) 512 | } 513 | 514 | public static func vecOfSelfLen(vecPtr: UnsafeMutableRawPointer) -> UInt { 515 | __swift_bridge__$Vec_i8$len(vecPtr) 516 | } 517 | } 518 | 519 | extension Int16: Vectorizable { 520 | public static func vecOfSelfNew() -> UnsafeMutableRawPointer { 521 | __swift_bridge__$Vec_i16$new() 522 | } 523 | 524 | public static func vecOfSelfFree(vecPtr: UnsafeMutableRawPointer) { 525 | __swift_bridge__$Vec_i16$_free(vecPtr) 526 | } 527 | 528 | public static func vecOfSelfPush(vecPtr: UnsafeMutableRawPointer, value: Self) { 529 | __swift_bridge__$Vec_i16$push(vecPtr, value) 530 | } 531 | 532 | public static func vecOfSelfPop(vecPtr: UnsafeMutableRawPointer) -> Optional { 533 | let val = __swift_bridge__$Vec_i16$pop(vecPtr) 534 | if val.is_some { 535 | return val.val 536 | } else { 537 | return nil 538 | } 539 | } 540 | 541 | public static func vecOfSelfGet(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 542 | let val = __swift_bridge__$Vec_i16$get(vecPtr, index) 543 | if val.is_some { 544 | return val.val 545 | } else { 546 | return nil 547 | } 548 | } 549 | 550 | public static func vecOfSelfGetMut(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 551 | let val = __swift_bridge__$Vec_i16$get_mut(vecPtr, index) 552 | if val.is_some { 553 | return val.val 554 | } else { 555 | return nil 556 | } 557 | } 558 | 559 | public static func vecOfSelfAsPtr(vecPtr: UnsafeMutableRawPointer) -> UnsafePointer { 560 | UnsafePointer(OpaquePointer(__swift_bridge__$Vec_i16$as_ptr(vecPtr))) 561 | } 562 | 563 | public static func vecOfSelfLen(vecPtr: UnsafeMutableRawPointer) -> UInt { 564 | __swift_bridge__$Vec_i16$len(vecPtr) 565 | } 566 | } 567 | 568 | extension Int32: Vectorizable { 569 | public static func vecOfSelfNew() -> UnsafeMutableRawPointer { 570 | __swift_bridge__$Vec_i32$new() 571 | } 572 | 573 | public static func vecOfSelfFree(vecPtr: UnsafeMutableRawPointer) { 574 | __swift_bridge__$Vec_i32$_free(vecPtr) 575 | } 576 | 577 | public static func vecOfSelfPush(vecPtr: UnsafeMutableRawPointer, value: Self) { 578 | __swift_bridge__$Vec_i32$push(vecPtr, value) 579 | } 580 | 581 | public static func vecOfSelfPop(vecPtr: UnsafeMutableRawPointer) -> Optional { 582 | let val = __swift_bridge__$Vec_i32$pop(vecPtr) 583 | if val.is_some { 584 | return val.val 585 | } else { 586 | return nil 587 | } 588 | } 589 | 590 | public static func vecOfSelfGet(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 591 | let val = __swift_bridge__$Vec_i32$get(vecPtr, index) 592 | if val.is_some { 593 | return val.val 594 | } else { 595 | return nil 596 | } 597 | } 598 | 599 | public static func vecOfSelfGetMut(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 600 | let val = __swift_bridge__$Vec_i32$get_mut(vecPtr, index) 601 | if val.is_some { 602 | return val.val 603 | } else { 604 | return nil 605 | } 606 | } 607 | 608 | public static func vecOfSelfAsPtr(vecPtr: UnsafeMutableRawPointer) -> UnsafePointer { 609 | UnsafePointer(OpaquePointer(__swift_bridge__$Vec_i32$as_ptr(vecPtr))) 610 | } 611 | 612 | public static func vecOfSelfLen(vecPtr: UnsafeMutableRawPointer) -> UInt { 613 | __swift_bridge__$Vec_i32$len(vecPtr) 614 | } 615 | } 616 | 617 | extension Int64: Vectorizable { 618 | public static func vecOfSelfNew() -> UnsafeMutableRawPointer { 619 | __swift_bridge__$Vec_i64$new() 620 | } 621 | 622 | public static func vecOfSelfFree(vecPtr: UnsafeMutableRawPointer) { 623 | __swift_bridge__$Vec_i64$_free(vecPtr) 624 | } 625 | 626 | public static func vecOfSelfPush(vecPtr: UnsafeMutableRawPointer, value: Self) { 627 | __swift_bridge__$Vec_i64$push(vecPtr, value) 628 | } 629 | 630 | public static func vecOfSelfPop(vecPtr: UnsafeMutableRawPointer) -> Optional { 631 | let val = __swift_bridge__$Vec_i64$pop(vecPtr) 632 | if val.is_some { 633 | return val.val 634 | } else { 635 | return nil 636 | } 637 | } 638 | 639 | public static func vecOfSelfGet(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 640 | let val = __swift_bridge__$Vec_i64$get(vecPtr, index) 641 | if val.is_some { 642 | return val.val 643 | } else { 644 | return nil 645 | } 646 | } 647 | 648 | public static func vecOfSelfGetMut(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 649 | let val = __swift_bridge__$Vec_i64$get_mut(vecPtr, index) 650 | if val.is_some { 651 | return val.val 652 | } else { 653 | return nil 654 | } 655 | } 656 | 657 | public static func vecOfSelfAsPtr(vecPtr: UnsafeMutableRawPointer) -> UnsafePointer { 658 | UnsafePointer(OpaquePointer(__swift_bridge__$Vec_i64$as_ptr(vecPtr))) 659 | } 660 | 661 | public static func vecOfSelfLen(vecPtr: UnsafeMutableRawPointer) -> UInt { 662 | __swift_bridge__$Vec_i64$len(vecPtr) 663 | } 664 | } 665 | 666 | extension Int: Vectorizable { 667 | public static func vecOfSelfNew() -> UnsafeMutableRawPointer { 668 | __swift_bridge__$Vec_isize$new() 669 | } 670 | 671 | public static func vecOfSelfFree(vecPtr: UnsafeMutableRawPointer) { 672 | __swift_bridge__$Vec_isize$_free(vecPtr) 673 | } 674 | 675 | public static func vecOfSelfPush(vecPtr: UnsafeMutableRawPointer, value: Self) { 676 | __swift_bridge__$Vec_isize$push(vecPtr, value) 677 | } 678 | 679 | public static func vecOfSelfPop(vecPtr: UnsafeMutableRawPointer) -> Optional { 680 | let val = __swift_bridge__$Vec_isize$pop(vecPtr) 681 | if val.is_some { 682 | return val.val 683 | } else { 684 | return nil 685 | } 686 | } 687 | 688 | public static func vecOfSelfGet(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 689 | let val = __swift_bridge__$Vec_isize$get(vecPtr, index) 690 | if val.is_some { 691 | return val.val 692 | } else { 693 | return nil 694 | } 695 | } 696 | 697 | public static func vecOfSelfGetMut(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 698 | let val = __swift_bridge__$Vec_isize$get_mut(vecPtr, index) 699 | if val.is_some { 700 | return val.val 701 | } else { 702 | return nil 703 | } 704 | } 705 | 706 | public static func vecOfSelfAsPtr(vecPtr: UnsafeMutableRawPointer) -> UnsafePointer { 707 | UnsafePointer(OpaquePointer(__swift_bridge__$Vec_isize$as_ptr(vecPtr))) 708 | } 709 | 710 | public static func vecOfSelfLen(vecPtr: UnsafeMutableRawPointer) -> UInt { 711 | __swift_bridge__$Vec_isize$len(vecPtr) 712 | } 713 | } 714 | 715 | extension Bool: Vectorizable { 716 | public static func vecOfSelfNew() -> UnsafeMutableRawPointer { 717 | __swift_bridge__$Vec_bool$new() 718 | } 719 | 720 | public static func vecOfSelfFree(vecPtr: UnsafeMutableRawPointer) { 721 | __swift_bridge__$Vec_bool$_free(vecPtr) 722 | } 723 | 724 | public static func vecOfSelfPush(vecPtr: UnsafeMutableRawPointer, value: Self) { 725 | __swift_bridge__$Vec_bool$push(vecPtr, value) 726 | } 727 | 728 | public static func vecOfSelfPop(vecPtr: UnsafeMutableRawPointer) -> Optional { 729 | let val = __swift_bridge__$Vec_bool$pop(vecPtr) 730 | if val.is_some { 731 | return val.val 732 | } else { 733 | return nil 734 | } 735 | } 736 | 737 | public static func vecOfSelfGet(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 738 | let val = __swift_bridge__$Vec_bool$get(vecPtr, index) 739 | if val.is_some { 740 | return val.val 741 | } else { 742 | return nil 743 | } 744 | } 745 | 746 | public static func vecOfSelfGetMut(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 747 | let val = __swift_bridge__$Vec_bool$get_mut(vecPtr, index) 748 | if val.is_some { 749 | return val.val 750 | } else { 751 | return nil 752 | } 753 | } 754 | 755 | public static func vecOfSelfAsPtr(vecPtr: UnsafeMutableRawPointer) -> UnsafePointer { 756 | UnsafePointer(OpaquePointer(__swift_bridge__$Vec_bool$as_ptr(vecPtr))) 757 | } 758 | 759 | public static func vecOfSelfLen(vecPtr: UnsafeMutableRawPointer) -> UInt { 760 | __swift_bridge__$Vec_bool$len(vecPtr) 761 | } 762 | } 763 | 764 | extension Float: Vectorizable { 765 | public static func vecOfSelfNew() -> UnsafeMutableRawPointer { 766 | __swift_bridge__$Vec_f32$new() 767 | } 768 | 769 | public static func vecOfSelfFree(vecPtr: UnsafeMutableRawPointer) { 770 | __swift_bridge__$Vec_f32$_free(vecPtr) 771 | } 772 | 773 | public static func vecOfSelfPush(vecPtr: UnsafeMutableRawPointer, value: Self) { 774 | __swift_bridge__$Vec_f32$push(vecPtr, value) 775 | } 776 | 777 | public static func vecOfSelfPop(vecPtr: UnsafeMutableRawPointer) -> Optional { 778 | let val = __swift_bridge__$Vec_f32$pop(vecPtr) 779 | if val.is_some { 780 | return val.val 781 | } else { 782 | return nil 783 | } 784 | } 785 | 786 | public static func vecOfSelfGet(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 787 | let val = __swift_bridge__$Vec_f32$get(vecPtr, index) 788 | if val.is_some { 789 | return val.val 790 | } else { 791 | return nil 792 | } 793 | } 794 | 795 | public static func vecOfSelfGetMut(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 796 | let val = __swift_bridge__$Vec_f32$get_mut(vecPtr, index) 797 | if val.is_some { 798 | return val.val 799 | } else { 800 | return nil 801 | } 802 | } 803 | 804 | public static func vecOfSelfAsPtr(vecPtr: UnsafeMutableRawPointer) -> UnsafePointer { 805 | UnsafePointer(OpaquePointer(__swift_bridge__$Vec_f32$as_ptr(vecPtr))) 806 | } 807 | 808 | public static func vecOfSelfLen(vecPtr: UnsafeMutableRawPointer) -> UInt { 809 | __swift_bridge__$Vec_f32$len(vecPtr) 810 | } 811 | } 812 | 813 | extension Double: Vectorizable { 814 | public static func vecOfSelfNew() -> UnsafeMutableRawPointer { 815 | __swift_bridge__$Vec_f64$new() 816 | } 817 | 818 | public static func vecOfSelfFree(vecPtr: UnsafeMutableRawPointer) { 819 | __swift_bridge__$Vec_f64$_free(vecPtr) 820 | } 821 | 822 | public static func vecOfSelfPush(vecPtr: UnsafeMutableRawPointer, value: Self) { 823 | __swift_bridge__$Vec_f64$push(vecPtr, value) 824 | } 825 | 826 | public static func vecOfSelfPop(vecPtr: UnsafeMutableRawPointer) -> Optional { 827 | let val = __swift_bridge__$Vec_f64$pop(vecPtr) 828 | if val.is_some { 829 | return val.val 830 | } else { 831 | return nil 832 | } 833 | } 834 | 835 | public static func vecOfSelfGet(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 836 | let val = __swift_bridge__$Vec_f64$get(vecPtr, index) 837 | if val.is_some { 838 | return val.val 839 | } else { 840 | return nil 841 | } 842 | } 843 | 844 | public static func vecOfSelfGetMut(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 845 | let val = __swift_bridge__$Vec_f64$get_mut(vecPtr, index) 846 | if val.is_some { 847 | return val.val 848 | } else { 849 | return nil 850 | } 851 | } 852 | 853 | public static func vecOfSelfAsPtr(vecPtr: UnsafeMutableRawPointer) -> UnsafePointer { 854 | UnsafePointer(OpaquePointer(__swift_bridge__$Vec_f64$as_ptr(vecPtr))) 855 | } 856 | 857 | public static func vecOfSelfLen(vecPtr: UnsafeMutableRawPointer) -> UInt { 858 | __swift_bridge__$Vec_f64$len(vecPtr) 859 | } 860 | } 861 | 862 | protocol SwiftBridgeGenericFreer { 863 | func rust_free(); 864 | } 865 | 866 | protocol SwiftBridgeGenericCopyTypeFfiRepr {} 867 | 868 | public class RustString: RustStringRefMut { 869 | var isOwned: Bool = true 870 | 871 | public override init(ptr: UnsafeMutableRawPointer) { 872 | super.init(ptr: ptr) 873 | } 874 | 875 | deinit { 876 | if isOwned { 877 | __swift_bridge__$RustString$_free(ptr) 878 | } 879 | } 880 | } 881 | extension RustString { 882 | public convenience init() { 883 | self.init(ptr: __swift_bridge__$RustString$new()) 884 | } 885 | 886 | public convenience init(_ str: GenericToRustStr) { 887 | self.init(ptr: str.toRustStr({ strAsRustStr in 888 | __swift_bridge__$RustString$new_with_str(strAsRustStr) 889 | })) 890 | } 891 | } 892 | public class RustStringRefMut: RustStringRef { 893 | public override init(ptr: UnsafeMutableRawPointer) { 894 | super.init(ptr: ptr) 895 | } 896 | } 897 | public class RustStringRef { 898 | var ptr: UnsafeMutableRawPointer 899 | 900 | public init(ptr: UnsafeMutableRawPointer) { 901 | self.ptr = ptr 902 | } 903 | } 904 | extension RustStringRef { 905 | public func len() -> UInt { 906 | __swift_bridge__$RustString$len(ptr) 907 | } 908 | 909 | public func as_str() -> RustStr { 910 | __swift_bridge__$RustString$as_str(ptr) 911 | } 912 | 913 | public func trim() -> RustStr { 914 | __swift_bridge__$RustString$trim(ptr) 915 | } 916 | } 917 | extension RustString: Vectorizable { 918 | public static func vecOfSelfNew() -> UnsafeMutableRawPointer { 919 | __swift_bridge__$Vec_RustString$new() 920 | } 921 | 922 | public static func vecOfSelfFree(vecPtr: UnsafeMutableRawPointer) { 923 | __swift_bridge__$Vec_RustString$drop(vecPtr) 924 | } 925 | 926 | public static func vecOfSelfPush(vecPtr: UnsafeMutableRawPointer, value: RustString) { 927 | __swift_bridge__$Vec_RustString$push(vecPtr, {value.isOwned = false; return value.ptr;}()) 928 | } 929 | 930 | public static func vecOfSelfPop(vecPtr: UnsafeMutableRawPointer) -> Optional { 931 | let pointer = __swift_bridge__$Vec_RustString$pop(vecPtr) 932 | if pointer == nil { 933 | return nil 934 | } else { 935 | return (RustString(ptr: pointer!) as! Self) 936 | } 937 | } 938 | 939 | public static func vecOfSelfGet(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 940 | let pointer = __swift_bridge__$Vec_RustString$get(vecPtr, index) 941 | if pointer == nil { 942 | return nil 943 | } else { 944 | return RustStringRef(ptr: pointer!) 945 | } 946 | } 947 | 948 | public static func vecOfSelfGetMut(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional { 949 | let pointer = __swift_bridge__$Vec_RustString$get_mut(vecPtr, index) 950 | if pointer == nil { 951 | return nil 952 | } else { 953 | return RustStringRefMut(ptr: pointer!) 954 | } 955 | } 956 | 957 | public static func vecOfSelfAsPtr(vecPtr: UnsafeMutableRawPointer) -> UnsafePointer { 958 | UnsafePointer(OpaquePointer(__swift_bridge__$Vec_RustString$as_ptr(vecPtr))) 959 | } 960 | 961 | public static func vecOfSelfLen(vecPtr: UnsafeMutableRawPointer) -> UInt { 962 | __swift_bridge__$Vec_RustString$len(vecPtr) 963 | } 964 | } 965 | 966 | public class __private__RustFnOnceCallbackNoArgsNoRet { 967 | var ptr: UnsafeMutableRawPointer 968 | var called = false 969 | 970 | init(ptr: UnsafeMutableRawPointer) { 971 | self.ptr = ptr 972 | } 973 | 974 | deinit { 975 | if !called { 976 | __swift_bridge__$free_boxed_fn_once_no_args_no_return(ptr) 977 | } 978 | } 979 | 980 | func call() { 981 | if called { 982 | fatalError("Cannot call a Rust FnOnce function twice") 983 | } 984 | called = true 985 | return __swift_bridge__$call_boxed_fn_once_no_args_no_return(ptr) 986 | } 987 | } 988 | 989 | 990 | public enum RustResult { 991 | case Ok(T) 992 | case Err(E) 993 | } 994 | 995 | extension RustResult { 996 | func ok() -> T? { 997 | switch self { 998 | case .Ok(let ok): 999 | return ok 1000 | case .Err(_): 1001 | return nil 1002 | } 1003 | } 1004 | 1005 | func err() -> E? { 1006 | switch self { 1007 | case .Ok(_): 1008 | return nil 1009 | case .Err(let err): 1010 | return err 1011 | } 1012 | } 1013 | 1014 | func toResult() -> Result 1015 | where E: Error { 1016 | switch self { 1017 | case .Ok(let ok): 1018 | return .success(ok) 1019 | case .Err(let err): 1020 | return .failure(err) 1021 | } 1022 | } 1023 | } 1024 | 1025 | 1026 | extension __private__OptionU8 { 1027 | func intoSwiftRepr() -> Optional { 1028 | if self.is_some { 1029 | return self.val 1030 | } else { 1031 | return nil 1032 | } 1033 | } 1034 | 1035 | init(_ val: Optional) { 1036 | if let val = val { 1037 | self = Self(val: val, is_some: true) 1038 | } else { 1039 | self = Self(val: 123, is_some: false) 1040 | } 1041 | } 1042 | } 1043 | extension Optional where Wrapped == UInt8 { 1044 | func intoFfiRepr() -> __private__OptionU8 { 1045 | __private__OptionU8(self) 1046 | } 1047 | } 1048 | 1049 | extension __private__OptionI8 { 1050 | func intoSwiftRepr() -> Optional { 1051 | if self.is_some { 1052 | return self.val 1053 | } else { 1054 | return nil 1055 | } 1056 | } 1057 | 1058 | init(_ val: Optional) { 1059 | if let val = val { 1060 | self = Self(val: val, is_some: true) 1061 | } else { 1062 | self = Self(val: 123, is_some: false) 1063 | } 1064 | } 1065 | } 1066 | extension Optional where Wrapped == Int8 { 1067 | func intoFfiRepr() -> __private__OptionI8 { 1068 | __private__OptionI8(self) 1069 | } 1070 | } 1071 | 1072 | extension __private__OptionU16 { 1073 | func intoSwiftRepr() -> Optional { 1074 | if self.is_some { 1075 | return self.val 1076 | } else { 1077 | return nil 1078 | } 1079 | } 1080 | 1081 | init(_ val: Optional) { 1082 | if let val = val { 1083 | self = Self(val: val, is_some: true) 1084 | } else { 1085 | self = Self(val: 123, is_some: false) 1086 | } 1087 | } 1088 | } 1089 | extension Optional where Wrapped == UInt16 { 1090 | func intoFfiRepr() -> __private__OptionU16 { 1091 | __private__OptionU16(self) 1092 | } 1093 | } 1094 | 1095 | extension __private__OptionI16 { 1096 | func intoSwiftRepr() -> Optional { 1097 | if self.is_some { 1098 | return self.val 1099 | } else { 1100 | return nil 1101 | } 1102 | } 1103 | 1104 | init(_ val: Optional) { 1105 | if let val = val { 1106 | self = Self(val: val, is_some: true) 1107 | } else { 1108 | self = Self(val: 123, is_some: false) 1109 | } 1110 | } 1111 | } 1112 | extension Optional where Wrapped == Int16 { 1113 | func intoFfiRepr() -> __private__OptionI16 { 1114 | __private__OptionI16(self) 1115 | } 1116 | } 1117 | 1118 | extension __private__OptionU32 { 1119 | func intoSwiftRepr() -> Optional { 1120 | if self.is_some { 1121 | return self.val 1122 | } else { 1123 | return nil 1124 | } 1125 | } 1126 | 1127 | init(_ val: Optional) { 1128 | if let val = val { 1129 | self = Self(val: val, is_some: true) 1130 | } else { 1131 | self = Self(val: 123, is_some: false) 1132 | } 1133 | } 1134 | } 1135 | extension Optional where Wrapped == UInt32 { 1136 | func intoFfiRepr() -> __private__OptionU32 { 1137 | __private__OptionU32(self) 1138 | } 1139 | } 1140 | 1141 | extension __private__OptionI32 { 1142 | func intoSwiftRepr() -> Optional { 1143 | if self.is_some { 1144 | return self.val 1145 | } else { 1146 | return nil 1147 | } 1148 | } 1149 | 1150 | init(_ val: Optional) { 1151 | if let val = val { 1152 | self = Self(val: val, is_some: true) 1153 | } else { 1154 | self = Self(val: 123, is_some: false) 1155 | } 1156 | } 1157 | } 1158 | extension Optional where Wrapped == Int32 { 1159 | func intoFfiRepr() -> __private__OptionI32 { 1160 | __private__OptionI32(self) 1161 | } 1162 | } 1163 | 1164 | extension __private__OptionU64 { 1165 | func intoSwiftRepr() -> Optional { 1166 | if self.is_some { 1167 | return self.val 1168 | } else { 1169 | return nil 1170 | } 1171 | } 1172 | 1173 | init(_ val: Optional) { 1174 | if let val = val { 1175 | self = Self(val: val, is_some: true) 1176 | } else { 1177 | self = Self(val: 123, is_some: false) 1178 | } 1179 | } 1180 | } 1181 | extension Optional where Wrapped == UInt64 { 1182 | func intoFfiRepr() -> __private__OptionU64 { 1183 | __private__OptionU64(self) 1184 | } 1185 | } 1186 | 1187 | extension __private__OptionI64 { 1188 | func intoSwiftRepr() -> Optional { 1189 | if self.is_some { 1190 | return self.val 1191 | } else { 1192 | return nil 1193 | } 1194 | } 1195 | 1196 | init(_ val: Optional) { 1197 | if let val = val { 1198 | self = Self(val: val, is_some: true) 1199 | } else { 1200 | self = Self(val: 123, is_some: false) 1201 | } 1202 | } 1203 | } 1204 | extension Optional where Wrapped == Int64 { 1205 | func intoFfiRepr() -> __private__OptionI64 { 1206 | __private__OptionI64(self) 1207 | } 1208 | } 1209 | 1210 | extension __private__OptionUsize { 1211 | func intoSwiftRepr() -> Optional { 1212 | if self.is_some { 1213 | return self.val 1214 | } else { 1215 | return nil 1216 | } 1217 | } 1218 | 1219 | init(_ val: Optional) { 1220 | if let val = val { 1221 | self = Self(val: val, is_some: true) 1222 | } else { 1223 | self = Self(val: 123, is_some: false) 1224 | } 1225 | } 1226 | } 1227 | extension Optional where Wrapped == UInt { 1228 | func intoFfiRepr() -> __private__OptionUsize { 1229 | __private__OptionUsize(self) 1230 | } 1231 | } 1232 | 1233 | extension __private__OptionIsize { 1234 | func intoSwiftRepr() -> Optional { 1235 | if self.is_some { 1236 | return self.val 1237 | } else { 1238 | return nil 1239 | } 1240 | } 1241 | 1242 | init(_ val: Optional) { 1243 | if let val = val { 1244 | self = Self(val: val, is_some: true) 1245 | } else { 1246 | self = Self(val: 123, is_some: false) 1247 | } 1248 | } 1249 | } 1250 | extension Optional where Wrapped == Int { 1251 | func intoFfiRepr() -> __private__OptionIsize { 1252 | __private__OptionIsize(self) 1253 | } 1254 | } 1255 | 1256 | extension __private__OptionF32 { 1257 | func intoSwiftRepr() -> Optional { 1258 | if self.is_some { 1259 | return self.val 1260 | } else { 1261 | return nil 1262 | } 1263 | } 1264 | 1265 | init(_ val: Optional) { 1266 | if let val = val { 1267 | self = Self(val: val, is_some: true) 1268 | } else { 1269 | self = Self(val: 123.4, is_some: false) 1270 | } 1271 | } 1272 | } 1273 | extension Optional where Wrapped == Float { 1274 | func intoFfiRepr() -> __private__OptionF32 { 1275 | __private__OptionF32(self) 1276 | } 1277 | } 1278 | 1279 | extension __private__OptionF64 { 1280 | func intoSwiftRepr() -> Optional { 1281 | if self.is_some { 1282 | return self.val 1283 | } else { 1284 | return nil 1285 | } 1286 | } 1287 | 1288 | init(_ val: Optional) { 1289 | if let val = val { 1290 | self = Self(val: val, is_some: true) 1291 | } else { 1292 | self = Self(val: 123.4, is_some: false) 1293 | } 1294 | } 1295 | } 1296 | extension Optional where Wrapped == Double { 1297 | func intoFfiRepr() -> __private__OptionF64 { 1298 | __private__OptionF64(self) 1299 | } 1300 | } 1301 | 1302 | extension __private__OptionBool { 1303 | func intoSwiftRepr() -> Optional { 1304 | if self.is_some { 1305 | return self.val 1306 | } else { 1307 | return nil 1308 | } 1309 | } 1310 | 1311 | init(_ val: Optional) { 1312 | if let val = val { 1313 | self = Self(val: val, is_some: true) 1314 | } else { 1315 | self = Self(val: false, is_some: false) 1316 | } 1317 | } 1318 | } 1319 | extension Optional where Wrapped == Bool { 1320 | func intoFfiRepr() -> __private__OptionBool { 1321 | __private__OptionBool(self) 1322 | } 1323 | } 1324 | -------------------------------------------------------------------------------- /Tests/bevy_ios_gamecenterTests/bevy_ios_gamecenterTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import bevy_ios_gamecenter 3 | 4 | final class bevy_ios_gamecenterTests: XCTestCase { 5 | func testExample() throws { 6 | // XCTest Documentation 7 | // https://developer.apple.com/documentation/xctest 8 | 9 | // Defining Test Cases and Test Methods 10 | // https://developer.apple.com/documentation/xctest/defining_test_cases_and_test_methods 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /assets/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rustunit/bevy_ios_gamecenter/36f2e7011f234915fb3f1fd9abd8d12700f1a19e/assets/demo.gif -------------------------------------------------------------------------------- /assets/framework.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rustunit/bevy_ios_gamecenter/36f2e7011f234915fb3f1fd9abd8d12700f1a19e/assets/framework.png -------------------------------------------------------------------------------- /assets/xcode-spm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rustunit/bevy_ios_gamecenter/36f2e7011f234915fb3f1fd9abd8d12700f1a19e/assets/xcode-spm.png -------------------------------------------------------------------------------- /bevy_ios_gamecenter_egui/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## Unreleased 9 | 10 | ## [0.1.1] - 2024-01-10 11 | 12 | ### Changed 13 | * bevy_egui 0.32 upgrade 14 | -------------------------------------------------------------------------------- /bevy_ios_gamecenter_egui/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bevy_ios_gamecenter_egui" 3 | version = "0.2.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | bevy_ios_gamecenter = "0.4" 8 | bevy = { version = "0.16", default-features = false } 9 | bevy_egui = { version = "0.34", default-features = false } 10 | egui_extras = { version = "0.31" } 11 | -------------------------------------------------------------------------------- /bevy_ios_gamecenter_egui/README.md: -------------------------------------------------------------------------------- 1 | # bevy_ios_gamecenter_egui 2 | 3 | This helper crate is for interacting with the ios **gamecenter** api from within your bevy app. It is using [egui](https://github.com/emilk/egui) for the ui. 4 | 5 | ![demo](../assets/demo.gif) 6 | 7 | > Demo from our game using this crate: [zoolitaire.com](https://zoolitaire.com) 8 | 9 | # Usage 10 | 11 | For now the crate is not published on crates, so it has to be used as a git dependency: 12 | 13 | ```toml 14 | bevy_ios_gamecenter_egui = { git = "https://github.com/rustunit/bevy_ios_gamecenter.git" } 15 | ``` 16 | 17 | Add this to your code: 18 | 19 | ```rust 20 | // initialize the plugin on startup 21 | app.add_plugins(IosGamecenterEguiPlugin { 22 | test_achievement_ids: vec![ 23 | "com.yourapp.achievement".into() 24 | ], 25 | test_ranking_ids: vec!["com.yourapp.ranking".into()], 26 | }); 27 | 28 | // in any of your bevy systems you can toggle the ui with the following command: 29 | commands.trigger(IosGamecenterEguiOpen::Toggle); 30 | ``` -------------------------------------------------------------------------------- /bevy_ios_gamecenter_egui/src/lib.rs: -------------------------------------------------------------------------------- 1 | use bevy::prelude::*; 2 | use bevy_egui::{egui, EguiContexts, EguiPlugin}; 3 | use bevy_ios_gamecenter::{ 4 | view_states, IosGCPlayer, IosGCSaveGame, IosGCSaveGames, IosGCSaveGamesResponse, 5 | IosGamecenterEvents, 6 | }; 7 | use egui_extras::{Column, TableBuilder}; 8 | 9 | #[derive(Event)] 10 | pub enum IosGamecenterEguiOpen { 11 | Toggle, 12 | Open, 13 | Close, 14 | } 15 | 16 | #[derive(Resource, Default)] 17 | struct DebugUiResource { 18 | open: bool, 19 | } 20 | 21 | #[derive(Resource, Default)] 22 | struct DebugIosGamecenter { 23 | saves: Vec, 24 | conflicting: Vec, 25 | events: Vec, 26 | player: IosGCPlayer, 27 | test_achievement_ids: Vec, 28 | test_ranking_ids: Vec, 29 | } 30 | 31 | pub struct IosGamecenterEguiPlugin { 32 | pub test_achievement_ids: Vec, 33 | pub test_ranking_ids: Vec, 34 | } 35 | 36 | impl Plugin for IosGamecenterEguiPlugin { 37 | fn build(&self, app: &mut App) { 38 | if !app.is_plugin_added::() { 39 | app.add_plugins(EguiPlugin { 40 | enable_multipass_for_primary_context: false, 41 | }); 42 | } 43 | 44 | app.init_resource::(); 45 | app.insert_resource(DebugIosGamecenter { 46 | test_achievement_ids: self.test_achievement_ids.clone(), 47 | test_ranking_ids: self.test_ranking_ids.clone(), 48 | ..default() 49 | }); 50 | 51 | app.add_systems(Update, update); 52 | app.add_systems( 53 | Update, 54 | process_gc_events.run_if(on_event::), 55 | ); 56 | 57 | app.add_observer(on_toggle); 58 | } 59 | } 60 | 61 | fn on_toggle(trigger: Trigger, mut res: ResMut) { 62 | match trigger.event() { 63 | IosGamecenterEguiOpen::Toggle => res.open = !res.open, 64 | IosGamecenterEguiOpen::Open => res.open = true, 65 | IosGamecenterEguiOpen::Close => res.open = false, 66 | } 67 | } 68 | 69 | fn process_gc_events( 70 | mut events: EventReader, 71 | mut res: ResMut, 72 | ) { 73 | for e in events.read() { 74 | match e { 75 | IosGamecenterEvents::SaveGames((_, IosGCSaveGamesResponse::Done(items))) => { 76 | res.events.push(format!("SaveGames: {}", items.0.len())); 77 | res.saves.clone_from(&items.0); 78 | } 79 | IosGamecenterEvents::Player((_, p)) => res.player = p.clone(), 80 | IosGamecenterEvents::ConflictingSaveGames(items) => { 81 | res.events.push(format!( 82 | "Conflicting: '{}' [{}]", 83 | items.0.first().unwrap().name, 84 | items.0.len(), 85 | )); 86 | 87 | res.conflicting = items.0.clone(); 88 | } 89 | _ => res.events.push(format!("{:?}", e)), 90 | } 91 | } 92 | } 93 | 94 | fn update( 95 | mut contexts: EguiContexts, 96 | mut res: ResMut, 97 | mut res_gc: ResMut, 98 | ) { 99 | let mut open_state = res.open; 100 | let Some(ctx) = contexts.try_ctx_mut() else { 101 | return; 102 | }; 103 | 104 | egui::Window::new("bevy_ios_gamecenter") 105 | .default_pos((0., 200.)) 106 | .open(&mut open_state) 107 | .show(ctx, |ui| { 108 | ios_gamecenter_ui(ui, &mut res_gc); 109 | }); 110 | 111 | res.open = open_state; 112 | } 113 | 114 | fn ios_gamecenter_ui(ui: &mut egui::Ui, res: &mut ResMut) { 115 | ui.collapsing("player", |ui| { 116 | ui.label(format!("is_authenticated: {}", res.player.is_authenticated)); 117 | ui.label(format!("display_name: {}", res.player.display_name)); 118 | ui.label(format!("id: {}", res.player.game_id)); 119 | 120 | if ui.button("auth").clicked() { 121 | bevy_ios_gamecenter::authenticate(-1); 122 | } 123 | 124 | if ui.button("player").clicked() { 125 | bevy_ios_gamecenter::request_player(-1); 126 | } 127 | 128 | if ui.button("fetch sig").clicked() { 129 | bevy_ios_gamecenter::fetch_signature(-1); 130 | } 131 | }); 132 | 133 | ui.collapsing("leaderboards", |ui| { 134 | if ui.button("show ui").clicked() { 135 | bevy_ios_gamecenter::trigger_view(view_states::LEADERBOARDS); 136 | } 137 | for id in &res.test_ranking_ids { 138 | ui.collapsing(id, |ui| { 139 | if ui.button("submit score = 1").clicked() { 140 | bevy_ios_gamecenter::leaderboards_score(-1, id.clone(), 1, 2); 141 | } 142 | if ui.button("submit score = 100").clicked() { 143 | bevy_ios_gamecenter::leaderboards_score(-1, id.clone(), 100, 2); 144 | } 145 | }); 146 | } 147 | }); 148 | 149 | ui.collapsing("achievements", |ui| { 150 | if ui.button("show ui").clicked() { 151 | bevy_ios_gamecenter::trigger_view(view_states::ACHIEVEMENTS); 152 | } 153 | 154 | if ui.button("achievement: reset").clicked() { 155 | bevy_ios_gamecenter::achievements_reset(-1); 156 | } 157 | 158 | if ui.button("achievement: invalid id").clicked() { 159 | bevy_ios_gamecenter::achievement_progress(-1, "totally-invalid-id".into(), 100.0); 160 | } 161 | 162 | for id in &res.test_achievement_ids { 163 | ui.collapsing(id, |ui| { 164 | if ui.button("set to 50%").clicked() { 165 | bevy_ios_gamecenter::achievement_progress(-1, id.clone(), 50.); 166 | } 167 | 168 | if ui.button("set to 100%").clicked() { 169 | bevy_ios_gamecenter::achievement_progress(-1, id.clone(), 100.); 170 | } 171 | }); 172 | } 173 | }); 174 | 175 | ui.collapsing("saves", |ui| { 176 | ui.label(format!("savegames: {}", res.saves.len())); 177 | 178 | if ui.button("test save").clicked() { 179 | bevy_ios_gamecenter::save_game(-1, "test".into(), vec![1, 2, 3].as_slice()); 180 | } 181 | 182 | if ui.button("delete invalid").clicked() { 183 | bevy_ios_gamecenter::delete_savegame(-1, "invalid".into()); 184 | } 185 | 186 | if ui.button("fetch saves").clicked() { 187 | res.saves.clear(); 188 | bevy_ios_gamecenter::fetch_save_games(-1); 189 | } 190 | 191 | ui.label(format!("conflicting: {}", res.conflicting.len())); 192 | 193 | if ui.button("resolve conflicts").clicked() { 194 | bevy_ios_gamecenter::resolve_conflicting_games( 195 | -1, 196 | IosGCSaveGames(res.conflicting.clone()), 197 | vec![3, 2, 1].as_slice(), 198 | ); 199 | res.conflicting.clear(); 200 | } 201 | 202 | TableBuilder::new(ui) 203 | .column(Column::auto()) 204 | .column(Column::initial(50.).resizable(true)) 205 | .column(Column::initial(150.).resizable(true)) 206 | .column(Column::auto()) 207 | .header(20.0, |mut header| { 208 | header.col(|ui| { 209 | ui.heading("cmd"); 210 | }); 211 | header.col(|ui| { 212 | ui.heading("name"); 213 | }); 214 | header.col(|ui| { 215 | ui.heading("device"); 216 | }); 217 | header.col(|ui| { 218 | ui.heading("time"); 219 | }); 220 | }) 221 | .body(|mut body| { 222 | for p in &res.saves { 223 | body.row(30.0, |mut row| { 224 | row.col(|ui| { 225 | if ui.button("get").clicked() { 226 | bevy_ios_gamecenter::load_game(-1, p.clone()); 227 | } 228 | if ui.button("-").clicked() { 229 | bevy_ios_gamecenter::delete_savegame(-1, p.name.clone()); 230 | } 231 | }); 232 | row.col(|ui| { 233 | ui.label(p.name.clone()); 234 | }); 235 | row.col(|ui| { 236 | ui.label(p.device_name.clone()); 237 | }); 238 | row.col(|ui| { 239 | ui.label(p.modification_date.to_string()); 240 | }); 241 | }); 242 | } 243 | }); 244 | }); 245 | 246 | ui.collapsing("events", |ui| { 247 | ui.label(format!("received: {}", res.events.len())); 248 | if ui.button("clear").clicked() { 249 | res.events.clear(); 250 | } 251 | 252 | let mut string = res.events.join("\n"); 253 | ui.text_edit_multiline(&mut string); 254 | }); 255 | } 256 | -------------------------------------------------------------------------------- /crate/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | Cargo.lock -------------------------------------------------------------------------------- /crate/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "rust-analyzer.cargo.target": "aarch64-apple-ios-sim" 3 | } -------------------------------------------------------------------------------- /crate/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bevy_ios_gamecenter" 3 | version = "0.4.0" 4 | edition = "2024" 5 | build = "build.rs" 6 | readme = "../README.md" 7 | license = "MIT" 8 | authors = ["extrawurst "] 9 | documentation = "https://docs.rs/bevy_ios_gamecenter" 10 | repository = "https://github.com/rustunit/bevy_ios_gamecenter" 11 | keywords = ["bevy", "gamedev", "mobile", "ios", "swift"] 12 | description = "Bevy Plugin and Swift Package to provide access to iOS native GameKit (Gamecenter) from inside Bevy Apps" 13 | 14 | [lib] 15 | crate-type = ["staticlib", "rlib"] 16 | 17 | [dependencies] 18 | bevy_app = { version = "0.16", default-features = false } 19 | bevy_ecs = { version = "0.16", default-features = false } 20 | bevy_ecs_macros = { version = "0.16", default-features = false } 21 | bevy_log = { version = "0.16", default-features = false } 22 | swift-bridge = "0.1" 23 | bevy_crossbeam_event = "0.8" 24 | base64 = "0.22" 25 | 26 | [build-dependencies] 27 | swift-bridge-build = "0.1" 28 | -------------------------------------------------------------------------------- /crate/build-rust-release.sh: -------------------------------------------------------------------------------- 1 | # build-rust.sh 2 | 3 | #!/bin/bash 4 | 5 | set -e 6 | 7 | THISDIR=$(dirname $0) 8 | cd $THISDIR 9 | 10 | touch ./src/lib.rs 11 | cargo build --release --target aarch64-apple-ios 12 | cargo build --release --target x86_64-apple-ios 13 | # TODO: enable once https://github.com/rust-lang/rust-bindgen/issues/3181 is released 14 | # cargo build --release --target aarch64-apple-ios-sim 15 | 16 | mkdir -p ./target/universal-ios/release 17 | 18 | lipo -create \ 19 | ./target/aarch64-apple-ios/release/libbevy_ios_gamecenter.a \ 20 | ./target/x86_64-apple-ios/release/libbevy_ios_gamecenter.a \ 21 | -output ./target/universal-ios/release/libbevy_ios_gamecenter.a 22 | -------------------------------------------------------------------------------- /crate/build-rust.sh: -------------------------------------------------------------------------------- 1 | # build-rust.sh 2 | 3 | #!/bin/bash 4 | 5 | set -e 6 | 7 | THISDIR=$(dirname $0) 8 | cd $THISDIR 9 | 10 | touch ./src/lib.rs 11 | cargo build --target aarch64-apple-ios 12 | cargo build --target x86_64-apple-ios 13 | # TODO: enable once https://github.com/rust-lang/rust-bindgen/issues/3181 is released 14 | # cargo build --target aarch64-apple-ios-sim 15 | 16 | mkdir -p ./target/universal-ios/debug 17 | 18 | lipo -create \ 19 | "./target/aarch64-apple-ios/debug/libbevy_ios_gamecenter.a" \ 20 | "./target/x86_64-apple-ios/debug/libbevy_ios_gamecenter.a" \ 21 | -output "./target/universal-ios/debug/libbevy_ios_gamecenter.a" 22 | -------------------------------------------------------------------------------- /crate/build.rs: -------------------------------------------------------------------------------- 1 | // build.rs 2 | 3 | fn main() { 4 | let is_doc_rs = std::env::var("DOCS_RS") 5 | .map(|doc| &doc == "1") 6 | .unwrap_or_default(); 7 | 8 | if !is_doc_rs { 9 | use std::path::PathBuf; 10 | let out_dir = PathBuf::from("./generated"); 11 | 12 | let bridges = vec!["src/lib.rs", "src/native.rs"]; 13 | for path in &bridges { 14 | println!("cargo:rerun-if-changed={}", path); 15 | } 16 | 17 | swift_bridge_build::parse_bridges(bridges) 18 | .write_all_concatenated(out_dir, env!("CARGO_PKG_NAME")); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /crate/generated/.gitignore: -------------------------------------------------------------------------------- 1 | bevy_ios_gamecenter/ 2 | *.h 3 | *.swift -------------------------------------------------------------------------------- /crate/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod methods; 2 | mod native; 3 | mod plugin; 4 | mod request; 5 | 6 | use bevy_ecs::event::Event; 7 | pub use methods::{ 8 | achievement_progress, achievements_reset, authenticate, delete_savegame, fetch_save_games, 9 | fetch_signature, init_listeners, leaderboards_score, load_game, request_player, 10 | resolve_conflicting_games, save_game, trigger_view, 11 | }; 12 | pub use plugin::{IosGamecenterEvents, IosGamecenterPlugin}; 13 | pub use request::{BevyIosGamecenter, BevyIosGamecenterSet}; 14 | 15 | /// Expected event data in response to [`init`] method call or 16 | /// implicit on startup when registering Plugin via `IosGamecenterPlugin::new(true)`. 17 | /// 18 | /// See Event [`IosGamecenterEvents`] 19 | #[derive(Debug, Clone, Event)] 20 | pub enum IosGCAuthResult { 21 | IsAuthenticated, 22 | LoginPresented, 23 | Error(String), 24 | } 25 | 26 | impl IosGCAuthResult { 27 | fn authenticated() -> Self { 28 | Self::IsAuthenticated 29 | } 30 | 31 | fn login_presented() -> Self { 32 | Self::LoginPresented 33 | } 34 | 35 | fn error(e: String) -> Self { 36 | Self::Error(e) 37 | } 38 | } 39 | 40 | #[derive(Debug, Clone, Default)] 41 | pub struct IosGCSaveGames(pub Vec); 42 | 43 | impl IosGCSaveGames { 44 | fn new(items: Vec) -> Self { 45 | Self(items) 46 | } 47 | 48 | pub fn contains(items: &Self, a: &IosGCSaveGame) -> bool { 49 | items.0.contains(a) 50 | } 51 | } 52 | 53 | #[derive(Debug, Clone, Event)] 54 | pub enum IosGCResolvedConflictsResponse { 55 | Done(IosGCSaveGames), 56 | Error(String), 57 | } 58 | 59 | impl IosGCResolvedConflictsResponse { 60 | fn done(items: IosGCSaveGames) -> Self { 61 | Self::Done(items) 62 | } 63 | 64 | fn error(e: String) -> Self { 65 | Self::Error(e) 66 | } 67 | } 68 | 69 | /// Expected event data in response to [`request_player`] method call. 70 | /// See Event [`IosGamecenterEvents`] 71 | #[derive(Event, Debug, Clone, Default)] 72 | pub struct IosGCPlayer { 73 | pub game_id: String, 74 | pub team_id: String, 75 | pub is_authenticated: bool, 76 | pub alias: String, 77 | pub display_name: String, 78 | } 79 | 80 | impl IosGCPlayer { 81 | pub fn new( 82 | game_id: String, 83 | team_id: String, 84 | is_authenticated: bool, 85 | alias: String, 86 | display_name: String, 87 | ) -> Self { 88 | Self { 89 | game_id, 90 | team_id, 91 | is_authenticated, 92 | alias, 93 | display_name, 94 | } 95 | } 96 | } 97 | 98 | /// Expected event data in response to [`save_game`] method call. 99 | /// See Event [`IosGamecenterEvents`] 100 | #[derive(Debug, Clone, Event)] 101 | pub enum IosGCSavedGameResponse { 102 | Done(IosGCSaveGame), 103 | Error(String), 104 | } 105 | 106 | impl IosGCSavedGameResponse { 107 | fn done(item: IosGCSaveGame) -> Self { 108 | Self::Done(item) 109 | } 110 | 111 | fn error(e: String) -> Self { 112 | Self::Error(e) 113 | } 114 | } 115 | 116 | /// Expected event data in response to [`fetch_save_games`] method call. 117 | /// See Event [`IosGamecenterEvents`] 118 | #[derive(Debug, Clone, Event)] 119 | pub enum IosGCSaveGamesResponse { 120 | Done(IosGCSaveGames), 121 | Error(String), 122 | } 123 | 124 | impl IosGCSaveGamesResponse { 125 | fn done(items: IosGCSaveGames) -> Self { 126 | Self::Done(items) 127 | } 128 | 129 | fn error(e: String) -> Self { 130 | Self::Error(e) 131 | } 132 | } 133 | 134 | /// Save Game meta data. 135 | /// Expected event data in response to [`save_game`] or [`fetch_save_games`] method call. 136 | /// See Event [`IosGamecenterEvents`] 137 | /// 138 | /// ## Note 139 | /// This does not contain the actual saved bytes, these have to be requested via [`load_game`] 140 | #[derive(Debug, Clone, Default, PartialEq, Eq)] 141 | pub struct IosGCSaveGame { 142 | pub name: String, 143 | pub device_name: String, 144 | pub modification_date: u64, 145 | } 146 | 147 | impl IosGCSaveGame { 148 | pub fn new(name: String, device_name: String, modification_date: u64) -> Self { 149 | Self { 150 | name, 151 | device_name, 152 | modification_date, 153 | } 154 | } 155 | 156 | pub fn equals(a: &IosGCSaveGame, b: &IosGCSaveGame) -> bool { 157 | a == b 158 | } 159 | } 160 | 161 | /// Expected event data in response to [`load_game`] method call. 162 | /// See Event [`IosGamecenterEvents`] 163 | #[derive(Debug, Clone, Event)] 164 | pub enum IosGCLoadGamesResponse { 165 | /// Indicates a successfully loaded Save Game 166 | /// It will return the Save Game that was requested and the Data as a `Option>`. 167 | /// The `Option` will only be `None` in case of an error decoding the underlying Data back from base64 encoding. 168 | Done((IosGCSaveGame, Option>)), 169 | /// Returned if requested Save Game was not found 170 | Unknown(IosGCSaveGame), 171 | Error(String), 172 | } 173 | 174 | impl IosGCLoadGamesResponse { 175 | fn done(save_game: IosGCSaveGame, data: String) -> Self { 176 | use base64::Engine; 177 | Self::Done(( 178 | save_game, 179 | base64::engine::general_purpose::STANDARD.decode(data).ok(), 180 | )) 181 | } 182 | 183 | fn unknown(save_game: IosGCSaveGame) -> Self { 184 | Self::Unknown(save_game) 185 | } 186 | 187 | fn error(e: String) -> Self { 188 | Self::Error(e) 189 | } 190 | } 191 | 192 | #[derive(Debug, Clone, Default)] 193 | pub struct IosGCAchievement { 194 | pub identifier: String, 195 | pub progress: f64, 196 | pub is_completed: bool, 197 | pub last_reported_date: u64, 198 | } 199 | 200 | impl IosGCAchievement { 201 | pub fn new( 202 | identifier: String, 203 | progress: f64, 204 | is_completed: bool, 205 | last_reported_date: u64, 206 | ) -> Self { 207 | Self { 208 | identifier, 209 | progress, 210 | is_completed, 211 | last_reported_date, 212 | } 213 | } 214 | } 215 | 216 | /// Expected event data in response to [`achievement_progress`] method call. 217 | /// See Event [`IosGamecenterEvents`] 218 | #[derive(Event, Debug, Clone)] 219 | pub enum IosGCAchievementProgressResponse { 220 | Done(IosGCAchievement), 221 | Error(String), 222 | } 223 | 224 | impl IosGCAchievementProgressResponse { 225 | fn done(a: IosGCAchievement) -> Self { 226 | Self::Done(a) 227 | } 228 | 229 | fn error(e: String) -> Self { 230 | Self::Error(e) 231 | } 232 | } 233 | 234 | /// Expected event data in response to [`achievements_reset`] method call. 235 | /// See Event [`IosGamecenterEvents`] 236 | #[derive(Event, Debug, Clone)] 237 | pub enum IosGCAchievementsResetResponse { 238 | Done, 239 | Error(String), 240 | } 241 | 242 | impl IosGCAchievementsResetResponse { 243 | fn done() -> Self { 244 | Self::Done 245 | } 246 | 247 | fn error(e: String) -> Self { 248 | Self::Error(e) 249 | } 250 | } 251 | 252 | /// Expected event data in response to [`leaderboards_score`] method call. 253 | /// See Event [`IosGamecenterEvents`] 254 | #[derive(Event, Debug, Clone)] 255 | pub enum IosGCScoreSubmitResponse { 256 | Done, 257 | Error(String), 258 | } 259 | 260 | impl IosGCScoreSubmitResponse { 261 | fn done() -> Self { 262 | Self::Done 263 | } 264 | 265 | fn error(e: String) -> Self { 266 | Self::Error(e) 267 | } 268 | } 269 | 270 | /// Expected event data in response to [`delete_savegame`] method call. 271 | /// See Event [`IosGamecenterEvents`] 272 | #[derive(Event, Debug, Clone)] 273 | pub enum IosGCDeleteSaveGameResponse { 274 | Done(String), 275 | Error(String), 276 | } 277 | 278 | impl IosGCDeleteSaveGameResponse { 279 | fn done(name: String) -> Self { 280 | Self::Done(name) 281 | } 282 | 283 | fn error(e: String) -> Self { 284 | Self::Error(e) 285 | } 286 | } 287 | 288 | #[derive(Debug, Clone, Default)] 289 | pub struct IosGCFetchItemsForSignatureVerification { 290 | pub url: String, 291 | pub signature: Vec, 292 | pub salt: Vec, 293 | pub timestamp: u64, 294 | } 295 | 296 | impl IosGCFetchItemsForSignatureVerification { 297 | pub fn new( 298 | url: String, 299 | signature_as_base64: String, 300 | salt_as_base64: String, 301 | timestamp: u64, 302 | ) -> Self { 303 | use base64::Engine; 304 | let signature = base64::engine::general_purpose::STANDARD 305 | .decode(signature_as_base64) 306 | .unwrap_or_default(); 307 | let salt = base64::engine::general_purpose::STANDARD 308 | .decode(salt_as_base64) 309 | .unwrap_or_default(); 310 | Self { 311 | url, 312 | signature, 313 | salt, 314 | timestamp, 315 | } 316 | } 317 | } 318 | 319 | /// Expected event data in response to [`fetch_signature`] method call. 320 | /// See Event [`IosGamecenterEvents`] 321 | #[derive(Event, Debug, Clone)] 322 | pub enum IosGCFetchItemsForSignatureVerificationResponse { 323 | Done(IosGCFetchItemsForSignatureVerification), 324 | Error(String), 325 | } 326 | 327 | impl IosGCFetchItemsForSignatureVerificationResponse { 328 | fn done(items: IosGCFetchItemsForSignatureVerification) -> Self { 329 | Self::Done(items) 330 | } 331 | 332 | fn error(e: String) -> Self { 333 | Self::Error(e) 334 | } 335 | } 336 | 337 | /// used in [`trigger_view`] to define what view to open 338 | pub type IosGCViewState = i32; 339 | 340 | /// used in [`trigger_view`] to define what view to open. 341 | /// 342 | /// See values in Apple Docs: 343 | pub mod view_states { 344 | use crate::IosGCViewState; 345 | 346 | /// Defines what part of Gamecenter UI to open. See [`trigger_view`][crate::trigger_view] 347 | /// 348 | /// See values in Apple Docs: 349 | pub static DEFAULT: IosGCViewState = -1; 350 | /// Defines what part of Gamecenter UI to open. See [`trigger_view`][crate::trigger_view] 351 | /// 352 | /// See values in Apple Docs: 353 | pub static LEADERBOARDS: IosGCViewState = 0; 354 | /// Defines what part of Gamecenter UI to open. See [`trigger_view`][crate::trigger_view] 355 | /// 356 | /// See values in Apple Docs: 357 | pub static ACHIEVEMENTS: IosGCViewState = 1; 358 | /// Defines what part of Gamecenter UI to open. See [`trigger_view`][crate::trigger_view] 359 | /// 360 | /// See values in Apple Docs: 361 | pub static CHALLENGES: IosGCViewState = 2; 362 | /// Defines what part of Gamecenter UI to open. See [`trigger_view`][crate::trigger_view] 363 | /// 364 | /// See values in Apple Docs: 365 | pub static LOCAL_PLAYER_PROFILES: IosGCViewState = 3; 366 | /// Defines what part of Gamecenter UI to open. See [`trigger_view`][crate::trigger_view] 367 | /// 368 | /// See values in Apple Docs: 369 | pub static DASHBOARD: IosGCViewState = 4; 370 | /// Defines what part of Gamecenter UI to open. See [`trigger_view`][crate::trigger_view] 371 | /// 372 | /// See values in Apple Docs: 373 | pub static LOCAL_PLAYER_FRIENDS_LIST: IosGCViewState = 5; 374 | } 375 | -------------------------------------------------------------------------------- /crate/src/methods.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_variables)] 2 | 3 | #[allow(unused_imports)] 4 | use crate::native; 5 | use crate::{IosGCSaveGame, IosGCSaveGames, IosGCViewState}; 6 | 7 | /// Init internal listener that allows us to receive conflicting save game notifications 8 | pub fn init_listeners() { 9 | #[cfg(target_os = "ios")] 10 | native::init_listeners(); 11 | } 12 | 13 | /// Authenticate 14 | /// Expected to be confirmed with [`IosGamecenterEvents::Authentication`][crate::IosGamecenterEvents::Authentication] event 15 | pub fn authenticate(request: i64) { 16 | #[cfg(target_os = "ios")] 17 | native::authenticate(request); 18 | } 19 | 20 | /// Request Player Infos 21 | /// Expected to be confirmed with [`IosGamecenterEvents::Player`][crate::IosGamecenterEvents::Player] event 22 | pub fn request_player(request: i64) { 23 | #[cfg(target_os = "ios")] 24 | native::get_player(request) 25 | } 26 | 27 | /// Save Game under `name` 28 | /// Expected to be confirmed with [`IosGamecenterEvents::SavedGame`][crate::IosGamecenterEvents::SavedGame] event 29 | /// 30 | /// ## Note 31 | /// This will base64 encode the data to save it 32 | pub fn save_game(request: i64, name: String, data: &[u8]) { 33 | #[cfg(target_os = "ios")] 34 | { 35 | use base64::Engine; 36 | let s = base64::engine::general_purpose::STANDARD.encode(data); 37 | native::save_game(request, s, name); 38 | } 39 | } 40 | 41 | /// Requests the Data inside a given [`IosGCSaveGame`] 42 | /// Expected to be confirmed with [`IosGamecenterEvents::SavedGame`][crate::IosGamecenterEvents::LoadGame] event 43 | pub fn load_game(request: i64, save_game: IosGCSaveGame) { 44 | #[cfg(target_os = "ios")] 45 | native::load_game(request, save_game); 46 | } 47 | 48 | /// Delete Save Game by name 49 | /// Expected to be confirmed with [`IosGamecenterEvents::DeletedSaveGame`][crate::IosGamecenterEvents::DeletedSaveGame] event 50 | /// See 51 | pub fn delete_savegame(request: i64, name: String) { 52 | #[cfg(target_os = "ios")] 53 | native::delete_game(request, name); 54 | } 55 | 56 | /// Resolve conflicting save games. 57 | /// Conflicts will be reported via the [`IosGamecenterEvents::ConflictingSaveGames`][crate::IosGamecenterEvents::ConflictingSaveGames] event. 58 | /// Define the resolved save game via `data`, the conflicting save games will share the same name and the resolved save game will have a new timestamp. 59 | /// Expected to be confirmed with [`IosGamecenterEvents::ResolvedConflicts`][crate::IosGamecenterEvents::ResolvedConflicts] event. 60 | /// See 61 | pub fn resolve_conflicting_games(request: i64, save_games: IosGCSaveGames, data: &[u8]) { 62 | #[cfg(target_os = "ios")] 63 | { 64 | use base64::Engine; 65 | let s = base64::engine::general_purpose::STANDARD.encode(data); 66 | native::resolve_conflicting_games(request, save_games, s); 67 | } 68 | } 69 | 70 | /// Fetch Items for Signature Verification 71 | /// Expected to be confirmed with [`IosGamecenterEvents::ItemsForSignatureVerification`][crate::IosGamecenterEvents::ItemsForSignatureVerification] event 72 | /// See 73 | pub fn fetch_signature(request: i64) { 74 | #[cfg(target_os = "ios")] 75 | native::fetch_signature(request); 76 | } 77 | 78 | /// Requests a list of all available SaveGames 79 | /// Expected to be confirmed with [`IosGamecenterEvents::SaveGames`][crate::IosGamecenterEvents::SaveGames] event 80 | pub fn fetch_save_games(request: i64) { 81 | #[cfg(target_os = "ios")] 82 | native::fetch_save_games(request); 83 | } 84 | 85 | /// Updates progress on an Achievement. 86 | /// Expected to be confirmed with [`IosGamecenterEvents::AchievementProgress`][crate::IosGamecenterEvents::AchievementProgress] event 87 | pub fn achievement_progress(request: i64, id: String, progress: f64) { 88 | #[cfg(target_os = "ios")] 89 | native::achievement_progress(request, id, progress); 90 | } 91 | 92 | /// Resets all achievements. 93 | /// Expected to be confirmed with [`IosGamecenterEvents::AchievementsReset`][crate::IosGamecenterEvents::AchievementsReset] event 94 | pub fn achievements_reset(request: i64) { 95 | #[cfg(target_os = "ios")] 96 | native::reset_achievements(request); 97 | } 98 | 99 | /// Submits score to a leaderboard 100 | /// Expected to be confirmed with [`IosGamecenterEvents::LeaderboardScoreSubmitted`][crate::IosGamecenterEvents::LeaderboardScoreSubmitted] event 101 | pub fn leaderboards_score(request: i64, id: String, score: i64, context: i64) { 102 | #[cfg(target_os = "ios")] 103 | native::leaderboards_score(request, id, score, context); 104 | } 105 | 106 | /// Opens Gamecenter View to a specific [`IosGCViewState`] 107 | /// 108 | /// ## Note 109 | /// Unlike most other methods this will not trigger a response 110 | /// 111 | /// See Apple Docs: 112 | pub fn trigger_view(state: IosGCViewState) { 113 | #[cfg(target_os = "ios")] 114 | native::trigger_view(state); 115 | } 116 | -------------------------------------------------------------------------------- /crate/src/native.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::unnecessary_cast, unused_variables)] 2 | 3 | use std::sync::OnceLock; 4 | 5 | use bevy_crossbeam_event::CrossbeamEventSender; 6 | 7 | #[allow(unused_imports)] 8 | pub use ffi::*; 9 | 10 | use crate::{ 11 | plugin::IosGamecenterEvents, IosGCAchievement, IosGCAchievementProgressResponse, 12 | IosGCAchievementsResetResponse, IosGCAuthResult, IosGCDeleteSaveGameResponse, 13 | IosGCFetchItemsForSignatureVerification, IosGCFetchItemsForSignatureVerificationResponse, 14 | IosGCLoadGamesResponse, IosGCPlayer, IosGCResolvedConflictsResponse, IosGCSaveGame, 15 | IosGCSaveGames, IosGCSaveGamesResponse, IosGCSavedGameResponse, IosGCScoreSubmitResponse, 16 | }; 17 | 18 | #[swift_bridge::bridge] 19 | mod ffi { 20 | extern "Rust" { 21 | type IosGCPlayer; 22 | 23 | #[swift_bridge(associated_to = IosGCPlayer)] 24 | fn new( 25 | game_id: String, 26 | team_id: String, 27 | is_authenticated: bool, 28 | alias: String, 29 | display_name: String, 30 | ) -> IosGCPlayer; 31 | 32 | type IosGCAuthResult; 33 | 34 | #[swift_bridge(associated_to = IosGCAuthResult)] 35 | fn authenticated() -> IosGCAuthResult; 36 | #[swift_bridge(associated_to = IosGCAuthResult)] 37 | fn login_presented() -> IosGCAuthResult; 38 | #[swift_bridge(associated_to = IosGCAuthResult)] 39 | fn error(e: String) -> IosGCAuthResult; 40 | 41 | type IosGCSaveGame; 42 | 43 | #[swift_bridge(associated_to = IosGCSaveGame)] 44 | fn new(name: String, device_name: String, modification_date: u64) -> IosGCSaveGame; 45 | 46 | type IosGCSavedGameResponse; 47 | 48 | #[swift_bridge(associated_to = IosGCSavedGameResponse)] 49 | fn done(save: IosGCSaveGame) -> IosGCSavedGameResponse; 50 | #[swift_bridge(associated_to = IosGCSavedGameResponse)] 51 | fn error(e: String) -> IosGCSavedGameResponse; 52 | #[swift_bridge(associated_to = IosGCSaveGame)] 53 | fn equals(a: &IosGCSaveGame, b: &IosGCSaveGame) -> bool; 54 | 55 | type IosGCSaveGamesResponse; 56 | 57 | #[swift_bridge(associated_to = IosGCSaveGamesResponse)] 58 | fn done(items: IosGCSaveGames) -> IosGCSaveGamesResponse; 59 | #[swift_bridge(associated_to = IosGCSaveGamesResponse)] 60 | fn error(e: String) -> IosGCSaveGamesResponse; 61 | 62 | type IosGCLoadGamesResponse; 63 | 64 | #[swift_bridge(associated_to = IosGCLoadGamesResponse)] 65 | fn done(save_game: IosGCSaveGame, data: String) -> IosGCLoadGamesResponse; 66 | #[swift_bridge(associated_to = IosGCLoadGamesResponse)] 67 | fn unknown(save_game: IosGCSaveGame) -> IosGCLoadGamesResponse; 68 | #[swift_bridge(associated_to = IosGCLoadGamesResponse)] 69 | fn error(e: String) -> IosGCLoadGamesResponse; 70 | 71 | type IosGCAchievement; 72 | 73 | #[swift_bridge(associated_to = IosGCAchievement)] 74 | fn new( 75 | identifier: String, 76 | progress: f64, 77 | is_completed: bool, 78 | last_reported_date: u64, 79 | ) -> IosGCAchievement; 80 | 81 | type IosGCAchievementProgressResponse; 82 | 83 | #[swift_bridge(associated_to = IosGCAchievementProgressResponse)] 84 | fn done(a: IosGCAchievement) -> IosGCAchievementProgressResponse; 85 | #[swift_bridge(associated_to = IosGCAchievementProgressResponse)] 86 | fn error(e: String) -> IosGCAchievementProgressResponse; 87 | 88 | type IosGCAchievementsResetResponse; 89 | 90 | #[swift_bridge(associated_to = IosGCAchievementsResetResponse)] 91 | fn done() -> IosGCAchievementsResetResponse; 92 | #[swift_bridge(associated_to = IosGCAchievementsResetResponse)] 93 | fn error(e: String) -> IosGCAchievementsResetResponse; 94 | 95 | type IosGCScoreSubmitResponse; 96 | 97 | #[swift_bridge(associated_to = IosGCScoreSubmitResponse)] 98 | fn done() -> IosGCScoreSubmitResponse; 99 | #[swift_bridge(associated_to = IosGCScoreSubmitResponse)] 100 | fn error(e: String) -> IosGCScoreSubmitResponse; 101 | 102 | type IosGCDeleteSaveGameResponse; 103 | 104 | #[swift_bridge(associated_to = IosGCDeleteSaveGameResponse)] 105 | fn done(e: String) -> IosGCDeleteSaveGameResponse; 106 | #[swift_bridge(associated_to = IosGCDeleteSaveGameResponse)] 107 | fn error(e: String) -> IosGCDeleteSaveGameResponse; 108 | 109 | type IosGCFetchItemsForSignatureVerification; 110 | 111 | #[swift_bridge(associated_to = IosGCFetchItemsForSignatureVerification)] 112 | fn new( 113 | url: String, 114 | signature_as_base64: String, 115 | salt_as_base64: String, 116 | timestamp: u64, 117 | ) -> IosGCFetchItemsForSignatureVerification; 118 | 119 | type IosGCFetchItemsForSignatureVerificationResponse; 120 | 121 | #[swift_bridge(associated_to = IosGCFetchItemsForSignatureVerificationResponse)] 122 | fn done( 123 | items: IosGCFetchItemsForSignatureVerification, 124 | ) -> IosGCFetchItemsForSignatureVerificationResponse; 125 | #[swift_bridge(associated_to = IosGCFetchItemsForSignatureVerificationResponse)] 126 | fn error(e: String) -> IosGCFetchItemsForSignatureVerificationResponse; 127 | 128 | type IosGCSaveGames; 129 | 130 | #[swift_bridge(associated_to = IosGCSaveGames)] 131 | fn new(items: Vec) -> IosGCSaveGames; 132 | #[swift_bridge(associated_to = IosGCSaveGames)] 133 | fn contains(items: &IosGCSaveGames, item: &IosGCSaveGame) -> bool; 134 | 135 | type IosGCResolvedConflictsResponse; 136 | 137 | #[swift_bridge(associated_to = IosGCResolvedConflictsResponse)] 138 | fn done(items: IosGCSaveGames) -> IosGCResolvedConflictsResponse; 139 | #[swift_bridge(associated_to = IosGCResolvedConflictsResponse)] 140 | fn error(e: String) -> IosGCResolvedConflictsResponse; 141 | 142 | fn receive_authentication(request: i64, result: IosGCAuthResult); 143 | fn receive_player(request: i64, p: IosGCPlayer); 144 | fn receive_load_game(request: i64, response: IosGCLoadGamesResponse); 145 | fn receive_saved_game(request: i64, response: IosGCSavedGameResponse); 146 | fn receive_save_games(request: i64, response: IosGCSaveGamesResponse); 147 | fn receive_deleted_game(request: i64, response: IosGCDeleteSaveGameResponse); 148 | fn receive_achievement_progress(request: i64, response: IosGCAchievementProgressResponse); 149 | fn receive_achievement_reset(request: i64, response: IosGCAchievementsResetResponse); 150 | fn receive_leaderboard_score(request: i64, response: IosGCScoreSubmitResponse); 151 | fn receive_items_for_signature_verification( 152 | request: i64, 153 | response: IosGCFetchItemsForSignatureVerificationResponse, 154 | ); 155 | fn receive_resolved_conflicts(request: i64, response: IosGCResolvedConflictsResponse); 156 | 157 | // no response 158 | fn receive_conflicting_savegames(savegames: IosGCSaveGames); 159 | } 160 | 161 | extern "Swift" { 162 | pub fn init_listeners(); 163 | pub fn trigger_view(state: i32); 164 | 165 | pub fn authenticate(request: i64); 166 | pub fn get_player(request: i64); 167 | pub fn save_game(request: i64, data: String, name: String); 168 | pub fn load_game(request: i64, save_game: IosGCSaveGame); 169 | pub fn delete_game(request: i64, name: String); 170 | pub fn resolve_conflicting_games(request: i64, save_games: IosGCSaveGames, data: String); 171 | pub fn fetch_save_games(request: i64); 172 | pub fn achievement_progress(request: i64, id: String, progress: f64); 173 | pub fn reset_achievements(request: i64); 174 | pub fn leaderboards_score(request: i64, id: String, score: i64, context: i64); 175 | pub fn fetch_signature(request: i64); 176 | } 177 | } 178 | 179 | static SENDER: OnceLock>> = OnceLock::new(); 180 | 181 | #[allow(dead_code)] 182 | pub fn set_sender(sender: CrossbeamEventSender) { 183 | while SENDER.set(Some(sender.clone())).is_err() {} 184 | } 185 | 186 | fn receive_authentication(request: i64, result: IosGCAuthResult) { 187 | #[cfg(target_os = "ios")] 188 | SENDER 189 | .get() 190 | .unwrap() 191 | .as_ref() 192 | .unwrap() 193 | .send(IosGamecenterEvents::Authentication((request, result))); 194 | } 195 | 196 | fn receive_player(request: i64, p: IosGCPlayer) { 197 | #[cfg(target_os = "ios")] 198 | SENDER 199 | .get() 200 | .unwrap() 201 | .as_ref() 202 | .unwrap() 203 | .send(IosGamecenterEvents::Player((request, p))); 204 | } 205 | 206 | fn receive_saved_game(request: i64, response: IosGCSavedGameResponse) { 207 | #[cfg(target_os = "ios")] 208 | SENDER 209 | .get() 210 | .unwrap() 211 | .as_ref() 212 | .unwrap() 213 | .send(IosGamecenterEvents::SavedGame((request, response))); 214 | } 215 | 216 | fn receive_save_games(request: i64, response: IosGCSaveGamesResponse) { 217 | #[cfg(target_os = "ios")] 218 | SENDER 219 | .get() 220 | .unwrap() 221 | .as_ref() 222 | .unwrap() 223 | .send(IosGamecenterEvents::SaveGames((request, response))); 224 | } 225 | 226 | fn receive_load_game(request: i64, response: IosGCLoadGamesResponse) { 227 | #[cfg(target_os = "ios")] 228 | SENDER 229 | .get() 230 | .unwrap() 231 | .as_ref() 232 | .unwrap() 233 | .send(IosGamecenterEvents::LoadGame((request, response))); 234 | } 235 | 236 | fn receive_achievement_progress(request: i64, response: IosGCAchievementProgressResponse) { 237 | #[cfg(target_os = "ios")] 238 | SENDER 239 | .get() 240 | .unwrap() 241 | .as_ref() 242 | .unwrap() 243 | .send(IosGamecenterEvents::AchievementProgress(( 244 | request, response, 245 | ))); 246 | } 247 | 248 | fn receive_achievement_reset(request: i64, response: IosGCAchievementsResetResponse) { 249 | #[cfg(target_os = "ios")] 250 | SENDER 251 | .get() 252 | .unwrap() 253 | .as_ref() 254 | .unwrap() 255 | .send(IosGamecenterEvents::AchievementsReset((request, response))); 256 | } 257 | 258 | fn receive_leaderboard_score(request: i64, response: IosGCScoreSubmitResponse) { 259 | #[cfg(target_os = "ios")] 260 | SENDER 261 | .get() 262 | .unwrap() 263 | .as_ref() 264 | .unwrap() 265 | .send(IosGamecenterEvents::LeaderboardScoreSubmitted(( 266 | request, response, 267 | ))); 268 | } 269 | 270 | fn receive_deleted_game(request: i64, response: IosGCDeleteSaveGameResponse) { 271 | #[cfg(target_os = "ios")] 272 | SENDER 273 | .get() 274 | .unwrap() 275 | .as_ref() 276 | .unwrap() 277 | .send(IosGamecenterEvents::DeletedSaveGame((request, response))); 278 | } 279 | 280 | fn receive_items_for_signature_verification( 281 | request: i64, 282 | response: IosGCFetchItemsForSignatureVerificationResponse, 283 | ) { 284 | #[cfg(target_os = "ios")] 285 | SENDER.get().unwrap().as_ref().unwrap().send( 286 | IosGamecenterEvents::ItemsForSignatureVerification((request, response)), 287 | ); 288 | } 289 | 290 | fn receive_resolved_conflicts(request: i64, response: IosGCResolvedConflictsResponse) { 291 | #[cfg(target_os = "ios")] 292 | SENDER 293 | .get() 294 | .unwrap() 295 | .as_ref() 296 | .unwrap() 297 | .send(IosGamecenterEvents::ResolvedConflicts((request, response))); 298 | } 299 | 300 | fn receive_conflicting_savegames(savegames: IosGCSaveGames) { 301 | #[cfg(target_os = "ios")] 302 | SENDER 303 | .get() 304 | .unwrap() 305 | .as_ref() 306 | .unwrap() 307 | .send(IosGamecenterEvents::ConflictingSaveGames(savegames)); 308 | } 309 | -------------------------------------------------------------------------------- /crate/src/plugin.rs: -------------------------------------------------------------------------------- 1 | use bevy_app::prelude::*; 2 | use bevy_ecs::prelude::*; 3 | 4 | use crate::{ 5 | request, IosGCAchievementProgressResponse, IosGCAchievementsResetResponse, IosGCAuthResult, 6 | IosGCDeleteSaveGameResponse, IosGCFetchItemsForSignatureVerificationResponse, 7 | IosGCLoadGamesResponse, IosGCPlayer, IosGCResolvedConflictsResponse, IosGCSaveGames, 8 | IosGCSaveGamesResponse, IosGCSavedGameResponse, IosGCScoreSubmitResponse, 9 | }; 10 | 11 | /// All events for communication from native iOS (Swift) side to Rust/Bevy 12 | #[derive(Event, Clone, Debug)] 13 | pub enum IosGamecenterEvents { 14 | /// Triggered by calls to [`init`][crate::init] or implicit when registering [`IosGamecenterPlugin`] via `IosGamecenterPlugin::new(true)` 15 | Authentication((i64, IosGCAuthResult)), 16 | /// Triggered by calls to [`save_game`][crate::save_game] 17 | SavedGame((i64, IosGCSavedGameResponse)), 18 | /// Triggered by calls to [`fetch_save_games`][crate::fetch_save_games] 19 | SaveGames((i64, IosGCSaveGamesResponse)), 20 | /// Triggered by calls to [`load_game`][crate::load_game] 21 | LoadGame((i64, IosGCLoadGamesResponse)), 22 | /// Triggered by calls to [`delete_savegame`][crate::delete_savegame] 23 | DeletedSaveGame((i64, IosGCDeleteSaveGameResponse)), 24 | /// Triggered by calls to [`request_player`][crate::request_player] 25 | Player((i64, IosGCPlayer)), 26 | /// Triggered by calls to [`achievement_progress`][crate::achievement_progress] 27 | AchievementProgress((i64, IosGCAchievementProgressResponse)), 28 | /// Triggered by calls to [`achievements_reset`][crate::achievements_reset] 29 | AchievementsReset((i64, IosGCAchievementsResetResponse)), 30 | /// Triggered by calls to [`leaderboards_score`][crate::leaderboards_score] 31 | LeaderboardScoreSubmitted((i64, IosGCScoreSubmitResponse)), 32 | /// Triggered by calls to [`fetch_signature`][crate::fetch_signature] 33 | ItemsForSignatureVerification((i64, IosGCFetchItemsForSignatureVerificationResponse)), 34 | /// Triggered by calls to [`fetch_save_games`][crate::fetch_save_games] or [`save_game`][crate::save_game] 35 | ConflictingSaveGames(IosGCSaveGames), 36 | /// Triggered by calls to [`resolve_conflicting_games`][crate::resolve_conflicting_games] 37 | ResolvedConflicts((i64, IosGCResolvedConflictsResponse)), 38 | } 39 | 40 | /// Bevy plugin to integrate access to iOS Gamecenter 41 | #[allow(dead_code)] 42 | pub struct IosGamecenterPlugin { 43 | auto_init: bool, 44 | } 45 | 46 | impl IosGamecenterPlugin { 47 | /// create plugin and define whether it will authenticate automatically right on startup 48 | pub fn new(auto_init: bool) -> Self { 49 | Self { auto_init } 50 | } 51 | } 52 | 53 | impl Plugin for IosGamecenterPlugin { 54 | fn build(&self, app: &mut App) { 55 | app.add_plugins(request::plugin); 56 | 57 | #[cfg(not(target_os = "ios"))] 58 | { 59 | app.add_event::(); 60 | } 61 | 62 | #[cfg(target_os = "ios")] 63 | { 64 | use bevy_crossbeam_event::{CrossbeamEventApp, CrossbeamEventSender}; 65 | 66 | app.add_crossbeam_event::(); 67 | 68 | let sender = app 69 | .world() 70 | .get_resource::>() 71 | .unwrap() 72 | .clone(); 73 | 74 | crate::native::set_sender(sender); 75 | 76 | if self.auto_init { 77 | crate::native::init_listeners(); 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /crate/src/request.rs: -------------------------------------------------------------------------------- 1 | use std::marker::PhantomData; 2 | 3 | use bevy_app::{App, PreUpdate}; 4 | use bevy_ecs::{ 5 | prelude::*, 6 | system::{EntityCommands, IntoObserverSystem, SystemParam}, 7 | }; 8 | 9 | use crate::{ 10 | IosGCAchievementProgressResponse, IosGCAchievementsResetResponse, IosGCAuthResult, 11 | IosGCDeleteSaveGameResponse, IosGCFetchItemsForSignatureVerificationResponse, 12 | IosGCLoadGamesResponse, IosGCPlayer, IosGCResolvedConflictsResponse, IosGCSaveGame, 13 | IosGCSaveGames, IosGCSaveGamesResponse, IosGCSavedGameResponse, IosGCScoreSubmitResponse, 14 | IosGamecenterEvents, 15 | }; 16 | 17 | #[derive(Resource, Default)] 18 | struct BevyIosGamecenterState { 19 | request_id: i64, 20 | } 21 | 22 | #[derive(Component)] 23 | #[component(storage = "SparseSet")] 24 | struct RequestAuthentication; 25 | 26 | #[derive(Component)] 27 | #[component(storage = "SparseSet")] 28 | struct RequestPlayer; 29 | 30 | #[derive(Component)] 31 | #[component(storage = "SparseSet")] 32 | struct RequestSaveGames; 33 | 34 | #[derive(Component)] 35 | #[component(storage = "SparseSet")] 36 | struct RequestSaveGame; 37 | 38 | #[derive(Component)] 39 | #[component(storage = "SparseSet")] 40 | struct RequestLoadGame; 41 | 42 | #[derive(Component)] 43 | #[component(storage = "SparseSet")] 44 | struct RequestResolveConflicts; 45 | 46 | #[derive(Component)] 47 | #[component(storage = "SparseSet")] 48 | struct RequestDeleteSavegame; 49 | 50 | #[derive(Component)] 51 | #[component(storage = "SparseSet")] 52 | struct RequestFetchSignature; 53 | 54 | #[derive(Component)] 55 | #[component(storage = "SparseSet")] 56 | struct RequestAchievementProgress; 57 | 58 | #[derive(Component)] 59 | #[component(storage = "SparseSet")] 60 | struct RequestAchievementsReset; 61 | 62 | #[derive(Component)] 63 | #[component(storage = "SparseSet")] 64 | struct RequestLeaderboardScore; 65 | 66 | #[derive(Component)] 67 | struct RequestId(i64); 68 | 69 | #[derive(Component)] 70 | struct RequestEntity; 71 | 72 | /// Observer based API conveniently call and async wait for a gamecenter API response 73 | #[derive(SystemParam)] 74 | pub struct BevyIosGamecenter<'w, 's> { 75 | commands: Commands<'w, 's>, 76 | res: ResMut<'w, BevyIosGamecenterState>, 77 | } 78 | 79 | impl BevyIosGamecenter<'_, '_> { 80 | pub fn authenticate(&mut self) -> BevyIosGCRequestBuilder<'_, IosGCAuthResult> { 81 | let id = self.res.request_id; 82 | self.res.request_id += 1; 83 | crate::methods::authenticate(id); 84 | BevyIosGCRequestBuilder::new(self.commands.spawn(( 85 | RequestAuthentication, 86 | RequestId(id), 87 | RequestEntity, 88 | ))) 89 | } 90 | 91 | pub fn request_player(&mut self) -> BevyIosGCRequestBuilder<'_, IosGCPlayer> { 92 | let id = self.res.request_id; 93 | self.res.request_id += 1; 94 | crate::methods::request_player(id); 95 | BevyIosGCRequestBuilder::new(self.commands.spawn(( 96 | RequestPlayer, 97 | RequestId(id), 98 | RequestEntity, 99 | ))) 100 | } 101 | 102 | pub fn fetch_save_games(&mut self) -> BevyIosGCRequestBuilder<'_, IosGCSaveGamesResponse> { 103 | let id = self.res.request_id; 104 | self.res.request_id += 1; 105 | crate::methods::fetch_save_games(id); 106 | BevyIosGCRequestBuilder::new(self.commands.spawn(( 107 | RequestSaveGames, 108 | RequestId(id), 109 | RequestEntity, 110 | ))) 111 | } 112 | 113 | pub fn save_game( 114 | &mut self, 115 | name: String, 116 | data: &[u8], 117 | ) -> BevyIosGCRequestBuilder<'_, IosGCSavedGameResponse> { 118 | let id = self.res.request_id; 119 | self.res.request_id += 1; 120 | crate::methods::save_game(id, name, data); 121 | BevyIosGCRequestBuilder::new(self.commands.spawn(( 122 | RequestSaveGame, 123 | RequestId(id), 124 | RequestEntity, 125 | ))) 126 | } 127 | 128 | pub fn load_game( 129 | &mut self, 130 | game: IosGCSaveGame, 131 | ) -> BevyIosGCRequestBuilder<'_, IosGCLoadGamesResponse> { 132 | let id = self.res.request_id; 133 | self.res.request_id += 1; 134 | crate::methods::load_game(id, game); 135 | BevyIosGCRequestBuilder::new(self.commands.spawn(( 136 | RequestLoadGame, 137 | RequestId(id), 138 | RequestEntity, 139 | ))) 140 | } 141 | 142 | pub fn resolve_conflicts( 143 | &mut self, 144 | save_games: IosGCSaveGames, 145 | data: &[u8], 146 | ) -> BevyIosGCRequestBuilder<'_, IosGCResolvedConflictsResponse> { 147 | let id = self.res.request_id; 148 | self.res.request_id += 1; 149 | crate::methods::resolve_conflicting_games(id, save_games, data); 150 | BevyIosGCRequestBuilder::new(self.commands.spawn(( 151 | RequestResolveConflicts, 152 | RequestId(id), 153 | RequestEntity, 154 | ))) 155 | } 156 | 157 | pub fn delete_savegame( 158 | &mut self, 159 | name: String, 160 | ) -> BevyIosGCRequestBuilder<'_, IosGCDeleteSaveGameResponse> { 161 | let id = self.res.request_id; 162 | self.res.request_id += 1; 163 | crate::methods::delete_savegame(id, name); 164 | BevyIosGCRequestBuilder::new(self.commands.spawn(( 165 | RequestDeleteSavegame, 166 | RequestId(id), 167 | RequestEntity, 168 | ))) 169 | } 170 | 171 | pub fn fetch_signature( 172 | &mut self, 173 | ) -> BevyIosGCRequestBuilder<'_, IosGCFetchItemsForSignatureVerificationResponse> { 174 | let id = self.res.request_id; 175 | self.res.request_id += 1; 176 | crate::methods::fetch_signature(id); 177 | BevyIosGCRequestBuilder::new(self.commands.spawn(( 178 | RequestFetchSignature, 179 | RequestId(id), 180 | RequestEntity, 181 | ))) 182 | } 183 | 184 | pub fn achievement_progress( 185 | &mut self, 186 | achievement_id: String, 187 | progress: f64, 188 | ) -> BevyIosGCRequestBuilder<'_, IosGCAchievementProgressResponse> { 189 | let id = self.res.request_id; 190 | self.res.request_id += 1; 191 | crate::methods::achievement_progress(id, achievement_id, progress); 192 | BevyIosGCRequestBuilder::new(self.commands.spawn(( 193 | RequestAchievementProgress, 194 | RequestId(id), 195 | RequestEntity, 196 | ))) 197 | } 198 | 199 | pub fn achievements_reset( 200 | &mut self, 201 | ) -> BevyIosGCRequestBuilder<'_, IosGCAchievementsResetResponse> { 202 | let id = self.res.request_id; 203 | self.res.request_id += 1; 204 | crate::methods::achievements_reset(id); 205 | BevyIosGCRequestBuilder::new(self.commands.spawn(( 206 | RequestAchievementsReset, 207 | RequestId(id), 208 | RequestEntity, 209 | ))) 210 | } 211 | 212 | pub fn leaderboards_score( 213 | &mut self, 214 | leaderboard_id: String, 215 | score: i64, 216 | context: i64, 217 | ) -> BevyIosGCRequestBuilder<'_, IosGCScoreSubmitResponse> { 218 | let id = self.res.request_id; 219 | self.res.request_id += 1; 220 | crate::methods::leaderboards_score(id, leaderboard_id, score, context); 221 | BevyIosGCRequestBuilder::new(self.commands.spawn(( 222 | RequestLeaderboardScore, 223 | RequestId(id), 224 | RequestEntity, 225 | ))) 226 | } 227 | } 228 | 229 | pub struct BevyIosGCRequestBuilder<'a, T>(EntityCommands<'a>, PhantomData); 230 | 231 | impl<'a, T> BevyIosGCRequestBuilder<'a, T> 232 | where 233 | T: 'static + Event, 234 | { 235 | fn new(ec: EntityCommands<'a>) -> Self { 236 | Self(ec, PhantomData) 237 | } 238 | 239 | pub fn on_response>( 240 | &mut self, 241 | on_response: OR, 242 | ) -> &mut Self { 243 | self.0.observe(on_response); 244 | self 245 | } 246 | } 247 | 248 | #[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)] 249 | pub struct BevyIosGamecenterSet; 250 | 251 | pub fn plugin(app: &mut App) { 252 | app.init_resource::(); 253 | app.add_systems( 254 | PreUpdate, 255 | ( 256 | cleanup_finished_requests, 257 | process_events.run_if(on_event::), 258 | ) 259 | .chain() 260 | .in_set(BevyIosGamecenterSet), 261 | ); 262 | } 263 | 264 | fn cleanup_finished_requests( 265 | mut commands: Commands, 266 | query: Query, Without)>, 267 | ) { 268 | for e in query.iter() { 269 | if let Ok(mut ec) = commands.get_entity(e) { 270 | ec.despawn(); 271 | } 272 | } 273 | } 274 | 275 | #[allow(unused_variables, unused_mut, clippy::too_many_arguments)] 276 | fn process_events( 277 | mut events: EventReader, 278 | mut commands: Commands, 279 | request_authentication: Query<(Entity, &RequestId), With>, 280 | request_player: Query<(Entity, &RequestId), With>, 281 | request_save_games: Query<(Entity, &RequestId), With>, 282 | request_save_game: Query<(Entity, &RequestId), With>, 283 | request_load_game: Query<(Entity, &RequestId), With>, 284 | request_resolve_conflicts: Query<(Entity, &RequestId), With>, 285 | request_delete_savegame: Query<(Entity, &RequestId), With>, 286 | request_fetch_signature: Query<(Entity, &RequestId), With>, 287 | request_achievement_progress: Query<(Entity, &RequestId), With>, 288 | request_achievements_reset: Query<(Entity, &RequestId), With>, 289 | request_leaderboard_score: Query<(Entity, &RequestId), With>, 290 | ) { 291 | for e in events.read() { 292 | match e { 293 | IosGamecenterEvents::Authentication((r, response)) => { 294 | for (e, id) in &request_authentication { 295 | if id.0 == *r { 296 | commands.trigger_targets(response.clone(), e); 297 | if let Ok(mut ec) = commands.get_entity(e) { 298 | ec.remove::(); 299 | } 300 | break; 301 | } 302 | } 303 | } 304 | IosGamecenterEvents::Player((r, response)) => { 305 | for (e, id) in &request_player { 306 | if id.0 == *r { 307 | commands.trigger_targets(response.clone(), e); 308 | if let Ok(mut ec) = commands.get_entity(e) { 309 | ec.remove::(); 310 | } 311 | break; 312 | } 313 | } 314 | } 315 | IosGamecenterEvents::SaveGames((r, response)) => { 316 | for (e, id) in &request_save_games { 317 | if id.0 == *r { 318 | commands.trigger_targets(response.clone(), e); 319 | if let Ok(mut ec) = commands.get_entity(e) { 320 | ec.remove::(); 321 | } 322 | break; 323 | } 324 | } 325 | } 326 | IosGamecenterEvents::SavedGame((r, response)) => { 327 | for (e, id) in &request_save_game { 328 | if id.0 == *r { 329 | commands.trigger_targets(response.clone(), e); 330 | if let Ok(mut ec) = commands.get_entity(e) { 331 | ec.remove::(); 332 | } 333 | break; 334 | } 335 | } 336 | } 337 | IosGamecenterEvents::LoadGame((r, response)) => { 338 | for (e, id) in &request_load_game { 339 | if id.0 == *r { 340 | commands.trigger_targets(response.clone(), e); 341 | if let Ok(mut ec) = commands.get_entity(e) { 342 | ec.remove::(); 343 | } 344 | break; 345 | } 346 | } 347 | } 348 | IosGamecenterEvents::ResolvedConflicts((r, response)) => { 349 | for (e, id) in &request_resolve_conflicts { 350 | if id.0 == *r { 351 | commands.trigger_targets(response.clone(), e); 352 | if let Ok(mut ec) = commands.get_entity(e) { 353 | ec.remove::(); 354 | } 355 | break; 356 | } 357 | } 358 | } 359 | IosGamecenterEvents::DeletedSaveGame((r, response)) => { 360 | for (e, id) in &request_delete_savegame { 361 | if id.0 == *r { 362 | commands.trigger_targets(response.clone(), e); 363 | if let Ok(mut ec) = commands.get_entity(e) { 364 | ec.remove::(); 365 | } 366 | break; 367 | } 368 | } 369 | } 370 | IosGamecenterEvents::ItemsForSignatureVerification((r, response)) => { 371 | for (e, id) in &request_fetch_signature { 372 | if id.0 == *r { 373 | commands.trigger_targets(response.clone(), e); 374 | if let Ok(mut ec) = commands.get_entity(e) { 375 | ec.remove::(); 376 | } 377 | break; 378 | } 379 | } 380 | } 381 | IosGamecenterEvents::AchievementProgress((r, response)) => { 382 | for (e, id) in &request_achievement_progress { 383 | if id.0 == *r { 384 | commands.trigger_targets(response.clone(), e); 385 | if let Ok(mut ec) = commands.get_entity(e) { 386 | ec.remove::(); 387 | } 388 | break; 389 | } 390 | } 391 | } 392 | IosGamecenterEvents::AchievementsReset((r, response)) => { 393 | for (e, id) in &request_achievements_reset { 394 | if id.0 == *r { 395 | commands.trigger_targets(response.clone(), e); 396 | if let Ok(mut ec) = commands.get_entity(e) { 397 | ec.remove::(); 398 | } 399 | break; 400 | } 401 | } 402 | } 403 | IosGamecenterEvents::LeaderboardScoreSubmitted((r, response)) => { 404 | for (e, id) in &request_leaderboard_score { 405 | if id.0 == *r { 406 | commands.trigger_targets(response.clone(), e); 407 | if let Ok(mut ec) = commands.get_entity(e) { 408 | ec.remove::(); 409 | } 410 | break; 411 | } 412 | } 413 | } 414 | IosGamecenterEvents::ConflictingSaveGames(_) => {} 415 | } 416 | } 417 | } 418 | -------------------------------------------------------------------------------- /justfile: -------------------------------------------------------------------------------- 1 | check: 2 | cd ./crate/ && cargo c --target=aarch64-apple-ios-sim 3 | cd ./crate/ && cargo clippy --target=aarch64-apple-ios-sim 4 | cd bevy_ios_gamecenter_egui && cargo clippy 5 | cd bevy_ios_gamecenter_egui && cargo clippy --target=aarch64-apple-ios-sim 6 | 7 | build-rust-release: 8 | ./crate/build-rust-release.sh 9 | 10 | build-rust: 11 | ./crate/build-rust.sh 12 | 13 | copy-generated: 14 | sed -i '' 's/func __swift_bridge__/public func __swift_bridge__/g' crate/generated/bevy_ios_gamecenter/bevy_ios_gamecenter.swift 15 | echo "import BevyIosGamecenterRust "|cat - ./crate/generated/SwiftBridgeCore.swift > /tmp/out && mv /tmp/out ./crate/generated/SwiftBridgeCore.swift 16 | echo "import BevyIosGamecenterRust "|cat - ./crate/generated/bevy_ios_gamecenter/bevy_ios_gamecenter.swift > /tmp/out && mv /tmp/out ./crate/generated/bevy_ios_gamecenter/bevy_ios_gamecenter.swift 17 | mv ./crate/generated/SwiftBridgeCore.swift ./crate/generated/SwiftBridgeCoreGC.swift 18 | mv ./crate/generated/SwiftBridgeCore.h ./crate/generated/SwiftBridgeCoreGC.h 19 | cp ./crate/generated/bevy_ios_gamecenter/bevy_ios_gamecenter.h ./BevyIosGamecenterRust.xcframework/ios-arm64/Headers/BevyIosGamecenterRust/ 20 | cp ./crate/generated/SwiftBridgeCoreGC.h ./BevyIosGamecenterRust.xcframework/ios-arm64/Headers/BevyIosGamecenterRust/ 21 | cp ./crate/generated/bevy_ios_gamecenter/bevy_ios_gamecenter.h ./BevyIosGamecenterRust.xcframework/ios-arm64_x86_64-simulator/Headers/BevyIosGamecenterRust/ 22 | cp ./crate/generated/SwiftBridgeCoreGC.h ./BevyIosGamecenterRust.xcframework/ios-arm64_x86_64-simulator/Headers/BevyIosGamecenterRust/ 23 | cp ./crate/generated/bevy_ios_gamecenter/bevy_ios_gamecenter.swift ./Sources/bevy_ios_gamecenter/ 24 | cp ./crate/generated/SwiftBridgeCoreGC.swift ./Sources/bevy_ios_gamecenter/ 25 | 26 | build: build-rust copy-generated 27 | cp ./crate/target/universal-ios/debug/libbevy_ios_gamecenter.a ./BevyIosGamecenterRust.xcframework/ios-arm64_x86_64-simulator/ 28 | cp ./crate/target/aarch64-apple-ios/debug/libbevy_ios_gamecenter.a ./BevyIosGamecenterRust.xcframework/ios-arm64/ 29 | 30 | build-release: build-rust-release copy-generated 31 | cp ./crate/target/universal-ios/release/libbevy_ios_gamecenter.a ./BevyIosGamecenterRust.xcframework/ios-arm64_x86_64-simulator/ 32 | cp ./crate/target/aarch64-apple-ios/release/libbevy_ios_gamecenter.a ./BevyIosGamecenterRust.xcframework/ios-arm64/ 33 | ls -lisah ./BevyIosGamecenterRust.xcframework/ios-arm64/ 34 | ls -lisah ./BevyIosGamecenterRust.xcframework/ios-arm64_x86_64-simulator 35 | 36 | zip: build-release 37 | zip -r BevyIosGamecenterRust.xcframework.zip ./BevyIosGamecenterRust.xcframework/ 38 | ls -lisah BevyIosGamecenterRust.xcframework.zip 39 | shasum -a 256 BevyIosGamecenterRust.xcframework.zip 40 | shasum -a 256 BevyIosGamecenterRust.xcframework.zip > BevyIosGamecenterRust.xcframework.sha256.txt 41 | 42 | publish-crate: 43 | cd crate && cargo publish --no-verify 44 | --------------------------------------------------------------------------------