Skip to content

Commit

Permalink
Before an error in decoding caused the program to block forever since…
Browse files Browse the repository at this point in the history
… the read goroutine returned and stopped. Now errors are reported.
  • Loading branch information
Carrotman42 committed Apr 19, 2014
1 parent 667ac0b commit 56b5bc4
Showing 1 changed file with 26 additions and 16 deletions.
42 changes: 26 additions & 16 deletions device.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,25 @@ package gomotion

import (
"code.google.com/p/go.net/websocket"
"net"
"fmt"
)

// A simple type to carry decode errors along rather than just dieing.
type FrameErr struct {
Frame *Frame
Error error
}

// The LeapMotionDevice definition. Connecting to a device will return an instance of this struct.
type LeapMotionDevice struct {
Pipe chan *Frame
Pipe chan FrameErr
Connection *websocket.Conn
}

// This function acts as a constructor and connector for the gomotion package.
func GetDevice(url string) (*LeapMotionDevice, error) {
pipe := make(chan *Frame)
pipe := make(chan FrameErr)
connection, err := websocket.Dial(url, "", "http://localhost")
if err != nil {
return nil, err
Expand All @@ -23,30 +31,32 @@ func GetDevice(url string) (*LeapMotionDevice, error) {
}

// This function starts the listening on the WebSocket. By default it enables Gestures on the LeapMotionDevice.
func (device *LeapMotionDevice) Listen() (error) {
var config struct {
func (device *LeapMotionDevice) Listen() error {
config := struct {
enableGestures bool `json:"enableGestures"`
}
config.enableGestures = true
err := websocket.JSON.Send(device.Connection, &config)
if err != nil {
} { true }
if err := websocket.JSON.Send(device.Connection, &config); err != nil {
return err
}
go device.listenRead()
return nil
}

func (device *LeapMotionDevice) listenRead() (error){
func (device *LeapMotionDevice) listenRead() {
for {
var frame Frame
err := websocket.JSON.Receive(device.Connection, &frame)
if err == nil {
device.Pipe <- &frame
} else {
return err
var frame FrameErr
if err := websocket.JSON.Receive(device.Connection, &frame.Frame); err != nil {
// Slightly way to avoid another variable in LeapMotionDevice. Works for me.
if _, ok := err.(*net.OpError); ok {
fmt.Println("Closed!")
close(device.Pipe)
return
}
frame.Error = err
}
device.Pipe <- frame
}
return nil
close(device.Pipe)
}

// This function closes the internal WebSocket connection on a LeapMotionDevice
Expand Down

0 comments on commit 56b5bc4

Please sign in to comment.