hokusai-zero 0.2.6 → 0.2.8

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.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -1
  3. data/Gemfile.lock +0 -2
  4. data/README.md +1 -1
  5. data/ast/src/core/ast.c +3 -11
  6. data/ast/src/core/hml.c +214 -40
  7. data/ast/src/core/hml.h +1 -0
  8. data/ast/src/core/input.h +0 -1
  9. data/ast/src/core/log.c +87 -0
  10. data/ast/src/core/log.h +41 -0
  11. data/ast/src/core/util.c +23 -23
  12. data/ast/src/core/util.h +7 -7
  13. data/ast/test/parser.c +1 -0
  14. data/ext/extconf.rb +6 -6
  15. data/hokusai.gemspec +1 -2
  16. data/ui/examples/drag.rb +154 -0
  17. data/ui/examples/embedded.rb +58 -0
  18. data/ui/examples/forum/file.rb +1 -1
  19. data/ui/examples/forum/post.rb +0 -1
  20. data/ui/examples/forum.rb +7 -7
  21. data/ui/examples/game.rb +143 -0
  22. data/ui/examples/keyboard.rb +47 -0
  23. data/ui/examples/overlay.rb +233 -0
  24. data/ui/examples/provider.rb +56 -0
  25. data/ui/examples/shader/test.rb +155 -0
  26. data/ui/examples/shader.rb +100 -0
  27. data/ui/examples/spreadsheet.rb +12 -11
  28. data/ui/examples/wiki.rb +82 -0
  29. data/ui/lib/lib_hokusai.rb +43 -24
  30. data/ui/spec/hokusai/e2e/client_spec.rb +0 -1
  31. data/ui/spec/hokusai/e2e/keyboard_spec.rb +52 -0
  32. data/ui/spec/spec_helper.rb +1 -1
  33. data/ui/src/hokusai/assets/arrow-down-line.png +0 -0
  34. data/ui/src/hokusai/assets/arrow-down-wide-line.png +0 -0
  35. data/ui/src/hokusai/assets/icons/outline/arrow-big-up.svg +19 -0
  36. data/ui/src/hokusai/assets/icons/outline/backspace.svg +20 -0
  37. data/ui/src/hokusai/automation/driver_commands/base.rb +2 -8
  38. data/ui/src/hokusai/automation/driver_commands/trigger_keyboard.rb +3 -6
  39. data/ui/src/hokusai/automation/driver_commands/trigger_mouse.rb +12 -5
  40. data/ui/src/hokusai/automation/server.rb +2 -3
  41. data/ui/src/hokusai/backends/raylib/config.rb +2 -1
  42. data/ui/src/hokusai/backends/raylib/font.rb +55 -4
  43. data/ui/src/hokusai/backends/raylib.rb +199 -36
  44. data/ui/src/hokusai/backends/sdl2/config.rb +9 -6
  45. data/ui/src/hokusai/backends/sdl2/font.rb +3 -1
  46. data/ui/src/hokusai/backends/sdl2.rb +188 -93
  47. data/ui/src/hokusai/blocks/color_picker.rb +1080 -0
  48. data/ui/src/hokusai/blocks/dynamic.rb +2 -0
  49. data/ui/src/hokusai/blocks/input.rb +2 -2
  50. data/ui/src/hokusai/blocks/keyboard.rb +249 -0
  51. data/ui/src/hokusai/blocks/panel.rb +2 -0
  52. data/ui/src/hokusai/blocks/scrollbar.rb +7 -0
  53. data/ui/src/hokusai/blocks/selectable.rb +1 -0
  54. data/ui/src/hokusai/blocks/shader_begin.rb +22 -0
  55. data/ui/src/hokusai/blocks/shader_end.rb +12 -0
  56. data/ui/src/hokusai/blocks/slider.rb +139 -0
  57. data/ui/src/hokusai/blocks/text_stream.rb +130 -0
  58. data/ui/src/hokusai/blocks/texture.rb +23 -0
  59. data/ui/src/hokusai/blocks/translation.rb +91 -0
  60. data/ui/src/hokusai/commands/rect.rb +12 -3
  61. data/ui/src/hokusai/commands/rotation.rb +21 -0
  62. data/ui/src/hokusai/commands/scale.rb +20 -0
  63. data/ui/src/hokusai/commands/shader.rb +33 -0
  64. data/ui/src/hokusai/commands/texture.rb +26 -0
  65. data/ui/src/hokusai/commands/translation.rb +20 -0
  66. data/ui/src/hokusai/commands.rb +49 -3
  67. data/ui/src/hokusai/event.rb +2 -1
  68. data/ui/src/hokusai/events/keyboard.rb +11 -18
  69. data/ui/src/hokusai/events/mouse.rb +10 -8
  70. data/ui/src/hokusai/events/touch.rb +62 -0
  71. data/ui/src/hokusai/meta.rb +13 -6
  72. data/ui/src/hokusai/mounting/loop_entry.rb +4 -4
  73. data/ui/src/hokusai/mounting/update_entry.rb +5 -6
  74. data/ui/src/hokusai/painter.rb +31 -8
  75. data/ui/src/hokusai/types/display.rb +155 -0
  76. data/ui/src/hokusai/types/keyboard.rb +168 -0
  77. data/ui/src/hokusai/types/mouse.rb +36 -0
  78. data/ui/src/hokusai/types/primitives.rb +56 -0
  79. data/ui/src/hokusai/types/touch.rb +181 -0
  80. data/ui/src/hokusai/types.rb +20 -244
  81. data/ui/src/hokusai/util/selection.rb +28 -7
  82. data/ui/src/hokusai/util/wrap_stream.rb +268 -0
  83. data/ui/src/hokusai.rb +72 -35
  84. data/xmake.lua +2 -1
  85. metadata +39 -22
  86. data/ui/src/hokusai/assets/chevron-down.svg +0 -1
