joysticks

package module
v0.0.0-...-fcfd5a8 Latest Latest
Warning

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

Go to latest
Published: May 23, 2020 License: Unlicense Imports: 6 Imported by: 19

README

joysticks

Go language joystick/controller/gamepad input.

uses Linux kernel 'input' interface, available on a wide range of linux devices, to receive events directly, no polling.

uses go channels to pipe around events, for flexibility and multi-threading.

Using

basically, after some setup, you handle events on the channels returned by methods on the HID type. each specific to an event type; HID.On<<event type>>(<<index>>)

the Capture() method automates this by returning a slice of channels for all the required events.

package also has some higher-level event modifiers for common UI abstractions, to help standardise advanced usage.

Overview/docs: GoDoc

Installation:

 go get github.com/splace/joysticks

Examples:

highlevel

automates Connection to an available device, event chan creation and parcelling out those events

// block until button one pressed.
package main

import . "github.com/splace/joysticks"

func main() {
	evts := Capture(
		Channel{1, HID.OnClose},  // evts[0] set to receive button #1 closes events
	)
	<-evts[0]
}
Midlevel

allows device interrogation and event re-assigning.

// log a description of events when pressing button #1 or moving hat#1. 
// 10sec timeout.
package main

import . "github.com/splace/joysticks"
import "log"
import "time"

func main() {
	// try connecting to specific controller.
	// the index is system assigned, typically it increments on each new controller added.
	// indexes remain fixed for a given controller, if/when other controller(s) are removed.
	device := Connect(1)

	if device == nil {
		panic("no HIDs")
	}

	// using Connect allows a device to be interrogated
	log.Printf("HID#1:- Buttons:%d, Hats:%d\n", len(device.Buttons), len(device.HatAxes)/2)

	// get/assign channels for specific events
	b1press := device.OnClose(1)
	h1move := device.OnMove(1)

	// start feeding OS events onto the event channels. 
	go device.ParcelOutEvents()

	// handle event channels
	go func(){
		for{
			select {
			case <-b1press:
				log.Println("button #1 pressed")
			case h := <-h1move:
				hpos:=h.(CoordsEvent)
				log.Println("hat #1 moved too:", hpos.X,hpos.Y)
			}
		}
	}()

	log.Println("Timeout in 10 secs.")
	time.Sleep(time.Second*10)
	log.Println("Shutting down due to timeout.")
}

Note: "jstest-gtk" - gtk mapping and calibration for joysticks.

Documentation

Overview

Package joysticks, provides simplified event routing, through channels, from the Linux joystick driver File-like interface.

events can be listened for from any thread, dynamically re-mapped and simulated.

Highlevel Usage

'Capture', one call to setup and start basic 'Event' channeling on the first available device.

Midlevel

'Connect(index)' to a HID.

Use methods to add (or alter) 'Event' channels.

Start running by calling 'ParcelOutEvents()'.

(unlike highlevel, event index to channel mappings can be changed dynamically.)

Lowlevel

'Connect' to a HID by index number.

handle all events directly appearing on the returned HID's OSEvents channel.

Interface

'Event' interface, provides a time.Duration through a call to the Moment() method, returning whatever the underlying Linux driver provides as the events timestamp, as a time.Duration.

returned 'Event's need asserting to their underlying type ( '***Event' ) to access data other than moment.

Index

Constants

This section is empty.

Variables

View Source
var DefaultRepeat = time.Second / 4
View Source
var DoublePressDelay = time.Second / 10
View Source
var LongPressDelay = time.Second / 2
View Source
var VelocityRepeat = time.Second / 10

Functions

func Capture

func Capture(registrees ...Channel) []chan Event

Capture is highlevel automation of the setup of event channels. Returned is a slice of chan's, matching each registree, which then receive events of the type and index the registree indicated. It uses the first available joystick, from a max of 4. Since it doesn't return a HID object, channels are immutable.

func DeviceExists

func DeviceExists(index uint8) bool

see if Device exists.

func Duplicator

func Duplicator(c chan Event) (chan Event, chan Event)

duplicate event onto two chan's

func PositionFromVelocity

func PositionFromVelocity(c chan Event) chan Event

creates a chan on which you get CoordsEvent's that are the time integration of the CoordsEvent's on the parameter chan.

func Repeater

func Repeater(c1, c2 chan Event) chan Event

creates a channel that, after receiving any event on the first parameter chan, and until any event on second chan parameter, regularly receives 'when' events. the repeat interval is DefaultRepeat, and is stored, so retriggering is not effected by changing DefaultRepeat.

Types

type AngleEvent

type AngleEvent struct {
	Angle float32
	// contains filtered or unexported fields
}

Hat angle event type. Angle{-Pi...Pi}

