-
Notifications
You must be signed in to change notification settings - Fork 2
/
channel.go
148 lines (114 loc) · 3.71 KB
/
channel.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package multicam
// #include <multicam.h>
// #include <stdlib.h>
/*
extern void GoCallbackHandler(MCCALLBACKINFO* info);
static void MCCallbackHandler(MCCALLBACKINFO* info)
{
GoCallbackHandler(info);
}
static MCSTATUS SetCallbackHandler(MCHANDLE handle, PVOID context)
{
return McRegisterCallback(handle, MCCallbackHandler, context);
}
static MCSTATUS WaitSignal(MCHANDLE handle, MCSIGNAL signal, uint timeout, MCSIGNALINFO* info)
{
return McWaitSignal(handle, signal, timeout, info);
}
*/
import "C"
import "fmt"
const UninitializedChannel = 0
type CallbackInfo C.MCCALLBACKINFO
var channelCallbackHandlers map[int]func(*CallbackInfo)
func initChannels() {
channelCallbackHandlers = make(map[int]func(*CallbackInfo))
}
type Channel struct {
channel Handle
handler func(*CallbackInfo)
}
// NewChannel creates a new Multicam Channel.
func NewChannel() *Channel {
return &Channel{}
}
// Create creates a new MultiCam Channel object.
func (c *Channel) Create() error {
if c.channel != UninitializedChannel {
return ErrInvalidChannel
}
var ch C.uint
status := StatusCode(C.McCreate(C.MC_CHANNEL, &ch))
if status != StatusOK {
return fmt.Errorf("%s: %w", status.String(), ErrCannotCreateChannel)
}
c.channel = Handle(ch)
return nil
}
// Delete deletes an existing MultiCam Channel object.
func (c *Channel) Delete() error {
if c.channel == UninitializedChannel {
return ErrInvalidChannel
}
status := StatusCode(C.McDelete(C.uint(c.channel)))
if status != StatusOK {
return fmt.Errorf("%s: %w", status.String(), ErrCannotDeleteChannel)
}
return nil
}
// SetParamStr sets a parameter string value for this channel.
func (c *Channel) SetParamStr(id ParamID, val string) error {
return SetParamStr(c.channel, id, val)
}
// GetParamStr gets a parameter string value for this channel.
func (c *Channel) GetParamStr(id ParamID) (string, error) {
return GetParamStr(c.channel, id)
}
// SetParamInt sets a parameter int value for this channel.
func (c *Channel) SetParamInt(id ParamID, val int) error {
return SetParamInt(c.channel, id, val)
}
// GetParamInt gets a parameter int value for this channel.
func (c *Channel) GetParamInt(id ParamID) (int, error) {
return GetParamInt(c.channel, id)
}
// SetParamInst sets a parameter instance value for this channel.
func (c *Channel) SetParamInst(id ParamID, val Handle) error {
return SetParamInst(c.channel, id, val)
}
// GetParamInst gets a parameter instance value for this channel.
func (c *Channel) GetParamInst(id ParamID) (Handle, error) {
return GetParamInst(c.channel, id)
}
// RegisterCallback allows setting a callback handler function for this channel.
// TODO(re): allow setting context data
func (c *Channel) RegisterCallback(handler func(*CallbackInfo)) error {
c.handler = handler
status := StatusCode(C.SetCallbackHandler(C.uint(c.channel), C.PVOID(nil)))
if status != StatusOK {
return fmt.Errorf("%s: %w", status.String(), ErrCannotRegisterCallback)
}
channelCallbackHandlers[int(c.channel)] = handler
return nil
}
//export GoCallbackHandler
func GoCallbackHandler(info *CallbackInfo) {
if len(channelCallbackHandlers) == 0 {
return
}
if cb, ok := channelCallbackHandlers[int(info.Instance)]; ok {
cb(info)
return
}
return
}
// WaitSignal waits until a specific signal for this channel has occurred, or the timeout in ms is reached.
// On success, a pointer to the SignalInfo for this signal will be returned.
func (c *Channel) WaitSignal(signal ParamID, timeout int) (*SignalInfo, error) {
var info SignalInfo
status := StatusCode(C.WaitSignal(C.MCHANDLE(c.channel), C.MCSIGNAL(signal), C.uint(timeout), &(info.data)))
if status != StatusOK {
return nil, fmt.Errorf("%s: %w", status.String(), ErrCannotWaitSignal)
}
return &info, nil
}