@@ -0,0 +1,91 @@
1
+ class Hokusai::Blocks::TranslationBlock < Hokusai::Block
2
+ template <<~EOF
3
+ [template]
4
+ dynamic { @size_updated="set_size" }
5
+ slot
6
+ EOF
7
+
8
+ uses(dynamic: Hokusai::Blocks::Dynamic)
9
+
10
+ attr_accessor :content_width, :content_height
11
+
12
+ def set_size(width, height)
13
+ self.content_width = width
14
+ self.content_height = height
15
+ node.meta.set_prop(:width, width)
16
+ node.meta.set_prop(:height, height)
17
+ end
18
+
19
+ computed :duration, default: 500.0, convert: proc(&:to_f)
20
+ computed :from, default: :top, convert: proc(&:to_sym)
21
+
22
+ def on_mounted
23
+ @start = Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond)
24
+ end
25
+
26
+ def circular_in(t)
27
+ return 1.0 - Math.sqrt(1.0 - t * t);
28
+ end
29
+
30
+ def bounce_out(x)
31
+ n1 = 7.5625;
32
+ d1 = 2.75;
33
+ if (x < 1 / d1)
34
+ return n1 * x * x;
35
+ elsif (x < 2 / d1)
36
+ return n1 * (x -= 1.5 / d1) * x + 0.75;
37
+ elsif (x < 2.5 / d1)
38
+ return n1 * (x -= 2.25 / d1) * x + 0.9375;
39
+ else
40
+ return n1 * (x -= 2.625 / d1) * x + 0.984375;
41
+ end
42
+ end
43
+
44
+ def bounce_in(t)
45
+ return 1.0 - bounce_out(1.0 - t);
46
+ end
47
+
48
+ def ease(x)
49
+ return 1 - Math.cos((x * Math::PI) / 2);
50
+ end
51
+
52
+ def render(canvas)
53
+ @canvas ||= canvas
54
+ time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond) - @start
55
+
56
+ if time > duration
57
+ yield canvas
58
+
59
+ return
60
+ else
61
+ case from
62
+ when :top
63
+ @startx ||= canvas.x
64
+ @starty ||= canvas.y - canvas.height
65
+ when :left
66
+ @startx ||= canvas.x - canvas.width
67
+ @starty ||= canvas.y
68
+ when :right
69
+ @startx ||= canvas.x + canvas.width
70
+ @starty ||= canvas.y
71
+ when :bottom
72
+ @startx ||= canvas.x
73
+ @starty ||= canvas.y + canvas.height
74
+ end
75
+
76
+ @targetx ||= canvas.x
77
+ @targety ||= canvas.y
78
+
79
+ progress = bounce_in(time.to_f / duration)
80
+
81
+ if progress >= 1
82
+ progress = 1.0
83
+ end
84
+
85
+ canvas.x = (@startx + (-@startx * progress)) + (@targetx * progress)
86
+ canvas.y = (@starty + (-@starty * progress)) + (@targety * progress)
87
+
88
+ yield canvas
89
+ end
90
+ end
91
+ end
@@ -2,7 +2,7 @@ module Hokusai
2
2
  class Commands::Rect < Commands::Base
