Skip to content

Commit 2c8f334

Browse files
authored
Merge pull request #50 from firefly-zero/feature/bytesview
Use `BytesView` instead of `Bytes` (+add `Utf8` hint type)
2 parents e002d80 + 700fc8a commit 2c8f334

10 files changed

Lines changed: 103 additions & 51 deletions

File tree

example/font/main.mbt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub fn render() -> Unit {
6969
///|
7070
/// Example implementation of drawing text with a drop shadow
7171
fn draw_text_shadow(
72-
text : Bytes,
72+
text : BytesView,
7373
font : @firefly.Font,
7474
point : Point,
7575
text_color : Color,
@@ -83,7 +83,7 @@ fn draw_text_shadow(
8383
///|
8484
/// Example implementation of drawing text with a drop shadow
8585
fn draw_text_rainbow(
86-
text : Bytes,
86+
text : BytesView,
8787
font : @firefly.Font,
8888
point : Point,
8989
text_colors? : FixedArray[Color] = [

example/random/main.mbt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
///|
2-
using @firefly {type Style, type Point}
2+
using @firefly {type Style, type Point, type Utf8}
33

44
///|
55
fn main {
@@ -9,12 +9,12 @@ fn main {
99
///|
1010
/// boot is only called once, after all the memory is initialized.
1111
pub fn boot() -> Unit {
12-
@firefly.log_debug("random float: " + format(@random.float()))
13-
@firefly.log_debug("random double: " + format(@random.double()))
14-
@firefly.log_debug("random int: " + format(@random.int()))
15-
@firefly.log_debug("random uint: " + format(@random.uint()))
16-
@firefly.log_debug("random int64: " + format(@random.int64()))
17-
@firefly.log_debug("random uint64: " + format(@random.uint64()))
12+
@firefly.log_debug(("random float: " : Utf8) + format(@random.float()))
13+
@firefly.log_debug(("random double: " : Utf8) + format(@random.double()))
14+
@firefly.log_debug(("random int: " : Utf8) + format(@random.int()))
15+
@firefly.log_debug(("random uint: " : Utf8) + format(@random.uint()))
16+
@firefly.log_debug(("random int64: " : Utf8) + format(@random.int64()))
17+
@firefly.log_debug(("random uint64: " : Utf8) + format(@random.uint64()))
1818
let colors : FixedArray[@firefly.Color] = [
1919
Red,
2020
Orange,
@@ -57,6 +57,6 @@ pub fn render() -> Unit {
5757
}
5858

5959
///|
60-
fn[T : Show] format(v : T) -> Bytes {
60+
fn[T : Show] format(v : T) -> Utf8 {
6161
@utf8.encode(v.to_string())
6262
}

src/audio/moon.pkg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
"firefly/firefly",
23
"firefly/firefly/internal/ffi",
34
"firefly/firefly/internal/memory",
45
}

src/audio/node.mbt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,12 +310,12 @@ pub fn Node::add_zero(self : Node) -> Zero {
310310

311311
///|
312312
/// Add source playing audio from a file.
313-
pub fn Node::add_file(self : Node, path : Bytes) -> File {
313+
pub fn Node::add_file(self : Node, path : @firefly.Utf8View) -> File {
314314
let file = File(Node::{
315315
id: @ffi.audio_add_file(
316316
self.id,
317-
@memory.bytes_addr(path),
318-
@memory.bytes_size(path),
317+
@memory.bytesview_addr(path),
318+
@memory.bytesview_size(path),
319319
),
320320
})
321321
@memory.keep(path)

src/fs.mbt

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,25 @@
44
/// Firefly Zero runtime enforces flat structure for app data and ROMs,
55
/// so the path cannot contain path separators (`/`).
66
///
7+
/// Must be UTF-8 encoded.
78
/// Any String literal or Bytes literal is a valid ASCII string:
89
///
910
/// ```text
1011
/// @firefly.load_file("font")
1112
/// ```
1213
pub type Path = Bytes
1314
15+
///|
16+
pub type PathView = BytesView
17+
1418
///|
1519
/// Get size (in bytes) of a file from ROM or the data directory.
1620
///
1721
/// Returns 0 if the file does not exist.
18-
pub fn get_file_size(path : Path) -> Int {
22+
pub fn get_file_size(path : PathView) -> Int {
1923
let size = @ffi.get_file_size(
20-
@memory.bytes_addr(path),
21-
@memory.bytes_size(path),
24+
@memory.bytesview_addr(path),
25+
@memory.bytesview_size(path),
2226
)
2327
@memory.keep(path)
2428
size
@@ -27,24 +31,24 @@ pub fn get_file_size(path : Path) -> Int {
2731
///|
2832
/// Check if the given path points to a file in ROM or the data directory.
2933
#inline
30-
pub fn is_file(path : Path) -> Bool {
34+
pub fn is_file(path : PathView) -> Bool {
3135
get_file_size(path) != 0
3236
}
3337
3438
///|
3539
/// Load a file from ROM or the data directory.
3640
///
3741
/// Example: loading fonts, images, or save files.
38-
pub fn load_file(path : Path) -> File? {
42+
pub fn load_file(path : PathView) -> File? {
3943
let size = @ffi.get_file_size(
40-
@memory.bytes_addr(path),
41-
@memory.bytes_size(path),
44+
@memory.bytesview_addr(path),
45+
@memory.bytesview_size(path),
4246
)
4347
guard size != 0 else { None }
4448
let buf = FixedArray::make(size, Byte::default())
4549
let _ = @ffi.load_file(
46-
@memory.bytes_addr(path),
47-
@memory.bytes_size(path),
50+
@memory.bytesview_addr(path),
51+
@memory.bytesview_size(path),
4852
@memory.fixedbytes_addr(buf),
4953
@memory.fixedbytes_size(buf),
5054
)
@@ -58,10 +62,10 @@ pub fn load_file(path : Path) -> File? {
5862
/// Returns the number of bytes that has been loaded.
5963
///
6064
/// Example: loading fonts, images, or save files.
61-
pub fn load_file_to(path : Path, output : FixedArray[Byte]) -> Int {
65+
pub fn load_file_to(path : PathView, output : FixedArray[Byte]) -> Int {
6266
let size = @ffi.load_file(
63-
@memory.bytes_addr(path),
64-
@memory.bytes_size(path),
67+
@memory.bytesview_addr(path),
68+
@memory.bytesview_size(path),
6569
@memory.fixedbytes_addr(output),
6670
@memory.fixedbytes_size(output),
6771
)
@@ -78,10 +82,10 @@ pub fn load_file_to(path : Path, output : FixedArray[Byte]) -> Int {
7882
/// Example: writing save files.
7983
///
8084
/// Returns the number of bytes written.
81-
pub fn dump_file(path : Path, file : File) -> Int {
85+
pub fn dump_file(path : PathView, file : File) -> Int {
8286
let size = @ffi.load_file(
83-
@memory.bytes_addr(path),
84-
@memory.bytes_size(path),
87+
@memory.bytesview_addr(path),
88+
@memory.bytesview_size(path),
8589
@memory.fixedbytes_addr(file.0),
8690
@memory.fixedbytes_size(file.0),
8791
)
@@ -93,7 +97,7 @@ pub fn dump_file(path : Path, file : File) -> Int {
9397
/// Removes a file (if exists) from the data directory.
9498
///
9599
/// Example: removing save files.
96-
pub fn remove_file(path : Path) -> Unit {
97-
@ffi.remove_file(@memory.bytes_addr(path), @memory.bytes_size(path))
100+
pub fn remove_file(path : PathView) -> Unit {
101+
@ffi.remove_file(@memory.bytesview_addr(path), @memory.bytesview_size(path))
98102
@memory.keep(path)
99103
}

src/fs_file.mbt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub fn File::as_fixed_array(self : File) -> FixedArray[Byte] {
3939
///
4040
/// Example: loading fonts, images, or save files.
4141
#inline
42-
pub fn File::load(path : Bytes) -> File? {
42+
pub fn File::load(path : PathView) -> File? {
4343
load_file(path)
4444
}
4545

@@ -53,6 +53,6 @@ pub fn File::load(path : Bytes) -> File? {
5353
///
5454
/// Returns the number of bytes written.
5555
#inline
56-
pub fn File::dump(self : File, path : Bytes) -> Int {
56+
pub fn File::dump(self : File, path : PathView) -> Int {
5757
dump_file(path, self)
5858
}

src/graphics.mbt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -198,14 +198,14 @@ pub fn draw_sector(
198198
/// ignore(utf8)
199199
/// ```
200200
pub fn draw_text(
201-
text : Bytes,
201+
text : Utf8View,
202202
font : Font,
203203
point : Point,
204204
color : Color,
205205
) -> Unit {
206206
@ffi.draw_text(
207-
@memory.bytes_addr(text),
208-
@memory.bytes_size(text),
207+
@memory.bytesview_addr(text),
208+
@memory.bytesview_size(text),
209209
@memory.fixedbytes_addr(font.0),
210210
@memory.fixedbytes_size(font.0),
211211
point.x,
@@ -218,14 +218,14 @@ pub fn draw_text(
218218
///|
219219
/// Render a QR-code.
220220
pub fn draw_qr(
221-
text : Bytes,
221+
text : Utf8View,
222222
point : Point,
223223
black : Color,
224224
white : Color,
225225
) -> Unit {
226226
@ffi.draw_qr(
227-
@memory.bytes_addr(text),
228-
@memory.bytes_size(text),
227+
@memory.bytesview_addr(text),
228+
@memory.bytesview_size(text),
229229
point.x,
230230
point.y,
231231
black.to_int(),

src/internal/memory/memory.mbt

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55
/// before Firefly runtime consumes it. To prevent this, call "keep"
66
/// at the end of the function to keep the value from being deallocated too early.
77
#inline
8-
pub fn[T] keep(v : T) -> Unit {
9-
ignore(v)
10-
}
8+
pub fn[T] keep(v : T) -> Unit = "%ignore"
119

1210
///|
1311
#inline
@@ -21,6 +19,12 @@ pub fn bytes_size(bytes : Bytes) -> Int {
2119
bytes.length()
2220
}
2321

22+
///|
23+
#inline
24+
pub fn bytesview_size(bytes : BytesView) -> Int {
25+
bytes.length()
26+
}
27+
2428
///|
2529
#inline
2630
#borrow(bytes)
@@ -34,3 +38,9 @@ pub extern "wasm" fn fixedbytes_addr(bytes : FixedArray[Byte]) -> UInt =
3438
pub extern "wasm" fn bytes_addr(bytes : Bytes) -> UInt =
3539
#|(func (param i32) (result i32)
3640
#| (i32.add (local.get 0) (i32.const 8)))
41+
42+
///|
43+
#inline
44+
pub fn bytesview_addr(bytes : BytesView) -> UInt {
45+
bytes_addr(bytes.data()) + bytes.start_offset().reinterpret_as_uint()
46+
}

src/misc.mbt

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,51 @@
1+
///|
2+
/// Type hint that we need a UTF-8 formatted `Bytes`.
3+
///
4+
/// All Firefly functions that accept text only accepts UTF-8 encoded text.
5+
/// But MoonBit uses UTF-16 for its `string` type.
6+
/// Meaning, you should not be using the MoonBit `string` type with the Firefly SDK.
7+
///
8+
/// Instead, you can use string and bytes literals with `Utf8` (or `Bytes`)
9+
///
10+
/// ```mbt check
11+
/// test {
12+
/// let utf8 : @firefly.Utf8 = "hello"
13+
/// ignore(utf8)
14+
/// }
15+
/// ```
16+
pub type Utf8 = Bytes
17+
18+
///|
19+
/// Type hint that we need a UTF-8 formatted `BytesView`.
20+
///
21+
/// A "view" is a reference to a part of a `Bytes`, and is more flexible
22+
/// to use as function parameters.
23+
///
24+
/// All Firefly functions that accept text only accepts UTF-8 encoded text.
25+
/// But MoonBit uses UTF-16 for its `string` type.
26+
/// Meaning, you should not be using the MoonBit `string` type with the Firefly SDK.
27+
///
28+
/// Instead, you can use string and bytes literals with `Utf8View` (or `BytesView`)
29+
///
30+
/// ```mbt check
31+
/// test {
32+
/// let utf8 : @firefly.Utf8View = "hello"
33+
/// ignore(utf8)
34+
/// }
35+
/// ```
36+
pub type Utf8View = BytesView
37+
138
///|
239
/// Log a debug message.
3-
pub fn log_debug(s : Bytes) -> Unit {
4-
@ffi.log_debug(@memory.bytes_addr(s), @memory.bytes_size(s))
40+
pub fn log_debug(s : Utf8View) -> Unit {
41+
@ffi.log_debug(@memory.bytesview_addr(s), @memory.bytesview_size(s))
542
@memory.keep(s)
643
}
744
845
///|
946
/// Log an error message.
10-
pub fn log_error(s : Bytes) -> Unit {
11-
@ffi.log_error(@memory.bytes_addr(s), @memory.bytes_size(s))
47+
pub fn log_error(s : Utf8View) -> Unit {
48+
@ffi.log_error(@memory.bytesview_addr(s), @memory.bytesview_size(s))
1249
@memory.keep(s)
1350
}
1451
@@ -41,7 +78,7 @@ pub fn get_random() -> UInt {
4178
4279
///|
4380
/// Get name of the device.
44-
pub fn get_name(peer : Peer) -> Bytes {
81+
pub fn get_name(peer : Peer) -> Utf8 {
4582
let arr = FixedArray::make(16, Byte::default())
4683
let len = @ffi.get_name(peer.raw, @memory.fixedbytes_addr(arr))
4784
Bytes::from_array(arr[:len])

src/misc_language.mbt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ pub fn Language::from_raw(raw : UInt16) -> Language? {
5454
}
5555

5656
///|
57-
pub fn Language::from_code(code : Bytes) -> Language? {
57+
pub fn Language::from_code(code : Utf8View) -> Language? {
5858
match code {
5959
"en" => Some(English)
6060
"nl" => Some(Dutch)
@@ -75,7 +75,7 @@ pub fn Language::from_code(code : Bytes) -> Language? {
7575

7676
///|
7777
/// The language name in English.
78-
pub fn Language::name_english(lang : Language) -> Bytes {
78+
pub fn Language::name_english(lang : Language) -> Utf8 {
7979
match lang {
8080
English => "English"
8181
Dutch => "Dutch"
@@ -95,7 +95,7 @@ pub fn Language::name_english(lang : Language) -> Bytes {
9595

9696
///|
9797
/// The language name in the language itself (endonym).
98-
pub fn Language::name_native(lang : Language) -> Bytes {
98+
pub fn Language::name_native(lang : Language) -> Utf8 {
9999
match lang {
100100
English => "English"
101101
Dutch => "Nederlands"
@@ -114,7 +114,7 @@ pub fn Language::name_native(lang : Language) -> Bytes {
114114
}
115115

116116
///|
117-
pub fn Language::code(lang : Language) -> Bytes {
117+
pub fn Language::code(lang : Language) -> Utf8 {
118118
match lang {
119119
English => "en"
120120
Dutch => "nl"
@@ -136,7 +136,7 @@ pub fn Language::code(lang : Language) -> Bytes {
136136
/// ISO 8859 encoding slug for the language.
137137
///
138138
/// Useful for dynamically loading the correct font for the given language.
139-
pub fn Language::encoding(lang : Language) -> Bytes {
139+
pub fn Language::encoding(lang : Language) -> Utf8 {
140140
match lang {
141141
// Just like English, Dutch has very little non-ASCII characters
142142
// which can be avoided in translations to make it possible to stick

0 commit comments

Comments
 (0)