Documentation
¶
Index ¶
- func TrackValue[T any](tracker *Tracker, signal *Signal[T]) T
- type AcceptChild
- type AcceptChildTemplate
- type AcceptChildren
- type AcceptChildrenTemplate
- type AcceptNoChild
- type AcceptNoChildTemplate
- type BuildContext
- type ChildProps
- type Context
- type Event
- type EventId
- type Game
- func (g *Game) Draw(screen *ebiten.Image)
- func (g *Game) EmitEvent(contexts []*Context, event Event)
- func (g *Game) EmitEventNoContext(event Event)
- func (g *Game) GetSceneList() []Scene
- func (g *Game) Goto(scene Scene)
- func (g *Game) Height() float64
- func (g *Game) Layout(width, height int) (int, int)
- func (g *Game) LayoutF(logicWinWidth, logicWinHeight float64) (float64, float64)
- func (g *Game) Pop()
- func (g *Game) PopUntil(id string)
- func (g *Game) Push(scene Scene)
- func (g *Game) Update() error
- func (g *Game) Width() float64
- type Identifiable
- type KeyPressEvent
- type KeyReleaseEvent
- type Loadable
- type MoveEvent
- type Node
- type NodeBuilder
- type PositionalEvent
- type PressEvent
- type ReleaseEvent
- type RootProps
- type Scene
- type SceneTree
- func (st *SceneTree) Draw(c *Context, screen *ebiten.Image)
- func (st *SceneTree) GetId() string
- func (st *SceneTree) HandleEvent(c *Context, e Event) error
- func (st *SceneTree) Load()
- func (st *SceneTree) Mount(create func(t *Tracker, props *RootProps)) *SceneTree
- func (st *SceneTree) SetTransitionProps(handler func(bool) TransitionProperties) *SceneTree
- func (st *SceneTree) Transition(in bool) TransitionProperties
- func (st *SceneTree) Unload()
- func (st *SceneTree) Update(c *Context) error
- type ScrollEvent
- type Signal
- type SizeChangeEvent
- type StandardCreate
- type StandardMethods
- type StandardNode
- func (s *StandardNode[P]) Children() []Node
- func (s *StandardNode[P]) Context() *BuildContext
- func (s *StandardNode[P]) Draw(c *Context, image *ebiten.Image)
- func (s *StandardNode[P]) DrawChild(c *Context, image *ebiten.Image)
- func (s *StandardNode[P]) HandleEvent(c *Context, event Event) TracedError
- func (s *StandardNode[P]) HandleEventChild(c *Context, event Event) TracedError
- func (s *StandardNode[P]) ID() string
- func (s *StandardNode[P]) Load(parent Node)
- func (s *StandardNode[P]) Parent() Node
- func (s *StandardNode[P]) Props() P
- func (s *StandardNode[P]) PropsChanged(new P)
- func (s *StandardNode[P]) Tracker() *Tracker
- func (s *StandardNode[P]) Unload()
- func (s *StandardNode[P]) Update(c *Context) TracedError
- type State
- type StateMachine
- type StateMachineCreate
- type TracedError
- type Tracker
- type Tracking
- type TransitionCapable
- type TransitionProperties
- type TransitioningState
- type UpdateQueue
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func TrackValue ¶
TrackValue ensures tracker is subscribed to signal and returns the current value; closed or nil inputs return zero value.
Types ¶
type AcceptChild ¶
type AcceptChild = AcceptChildTemplate[NodeBuilder]
A struct that can be embedded as a pointer to implement a Child(builder NodeBuilder) function on props for a node with a single child.
This is recommended for use with a single child node as it saves a lot of code and implements all of the things required for children properly according to best practices.
func EmptyChild ¶
func EmptyChild() *AcceptChild
func WithChild ¶
func WithChild(builder NodeBuilder) *AcceptChild
type AcceptChildTemplate ¶
type AcceptChildTemplate[B any] struct { // contains filtered or unexported fields }
Template struct for type aliases that can be embedded as a pointer to implement a Child(builder NodeBuilder) function on props for a node with a single child.
func EmptyChildTemplate ¶
func EmptyChildTemplate[B any]() *AcceptChildTemplate[B]
Helper function for quickly creating empty single child template.
func WithChildTemplate ¶
func WithChildTemplate[B any](builder B) *AcceptChildTemplate[B]
Helper function for quickly creating new single child props.
func (*AcceptChildTemplate[B]) Child ¶
func (ac *AcceptChildTemplate[B]) Child(builder B)
Child adds a child to the node. There can only be one child.
There are internal reasons for this to be a method. Trackers just need to work with this properly.
func (*AcceptChildTemplate[B]) ClearChanged ¶
func (ac *AcceptChildTemplate[B]) ClearChanged()
func (AcceptChildTemplate[B]) GetBuilders ¶
func (ac AcceptChildTemplate[B]) GetBuilders() []B
func (AcceptChildTemplate[B]) GetChanged ¶
func (ac AcceptChildTemplate[B]) GetChanged() []uint
type AcceptChildren ¶
type AcceptChildren = AcceptChildrenTemplate[NodeBuilder]
A struct that can be embedded as a pointer to implement a Child(idex int, builder NodeBuilder) function on props for a node with a multiple children.
This is recommended for use with a multi child node as it saves a lot of code and implements all of the things required for children properly according to best practices.
func EmptyChildren ¶
func EmptyChildren() *AcceptChildren
func WithChildren ¶
func WithChildren(builders []NodeBuilder) *AcceptChildren
type AcceptChildrenTemplate ¶
type AcceptChildrenTemplate[B any] struct { // contains filtered or unexported fields }
Template struct for type aliases that can be embedded as a pointer to implement a Child(i uint, builder NodeBuilder) function on props for a node with a multiple children.
There are internal reasons for this to be a method. Trackers just need to work with this properly.
func EmptyChildrenTemplate ¶
func EmptyChildrenTemplate[B any]() *AcceptChildrenTemplate[B]
Helper function for quickly creating empty multi child template.
func WithChildrenTemplate ¶
func WithChildrenTemplate[B any](builders []B) *AcceptChildrenTemplate[B]
Helper function for quickly creating new single child props.
func (*AcceptChildrenTemplate[B]) Child ¶
func (ac *AcceptChildrenTemplate[B]) Child(i uint, builder B)
Child adds a new child to the node. i is the index of the child. Make sure it is actually valid and stuff.
There are internal reasons for this to be a method. Trackers just need to work with this properly.
func (*AcceptChildrenTemplate[B]) ClearChanged ¶
func (ac *AcceptChildrenTemplate[B]) ClearChanged()
func (AcceptChildrenTemplate[B]) GetBuilders ¶
func (ac AcceptChildrenTemplate[B]) GetBuilders() []B
func (AcceptChildrenTemplate[B]) GetChanged ¶
func (ac AcceptChildrenTemplate[B]) GetChanged() []uint
type AcceptNoChild ¶
type AcceptNoChild = AcceptNoChildTemplate[NodeBuilder]
A struct that can be embedded as a pointer to implement a Child(builder NodeBuilder) function on props for a node with no children.
This is recommended for use with a single child node as it saves a lot of code and implements all of the things required for children properly according to best practices.
func EmptyNoChild ¶
func EmptyNoChild() AcceptNoChild
type AcceptNoChildTemplate ¶
type AcceptNoChildTemplate[B any] struct{}
Template struct for type aliases that can be embedded as a pointer to implement a Child(builder NodeBuilder) function on props for a node that should have no child.
func EmptyNoChildTemplate ¶
func EmptyNoChildTemplate[B any]() AcceptNoChildTemplate[B]
Helper function for quickly creating no child template
func (AcceptNoChildTemplate[B]) ClearChanged ¶
func (anc AcceptNoChildTemplate[B]) ClearChanged()
func (AcceptNoChildTemplate[B]) GetBuilders ¶
func (anc AcceptNoChildTemplate[B]) GetBuilders() []B
func (AcceptNoChildTemplate[B]) GetChanged ¶
func (anc AcceptNoChildTemplate[B]) GetChanged() []uint
type BuildContext ¶
type BuildContext struct {
// contains filtered or unexported fields
}
All the context for nodes being created within ScaffUI
func (BuildContext) AssetManager ¶
func (bc BuildContext) AssetManager() *paint.AssetManager
func (BuildContext) CopyWithNewUpdateQueue ¶
func (bc BuildContext) CopyWithNewUpdateQueue() *BuildContext
func (BuildContext) UpdateQueue ¶
func (bc BuildContext) UpdateQueue() *UpdateQueue
type ChildProps ¶
type ChildProps[B any] interface { // GetBuilders gets all the builders for the children of this node GetBuilders() []B // GetChanged gets all the changed indices since the last time ClearChanged was called. GetChanged() []uint // ClearChanged clears all the changed indices ClearChanged() }
An interface for props of a node that has children. This helps nodes like single child not rebuild as often.
type Context ¶
type Context struct {
// contains filtered or unexported fields
}
func (Context) TransitionFrame ¶
The timeframe for the transition
type EventId ¶
type EventId string
const ( EventIdMove EventId = "scaff::move" EventIdScroll EventId = "scaff::scroll" EventIdSizeChange EventId = "scaff::size-change" )
All types of events in Scaff
func EventIdKeyPress ¶
This event id has the key in it to make sure it can be handled separately from other events.
func EventIdKeyRelease ¶
This event id has the key in it to make sure it can be handled separately from other events.
func EventIdPress ¶
func EventIdPress(button ebiten.MouseButton) EventId
This event id has the button in it to make sure it can be marked as handled separately from events for other buttons
func EventIdRelease ¶
func EventIdRelease(button ebiten.MouseButton) EventId
This event id has the button in it to make sure it can be marked as handled separately from events for other buttons
type Game ¶
type Game struct {
// contains filtered or unexported fields
}
func (*Game) Draw ¶
Draw handles drawing of the game by drawing the bottom scene first and then going up from there.
func (*Game) EmitEvent ¶
EmitEvent sends an event to all scenes in the scene list in proper order (top -> bottom)
func (*Game) EmitEventNoContext ¶
EmitEventNoContext sends an event to all scenes in the scene list in proper order (top -> bottom), but it also builds a context for the scenes at the same time. Scenes that are not fully transitioned will not receive events.
func (*Game) GetSceneList ¶
Get the scene list, this may not be the last updated one, but the one that will be set next time Update is called.
func (*Game) Goto ¶
Goto completely removes all scenes from the scene stack and makes this scene the new one and only scene.
func (*Game) Layout ¶
This is not needed as we have LayoutF below, we want to make sure the scale factor is taken into account properly.
func (*Game) LayoutF ¶
This makes sure the monitor's resolution is actually properly respected (Source: https://github.com/tinne26/kage-desk/blob/main/docs/tutorials/ebitengine_game.md#layout)
func (*Game) PopUntil ¶
PopUntil "pops" (removes from the top) all scenes in the scene stack until a scene with a certain id is found (but that one is not removed).
type Identifiable ¶
type Identifiable interface {
ID() string
}
An interface that attaches a simple string identifer to
type KeyPressEvent ¶
Emitted when a user presses a key.
func (KeyPressEvent) EventID ¶
func (kp KeyPressEvent) EventID() EventId
type KeyReleaseEvent ¶
Emitted when a user releases a key.
func (KeyReleaseEvent) EventID ¶
func (kr KeyReleaseEvent) EventID() EventId
type Loadable ¶
type Loadable[T any] interface { // Called when the Node is initialized in the tree Load(parent T) // Called when the Node is removed from the tree Unload() }
type Node ¶
type Node interface {
Tracking
Identifiable
Loadable[Node]
// Should return your own parent
Parent() Node
// Should return your own children
Children() []Node
// Called on every physics tick (like 60 times a second, depending on what ebitens tick rate is)
Update(c *Context) TracedError
// Handle events from the system (you do not have to handle any, but should always push them along to children at least)
HandleEvent(c *Context, event Event) TracedError
// Draw the thing onto the screen
Draw(c *Context, image *ebiten.Image)
}
type NodeBuilder ¶
type NodeBuilder func(*BuildContext) Node
func Standard ¶
func Standard[P ChildProps[NodeBuilder]](create StandardCreate[P]) NodeBuilder
Standard lets you create a node with multiple children. Simply implement the ChildProps interface on the props you want to have for your node.
type PositionalEvent ¶
type PressEvent ¶
type PressEvent struct {
X int
Y int
Button ebiten.MouseButton
}
Emitted when the user presses a mouse button down.
func (PressEvent) EventID ¶
func (de PressEvent) EventID() EventId
func (PressEvent) Position ¶
func (de PressEvent) Position() scath.Vec
type ReleaseEvent ¶
type ReleaseEvent struct {
X int
Y int
Button ebiten.MouseButton
}
Emitted when a user releases a mouse button.
func (ReleaseEvent) EventID ¶
func (re ReleaseEvent) EventID() EventId
func (ReleaseEvent) Position ¶
func (re ReleaseEvent) Position() scath.Vec
type RootProps ¶
type RootProps struct {
*AcceptChildren
}
type Scene ¶
type Scene interface {
// GetId returns the unique identifier of the scene.
GetId() string
// Update updates the scene with the given context.
Update(c *Context) error
// Draw draws the scene onto the screen.
Draw(c *Context, screen *ebiten.Image)
// HandleEvent should handle an event (like input events + resizing, etc.)
HandleEvent(c *Context, e Event) error
TransitionCapable
}
type SceneTree ¶
type SceneTree struct {
// contains filtered or unexported fields
}
func NewSceneTree ¶
func NewSceneTree(id string, assetManager *paint.AssetManager) *SceneTree
NewSceneTree makes a new scene tree based on an identifier. This tree supports a builder pattern, just use .Mount(<node>) to mount a node into it or add a transition with SetTransitionProps.
func (*SceneTree) HandleEvent ¶
Pass events to the root node
func (*SceneTree) Load ¶
func (st *SceneTree) Load()
Transfers Load from the Scene interface to the scene root.
func (*SceneTree) SetTransitionProps ¶
func (st *SceneTree) SetTransitionProps(handler func(bool) TransitionProperties) *SceneTree
Set what kind of transition properties the scene should use (the parameter in the function is if the transition is reverse or not)
func (*SceneTree) Transition ¶
func (st *SceneTree) Transition(in bool) TransitionProperties
Forward transition properties from the embedded function
type ScrollEvent ¶
Emitted when there is a new scroll delta. This can be either the mouse, a touchpad or potentially also swiping around on mobile.
func (ScrollEvent) EventID ¶
func (se ScrollEvent) EventID() EventId
func (ScrollEvent) Position ¶
func (se ScrollEvent) Position() scath.Vec
type Signal ¶
type Signal[T any] struct { // contains filtered or unexported fields }
func (*Signal[T]) AddListener ¶
func (s *Signal[T]) AddListener(listener func(T)) func()
AddListener registers a listener and immediately pushes the current value; it returns an unsubscribe function.
func (*Signal[T]) Refresh ¶
func (s *Signal[T]) Refresh()
Refresh re-emits the current value to all listeners without changing it; listeners run synchronously.
func (*Signal[T]) Set ¶
func (s *Signal[T]) Set(value T)
Set updates the value and notifies all current listeners; listeners run synchronously and can block callers.
type SizeChangeEvent ¶
type SizeChangeEvent struct{}
Emitted when the size of the application changes.
This does not contain the new size as the context already does anyway.
func (SizeChangeEvent) EventID ¶
func (sce SizeChangeEvent) EventID() EventId
type StandardCreate ¶
type StandardCreate[P ChildProps[NodeBuilder]] struct { ID string DefaultProps P PropsCreator func(t *Tracker, props *P) Create func(methods *StandardMethods[P]) }
Struct for defining a new standard node.
ID should be a unique id for the node, but also probably be readable as it shows up in error messages.
DefaultProps are the props as they are by default. Make sure to also specify any embedded struct pointers.
PropsCreator should be the function passed in by users of your node (as in it should probably be an argument of the function creating your node).
Create is the function actually specifying your node. You can overwrite all of the functions of the node interface there, with some exceptions that we implement for you.
type StandardMethods ¶
type StandardMethods[P ChildProps[NodeBuilder]] struct { OnLoad func(node *StandardNode[P], parent Node) OnUnload func(node *StandardNode[P]) OnPropsChanged func(node *StandardNode[P]) OnUpdate func(node *StandardNode[P], c *Context) error OnHandleEvent func(node *StandardNode[P], c *Context, event Event) error OnDraw func(node *StandardNode[P], c *Context, image *ebiten.Image) }
type StandardNode ¶
type StandardNode[P ChildProps[NodeBuilder]] struct { // contains filtered or unexported fields }
func (*StandardNode[P]) Children ¶
func (s *StandardNode[P]) Children() []Node
func (*StandardNode[P]) Context ¶
func (s *StandardNode[P]) Context() *BuildContext
func (*StandardNode[P]) DrawChild ¶
func (s *StandardNode[P]) DrawChild(c *Context, image *ebiten.Image)
Draw the children of the node
func (*StandardNode[P]) HandleEvent ¶
func (s *StandardNode[P]) HandleEvent(c *Context, event Event) TracedError
func (*StandardNode[P]) HandleEventChild ¶
func (s *StandardNode[P]) HandleEventChild(c *Context, event Event) TracedError
func (*StandardNode[P]) ID ¶
func (s *StandardNode[P]) ID() string
func (*StandardNode[P]) Load ¶
func (s *StandardNode[P]) Load(parent Node)
func (*StandardNode[P]) Parent ¶
func (s *StandardNode[P]) Parent() Node
func (*StandardNode[P]) Props ¶
func (s *StandardNode[P]) Props() P
func (*StandardNode[P]) PropsChanged ¶
func (s *StandardNode[P]) PropsChanged(new P)
func (*StandardNode[P]) Tracker ¶
func (s *StandardNode[P]) Tracker() *Tracker
func (*StandardNode[P]) Unload ¶
func (s *StandardNode[P]) Unload()
func (*StandardNode[P]) Update ¶
func (s *StandardNode[P]) Update(c *Context) TracedError
type State ¶
func DefaultState ¶
ONLY USE THIS FOR THE DEFAULT STATE. Sort of like the else branch of an if statement, this state is active if no other state's checker returns true.
func NewState ¶
Create a new state. Will be activated if checker returned true and no state upper in the ladder has been activated.
func (*State[O, S]) Load ¶
func (s *State[O, S]) Load()
These functions are just required to implement the interface, they don't really matter
func (*State[O, S]) Transition ¶
func (s *State[O, S]) Transition(in bool) TransitionProperties
type StateMachine ¶
type StateMachine[O any, S comparable] struct { // contains filtered or unexported fields }
func NewStateMachine ¶
func NewStateMachine[O any, S comparable](create StateMachineCreate[O, S]) *StateMachine[O, S]
Create a new StateMachine.
Some things to keep in mind: - The first states are the highest priority (just like in a if statement). - def is the default state meaning when no other state works for the conditions, it will be used.
func (*StateMachine[O, S]) Draw ¶
func (sm *StateMachine[O, S]) Draw(now time.Time, drawFunc func(state S, frame scath.Timeframe))
Use this to draw the actual object that is supposed to be drawn from the state in the StateMachine.
func (*StateMachine[O, S]) Update ¶
func (sm *StateMachine[O, S]) Update(now time.Time, obj O)
Call to update the state in the StateMachine.
type StateMachineCreate ¶
type StateMachineCreate[O any, S comparable] struct { // What transition to use between states. If not set, no transition will be used. Transition optional.O[TransitionProperties] // All the states in StateMachine States []*State[O, S] // The default state (at the start, should not be in States) Default *State[O, S] }
A struct to create a new StateMachine.
type TracedError ¶
type TracedError interface {
error
// contains filtered or unexported methods
}
func NewTracedError ¶
func NewTracedError(identifiable Identifiable, err error) TracedError
Create a new error that actually traces the path of different identifiable objects. This makes it visible where an error happened for more easy debugging.
To use this, just wrap all of the times you return an error with this function.
type Tracker ¶
type Tracker struct {
// contains filtered or unexported fields
}
TODO: We need a method for actually, after the props are created, running all the effects cause otherwise those parts of the props won't be set, an ideal thing to do additionally would be to when the effects are ran, track which signals were added in each effect and then create a mapping between signal -> effect index, that way we could only re-run the effects that matter, for others we just re-run all effects obv.
func NewTracker ¶
func NewTracker(context *BuildContext, onChange func()) *Tracker
func (*Tracker) Clear ¶
func (t *Tracker) Clear()
Clear removes all tracked signals and is safe to call multiple times.
func (*Tracker) Effect ¶
func (t *Tracker) Effect(handler func())
Effect adds a new handler being called when the thing changes, use this to actually react to changes of signals (runs first immediately after being called).
RECURSIVE EFFECTS ARE NOT ALLOWED.
type Tracking ¶
type Tracking interface {
// Should return the tracker for the current Node
Tracker() *Tracker
}
type TransitionCapable ¶
type TransitionCapable interface {
// Transition is called when the state is transitioned in or out to configure the transition properly.
Transition(in bool) TransitionProperties
// Load is called when the state is loaded.
Load()
// Unload is called when the state is unloaded.
Unload()
}
type TransitionProperties ¶
type TransitionProperties struct {
// If the transition is isolated, the next / previous state will be transitioned in / out after.
//
// If the duration is not the same, the transition currently coming in always wins since it is drawn on top and the other state will just be dropped.
//
// Isolation will always be prioritied over non-isolation.
Isolated bool
// How long the transition should take. 0 = instant
Duration time.Duration
}
func NoTransition ¶
func NoTransition() TransitionProperties
func (TransitionProperties) ToTimeframe ¶
func (tp TransitionProperties) ToTimeframe(now time.Time, outTransition optional.O[TransitionProperties]) scath.Timeframe
ToTimeframe converts the transition properties to a scath.Timeframe.
type TransitioningState ¶
type TransitioningState[T TransitionCapable] struct { // contains filtered or unexported fields }
TransitioningState is a struct storing one object that can transition.
NOT GOROUTINE SAFE
func NewTransitioningState ¶
func NewTransitioningState[T TransitionCapable](now time.Time, state T) *TransitioningState[T]
NewTransitioningState creates a new TransitioningState with the given state.
The in transition will be initialized to start immediately.
func (*TransitioningState[T]) GetCurrent ¶
func (ts *TransitioningState[T]) GetCurrent() optional.O[T]
GetCurrent returns the current state, immediately returns new state, even when the transition is not over.
func (*TransitioningState[T]) Set ¶
func (ts *TransitioningState[T]) Set(now time.Time, state optional.O[T])
Set the state in the TransitioningState. You can also use nil to transition the thing out.
This will not handle setting the same thing twice, please deal with that at a higher level since comparisons in here are expensive.
func (*TransitioningState[T]) SetEmpty ¶
func (ts *TransitioningState[T]) SetEmpty(now time.Time)
type UpdateQueue ¶
type UpdateQueue struct {
// contains filtered or unexported fields
}
func NewUpdateQueue ¶
func NewUpdateQueue() *UpdateQueue
func (*UpdateQueue) Clear ¶
func (u *UpdateQueue) Clear()
Clear removes all callbacks from the queue without executing them
func (*UpdateQueue) Push ¶
func (u *UpdateQueue) Push(tracker *Tracker, effect int, callback func())
Push adds a callback to the queue, it's indexed by the tracker pointer and effect ID to avoid duplicates
func (*UpdateQueue) Update ¶
func (u *UpdateQueue) Update()
Update runs all the callbacks in the queue and then clears it
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
The paint package provides utilities for painting all kinds of things using Ebiten.
|
The paint package provides utilities for painting all kinds of things using Ebiten. |
|
This package provides support for creating world layers using declarative state.
|
This package provides support for creating world layers using declarative state. |
|
This package provides support for rich UI layers with input handling, rendering, layouting and declarative UI.
|
This package provides support for rich UI layers with input handling, rendering, layouting and declarative UI. |
|
uinode
This package provides very basic nodes that work with scaffui.
|
This package provides very basic nodes that work with scaffui. |
|
Scaff + math = scath.
|
Scaff + math = scath. |
|
Scaff's utility package.
|
Scaff's utility package. |