vreactive

package
v0.1.333 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 12, 2026 License: BSD-3-Clause Imports: 1 Imported by: 0

README

vreactive - Reactive Layer for vgui & vtui

vreactive provides a lightweight, thread-safe, and cycle-protected reactive primitives library for Go UI frameworks (vtui and vgui).

Features

  • Property[T]: Reactive state container with subscription handlers.
  • Computed[T] / Computed2[T] / ComputedIf[T]: Automatically recomputed properties derived from reactive dependencies, including declarative ternary expressions (ComputedIf).
  • Bind[T]: One-way property synchronization.
  • StateMachine: Declarative state transitions and property setters.
  • Behavior[T] & Animator[T]: Smooth and discrete property transition animations (SmoothBehavior, DiscreteBehavior) supporting easing curves (EaseOutBack, EaseInOutQuad, EaseOutBounce, etc.).
  • RGBInterpolator: Seamless 24-bit TrueColor animation and channel blending.
  • Effect(fn, deps...): Signal-based side-effects running initially and tracking multi-property changes.
  • TwoWayBind: Cycle-safe bidirectional binding between state properties and external UI components.
  • BindEnabled / BindVisible: One-line declarative adapters linking widget flags directly to boolean properties.
  • Cycle Detection: Prevents infinite notification loops by enforcing a maximum call depth limit.
  • Thread Safety: Mutex-protected reads/writes and SafeSet for asynchronous background goroutine updates via UI event queues.

Usage Example

nameProp := vreactive.NewProperty("Alice")
greetingProp := vreactive.Computed(nameProp, func(name string) string {
    return "Hello, " + name + "!"
})

// Reacting to changes
greetingProp.OnChange(func(val string) {
    fmt.Println(val)
})

nameProp.Set("Bob") // Prints "Hello, Bob!"

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Bind

func Bind[T any](dest Property[T], src Property[T])

Bind automatically sets dest to the value of src whenever src changes.

func BindEnabled

func BindEnabled(prop Property[bool], target Disabler) func()

BindEnabled binds a widget's enabled state to prop (enabled when true).

func BindTo

func BindTo[T any](prop Property[T], target func(T)) func()

BindTo immediately applies prop.Get() to target and subscribes to all future updates.

func BindVisible

func BindVisible(prop Property[bool], target VisibilitySetter) func()

BindVisible binds a widget's visibility to prop.

func EaseInBack

func EaseInBack(t float64) float64

func EaseInCubic

func EaseInCubic(t float64) float64

Cubic easings

func EaseInOutCubic

func EaseInOutCubic(t float64) float64

func EaseInOutQuad

func EaseInOutQuad(t float64) float64

func EaseInQuad

func EaseInQuad(t float64) float64

Quadratic easings

func EaseOutBack

func EaseOutBack(t float64) float64

Back easings (overshooting transitions, corresponding to QML Easing.OutBack / InBack)

func EaseOutBounce

func EaseOutBounce(t float64) float64

Bounce easings

func EaseOutCubic

func EaseOutCubic(t float64) float64

func EaseOutQuad

func EaseOutQuad(t float64) float64

func Effect

func Effect(fn func(), deps ...Watcher) func()

Effect runs fn immediately and re-executes it whenever any dependency changes. It represents the standard Signal Effect pattern (SolidJS / Svelte / Vue).

func Float64Interpolator

func Float64Interpolator(start, end float64, progress float64) float64

func IntInterpolator

func IntInterpolator(start, end int, progress float64) int

func Linear

func Linear(t float64) float64

Linear is the standard default linear progress function.

func RGBInterpolator

func RGBInterpolator(start, end uint32, progress float64) uint32

RGBInterpolator smoothly blends between two 24-bit 0xRRGGBB colors across RGB channels.

func SafeSet

func SafeSet[T any](p Property[T], val T)

SafeSet updates the property value on the global update queue if configured. Extremely useful for thread-safe mutation from background goroutines.

func SetProp

func SetProp[T any](p Property[T], val T) func()

