├── .github
└── workflows
│ └── rust.yml
├── .gitignore
├── Bridging-Header.h
├── Cargo.toml
├── LICENSE
├── README.md
├── Shared
├── Assets.xcassets
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
├── RuiApp.swift
└── RuiSwiftUIView.swift
├── build-rust.sh
├── build.rs
├── cbindgen.toml
├── iOS
└── Info.plist
├── macOS
├── Info.plist
└── macOS.entitlements
├── rui-ios.xcodeproj
├── project.pbxproj
└── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ └── IDEWorkspaceChecks.plist
├── screenshot.png
└── src
└── lib.rs
/.github/workflows/rust.yml:
--------------------------------------------------------------------------------
1 | name: Rust
2 |
3 | on: [push, pull_request]
4 |
5 | env:
6 | CARGO_TERM_COLOR: always
7 |
8 | jobs:
9 | build:
10 |
11 | runs-on: macos-latest
12 |
13 | steps:
14 | - uses: actions/checkout@v2
15 | - name: Add iOS archs
16 | run: rustup target add aarch64-apple-ios x86_64-apple-ios
17 | - name: Install cargo-lipo
18 | run: cargo install cargo-lipo
19 | - name: Build
20 | run: PROJECT_DIR="${PWD}" ./build-rust.sh
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## User settings
6 | xcuserdata/
7 |
8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
9 | *.xcscmblueprint
10 | *.xccheckout
11 |
12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
13 | build/
14 | DerivedData/
15 | *.moved-aside
16 | *.pbxuser
17 | !default.pbxuser
18 | *.mode1v3
19 | !default.mode1v3
20 | *.mode2v3
21 | !default.mode2v3
22 | *.perspectivev3
23 | !default.perspectivev3
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 |
28 | ## App packaging
29 | *.ipa
30 | *.dSYM.zip
31 | *.dSYM
32 |
33 | ## Playgrounds
34 | timeline.xctimeline
35 | playground.xcworkspace
36 |
37 | # Swift Package Manager
38 | #
39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
40 | # Packages/
41 | # Package.pins
42 | # Package.resolved
43 | # *.xcodeproj
44 | #
45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
46 | # hence it is not needed unless you have added a package configuration file to your project
47 | # .swiftpm
48 |
49 | .build/
50 |
51 | # CocoaPods
52 | #
53 | # We recommend against adding the Pods directory to your .gitignore. However
54 | # you should judge for yourself, the pros and cons are mentioned at:
55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
56 | #
57 | # Pods/
58 | #
59 | # Add this line if you want to avoid checking in source code from the Xcode workspace
60 | # *.xcworkspace
61 |
62 | # Carthage
63 | #
64 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
65 | # Carthage/Checkouts
66 |
67 | Carthage/Build/
68 |
69 | # Accio dependency management
70 | Dependencies/
71 | .accio/
72 |
73 | # fastlane
74 | #
75 | # It is recommended to not store the screenshots in the git repo.
76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed.
77 | # For more information about the recommended setup visit:
78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
79 |
80 | fastlane/report.xml
81 | fastlane/Preview.html
82 | fastlane/screenshots/**/*.png
83 | fastlane/test_output
84 |
85 | # Code Injection
86 | #
87 | # After new code Injection tools there's a generated folder /iOSInjectionProject
88 | # https://github.com/johnno1962/injectionforxcode
89 |
90 | iOSInjectionProject/
91 |
92 |
93 | # Added by cargo
94 |
95 | /target
96 | /Cargo.lock
97 |
98 | # swift-bridge generated files
99 |
100 | Generated
101 |
102 | # macOS turds
103 | .DS_Store
104 |
--------------------------------------------------------------------------------
/Bridging-Header.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef Bridging_Header_h
3 | #define Bridging_Header_h
4 |
5 | #include "Generated/SwiftBridgeCore.h"
6 | #include "Generated/rui-ios/rui-ios.h"
7 |
8 | #endif /* Bridging_Header_h */
9 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "rui-ios"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [lib]
9 | name = "rui_ios"
10 | crate-type = ["staticlib", "cdylib"]
11 |
12 | [build-dependencies]
13 | swift-bridge-build = "0.1.31"
14 | cbindgen = "0.23.0"
15 |
16 | [dependencies]
17 | rui = { version = "0.4.0", default-features = false }
18 | swift-bridge = "0.1.31"
19 | wgpu = "0.13.1"
20 | futures = "0.3"
21 | vger = "0.2.4"
22 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Audulus LLC
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # rui-ios
2 | Demo of [rui](https://github.com/audulus/rui) embedded on iOS
3 |
4 | To run:
5 |
6 | 1. `rustup target add aarch64-apple-ios x86_64-apple-ios`
7 | 1. `cargo install cargo-lipo`
8 | 1. Open Xcode project
9 | 1. Run
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Shared/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Shared/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "scale" : "1x",
46 | "size" : "20x20"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "scale" : "2x",
51 | "size" : "20x20"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "scale" : "1x",
56 | "size" : "29x29"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "scale" : "2x",
61 | "size" : "29x29"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "scale" : "1x",
66 | "size" : "40x40"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "scale" : "2x",
71 | "size" : "40x40"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "scale" : "1x",
76 | "size" : "76x76"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "scale" : "2x",
81 | "size" : "76x76"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "scale" : "2x",
86 | "size" : "83.5x83.5"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "scale" : "1x",
91 | "size" : "1024x1024"
92 | },
93 | {
94 | "idiom" : "mac",
95 | "scale" : "1x",
96 | "size" : "16x16"
97 | },
98 | {
99 | "idiom" : "mac",
100 | "scale" : "2x",
101 | "size" : "16x16"
102 | },
103 | {
104 | "idiom" : "mac",
105 | "scale" : "1x",
106 | "size" : "32x32"
107 | },
108 | {
109 | "idiom" : "mac",
110 | "scale" : "2x",
111 | "size" : "32x32"
112 | },
113 | {
114 | "idiom" : "mac",
115 | "scale" : "1x",
116 | "size" : "128x128"
117 | },
118 | {
119 | "idiom" : "mac",
120 | "scale" : "2x",
121 | "size" : "128x128"
122 | },
123 | {
124 | "idiom" : "mac",
125 | "scale" : "1x",
126 | "size" : "256x256"
127 | },
128 | {
129 | "idiom" : "mac",
130 | "scale" : "2x",
131 | "size" : "256x256"
132 | },
133 | {
134 | "idiom" : "mac",
135 | "scale" : "1x",
136 | "size" : "512x512"
137 | },
138 | {
139 | "idiom" : "mac",
140 | "scale" : "2x",
141 | "size" : "512x512"
142 | }
143 | ],
144 | "info" : {
145 | "author" : "xcode",
146 | "version" : 1
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/Shared/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Shared/RuiApp.swift:
--------------------------------------------------------------------------------
1 |
2 | import SwiftUI
3 |
4 | class AppModel {
5 | var appState = AppState()
6 |
7 | init() {}
8 | }
9 |
10 | @main
11 | struct RuiApp: App {
12 |
13 | let model = AppModel()
14 |
15 | var body: some Scene {
16 | WindowGroup {
17 | ZStack {
18 | Rectangle().fill(.black).edgesIgnoringSafeArea(.all)
19 | RuiSwiftUIView(appState: model.appState)
20 | }
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Shared/RuiSwiftUIView.swift:
--------------------------------------------------------------------------------
1 |
2 | import SwiftUI
3 | import Metal
4 | import QuartzCore
5 | import MetalKit
6 |
7 | class Renderer: NSObject, MTKViewDelegate {
8 |
9 | var appState: AppState
10 |
11 | init(appState: AppState) {
12 | self.appState = appState
13 | }
14 |
15 | func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {
16 | // do nothing
17 | }
18 |
19 | func draw(in view: MTKView) {
20 | let size = view.frame.size
21 | let scale = view.contentScaleFactor
22 | appState.update(Float(size.width), Float(size.height))
23 | appState.render(Float(size.width), Float(size.height), Float(scale))
24 | }
25 |
26 | }
27 |
28 | class RuiView: MTKView {
29 | var appState: AppState
30 |
31 | init(appState: AppState) {
32 | self.appState = appState
33 | super.init(frame: CGRect(x: 0, y: 0, width: 1024, height: 768),
34 | device: MTLCreateSystemDefaultDevice())
35 | }
36 |
37 | required init(coder: NSCoder) {
38 | fatalError("init(coder:) has not been implemented")
39 | }
40 |
41 | // MARK: - Event Handling
42 |
43 | /// Keep track of all the active touches so we can give them indices.
44 | var touches: [UITouch?] = Array(repeating: nil, count: 16)
45 |
46 | func add(touch: UITouch) -> Int? {
47 | for i in 0.., with event: UIEvent?) {
57 | for touch in touches {
58 | if let index = add(touch: touch) {
59 | let p = touch.location(in: self)
60 | let appEvent = AppEvent(x: Float(p.x),
61 | y: Float(bounds.size.height - p.y),
62 | id: UInt(index),
63 | kind: .TouchBegin)
64 | appState.process(appEvent)
65 | }
66 | }
67 | }
68 |
69 | override func touchesMoved(_ touches: Set, with event: UIEvent?) {
70 | for index in 0.., with event: UIEvent?) {
83 | for index in 0.. Coordinator {
104 | Coordinator()
105 | }
106 |
107 | class Coordinator: NSObject {
108 | var renderer: Renderer?
109 | }
110 |
111 | func makeUIView(context: Context) -> RuiView {
112 | let view = RuiView(appState: appState)
113 | view.isMultipleTouchEnabled = true
114 | var metalLayer = view.layer as! CAMetalLayer
115 | appState.setup_surface(&metalLayer)
116 |
117 | let renderer = Renderer(appState: appState)
118 | context.coordinator.renderer = renderer
119 | view.delegate = renderer
120 |
121 | return view
122 | }
123 |
124 | func updateUIView(_ uiView: RuiView, context: Context) {
125 | // do nothing
126 |
127 | }
128 |
129 | }
130 |
131 |
--------------------------------------------------------------------------------
/build-rust.sh:
--------------------------------------------------------------------------------
1 | #!/bin/zsh
2 |
3 | ##################################################
4 | # We call this from an Xcode run script.
5 | ##################################################
6 |
7 | set -e
8 |
9 | if [[ -z "$PROJECT_DIR" ]]
10 | then
11 | echo "Must provide PROJECT_DIR environment variable set to the Xcode project directory." 1>&2
12 | exit 1
13 | fi
14 |
15 | cd $PROJECT_DIR
16 |
17 | export PATH="$HOME/.cargo/bin:$PATH"
18 |
19 | export SWIFT_BRIDGE_OUT_DIR="${PROJECT_DIR}/Generated"
20 | mkdir -p "${SWIFT_BRIDGE_OUT_DIR}"
21 |
22 | # Without this we can't compile on MacOS Big Sur
23 | # https://github.com/TimNN/cargo-lipo/issues/41#issuecomment-774793892
24 | if [[ -n "${DEVELOPER_SDK_DIR:-}" ]]
25 | then
26 | export LIBRARY_PATH="${DEVELOPER_SDK_DIR}/MacOSX.sdk/usr/lib:${LIBRARY_PATH:-}"
27 | fi
28 |
29 | pwd
30 |
31 | if [[ $CONFIGURATION == "Release" ]]
32 | then
33 | echo "BUIlDING FOR RELEASE"
34 |
35 | cargo lipo --release --manifest-path Cargo.toml
36 | else
37 | echo "BUIlDING FOR DEBUG"
38 |
39 | cargo lipo --manifest-path Cargo.toml
40 | fi
41 |
--------------------------------------------------------------------------------
/build.rs:
--------------------------------------------------------------------------------
1 | const XCODE_CONFIGURATION_ENV: &'static str = "CONFIGURATION";
2 |
3 | fn main() {
4 | let out_dir = "Generated";
5 |
6 | let bridges = vec!["src/lib.rs"];
7 | for path in &bridges {
8 | println!("cargo:rerun-if-changed={}", path);
9 | }
10 | println!("cargo:rerun-if-env-changed={}", XCODE_CONFIGURATION_ENV);
11 |
12 | swift_bridge_build::parse_bridges(bridges)
13 | .write_all_concatenated(out_dir, env!("CARGO_PKG_NAME"));
14 | }
15 |
--------------------------------------------------------------------------------
/cbindgen.toml:
--------------------------------------------------------------------------------
1 | # This is a template cbindgen.toml file with all of the default values.
2 | # Some values are commented out because their absence is the real default.
3 | #
4 | # See https://github.com/eqrion/cbindgen/blob/master/docs.md#cbindgentoml
5 | # for detailed documentation of every option here.
6 |
7 |
8 |
9 | language = "C"
10 |
11 |
12 |
13 | ############## Options for Wrapping the Contents of the Header #################
14 |
15 | # header = "/* Text to put at the beginning of the generated file. Probably a license. */"
16 | # trailer = "/* Text to put at the end of the generated file */"
17 | # include_guard = "my_bindings_h"
18 | # pragma_once = true
19 | # autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */"
20 | include_version = false
21 | # namespace = "my_namespace"
22 | namespaces = []
23 | using_namespaces = []
24 | sys_includes = []
25 | includes = []
26 | no_includes = false
27 | after_includes = ""
28 |
29 |
30 |
31 |
32 | ############################ Code Style Options ################################
33 |
34 | braces = "SameLine"
35 | line_length = 100
36 | tab_width = 2
37 | documentation = true
38 | documentation_style = "auto"
39 | documentation_length = "full"
40 | line_endings = "LF" # also "CR", "CRLF", "Native"
41 |
42 |
43 |
44 |
45 | ############################# Codegen Options ##################################
46 |
47 | style = "both"
48 | sort_by = "Name" # default for `fn.sort_by` and `const.sort_by`
49 | usize_is_size_t = true
50 |
51 |
52 |
53 | [defines]
54 | # "target_os = freebsd" = "DEFINE_FREEBSD"
55 | # "feature = serde" = "DEFINE_SERDE"
56 |
57 |
58 |
59 | [export]
60 | include = []
61 | exclude = []
62 | # prefix = "CAPI_"
63 | item_types = []
64 | renaming_overrides_prefixing = false
65 |
66 |
67 |
68 | [export.rename]
69 |
70 |
71 |
72 | [export.body]
73 |
74 |
75 | [export.mangle]
76 |
77 |
78 | [fn]
79 | rename_args = "None"
80 | # must_use = "MUST_USE_FUNC"
81 | # no_return = "NO_RETURN"
82 | # prefix = "START_FUNC"
83 | # postfix = "END_FUNC"
84 | args = "auto"
85 | sort_by = "Name"
86 |
87 |
88 |
89 |
90 | [struct]
91 | rename_fields = "None"
92 | # must_use = "MUST_USE_STRUCT"
93 | derive_constructor = false
94 | derive_eq = false
95 | derive_neq = false
96 | derive_lt = false
97 | derive_lte = false
98 | derive_gt = false
99 | derive_gte = false
100 |
101 |
102 |
103 |
104 | [enum]
105 | rename_variants = "None"
106 | # must_use = "MUST_USE_ENUM"
107 | add_sentinel = false
108 | prefix_with_name = false
109 | derive_helper_methods = false
110 | derive_const_casts = false
111 | derive_mut_casts = false
112 | # cast_assert_name = "ASSERT"
113 | derive_tagged_enum_destructor = false
114 | derive_tagged_enum_copy_constructor = false
115 | enum_class = true
116 | private_default_tagged_enum_constructor = false
117 |
118 |
119 |
120 |
121 | [const]
122 | allow_static_const = true
123 | allow_constexpr = false
124 | sort_by = "Name"
125 |
126 |
127 |
128 |
129 | [macro_expansion]
130 | bitflags = false
131 |
132 |
133 |
134 |
135 |
136 |
137 | ############## Options for How Your Rust library Should Be Parsed ##############
138 |
139 | [parse]
140 | parse_deps = false
141 | # include = []
142 | exclude = []
143 | clean = false
144 | extra_bindings = []
145 |
146 |
147 |
148 | [parse.expand]
149 | crates = []
150 | all_features = false
151 | default_features = true
152 | features = []
--------------------------------------------------------------------------------
/iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDocumentTypes
6 |
7 |
8 | LSItemContentTypes
9 |
10 | com.example.plain-text
11 |
12 | NSUbiquitousDocumentUserActivityType
13 | $(PRODUCT_BUNDLE_IDENTIFIER).example-document
14 |
15 |
16 | UTImportedTypeDeclarations
17 |
18 |
19 | UTTypeConformsTo
20 |
21 | public.plain-text
22 |
23 | UTTypeDescription
24 | Example Text
25 | UTTypeIdentifier
26 | com.example.plain-text
27 | UTTypeTagSpecification
28 |
29 | public.filename-extension
30 |
31 | exampletext
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/macOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDocumentTypes
6 |
7 |
8 | CFBundleTypeRole
9 | Editor
10 | LSItemContentTypes
11 |
12 | com.example.plain-text
13 |
14 | NSUbiquitousDocumentUserActivityType
15 | $(PRODUCT_BUNDLE_IDENTIFIER).example-document
16 |
17 |
18 | UTImportedTypeDeclarations
19 |
20 |
21 | UTTypeConformsTo
22 |
23 | public.plain-text
24 |
25 | UTTypeDescription
26 | Example Text
27 | UTTypeIdentifier
28 | com.example.plain-text
29 | UTTypeTagSpecification
30 |
31 | public.filename-extension
32 |
33 | exampletext
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/macOS/macOS.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-write
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/rui-ios.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 55;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 293B43652821D0A80085DC2C /* SwiftBridgeCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 293B43642821D0630085DC2C /* SwiftBridgeCore.swift */; };
11 | 293B43662821D0AA0085DC2C /* rui-ios.swift in Sources */ = {isa = PBXBuildFile; fileRef = 293B43612821D0630085DC2C /* rui-ios.swift */; };
12 | 2957DA6B28148BEF0010A362 /* librui_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2957DA5A281472640010A362 /* librui_ios.a */; };
13 | 29DEE522281465C9000C3626 /* RuiApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29DEE50E281465C8000C3626 /* RuiApp.swift */; };
14 | 29DEE526281465C9000C3626 /* RuiSwiftUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29DEE510281465C8000C3626 /* RuiSwiftUIView.swift */; };
15 | 29DEE528281465C9000C3626 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 29DEE511281465C9000C3626 /* Assets.xcassets */; };
16 | /* End PBXBuildFile section */
17 |
18 | /* Begin PBXFileReference section */
19 | 293B43582821CD890085DC2C /* Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Bridging-Header.h"; sourceTree = ""; };
20 | 293B43612821D0630085DC2C /* rui-ios.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "rui-ios.swift"; sourceTree = ""; };
21 | 293B43622821D0630085DC2C /* rui-ios.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "rui-ios.h"; sourceTree = ""; };
22 | 293B43632821D0630085DC2C /* SwiftBridgeCore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwiftBridgeCore.h; sourceTree = ""; };
23 | 293B43642821D0630085DC2C /* SwiftBridgeCore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftBridgeCore.swift; sourceTree = ""; };
24 | 2957DA5A281472640010A362 /* librui_ios.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = librui_ios.a; path = target/universal/debug/librui_ios.a; sourceTree = ""; };
25 | 29DEE50E281465C8000C3626 /* RuiApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuiApp.swift; sourceTree = ""; };
26 | 29DEE510281465C8000C3626 /* RuiSwiftUIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuiSwiftUIView.swift; sourceTree = ""; };
27 | 29DEE511281465C9000C3626 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
28 | 29DEE516281465C9000C3626 /* rui-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "rui-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; };
29 | 29DEE519281465C9000C3626 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
30 | 29DEE520281465C9000C3626 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
31 | 29DEE521281465C9000C3626 /* macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = macOS.entitlements; sourceTree = ""; };
32 | /* End PBXFileReference section */
33 |
34 | /* Begin PBXFrameworksBuildPhase section */
35 | 29DEE513281465C9000C3626 /* Frameworks */ = {
36 | isa = PBXFrameworksBuildPhase;
37 | buildActionMask = 2147483647;
38 | files = (
39 | 2957DA6B28148BEF0010A362 /* librui_ios.a in Frameworks */,
40 | );
41 | runOnlyForDeploymentPostprocessing = 0;
42 | };
43 | /* End PBXFrameworksBuildPhase section */
44 |
45 | /* Begin PBXGroup section */
46 | 293B435F2821D0630085DC2C /* Generated */ = {
47 | isa = PBXGroup;
48 | children = (
49 | 293B43602821D0630085DC2C /* rui-ios */,
50 | 293B43632821D0630085DC2C /* SwiftBridgeCore.h */,
51 | 293B43642821D0630085DC2C /* SwiftBridgeCore.swift */,
52 | );
53 | path = Generated;
54 | sourceTree = "";
55 | };
56 | 293B43602821D0630085DC2C /* rui-ios */ = {
57 | isa = PBXGroup;
58 | children = (
59 | 293B43612821D0630085DC2C /* rui-ios.swift */,
60 | 293B43622821D0630085DC2C /* rui-ios.h */,
61 | );
62 | path = "rui-ios";
63 | sourceTree = "";
64 | };
65 | 2957DA59281472640010A362 /* Frameworks */ = {
66 | isa = PBXGroup;
67 | children = (
68 | 2957DA5A281472640010A362 /* librui_ios.a */,
69 | );
70 | name = Frameworks;
71 | sourceTree = "";
72 | };
73 | 29DEE508281465C7000C3626 = {
74 | isa = PBXGroup;
75 | children = (
76 | 293B43582821CD890085DC2C /* Bridging-Header.h */,
77 | 293B435F2821D0630085DC2C /* Generated */,
78 | 29DEE50D281465C8000C3626 /* Shared */,
79 | 29DEE518281465C9000C3626 /* iOS */,
80 | 29DEE51F281465C9000C3626 /* macOS */,
81 | 29DEE517281465C9000C3626 /* Products */,
82 | 2957DA59281472640010A362 /* Frameworks */,
83 | );
84 | sourceTree = "";
85 | };
86 | 29DEE50D281465C8000C3626 /* Shared */ = {
87 | isa = PBXGroup;
88 | children = (
89 | 29DEE50E281465C8000C3626 /* RuiApp.swift */,
90 | 29DEE510281465C8000C3626 /* RuiSwiftUIView.swift */,
91 | 29DEE511281465C9000C3626 /* Assets.xcassets */,
92 | );
93 | path = Shared;
94 | sourceTree = "";
95 | };
96 | 29DEE517281465C9000C3626 /* Products */ = {
97 | isa = PBXGroup;
98 | children = (
99 | 29DEE516281465C9000C3626 /* rui-ios.app */,
100 | );
101 | name = Products;
102 | sourceTree = "";
103 | };
104 | 29DEE518281465C9000C3626 /* iOS */ = {
105 | isa = PBXGroup;
106 | children = (
107 | 29DEE519281465C9000C3626 /* Info.plist */,
108 | );
109 | path = iOS;
110 | sourceTree = "";
111 | };
112 | 29DEE51F281465C9000C3626 /* macOS */ = {
113 | isa = PBXGroup;
114 | children = (
115 | 29DEE520281465C9000C3626 /* Info.plist */,
116 | 29DEE521281465C9000C3626 /* macOS.entitlements */,
117 | );
118 | path = macOS;
119 | sourceTree = "";
120 | };
121 | /* End PBXGroup section */
122 |
123 | /* Begin PBXNativeTarget section */
124 | 29DEE515281465C9000C3626 /* rui-ios (iOS) */ = {
125 | isa = PBXNativeTarget;
126 | buildConfigurationList = 29DEE52C281465C9000C3626 /* Build configuration list for PBXNativeTarget "rui-ios (iOS)" */;
127 | buildPhases = (
128 | 29C7AB09281CA61B00D19AAA /* Build Rust */,
129 | 29DEE512281465C9000C3626 /* Sources */,
130 | 29DEE513281465C9000C3626 /* Frameworks */,
131 | 29DEE514281465C9000C3626 /* Resources */,
132 | );
133 | buildRules = (
134 | );
135 | dependencies = (
136 | );
137 | name = "rui-ios (iOS)";
138 | productName = "rui-ios (iOS)";
139 | productReference = 29DEE516281465C9000C3626 /* rui-ios.app */;
140 | productType = "com.apple.product-type.application";
141 | };
142 | /* End PBXNativeTarget section */
143 |
144 | /* Begin PBXProject section */
145 | 29DEE509281465C7000C3626 /* Project object */ = {
146 | isa = PBXProject;
147 | attributes = {
148 | BuildIndependentTargetsInParallel = 1;
149 | LastSwiftUpdateCheck = 1330;
150 | LastUpgradeCheck = 1330;
151 | TargetAttributes = {
152 | 29DEE515281465C9000C3626 = {
153 | CreatedOnToolsVersion = 13.3.1;
154 | };
155 | };
156 | };
157 | buildConfigurationList = 29DEE50C281465C7000C3626 /* Build configuration list for PBXProject "rui-ios" */;
158 | compatibilityVersion = "Xcode 13.0";
159 | developmentRegion = en;
160 | hasScannedForEncodings = 0;
161 | knownRegions = (
162 | en,
163 | Base,
164 | );
165 | mainGroup = 29DEE508281465C7000C3626;
166 | productRefGroup = 29DEE517281465C9000C3626 /* Products */;
167 | projectDirPath = "";
168 | projectRoot = "";
169 | targets = (
170 | 29DEE515281465C9000C3626 /* rui-ios (iOS) */,
171 | );
172 | };
173 | /* End PBXProject section */
174 |
175 | /* Begin PBXResourcesBuildPhase section */
176 | 29DEE514281465C9000C3626 /* Resources */ = {
177 | isa = PBXResourcesBuildPhase;
178 | buildActionMask = 2147483647;
179 | files = (
180 | 29DEE528281465C9000C3626 /* Assets.xcassets in Resources */,
181 | );
182 | runOnlyForDeploymentPostprocessing = 0;
183 | };
184 | /* End PBXResourcesBuildPhase section */
185 |
186 | /* Begin PBXShellScriptBuildPhase section */
187 | 29C7AB09281CA61B00D19AAA /* Build Rust */ = {
188 | isa = PBXShellScriptBuildPhase;
189 | buildActionMask = 2147483647;
190 | files = (
191 | );
192 | inputFileListPaths = (
193 | );
194 | inputPaths = (
195 | );
196 | name = "Build Rust";
197 | outputFileListPaths = (
198 | );
199 | outputPaths = (
200 | );
201 | runOnlyForDeploymentPostprocessing = 0;
202 | shellPath = /bin/sh;
203 | shellScript = "./build-rust.sh\n";
204 | };
205 | /* End PBXShellScriptBuildPhase section */
206 |
207 | /* Begin PBXSourcesBuildPhase section */
208 | 29DEE512281465C9000C3626 /* Sources */ = {
209 | isa = PBXSourcesBuildPhase;
210 | buildActionMask = 2147483647;
211 | files = (
212 | 293B43662821D0AA0085DC2C /* rui-ios.swift in Sources */,
213 | 293B43652821D0A80085DC2C /* SwiftBridgeCore.swift in Sources */,
214 | 29DEE522281465C9000C3626 /* RuiApp.swift in Sources */,
215 | 29DEE526281465C9000C3626 /* RuiSwiftUIView.swift in Sources */,
216 | );
217 | runOnlyForDeploymentPostprocessing = 0;
218 | };
219 | /* End PBXSourcesBuildPhase section */
220 |
221 | /* Begin XCBuildConfiguration section */
222 | 29DEE52A281465C9000C3626 /* Debug */ = {
223 | isa = XCBuildConfiguration;
224 | buildSettings = {
225 | ALWAYS_SEARCH_USER_PATHS = NO;
226 | CLANG_ANALYZER_NONNULL = YES;
227 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
228 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
229 | CLANG_ENABLE_MODULES = YES;
230 | CLANG_ENABLE_OBJC_ARC = YES;
231 | CLANG_ENABLE_OBJC_WEAK = YES;
232 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
233 | CLANG_WARN_BOOL_CONVERSION = YES;
234 | CLANG_WARN_COMMA = YES;
235 | CLANG_WARN_CONSTANT_CONVERSION = YES;
236 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
237 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
238 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
239 | CLANG_WARN_EMPTY_BODY = YES;
240 | CLANG_WARN_ENUM_CONVERSION = YES;
241 | CLANG_WARN_INFINITE_RECURSION = YES;
242 | CLANG_WARN_INT_CONVERSION = YES;
243 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
244 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
245 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
246 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
247 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
248 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
249 | CLANG_WARN_STRICT_PROTOTYPES = YES;
250 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
251 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
252 | CLANG_WARN_UNREACHABLE_CODE = YES;
253 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
254 | COPY_PHASE_STRIP = NO;
255 | DEBUG_INFORMATION_FORMAT = dwarf;
256 | ENABLE_STRICT_OBJC_MSGSEND = YES;
257 | ENABLE_TESTABILITY = YES;
258 | GCC_C_LANGUAGE_STANDARD = gnu11;
259 | GCC_DYNAMIC_NO_PIC = NO;
260 | GCC_NO_COMMON_BLOCKS = YES;
261 | GCC_OPTIMIZATION_LEVEL = 0;
262 | GCC_PREPROCESSOR_DEFINITIONS = (
263 | "DEBUG=1",
264 | "$(inherited)",
265 | );
266 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
267 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
268 | GCC_WARN_UNDECLARED_SELECTOR = YES;
269 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
270 | GCC_WARN_UNUSED_FUNCTION = YES;
271 | GCC_WARN_UNUSED_VARIABLE = YES;
272 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
273 | MTL_FAST_MATH = YES;
274 | ONLY_ACTIVE_ARCH = YES;
275 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
276 | SWIFT_OBJC_BRIDGING_HEADER = "Bridging-Header.h";
277 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
278 | };
279 | name = Debug;
280 | };
281 | 29DEE52B281465C9000C3626 /* Release */ = {
282 | isa = XCBuildConfiguration;
283 | buildSettings = {
284 | ALWAYS_SEARCH_USER_PATHS = NO;
285 | CLANG_ANALYZER_NONNULL = YES;
286 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
287 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
288 | CLANG_ENABLE_MODULES = YES;
289 | CLANG_ENABLE_OBJC_ARC = YES;
290 | CLANG_ENABLE_OBJC_WEAK = YES;
291 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
292 | CLANG_WARN_BOOL_CONVERSION = YES;
293 | CLANG_WARN_COMMA = YES;
294 | CLANG_WARN_CONSTANT_CONVERSION = YES;
295 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
296 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
297 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
298 | CLANG_WARN_EMPTY_BODY = YES;
299 | CLANG_WARN_ENUM_CONVERSION = YES;
300 | CLANG_WARN_INFINITE_RECURSION = YES;
301 | CLANG_WARN_INT_CONVERSION = YES;
302 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
303 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
304 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
305 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
306 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
307 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
308 | CLANG_WARN_STRICT_PROTOTYPES = YES;
309 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
310 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
311 | CLANG_WARN_UNREACHABLE_CODE = YES;
312 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
313 | COPY_PHASE_STRIP = NO;
314 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
315 | ENABLE_NS_ASSERTIONS = NO;
316 | ENABLE_STRICT_OBJC_MSGSEND = YES;
317 | GCC_C_LANGUAGE_STANDARD = gnu11;
318 | GCC_NO_COMMON_BLOCKS = YES;
319 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
320 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
321 | GCC_WARN_UNDECLARED_SELECTOR = YES;
322 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
323 | GCC_WARN_UNUSED_FUNCTION = YES;
324 | GCC_WARN_UNUSED_VARIABLE = YES;
325 | MTL_ENABLE_DEBUG_INFO = NO;
326 | MTL_FAST_MATH = YES;
327 | SWIFT_COMPILATION_MODE = wholemodule;
328 | SWIFT_OBJC_BRIDGING_HEADER = "Bridging-Header.h";
329 | SWIFT_OPTIMIZATION_LEVEL = "-O";
330 | };
331 | name = Release;
332 | };
333 | 29DEE52D281465C9000C3626 /* Debug */ = {
334 | isa = XCBuildConfiguration;
335 | buildSettings = {
336 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
337 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
338 | CODE_SIGN_STYLE = Automatic;
339 | CURRENT_PROJECT_VERSION = 1;
340 | DEVELOPMENT_TEAM = J6F2XLS3BY;
341 | ENABLE_PREVIEWS = YES;
342 | GENERATE_INFOPLIST_FILE = YES;
343 | INFOPLIST_FILE = iOS/Info.plist;
344 | INFOPLIST_KEY_LSSupportsOpeningDocumentsInPlace = YES;
345 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
346 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
347 | INFOPLIST_KEY_UILaunchScreen_Generation = YES;
348 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
349 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
350 | INFOPLIST_KEY_UISupportsDocumentBrowser = YES;
351 | IPHONEOS_DEPLOYMENT_TARGET = 15.4;
352 | LD_RUNPATH_SEARCH_PATHS = (
353 | "$(inherited)",
354 | "@executable_path/Frameworks",
355 | );
356 | LIBRARY_SEARCH_PATHS = (
357 | "$(inherited)",
358 | "$(PROJECT_DIR)/target/universal/release",
359 | "$(PROJECT_DIR)/target/universal/debug",
360 | );
361 | MARKETING_VERSION = 1.0;
362 | PRODUCT_BUNDLE_IDENTIFIER = "com.audulus.rui-ios";
363 | PRODUCT_NAME = "rui-ios";
364 | SDKROOT = iphoneos;
365 | SWIFT_EMIT_LOC_STRINGS = YES;
366 | SWIFT_VERSION = 5.0;
367 | TARGETED_DEVICE_FAMILY = "1,2";
368 | };
369 | name = Debug;
370 | };
371 | 29DEE52E281465C9000C3626 /* Release */ = {
372 | isa = XCBuildConfiguration;
373 | buildSettings = {
374 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
375 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
376 | CODE_SIGN_STYLE = Automatic;
377 | CURRENT_PROJECT_VERSION = 1;
378 | DEVELOPMENT_TEAM = J6F2XLS3BY;
379 | ENABLE_PREVIEWS = YES;
380 | GENERATE_INFOPLIST_FILE = YES;
381 | INFOPLIST_FILE = iOS/Info.plist;
382 | INFOPLIST_KEY_LSSupportsOpeningDocumentsInPlace = YES;
383 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
384 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
385 | INFOPLIST_KEY_UILaunchScreen_Generation = YES;
386 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
387 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
388 | INFOPLIST_KEY_UISupportsDocumentBrowser = YES;
389 | IPHONEOS_DEPLOYMENT_TARGET = 15.4;
390 | LD_RUNPATH_SEARCH_PATHS = (
391 | "$(inherited)",
392 | "@executable_path/Frameworks",
393 | );
394 | LIBRARY_SEARCH_PATHS = (
395 | "$(inherited)",
396 | "$(PROJECT_DIR)/target/universal/release",
397 | "$(PROJECT_DIR)/target/universal/debug",
398 | );
399 | MARKETING_VERSION = 1.0;
400 | PRODUCT_BUNDLE_IDENTIFIER = "com.audulus.rui-ios";
401 | PRODUCT_NAME = "rui-ios";
402 | SDKROOT = iphoneos;
403 | SWIFT_EMIT_LOC_STRINGS = YES;
404 | SWIFT_VERSION = 5.0;
405 | TARGETED_DEVICE_FAMILY = "1,2";
406 | VALIDATE_PRODUCT = YES;
407 | };
408 | name = Release;
409 | };
410 | /* End XCBuildConfiguration section */
411 |
412 | /* Begin XCConfigurationList section */
413 | 29DEE50C281465C7000C3626 /* Build configuration list for PBXProject "rui-ios" */ = {
414 | isa = XCConfigurationList;
415 | buildConfigurations = (
416 | 29DEE52A281465C9000C3626 /* Debug */,
417 | 29DEE52B281465C9000C3626 /* Release */,
418 | );
419 | defaultConfigurationIsVisible = 0;
420 | defaultConfigurationName = Release;
421 | };
422 | 29DEE52C281465C9000C3626 /* Build configuration list for PBXNativeTarget "rui-ios (iOS)" */ = {
423 | isa = XCConfigurationList;
424 | buildConfigurations = (
425 | 29DEE52D281465C9000C3626 /* Debug */,
426 | 29DEE52E281465C9000C3626 /* Release */,
427 | );
428 | defaultConfigurationIsVisible = 0;
429 | defaultConfigurationName = Release;
430 | };
431 | /* End XCConfigurationList section */
432 | };
433 | rootObject = 29DEE509281465C7000C3626 /* Project object */;
434 | }
435 |
--------------------------------------------------------------------------------
/rui-ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/rui-ios.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/audulus/rui-ios/b8353379c43dde5eccb49f5c159ac1cea1467984/screenshot.png
--------------------------------------------------------------------------------
/src/lib.rs:
--------------------------------------------------------------------------------
1 | use core::ffi::c_void;
2 | use futures::executor::block_on;
3 | use rui::*;
4 | use vger::*;
5 |
6 | fn button_example() -> impl View {
7 | hstack((
8 | caption("button"),
9 | button("press me", |_| println!("pressed")),
10 | ))
11 | }
12 |
13 | fn slider_example() -> impl View {
14 | hstack((caption("slider"), state(|| 0.5, |s, _| hslider(s))))
15 | }
16 |
17 | fn caption(s: &'static str) -> impl View {
18 | s.font_size(12).padding(Auto)
19 | }
20 |
21 | fn knob_example() -> impl View {
22 | hstack((
23 | caption("knob"),
24 | state(|| 0.5, |s, _| knob(s).size([30.0, 30.0]).padding(Auto)),
25 | ))
26 | }
27 |
28 | fn toggle_example() -> impl View {
29 | hstack((
30 | caption("toggle"),
31 | state(|| false, |s, _| toggle(s).size([30.0, 30.0]).padding(Auto)),
32 | ))
33 | }
34 |
35 | fn text_editor_example() -> impl View {
36 | hstack((
37 | caption("text_editor"),
38 | state(
39 | || "edit me".to_string(),
40 | |txt, _| text_editor(txt).padding(Auto),
41 | ),
42 | ))
43 | }
44 |
45 | fn my_ui() -> impl View {
46 | vstack((
47 | "rui widget gallery",
48 | button_example(),
49 | slider_example(),
50 | knob_example(),
51 | toggle_example(),
52 | text_editor_example(),
53 | ))
54 | .padding(Auto)
55 | }
56 |
57 | pub struct AppState {
58 | cx: Context,
59 | setup: Option,
60 | config: Option,
61 | vger: Option,
62 | }
63 |
64 | impl AppState {
65 | pub fn new() -> Self {
66 | Self {
67 | cx: Context::new(),
68 | setup: None,
69 | config: None,
70 | vger: None,
71 | }
72 | }
73 |
74 | pub fn setup_surface(&mut self, ca_layer_ptr: *mut c_void) {
75 | println!("ca_layer_ptr: {:?}", ca_layer_ptr);
76 |
77 | let setup = block_on(setup(unsafe { *(ca_layer_ptr as *mut *mut c_void) }));
78 |
79 | let config = wgpu::SurfaceConfiguration {
80 | usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
81 | format: setup.surface.get_supported_formats(&setup.adapter)[0],
82 | width: 1024,
83 | height: 768,
84 | present_mode: wgpu::PresentMode::Fifo,
85 | };
86 | setup.surface.configure(&setup.device, &config);
87 |
88 | self.vger = Some(Vger::new(
89 | &setup.device,
90 | wgpu::TextureFormat::Bgra8UnormSrgb,
91 | ));
92 |
93 | self.setup = Some(setup);
94 | self.config = Some(config);
95 | }
96 |
97 | pub fn update(&mut self, width: f32, height: f32) {
98 | let mut access_nodes = vec![];
99 |
100 | self.cx.update(
101 | &my_ui(),
102 | &mut self.vger.as_mut().unwrap(),
103 | &mut access_nodes,
104 | [width, height].into(),
105 | );
106 | }
107 |
108 | pub fn render(&mut self, width: f32, height: f32, scale: f32) {
109 | if let Some(setup) = &self.setup {
110 | self.cx.render(
111 | RenderInfo {
112 | device: &setup.device,
113 | surface: &setup.surface,
114 | config: &self.config.as_ref().unwrap(),
115 | queue: &setup.queue,
116 | },
117 | &my_ui(),
118 | &mut self.vger.as_mut().unwrap(),
119 | [width, height].into(),
120 | scale,
121 | );
122 | }
123 | }
124 |
125 | fn process(&mut self, event: ffi::AppEvent) {
126 | let position = LocalPoint::from([event.x,event.y]);
127 | let id = event.id;
128 | let rui_event = match event.kind {
129 | ffi::AppEventKind::TouchBegin => Event::TouchBegin { id, position },
130 | ffi::AppEventKind::TouchMove => Event::TouchMove { id, position },
131 | ffi::AppEventKind::TouchEnd => Event::TouchMove { id, position },
132 | };
133 | self.cx.process(&my_ui(), &rui_event)
134 | }
135 | }
136 |
137 | #[swift_bridge::bridge]
138 | mod ffi {
139 |
140 | pub enum AppEventKind {
141 | TouchBegin,
142 | TouchMove,
143 | TouchEnd
144 | }
145 |
146 | #[swift_bridge(swift_repr = "struct")]
147 | pub struct AppEvent {
148 | x: f32,
149 | y: f32,
150 | id: usize,
151 | kind: AppEventKind
152 | }
153 |
154 | extern "Rust" {
155 | type AppState;
156 |
157 | #[swift_bridge(init)]
158 | fn new() -> AppState;
159 |
160 | fn setup_surface(&mut self, ca_layer_ptr: *mut c_void);
161 | fn update(&mut self, width: f32, height: f32);
162 | fn render(&mut self, width: f32, height: f32, scale: f32);
163 | fn process(&mut self, event: AppEvent);
164 | }
165 | }
166 |
167 | struct Setup {
168 | surface: wgpu::Surface,
169 | adapter: wgpu::Adapter,
170 | device: wgpu::Device,
171 | queue: wgpu::Queue,
172 | }
173 |
174 | async fn setup(ca_layer_ptr: *mut core::ffi::c_void) -> Setup {
175 | let backend = wgpu::util::backend_bits_from_env().unwrap_or_else(wgpu::Backends::all);
176 |
177 | let instance = wgpu::Instance::new(backend);
178 | let surface = unsafe { instance.create_surface_from_core_animation_layer(ca_layer_ptr) };
179 | let adapter =
180 | wgpu::util::initialize_adapter_from_env_or_default(&instance, backend, Some(&surface))
181 | .await
182 | .expect("No suitable GPU adapters found on the system!");
183 |
184 | let adapter_info = adapter.get_info();
185 | println!("Using {} ({:?})", adapter_info.name, adapter_info.backend);
186 |
187 | let trace_dir = std::env::var("WGPU_TRACE");
188 | let (device, queue) = adapter
189 | .request_device(
190 | &wgpu::DeviceDescriptor {
191 | label: None,
192 | features: wgpu::Features::default(),
193 | limits: adapter.limits(),
194 | },
195 | trace_dir.ok().as_ref().map(std::path::Path::new),
196 | )
197 | .await
198 | .expect("Unable to find a suitable GPU adapter!");
199 |
200 | Setup {
201 | surface,
202 | adapter,
203 | device,
204 | queue,
205 | }
206 | }
207 |
--------------------------------------------------------------------------------