forked from Elara6331/itd
		
	Switch to autogenerated DRPC framework
This commit is contained in:
		
							
								
								
									
										29
									
								
								api/api.go
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								api/api.go
									
									
									
									
									
								
							| @@ -4,14 +4,15 @@ import ( | ||||
| 	"io" | ||||
| 	"net" | ||||
|  | ||||
| 	"go.arsenm.dev/lrpc/client" | ||||
| 	"go.arsenm.dev/lrpc/codec" | ||||
| 	"go.arsenm.dev/itd/internal/rpc" | ||||
| 	"storj.io/drpc/drpcconn" | ||||
| ) | ||||
|  | ||||
| const DefaultAddr = "/tmp/itd/socket" | ||||
|  | ||||
| type Client struct { | ||||
| 	client *client.Client | ||||
| 	conn   *drpcconn.Conn | ||||
| 	client rpc.DRPCITDClient | ||||
| } | ||||
|  | ||||
| func New(sockPath string) (*Client, error) { | ||||
| @@ -19,19 +20,27 @@ func New(sockPath string) (*Client, error) { | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	dconn := drpcconn.New(conn) | ||||
|  | ||||
| 	out := &Client{ | ||||
| 		client: client.New(conn, codec.Default), | ||||
| 	} | ||||
| 	return out, nil | ||||
| 	return &Client{ | ||||
| 		conn:   dconn, | ||||
| 		client: rpc.NewDRPCITDClient(dconn), | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| func NewFromConn(conn io.ReadWriteCloser) *Client { | ||||
| 	dconn := drpcconn.New(conn) | ||||
|  | ||||
| 	return &Client{ | ||||
| 		client: client.New(conn, codec.Default), | ||||
| 		conn:   dconn, | ||||
| 		client: rpc.NewDRPCITDClient(dconn), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (c *Client) Close() error { | ||||
| 	return c.client.Close() | ||||
| func (c *Client) FS() *FSClient { | ||||
| 	return &FSClient{rpc.NewDRPCFSClient(c.conn)} | ||||
| } | ||||
|  | ||||
| func (c *Client) Close() error { | ||||
| 	return c.conn.Close() | ||||
| } | ||||
|   | ||||
| @@ -3,24 +3,34 @@ package api | ||||
| import ( | ||||
| 	"context" | ||||
|  | ||||
| 	"go.arsenm.dev/infinitime" | ||||
| 	"go.arsenm.dev/itd/internal/rpc" | ||||
| ) | ||||
|  | ||||
| func (c *Client) FirmwareUpgrade(ctx context.Context, upgType UpgradeType, files ...string) (chan infinitime.DFUProgress, error) { | ||||
| 	progressCh := make(chan infinitime.DFUProgress, 5) | ||||
| 	err := c.client.Call( | ||||
| 		ctx, | ||||
| 		"ITD", | ||||
| 		"FirmwareUpgrade", | ||||
| 		FwUpgradeData{ | ||||
| 			Type:  upgType, | ||||
| 			Files: files, | ||||
| 		}, | ||||
| 		progressCh, | ||||
| 	) | ||||
| type DFUProgress struct { | ||||
| 	Sent     int64 | ||||
| 	Received int64 | ||||
| 	Total    int64 | ||||
| 	Err      error | ||||
| } | ||||
|  | ||||
| func (c *Client) FirmwareUpgrade(ctx context.Context, upgType UpgradeType, files ...string) (chan DFUProgress, error) { | ||||
| 	progressCh := make(chan DFUProgress, 5) | ||||
| 	fc, err := c.client.FirmwareUpgrade(ctx, &rpc.FirmwareUpgradeRequest{ | ||||
| 		Type:  rpc.FirmwareUpgradeRequest_Type(upgType), | ||||
| 		Files: files, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	go fsRecvToChannel[rpc.DFUProgress](fc, progressCh, func(evt *rpc.DFUProgress, err error) DFUProgress { | ||||
| 		return DFUProgress{ | ||||
| 			Sent:     evt.Sent, | ||||
| 			Received: evt.Recieved, | ||||
| 			Total:    evt.Total, | ||||
| 			Err:      err, | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	return progressCh, nil | ||||
| } | ||||
|   | ||||
							
								
								
									
										155
									
								
								api/fs.go
									
									
									
									
									
								
							
							
						
						
									
										155
									
								
								api/fs.go
									
									
									
									
									
								
							| @@ -1,96 +1,119 @@ | ||||
| package api | ||||
|  | ||||
| import "context" | ||||
| import ( | ||||
| 	"context" | ||||
| 	"errors" | ||||
| 	"io" | ||||
|  | ||||
| func (c *Client) RemoveAll(ctx context.Context, paths ...string) error { | ||||
| 	return c.client.Call( | ||||
| 		ctx, | ||||
| 		"FS", | ||||
| 		"RemoveAll", | ||||
| 		paths, | ||||
| 		nil, | ||||
| 	) | ||||
| 	"go.arsenm.dev/itd/internal/rpc" | ||||
| ) | ||||
|  | ||||
| type FSClient struct { | ||||
| 	client rpc.DRPCFSClient | ||||
| } | ||||
|  | ||||
| func (c *Client) Remove(ctx context.Context, paths ...string) error { | ||||
| 	return c.client.Call( | ||||
| 		ctx, | ||||
| 		"FS", | ||||
| 		"Remove", | ||||
| 		paths, | ||||
| 		nil, | ||||
| 	) | ||||
| func (c *FSClient) RemoveAll(ctx context.Context, paths ...string) error { | ||||
| 	_, err := c.client.RemoveAll(ctx, &rpc.PathsRequest{Paths: paths}) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func (c *Client) Rename(ctx context.Context, old, new string) error { | ||||
| 	return c.client.Call( | ||||
| 		ctx, | ||||
| 		"FS", | ||||
| 		"Rename", | ||||
| 		[2]string{old, new}, | ||||
| 		nil, | ||||
| 	) | ||||
| func (c *FSClient) Remove(ctx context.Context, paths ...string) error { | ||||
| 	_, err := c.client.Remove(ctx, &rpc.PathsRequest{Paths: paths}) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func (c *Client) MkdirAll(ctx context.Context, paths ...string) error { | ||||
| 	return c.client.Call( | ||||
| 		ctx, | ||||
| 		"FS", | ||||
| 		"MkdirAll", | ||||
| 		paths, | ||||
| 		nil, | ||||
| 	) | ||||
| func (c *FSClient) Rename(ctx context.Context, old, new string) error { | ||||
| 	_, err := c.client.Rename(ctx, &rpc.RenameRequest{ | ||||
| 		From: old, | ||||
| 		To:   new, | ||||
| 	}) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func (c *Client) Mkdir(ctx context.Context, paths ...string) error { | ||||
| 	return c.client.Call( | ||||
| 		ctx, | ||||
| 		"FS", | ||||
| 		"Mkdir", | ||||
| 		paths, | ||||
| 		nil, | ||||
| 	) | ||||
| func (c *FSClient) MkdirAll(ctx context.Context, paths ...string) error { | ||||
| 	_, err := c.client.MkdirAll(ctx, &rpc.PathsRequest{Paths: paths}) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func (c *Client) ReadDir(ctx context.Context, dir string) (out []FileInfo, err error) { | ||||
| 	err = c.client.Call( | ||||
| 		ctx, | ||||
| 		"FS", | ||||
| 		"ReadDir", | ||||
| 		dir, | ||||
| 		&out, | ||||
| 	) | ||||
| 	return | ||||
| func (c *FSClient) Mkdir(ctx context.Context, paths ...string) error { | ||||
| 	_, err := c.client.Mkdir(ctx, &rpc.PathsRequest{Paths: paths}) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func (c *Client) Upload(ctx context.Context, dst, src string) (chan FSTransferProgress, error) { | ||||
| func (c *FSClient) ReadDir(ctx context.Context, dir string) ([]FileInfo, error) { | ||||
| 	res, err := c.client.ReadDir(ctx, &rpc.PathRequest{Path: dir}) | ||||
| 	return convertEntries(res.Entries), err | ||||
| } | ||||
|  | ||||
| func convertEntries(e []*rpc.FileInfo) []FileInfo { | ||||
| 	out := make([]FileInfo, len(e)) | ||||
| 	for i, fi := range e { | ||||
| 		out[i] = FileInfo{ | ||||
| 			Name:  fi.Name, | ||||
| 			Size:  fi.Size, | ||||
| 			IsDir: fi.IsDir, | ||||
| 		} | ||||
| 	} | ||||
| 	return out | ||||
| } | ||||
|  | ||||
| func (c *FSClient) Upload(ctx context.Context, dst, src string) (chan FSTransferProgress, error) { | ||||
| 	progressCh := make(chan FSTransferProgress, 5) | ||||
| 	err := c.client.Call( | ||||
| 		ctx, | ||||
| 		"FS", | ||||
| 		"Upload", | ||||
| 		[2]string{dst, src}, | ||||
| 		progressCh, | ||||
| 	) | ||||
| 	tc, err := c.client.Upload(ctx, &rpc.TransferRequest{Source: src, Destination: dst}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	go fsRecvToChannel[rpc.TransferProgress](tc, progressCh, func(evt *rpc.TransferProgress, err error) FSTransferProgress { | ||||
| 		return FSTransferProgress{ | ||||
| 			Sent:  evt.Sent, | ||||
| 			Total: evt.Total, | ||||
| 			Err:   err, | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	return progressCh, nil | ||||
| } | ||||
|  | ||||
| func (c *Client) Download(ctx context.Context, dst, src string) (chan FSTransferProgress, error) { | ||||
| func (c *FSClient) Download(ctx context.Context, dst, src string) (chan FSTransferProgress, error) { | ||||
| 	progressCh := make(chan FSTransferProgress, 5) | ||||
| 	err := c.client.Call( | ||||
| 		ctx, | ||||
| 		"FS", | ||||
| 		"Download", | ||||
| 		[2]string{dst, src}, | ||||
| 		progressCh, | ||||
| 	) | ||||
| 	tc, err := c.client.Download(ctx, &rpc.TransferRequest{Source: src, Destination: dst}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	go fsRecvToChannel[rpc.TransferProgress](tc, progressCh, func(evt *rpc.TransferProgress, err error) FSTransferProgress { | ||||
| 		return FSTransferProgress{ | ||||
| 			Sent:  evt.Sent, | ||||
| 			Total: evt.Total, | ||||
| 			Err:   err, | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	return progressCh, nil | ||||
| } | ||||
|  | ||||
| // fsRecvToChannel converts a DRPC stream client to a Go channel, using cf to convert | ||||
| // RPC generated types to API response types. | ||||
| func fsRecvToChannel[R any, A any](s StreamClient[R], ch chan<- A, cf func(evt *R, err error) A) { | ||||
| 	defer close(ch) | ||||
|  | ||||
| 	var err error | ||||
| 	var evt *R | ||||
|  | ||||
| 	for { | ||||
| 		select { | ||||
| 		case <-s.Context().Done(): | ||||
| 			return | ||||
| 		default: | ||||
| 			evt, err = s.Recv() | ||||
| 			if errors.Is(err, io.EOF) { | ||||
| 				return | ||||
| 			} else if err != nil { | ||||
| 				ch <- cf(new(R), err) | ||||
| 				return | ||||
| 			} | ||||
| 			ch <- cf(evt, nil) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
							
								
								
									
										72
									
								
								api/get.go
									
									
									
									
									
								
							
							
						
						
									
										72
									
								
								api/get.go
									
									
									
									
									
								
							| @@ -3,71 +3,39 @@ package api | ||||
| import ( | ||||
| 	"context" | ||||
|  | ||||
| 	"go.arsenm.dev/infinitime" | ||||
| 	"go.arsenm.dev/itd/internal/rpc" | ||||
| ) | ||||
|  | ||||
| func (c *Client) HeartRate(ctx context.Context) (out uint8, err error) { | ||||
| 	err = c.client.Call( | ||||
| 		ctx, | ||||
| 		"ITD", | ||||
| 		"HeartRate", | ||||
| 		nil, | ||||
| 		&out, | ||||
| 	) | ||||
| 	return | ||||
| func (c *Client) HeartRate(ctx context.Context) (uint8, error) { | ||||
| 	res, err := c.client.HeartRate(ctx, &rpc.Empty{}) | ||||
| 	return uint8(res.Value), err | ||||
| } | ||||
|  | ||||
| func (c *Client) BatteryLevel(ctx context.Context) (out uint8, err error) { | ||||
| 	err = c.client.Call( | ||||
| 		ctx, | ||||
| 		"ITD", | ||||
| 		"BatteryLevel", | ||||
| 		nil, | ||||
| 		&out, | ||||
| 	) | ||||
| 	return | ||||
| func (c *Client) BatteryLevel(ctx context.Context) (uint8, error) { | ||||
| 	res, err := c.client.BatteryLevel(ctx, &rpc.Empty{}) | ||||
| 	return uint8(res.Value), err | ||||
| } | ||||
|  | ||||
| func (c *Client) Motion(ctx context.Context) (out infinitime.MotionValues, err error) { | ||||
| 	err = c.client.Call( | ||||
| 		ctx, | ||||
| 		"ITD", | ||||
| 		"Motion", | ||||
| 		nil, | ||||
| 		&out, | ||||
| 	) | ||||
| 	return | ||||
| type MotionValues struct { | ||||
| 	X, Y, Z int16 | ||||
| } | ||||
|  | ||||
| func (c *Client) Motion(ctx context.Context) (MotionValues, error) { | ||||
| 	res, err := c.client.Motion(ctx, &rpc.Empty{}) | ||||
| 	return MotionValues{int16(res.X), int16(res.Y), int16(res.Z)}, err | ||||
| } | ||||
|  | ||||
| func (c *Client) StepCount(ctx context.Context) (out uint32, err error) { | ||||
| 	err = c.client.Call( | ||||
| 		ctx, | ||||
| 		"ITD", | ||||
| 		"StepCount", | ||||
| 		nil, | ||||
| 		&out, | ||||
| 	) | ||||
| 	return | ||||
| 	res, err := c.client.StepCount(ctx, &rpc.Empty{}) | ||||
| 	return res.Value, err | ||||
| } | ||||
|  | ||||
| func (c *Client) Version(ctx context.Context) (out string, err error) { | ||||
| 	err = c.client.Call( | ||||
| 		ctx, | ||||
| 		"ITD", | ||||
| 		"Version", | ||||
| 		nil, | ||||
| 		&out, | ||||
| 	) | ||||
| 	return | ||||
| 	res, err := c.client.Version(ctx, &rpc.Empty{}) | ||||
| 	return res.Value, err | ||||
| } | ||||
|  | ||||
| func (c *Client) Address(ctx context.Context) (out string, err error) { | ||||
| 	err = c.client.Call( | ||||
| 		ctx, | ||||
| 		"ITD", | ||||
| 		"Address", | ||||
| 		nil, | ||||
| 		&out, | ||||
| 	) | ||||
| 	return | ||||
| 	res, err := c.client.Address(ctx, &rpc.Empty{}) | ||||
| 	return res.Value, err | ||||
| } | ||||
|   | ||||
| @@ -1,16 +1,15 @@ | ||||
| package api | ||||
|  | ||||
| import "context" | ||||
| import ( | ||||
| 	"context" | ||||
|  | ||||
| 	"go.arsenm.dev/itd/internal/rpc" | ||||
| ) | ||||
|  | ||||
| func (c *Client) Notify(ctx context.Context, title, body string) error { | ||||
| 	return c.client.Call( | ||||
| 		ctx, | ||||
| 		"ITD", | ||||
| 		"Notify", | ||||
| 		NotifyData{ | ||||
| 			Title: title, | ||||
| 			Body:  body, | ||||
| 		}, | ||||
| 		nil, | ||||
| 	) | ||||
| 	_, err := c.client.Notify(ctx, &rpc.NotifyRequest{ | ||||
| 		Title: title, | ||||
| 		Body:  body, | ||||
| 	}) | ||||
| 	return err | ||||
| } | ||||
|   | ||||
| @@ -4,23 +4,48 @@ import ( | ||||
| 	"context" | ||||
|  | ||||
| 	"go.arsenm.dev/infinitime" | ||||
| 	"go.arsenm.dev/itd/internal/rpc" | ||||
| ) | ||||
|  | ||||
| type ResourceOperation uint8 | ||||
|  | ||||
| const ( | ||||
| 	ResourceOperationRemoveObsolete = infinitime.ResourceOperationRemoveObsolete | ||||
| 	ResourceOperationUpload         = infinitime.ResourceOperationUpload | ||||
| ) | ||||
|  | ||||
| type ResourceLoadProgress struct { | ||||
| 	Operation ResourceOperation | ||||
| 	Name      string | ||||
| 	Total     int64 | ||||
| 	Sent      int64 | ||||
| 	Err       error | ||||
| } | ||||
|  | ||||
| // LoadResources loads resources onto the watch from the given | ||||
| // file path to the resources zip | ||||
| func (c *Client) LoadResources(ctx context.Context, path string) (<-chan infinitime.ResourceLoadProgress, error) { | ||||
| 	progCh := make(chan infinitime.ResourceLoadProgress) | ||||
| func (c *FSClient) LoadResources(ctx context.Context, path string) (<-chan ResourceLoadProgress, error) { | ||||
| 	progCh := make(chan ResourceLoadProgress, 2) | ||||
|  | ||||
| 	err := c.client.Call( | ||||
| 		ctx, | ||||
| 		"FS", | ||||
| 		"LoadResources", | ||||
| 		path, | ||||
| 		progCh, | ||||
| 	) | ||||
| 	rc, err := c.client.LoadResources(ctx, &rpc.PathRequest{Path: path}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	go fsRecvToChannel[rpc.ResourceLoadProgress](rc, progCh, func(evt *rpc.ResourceLoadProgress, err error) ResourceLoadProgress { | ||||
| 		return ResourceLoadProgress{ | ||||
| 			Operation: ResourceOperation(evt.Operation), | ||||
| 			Name:      evt.Name, | ||||
| 			Sent:      evt.Sent, | ||||
| 			Total:     evt.Total, | ||||
| 			Err:       err, | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	return progCh, nil | ||||
| } | ||||
|  | ||||
| type StreamClient[T any] interface { | ||||
| 	Recv() (*T, error) | ||||
| 	Context() context.Context | ||||
| } | ||||
|   | ||||
							
								
								
									
										11
									
								
								api/set.go
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								api/set.go
									
									
									
									
									
								
							| @@ -3,14 +3,11 @@ package api | ||||
| import ( | ||||
| 	"context" | ||||
| 	"time" | ||||
|  | ||||
| 	"go.arsenm.dev/itd/internal/rpc" | ||||
| ) | ||||
|  | ||||
| func (c *Client) SetTime(ctx context.Context, t time.Time) error { | ||||
| 	return c.client.Call( | ||||
| 		ctx, | ||||
| 		"ITD", | ||||
| 		"SetTime", | ||||
| 		t, | ||||
| 		nil, | ||||
| 	) | ||||
| 	_, err := c.client.SetTime(ctx, &rpc.SetTimeRequest{UnixNano: t.UnixNano()}) | ||||
| 	return err | ||||
| } | ||||
|   | ||||
| @@ -30,6 +30,7 @@ type NotifyData struct { | ||||
| type FSTransferProgress struct { | ||||
| 	Total uint32 | ||||
| 	Sent  uint32 | ||||
| 	Err error | ||||
| } | ||||
|  | ||||
| type FileInfo struct { | ||||
|   | ||||
| @@ -1,13 +1,12 @@ | ||||
| package api | ||||
|  | ||||
| import "context" | ||||
| import ( | ||||
| 	"context" | ||||
|  | ||||
| 	"go.arsenm.dev/itd/internal/rpc" | ||||
| ) | ||||
|  | ||||
| func (c *Client) WeatherUpdate(ctx context.Context) error { | ||||
| 	return c.client.Call( | ||||
| 		ctx, | ||||
| 		"ITD", | ||||
| 		"WeatherUpdate", | ||||
| 		nil, | ||||
| 		nil, | ||||
| 	) | ||||
| 	_, err := c.client.WeatherUpdate(ctx, &rpc.Empty{}) | ||||
| 	return err | ||||
| } | ||||
|   | ||||
							
								
								
									
										126
									
								
								api/watch.go
									
									
									
									
									
								
							
							
						
						
									
										126
									
								
								api/watch.go
									
									
									
									
									
								
							| @@ -3,69 +3,133 @@ package api | ||||
| import ( | ||||
| 	"context" | ||||
|  | ||||
| 	"go.arsenm.dev/infinitime" | ||||
| 	"go.arsenm.dev/itd/internal/rpc" | ||||
| ) | ||||
|  | ||||
| func (c *Client) WatchHeartRate(ctx context.Context) (<-chan uint8, error) { | ||||
| 	outCh := make(chan uint8, 2) | ||||
| 	err := c.client.Call( | ||||
| 		ctx, | ||||
| 		"ITD", | ||||
| 		"WatchHeartRate", | ||||
| 		nil, | ||||
| 		outCh, | ||||
| 	) | ||||
| 	wc, err := c.client.WatchHeartRate(ctx, &rpc.Empty{}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	go func() { | ||||
| 		defer close(outCh) | ||||
|  | ||||
| 		var err error | ||||
| 		var evt *rpc.IntResponse | ||||
|  | ||||
| 		for { | ||||
| 			select { | ||||
| 			case <-ctx.Done(): | ||||
| 				wc.Close() | ||||
| 				return | ||||
| 			default: | ||||
| 				evt, err = wc.Recv() | ||||
| 				if err != nil { | ||||
| 					return | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			outCh <- uint8(evt.Value) | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	return outCh, nil | ||||
| } | ||||
|  | ||||
| func (c *Client) WatchBatteryLevel(ctx context.Context) (<-chan uint8, error) { | ||||
| 	outCh := make(chan uint8, 2) | ||||
| 	err := c.client.Call( | ||||
| 		ctx, | ||||
| 		"ITD", | ||||
| 		"WatchBatteryLevel", | ||||
| 		nil, | ||||
| 		outCh, | ||||
| 	) | ||||
| 	wc, err := c.client.WatchBatteryLevel(ctx, &rpc.Empty{}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	go func() { | ||||
| 		defer close(outCh) | ||||
|  | ||||
| 		var err error | ||||
| 		var evt *rpc.IntResponse | ||||
|  | ||||
| 		for { | ||||
| 			select { | ||||
| 			case <-ctx.Done(): | ||||
| 				wc.Close() | ||||
| 				return | ||||
| 			default: | ||||
| 				evt, err = wc.Recv() | ||||
| 				if err != nil { | ||||
| 					return | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			outCh <- uint8(evt.Value) | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	return outCh, nil | ||||
| } | ||||
|  | ||||
| func (c *Client) WatchStepCount(ctx context.Context) (<-chan uint32, error) { | ||||
| 	outCh := make(chan uint32, 2) | ||||
| 	err := c.client.Call( | ||||
| 		ctx, | ||||
| 		"ITD", | ||||
| 		"WatchStepCount", | ||||
| 		nil, | ||||
| 		outCh, | ||||
| 	) | ||||
| 	wc, err := c.client.WatchStepCount(ctx, &rpc.Empty{}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	go func() { | ||||
| 		defer close(outCh) | ||||
|  | ||||
| 		var err error | ||||
| 		var evt *rpc.IntResponse | ||||
|  | ||||
| 		for { | ||||
| 			select { | ||||
| 			case <-ctx.Done(): | ||||
| 				wc.Close() | ||||
| 				return | ||||
| 			default: | ||||
| 				evt, err = wc.Recv() | ||||
| 				if err != nil { | ||||
| 					return | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			outCh <- evt.Value | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	return outCh, nil | ||||
| } | ||||
|  | ||||
| func (c *Client) WatchMotion(ctx context.Context) (<-chan infinitime.MotionValues, error) { | ||||
| 	outCh := make(chan infinitime.MotionValues, 2) | ||||
| 	err := c.client.Call( | ||||
| 		ctx, | ||||
| 		"ITD", | ||||
| 		"WatchMotion", | ||||
| 		nil, | ||||
| 		outCh, | ||||
| 	) | ||||
| func (c *Client) WatchMotion(ctx context.Context) (<-chan MotionValues, error) { | ||||
| 	outCh := make(chan MotionValues, 2) | ||||
| 	wc, err := c.client.WatchMotion(ctx, &rpc.Empty{}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	go func() { | ||||
| 		defer close(outCh) | ||||
|  | ||||
| 		var err error | ||||
| 		var evt *rpc.MotionResponse | ||||
|  | ||||
| 		for { | ||||
| 			select { | ||||
| 			case <-ctx.Done(): | ||||
| 				wc.Close() | ||||
| 				return | ||||
| 			default: | ||||
| 				evt, err = wc.Recv() | ||||
| 				if err != nil { | ||||
| 					return | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			outCh <- MotionValues{int16(evt.X), int16(evt.Y), int16(evt.Z)} | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	return outCh, nil | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user