examples,os: add an os.asset module, use it to simplify code in examples/, by removing $if android { checks (#22281)

This commit is contained in:
Delyan Angelov 2024-09-22 16:04:05 +03:00 committed by GitHub
parent 64d1770cf1
commit cfa91d81d7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 69 additions and 117 deletions

View file

@ -1,7 +1,7 @@
import gg
import gx
import math
import os
import os.asset
import rand
import time
@ -899,10 +899,6 @@ fn init(mut app App) {
fn main() {
mut app := &App{}
app.new_game()
mut font_path := os.resource_abs_path(os.join_path('..', 'assets', 'fonts', 'RobotoMono-Regular.ttf'))
$if android {
font_path = 'fonts/RobotoMono-Regular.ttf'
}
app.gg = gg.new_context(
bg_color: app.theme.bg_color
width: default_window_width
@ -913,7 +909,7 @@ fn main() {
event_fn: on_event
init_fn: init
user_data: app
font_path: font_path
font_path: asset.get_path('../assets', 'fonts/RobotoMono-Regular.ttf')
)
app.gg.run()
}

View file

@ -2,7 +2,6 @@
// This is a small V example that was based off of the fireworks example.
// Written by Stefan Schroeder in 2021 for the v project examples.
// See LICENSE for license information.
import os
import gg
import gx
import math
@ -147,13 +146,7 @@ fn on_init(mut app App) {
fn main() {
println("Press 'q' to quit.")
mut font_path := os.resource_abs_path(os.join_path('..', 'assets', 'fonts', 'RobotoMono-Regular.ttf'))
$if android {
font_path = 'fonts/RobotoMono-Regular.ttf'
}
mut app := &App{}
app.gg = gg.new_context(
width: design_size
height: design_size
@ -163,8 +156,6 @@ fn main() {
frame_fn: on_frame
event_fn: on_event
init_fn: on_init
font_path: font_path
)
app.gg.run()
}

View file

@ -1,4 +1,3 @@
import os
import objects
import gg
import gx
@ -94,14 +93,8 @@ fn (mut app App) resize() {
}
fn main() {
mut font_path := os.resource_abs_path(os.join_path('..', 'assets', 'fonts', 'RobotoMono-Regular.ttf'))
$if android {
font_path = 'fonts/RobotoMono-Regular.ttf'
}
mut app := &App{}
app.ui = objects.get_params()
app.gg = gg.new_context(
width: app.ui.width
height: app.ui.height
@ -110,8 +103,6 @@ fn main() {
user_data: app
frame_fn: on_frame
event_fn: on_event
font_path: font_path
)
app.gg.run()
}

View file

@ -2,11 +2,11 @@ module main
import gg
import gx
import os
import time
import math
import rand
import neuroevolution
import os.asset
const win_width = 500
const win_height = 512
@ -173,10 +173,6 @@ fn (mut app App) update() {
fn main() {
mut app := &App{}
mut font_path := os.resource_abs_path(os.join_path('..', 'assets', 'fonts', 'RobotoMono-Regular.ttf'))
$if android {
font_path = 'fonts/RobotoMono-Regular.ttf'
}
app.gg = gg.new_context(
bg_color: gx.white
width: win_width
@ -187,7 +183,7 @@ fn main() {
event_fn: on_event
user_data: app
init_fn: app.init_images_wrapper
font_path: font_path
font_path: asset.get_path('../assets', 'fonts/RobotoMono-Regular.ttf')
)
app.nv = neuroevolution.Generations{
population: 50
@ -210,21 +206,10 @@ fn (mut app App) init_images_wrapper() {
}
fn (mut app App) init_images() ! {
$if android {
background := os.read_apk_asset('img/background.png')!
app.background = app.gg.create_image_from_byte_array(background)!
bird := os.read_apk_asset('img/bird.png')!
app.bird = app.gg.create_image_from_byte_array(bird)!
pipetop := os.read_apk_asset('img/pipetop.png')!
app.pipetop = app.gg.create_image_from_byte_array(pipetop)!
pipebottom := os.read_apk_asset('img/pipebottom.png')!
app.pipebottom = app.gg.create_image_from_byte_array(pipebottom)!
} $else {
app.background = app.gg.create_image(os.resource_abs_path('assets/img/background.png'))!
app.bird = app.gg.create_image(os.resource_abs_path('assets/img/bird.png'))!
app.pipetop = app.gg.create_image(os.resource_abs_path('assets/img/pipetop.png'))!
app.pipebottom = app.gg.create_image(os.resource_abs_path('assets/img/pipebottom.png'))!
}
app.background = app.gg.create_image_from_byte_array(asset.read_bytes('assets', 'img/background.png')!)!
app.bird = app.gg.create_image_from_byte_array(asset.read_bytes('assets', 'img/bird.png')!)!
app.pipetop = app.gg.create_image_from_byte_array(asset.read_bytes('assets', 'img/pipetop.png')!)!
app.pipebottom = app.gg.create_image_from_byte_array(asset.read_bytes('assets', 'img/pipebottom.png')!)!
}
fn frame(app &App) {

View file

@ -2,7 +2,7 @@ module main
import gg
import gx
import os
import os.asset
import math
const win_width = 600
@ -62,10 +62,6 @@ mut:
fn main() {
mut app := &App{}
mut font_path := os.resource_abs_path(os.join_path('..', 'assets', 'fonts', 'RobotoMono-Regular.ttf'))
$if android {
font_path = 'fonts/RobotoMono-Regular.ttf'
}
app.gg = gg.new_context(
width: win_width
height: win_height
@ -74,7 +70,8 @@ fn main() {
user_data: app
bg_color: bg_color
frame_fn: frame
font_path: font_path // window_user_ptr: ctx
font_path: asset.get_path('../assets', 'fonts/RobotoMono-Regular.ttf')
// window_user_ptr: ctx
// native_rendering: true
)
app.gg.run()

View file

@ -2,7 +2,7 @@ module main
import gg
import gx
import os
import os.asset
const win_width = 600
const win_height = 300
@ -23,20 +23,12 @@ fn main() {
window_title: 'Rectangles'
frame_fn: frame
user_data: app
init_fn: init_images
)
mut logo_path := os.resource_abs_path(os.join_path('..', 'assets', 'logo.png'))
$if android {
logo_path = 'logo.png'
}
logo_path := asset.get_path('../assets', 'logo.png')
app.image = app.gg.create_image(logo_path)!.id
app.gg.run()
}
fn init_images(mut app App) {
// app.image = gg.create_image('logo.png')
}
fn frame(app &App) {
app.gg.begin()
app.draw()

View file

@ -1,6 +1,6 @@
import gg
import gx
import os
import os.asset
import sokol.sgl
pub struct Window {
@ -10,11 +10,7 @@ pub mut:
}
pub fn (mut window Window) init() {
image_path := $if android {
'logo.png'
} $else {
os.resource_abs_path('../assets/logo.png')
}
image_path := asset.get_path('../assets', 'logo.png')
window.img = window.ctx.create_image(image_path) or { panic(err) }
}

View file

@ -1,6 +1,6 @@
module main
import os
import os.asset
import gg
import gx
import rand
@ -78,10 +78,7 @@ fn main() {
}
fn init_images(mut app App) {
mut logo_path := os.resource_abs_path(os.join_path('..', 'assets', 'logo.png'))
$if android {
logo_path = 'logo.png'
}
logo_path := asset.get_path('../assets', 'logo.png')
app.image = app.gg.create_image(logo_path) or { panic(err) }
}

View file

@ -1,52 +1,24 @@
module obj
import os
import os.asset
// read a file as single lines
pub fn read_lines_from_file(file_path string) []string {
mut path := ''
mut rows := []string{}
$if android {
path = 'models/' + file_path
bts := os.read_apk_asset(path) or {
eprintln('File [${path}] NOT FOUND!')
return rows
if os.exists(file_path) {
return os.read_lines(file_path) or { [] }
}
rows = bts.bytestr().split_into_lines()
} $else {
path = if os.exists(file_path) {
file_path
} else {
os.resource_abs_path('assets/models/${file_path}')
}
rows = os.read_lines(path) or {
eprintln('File [${path}] NOT FOUND! file_path: ${file_path}')
return rows
}
}
return rows
return read_bytes_from_file(file_path).bytestr().split_into_lines()
}
// read a file as []u8
pub fn read_bytes_from_file(file_path string) []u8 {
mut path := ''
mut buffer := []u8{}
$if android {
path = 'models/' + file_path
buffer = os.read_apk_asset(path) or {
eprintln('Texture file: [${path}] NOT FOUND!')
if os.exists(file_path) {
return os.read_bytes(file_path) or { [] }
}
mpath := 'models/${file_path}'
return asset.read_bytes('assets', mpath) or {
eprintln('Model file NOT FOUND: `${mpath}`')
exit(0)
}
} $else {
path = if os.exists(file_path) {
file_path
} else {
os.resource_abs_path('assets/models/${file_path}')
}
buffer = os.read_bytes(path) or {
eprintln('Texture file: [${path}] NOT FOUND!')
exit(0)
}
}
return buffer
}

View file

@ -3,7 +3,7 @@
// that can be found in the LICENSE file.
module main
import os
import os.asset
import rand
import time
import gx
@ -157,10 +157,6 @@ fn frame(mut game Game) {
fn main() {
mut game := &Game{}
mut fpath := os.resource_abs_path(os.join_path('..', 'assets', 'fonts', 'RobotoMono-Regular.ttf'))
$if android {
fpath = 'fonts/RobotoMono-Regular.ttf'
}
game.gg = gg.new_context(
bg_color: gx.white
width: win_width
@ -170,7 +166,8 @@ fn main() {
user_data: game
frame_fn: frame
event_fn: on_event
font_path: fpath // wait_events: true
font_path: asset.get_path('../assets', 'fonts/RobotoMono-Regular.ttf')
// wait_events: true
)
game.init_game()
game.gg.run() // Run the render loop in the main thread

11
vlib/os/asset/README.md Normal file
View file

@ -0,0 +1,11 @@
# Asset
The `asset` module provides a cross platform way to read assets, without cluttering
the user code with comptime conditionals, like `$if ios {` or `$if android {` etc.
Currently it supports Android assets, and desktop applications, that do not use
archived/zipped files, but could be extended to support archived files too in the future.
It relies on the assumption that each platform has a way to either read files, relative
to the location of the executable, or a platform specific way, to package all asset files
into the application archive/package/executable, that is then distributed to the end users.

27
vlib/os/asset/asset.v Normal file
View file

@ -0,0 +1,27 @@
module asset
import os
// get_path returns a platform specific path, based on the given asset base folder and relative path
// of a resource in it. On desktop systems, it returns a path relative to the location of the executable.
// On Android, it will return just the relative_path segment, allowing you to later use os.read_apk_asset
// to read from it.
pub fn get_path(base_folder string, relative_path string) string {
$if android {
return relative_path
} $else {
return os.resource_abs_path(os.join_path(base_folder, relative_path))
}
}
// read_bytes will read all of the given asset, specified by its base_folder and relative path in it.
// On Android, it will use os.read_apk_asset, relying that the asset base folder has been prepared, and
// prepackaged inside your APK. On desktop systems, it will use the base_folder and relative_path, to
// locate the file, in a way, that is relative to the executable.
pub fn read_bytes(base_folder string, relative_path string) ![]u8 {
$if android {
return os.read_apk_asset(get_path(base_folder, relative_path))
} $else {
return os.read_bytes(get_path(base_folder, relative_path))
}
}