Ruin0x11 / OpenNefia

(Archived) Moddable engine reimplementation of the Japanese roguelike Elona.
MIT License
116 stars 18 forks source link

More ergonomic way of creating draw callbacks #346

Open Ruin0x11 opened 3 years ago

Ruin0x11 commented 3 years ago

The draw callback system can be error-prone if misused, because you have to call coroutine.yield (Draw.yield) manually inside the callback closure you submit.

local cb = function(draw_x, draw_y)
   local t = UiTheme.load()
   local frames = 0.0
   while true do
      t.base.void:draw(0, 0, Draw.get_width(), Draw.get_height())
      local _, _, _, dt = Draw.yield(config.base.general_wait)
      frames = frames + dt
      if frames > 10.0 then
         break
      end
   end
end

Draw.start_draw_callback(cb)

A cleaner interface might help.

local cb = {}

function cb:init()
   self.t = UiTheme.load()
   self.frames = 0.0
end

function cb:draw(draw_x, draw_y)
   self.t.base.void:draw(0, 0, Draw.get_width(), Draw.get_height())
end

function cb:update(dt)
   self.frames = self.frames + dt
   if self.frames > 10.0
      return true
   end

   return false, config.base.general_wait
end

Draw.start_draw_callback(cb)

The :update() function would return the continue/stop result and the amount of delta time to wait for. The scheduling and execution would be handled behind the scenes.

This would also make it easier to program and instantiate new classes that implement the draw callback interface instead of needing to allocate a new closure every time.