1
0
Fork 0

Initial API

pull/1/head
Ambrose Chua 2019-04-12 15:11:11 +08:00
parent 3c9b9a538b
commit 586a5de9b3
11 changed files with 618 additions and 11 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
leet

86
draw.go Normal file
View File

@ -0,0 +1,86 @@
package main // import "github.com/serverwentdown/leet"
import (
"log"
ws2811 "github.com/rpi-ws281x/rpi-ws281x-go"
)
// TODO: full-sized grid with multiple channels mapped onto the grid
type Drawer struct {
layers [][]uint32
length int
device *ws2811.WS2811
}
func NewDrawer(length int) (*Drawer, error) {
opt := ws2811.DefaultOptions
opt.Channels[0].LedCount = length
d := &Drawer{}
d.length = length
d.layers = make([][]uint32, 100)
dev, err := ws2811.MakeWS2811(&opt)
if err != nil {
return nil, err
}
err = dev.Init()
if err != nil {
return nil, err
}
d.device = dev
return d, nil
}
func (d *Drawer) SetLayer(layer int32, dots []uint32) {
d.layers[layer] = dots
}
func (d *Drawer) SetLayerOrFill(layer int32, dots []uint32, fill uint32) {
if dots == nil {
fillDots := make([]uint32, d.length)
for i := 0; i < d.length; i++ {
fillDots[i] = fill
}
d.layers[layer] = fillDots
} else {
d.SetLayer(layer, dots)
}
}
func (d *Drawer) Draw() error {
for i := 0; i < len(d.device.Leds(0)); i++ {
dot := mix(d.layers, i)
d.device.Leds(0)[i] = dot
}
if err := d.device.Render(); err != nil {
return err
}
return nil
}
func mix(layers [][]uint32, j int) uint32 {
var base uint32
for i := 0; i < len(layers); i++ {
base = mixColors(base, layers[i][j])
}
return base
}
func mixColors(a uint32, b uint32) uint32 {
// Extract channels
aa, ba := uint32(a>>24), uint32(b>>24)
ar, br := a&uint32(0x00FF0000)>>16, b&uint32(0x00FF0000)>>16
ag, bg := a&uint32(0x0000FF00)>>8, b&uint32(0x0000FF00)>>8
ab, bb := a&uint32(0x000000FF), b&uint32(0x000000FF)
// Apply alpha computation to each channel
log.Println(aa, ar, ag, ab, ba, br, bg, bb)
oa := uint32(ba*(255-aa)/255 + aa)
or := uint32(br*ba*(255-aa)/(255*255) + ar*aa/255)
og := uint32(bg*ba*(255-aa)/(255*255) + ag*aa/255)
ob := uint32(bb*ba*(255-aa)/(255*255) + ab*aa/255)
return (oa << 24) | (or << 16) | (og << 8) | ob
}

18
draw_test.go Normal file
View File

@ -0,0 +1,18 @@
package main
import "testing"
func TestMixColors(t *testing.T) {
mixed := mixColors(uint32(0), uint32(0xFFFF0000))
if mixed != uint32(0xFFFF0000) {
t.Errorf("mixColors(0, 0xFFFF0000) was incorrect, got: %#x, want: %#x", mixed, uint32(0xFFFF0000))
}
mixed = mixColors(uint32(0), uint32(0))
if mixed != uint32(0) {
t.Errorf("mixColors(0, 0) was incorrect, got: %#x, want: %#x", mixed, uint32(0))
}
mixed = mixColors(uint32(0x7FFF0000), uint32(0x7F00FF00))
if mixed != uint32(0xbe7f3f00) {
t.Errorf("mixColors(0x7FFF0000, 0x7F00FF00) was incorrect, got: %#x, want: %#x", mixed, uint32(0xbe7f3f00))
}
}

View File

@ -1,5 +0,0 @@
package main // import "github.com/serverwentdown/leet"
import (
ws2811 "github.com/rpi-ws281x/rpi-ws281x-go"
)

