hokusai-zero 0.2.6.pre.pinephone → 0.2.6.pre.pinephone3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,564 +0,0 @@
1
- require "raylib"
2
- require 'memory_profiler'
3
-
4
- # frozen_string_literal: true
5
-
6
- module Hokusai::Backends
7
- class EmbeddedBackend
8
-
9
- RAYLIB_PATH = ENV["RAYLIB_PATH"] || begin
10
- path = "#{__dir__}/../../../../vendor/lib"
11
- case RbConfig::CONFIG['host_os']
12
- when /darwin/
13
- "#{path}/libraylib.dylib"
14
- when /mswin|msys|mingw/
15
- "#{path}/libraylib.dll"
16
- when /linux/
17
- "#{path}/libraylib.so"
18
- end
19
- end
20
-
21
- attr_reader :config, :last_touch
22
-
23
- def self.icons
24
- @icons ||= {}
25
- end
26
-
27
- def self.images
28
- @images ||= {}
29
- end
30
-
31
- def self.shaders
32
- @shaders ||= {}
33
- end
34
-
35
- def self.stopped?
36
- @stop = false if @stop.nil?
37
-
38
- @stop
39
- end
40
-
41
- def self.stop!
42
- @stop = true
43
- end
44
-
45
- def self.reset
46
- @stop = false
47
- end
48
-
49
- def initialize
50
- @config = Config.new
51
-
52
- yield(config)
53
- end
54
-
55
- def vec2(x, y, fresh = false)
56
- if @raylib_vec2.nil? || fresh
57
- @raylib_vec2 = Raylib::Vector2.new
58
- end
59
- @raylib_vec2[:x] = x
60
- @raylib_vec2[:y] = y
61
-
62
- @raylib_vec2
63
- end
64
-
65
- def hml_vec2(x, y)
66
- if @hml_vec2.nil?
67
- @hml_vec2 = LibHokusai::HmlVec2.create(x, y)
68
- else
69
- @hml_vec2[:x] = x
70
- @hml_vec2[:y] = y
71
- end
72
-
73
- @hml_vec2
74
- end
75
-
76
- def color(hc, fresh = false)
77
- if @raylib_color.nil? || fresh
78
- @raylib_color = Raylib::Color.from_u8(hc.red, hc.green, hc.blue, hc.alpha)
79
- else
80
- @raylib_color[:r] = hc.red
81
- @raylib_color[:g] = hc.green
82
- @raylib_color[:b] = hc.blue
83
- @raylib_color[:a] = hc.alpha
84
- end
85
-
86
- @raylib_color
87
- end
88
-
89
- def rect(arr)
90
- if @raylib_rect.nil?
91
- @raylib_rect = Raylib::Rectangle.create(arr[0], arr[1], arr[2], arr[3])
92
- else
93
- @raylib_rect[:x] = arr[0]
94
- @raylib_rect[:y] = arr[1]
95
- @raylib_rect[:width] = arr[2]
96
- @raylib_rect[:height] = arr[3]
97
- end
98
-
99
- @raylib_rect
100
- end
101
-
102
- def mouse_button(clicked: false, down: false, released: false, up: false)
103
- if @mouse_button.nil?
104
- @mouse_button = LibHokusai::HmlInputMouseButton.create(clicked: clicked, down: down, released: released, up: up)
105
- else
106
- @mouse_button[:clicked] = clicked
107
- @mouse_button[:down] = down
108
- @mouse_button[:released] = released
109
- @mouse_button[:up] = up
110
- end
111
-
112
- @mouse_button
113
- end
114
-
115
- def process_input(input)
116
- raylib_mouse_pos = Raylib.GetMousePosition
117
- raylib_mouse_delta = Raylib.GetMouseDelta
118
- LibHokusai.hoku_input_set_mouse_position(input.raw, hml_vec2(raylib_mouse_pos.x, raylib_mouse_pos.y))
119
-
120
- input.raw[:mouse][:delta][:x] = raylib_mouse_delta.x
121
- input.raw[:mouse][:delta][:y] = raylib_mouse_delta.y
122
-
123
- if Raylib.GetTouchPointCount > 0
124
- self.last_touch = Raylib.GetTouchPosition(0)
125
-
126
- button = mouse_button(clicked: false, down: true, released: false, up: false)
127
- LibHokusai.hoku_input_mouse_set_button(input.raw, button, 0)
128
- else
129
- if last_touch
130
- button = mouse_button(clicked: true, down: false, released: true, up: true)
131
- LibHokusai.hoku_input_mouse_set_button(input.raw, button, 0)
132
- end
133
- end
134
-
135
- LibHokusai.hoku_input_embedded_set_drag(input.raw, false, :up, 0.0, 0.0, 0.0)
136
- LibHokusai.hoku_input_embedded_set_hold(input.raw, false, 0)
137
- LibHokusai.hoku_input_embedded_set_pinch(input.raw, false, :in, 0.0, 0.0, 0.0)
138
-
139
- gesture = Raylib.GetGestureDetected
140
- case gesture
141
- when Raylib::GESTURE_NONE
142
- # nothing yet
143
- when Raylib::GESTURE_DOUBLETAP
144
- # nothing yet
145
- when Raylib::GESTURE_HOLD
146
- LibHokusai.hoku_input_embedded_set_hold(input.raw, true, Raylib.GetGestureHoldDuration)
147
- when Raylib::GESTURE_DRAG
148
- # nothing yet
149
- when Raylib::GESTURE_SWIPE_DOWN
150
- pos = Raylb.GetGestureDragVector
151
- LibHokusai.hoku_input_embedded_set_drag(input.raw, true, :down, pos.x, pos.y, Raylb.GetGestureDragAngle)
152
- when Raylib::GESTURE_SWIPE_UP
153
- pos = Raylb.GetGestureDragVector
154
- LibHokusai.hoku_input_embedded_set_drag(input.raw, true, :up, pos.x, pos.y, Raylb.GetGestureDragAngle)
155
- when Raylib::GESTURE_SWIPE_LEFT
156
- pos = Raylb.GetGestureDragVector
157
- LibHokusai.hoku_input_embedded_set_drag(input.raw, true, :left, pos.x, pos.y, Raylb.GetGestureDragAngle)
158
- when Raylib::GESTURE_SWIPE_RIGHT
159
- pos = Raylb.GetGestureDragVector
160
- LibHokusai.hoku_input_embedded_set_drag(input.raw, true, :right, pos.x, pos.y, Raylb.GetGestureDragAngle)
161
- when Raylib::GESTURE_PINCH_IN
162
- pos = Raylib.GetGesturePinchVector
163
- LibHokusai.hoku_input_embedded_set_pinch(input.raw, true, :in, pos.x, pos.y, Raylb.GetGesturePinchAngle)
164
- when Raylib::GESTURE_PINCH_OUT
165
- LibHokusai.hoku_input_embedded_set_pinch(input.raw, true, :out, pos.x, pos.y, Raylb.GetGesturePinchAngle)
166
- end
167
- end
168
-
169
- def self.run(app)
170
- backend = new do |config|
171
- yield config
172
- end
173
-
174
- block = app.mount
175
- backend.run(block)
176
- end
177
-
178
- def run(block)
179
- self.class.reset
180
-
181
- Raylib.load_lib(RAYLIB_PATH)
182
-
183
- resize = false
184
- initial = true
185
- width = config.width
186
- height = config.height
187
-
188
- register_command_handlers
189
-
190
- ptr = FFI::MemoryPointer.new :pointer
191
- LibHokusai.hoku_input_init(ptr)
192
- raw = LibHokusai::HmlInput.new(ptr.get_pointer(0))
193
- LibHokusai.hoku_input_attach_embedded(raw)
194
-
195
- input = Hokusai::Input.new(raw)
196
- ptr.free
197
-
198
- Raylib.SetConfigFlags(config.config_flags)
199
- Raylib.InitWindow(config.width, config.height, config.title)
200
- Raylib.SetTargetFPS(config.fps)
201
- Raylib.SetWindowState(config.window_state_flags)
202
-
203
- unless Hokusai.fonts.get("default")
204
- Hokusai.fonts.register "default", Hokusai::Backends::EmbeddedBackend::Font.default
205
- Hokusai.fonts.activate "default"
206
- end
207
-
208
- config.after_load_cb&.call
209
-
210
- if config.automated
211
- config.start_automation_driver
212
- end
213
-
214
- canvas = Hokusai::Canvas.new(width.to_f, height.to_f, 0.0, 0.0)
215
- @texture = Raylib.LoadRenderTexture(width, height)
216
- Raylib.SetTextureFilter(@texture.texture, Raylib::TEXTURE_FILTER_POINT)
217
-
218
- width = nil
219
- height = nil
220
-
221
- MemoryProfiler.start if ENV["PROFILE"]
222
-
223
- Raylib.EnableEventWaiting if config.event_waiting
224
- last_input_hash = nil
225
-
226
- until Raylib.WindowShouldClose
227
- if Raylib.IsWindowFocused
228
- Raylib.DisableEventWaiting
229
- else
230
- Raylib.EnableEventWaiting
231
- end
232
-
233
- last_width = Raylib.GetScreenWidth
234
- last_height = Raylib.GetScreenHeight
235
-
236
- if last_width != width || last_height != height
237
- resize = true
238
- else
239
- resize = false
240
- end
241
-
242
- width = last_width
243
- height = last_height
244
-
245
- process_input(input)
246
- block.public_send(:before_updated) if block.respond_to?(:before_updated)
247
- block.update
248
- block.public_send(:after_updated) if block.respond_to?(:after_updated)
249
-
250
- canvas.reset(nil, nil, width.to_f, height.to_f)
251
-
252
- Raylib.BeginDrawing
253
- Raylib.ClearBackground(config.background)
254
-
255
- painter = Hokusai::Painter.new(block, input)
256
-
257
- if config.automation_driver
258
- painter.on_before_render do |blocks, canvas, input|
259
- config.automation_driver.process(blocks, canvas, input)
260
- end
261
-
262
- painter.on_after_render do
263
- config.automation_driver.complete
264
- end
265
-
266
- sleep 0.004
267
- end
268
-
269
- painter.render(canvas, resize)
270
-
271
- Raylib.DrawFPS(10, 10) if ENV["PROFILE"] || ENV["FPS"]
272
- Raylib.EndDrawing
273
-
274
-
275
- break if self.class.stopped?
276
- end
277
-
278
- Hokusai.fonts.fonts.each do |key, font|
279
- Raylib.UnloadFont(font.raw)
280
- end
281
-
282
- self.class.images.each do |_, texture|
283
- Raylib.UnloadTexture(texture)
284
- end
285
-
286
- self.class.shaders.each do |k, shader|
287
- Raylib.UnloadShader(shader)
288
- end
289
-
290
- LibHokusai.hoku_input_free(input.raw)
291
-
292
- if ENV["PROFILE"]
293
- report = MemoryProfiler.stop
294
- report.pretty_print(scale_bytes: true)
295
- end
296
-
297
- Raylib.CloseWindow
298
-
299
- config.automation_driver&.stop
300
- end
301
-
302
- def shader_value(value, type)
303
- case type
304
- when Hokusai::SHADER_UNIFORM_FLOAT
305
- ptr = FFI::MemoryPointer.new(:float)
306
- ptr.write_float(value)
307
- ptr
308
- when Hokusai::SHADER_UNIFORM_INT
309
- ptr = FFI::MemoryPointer.new(:int)
310
- ptr.write_int(value)
311
- ptr
312
- when Hokusai::SHADER_UNIFORM_IVEC2, Hokusai::SHADER_UNIFORM_UIVEC2, Hokusai::SHADER_UNIFORM_VEC2
313
- Raylib::Vector2.create(*value)
314
- when Hokusai::SHADER_UNIFORM_VEC3, Hokusai::SHADER_UNIFORM_IVEC3, Hokusai::SHADER_UNIFORM_UIVEC3
315
- Raylib::Vector3.create(*value)
316
- when Hokusai::SHADER_UNIFORM_VEC4, Hokusai::SHADER_UNIFORM_UIVEC4, Hokusai::SHADER_UNIFORM_IVEC4
317
- Raylib::Vector4.create(*value)
318
- end
319
- end
320
-
321
-
322
- def inside_scissor(x, y, h = 0)
323
- return true if @scissor.nil?
324
-
325
- val = y + h >= @scissor[1] && y <= @scissor[1] + @scissor[3]
326
- val
327
- end
328
-
329
- def register_command_handlers
330
- Hokusai.on_close_window do
331
- self.class.stop!
332
- end
333
-
334
- Hokusai.on_set_mouse_cursor do |type|
335
- raylib_type = {
336
- default: Raylib::MOUSE_CURSOR_DEFAULT,
337
- arrow: Raylib::MOUSE_CURSOR_ARROW,
338
- ibeam: Raylib::MOUSE_CURSOR_IBEAM,
339
- crosshair: Raylib::MOUSE_CURSOR_CROSSHAIR,
340
- pointer: Raylib::MOUSE_CURSOR_POINTING_HAND,
341
- none: -1,
342
- }[type]
343
-
344
- raise Hokusai::Error.new("Cursor #{type} not recognized") if raylib_type.nil?
345
-
346
- if raylib_type == -1
347
- Raylib.HideCursor
348
- else
349
- Raylib.ShowCursor
350
- Raylib::SetMouseCursor(raylib_type)
351
- end
352
- end
353
-
354
- Hokusai.on_set_mouse_position do |mouse|
355
- Raylib.SetMousePosition(mouse.pos.x, mouse.pos.y)
356
- end
357
-
358
- Hokusai.on_set_window_position do |(dx, dy)|
359
- wpos = Raylib.GetWindowPosition
360
-
361
- Raylib.SetWindowPosition(wpos.x + dx, wpos.y + dy)
362
- end
363
-
364
- Hokusai.on_restore_window do
365
- Raylib.RestoreWindow
366
- end
367
-
368
- Hokusai.on_maximize_window do
369
- if Raylib.IsWindowMaximized
370
- Raylib.RestoreWindow
371
- else
372
- Raylib.MaximizeWindow
373
- end
374
- end
375
-
376
- Hokusai.on_minimize_window do
377
- Raylib.MinimizeWindow
378
- end
379
-
380
- Hokusai.on_renderable do |canvas|
381
- inside_scissor(canvas.x, canvas.y, canvas.height)
382
- end
383
-
384
- Hokusai::Commands::ShaderBegin.on_draw do |command|
385
- self.class.shaders[command.hash] ||= Raylib.LoadShaderFromMemory(command.vertex_shader, command.fragment_shader)
386
-
387
- unless command.uniforms.empty?
388
- command.uniforms.each do |key, value|
389
- location = Raylib.GetShaderLocation(self.class.shaders[command.hash], key.to_s)
390
-
391
- ptr = shader_value(value[0], value[1])
392
- Raylib.SetShaderValue(self.class.shaders[command.hash], location, ptr, value[1])
393
- ptr.free if ptr.is_a?(FFI::MemoryPointer)
394
- end
395
- end
396
-
397
- Raylib.BeginShaderMode(self.class.shaders[command.hash])
398
-
399
- @shader = self.class.shaders[command.hash]
400
- end
401
-
402
- Hokusai::Commands::ShaderEnd.on_draw do |_|
403
- Raylib.EndShaderMode
404
-
405
- @shader = nil
406
- end
407
-
408
- Hokusai::Commands::Texture.on_draw do |command|
409
- self.class.images[command.hash] ||= begin
410
- image = Raylib.GenImageColor(command.width, command.height, Raylib::BLANK)
411
- Raylib.LoadTextureFromImage(image)
412
- end
413
- Raylib.DrawTexture(self.class.images[command.hash], command.x, command.y, Raylib::WHITE)
414
- end
415
-
416
- Hokusai::Commands::ScissorBegin.on_draw do |command|
417
- Raylib.BeginScissorMode(command.x, command.y, command.width, command.height)
418
- @scissor = [command.x, command.y, command.width, command.height]
419
- end
420
-
421
- Hokusai::Commands::ScissorEnd.on_draw do |_|
422
- Raylib.EndScissorMode
423
- @scissor = nil
424
- end
425
-
426
- Hokusai::Commands::Circle.on_draw do |command|
427
- next unless inside_scissor(command.x, command.y)
428
-
429
- radius = command.radius - command.outline
430
- rc = command.color
431
- color = Raylib::Color.from_u8(rc.r, rc.g, rc.b, rc.a)
432
- Raylib.DrawCircleV(vec2(command.x, command.y), radius, color)
433
-
434
- if command.outline > 0
435
- Raylib.DrawCircleLines(command.x.ceil.to_i, command.y.ceil.to_i, command.radius, color(command.color))
436
- end
437
- end
438
-
439
- Hokusai::Commands::SVG.on_draw do |command|
440
- texture = begin
441
- if self.class.images[command.source]
442
- self.class.images[command.source]
443
- else
444
- img = Raylib.LoadImageSVG(command.source, command.width, command.height)
445
- texture = Raylib.load_texture_from_image(img)
446
- Raylib.UnloadImage(img)
447
- self.class.images[command.source] = texture
448
- texture
449
- end
450
- end
451
-
452
- Raylib.DrawTexture(texture, command.x, command.y, color(command.color))
453
- end
454
-
455
- Hokusai::Commands::Image.on_draw do |command|
456
- next unless inside_scissor(command.x, command.y, command.height)
457
-
458
- texture = begin
459
- if self.class.images[command.cache]
460
- self.class.images[command.cache]
461
- else
462
- img = Raylib.LoadImage(command.source)
463
- Raylib.ImageResize(img.to_ptr, command.width, command.height)
464
-
465
- texture = Raylib.LoadTextureFromImage(img)
466
- Raylib.UnloadImage(img)
467
- self.class.images[command.cache] = texture
468
- texture
469
- end
470
- end
471
-
472
- Raylib.DrawTexture(texture, command.x, command.y, Raylib::WHITE)
473
- end
474
-
475
- Hokusai::Commands::Text.on_draw do |command|
476
- next unless inside_scissor(command.x, command.y, command.size)
477
-
478
- active_name = Hokusai.fonts.active_font_name
479
- font = Hokusai.fonts.active
480
-
481
- Hokusai.fonts.activate command.font.nil? ? active_name : command.font
482
- font = Hokusai.fonts.active
483
-
484
- c = color(command.color)
485
- x = command.x + command.padding.l
486
- y = command.y + command.padding.t
487
-
488
- if fnt = font
489
- # content = FFI::MemoryPointer.from_string(command.content)
490
- Raylib.DrawTextEx(fnt.raw, command.content.to_s, vec2(x, y), command.size, fnt.spacing, c)
491
- # content.free
492
- else
493
- Raylib.DrawText(command.content, x, y, command.size, c)
494
- end
495
-
496
- Hokusai.fonts.activate active_name
497
- end
498
-
499
- Hokusai::Commands::Rect.on_draw do |command|
500
- next unless inside_scissor(command.x, command.y, command.height)
501
-
502
- background_color = color(command.color)
503
- # the rect has an outline
504
- # so we want to render twice
505
- if command.outline?
506
- # for Raylib, the boundaries for background and outline are the same
507
- # rectangles render in from the boundary
508
- # and outlines render out from the boundary
509
- # background_rect = outline_rect
510
- outline_rect = rect(command.background_boundary)
511
- background_rect = outline_rect
512
- # rect is rounded so we need a rounded outline and
513
- # a regular one
514
- if command.rounding > 0
515
- Raylib.DrawRectangleRounded(background_rect, command.rounding, 50, background_color)
516
- else
517
- Raylib.DrawRectangleRec(background_rect, background_color)
518
- end
519
-
520
- outline_color = color(command.outline_color)
521
-
522
- # now draw the outlines
523
- if command.outline_uniform? && command.rounding > 0.0 && outline_color.a > 0
524
- Raylib.DrawRectangleRoundedLinesEx(outline_rect, command.rounding, 50, command.outline.top + 1, outline_color)
525
- elsif command.outline_uniform? && !(command.rounding <= 0.0) && outline_color.a > 0
526
- Raylib.DrawRectangleLinesEx(outline_rect, command.outline.top, outline_color)
527
- elsif !command.outline_uniform?
528
- ox, oy, ow, oh = command.background_boundary
529
-
530
- if command.outline.top > 0.0
531
- Raylib.DrawLineEx(vec2(ox, oy, true), vec2(ox + ow, oy, true), command.outline.top, outline_color)
532
- end
533
-
534
- if command.outline.left > 0.0
535
- Raylib.DrawLineEx(vec2(ox, oy, true), vec2(ox, oy + oh, true), command.outline.left, outline_color)
536
- end
537
-
538
- if command.outline.right > 0.0
539
- Raylib.DrawLineEx(vec2(ox + ow, oy, true), vec2(ox + ow, oy + oh, true), command.outline.right, outline_color)
540
- end
541
-
542
- if command.outline.bottom > 0.0
543
- Raylib.DrawLineEx(vec2(ox, oy + oh, true), vec2(ox + ow, oy + oh, true), command.outline.bottom, outline_color)
544
- end
545
- end
546
- else
547
- rect = rect(command.background_boundary)
548
- if command.gradient
549
- Raylib.DrawRectangleGradientEx(rect, color(command.gradient[0], true), color(command.gradient[1], true), color(command.gradient[2], true), color(command.gradient[3], true))
550
- elsif command.rounding > 0
551
- Raylib.DrawRectangleRounded(rect, command.rounding, 50, background_color)
552
- else
553
- Raylib.DrawRectangleRec(rect, background_color)
554
- end
555
- end
556
- end
557
- end
558
- end
559
- end
560
-
561
- require_relative "../../hokusai/font"
562
- require_relative "./embedded/config"
563
- require_relative "./embedded/font"
564
- require_relative "./embedded/keys"