[Library] st8.lua

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: [Library] st8.lua

Post by s-ol »

Update!

Changed some things around with St8.pop and added a demo.
Attachments
st8-example.love
(4.97 KiB) Downloaded 105 times

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
User avatar
beforan
Prole
Posts: 10
Joined: Sat Dec 15, 2012 1:15 pm
Location: Nottingham, UK

Re: [Library] st8.lua

Post by beforan »

I've been playing with St8 a bit this afternoon and I like it a lot, really lightweight and straightforward, but does what it needs to :)

I was trying to get a way to determine if a state is the topmost state in the active stack, so the not topmost ones can draw themselves differently, potentially. Obviously they're all "active" in that they all process events, but I sort of want to consider the top one "focused" and be able to show that visually.

I added the following to st8.lua:

Code: Select all

function St8.isFocused(which)
  local stack = St8.stacks[#St8.stacks]
  return which == stack[#stack]
end
My plan was then, in a state, to do something like this:

Code: Select all

function myState:draw()
  -- assume colors is defined elsewhere ;)
  love.graphics.setColor(st8.isFocused(self) and colors.active or colors.inactive)
  -- then draw as normal
end
Due to the callbacky bits though, self becomes the callback return value, rather than the state. The following works, due to closures:

Code: Select all

love.graphics.setColor(st8.isFocused(myState) and colors.active or colors.inactive)
But it feels sort of wrong :\

Am I missing a much nicer way to do this? Or should I stop fussing about using the closured state reference instead of self?
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: [Library] st8.lua

Post by s-ol »

beforan wrote:I've been playing with St8 a bit this afternoon and I like it a lot, really lightweight and straightforward, but does what it needs to :)

I was trying to get a way to determine if a state is the topmost state in the active stack, so the not topmost ones can draw themselves differently, potentially. Obviously they're all "active" in that they all process events, but I sort of want to consider the top one "focused" and be able to show that visually.

I added the following to st8.lua:

Code: Select all

function St8.isFocused(which)
  local stack = St8.stacks[#St8.stacks]
  return which == stack[#stack]
end
My plan was then, in a state, to do something like this:

Code: Select all

function myState:draw()
  -- assume colors is defined elsewhere ;)
  love.graphics.setColor(st8.isFocused(self) and colors.active or colors.inactive)
  -- then draw as normal
end
Due to the callbacky bits though, self becomes the callback return value, rather than the state. The following works, due to closures:

Code: Select all

love.graphics.setColor(st8.isFocused(myState) and colors.active or colors.inactive)
But it feels sort of wrong :\

Am I missing a much nicer way to do this? Or should I stop fussing about using the closured state reference instead of self?
You can use the callback return values, they are passed through the stack downwards (or upwards, dependig on the callback order). For example with keypressed I often only want the topmost state to respond to keyboard input, or I want to go down the stack until someone handles it. Here's how I do both these things:

Code: Select all

UpperState:keypressed(key)
  if key == "space" then
    -- do something
    return true -- signal "THIS KEY WAS HANDLED"
  end
end

LowerState:keypressed(key)
  if self then return self end -- if the return value of the previous state evaluates to true, dont do anything except passing it on
  if key == "space" then
    -- do something else usually
  elseif key == "escape"
    -- do something
  end
  return true -- catch ALL key input in this state
end
I use the same "if self then return self end" line in update(dt) too. Then I can do "return true" in the pause state's update function to keep the state drawn (for example behind a semi-transparent overlay) but freeze the game.

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
User avatar
beforan
Prole
Posts: 10
Joined: Sat Dec 15, 2012 1:15 pm
Location: Nottingham, UK

Re: [Library] st8.lua

Post by beforan »

I did wonder about using the returns, but due to drawing bottom up, you can't say "i've already drawn the focused window, draw yourself as unfocused" because it goes in the wrong order; the focused window is drawn last, but has no way of knowing it's the last thing to be drawn.

Then it occurred to me that update() is still working top down, so i can use update to manage state, then draw based on that state '-.-

doing something like this:

Code: Select all

local focused
function myState:update()
  self = self or {}
  focused = not self.focusHandled
  self.focusHandled = true
  return self
end
function myState:draw()
  love.graphics.setColor(focused and colors.active or colors.inactive)
  ...
end
Thanks!
User avatar
beforan
Prole
Posts: 10
Joined: Sat Dec 15, 2012 1:15 pm
Location: Nottingham, UK

Re: [Library] st8.lua

Post by beforan »

Another question for you: you can pass arbitrary arguments to each function, but it's not always clear which function in the following picks up these arguments.

I've attached a .love which demonstrates the following information:

st8.pause()
* triggers state:pause() for all States in the Stack you're leaving
* triggers state:enter() for all States in the Stack you're going to

st8.resume()
* triggers state:exit() for all States in the Stack you're leaving
* triggers state:resume() for all States in the Stack you're going to

st8.push()
* triggers state:enter() for the State you're going to
* doesn't trigger state:pause() for the State you're leaving
* Does it trigger any callback in the State you're leaving?

st8.pop()
* triggers state:exit() for the State you're leaving
* doesn't trigger state:resume() for the State you're going to
* Does it trigger any callback in the State you're going to?

Basically, it's really cool that you can do this:

Code: Select all

function state1:keypressed(key)
  if key == "return" then
    st8.push(state2, "arg")
  end
end

state2.argReceived = false
function state2:enter(arg)
  if arg then state2.argReceived = true end
end
But it's a shame you can't seem to do this:

Code: Select all

function state2:keypressed(key)
  if key == "y" then
    st8.pop(1, "y")
  end
end

state1.dialogResult = false
function state2:resume(arg) -- or some other callback i haven't noticed?
  if arg == "y" then state1.dialogResult = true end
end
On github it says "these arguments will be passed on both to the last State(s) and the new ones", so I'm guess I'm asking what picks up the arguments when push() or pop() is used.
Attachments
st8-args.love
(2.84 KiB) Downloaded 95 times
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: [Library] st8.lua

Post by s-ol »

beforan wrote:Another question for you: you can pass arbitrary arguments to each function, but it's not always clear which function in the following picks up these arguments.

I've attached a .love which demonstrates the following information:

st8.pause()
* triggers state:pause() for all States in the Stack you're leaving
* triggers state:enter() for all States in the Stack you're going to

st8.resume()
* triggers state:exit() for all States in the Stack you're leaving
* triggers state:resume() for all States in the Stack you're going to

st8.push()
* triggers state:enter() for the State you're going to
* doesn't trigger state:pause() for the State you're leaving
* Does it trigger any callback in the State you're leaving?

st8.pop()
* triggers state:exit() for the State you're leaving
* doesn't trigger state:resume() for the State you're going to
* Does it trigger any callback in the State you're going to?
I know all of this is confusing, and I am procrastinating cleaning up the code as well as the documentation in this respect. The st8.lua version I actually use in my projects is slightly modified already and I need to clear things up a bit.

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
User avatar
beforan
Prole
Posts: 10
Joined: Sat Dec 15, 2012 1:15 pm
Location: Nottingham, UK

Re: [Library] st8.lua

Post by beforan »

S0lll0s wrote:I know all of this is confusing, and I am procrastinating cleaning up the code as well as the documentation in this respect.
Haha, no worries.

After enough poking the source I did see that the "lower" state in the stack has no callbacks that receive the arguments from push() and pop(), so I added my own in a dirty hacky way for now, to sort of proof of concept it to myself.

This seems to be working pretty well. Attached is a modified .love from before with this included.

So, thanks for providing st8 as a starting point for me to prod at all this :P
Attachments
st8-args.love
(3.43 KiB) Downloaded 286 times
Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests