| 1 | module sim |
| 2 | |
| 3 | import benchmark |
| 4 | import term |
| 5 | |
| 6 | pub type SimRequestHandler = fn (request &SimRequest) ! |
| 7 | |
| 8 | pub type SimStartHandler = fn () ! |
| 9 | |
| 10 | pub type SimFinishHandler = fn () ! |
| 11 | |
| 12 | pub const default_width = 600 |
| 13 | pub const default_height = 600 |
| 14 | |
| 15 | @[params] |
| 16 | pub struct GridSettings { |
| 17 | pub: |
| 18 | width int = default_width |
| 19 | height int = default_height |
| 20 | } |
| 21 | |
| 22 | pub fn new_grid_settings(settings GridSettings) GridSettings { |
| 23 | return GridSettings{ |
| 24 | ...settings |
| 25 | } |
| 26 | } |
| 27 | |
| 28 | @[params] |
| 29 | pub struct RunnerSettings { |
| 30 | pub: |
| 31 | grid GridSettings |
| 32 | on_request SimRequestHandler = unsafe { nil } |
| 33 | on_start SimStartHandler = unsafe { nil } |
| 34 | on_finish SimFinishHandler = unsafe { nil } |
| 35 | } |
| 36 | |
| 37 | pub fn run(params SimParams, settings RunnerSettings) { |
| 38 | height := settings.grid.height |
| 39 | width := settings.grid.width |
| 40 | |
| 41 | if !isnil(settings.on_start) { |
| 42 | settings.on_start() or { |
| 43 | log(@MOD + '.' + @FN + ': Simulation start handler failed. Error ${err}') |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | mut index := 0 |
| 48 | log('') |
| 49 | |
| 50 | mut bmark := benchmark.new_benchmark() |
| 51 | for y in 0 .. height { |
| 52 | $if verbose ? { |
| 53 | term.clear_previous_line() |
| 54 | } |
| 55 | log(@MOD + '.' + @FN + ': y: ${y + 1}') |
| 56 | for x in 0 .. width { |
| 57 | bmark.step() |
| 58 | // setup state conditions |
| 59 | position := vector( |
| 60 | x: 0.1 * ((f64(x) - 0.5 * f64(width - 1)) / f64(width - 1)) |
| 61 | y: 0.1 * ((f64(y) - 0.5 * f64(height - 1)) / f64(height - 1)) |
| 62 | z: 0.0 |
| 63 | ) |
| 64 | velocity := vector(x: 0, y: 0, z: 0) |
| 65 | |
| 66 | mut state := new_state( |
| 67 | position: position |
| 68 | velocity: velocity |
| 69 | ) |
| 70 | |
| 71 | state.satisfy_rope_constraint(params) |
| 72 | request := &SimRequest{ |
| 73 | id: index |
| 74 | state: state |
| 75 | params: params |
| 76 | } |
| 77 | settings.on_request(request) or { |
| 78 | log(@MOD + '.' + @FN + ': request handler failed. Error ${err}') |
| 79 | bmark.fail() |
| 80 | break |
| 81 | } |
| 82 | index++ |
| 83 | bmark.ok() |
| 84 | } |
| 85 | } |
| 86 | bmark.stop() |
| 87 | println(bmark.total_message(@FN)) |
| 88 | |
| 89 | if !isnil(settings.on_finish) { |
| 90 | settings.on_finish() or { |
| 91 | log(@MOD + '.' + @FN + ': Simulation stop handler failed. Error ${err}') |
| 92 | } |
| 93 | } |
| 94 | } |
| 95 | |