loop

package
v0.0.0-...-241255c Latest Latest
Warning

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

Go to latest
Published: Feb 1, 2019 License: BSD-3-Clause Imports: 6 Imported by: 0

Documentation

Overview

Package loop provides a GUI event loop. The event loop will be locked to an OS thread and not return until all GUI elements have been destroyed. However, callbacks can be dispatched to the event loop, and will be executed on the same thread.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrNotRunning indicates that the main loop is not running.
	ErrNotRunning = errors.New("main loop is not running")

	// ErrAlreadyRunning indicates that the main loop is already running.
	ErrAlreadyRunning = errors.New("main loop is already running")
)

Functions

func AddLockCount

func AddLockCount(delta int32)

AddLockCount is used to track the number of top-level GUI elements that are created. When the count falls back to zero, the event loop will terminate.

Users should not typically need to call this function. Top-level GUI elements, such as windows, will increment and decrement the count as they are created and destroyed.

If the GUI event loop is not running, this function will panic.

func Do

func Do(action func() error) error

Do runs the passed function on the GUI thread. If the GUI event loop is not running, this function will return an error (ErrNotRunning). Any error from the callback will also be returned.

Because this function involves asynchronous communication with the GUI thread, it can deadlock if called from the GUI thread. It is therefore not safe to use in any event callbacks from widgets. However, since those callbacks are already executing on the GUI thread, the use of Do is also unnecessary in that context.

Note, this function contains a race-condition. An action may be scheduled while the event loop is being terminated, in which case the scheduled action may never be run. Presumably, those actions don't need to be run on the GUI thread, so they should be scheduled using a different mechanism.

If the passed function panics, the panic will be recovered, and wrapped into an error. That error will be used to create a new panic within the caller's goroutine. If the program terminates because of that panic, there will be two active goroutines in the stack trace. One active goroutine will be the GUI thread, where the panic originated, and a secton active goroutine from caller's goroutine.

Example
err := Do(func() error {
	// Inside this closure, we will be executing only on the GUI thread.
	_, err := fmt.Println("Hello.")
	// Return the error (if any) back to the caller.
	return err
})

// Report on the success or failure
fmt.Println("Previous call to fmt.Println resulted in ", err)
Output:

func Run

func Run(action func() error) error

Run locks the OS thread to act as a GUI thread, and then starts the GUI event loop until there are no more instances of Window open. If the main loop is already running, this function will return an error (ErrAlreadyRunning).

Modification of the GUI should happen only on the GUI thread. This includes creating any windows, mounting any widgets, or updating the properties of any elements.

The parameter action takes a closure that can be used to initialize the GUI. Any further modifications to the GUI also need to be scheduled on the GUI thread, which can be done using the function Do.

Example
// This init function will be used to create a window on the GUI thread.
init := func() error {
	// Create an empty window.
	AddLockCount(1)

	go func() {
		// Because of goroutine, we are now off the GUI thread.
		// Schedule an action.
		err := Do(func() error {
			AddLockCount(-1)
			fmt.Println("...like tears in rain")
			return nil
		})
		if err != nil {
			fmt.Println("Error:", err)
		}
	}()

	return nil
}

err := Run(init)
if err != nil {
	fmt.Println("Error:", err)
}
Output:

...like tears in rain

Types

This section is empty.

Jump to

Keyboard shortcuts

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