3
3
  attr_reader :x, :y, :width, :height,
4
4
  :rounding, :color, :outline,
5
- :outline_color, :padding
5
+ :outline_color, :padding, :gradient
6
6
 
7
7
  def initialize(x, y, width, height)
8
8
  @x = x.to_f
@@ -11,9 +11,10 @@ module Hokusai
11
11
  @height = height.to_f
12
12
  @outline = Outline.default
13
13
  @rounding = 0.0
14
- @color = Color.new(0, 0, 0, 0)
15
- @outline_color = Color.new(0, 0, 0, 255)
14
+ @color = Color.new(255, 255, 255, 0)
15
+ @outline_color = Color.new(0, 0, 0, 0)
16
16
  @padding = Padding.new(0.0, 0.0, 0.0, 0.0)
17
+ @gradient = nil
17
18
  end
18
19
 
19
20
  def hash
@@ -44,6 +45,14 @@ module Hokusai
44
45
  height
45
46
  end
46
47
 
48
+ def gradient=(colors)
49
+ unless colors.is_a?(Array) && colors.size == 4 && colors.all? { |color| color.is_a?(Hokusai::Color) }
50
+ raise Hokusai::Error.new("Gradient must be an array of 4 Hokuai::Color")
51
+ end
52
+
53
+ @gradient = colors
54
+ end
55
+
47
56
  # Sets padding for the rectangle
48
57
  # `value` is an array with padding declarations
49
58
  # at [top, right, bottom, left]