SetProp is a convenient helper for AddState to declare target property values.

func TwoWayBind

func TwoWayBind[T comparable](
	prop Property[T],
	get func() T,
	set func(T),
	listen func(onChange func(T)) (unlisten func()),
) func()

TwoWayBind creates a seamless 2-way binding between a Property[T] and an external control, eliminating infinite ping-pong notification echoes.

Types

type AnimationManager

type AnimationManager interface {
	AddAnimation(anim func(dt float64) bool)
}

AnimationManager handles the ticking of animators.

var GlobalAnimationManager AnimationManager

GlobalAnimationManager should be set by the UI framework.

type Animator

type Animator[T any] interface {
	Tick(dt float64) (val T, done bool)
}

type BehaviorDef

type BehaviorDef[T any] interface {
	CreateAnimator(start, end T) Animator[T]
}

type Disabler

type Disabler interface {
	SetDisabled(bool)
}

type DiscreteAnimator

type DiscreteAnimator[T any] struct {
	Target T
}

func (*DiscreteAnimator[T]) Tick

func (a *DiscreteAnimator[T]) Tick(dt float64) (T, bool)

type DiscreteBehavior

type DiscreteBehavior[T any] struct{}

func (*DiscreteBehavior[T]) CreateAnimator

func (b *DiscreteBehavior[T]) CreateAnimator(start, end T) Animator[T]

type EasingFunc

type EasingFunc func(t float64) float64

EasingFunc maps a normalized linear progress [0..1] to an eased progress value.

type Interpolator

type Interpolator[T any] func(start, end T, progress float64) T

type Property

type Property[T any] interface {
	Get() T
	Set(val T)
	OnChange(handler func(newVal T)) func()
	SetBehavior(b BehaviorDef[T])
	Watch(handler func()) func()
}

func Computed

func Computed[T any, A any](dep Property[A], compute func(A) T) Property[T]

Computed creates a read-only (in terms of design) property that reacts to dep.

func Computed2

func Computed2[T any, A, B any](dep1 Property[A], dep2 Property[B], compute func(A, B) T) Property[T]

Computed2 creates a property depending on two reactive sources.

func ComputedIf

func ComputedIf[T any](cond Property[bool], whenTrue, whenFalse T) Property[T]

ComputedIf creates a reactive property that evaluates to whenTrue when cond is true, or whenFalse otherwise.

func NewProperty

func NewProperty[T any](initial T) Property[T]

type SmoothAnimator

type SmoothAnimator[T any] struct {
	Start    T
	End      T
	Duration float64
	Elapsed  float64
	Easing   EasingFunc
	Interp   Interpolator[T]
}

func (*SmoothAnimator[T]) Tick

func (a *SmoothAnimator[T]) Tick(dt float64) (T, bool)

type SmoothBehavior

type SmoothBehavior[T any] struct {
	Duration float64
	Easing   EasingFunc
	Interp   Interpolator[T]
}

SmoothBehavior smoothly interpolates property transitions over Duration with optional Easing.

func (*SmoothBehavior[T]) CreateAnimator

func (b *SmoothBehavior[T]) CreateAnimator(start, end T) Animator[T]

type StateMachine

type StateMachine struct {
	State Property[string]
	// contains filtered or unexported fields
}

StateMachine helps defining declarative UI states.

func NewStateMachine

func NewStateMachine(initialState string) *StateMachine

func (*StateMachine) AddState

func (sm *StateMachine) AddState(name string, setters ...func())

type UpdateQueue

type UpdateQueue interface {
	PostTask(task func())
}

UpdateQueue interface allows posting tasks to the UI thread.

var GlobalUpdateQueue UpdateQueue

GlobalUpdateQueue should be set to the UI framework's task queue (e.g. vtui.FrameManager).

type VisibilitySetter

type VisibilitySetter interface {
	SetVisible(bool)
}

type Watcher

type Watcher interface {
	Watch(handler func()) func()
}

Watcher provides a value-agnostic notification subscription.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL