tools: format most examples and tutorials, add them to `v test-cleancode` (#9826)

pull/9830/head
Lukas Neubert 2021-04-20 16:16:35 +02:00 committed by GitHub
parent dff50686d6
commit 16e79bc3ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 471 additions and 433 deletions

View File

@ -18,12 +18,18 @@ const (
'examples/term.ui',
]
verify_known_failing_exceptions = [
// Handcrafted meaningful formatting of code parts (mostly arrays)
'examples/sokol/02_cubes_glsl/cube_glsl.v',
'examples/sokol/03_march_tracing_glsl/rt_glsl.v',
'examples/sokol/04_multi_shader_glsl/rt_glsl.v',
'examples/sokol/05_instancing_glsl/rt_glsl.v',
'vlib/gg/m4/graphic.v',
'vlib/gg/m4/m4_test.v',
'vlib/gg/m4/matrix.v',
'vlib/builtin/int_test.v' /* special number formatting that should be tested */,
// TODOs and unfixed vfmt bugs
'vlib/builtin/int.v' /* TODO byteptr: vfmt converts `pub fn (nn byteptr) str() string {` to `nn &byte` and that conflicts with `nn byte` */,
'vlib/builtin/string_charptr_byteptr_helpers.v' /* TODO byteptr: a temporary shim to ease the byteptr=>&byte transition */,
'vlib/gg/m4/graphic.v' /* has hand crafted meaningful formatting of matrices */,
'vlib/gg/m4/m4_test.v' /* has hand crafted meaningful formatting of matrices */,
'vlib/gg/m4/matrix.v' /* has hand crafted meaningful formatting of matrices */,
'vlib/v/tests/array_append_short_struct_test.v', /* extra empty line */
'vlib/v/tests/fixed_array_const_size_test.v', /* fixed arr type is changed */
'vlib/v/tests/fn_high_test.v', /* param name removed */
@ -34,9 +40,13 @@ const (
'vlib/v/tests/string_interpolation_test.v' /* TODO byteptr: &byte.str() behaves differently than byteptr.str() */,
'vlib/v/gen/js/tests/js.v', /* local `hello` fn, gets replaced with module `hello` aliased as `hl` */
'vlib/v/gen/c/cheaders.v' /* the preprocessor directives are formated to the V standard, even though they are in a string literal */,
'examples/c_interop_wkhtmltopdf.v', /* &charptr --> &&char */
'examples/path_tracing.v', /* block --> line comments corrupts code */
]
vfmt_verify_list = [
'cmd/',
'examples/',
'tutorials/',
'vlib/arrays/',
'vlib/benchmark/',
'vlib/bitfield/',

View File

@ -32,9 +32,9 @@ fn main() {
description: 'Number of times the message gets printed.'
})
greet_cmd.add_flag(Flag{
flag: .string_array
name: 'fun'
description: 'Just a dumby flags to show multiple.'
flag: .string_array
name: 'fun'
description: 'Just a dumby flags to show multiple.'
})
cmd.add_command(greet_cmd)
cmd.setup()

View File

@ -1,12 +1,18 @@
struct App {}
fn (mut app App) method_one() {}
fn (mut app App) method_two() int { return 0 }
fn (mut app App) method_three(s string) string { return s }
fn (mut app App) method_two() int {
return 0
}
fn (mut app App) method_three(s string) string {
return s
}
fn main() {
$for method in App.methods {
$if method.typ is fn(string) string {
$if method.typ is fn (string) string {
println('$method.name IS `fn(string) string`')
} $else {
println('$method.name is NOT `fn(string) string`')
@ -17,12 +23,12 @@ fn main() {
println('$method.name DOES return `int`')
}
$if method.args[0].typ !is string {
println("${method.name}'s first arg is NOT `string`")
println("$method.name's first arg is NOT `string`")
} $else {
println("${method.name}'s first arg IS `string`")
println("$method.name's first arg IS `string`")
}
// TODO: Double inversion, should this even be allowed?
$if method.typ is fn() {
$if method.typ is fn () {
println('$method.name IS a void method')
} $else {
println('$method.name is NOT a void method')

View File

@ -4,7 +4,7 @@ import time
fn vlang_time(mut wg sync.WaitGroup) ?string {
start := time.ticks()
data := http.get('https://vlang.io/utc_now')?
data := http.get('https://vlang.io/utc_now') ?
finish := time.ticks()
println('Finish getting time ${finish - start} ms')
println(data.text)
@ -14,7 +14,7 @@ fn vlang_time(mut wg sync.WaitGroup) ?string {
fn remote_ip(mut wg sync.WaitGroup) ?string {
start := time.ticks()
data := http.get('https://api.ipify.org')?
data := http.get('https://api.ipify.org') ?
finish := time.ticks()
println('Finish getting ip ${finish - start} ms')
println(data.text)

View File

@ -1,7 +1,7 @@
import sqlite
fn main() {
db := sqlite.connect(':memory:')?
db := sqlite.connect(':memory:') ?
db.exec("create table users (id integer primary key, name text default '');")
db.exec("insert into users (name) values ('Sam')")
@ -15,7 +15,7 @@ fn main() {
assert name == 'Sam'
users, code := db.exec('select * from users')
println("SQL Result code: $code")
println('SQL Result code: $code')
for row in users {
println(row.vals)
}

View File

@ -2,9 +2,9 @@ module main
import some_module
fn main(){
fn main() {
mut sub := some_module.get_subscriber()
sub.subscribe("error", on_error)
sub.subscribe('error', on_error)
some_module.do_work()
}

View File

@ -16,19 +16,19 @@ pub:
message string
}
pub fn do_work(){
pub fn do_work() {
work := Work{20}
for i in 0..20 {
println("working...")
for i in 0 .. 20 {
println('working...')
if i == 15 {
error := &MyError{"There was an error."}
eb.publish("error", work, error)
eb.publish("error", work, error)
error := &MyError{'There was an error.'}
some_module.eb.publish('error', work, error)
some_module.eb.publish('error', work, error)
return
}
}
}
pub fn get_subscriber() eventbus.Subscriber {
return *eb.subscriber
return *some_module.eb.subscriber
}

View File

@ -3,15 +3,15 @@
fn main() {
// Check for user input
//if os.args.len != 2 {
// println('usage: fibonacci [rank]')
// if os.args.len != 2 {
// println('usage: fibonacci [rank]')
// Exit
// return
// }
// Exit
// return
// }
// Parse first argument and cast it to int
// stop := os.args[1].int()
// stop := os.args[1].int()
stop := 23
// Can only calculate correctly until rank 92
if stop > 92 {
@ -23,7 +23,7 @@ fn main() {
mut a := 0
mut b := 0
mut c := 1
println(a+c+c)
println(a + c + c)
for _ in 0 .. stop {
// Set a and b to the next term
a = b

View File

@ -61,14 +61,18 @@ fn on_frame(mut app App) {
fn on_event(e &gg.Event, mut app App) {
match e.typ {
.resized, .resumed { app.resize() }
.iconified { app.draw_flag = false }
.resized, .resumed {
app.resize()
}
.iconified {
app.draw_flag = false
}
.restored {
app.draw_flag = true
app.resize()
}
else {
//println("Type ${e.typ}")
// println("Type ${e.typ}")
}
}
}
@ -89,7 +93,8 @@ fn (mut app App) resize() {
app.ui.height = size.height
}
[console] // is needed for easier diagnostics on windows
// is needed for easier diagnostics on windows
[console]
fn main() {
mut font_path := os.resource_abs_path(os.join_path('../assets/fonts/', 'RobotoMono-Regular.ttf'))
$if android {

View File

@ -29,7 +29,7 @@ fn (mut n Neuron) populate(nb int) {
}
struct Layer {
id int
id int
mut:
neurons []Neuron
}
@ -50,7 +50,7 @@ mut:
fn (mut n Network) populate(network []int) {
assert network.len >= 2
input := network[0]
hiddens := network[1..network.len-1]
hiddens := network[1..network.len - 1]
output := network[network.len - 1]
mut index := 0
mut previous_neurons := 0
@ -232,8 +232,8 @@ fn (g Generation) next(population int) []Save {
pub struct Generations {
pub:
population int
network []int
population int
network []int
mut:
generations []Generation
}

View File

@ -42,7 +42,7 @@ fn main() {
gg: 0
a: automaton.gun()
}
app.gg = gg.new_context({
app.gg = gg.new_context(
bg_color: gx.white
frame_fn: frame
user_data: &app
@ -52,6 +52,6 @@ fn main() {
create_window: true
resizable: false
window_title: 'v life (with gg, gx)'
})
)
app.gg.run()
}

View File

@ -79,15 +79,11 @@ pub fn (mut aa Automaton) update() {
for y := 1; y < aa.field.maxy; y++ {
for x := 1; x < aa.field.maxx; x++ {
moore_sum := (0 + aa.field.get(x - 1, y - 1) + aa.field.get(x, y - 1) + aa.field.get(x +
1, y - 1) + aa.field.get(x - 1, y) + 0 + aa.field.get(x + 1, y) + aa.field.get(x - 1, y + 1) +
aa.field.get(x, y + 1) + aa.field.get(x + 1, y + 1))
1, y - 1) + aa.field.get(x - 1, y) + 0 + aa.field.get(x + 1, y) +
aa.field.get(x - 1, y + 1) + aa.field.get(x, y + 1) + aa.field.get(x + 1, y + 1))
cell := aa.field.get(x, y)
v := if cell == 1 { moore_sum in [2, 3] } else { moore_sum == 3 }
aa.new_field.set(x, y, if v {
1
} else {
0
})
aa.new_field.set(x, y, if v { 1 } else { 0 })
}
}
tmp := aa.field

View File

@ -19,7 +19,7 @@ fn main() {
mut app := &App{
gg: 0
}
app.gg = gg.new_context({
app.gg = gg.new_context(
bg_color: gx.white
width: win_width
height: win_height
@ -29,7 +29,7 @@ fn main() {
frame_fn: frame
user_data: app
init_fn: init_images
})
)
app.image = app.gg.create_image(os.resource_abs_path('logo.png'))
app.gg.run()
}

View File

@ -73,7 +73,7 @@ fn (ctx &Context) draw() {
// y = x * x + stime * stime
// y = stime
// y = stime * h
y = stime * 1.0 * math.sin((x) + stime + atime / 32) * ((h / 256) + x)
y = stime * 1.0 * math.sin(x + stime + atime / 32) * ((h / 256) + x)
// y = (stime * x) * x + stime
// y = (x + 3) * (x + 3) / stime + stime*2.5
// y = math.sqrt(30.0 - x * x) * stime

View File

@ -24,6 +24,7 @@ struct Lander {
fn (l Lander) deorbit() {
println('leaving orbit')
}
fn (l Lander) open_parachutes(n int) {
println('opening $n parachutes')
}

View File

@ -19,7 +19,6 @@ fn hello_response() string {
return 'Hello, World!'
}
fn callback(req picohttpparser.Request, mut res picohttpparser.Response) {
if picohttpparser.cmpn(req.method, 'GET ', 4) {
if picohttpparser.cmp(req.path, '/t') {
@ -28,19 +27,16 @@ fn callback(req picohttpparser.Request, mut res picohttpparser.Response) {
res.header_date()
res.plain()
res.body(hello_response())
}
else if picohttpparser.cmp(req.path, '/j') {
} else if picohttpparser.cmp(req.path, '/j') {
res.http_ok()
res.header_server()
res.header_date()
res.json()
res.body(json_response())
}
else {
} else {
res.http_404()
}
}
else {
} else {
res.http_405()
}
}

View File

@ -31,10 +31,6 @@ fn main() {
body_type: .html
body: body
}
mut client := smtp.new_client(client_cfg) or {
panic('Error configuring smtp')
}
client.send(send_cfg) or {
panic('Error resolving email address')
}
mut client := smtp.new_client(client_cfg) or { panic('Error configuring smtp') }
client.send(send_cfg) or { panic('Error resolving email address') }
}

View File

@ -9,10 +9,11 @@
* TODO:
**********************************************************************/
module obj
import gg.m4
import strconv
enum F_state{
enum F_state {
start
first
ints
@ -24,9 +25,9 @@ enum F_state{
// read a int from a string
fn get_int(s string, start_index int) (int, int) {
mut i := start_index
mut res := 0
mut sgn := 1
mut i := start_index
mut res := 0
mut sgn := 1
mut state := F_state.start
for true {
@ -50,11 +51,11 @@ fn get_int(s string, start_index int) (int, int) {
`0`...`9` {
state = .ints
}
` `,`\t` {
` `, `\t` {
i++
continue
}
else{ // no number found
else { // no number found
break
}
}
@ -63,7 +64,7 @@ fn get_int(s string, start_index int) (int, int) {
if state == .ints {
match c {
`0`...`9` {
//println("$res => ${(int(c) - 48)}")
// println("$res => ${(int(c) - 48)}")
res = res * 10 + (int(c) - 48)
i++
continue
@ -73,55 +74,60 @@ fn get_int(s string, start_index int) (int, int) {
}
}
}
}
//println("---")
// println("---")
return res * sgn, i
}
// reas a float number from a string
fn get_float(s string, start_index int) (f64, int) {
mut i1 := start_index //+ 1
for i1 < s.len && s[i1] in [` `,`\t`] {
for i1 < s.len && s[i1] in [` `, `\t`] {
i1++
}
mut i := i1
for i < s.len {
if s[i] in [` `,`\t`] {
if s[i] in [` `, `\t`] {
break
}
i++
}
//println(" get_float: ($start_index,$i) [${s[start_index..i]}]")
//f_res := strconv.atof_quick(s[start_index..i])
// println(" get_float: ($start_index,$i) [${s[start_index..i]}]")
// f_res := strconv.atof_quick(s[start_index..i])
f_res := strconv.atof_quick(s[i1..i])
return f_res, i
}
// read 3 f32 in sequence from a string
fn parse_3f(row string, start_index int) m4.Vec4 {
//println(row)
// println(row)
mut i := start_index //+ 1
mut f1 := f64(0)
mut f2 := f64(0)
f0,mut p := get_float(row,i)
//print("Here f0: $f0 $p ")
f1, p = get_float(row,p+1)
//print("Here f1: $f1 $p ")
f2, p = get_float(row,p+1)
//print("Here f2: $f2 $p ")
return m4.Vec4{e:[f32(f0), f32(f1), f32(f2), 1]!}
f0, mut p := get_float(row, i)
// print("Here f0: $f0 $p ")
f1, p = get_float(row, p + 1)
// print("Here f1: $f1 $p ")
f2, p = get_float(row, p + 1)
// print("Here f2: $f2 $p ")
return m4.Vec4{
e: [f32(f0), f32(f1), f32(f2), 1]!
}
}
// reas a sequence of f32 from a string
fn (mut m ObjPart) parse_floats(row string, start_index int) m4.Vec4 {
mut i := start_index //+ 1
mut res_f := f64(0)
mut res := m4.Vec4{e:[f32(0), 0, 0, 1]!}
mut c := 0
mut i := start_index //+ 1
mut res_f := f64(0)
mut res := m4.Vec4{
e: [f32(0), 0, 0, 1]!
}
mut c := 0
for true {
res_f, i = get_float(row, i)
unsafe { res.e[c] = f32(res_f) }
unsafe {
res.e[c] = f32(res_f)
}
c++
i++
if i >= row.len {
@ -133,12 +139,12 @@ fn (mut m ObjPart) parse_floats(row string, start_index int) m4.Vec4 {
// read and manage all the faes from an .obj file data
fn (mut p Part) parse_faces(row string, start_index int, obj ObjPart) {
mut i := start_index + 1
mut res := [][3]int{}
mut v := 0
mut t := 0
mut n := 0
//println("row: ${row[i..]}")
mut i := start_index + 1
mut res := [][3]int{}
mut v := 0
mut t := 0
mut n := 0
// println("row: ${row[i..]}")
for true {
t = 0
n = 0
@ -146,29 +152,28 @@ fn (mut p Part) parse_faces(row string, start_index int, obj ObjPart) {
break
}
mut c := row[i]
if (c > `9` || c < `0`) && c != `-`{
if (c > `9` || c < `0`) && c != `-` {
i++
continue
}
v, i = get_int(row, i)
if i < row.len && row[i] == `/` {
if row[i+1] != `/` {
t,i = get_int(row, i+1)
if row[i + 1] != `/` {
t, i = get_int(row, i + 1)
if i < row.len && row[i] == `/` {
n,i = get_int(row, i+1)
n, i = get_int(row, i + 1)
}
} else {
i++
n,i = get_int(row, i+1)
n, i = get_int(row, i + 1)
}
}
// manage negative indexes
// NOTE: not well suporeted now
if v < 0 {
//println("${obj.v.len} ${obj.v.len-c}")
// println("${obj.v.len} ${obj.v.len-c}")
v = obj.v.len - v + 1
//exit(0)
// exit(0)
}
if n < 0 {
n = obj.vn.len - n + 1
@ -176,23 +181,24 @@ fn (mut p Part) parse_faces(row string, start_index int, obj ObjPart) {
if t < 0 {
t = obj.vt.len - t + 1
}
res << [v-1,n-1,t-1]!
res << [v - 1, n - 1, t - 1]!
}
//println("ok res: ${res}")
//println(p.faces.len)
// println("ok res: ${res}")
// println(p.faces.len)
p.faces << res
}
// parse the obj file, if single_material is true it use only one default material
pub fn (mut obj_part ObjPart) parse_obj_buffer(rows []string, single_material bool){
pub fn (mut obj_part ObjPart) parse_obj_buffer(rows []string, single_material bool) {
mut mat_count := 0
mut row_count := 0
default_part := Part{name:"default part"}
default_part := Part{
name: 'default part'
}
obj_part.part << default_part
//println("OBJ file has ${rows.len} rows")
// println("OBJ file has ${rows.len} rows")
for c, row in rows {
//println("$c $row")
// println("$c $row")
mut i := 0
row_count++
for true {
@ -204,32 +210,35 @@ pub fn (mut obj_part ObjPart) parse_obj_buffer(rows []string, single_material bo
break
}
`m` {
if row[i..i+6] == "mtllib" {
obj_part.material_file = row[i+7..].trim_space()
if row[i..i + 6] == 'mtllib' {
obj_part.material_file = row[i + 7..].trim_space()
obj_part.load_materials()
}
break
}
`o`, `g` {
mut part := Part{}
part.name = row[i+1..].trim_space()
part.name = row[i + 1..].trim_space()
obj_part.part << part
mat_count = 0
break
}
`u` {
if single_material == false && row[i..i+6] == "usemtl" {
material := row[i+7..].trim_space()
//println("material: $material")
if single_material == false && row[i..i + 6] == 'usemtl' {
material := row[i + 7..].trim_space()
// println("material: $material")
// manage multiple materials in an part
if obj_part.part[obj_part.part.len - 1].material.len > 0 {
mat_count++
mut part := Part{}
if mat_count > 1 {
li := obj_part.part[obj_part.part.len - 1].name.last_index("_m") or {obj_part.part[obj_part.part.len - 1].name.len - 1}
part.name = obj_part.part[obj_part.part.len - 1].name[..li] + "_m${mat_count:02}"
li := obj_part.part[obj_part.part.len - 1].name.last_index('_m') or {
obj_part.part[obj_part.part.len - 1].name.len - 1
}
part.name = obj_part.part[obj_part.part.len - 1].name[..li] +
'_m${mat_count:02}'
} else {
part.name = obj_part.part[obj_part.part.len - 1].name + "_m01"
part.name = obj_part.part[obj_part.part.len - 1].name + '_m01'
}
obj_part.part << part
}
@ -239,54 +248,53 @@ pub fn (mut obj_part ObjPart) parse_obj_buffer(rows []string, single_material bo
}
`v` {
i++
match row[i]{
match row[i] {
// normals
`n` {
obj_part.vn << parse_3f(row, i+2)
//println("Vertex line: $c")
obj_part.vn << parse_3f(row, i + 2)
// println("Vertex line: $c")
break
}
// parameteres uvw
`p` {
obj_part.vp << parse_3f(row, i+2)
//println("Vertex line: ${obj_part.vp.len}")
obj_part.vp << parse_3f(row, i + 2)
// println("Vertex line: ${obj_part.vp.len}")
break
}
// texture uvw
`t` {
obj_part.vt << obj_part.parse_floats(row, i+2)
//println("Vertex line: $c")
obj_part.vt << obj_part.parse_floats(row, i + 2)
// println("Vertex line: $c")
break
}
else {
obj_part.v << parse_3f(row, i+1)
//println("$row => ${obj_part.v[obj_part.v.len-1]}")
obj_part.v << parse_3f(row, i + 1)
// println("$row => ${obj_part.v[obj_part.v.len-1]}")
break
}
}
}
`f` {
//println("$c $row")
// println("$c $row")
obj_part.part[obj_part.part.len - 1].parse_faces(row, i, obj_part)
//println(obj_part.part[obj_part.part.len - 1].faces.len)
//println("Faces line: $c")
// println(obj_part.part[obj_part.part.len - 1].faces.len)
// println("Faces line: $c")
break
}
// end of the line, comments
`\n`,`#` {
`\n`, `#` {
break
}
else{}
else {}
}
i++
}
//if c == 2 { break }
if c % 100000 == 0 && c > 0{
println("$c rows parsed")
// if c == 2 { break }
if c % 100000 == 0 && c > 0 {
println('$c rows parsed')
}
}
println("$row_count .obj Rows parsed")
println('$row_count .obj Rows parsed')
// remove default part if empty
if obj_part.part.len > 1 && obj_part.part[0].faces.len == 0 {
obj_part.part = obj_part.part[1..]
@ -295,10 +303,10 @@ pub fn (mut obj_part ObjPart) parse_obj_buffer(rows []string, single_material bo
// load the materials if found the .mtl file
fn (mut obj_part ObjPart) load_materials() {
rows := obj.read_lines_from_file(obj_part.material_file)
println("Material file [${obj_part.material_file}] ${rows.len} Rows.")
rows := read_lines_from_file(obj_part.material_file)
println('Material file [$obj_part.material_file] $rows.len Rows.')
for row in rows {
//println("$row")
// println("$row")
mut i := 0
for true {
if i >= row.len {
@ -306,35 +314,37 @@ fn (mut obj_part ObjPart) load_materials() {
}
match row[i] {
`n` {
if row[i..i+6] == "newmtl" {
name := row[i+6..].trim_space()
mut mat := Material{name: name}
if row[i..i + 6] == 'newmtl' {
name := row[i + 6..].trim_space()
mut mat := Material{
name: name
}
obj_part.mat << mat
break
}
}
`K` {
if row[i+1] !in [`a`, `d`, `e`, `s`] {
if row[i + 1] !in [`a`, `d`, `e`, `s`] {
break
}
k_name := row[i..i+2]
k_name := row[i..i + 2]
i += 3
value := parse_3f(row, i)
obj_part.mat[obj_part.mat.len - 1].ks[k_name] = value
break
}
`N` {
n_name := row[i..i+2]
n_name := row[i..i + 2]
i += 3
value, _ := get_float(row, i)
obj_part.mat[obj_part.mat.len - 1].ns[n_name] = f32(value)
break
}
`m` {
if row[i..i+4] == "map_" {
name := row[i..i+6]
if row[i..i + 4] == 'map_' {
name := row[i..i + 6]
if (i + 7) < row.len {
file_name := row[i+7..].trim_space()
file_name := row[i + 7..].trim_space()
obj_part.mat[obj_part.mat.len - 1].maps[name] = file_name
}
break
@ -342,26 +352,26 @@ fn (mut obj_part ObjPart) load_materials() {
}
// trasparency
`d` {
if row[i+1] == ` ` {
value, _ := get_float(row, i+2)
if row[i + 1] == ` ` {
value, _ := get_float(row, i + 2)
obj_part.mat[obj_part.mat.len - 1].ns['Tr'] = f32(value)
}
}
`T` {
if row[i+1] == `r` {
value, _ := get_float(row, i+3)
if row[i + 1] == `r` {
value, _ := get_float(row, i + 3)
obj_part.mat[obj_part.mat.len - 1].ns['Tr'] = f32(1.0 - value)
}
}
// end of the line, comments
`\n`,`#` {
`\n`, `#` {
break
}
` `,`\t` {
` `, `\t` {
i++
continue
}
else{
else {
break
}
}
@ -376,7 +386,7 @@ fn (mut obj_part ObjPart) load_materials() {
}
}
println("Material Loading Done!")
println('Material Loading Done!')
}
//==============================================================================
@ -392,7 +402,7 @@ pub mut:
nx f32 // normal
ny f32
nz f32
color u32 = 0xFFFFFFFF // color
color u32 = 0xFFFFFFFF // color
u f32 // uv
v f32
// u u16 // for compatibility with D3D11
@ -402,27 +412,27 @@ pub mut:
// struct used to pass the data to the sokol calls
pub struct Skl_buffer {
pub mut:
vbuf []Vertex_pnct
ibuf []u32
vbuf []Vertex_pnct
ibuf []u32
n_vertex u32
}
// transforms data from .obj format to buffer ready to be used in the render
pub fn (mut obj_part ObjPart) get_buffer(in_part_list []int) Skl_buffer {
//in_part := 0
// in_part := 0
mut v_count_index := 0
mut out_buf := Skl_buffer{}
mut out_buf := Skl_buffer{}
mut cache := map[string]int
mut cache := map[string]int{}
mut cache_hit := 0
//has_normals := obj_part.vn.len > 0
//has_uvs := obj_part.vt.len > 0
// has_normals := obj_part.vn.len > 0
// has_uvs := obj_part.vt.len > 0
for in_part in in_part_list {
part := obj_part.part[in_part]
for fc, face in part.faces {
//println("$fc $face")
// println("$fc $face")
// default 3 faces
mut v_seq := [0, 1, 2]
if face.len == 4 {
@ -440,7 +450,7 @@ pub fn (mut obj_part ObjPart) get_buffer(in_part_list []int) Skl_buffer {
v_seq << (i + 1)
i++
}
//println("BIG FACES! ${fc} ${face.len} v_seq:${v_seq.len}")
// println("BIG FACES! ${fc} ${face.len} v_seq:${v_seq.len}")
}
// no vertex index, generate normals
@ -457,7 +467,7 @@ pub fn (mut obj_part ObjPart) get_buffer(in_part_list []int) Skl_buffer {
for v_count < face.len {
obj_part.vn << tmp_normal
obj_part.part[in_part].faces[fc][v_count][1] = obj_part.vn.len - 1
v_count ++
v_count++
}
}
@ -469,10 +479,10 @@ pub fn (mut obj_part ObjPart) get_buffer(in_part_list []int) Skl_buffer {
v_index := face[vertex_index][0] // vertex index
n_index := face[vertex_index][1] // normal index
t_index := face[vertex_index][2] // uv texture index
key := "${v_index}_${n_index}_${t_index}"
key := '${v_index}_${n_index}_$t_index'
if key !in cache {
cache[key] = v_count_index
mut pnct := Vertex_pnct {
mut pnct := Vertex_pnct{
x: obj_part.v[v_index].e[0]
y: obj_part.v[v_index].e[1]
z: obj_part.v[v_index].e[2]
@ -493,13 +503,11 @@ pub fn (mut obj_part ObjPart) get_buffer(in_part_list []int) Skl_buffer {
out_buf.ibuf << u32(v_count_index)
v_count_index++
} else {
//println("Cache used! $key")
// println("Cache used! $key")
out_buf.ibuf << u32(cache[key])
cache_hit++
}
}
}
}
@ -510,7 +518,7 @@ pub fn (mut obj_part ObjPart) get_buffer(in_part_list []int) Skl_buffer {
}
println(out_buf.ibuf[..10])
*/
//println("vbuf size: ${out_buf.vbuf.len} ibuf size: ${out_buf.ibuf.len} Cache hit: $cache_hit")
// println("vbuf size: ${out_buf.vbuf.len} ibuf size: ${out_buf.ibuf.len} Cache hit: $cache_hit")
out_buf.n_vertex = u32(out_buf.ibuf.len)
return out_buf
}
@ -520,36 +528,36 @@ pub fn (mut obj_part ObjPart) get_buffer(in_part_list []int) Skl_buffer {
//==============================================================================
// print on the console the summary of the .obj model loaded
pub fn (obj_part ObjPart) summary() {
println("---- Stats ----")
println("vertices: ${obj_part.v.len}")
println("normals : ${obj_part.vn.len}")
println("uv : ${obj_part.vt.len}")
println("parts : ${obj_part.part.len}")
println('---- Stats ----')
println('vertices: $obj_part.v.len')
println('normals : $obj_part.vn.len')
println('uv : $obj_part.vt.len')
println('parts : $obj_part.part.len')
// Parts
println("---- Parts ----")
println('---- Parts ----')
for c, x in obj_part.part {
println("${c:3} [${x.name:-16}] mat:[${x.material:-10}] ${x.faces.len:7} faces")
println('${c:3} [${x.name:-16}] mat:[${x.material:-10}] ${x.faces.len:7} faces')
}
// Materials
println("---- Materials ----")
println("Material dict: ${obj_part.mat_map.keys()}")
println('---- Materials ----')
println('Material dict: $obj_part.mat_map.keys()')
for c, mat in obj_part.mat {
println("${c:3} [${mat.name:-16}]")
for k,v in mat.ks {
print("$k = $v")
println('${c:3} [${mat.name:-16}]')
for k, v in mat.ks {
print('$k = $v')
}
for k,v in mat.ns {
println("$k = $v")
for k, v in mat.ns {
println('$k = $v')
}
for k,v in mat.maps {
println("$k = $v")
for k, v in mat.maps {
println('$k = $v')
}
}
}
// debug test function, do not remove.
pub fn tst(){
/*
pub fn tst() {
/*
//fname := "capsule.obj"
//fname := "Forklift.obj"
fname := "cube.obj"
@ -559,8 +567,8 @@ pub fn tst(){
buf := os.read_lines(fname) or { panic(err.msg) }
obj.parse_obj_buffer(buf)
obj.summary()
*/
/*
*/
/*
a :="f 7048 7070 7071 7072 7073 7074 7075 7076 7077 7078 7079 7080 7003"
mut f1 := 0
mut f2 := 0
@ -568,20 +576,20 @@ pub fn tst(){
f1, p = get_int(a,p)
f2, p = get_int(a,p)
println("res: ${f0} ${f1} ${f2}")
*/
/*
*/
/*
a :="v -0 0.107769 -0.755914"
println("${parse_3f(a,1)}")
*/
/*
*/
/*
ort := m4.ortho(0,300,0,200,0,0)
println(ort)
a := m4.vec3(0,0,0)
println("a: $a")
res := m4.mul_vec(ort, a)
println("res:\n${res}")
*/
s := "K 1 1 1"
r := strconv.atof_quick(s[1..s.len-1])
*/
s := 'K 1 1 1'
r := strconv.atof_quick(s[1..s.len - 1])
println(r)
}

View File

@ -9,6 +9,7 @@
* TODO:
**********************************************************************/
module obj
import sokol.gfx
import gg.m4
import math
@ -46,10 +47,10 @@ pub fn destroy_texture(sg_img C.sg_image) {
}
pub fn load_texture(file_name string) C.sg_image {
buffer := obj.read_bytes_from_file(file_name)
buffer := read_bytes_from_file(file_name)
stbi.set_flip_vertically_on_load(true)
img := stbi.load_from_memory(buffer.data, buffer.len) or {
eprintln("Texure file: [$file_name] ERROR!")
eprintln('Texure file: [$file_name] ERROR!')
exit(0)
}
res := create_texture(int(img.width), int(img.height), img.data)
@ -82,7 +83,7 @@ pub fn (mut obj_part ObjPart) create_pipeline(in_part []int, shader C.sg_shader,
// index buffer
mut index_buffer_desc := C.sg_buffer_desc{}
unsafe {C.memset(&index_buffer_desc, 0, sizeof(index_buffer_desc))}
unsafe { C.memset(&index_buffer_desc, 0, sizeof(index_buffer_desc)) }
index_buffer_desc.size = size_t(obj_buf.ibuf.len * int(sizeof(u32)))
index_buffer_desc.data = C.sg_range{
@ -90,8 +91,8 @@ pub fn (mut obj_part ObjPart) create_pipeline(in_part []int, shader C.sg_shader,
size: size_t(obj_buf.ibuf.len * int(sizeof(u32)))
}
index_buffer_desc.@type = .indexbuffer
index_buffer_desc.label = "indbuf_part_${in_part:03}".str
index_buffer_desc.@type = .indexbuffer
index_buffer_desc.label = 'indbuf_part_${in_part:03}'.str
ibuf := gfx.make_buffer(&index_buffer_desc)
mut pipdesc := C.sg_pipeline_desc{}
@ -99,10 +100,10 @@ pub fn (mut obj_part ObjPart) create_pipeline(in_part []int, shader C.sg_shader,
pipdesc.layout.buffers[0].stride = int(sizeof(Vertex_pnct))
// the constants [C.ATTR_vs_a_Position, C.ATTR_vs_a_Color, C.ATTR_vs_a_Texcoord0] are generated by sokol-shdc
pipdesc.layout.attrs[C.ATTR_vs_a_Position].format = .float3 // x,y,z as f32
pipdesc.layout.attrs[C.ATTR_vs_a_Normal ].format = .float3 // x,y,z as f32
pipdesc.layout.attrs[C.ATTR_vs_a_Color ].format = .ubyte4n // color as u32
pipdesc.layout.attrs[C.ATTR_vs_a_Texcoord0 ].format = .float2 // u,v as f32
pipdesc.layout.attrs[C.ATTR_vs_a_Position].format = .float3 // x,y,z as f32
pipdesc.layout.attrs[C.ATTR_vs_a_Normal].format = .float3 // x,y,z as f32
pipdesc.layout.attrs[C.ATTR_vs_a_Color].format = .ubyte4n // color as u32
pipdesc.layout.attrs[C.ATTR_vs_a_Texcoord0].format = .float2 // u,v as f32
// pipdesc.layout.attrs[C.ATTR_vs_a_Texcoord0].format = .short2n // u,v as u16
pipdesc.index_type = .uint32
@ -130,7 +131,7 @@ pub fn (mut obj_part ObjPart) create_pipeline(in_part []int, shader C.sg_shader,
res.bind.index_buffer = ibuf
res.bind.fs_images[C.SLOT_tex] = texture
res.pipeline = gfx.make_pipeline(&pipdesc)
//println('Buffers part [$in_part] init done!')
// println('Buffers part [$in_part] init done!')
return res
}
@ -151,10 +152,10 @@ pub fn (mut obj_part ObjPart) init_render_data(texture C.sg_image) {
}
}
obj_part.rend_data.clear()
//println("Material dict: ${obj_part.mat_map.keys()}")
// println("Material dict: ${obj_part.mat_map.keys()}")
for k, v in part_dict {
//println("$k => Parts $v")
// println("$k => Parts $v")
mut txt := texture
@ -164,22 +165,22 @@ pub fn (mut obj_part ObjPart) init_render_data(texture C.sg_image) {
file_name := mat_map.maps['map_Kd']
if file_name in obj_part.texture {
txt = obj_part.texture[file_name]
//println("Texture [${file_name}] => from CACHE")
// println("Texture [${file_name}] => from CACHE")
} else {
txt = obj.load_texture(file_name)
txt = load_texture(file_name)
obj_part.texture[file_name] = txt
//println("Texture [${file_name}] => LOADED")
// println("Texture [${file_name}] => LOADED")
}
}
}
//key := obj_part.texture.keys()[0]
//obj_part.rend_data << obj_part.create_pipeline(v, shader, obj_part.texture[key])
// key := obj_part.texture.keys()[0]
// obj_part.rend_data << obj_part.create_pipeline(v, shader, obj_part.texture[key])
obj_part.rend_data << obj_part.create_pipeline(v, shader, txt)
}
//println("Texture array len: ${obj_part.texture.len}")
//println("Calc bounding box.")
// println("Texture array len: ${obj_part.texture.len}")
// println("Calc bounding box.")
obj_part.calc_bbox()
println("init_render_data DONE!")
println('init_render_data DONE!')
}
pub fn (obj_part ObjPart) bind_and_draw(rend_data_index int, in_data Shader_data) u32 {
@ -187,7 +188,7 @@ pub fn (obj_part ObjPart) bind_and_draw(rend_data_index int, in_data Shader_data
mut part_render_data := obj_part.rend_data[rend_data_index]
// pass light position
mut tmp_fs_params := obj.Tmp_fs_param{}
mut tmp_fs_params := Tmp_fs_param{}
tmp_fs_params.ligth = in_data.fs_data.ligth
if part_render_data.material in obj_part.mat_map {
@ -246,27 +247,47 @@ pub fn (obj_part ObjPart) bind_and_draw(rend_data_index int, in_data Shader_data
pub fn (obj_part ObjPart) bind_and_draw_all(in_data Shader_data) u32 {
mut n_vert := u32(0)
//println("Parts: ${obj_part.rend_data.len}")
// println("Parts: ${obj_part.rend_data.len}")
for i, _ in obj_part.rend_data {
n_vert += obj_part.bind_and_draw(i,in_data)
n_vert += obj_part.bind_and_draw(i, in_data)
}
return n_vert
}
pub fn (mut obj_part ObjPart) calc_bbox() {
obj_part.max = m4.Vec4{e:[f32(-math.max_f32), -math.max_f32, -math.max_f32, 0]!}
obj_part.min = m4.Vec4{e:[f32( math.max_f32), math.max_f32, math.max_f32, 0]!}
obj_part.max = m4.Vec4{
e: [f32(-math.max_f32), -math.max_f32, -math.max_f32, 0]!
}
obj_part.min = m4.Vec4{
e: [f32(math.max_f32), math.max_f32, math.max_f32, 0]!
}
for v in obj_part.v {
if v.e[0] > obj_part.max.e[0] { obj_part.max.e[0] = v.e[0] }
if v.e[1] > obj_part.max.e[1] { obj_part.max.e[1] = v.e[1] }
if v.e[2] > obj_part.max.e[2] { obj_part.max.e[2] = v.e[2] }
if v.e[0] > obj_part.max.e[0] {
obj_part.max.e[0] = v.e[0]
}
if v.e[1] > obj_part.max.e[1] {
obj_part.max.e[1] = v.e[1]
}
if v.e[2] > obj_part.max.e[2] {
obj_part.max.e[2] = v.e[2]
}
if v.e[0] < obj_part.min.e[0] { obj_part.min.e[0] = v.e[0] }
if v.e[1] < obj_part.min.e[1] { obj_part.min.e[1] = v.e[1] }
if v.e[2] < obj_part.min.e[2] { obj_part.min.e[2] = v.e[2] }
if v.e[0] < obj_part.min.e[0] {
obj_part.min.e[0] = v.e[0]
}
if v.e[1] < obj_part.min.e[1] {
obj_part.min.e[1] = v.e[1]
}
if v.e[2] < obj_part.min.e[2] {
obj_part.min.e[2] = v.e[2]
}
}
val1 := obj_part.max.mod3()
val2 := obj_part.min.mod3()
if val1 > val2 { obj_part.radius = f32(val1) } else { obj_part.radius = f32(val2) }
//println("BBox: ${obj_part.min} <=> ${obj_part.max}\nRadius: ${obj_part.radius}")
if val1 > val2 {
obj_part.radius = f32(val1)
} else {
obj_part.radius = f32(val2)
}
// println("BBox: ${obj_part.min} <=> ${obj_part.max}\nRadius: ${obj_part.radius}")
}

View File

@ -9,27 +9,28 @@
* TODO:
**********************************************************************/
module obj
import gg.m4
// part struct mantain the fae indexes list
pub struct Part {
pub mut:
faces [][][3]int // v n t index order, if -1 not available
name string
material string
faces [][][3]int // v n t index order, if -1 not available
name string
material string
}
// materias struct, all Ks and Ns are stored as maps of string
pub struct Material {
pub mut:
name string
ks map[string]m4.Vec4
ns map[string]f32
maps map[string]string
name string
ks map[string]m4.Vec4
ns map[string]f32
maps map[string]string
}
// render data used for the rendering
pub struct Render_data{
pub struct Render_data {
pub mut:
pipeline C.sg_pipeline
bind C.sg_bindings
@ -40,41 +41,40 @@ pub mut:
// base object parts struct
pub struct ObjPart {
pub mut:
v []m4.Vec4 // position
vn []m4.Vec4 // normals
vp []m4.Vec4 // vertex params
vt []m4.Vec4 // textures
v []m4.Vec4 // position
vn []m4.Vec4 // normals
vp []m4.Vec4 // vertex params
vt []m4.Vec4 // textures
name string
part []Part // parts of the ObjPart
mat []Material // list of the materials of the ObjPart
mat_map map[string]int // maping material name to its material index
texture map[string]C.sg_image // GPU loaded texture map
material_file string // .mtl file name for the .obj
name string
part []Part // parts of the ObjPart
mat []Material // list of the materials of the ObjPart
mat_map map[string]int // maping material name to its material index
texture map[string]C.sg_image // GPU loaded texture map
material_file string // .mtl file name for the .obj
rend_data []Render_data // render data used for the rendering
t_m m4.Mat4 = m4.unit_m4() // transform matrix for this ObjPart
//child []ObjPart // childs
rend_data []Render_data // render data used for the rendering
t_m m4.Mat4 = m4.unit_m4() // transform matrix for this ObjPart
// child []ObjPart // childs
// stats
min m4.Vec4 // min 3d position in the ObjPart
max m4.Vec4 // max 3d position in the ObjPart
radius f32 // bounding circle radius of the ObjPart
min m4.Vec4 // min 3d position in the ObjPart
max m4.Vec4 // max 3d position in the ObjPart
radius f32 // bounding circle radius of the ObjPart
}
// used in to pass the matrices to the shader
pub struct Mats {
pub mut:
mv m4.Mat4
mvp m4.Mat4
nm m4.Mat4
mv m4.Mat4
mvp m4.Mat4
nm m4.Mat4
}
// data passed to the vertex shader
pub struct Tmp_vs_param {
pub mut:
mv m4.Mat4
mv m4.Mat4
mvp m4.Mat4
nm m4.Mat4
}
@ -83,9 +83,15 @@ pub mut:
pub struct Tmp_fs_param {
pub mut:
ligth m4.Vec4
ka m4.Vec4 = m4.Vec4{e:[f32(0.1), 0.0, 0.0, 1.0]!}
kd m4.Vec4 = m4.Vec4{e:[f32(0.5), 0.5, 0.5, 1.0]!}
ks m4.Vec4 = m4.Vec4{e:[f32(1.0), 1.0, 1.0, 1.0]!}
ka m4.Vec4 = m4.Vec4{
e: [f32(0.1), 0.0, 0.0, 1.0]!
}
kd m4.Vec4 = m4.Vec4{
e: [f32(0.5), 0.5, 0.5, 1.0]!
}
ks m4.Vec4 = m4.Vec4{
e: [f32(1.0), 1.0, 1.0, 1.0]!
}
}
// shader data for the rendering

View File

@ -1,21 +1,22 @@
module obj
import os
// read a file as single lines
pub fn read_lines_from_file(file_path string) []string {
mut path := ""
mut path := ''
mut rows := []string{}
$if android {
path = "models/"+file_path
path = 'models/' + file_path
bts := os.read_apk_asset(path) or {
eprintln("File [$path] NOT FOUND!")
eprintln('File [$path] NOT FOUND!')
return rows
}
rows = bts.bytestr().split_into_lines()
} $else {
path = "assets/models/"+file_path
path = 'assets/models/' + file_path
rows = os.read_lines(path) or {
eprintln("File [$path] NOT FOUND!")
eprintln('File [$path] NOT FOUND!')
return rows
}
}
@ -24,18 +25,18 @@ pub fn read_lines_from_file(file_path string) []string {
// read a file as []byte
pub fn read_bytes_from_file(file_path string) []byte {
mut path := ""
mut path := ''
mut buffer := []byte{}
$if android {
path = "models/"+file_path
path = 'models/' + file_path
buffer = os.read_apk_asset(path) or {
eprintln("Texure file: [$path] NOT FOUND!")
eprintln('Texure file: [$path] NOT FOUND!')
exit(0)
}
} $else {
path = "assets/models/"+file_path
path = 'assets/models/' + file_path
buffer = os.read_bytes(path) or {
eprintln("Texure file: [$path] NOT FOUND!")
eprintln('Texure file: [$path] NOT FOUND!')
exit(0)
}
}

View File

@ -44,7 +44,6 @@ import sokol.sapp
import sokol.gfx
import sokol.sgl
import time
import os
import obj
@ -52,6 +51,7 @@ import obj
#flag -I @VMODROOT/.
#include "gouraud.h" #Please use sokol-shdc to generate the necessary rt_glsl.h file from rt_glsl.glsl (see the instructions at the top of this file)
fn C.gouraud_shader_desc(gfx.Backend) &C.sg_shader_desc
const (
@ -67,19 +67,16 @@ mut:
init_flag bool
frame_count int
mouse_x int = -1
mouse_y int = -1
scroll_y int //mouse wheel value
mouse_x int = -1
mouse_y int = -1
scroll_y int // mouse wheel value
// time
ticks i64
ticks i64
// model
obj_part &obj.ObjPart
n_vertex u32
obj_part &obj.ObjPart
n_vertex u32
// init parameters
file_name string
file_name string
single_material_flag bool
}
@ -88,12 +85,15 @@ mut:
******************************************************************************/
[inline]
fn vec4(x f32, y f32, z f32, w f32) m4.Vec4 {
return m4.Vec4{e:[x, y, z, w]!}
return m4.Vec4{
e: [x, y, z, w]!
}
}
fn calc_matrices(w f32, h f32, rx f32, ry f32, in_scale f32, pos m4.Vec4) obj.Mats {
proj := m4.perspective(60, w/h, 0.01, 100.0) // set far plane to 100 fro the zoom function
view := m4.look_at(vec4(f32(0.0) ,0 , 6, 0), vec4(f32(0), 0, 0, 0), vec4(f32(0), 1, 0, 0))
proj := m4.perspective(60, w / h, 0.01, 100.0) // set far plane to 100 fro the zoom function
view := m4.look_at(vec4(f32(0.0), 0, 6, 0), vec4(f32(0), 0, 0, 0), vec4(f32(0), 1,
0, 0))
view_proj := view * proj
rxm := m4.rotate(m4.rad(rx), vec4(f32(1), 0, 0, 0))
@ -101,14 +101,18 @@ fn calc_matrices(w f32, h f32, rx f32, ry f32, in_scale f32, pos m4.Vec4) obj.Ma
model_pos := m4.unit_m4().translate(pos)
model_m := (rym * rxm) * model_pos
model_m := (rym * rxm) * model_pos
scale_m := m4.scale(vec4(in_scale, in_scale, in_scale, 1))
mv := scale_m * model_m // model view
mv := scale_m * model_m // model view
nm := mv.inverse().transpose() // normal matrix
mvp := mv * view_proj // model view projection
mvp := mv * view_proj // model view projection
return obj.Mats{mv:mv, mvp:mvp, nm:nm}
return obj.Mats{
mv: mv
mvp: mvp
nm: nm
}
}
fn draw_model(app App, model_pos m4.Vec4) u32 {
@ -117,12 +121,12 @@ fn draw_model(app App, model_pos m4.Vec4) u32 {
}
ws := gg.window_size_real_pixels()
dw := ws.width/2
dh := ws.height/2
dw := ws.width / 2
dh := ws.height / 2
mut scale := f32(1)
if app.obj_part.radius > 1 {
scale = 1/(app.obj_part.radius)
scale = 1 / (app.obj_part.radius)
} else {
scale = app.obj_part.radius
}
@ -130,29 +134,29 @@ fn draw_model(app App, model_pos m4.Vec4) u32 {
// *** vertex shader uniforms ***
rot := [f32(app.mouse_y), f32(app.mouse_x)]
mut zoom_scale := scale + f32(app.scroll_y) / (app.obj_part.radius*4)
mats := calc_matrices(dw, dh, rot[0], rot[1] , zoom_scale, model_pos)
mut zoom_scale := scale + f32(app.scroll_y) / (app.obj_part.radius * 4)
mats := calc_matrices(dw, dh, rot[0], rot[1], zoom_scale, model_pos)
mut tmp_vs_param := obj.Tmp_vs_param{
mv: mats.mv,
mvp: mats.mvp,
nm: mats.nm
mv: mats.mv
mvp: mats.mvp
nm: mats.nm
}
// *** fragment shader uniforms ***
time_ticks := f32(time.ticks() - app.ticks) / 1000
radius_light := f32(app.obj_part.radius)
x_light := f32(math.cos(time_ticks) * radius_light)
z_light := f32(math.sin(time_ticks) * radius_light)
radius_light := f32(app.obj_part.radius)
x_light := f32(math.cos(time_ticks) * radius_light)
z_light := f32(math.sin(time_ticks) * radius_light)
mut tmp_fs_params := obj.Tmp_fs_param{}
tmp_fs_params.ligth = m4.vec3(x_light, radius_light, z_light)
sd := obj.Shader_data{
vs_data: &tmp_vs_param
vs_len: int(sizeof(tmp_vs_param))
vs_len: int(sizeof(tmp_vs_param))
fs_data: &tmp_fs_params
fs_len: int(sizeof(tmp_fs_params))
fs_len: int(sizeof(tmp_fs_params))
}
return app.obj_part.bind_and_draw_all(sd)
@ -179,8 +183,8 @@ fn frame(mut app App) {
// render the data
draw_start_glsl(app)
draw_model(app, m4.Vec4{})
// uncoment if you want a raw benchmark mode
/*
// uncoment if you want a raw benchmark mode
/*
mut n_vertex_drawn := u32(0)
n_x_obj := 20
@ -191,14 +195,14 @@ fn frame(mut app App) {
}
}
}
*/
*/
draw_end_glsl(app)
//println("v:$n_vertex_drawn")
// println("v:$n_vertex_drawn")
app.frame_count++
}
fn draw_start_glsl(app App){
fn draw_start_glsl(app App) {
if app.init_flag == false {
return
}
@ -206,7 +210,7 @@ fn draw_start_glsl(app App){
gfx.apply_viewport(0, 0, ws.width, ws.height, true)
}
fn draw_end_glsl(app App){
fn draw_end_glsl(app App) {
gfx.end_pass()
gfx.commit()
}
@ -240,7 +244,6 @@ fn my_init(mut app App) {
app.texture = obj.create_texture(1, 1, tmp_txt)
free(tmp_txt)
}
// glsl
app.obj_part.init_render_data(app.texture)
app.init_flag = true
@ -248,11 +251,11 @@ fn my_init(mut app App) {
fn cleanup(mut app App) {
gfx.shutdown()
/*
/*
for _, mat in app.obj_part.texture {
obj.destroy_texture(mat)
}
*/
*/
}
/******************************************************************************
@ -280,20 +283,21 @@ fn my_event_manager(mut ev gg.Event, mut app App) {
/******************************************************************************
* Main
******************************************************************************/
[console] // is needed for easier diagnostics on windows
// is needed for easier diagnostics on windows
[console]
fn main() {
/*
/*
obj.tst()
exit(0)
*/
*/
// App init
mut app := &App{
gg: 0
gg: 0
obj_part: 0
}
app.file_name = "v.obj_" // default object is the v logo
app.file_name = 'v.obj_' // default object is the v logo
app.single_material_flag = false
$if !android {
@ -302,7 +306,7 @@ fn main() {
eprintln('file_name : name of the .obj file, it must be in the folder "assets/models"')
eprintln(' if no file name is passed the default V logo will be showed.')
eprintln(' if you want custom models you can put them in the folder "assets/models".')
eprintln('single_material_flag: if true the viewer use for all the model\'s parts the default material\n')
eprintln("single_material_flag: if true the viewer use for all the model's parts the default material\n")
exit(0)
}
@ -312,8 +316,8 @@ fn main() {
if os.args.len >= 3 {
app.single_material_flag = os.args[2].bool()
}
println("Loading model: $app.file_name")
println("Using single material: $app.single_material_flag")
println('Loading model: $app.file_name')
println('Using single material: $app.single_material_flag')
}
app.gg = gg.new_context(

View File

@ -48,7 +48,8 @@ fn init(mut state AppState) {
// or use DroidSerif-Regular.ttf
if bytes := os.read_bytes(os.resource_abs_path('../assets/fonts/RobotoMono-Regular.ttf')) {
println('loaded font: $bytes.len')
state.font_normal = C.fonsAddFontMem(state.fons, 'sans', bytes.data, bytes.len, false)
state.font_normal = C.fonsAddFontMem(state.fons, 'sans', bytes.data, bytes.len,
false)
}
}
@ -101,7 +102,8 @@ fn (state &AppState) render_font() {
C.fonsSetSize(state.fons, 20.0)
C.fonsSetFont(state.fons, state.font_normal)
C.fonsSetColor(state.fons, blue)
C.fonsDrawText(state.fons, dx, dy, c'Now is the time for all good men to come to the aid of the party.', C.NULL)
C.fonsDrawText(state.fons, dx, dy, c'Now is the time for all good men to come to the aid of the party.',
C.NULL)
dx = 300
dy = 350
C.fonsSetAlign(state.fons, C.FONS_ALIGN_LEFT | C.FONS_ALIGN_BASELINE)

View File

@ -6,9 +6,8 @@ import sokol.sfons
import os
import time
const (
text = '
text = '
Once upon a midnight dreary, while I pondered, weak and weary,
Over many a quaint and curious volume of forgotten lore
While I nodded, nearly napping, suddenly there came a tapping,
@ -51,7 +50,7 @@ Soon again I heard a tapping somewhat louder than before.
Let my heart be still a moment and this mystery explore;
Tis the wind and nothing more!
'
lines = text.split('\n')
lines = text.split('\n')
)
struct AppState {
@ -59,7 +58,7 @@ mut:
pass_action C.sg_pass_action
fons &C.FONScontext
font_normal int
inited bool
inited bool
}
fn main() {
@ -102,7 +101,8 @@ fn init(user_data voidptr) {
// or use DroidSerif-Regular.ttf
if bytes := os.read_bytes(os.resource_abs_path('../assets/fonts/RobotoMono-Regular.ttf')) {
println('loaded font: $bytes.len')
state.font_normal = C.fonsAddFontMem(state.fons, 'sans', bytes.data, bytes.len, false)
state.font_normal = C.fonsAddFontMem(state.fons, 'sans', bytes.data, bytes.len,
false)
}
}
@ -114,12 +114,11 @@ fn frame(user_data voidptr) {
sgl.draw()
gfx.end_pass()
gfx.commit()
println(time.ticks()-t)
println(time.ticks() - t)
}
const (
black = C.sfons_rgba(0, 0, 0, 255)
black = C.sfons_rgba(0, 0, 0, 255)
)
fn (mut state AppState) render_font() {

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by an MIT license file distributed with this software package
module particle
import vec2
import particle.vec2
import sokol.sgl
const (
@ -16,9 +16,9 @@ pub fn new(location vec2.Vec2) &Particle {
location: location
velocity: vec2.Vec2{0, 0}
acceleration: vec2.Vec2{0, 0}
color: default_v_color
life_time: default_life_time
life_time_init: default_life_time
color: particle.default_v_color
life_time: particle.default_life_time
life_time_init: particle.default_life_time
}
return p
}
@ -75,7 +75,7 @@ pub fn (mut p Particle) reset() {
p.acceleration.zero()
p.velocity.zero()
// p.color = Color{93, 136, 193, 255}
p.color = default_v_color
p.life_time = default_life_time
p.color = particle.default_v_color
p.life_time = particle.default_life_time
p.life_time_init = p.life_time
}

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by an MIT license file distributed with this software package
module particle
import vec2
import particle.vec2
import rand
import sokol.sgl
@ -14,8 +14,8 @@ pub struct System {
width int
height int
mut:
pool []&Particle
bin []&Particle
pool []&Particle
bin []&Particle
}
pub fn (mut s System) init(sc SystemConfig) {
@ -82,7 +82,7 @@ pub fn (mut s System) free() {
print(ptr_str(p) + ' ouch')
continue
}
unsafe {free(p)}
unsafe { free(p) }
}
s.pool.clear()
for p in s.bin {

View File

@ -20,7 +20,7 @@ pub fn (mut v Vec2) from(src Vec2) {
// * Addition
// + operator overload. Adds two vectors
pub fn (v1 Vec2) +(v2 Vec2) Vec2 {
pub fn (v1 Vec2) + (v2 Vec2) Vec2 {
return Vec2{v1.x + v2.x, v1.y + v2.y}
}
@ -43,7 +43,7 @@ pub fn (mut v Vec2) plus_f64(scalar f64) {
}
// * Subtraction
pub fn (v1 Vec2) -(v2 Vec2) Vec2 {
pub fn (v1 Vec2) - (v2 Vec2) Vec2 {
return Vec2{v1.x - v2.x, v1.y - v2.y}
}
@ -66,7 +66,7 @@ pub fn (mut v Vec2) subtract_f64(scalar f64) {
}
// * Multiplication
pub fn (v1 Vec2) *(v2 Vec2) Vec2 {
pub fn (v1 Vec2) * (v2 Vec2) Vec2 {
return Vec2{v1.x * v2.x, v1.y * v2.y}
}

View File

@ -26,12 +26,12 @@ fn main() {
struct App {
pass_action C.sg_pass_action
mut:
width int
height int
frame i64
last i64
ps particle.System
alpha_pip C.sgl_pipeline
width int
height int
frame i64
last i64
ps particle.System
alpha_pip C.sgl_pipeline
}
fn (mut a App) init() {
@ -80,7 +80,7 @@ fn init(user_data voidptr) {
}
sgl.setup(&sgl_desc)
mut pipdesc := C.sg_pipeline_desc{}
unsafe {C.memset(&pipdesc, 0, sizeof(pipdesc))}
unsafe { C.memset(&pipdesc, 0, sizeof(pipdesc)) }
color_state := C.sg_color_state{
blend: C.sg_blend_state{

View File

@ -117,13 +117,12 @@ struct RIFFFormat {
}
fn read_wav_file_samples(fpath string) ?[]f32 {
mut res := []f32{}
// eprintln('> read_wav_file_samples: $fpath -------------------------------------------------')
mut bytes := os.read_bytes(fpath) ?
mut pbytes := &byte(bytes.data)
mut offset := u32(0)
rh := unsafe{ &RIFFHeader(pbytes) }
rh := unsafe { &RIFFHeader(pbytes) }
// eprintln('rh: $rh')
if rh.riff != [byte(`R`), `I`, `F`, `F`]! {
return error('WAV should start with `RIFF`')
@ -141,7 +140,7 @@ fn read_wav_file_samples(fpath string) ?[]f32 {
break
}
//
ch := unsafe{ &RIFFChunkHeader(pbytes + offset) }
ch := unsafe { &RIFFChunkHeader(pbytes + offset) }
offset += 8 + ch.chunk_size
// eprintln('ch: $ch')
// eprintln('p: $pbytes | offset: $offset | bytes.len: $bytes.len')
@ -176,20 +175,20 @@ fn read_wav_file_samples(fpath string) ?[]f32 {
}
// eprintln('`fmt ` chunk: $rf\n`data` chunk: $ch')
mut doffset := 0
mut dp := unsafe{ &byte(&ch.chunk_data) }
mut dp := unsafe { &byte(&ch.chunk_data) }
for doffset < ch.chunk_size {
for c := 0; c < rf.nchannels; c++ {
mut x := f32(0.0)
mut step := 0
ppos := unsafe { dp + doffset }
if rf.bits_per_sample == 8 {
d8 := unsafe{ &byte(ppos) }
d8 := unsafe { &byte(ppos) }
x = (f32(*d8) - 128) / 128.0
step = 1
doffset++
}
if rf.bits_per_sample == 16 {
d16 := unsafe{ &i16(ppos) }
d16 := unsafe { &i16(ppos) }
x = f32(*d16) / 32768.0
step = 2
}
@ -207,5 +206,4 @@ fn read_wav_file_samples(fpath string) ?[]f32 {
}
}
return res
}

View File

@ -71,7 +71,9 @@ fn data_get() []SiteConfig {
cat: .web
alias: 'marketplace'
path_code: '/Users/despiegk/codewww/github/threefoldfoundation/www_threefold_marketplace'
domains: ['now.threefold.io', 'marketplace.threefold.io', 'now.threefold.me', 'marketplace.threefold.me']
domains: ['now.threefold.io', 'marketplace.threefold.io', 'now.threefold.me',
'marketplace.threefold.me',
]
descr: 'apps for community builders, runs on top of evdc'
}, SiteConfig{
name: 'www_conscious_internet'
@ -81,9 +83,8 @@ fn data_get() []SiteConfig {
cat: .web
alias: 'conscious_internet'
path_code: '/Users/despiegk/codewww/github/threefoldfoundation/www_conscious_internet'
domains: ['www.consciousinternet.org', 'eco.threefold.io', 'community.threefold.io', 'eco.threefold.me',
'community.threefold.me',
]
domains: ['www.consciousinternet.org', 'eco.threefold.io', 'community.threefold.io',
'eco.threefold.me', 'community.threefold.me']
descr: 'community around threefold, partners, friends, ...'
}, SiteConfig{
name: 'www_threefold_tech'

View File

@ -300,7 +300,7 @@ fn (mut b Buffer) free() {
eprintln(@MOD + '.' + @STRUCT + '::' + @FN)
}
for line in b.lines {
unsafe {line.free()}
unsafe { line.free() }
}
unsafe { b.lines.free() }
}
@ -374,12 +374,12 @@ fn (mut b Buffer) move_to_word(movement Movement) {
}
// first, move past all non-`a-zA-Z0-9_` characters
for x + a >= 0 && x + a < line.len && !(line[x + a].is_letter()
|| line[x + a].is_digit()|| line[x + a] == `_`) {
|| line[x + a].is_digit() || line[x + a] == `_`) {
x += a
}
// then, move past all the letters and numbers
for x + a >= 0 && x + a < line.len && (line[x + a].is_letter()
|| line[x + a].is_digit()|| line[x + a] == `_`) {
|| line[x + a].is_digit() || line[x + a] == `_`) {
x += a
}
// if the cursor is out of bounds, move it to the next/previous line
@ -393,19 +393,11 @@ fn (mut b Buffer) move_to_word(movement Movement) {
}
fn imax(x int, y int) int {
return if x < y {
y
} else {
x
}
return if x < y { y } else { x }
}
fn imin(x int, y int) int {
return if x < y {
x
} else {
y
}
return if x < y { x } else { y }
}
struct Cursor {

View File

@ -396,7 +396,7 @@ fn (a App) check_capture() bool {
snake_pos := a.snake.get_head().pos
rat_pos := a.rat.pos
return snake_pos.x <= rat_pos.x + block_size && snake_pos.x + block_size >= rat_pos.x
&& snake_pos.y <= rat_pos.y + block_size&& snake_pos.y + block_size >= rat_pos.y
&& snake_pos.y <= rat_pos.y + block_size && snake_pos.y + block_size >= rat_pos.y
}
fn (mut a App) draw_snake() {

5
examples/v_script.vsh 100755 → 100644
View File

@ -1,9 +1,10 @@
#!/usr/local/bin/v run
// The shebang above associates the file to V on Unix-like systems,
// so it can be run just by specifying the path to the file
// once it's made executable using `chmod +x`.
for _ in 0..3 {
for _ in 0 .. 3 {
println('V script')
}
@ -16,7 +17,7 @@ files := ls('.') or { panic(err.msg) }
println(files)
println('\nCreating foo.txt')
create('foo.txt')?
create('foo.txt') ?
println('\nFiles:')
again_ls := ls('.') or { panic(err.msg) }

View File

@ -18,15 +18,14 @@ pub fn (mut app App) index() vweb.Result {
return $vweb.html()
}
[post]
['/upload']
['/upload'; post]
pub fn (mut app App) upload() vweb.Result {
fdata := app.files['upfile']
mut files := []vweb.RawHtml{}
for d in fdata {
files << d.data.replace_each(['\n', '<br>', '\n\r', '<br>' '\t', ' ', ' ', '&nbsp;'])
files << d.data.replace_each(['\n', '<br>', '\n\r', '<br>', '\t', ' ', ' ', '&nbsp;'])
}
return $vweb.html()

View File

@ -1,7 +1,7 @@
module main
import vweb
//import vweb.assets
// import vweb.assets
import time
const (

View File

@ -1,7 +1,6 @@
// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.
import os
fn main() {
@ -9,15 +8,14 @@ fn main() {
if os.args.len != 2 {
println('usage: word_counter [text_file]')
println('using $path')
}
else {
} else {
path = os.args[1]
}
contents := os.read_file(path.trim_space()) or {
println('failed to open $path')
return
}
mut m := map[string]int
mut m := map[string]int{}
for word in extract_words(contents) {
m[word]++
}
@ -37,8 +35,7 @@ fn extract_words(contents string) []string {
for space_splitted in contents.to_lower().split(' ') {
if space_splitted.contains('\n') {
splitted << space_splitted.split('\n')
}
else {
} else {
splitted << space_splitted
}
}

View File

@ -1,21 +1,20 @@
//fn println(s string) { }
// fn println(s string) { }
//fn test_fn() {
//println('test fn')
// fn test_fn() {
// println('test fn')
//}
fn main() {
println('x64 test')
//i := 0
//for i < 5 {
for _ in 1..5 {
// i := 0
// for i < 5 {
for _ in 1 .. 5 {
println('Hello world from V x64 machine code generator!')
//i++
// i++
}
/*
/*
println('Hello again!')
//test_fn()
println('done')
*/
}