@@ -0,0 +1,21 @@
1
+ module Hokusai
2
+ class Commands::RotationBegin < Commands::Base
3
+ attr_reader :x, :y, :degrees
4
+
5
+ def initialize(x, y, deg)
6
+ @x = x
7
+ @y = y
8
+ @degrees = deg
9
+ end
10
+
11
+ def hash
12
+ [self.class, x, y, degrees].hash
13
+ end
14
+ end
15
+
16
+ class Commands::RotationEnd < Commands::Base;
17
+ def hash
18
+ [self.class].hash
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ module Hokusai
2
+ class Commands::ScaleBegin < Commands::Base
3
+ attr_reader :x, :y
4
+
5
+ def initialize(x, y = x)
6
+ @x = x
7
+ @y = y
8
+ end
9
+
10
+ def hash
11
+ [self.class, x, y].hash
12
+ end
13
+ end
14
+
15
+ class Commands::ScaleEnd < Commands::Base;
16
+ def hash
17
+ [self.class].hash
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,33 @@
1
+ module Hokusai
2
+ class Commands::ShaderBegin < Commands::Base
3
+ attr_reader :vertex_shader, :fragment_shader, :uniforms
4
+
5
+ def initialize
6
+ @uniforms = []
7
+ @vertex_shader = nil
8
+ @fragment_shader = nil
9
+ end
10
+
11
+ def vertex_shader=(content)
12
+ @vertex_shader = content
13
+ end
14
+
15
+ def fragment_shader=(content)
16
+ @fragment_shader = content
17
+ end
18
+
19
+ def uniforms=(values)
20
+ @uniforms = values
21
+ end
22
+
23
+ def hash
24
+ [self.class, vertex_shader, fragment_shader].hash
25
+ end
26
+ end
27
+
28
+ class Commands::ShaderEnd < Commands::Base;
29
+ def hash
30
+ [self.class].hash
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,26 @@
1
+ module Hokusai
2
+ class Commands::Texture < Commands::Base
3
+ attr_reader :x, :y, :width, :height, :rotation, :scale
4
+
5
+ def initialize(x, y, width, height)
6
+ @x = x
7
+ @y = y
8
+ @width = width
9
+ @height = height
10
+ @rotation = 0.0
11
+ @scale = 10.0
12
+ end
13
+
14
+ def rotation=(value)
15
+ @rotation = value
16
+ end
17
+
18
+ def scale=(value)
19
+ @scale = value
20
+ end
21
+
22
+ def hash
23
+ [self.class, x, y, width, height].hash
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,20 @@
1
+ module Hokusai
2
+ class Commands::TranslationBegin < Commands::Base
3
+ attr_reader :x, :y
4
+
5
+ def initialize(x, y = x)
6
+ @x = x
7
+ @y = y
8
+ end
9
+
10
+ def hash
11
+ [self.class, x, y].hash
12
+ end
13
+ end
14
+
15
+ class Commands::TranslationEnd < Commands::Base;
16
+ def hash
17
+ [self.class].hash
18
+ end
19
+ end
20
+ end
@@ -4,6 +4,11 @@ require_relative "./commands/image"
4
4
  require_relative "./commands/rect"
5
5
  require_relative "./commands/scissor"
6
6
  require_relative "./commands/text"
7
+ require_relative "./commands/shader"
8
+ require_relative "./commands/texture"
9
+ require_relative "./commands/rotation"
10
+ require_relative "./commands/scale"
11
+ require_relative "./commands/translation"
7
12
 
8
13
  module Hokusai
9
14
  # A proxy class for invoking various UI commands
@@ -31,7 +36,6 @@ module Hokusai
31
36
  yield(command)
32
37
 
33
38
  queue << command
34
- # command.draw
35
39
  end
36
40
 
37
41
  # Draw a circle
@@ -44,9 +48,7 @@ module Hokusai
44
48
 
45
49
  yield(command)
46
50
 
47
-
48
51
  queue << command
49
- # command.draw
50
52
  end
51
53
 
52
54
  # Draws an SVG
@@ -81,6 +83,50 @@ module Hokusai
81
83
  queue << Commands::ScissorEnd.new
82
84
  end
83
85
 
86
+ def shader_begin
87
+ command = Commands::ShaderBegin.new
88
+
89
+ yield command
90
+
91
+ queue << command
92
+ end
93
+
94
+ def shader_end
95
+ queue << Commands::ShaderEnd.new
96
+ end
97
+
98
+ def rotation_begin(x, y, deg)
99
+ queue << Commands::RotationBegin.new(x, y, deg)
100
+ end
101
+
102
+ def rotation_end
103
+ queue << Commands::RotationEnd.new
104
+ end
105
+
106
+ def scale_begin(*args)
107
+ queue << Commands::ScaleBegin.new(*args)
108
+ end
109
+
110
+ def scale_end
111
+ queue << Commands::ScaleEnd.new
112
+ end
113
+
114
+ def translation_Begin(x, y)
115
+ queue << Commands::TranslationBegin.new
116
+ end
117
+
118
+ def translation_end
119
+ queue << Commands::TranslationEnd.new
120
+ end
121
+
122
+ def texture(x, y, w, h)
123
+ command = Commands::Texture.new(x, y, w, h)
124
+
125
+ yield command
126
+
127
+ queue << command
128
+ end
129
+
84
130
  # Draws text
