From 1edd15c5045ccdf84dd57a3de199e008cda52f34 Mon Sep 17 00:00:00 2001 From: Kyle Mendes Date: Thu, 16 Feb 2023 14:33:05 -0500 Subject: Adding statefulness when toggling settings --- lua/pets.lua | 23 ++++++++++++++++---- lua/pets/animations.lua | 57 +++++++++++++++++++++++++++++++++++++++++++------ lua/pets/pet.lua | 46 ++++++++++++++++----------------------- 3 files changed, 87 insertions(+), 39 deletions(-) (limited to 'lua') diff --git a/lua/pets.lua b/lua/pets.lua index ac53551..282a147 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,26 @@ 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 + 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..9bbe97d 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 @@ -65,6 +70,7 @@ function M.Animation:start_timer() end function M.Animation:stop_timer() + print() if self.timer == nil then return end @@ -79,8 +85,18 @@ 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 + M.Animation.next_frame(self) + end end -- @function called on every tick from the timer, go to the next frame @@ -131,11 +147,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 +189,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_timer() + end + end +end + return M diff --git a/lua/pets/pet.lua b/lua/pets/pet.lua index 411efa6..7e2a302 100644 --- a/lua/pets/pet.lua +++ b/lua/pets/pet.lua @@ -8,19 +8,20 @@ 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) + require("pets.animations").Animation.new(instance.sourcedir, type, style, instance.popup, user_opts, instance.state) return instance end @@ -44,36 +45,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 -- cgit v1.3-2-g11bf From 67aef69c75a4e797b4fb4848722e6e749d3fbe89 Mon Sep 17 00:00:00 2001 From: Giuseppe Gadola Date: Fri, 17 Feb 2023 12:27:24 +0100 Subject: fix(toggles): fix pause after hide Fixed the pets not pausing after being hidden and unhidden. Also fixed an hologram error found in the process --- lua/pets.lua | 2 ++ lua/pets/animations.lua | 10 ++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'lua') diff --git a/lua/pets.lua b/lua/pets.lua index 282a147..cf76f0f 100644 --- a/lua/pets.lua +++ b/lua/pets.lua @@ -108,6 +108,8 @@ 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:set_hidden(hidden) diff --git a/lua/pets/animations.lua b/lua/pets/animations.lua index 9bbe97d..7b9cf17 100644 --- a/lua/pets/animations.lua +++ b/lua/pets/animations.lua @@ -15,7 +15,7 @@ for _ = 0, 20 do end local listdir = require("pets.utils").listdir -local sleeping_animations = {'idle', 'sit', 'liedown'} +local sleeping_animations = { "idle", "sit", "liedown" } local function get_sleeping_animation() return sleeping_animations[math.random(#sleeping_animations)] @@ -104,9 +104,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 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 @@ -205,7 +206,8 @@ function M.Animation:set_state(new_state) self.popup:mount() self:start() end - elseif new_state.paused ~= nil then + end + if new_state.paused ~= nil then if self.state.paused then self:stop_timer() else -- cgit v1.3-2-g11bf From 339f353f46f3a8d0c7f8d2eb369f85d1864718a3 Mon Sep 17 00:00:00 2001 From: Giuseppe Gadola Date: Fri, 17 Feb 2023 16:25:32 +0100 Subject: fix(toggles): fixed pausing while hidden before this fix pausing the pets while hidden would cause an error and/or break them and have them move twice as fast after being unhidden --- lua/pets/animations.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'lua') diff --git a/lua/pets/animations.lua b/lua/pets/animations.lua index 7b9cf17..a060720 100644 --- a/lua/pets/animations.lua +++ b/lua/pets/animations.lua @@ -59,9 +59,10 @@ function M.Animation.new(sourcedir, type, style, popup, user_opts, state) 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) @@ -104,7 +105,7 @@ function M.Animation:next_frame() self.frame_counter = self.frame_counter + 1 -- pouplate the buffer with spaces to avoid image distortion - if not vim.api.nvim_buf_is_valid(self.popup.bufnr) then + 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) @@ -206,15 +207,14 @@ function M.Animation:set_state(new_state) self.popup:mount() self:start() end - end - if new_state.paused ~= nil then + 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_timer() + self:start() end end end -- cgit v1.3-2-g11bf From a064533f569572b14f4ef1231a8a0e8e678ad5c1 Mon Sep 17 00:00:00 2001 From: Giuseppe Gadola Date: Fri, 17 Feb 2023 16:45:47 +0100 Subject: fix(toggles): fix pet spawning one row below while paused --- lua/pets/animations.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lua') diff --git a/lua/pets/animations.lua b/lua/pets/animations.lua index a060720..3324b61 100644 --- a/lua/pets/animations.lua +++ b/lua/pets/animations.lua @@ -96,7 +96,9 @@ function M.Animation:start() 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 - M.Animation.next_frame(self) + vim.schedule(function() + M.Animation.next_frame(self) + end) end end -- cgit v1.3-2-g11bf