View File

@ -0,0 +1,400 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: framebuffer.proto
package framebuffer
import (
context "context"
fmt "fmt"
proto "github.com/golang/protobuf/proto"
grpc "google.golang.org/grpc"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type Layer int32
const (
Layer_NONE Layer = 0
// Well-known layers
Layer_LIGHT Layer = 10
Layer_COLOR Layer = 20
Layer_NOTIFICATIONS Layer = 90
// Public layers
Layer_GENERAL_0 Layer = 40
Layer_GENERAL_1 Layer = 41
Layer_GENERAL_2 Layer = 42
Layer_GENERAL_3 Layer = 43
Layer_GENERAL_4 Layer = 44
Layer_GENERAL_5 Layer = 45
Layer_GENERAL_6 Layer = 46
Layer_GENERAL_7 Layer = 47
Layer_GENERAL_8 Layer = 48
Layer_GENERAL_9 Layer = 49
)
var Layer_name = map[int32]string{
0: "NONE",
10: "LIGHT",
20: "COLOR",
90: "NOTIFICATIONS",
40: "GENERAL_0",
41: "GENERAL_1",
42: "GENERAL_2",
43: "GENERAL_3",
44: "GENERAL_4",
45: "GENERAL_5",
46: "GENERAL_6",
47: "GENERAL_7",
48: "GENERAL_8",
49: "GENERAL_9",
}
var Layer_value = map[string]int32{
"NONE": 0,
"LIGHT": 10,
"COLOR": 20,
"NOTIFICATIONS": 90,
"GENERAL_0": 40,
"GENERAL_1": 41,
"GENERAL_2": 42,
"GENERAL_3": 43,
"GENERAL_4": 44,
"GENERAL_5": 45,
"GENERAL_6": 46,
"GENERAL_7": 47,
"GENERAL_8": 48,
"GENERAL_9": 49,
}
func (x Layer) String() string {
return proto.EnumName(Layer_name, int32(x))
}
func (Layer) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_4476fbda566a3634, []int{0}
}
type FrameData struct {
// ARGB
Dots []uint32 `protobuf:"fixed32,1,rep,packed,name=dots,proto3" json:"dots,omitempty"`
Fill uint32 `protobuf:"fixed32,2,opt,name=fill,proto3" json:"fill,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *FrameData) Reset() { *m = FrameData{} }
func (m *FrameData) String() string { return proto.CompactTextString(m) }
func (*FrameData) ProtoMessage() {}
func (*FrameData) Descriptor() ([]byte, []int) {
return fileDescriptor_4476fbda566a3634, []int{0}
}
func (m *FrameData) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_FrameData.Unmarshal(m, b)
}
func (m *FrameData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_FrameData.Marshal(b, m, deterministic)
}
func (m *FrameData) XXX_Merge(src proto.Message) {
xxx_messageInfo_FrameData.Merge(m, src)
}
func (m *FrameData) XXX_Size() int {
return xxx_messageInfo_FrameData.Size(m)
}
func (m *FrameData) XXX_DiscardUnknown() {
xxx_messageInfo_FrameData.DiscardUnknown(m)
}
var xxx_messageInfo_FrameData proto.InternalMessageInfo
func (m *FrameData) GetDots() []uint32 {
if m != nil {
return m.Dots
}
return nil
}
func (m *FrameData) GetFill() uint32 {
if m != nil {
return m.Fill
}
return 0
}
type FrameBuffer struct {
Frame *FrameData `protobuf:"bytes,1,opt,name=frame,proto3" json:"frame,omitempty"`
Timestamp uint32 `protobuf:"fixed32,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
Layer Layer `protobuf:"varint,4,opt,name=layer,proto3,enum=Layer" json:"layer,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *FrameBuffer) Reset() { *m = FrameBuffer{} }
func (m *FrameBuffer) String() string { return proto.CompactTextString(m) }
func (*FrameBuffer) ProtoMessage() {}
func (*FrameBuffer) Descriptor() ([]byte, []int) {
return fileDescriptor_4476fbda566a3634, []int{1}
}
func (m *FrameBuffer) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_FrameBuffer.Unmarshal(m, b)
}
func (m *FrameBuffer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_FrameBuffer.Marshal(b, m, deterministic)
}
func (m *FrameBuffer) XXX_Merge(src proto.Message) {
xxx_messageInfo_FrameBuffer.Merge(m, src)
}
func (m *FrameBuffer) XXX_Size() int {
return xxx_messageInfo_FrameBuffer.Size(m)
}
func (m *FrameBuffer) XXX_DiscardUnknown() {
xxx_messageInfo_FrameBuffer.DiscardUnknown(m)
}
var xxx_messageInfo_FrameBuffer proto.InternalMessageInfo
func (m *FrameBuffer) GetFrame() *FrameData {
if m != nil {
return m.Frame
}
return nil
}
func (m *FrameBuffer) GetTimestamp() uint32 {
if m != nil {
return m.Timestamp
}
return 0
}
func (m *FrameBuffer) GetLayer() Layer {
if m != nil {
return m.Layer
}
return Layer_NONE
}
type FrameSequence struct {
Frames []*FrameBuffer `protobuf:"bytes,1,rep,name=frames,proto3" json:"frames,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *FrameSequence) Reset() { *m = FrameSequence{} }
func (m *FrameSequence) String() string { return proto.CompactTextString(m) }
func (*FrameSequence) ProtoMessage() {}
func (*FrameSequence) Descriptor() ([]byte, []int) {
return fileDescriptor_4476fbda566a3634, []int{2}
}
func (m *FrameSequence) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_FrameSequence.Unmarshal(m, b)
}
func (m *FrameSequence) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_FrameSequence.Marshal(b, m, deterministic)
}
func (m *FrameSequence) XXX_Merge(src proto.Message) {
xxx_messageInfo_FrameSequence.Merge(m, src)
}
func (m *FrameSequence) XXX_Size() int {
return xxx_messageInfo_FrameSequence.Size(m)
}
func (m *FrameSequence) XXX_DiscardUnknown() {
xxx_messageInfo_FrameSequence.DiscardUnknown(m)
}
var xxx_messageInfo_FrameSequence proto.InternalMessageInfo
func (m *FrameSequence) GetFrames() []*FrameBuffer {
if m != nil {
return m.Frames
}
return nil
}
type DrawResponse struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *DrawResponse) Reset() { *m = DrawResponse{} }
func (m *DrawResponse) String() string { return proto.CompactTextString(m) }
func (*DrawResponse) ProtoMessage() {}
func (*DrawResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_4476fbda566a3634, []int{3}
}
func (m *DrawResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DrawResponse.Unmarshal(m, b)
}
func (m *DrawResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_DrawResponse.Marshal(b, m, deterministic)
}
func (m *DrawResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_DrawResponse.Merge(m, src)
}
func (m *DrawResponse) XXX_Size() int {
return xxx_messageInfo_DrawResponse.Size(m)
}
func (m *DrawResponse) XXX_DiscardUnknown() {
xxx_messageInfo_DrawResponse.DiscardUnknown(m)
}
var xxx_messageInfo_DrawResponse proto.InternalMessageInfo
func init() {
proto.RegisterEnum("Layer", Layer_name, Layer_value)
proto.RegisterType((*FrameData)(nil), "FrameData")
proto.RegisterType((*FrameBuffer)(nil), "FrameBuffer")
proto.RegisterType((*FrameSequence)(nil), "FrameSequence")
proto.RegisterType((*DrawResponse)(nil), "DrawResponse")
}
func init() { proto.RegisterFile("framebuffer.proto", fileDescriptor_4476fbda566a3634) }
var fileDescriptor_4476fbda566a3634 = []byte{
// 349 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x92, 0x4f, 0x6f, 0xaa, 0x40,
0x14, 0xc5, 0xe5, 0x29, 0xbc, 0xc7, 0x55, 0xcc, 0x78, 0xf3, 0x16, 0xe4, 0xc5, 0x05, 0x21, 0x6f,
0x41, 0x6d, 0xa5, 0x8a, 0xb5, 0x7f, 0x96, 0xd6, 0x7f, 0x25, 0x21, 0x90, 0x8c, 0xae, 0xba, 0x69,
0xd0, 0x0e, 0x89, 0xa9, 0x8a, 0x05, 0x4c, 0xd3, 0x6f, 0xd9, 0x8f, 0xd4, 0xcc, 0xd8, 0xd8, 0x31,
0xdd, 0x9d, 0xdf, 0xb9, 0x97, 0x93, 0xcb, 0xc9, 0x40, 0x23, 0xc9, 0xe2, 0x0d, 0x5b, 0xec, 0x93,
0x84, 0x65, 0xee, 0x2e, 0x4b, 0x8b, 0xd4, 0xee, 0x81, 0x3e, 0xe1, 0xe6, 0x28, 0x2e, 0x62, 0x44,
0xa8, 0x3c, 0xa7, 0x45, 0x6e, 0x2a, 0x56, 0xd9, 0xf9, 0x4d, 0x85, 0xe6, 0x5e, 0xb2, 0x5a, 0xaf,
0xcd, 0x5f, 0x96, 0xc2, 0x3d, 0xae, 0xed, 0x17, 0xa8, 0x8a, 0x8f, 0xee, 0x45, 0x12, 0x5a, 0xa0,
0x8a, 0x60, 0x53, 0xb1, 0x14, 0xa7, 0xea, 0x81, 0x7b, 0x4c, 0xa4, 0x87, 0x01, 0x36, 0x41, 0x2f,
0x56, 0x1b, 0x96, 0x17, 0xf1, 0x66, 0x67, 0x96, 0x45, 0xd2, 0xb7, 0x81, 0x4d, 0x50, 0xd7, 0xf1,
0x3b, 0xcb, 0xcc, 0x8a, 0xa5, 0x38, 0x75, 0x4f, 0x73, 0x03, 0x4e, 0xf4, 0x60, 0xda, 0x7d, 0x30,
0x44, 0xde, 0x8c, 0xbd, 0xee, 0xd9, 0x76, 0xc9, 0xf0, 0x3f, 0x68, 0x22, 0xf5, 0x70, 0x67, 0xd5,
0xab, 0xb9, 0xd2, 0x31, 0xf4, 0x6b, 0x66, 0xd7, 0xa1, 0x36, 0xca, 0xe2, 0x37, 0xca, 0xf2, 0x5d,
0xba, 0xcd, 0x59, 0xeb, 0x43, 0x01, 0x55, 0xe4, 0xe2, 0x1f, 0xa8, 0x84, 0x51, 0x38, 0x26, 0x25,
0xd4, 0x41, 0x0d, 0xfc, 0xe9, 0xc3, 0x9c, 0x00, 0x97, 0xc3, 0x28, 0x88, 0x28, 0xf9, 0x8b, 0x0d,
0x30, 0xc2, 0x68, 0xee, 0x4f, 0xfc, 0xe1, 0x60, 0xee, 0x47, 0xe1, 0x8c, 0x3c, 0xa2, 0x01, 0xfa,
0x74, 0x1c, 0x8e, 0xe9, 0x20, 0x78, 0xea, 0x10, 0x47, 0xc6, 0x2e, 0x39, 0x93, 0xd1, 0x23, 0x2d,
0x19, 0x7b, 0xe4, 0x5c, 0xc6, 0x2b, 0x72, 0x21, 0x63, 0x9f, 0xb4, 0x65, 0xbc, 0x26, 0xae, 0x8c,
0x37, 0xe4, 0x52, 0xc6, 0x5b, 0xd2, 0x91, 0xf1, 0x8e, 0x74, 0xbd, 0x25, 0x68, 0xfc, 0x17, 0x59,
0x86, 0x2d, 0xd0, 0xb9, 0x12, 0x3d, 0xe0, 0x49, 0x1f, 0xff, 0x0c, 0x57, 0xae, 0xc1, 0x2e, 0x61,
0x1b, 0xe0, 0xb8, 0x9b, 0x63, 0xdd, 0x3d, 0x29, 0xf7, 0xc7, 0xfa, 0x42, 0x13, 0xef, 0xa4, 0xf7,
0x19, 0x00, 0x00, 0xff, 0xff, 0xb6, 0x99, 0xbe, 0xf0, 0x3c, 0x02, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// DrawerClient is the client API for Drawer service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type DrawerClient interface {
DrawFrame(ctx context.Context, in *FrameBuffer, opts ...grpc.CallOption) (*DrawResponse, error)
DrawFrames(ctx context.Context, in *FrameSequence, opts ...grpc.CallOption) (*DrawResponse, error)
}
type drawerClient struct {
cc *grpc.ClientConn
}
func NewDrawerClient(cc *grpc.ClientConn) DrawerClient {
return &drawerClient{cc}
}
func (c *drawerClient) DrawFrame(ctx context.Context, in *FrameBuffer, opts ...grpc.CallOption) (*DrawResponse, error) {
out := new(DrawResponse)
err := c.cc.Invoke(ctx, "/Drawer/DrawFrame", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *drawerClient) DrawFrames(ctx context.Context, in *FrameSequence, opts ...grpc.CallOption) (*DrawResponse, error) {
out := new(DrawResponse)
err := c.cc.Invoke(ctx, "/Drawer/DrawFrames", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// DrawerServer is the server API for Drawer service.
type DrawerServer interface {
DrawFrame(context.Context, *FrameBuffer) (*DrawResponse, error)
DrawFrames(context.Context, *FrameSequence) (*DrawResponse, error)
}
func RegisterDrawerServer(s *grpc.Server, srv DrawerServer) {
s.RegisterService(&_Drawer_serviceDesc, srv)
}
func _Drawer_DrawFrame_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(FrameBuffer)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(DrawerServer).DrawFrame(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/Drawer/DrawFrame",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(DrawerServer).DrawFrame(ctx, req.(*FrameBuffer))
}
return interceptor(ctx, in, info, handler)
}
func _Drawer_DrawFrames_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(FrameSequence)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(DrawerServer).DrawFrames(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/Drawer/DrawFrames",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(DrawerServer).DrawFrames(ctx, req.(*FrameSequence))
}
return interceptor(ctx, in, info, handler)
}
var _Drawer_serviceDesc = grpc.ServiceDesc{
ServiceName: "Drawer",
HandlerType: (*DrawerServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "DrawFrame",
Handler: _Drawer_DrawFrame_Handler,
},
{
MethodName: "DrawFrames",
Handler: _Drawer_DrawFrames_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "framebuffer.proto",
}

View File

@ -0,0 +1,45 @@
syntax = "proto3";
enum Layer {
NONE = 0;
// Well-known layers
LIGHT = 10;
COLOR = 20;
NOTIFICATIONS = 90;
// Public layers
GENERAL_0 = 40;
GENERAL_1 = 41;
GENERAL_2 = 42;
GENERAL_3 = 43;
GENERAL_4 = 44;
GENERAL_5 = 45;
GENERAL_6 = 46;
GENERAL_7 = 47;
GENERAL_8 = 48;
GENERAL_9 = 49;
}
message FrameData {
// ARGB
repeated fixed32 dots = 1;
fixed32 fill = 2;
}
message FrameBuffer {
FrameData frame = 1;
fixed32 timestamp = 3;
Layer layer = 4;
}
message FrameSequence {
repeated FrameBuffer frames = 1;
}
message DrawResponse {
}
service Drawer {
rpc DrawFrame (FrameBuffer) returns (DrawResponse) {}
rpc DrawFrames (FrameSequence) returns (DrawResponse) {}
}

View File

@ -10,11 +10,11 @@ git clone https://github.com/jgarff/rpi_ws281x /tmp/rpi_ws281x
echo "Building ws281x"
cd /tmp/rpi_ws281x
scons deb
scons
echo "Installing package"
sudo dpkg --purge libws2811 || true
sudo dpkg -i libws2811*.deb
echo "Installing into /usr/local"
sudo cp libws2811.a /usr/local/lib
sudo cp ws2811.h pwm.h rpihw.h /usr/local/include
echo "Cleaning up"
cd /tmp

5
go.mod
View File

@ -2,7 +2,10 @@ module github.com/serverwentdown/leet
go 1.12
replace github.com/rpi-ws281x/rpi-ws281x-go => github.com/serverwentdown/rpi-ws281x-go v1.0.4
require (
github.com/rpi-ws281x/rpi-ws281x-go v1.0.3
github.com/golang/protobuf v1.3.1
github.com/rpi-ws281x/rpi-ws281x-go v0.0.0-00010101000000-000000000000
google.golang.org/grpc v1.19.1
)

4
go.sum
View File

@ -5,10 +5,14 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/rpi-ws281x/rpi-ws281x-go v1.0.3 h1:mp3eVMYTuaH1cTmnzo5nKSCrQfYTx7pkG7Jxxdl+aZc=
github.com/rpi-ws281x/rpi-ws281x-go v1.0.3/go.mod h1:NJ9ZCa/NPRHHb841qr+G9IEJe1J4aOgBMwkf9xyDnmk=
github.com/serverwentdown/rpi-ws281x-go v1.0.4 h1:Ti+oxrYcU/lp0NjBl/y0EMcJp9gqvKJka2zFSCM2r2c=
github.com/serverwentdown/rpi-ws281x-go v1.0.4/go.mod h1:NJ9ZCa/NPRHHb841qr+G9IEJe1J4aOgBMwkf9xyDnmk=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d h1:g9qWBGx4puODJTMVyoPrpoxPFgVGd+z1DZwjfRu4d0I=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=

22
main.go
View File

@ -2,11 +2,31 @@ package main // import "github.com/serverwentdown/leet"
import (
"log"
"net"
"github.com/serverwentdown/leet/framebuffer"
"google.golang.org/grpc"
)
const listen = ":5000"
const length = 287
func main() {
log.Print("starting server")
_ := grpc.NewServer()
lis, err := net.Listen("tcp", listen)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
drawer, err := NewDrawer(287)
if err != nil {
log.Fatalf("failed to setup WS281x library: %v", err)
}
framebuffer.RegisterDrawerServer(s, NewServer(drawer))
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}

35
server.go Normal file
View File

@ -0,0 +1,35 @@
package main // import "github.com/serverwentdown/leet"
//go:generate protoc -I framebuffer framebuffer/framebuffer.proto --go_out=plugins=grpc:framebuffer
import (
"context"
"log"
"github.com/serverwentdown/leet/framebuffer"
)
type Server struct {
drawer *Drawer
}
func NewServer(drawer *Drawer) *Server {
s := &Server{
drawer: drawer,
}
return s
}
func (s *Server) DrawFrame(ctx context.Context, in *framebuffer.FrameBuffer) (*framebuffer.DrawResponse, error) {
s.drawer.SetLayerOrFill(int32(in.Layer), in.Frame.Dots, in.Frame.Fill)
err := s.drawer.Draw()
if err != nil {
return nil, err
}
return &framebuffer.DrawResponse{}, nil
}
func (s *Server) DrawFrames(ctx context.Context, in *framebuffer.FrameSequence) (*framebuffer.DrawResponse, error) {
log.Print("Received FrameSequence, but not implemented")
return &framebuffer.DrawResponse{}, nil
}