85
131
  #
86
132
  # @param [String] the text content
@@ -65,4 +65,5 @@ module Hokusai
65
65
  end
66
66
 
67
67
  require_relative './events/keyboard'
68
- require_relative './events/mouse'
68
+ require_relative './events/mouse'
69
+ require_relative './events/touch'
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hokusai
2
4
  class KeyboardEvent < Event
3
5
  extend Forwardable
4
6
 
5
7
  def_delegators :@keyboard, :shift, :super, :ctrl,
6
- :alt, :pressed, :pressed_len, :released,
7
- :released_len
8
+ :alt, :pressed, :released, :char, :code
8
9
 
9
10
  attr_reader :input
10
11
 
@@ -35,48 +36,40 @@ module Hokusai
35
36
  class KeyUpEvent < KeyboardEvent
36
37
  name "keyup"
37
38
 
38
- def keyboard_key
39
- input.raw[:keyboard][:released]
40
- end
41
-
42
39
  def key
43
- keyboard_key[:key][:key]
40
+ released[0]&.[](:symbol)
44
41
  end
45
42
 
46
43
  def code
47
- keyboard_key[:char_code]
44
+ released[0]&.[](:code)
48
45
  end
49
46
 
50
47
  def char
51
- code.chr
48
+ released[0]&.[](:char)
52
49
  end
53
50
 
54
51
  def capture(block, _)
55
- captures << block if matches(block) && released_len > 0
52
+ captures << block if matches(block) && released.size > 0
56
53
  end
57
54
  end
58
55
 
59
56
  class KeyPressEvent < KeyboardEvent
60
57
  name "keypress"
61
58
 
62
- def keyboard_key
63
- input.raw[:keyboard][:pressed]
64
- end
65
-
66
59
  def key
67
- keyboard_key[:key][:key]
60
+ pressed[0]&.[](:symbol)
68
61
  end
69
62
 
70
63
  def code
71
- keyboard_key[:char_code]
64
+ pressed[0]&.[](:code)
72
65
  end
73
66
 
74
67
  def char
75
- code.chr
68
+ pressed[0]&.[](:char)
76
69
  end
77
70
 
78
71
  def capture(block, _)
79
- return unless matches(block) && pressed_len > 0
72
+ return unless matches(block) && pressed.size > 0
80
73
 
81
74
  captures << block
82
75
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hokusai
2
4
  class MouseEvent < Event
3
5
  extend Forwardable
@@ -67,7 +69,7 @@ module Hokusai
67
69
  protected
68
70
 
69
71
  def hovered(canvas)
70
- LibHokusai.hoku_input_is_hovered(input.raw, canvas.to_hoku_rect)
72
+ input.hovered?(canvas)
71
73
  end
72
74
  end
73
75
 
@@ -85,19 +87,19 @@ module Hokusai
85
87
  name "click"
86
88
 
87
89
  def capture(block, canvas)
88
- if left[:clicked] && clicked(canvas)
90
+ if left.clicked && clicked(canvas)
89
91
  block.node.meta.focus
90
92
 
91
93
  if matches(block)
92
94
  captures << block
93
95
  end
94
- elsif left[:clicked]
96
+ elsif left.clicked
95
97
  block.node.meta.blur
96
98
  end
97
99
  end
98
100
 
99
101
  def clicked(canvas)
100
- LibHokusai.hoku_input_is_clicked(input.raw, canvas.to_hoku_rect)
102
+ left.clicked && input.hovered?(canvas)
101
103
  end
102
104
  end
103
105
 
@@ -105,7 +107,7 @@ module Hokusai
105
107
  name "mouseup"
