The base tomo module only retains a singleton backend

This commit is contained in:
Sasha Koshka 2023-04-30 01:27:04 -04:00
parent cd8371a3f3
commit 363779a947
8 changed files with 21 additions and 103 deletions

View File

@ -1,4 +1,4 @@
package canvas
package artist
import "image"
import "image/draw"

View File

@ -2,12 +2,11 @@ package artist
import "image"
import "image/color"
import "git.tebibyte.media/sashakoshka/tomo/canvas"
type Icon interface {
// Draw draws the icon to the destination canvas at the specified point,
// using the specified color (if the icon is monochrome).
Draw (destination canvas.Canvas, color color.RGBA, at image.Point)
Draw (destination Canvas, color color.RGBA, at image.Point)
// Bounds returns the bounds of the icon.
Bounds () image.Rectangle

View File

@ -1,7 +1,6 @@
package artist
import "image"
import "git.tebibyte.media/sashakoshka/tomo/canvas"
// Pattern is capable of drawing to a canvas within the bounds of a given
// clipping rectangle.
@ -10,5 +9,5 @@ type Pattern interface {
// specified bounds. The given bounds can be smaller or larger than the
// bounds of the destination canvas. The destination canvas can be cut
// using canvas.Cut() to draw only a specific subset of a pattern.
Draw (destination canvas.Canvas, bounds image.Rectangle)
Draw (destination Canvas, bounds image.Rectangle)
}

View File

@ -1,7 +1,6 @@
package tomo
import "image"
import "errors"
// Backend represents a connection to a display server, or something similar.
// It is capable of managing an event loop, and creating windows.
@ -32,33 +31,21 @@ type Backend interface {
SetConfig (Config)
}
// BackendFactory represents a function capable of constructing a backend
// struct. Any connections should be initialized within this function. If there
// any errors encountered during this process, the function should immediately
// stop, clean up any resources, and return an error.
type BackendFactory func () (backend Backend, err error)
var backend Backend
// RegisterBackend registers a backend factory. When an application calls
// tomo.Run(), the first registered backend that does not throw an error will be
// used.
func RegisterBackend (factory BackendFactory) {
factories = append(factories, factory)
// GetBackend returns the currently running backend.
func GetBackend () Backend {
return backend
}
var factories []BackendFactory
func instantiateBackend () (backend Backend, err error) {
// find a suitable backend
for _, factory := range factories {
backend, err = factory()
if err == nil && backend != nil { return }
}
// if none were found, but there was no error produced, produce an
// error
if err == nil {
err = errors.New("no available backends")
}
return
// SetBackend sets the currently running backend. The backend can only be set
// once—if there already is one then this function will do nothing.
func SetBackend (b Backend) {
if backend != nil { return }
backend = b
}
// Bounds creates a rectangle from an x, y, width, and height.
func Bounds (x, y, width, height int) image.Rectangle {
return image.Rect(x, y, x + width, y + height)
}

View File

@ -1,4 +0,0 @@
// Package canvas provides a canvas interface that is able to return a pixel
// buffer for drawing. This makes it considerably more efficient than the
// standard draw.Image.
package canvas

View File

@ -1,6 +1,6 @@
package tomo
import "git.tebibyte.media/sashakoshka/tomo/canvas"
import "git.tebibyte.media/sashakoshka/tomo/artist"
// Element represents a basic on-screen object. Extended element interfaces are
// defined in the ability module.
@ -8,7 +8,7 @@ type Element interface {
// Draw causes the element to draw to the specified canvas. The bounds
// of this canvas specify the area that is actually drawn to, while the
// Entity bounds specify the actual area of the element.
Draw (canvas.Canvas)
Draw (artist.Canvas)
// Entity returns this element's entity.
Entity () Entity

View File

@ -1,7 +1,7 @@
package tomo
import "image"
import "git.tebibyte.media/sashakoshka/tomo/canvas"
import "git.tebibyte.media/sashakoshka/tomo/artist"
// Entity is a handle given to elements by the backend. Extended entity
// interfaces are defined in the ability module.
@ -28,5 +28,5 @@ type Entity interface {
// labels. If there is no parent element (that is, the element is
// directly inside of the window), the backend will draw a default
// background pattern.
DrawBackground (canvas.Canvas)
DrawBackground (artist.Canvas)
}

63
tomo.go
View File

@ -1,63 +0,0 @@
package tomo
import "image"
var backend Backend
// Run initializes a backend, calls the callback function, and begins the event
// loop in that order. This function does not return until Stop() is called, or
// the backend experiences a fatal error.
func Run (callback func ()) (err error) {
backend, err = instantiateBackend()
if err != nil { return }
if callback != nil { callback() }
err = backend.Run()
backend = nil
return
}
// Stop gracefully stops the event loop and shuts the backend down. Call this
// before closing your application.
func Stop () {
if backend != nil { backend.Stop() }
}
// Do executes the specified callback within the main thread as soon as
// possible. This function can be safely called from other threads.
func Do (callback func ()) {
assertBackend()
backend.Do(callback)
}
// NewEntity generates an entity for an element using the current backend.
func NewEntity (owner Element) Entity {
assertBackend()
return backend.NewEntity(owner)
}
// NewWindow creates a new window using the current backend, and returns it as a
// MainWindow. If the window could not be created, an error is returned
// explaining why.
func NewWindow (bounds image.Rectangle) (window MainWindow, err error) {
assertBackend()
return backend.NewWindow(bounds)
}
// SetTheme sets the theme of all open windows.
func SetTheme (theme Theme) {
backend.SetTheme(theme)
}
// SetConfig sets the configuration of all open windows.
func SetConfig (config Config) {
backend.SetConfig(config)
}
// Bounds creates a rectangle from an x, y, width, and height.
func Bounds (x, y, width, height int) image.Rectangle {
return image.Rect(x, y, x + width, y + height)
}
func assertBackend () {
if backend == nil { panic("no backend is running") }
}