Class: Mayu::VDOM::VTree
- Inherits:
-
Object
- Object
- Mayu::VDOM::VTree
- Extended by:
- T::Sig
- Includes:
- Interfaces::VTree
- Defined in:
- lib/mayu/vdom/vtree.rb
Defined Under Namespace
Classes: Updater
Instance Attribute Summary collapse
-
#assets ⇒ Object
readonly
Returns the value of attribute assets.
-
#root ⇒ Object
readonly
Returns the value of attribute root.
-
#session ⇒ Object
readonly
Returns the value of attribute session.
-
#update_queue ⇒ Object
readonly
Returns the value of attribute update_queue.
Instance Method Summary collapse
- #action(type, payload) ⇒ Object
- #cleanup_unused_handlers! ⇒ Object
- #enqueue_update!(vnode) ⇒ Object
- #handle_callback(handler_id, payload = {}) ⇒ Object
- #id_tree ⇒ Object
-
#initialize(session:, task: Async::Task.current) ⇒ VTree
constructor
A new instance of VTree.
- #marshal_dump ⇒ Object
- #marshal_load(a) ⇒ Object
- #navigate(path) ⇒ Object
- #next_id! ⇒ Object
- #patch(ctx, vnode, descriptor, lifecycles:) ⇒ Object
- #render(descriptor, ctx: UpdateContext.new, lifecycles: true) ⇒ Object
- #replace_root(descriptor) ⇒ Object
- #to_html ⇒ Object
Constructor Details
#initialize(session:, task: Async::Task.current) ⇒ VTree
Returns a new instance of VTree.
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/mayu/vdom/vtree.rb', line 174 def initialize(session:, task: Async::Task.current) @root = T.let(nil, T.nilable(VNode)) @id_generator = T.let(IdGenerator.new, IdGenerator) @session = T.let(session, Session) @handlers = T.let({}, T::Hash[String, Component::HandlerRef]) @handler_counts = T.let(RefCounter.new, RefCounter[String]) @update_queue = T.let(Async::Queue.new, Async::Queue) @update_semaphore = T.let(Async::Semaphore.new(parent: task), Async::Semaphore) @assets = T.let(Set.new, T::Set[String]) end |
Instance Attribute Details
#assets ⇒ Object (readonly)
Returns the value of attribute assets.
171 172 173 |
# File 'lib/mayu/vdom/vtree.rb', line 171 def assets @assets end |
#root ⇒ Object (readonly)
Returns the value of attribute root.
168 169 170 |
# File 'lib/mayu/vdom/vtree.rb', line 168 def root @root end |
#session ⇒ Object (readonly)
Returns the value of attribute session.
163 164 165 |
# File 'lib/mayu/vdom/vtree.rb', line 163 def session @session end |
#update_queue ⇒ Object (readonly)
Returns the value of attribute update_queue.
166 167 168 |
# File 'lib/mayu/vdom/vtree.rb', line 166 def update_queue @update_queue end |
Instance Method Details
#action(type, payload) ⇒ Object
280 281 282 |
# File 'lib/mayu/vdom/vtree.rb', line 280 def action(type, payload) @update_queue.enqueue([:action, { type:, payload: }]) end |
#cleanup_unused_handlers! ⇒ Object
314 315 316 317 318 319 320 321 |
# File 'lib/mayu/vdom/vtree.rb', line 314 def cleanup_unused_handlers! @handlers.delete_if do |id, handler| if @handler_counts.count(id).zero? Console.logger.warn(self, "Removing handler #{id}") true end end end |
#enqueue_update!(vnode) ⇒ Object
262 263 264 265 266 267 268 269 |
# File 'lib/mayu/vdom/vtree.rb', line 262 def enqueue_update!(vnode) component = vnode.component return unless component return if component.dirty? component.dirty! @update_queue.enqueue(vnode) end |
#handle_callback(handler_id, payload = {}) ⇒ Object
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'lib/mayu/vdom/vtree.rb', line 225 def handle_callback(handler_id, payload = {}) case handler_id when "ping" @update_queue.enqueue([:pong, payload[:timestamp]]) return when "navigate" navigate(payload[:path]) return end @handlers .fetch(handler_id) do raise KeyError, "Handler not found: #{handler_id}" end .call(payload) rescue => e puts e. puts e.backtrace error = { type: e.class.name, message: e., backtrace: e.backtrace } @update_queue.enqueue([:exception, error]) end |
#id_tree ⇒ Object
257 258 259 |
# File 'lib/mayu/vdom/vtree.rb', line 257 def id_tree @root&.id_tree end |
#marshal_dump ⇒ Object
191 192 193 |
# File 'lib/mayu/vdom/vtree.rb', line 191 def marshal_dump [@root, @id_generator, @assets] end |
#marshal_load(a) ⇒ Object
196 197 198 199 200 201 202 203 204 |
# File 'lib/mayu/vdom/vtree.rb', line 196 def marshal_load(a) @root, @id_generator, @assets = a @handlers = {} @handler_counts = RefCounter.new @update_queue = Async::Queue.new @update_semaphore = Async::Semaphore.new @assets = Set.new @root.instance_variable_set(:@vtree, self) end |
#navigate(path) ⇒ Object
275 276 277 |
# File 'lib/mayu/vdom/vtree.rb', line 275 def navigate(path) @update_queue.enqueue([:navigate, path]) end |
#next_id! ⇒ Object
272 |
# File 'lib/mayu/vdom/vtree.rb', line 272 def next_id! = @id_generator.next! |
#patch(ctx, vnode, descriptor, lifecycles:) ⇒ Object
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
# File 'lib/mayu/vdom/vtree.rb', line 292 def patch(ctx, vnode, descriptor, lifecycles:) unless vnode return nil unless descriptor vnode = init_vnode(ctx, descriptor, lifecycles:) ctx.insert(vnode) return vnode end return remove_vnode(ctx, vnode, lifecycles:) unless descriptor if vnode.descriptor.same?(descriptor) patch_vnode(ctx, vnode, descriptor, lifecycles:) else remove_vnode(ctx, vnode, lifecycles:) vnode = init_vnode(ctx, descriptor, lifecycles:) ctx.insert(vnode) return vnode end end |
#render(descriptor, ctx: UpdateContext.new, lifecycles: true) ⇒ Object
213 214 215 216 217 |
# File 'lib/mayu/vdom/vtree.rb', line 213 def render(descriptor, ctx: UpdateContext.new, lifecycles: true) start_at = Time.now @root = patch(ctx, @root, descriptor, lifecycles:) ctx end |
#replace_root(descriptor) ⇒ Object
220 221 222 |
# File 'lib/mayu/vdom/vtree.rb', line 220 def replace_root(descriptor) @update_queue.enqueue([:replace_root, descriptor]) end |
#to_html ⇒ Object
252 253 254 |
# File 'lib/mayu/vdom/vtree.rb', line 252 def to_html @root&.to_html.to_s end |