106
108
 
107
109
  def capture(block, _)
108
- if left[:up] && matches(block)
110
+ if left.up && matches(block)
109
111
  captures << block
110
112
  end
111
113
  end
@@ -115,7 +117,7 @@ module Hokusai
115
117
  name "mousedown"
116
118
 
117
119
  def capture(block, _)
118
- if left[:down] && matches(block)
120
+ if left.down && matches(block)
119
121
  captures << block
120
122
  end
121
123
  end
@@ -168,13 +170,13 @@ module Hokusai
168
170
  def capture(block, canvas)
169
171
  captures << block if matches(block)
170
172
 
171
- if left[:clicked] && !clicked(canvas)
173
+ if left.clicked && !clicked(canvas)
172
174
  block.node.meta.blur
173
175
  end
174
176
  end
175
177
 
176
178
  def clicked(canvas)
177
- LibHokusai.hoku_input_is_clicked(input.raw, canvas.to_hoku_rect)
179
+ left.clicked && input.hovered?(canvas)
178
180
  end
179
181
  end
180
182
  end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hokusai
4
+ class TouchEvent < Event
5
+ extend Forwardable
6
+
7
+ def_delegators :@touch, :tapped?, :swiped?, :longtapped?, :longtapping?, :touching?,
8
+ :duration, :direction, :distance, :angle, :position, :last_position,
9
+ :touch_len, :touch_count, :timer
10
+
11
+ attr_reader :input
12
+
13
+ def initialize(input, state)
14
+ @input = input
15
+ @state = state
16
+ @touch = input.touch
17
+ end
18
+
19
+ def hovered(canvas)
20
+ input.hovered?(canvas)
21
+ end
22
+
23
+ def to_json
24
+ {
25
+ keypress: {
26
+ hold: hold,
27
+ hold_duration: hold_duration.to_s,
28
+ }
29
+ }.to_json
30
+ end
31
+ end
32
+
33
+ class TapHoldEvent < TouchEvent
34
+ name "taphold"
35
+
36
+ def capture(block, canvas)
37
+ if matches(block) && longtapped? && hovered(canvas)
38
+ captures << block
39
+ end
40
+ end
41
+ end
42
+
43
+ class PinchEvent < TouchEvent
44
+ name "pinch"
45
+
46
+ def capture(block, canvas)
47
+ if false && matches(block)
48
+ captures << block
49
+ end
50
+ end
51
+ end
52
+
53
+ class SwipeEvent < TouchEvent
54
+ name "swipe"
55
+
56
+ def capture(block, canvas)
57
+ if swiped? && matches(block)
58
+ captures << block
59
+ end
60
+ end
61
+ end
62
+ end
@@ -107,21 +107,28 @@ module Hokusai
107
107
  def update(block)
108
108
  if target_block = target
109
109
  if updater_block = updater
110
- block.public_send(:before_updated) if block.respond_to?(:before_updated)
110
+ block.before_updated if block.respond_to?(:before_updated)
111
111
 
112
112
  updater_block.call(block, target_block, target_block)
113
- block.public_send(:after_updated) if block.respond_to?(:after_updated)
113
+ block.after_updated if block.respond_to?(:after_updated)
114
114
  end
115
115
  end
116
116
 
117
117
  children?&.each do |child|
118
118
  child.update
119
119
  end
120
- end
121
120
 
122
- def has_ast?(ast, index)
123
- if portal = children![index]&.node&.portal&.portal
124
- return portal.ast.object_id == ast.object_id
121
+ block.after_children_updated if block.respond_to?(:after_children_updated)
122
+ end
123
+ def has_ast?(ast, index, elsy = false)
124
+ if elsy
125
+ if portal = children![index]&.node&.portal
126
+ return portal.ast.object_id == ast.object_id
127
+ end
128
+ else
129
+ if portal = children![index]&.node&.portal&.portal
130
+ return portal.ast.object_id == ast.object_id
131
+ end
125
132
  end
