diff options
| author | Giuseppe Gadola <67549788+giusgad@users.noreply.github.com> | 2023-02-17 18:04:38 +0100 |
|---|---|---|
| committer | Giuseppe Gadola <giusgadola@gmail.com> | 2023-02-17 18:26:18 +0100 |
| commit | f72193b3f0f4888bd2480726dc756500767dc4f0 (patch) | |
| tree | 510764bf78cfe0320b5ef479ae714147f821bf87 /lua | |
| parent | docs(help): auto generate docs (diff) | |
| parent | fix(toggles): fix pet spawning one row below while paused (diff) | |
fix: merge pull request #10 from Kyle-Mendes/statefulness
Adding statefulness when toggling settings
Diffstat (limited to 'lua')
| -rw-r--r-- | lua/pets.lua | 25 | ||||
| -rw-r--r-- | lua/pets/animations.lua | 69 | ||||
| -rw-r--r-- | lua/pets/pet.lua | 54 |
3 files changed, 104 insertions, 44 deletions
diff --git a/lua/pets.lua b/lua/pets.lua index ac53551..cf76f0f 100644 --- a/lua/pets.lua +++ b/lua/pets.lua @@ -1,6 +1,10 @@ local M = {} local utils = require("pets.utils") +local paused = false +local hidden = false +local sleeping = false + M.options = { row = 1, -- the row (height) to display the pet at col = 0, -- the column to display the pet at (set to high numeber to have it stay stil at the right) @@ -56,7 +60,12 @@ function M.create_pet(name, type, style) utils.warning('Name "' .. name .. '" already in use') return end - local pet = require("pets.pet").Pet.new(name, type, style, M.options) + local state = { + paused = paused, + hidden = hidden, + sleeping = sleeping, + } + local pet = require("pets.pet").Pet.new(name, type, style, M.options, state) pet:animate() M.pets[pet.name] = pet end @@ -89,20 +98,28 @@ function M.list() end function M.toggle_pause() + paused = not paused for _, pet in pairs(M.pets) do - pet:toggle_pause() + pet:set_paused(paused) end end function M.toggle_hide() + hidden = not hidden + if hidden then -- Hiding relies on the pets being paused as well + paused = true + else + paused = false + end for _, pet in pairs(M.pets) do - pet:toggle_hide() + pet:set_hidden(hidden) end end function M.toggle_sleep() + sleeping = not sleeping for _, pet in pairs(M.pets) do - pet:toggle_sleep() + pet:set_sleep(sleeping) end end diff --git a/lua/pets/animations.lua b/lua/pets/animations.lua index 1a0aa4b..3324b61 100644 --- a/lua/pets/animations.lua +++ b/lua/pets/animations.lua @@ -15,13 +15,18 @@ for _ = 0, 20 do end local listdir = require("pets.utils").listdir +local sleeping_animations = { "idle", "sit", "liedown" } + +local function get_sleeping_animation() + return sleeping_animations[math.random(#sleeping_animations)] +end -- @param sourcedir the full path for the media directory -- @param type,style type and style of the pet -- @param popup the popup where the pet is displayed -- @param user_opts table with user options -- @return a new animation instance -function M.Animation.new(sourcedir, type, style, popup, user_opts) +function M.Animation.new(sourcedir, type, style, popup, user_opts, state) local instance = setmetatable({}, M.Animation) instance.type = type instance.style = style @@ -30,7 +35,7 @@ function M.Animation.new(sourcedir, type, style, popup, user_opts) instance.actions = listdir(sourcedir) instance.frames = {} instance.popup = popup - instance.sleeping = false + instance.state = state -- user options instance.row, instance.col = user_opts.row, user_opts.col @@ -54,9 +59,10 @@ function M.Animation.new(sourcedir, type, style, popup, user_opts) end function M.Animation:start_timer() - if self.timer == nil then - self.timer = vim.loop.new_timer() + if self.timer ~= nil then + self:stop_timer() end + self.timer = vim.loop.new_timer() self.timer:start(0, 1000 / (self.speed_multiplier * 8), function() vim.schedule(function() M.Animation.next_frame(self) @@ -65,6 +71,7 @@ function M.Animation:start_timer() end function M.Animation:stop_timer() + print() if self.timer == nil then return end @@ -79,8 +86,20 @@ function M.Animation:start() if self.timer ~= nil then -- reset timer self.timer = nil end - self.current_action = self.current_action or "idle" - M.Animation.start_timer(self) + + if self.state.sleeping then + self.current_action = get_sleeping_animation() + else + self.current_action = self.current_action or "idle" + end + + if not self.state.paused and not self.state.hidden then + M.Animation.start_timer(self) + elseif self.state.paused and not self.state.hidden then + vim.schedule(function() + M.Animation.next_frame(self) + end) + end end -- @function called on every tick from the timer, go to the next frame @@ -88,9 +107,10 @@ function M.Animation:next_frame() self.frame_counter = self.frame_counter + 1 -- pouplate the buffer with spaces to avoid image distortion - if vim.api.nvim_buf_is_valid(self.popup.bufnr) then - vim.api.nvim_buf_set_lines(self.popup.bufnr, 0, -1, false, lines) + if self.popup.bufnr == nil or not vim.api.nvim_buf_is_valid(self.popup.bufnr) then + return end + vim.api.nvim_buf_set_lines(self.popup.bufnr, 0, -1, false, lines) if not self.current_image then self.frame_counter = 1 else @@ -131,11 +151,10 @@ function M.Animation:set_next_action() sneak = { "crouch", "walk", "liedown" }, walk = { "idle", "idle_blink" }, } - local sleeping_animations = {'idle', 'sit', 'liedown'} - if self.sleeping then + if self.state.sleeping then -- If the animation isn't currently a sleeping animtion, put the pet in it, otherwise loop the animation if not utils.table_includes(sleeping_animations, self.current_action) then - self.current_action = sleeping_animations[math.random(#sleeping_animations)] + self.current_action = get_sleeping_animation() end else if math.random() < 0.5 then @@ -174,4 +193,32 @@ function M.Animation:stop() end end +function M.Animation:set_state(new_state) + for key, value in pairs(new_state) do + self.state[key] = value + end + + if new_state.hidden ~= nil then + if self.state.hidden then + self:stop_timer() + if self.current_image then + self.current_image:delete(0, { free = false }) + end + self.popup:unmount() + else + self.popup:mount() + self:start() + end + elseif new_state.paused ~= nil then + if self.state.paused then + self:stop_timer() + else + if self.current_image then + self.current_image:delete(0, { free = false }) + end + self:start() + end + end +end + return M diff --git a/lua/pets/pet.lua b/lua/pets/pet.lua index 411efa6..d165b98 100644 --- a/lua/pets/pet.lua +++ b/lua/pets/pet.lua @@ -8,19 +8,26 @@ M.Pet.__index = M.Pet -- @param style the color/style of the pet e.g. brown -- @param user_opts the table with user options -- @return a new Pet instance -function M.Pet.new(name, type, style, user_opts) +function M.Pet.new(name, type, style, user_opts, state) local instance = setmetatable({}, M.Pet) instance.name = name instance.type = type instance.style = style instance.death_animation = user_opts.death_animation + instance.state = state local wd = debug.getinfo(1).source:sub(2):match("(.*nvim/)") .. "media/" instance.sourcedir = wd .. type .. "/" .. style .. "/" instance.popup = require("nui.popup")(user_opts.popup) - instance.animation = - require("pets.animations").Animation.new(instance.sourcedir, type, style, instance.popup, user_opts) + instance.animation = require("pets.animations").Animation.new( + instance.sourcedir, + type, + style, + instance.popup, + user_opts, + instance.state + ) return instance end @@ -44,36 +51,25 @@ function M.Pet:kill() end end -function M.Pet:toggle_pause() - if not self.paused then - self.animation:stop_timer() - self.paused = true - else - if self.animation.current_image then - self.animation.current_image:delete(0, { free = false }) - end - self.animation:start_timer() - self.paused = false - end +function M.Pet:set_paused(paused) + self.state.paused = paused + self.animation:set_state({ + paused = paused, + }) end -function M.Pet:toggle_hide() - if not self.paused then - self.animation:stop_timer() - if self.animation.current_image then - self.animation.current_image:delete(0, { free = false }) - end - self.popup:unmount() - self.paused = true - else - self.popup:mount() - self.animation:start() - self.paused = false - end +function M.Pet:set_hidden(hidden) + self.state.hidden = hidden + self.state.paused = hidden + + self.animation:set_state({ + hidden = hidden, + paused = hidden, + }) end -function M.Pet:toggle_sleep() - self.animation.sleeping = not self.animation.sleeping +function M.Pet:set_sleep(sleeping) + self.animation:set_state({ sleeping = sleeping }) end return M |