func (AngleEvent) Moment

func (b AngleEvent) Moment() time.Duration

type AxisEvent

type AxisEvent struct {
	V float32
	// contains filtered or unexported fields
}

Hat Axis event type. V{-1...1}

func (AxisEvent) Moment

func (b AxisEvent) Moment() time.Duration

type ButtonEvent

type ButtonEvent struct {
	// contains filtered or unexported fields
}

button changed

func (ButtonEvent) Moment

func (b ButtonEvent) Moment() time.Duration

type Channel

type Channel struct {
	Number uint8
	Method func(HID, uint8) chan Event
}

Type of register-able methods and the index they are called with. (Note: the event type is indicated by the method.)

type CoordsEvent

type CoordsEvent struct {
	X, Y float32
	// contains filtered or unexported fields
}

Hat position event type. X,Y{-1...1}

func (CoordsEvent) Moment

func (b CoordsEvent) Moment() time.Duration

type Event

type Event interface {
	Moment() time.Duration
}

Events always have the time they occurred.

type HID

type HID struct {
	OSEvents chan osEventRecord
	Buttons  map[uint8]button
	HatAxes  map[uint8]hatAxis
	Events   map[eventSignature]chan Event
}

HID holds the in-coming event channel, available button and hat indexes, and registered events, for a human interface device. It has methods to control and adjust behaviour.

func Connect

func Connect(index int) (d *HID)

Connect sets up a go routine that puts a joysticks events onto registered channels. to register channels use the returned HID object's On<xxx>(index) methods. Note: only one event, of each type '<xxx>', for each 'index', so re-registering, or deleting, an event stops events going on the old channel. It Needs the HID objects ParcelOutEvents() method to be running to perform routing.(so usually in a go routine.)

func (HID) ButtonClosed

func (d HID) ButtonClosed(index uint8) bool

Button current state.

func (HID) ButtonExists

func (d HID) ButtonExists(index uint8) (ok bool)

see if Button exists.

func (HID) HatCoords

func (d HID) HatCoords(index uint8, coords []float32)

Hat latest position. provided coords slice needs to be long enough to hold all the hat's axis.

func (HID) HatExists

func (d HID) HatExists(index uint8) (ok bool)

see if Hat exists.

func (HID) InsertSyntheticEvent

func (d HID) InsertSyntheticEvent(v int16, t uint8, i uint8)

insert events as if from hardware.

func (HID) OnButton

func (d HID) OnButton(index uint8) chan Event

button changes event channel.

func (HID) OnCenter

func (d HID) OnCenter(index uint8) chan Event

hat moved event channel.

func (HID) OnClose

func (d HID) OnClose(index uint8) chan Event

button goes closed event channel.

func (HID) OnDouble

func (d HID) OnDouble(index uint8) chan Event

button goes closed and the previous event, open, was less than DoublePressDelay ago, event channel.

func (HID) OnEdge

func (d HID) OnEdge(index uint8) chan Event

hat moved to edge

func (HID) OnHat

func (d HID) OnHat(index uint8) chan Event

hat moved event channel.

func (HID) OnLong

func (d HID) OnLong(index uint8) chan Event

button goes open and the previous event, closed, was more than LongPressDelay ago, event channel.

func (HID) OnMove

func (d HID) OnMove(index uint8) chan Event

hat position changed event channel.

func (HID) OnOpen

func (d HID) OnOpen(index uint8) chan Event

button goes open event channel.

func (HID) OnPanX

func (d HID) OnPanX(index uint8) chan Event

hat axis-X moved event channel.

func (HID) OnPanY

func (d HID) OnPanY(index uint8) chan Event

hat axis-Y moved event channel.

func (HID) OnRotate

func (d HID) OnRotate(index uint8) chan Event

hat angle changed event channel.

func (HID) OnSpeedX

func (d HID) OnSpeedX(index uint8) chan Event

hat axis-X speed changed event channel.

func (HID) OnSpeedY

func (d HID) OnSpeedY(index uint8) chan Event

hat axis-Y speed changed event channel.

func (HID) ParcelOutEvents

func (d HID) ParcelOutEvents()

ParcelOutEvents waits on the HID.OSEvents channel (so is blocking), then puts any events matching onto any registered channel(s).

type HatEvent

type HatEvent struct {
	// contains filtered or unexported fields
}

hat changed

func (HatEvent) Moment

func (b HatEvent) Moment() time.Duration

type RadiusEvent

type RadiusEvent struct {
	Radius float32
	// contains filtered or unexported fields
}

Hat radius event type. Radius{0...√2}

func (RadiusEvent) Moment

func (b RadiusEvent) Moment() time.Duration

Directories

Path Synopsis
VR

Jump to

Keyboard shortcuts

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