126
133
 
127
134
  false
@@ -65,7 +65,7 @@ module Hokusai
65
65
 
66
66
  portal = Node.new(ast)
67
67
  node = child_block_class.compile(ast.type, portal)
68
- child_block = child_block_class.new(node: node)
68
+ child_block = child_block_class.new(node: node, providers: mount_providers)
69
69
  child_block.node.add_styles(target.class)
70
70
  child_block.node.add_props_from_block(target, context: ctx)
71
71
  child_block.node.meta.set_prop(ast.loop.var.to_sym, value)
@@ -154,7 +154,7 @@ module Hokusai
154
154
  if patch.delete
155
155
  from = children[patch.from]
156
156
  children[patch.to] = from
157
- children[patch.from].public_send(:on_destroy) if children[patch.from].respond_to? :on_destroy
157
+ children[patch.from].public_send(:before_destroy) if children[patch.from].respond_to? :before_destroy
158
158
  children[patch.from].node.destroy
159
159
  children[patch.from] = nil
160
160
  else
@@ -189,7 +189,7 @@ module Hokusai
189
189
  if !condition && ast.has_else_condition?
190
190
  target_ast = ast.else_ast
191
191
  elsif !condition
192
- children[patch.target].public_send(:on_destroy) if children[patch.target].respond_to? :on_destroy
192
+ children[patch.target].public_send(:before_destroy) if children[patch.target].respond_to? :before_destroy
193
193
  children[patch.target].node.destroy
194
194
  children[patch.target] = nil
195
195
  next
@@ -210,7 +210,7 @@ module Hokusai
210
210
  children.insert(patch.target, child_block)
211
211
  end
212
212
  when DeletePatch
213
- children[patch.target].public_send(:on_destroy) if children[patch.target].respond_to? :on_destroy
213
+ children[patch.target].public_send(:before_destroy) if children[patch.target].respond_to? :before_destroy
214
214
  children[patch.target].node.destroy
215
215
  children[patch.target] = nil
216
216
  # TODO: update rest of block props
@@ -19,8 +19,8 @@ module Hokusai
19
19
  portal.ast.children.each_with_index do |child, index|
20
20
  next unless child.has_if_condition?
21
21
 
22
- child_present = ->(child) do
23
- meta.has_ast?(child, index)
22
+ child_present = ->(child, elsy) do
23
+ meta.has_ast?(child, index, elsy)
24
24
  end
25
25
 
26
26
  if child.if.args.size > 0
@@ -33,11 +33,11 @@ module Hokusai
33
33
 
34
34
  if !!visible
35
35
  if child.else_condition_active?
36
- meta.child_delete(index) if child_present.call(child)
36
+ meta.child_delete(index) if child_present.call(child, false)
37
37
  child.else_active = 0
38
38
  end
39
39
 
40
- unless child_present.call(child)
40
+ unless child_present.call(child, true)
41
41
  portal = Node.new(child, Node.new(child))
42
42
  node = child_block_klass.compile("root", portal)
43
43
  node.add_styles(target.class)
@@ -52,7 +52,6 @@ module Hokusai
52
52
  child_block = NodeMounter.new(node, child_block_klass, [stack], previous_providers: providers).mount(context: context, providers: providers)
53
53
 
54
54
  UpdateEntry.new(child_block, block, target).register(context: context, providers: providers)
55
-
56
55
  meta.children!.insert(index, child_block)
57
56
 
58
57
  child_block.public_send(:before_updated) if child_block.respond_to?(:before_updated)
@@ -61,7 +60,7 @@ module Hokusai
61
60
  end
62
61
  elsif !visible
63
62
  if !child.has_else_condition? || (child.has_else_condition? && !child.else_condition_active?)
64
- if (child_present.call(child))
63
+ if (child_present.call(child, true))
65
64
  meta.child_delete(index)
66
65
  end
67
66
  end