92 lines
2.5 KiB
Go
92 lines
2.5 KiB
Go
package v1
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
|
|
"forge.cadoles.com/cadoles/go-emlid/reach/client/protocol"
|
|
"forge.cadoles.com/cadoles/go-emlid/reach/client/protocol/v1/model"
|
|
"forge.cadoles.com/cadoles/go-emlid/reach/client/socketio"
|
|
"github.com/mitchellh/mapstructure"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
const (
|
|
eventGetConfiguration = "get configuration"
|
|
eventCurrentConfiguration = "current configuration"
|
|
eventApplyConfiguration = "apply configuration"
|
|
eventConfigurationApplied = "configuration applied"
|
|
eventResetConfiguration = "reset configuration to default"
|
|
eventSettingsResetToDefault = "settings reset to default"
|
|
)
|
|
|
|
type configurationApplied struct {
|
|
Configuration *model.Configuration `mapstructure:"configuration,omitempty"`
|
|
Result string `mapstructure:"result"`
|
|
Constraints *model.Constraints `mapstructure:"constraints,omitempty"`
|
|
}
|
|
|
|
func (o *Operations) ApplyConfiguration(ctx context.Context, config *model.Configuration) (string, *model.Configuration, error) {
|
|
res := &configurationApplied{}
|
|
if err := o.ReqResp(ctx, eventApplyConfiguration, config, eventConfigurationApplied, res); err != nil {
|
|
return configurationApplyFailed, nil, err
|
|
}
|
|
return res.Result, res.Configuration, nil
|
|
}
|
|
|
|
func (o *Operations) RequestConfiguration(ctx context.Context) (*model.Configuration, error) {
|
|
configuration := &model.Configuration{}
|
|
if err := o.ReqResp(ctx, eventGetConfiguration, nil, eventCurrentConfiguration, configuration); err != nil {
|
|
return nil, err
|
|
}
|
|
return configuration, nil
|
|
}
|
|
|
|
// ReqResp emits an event with the given data and waits for a response
|
|
func (o *Operations) ReqResp(ctx context.Context,
|
|
requestEvent string, requestData any,
|
|
responseEvent string, res any) error {
|
|
o.mutex.RLock()
|
|
defer o.mutex.RUnlock()
|
|
|
|
if o.client == nil || !o.client.Alive() {
|
|
return errors.WithStack(protocol.ErrClosed)
|
|
}
|
|
|
|
var err error
|
|
var wg sync.WaitGroup
|
|
var once sync.Once
|
|
|
|
done := func() {
|
|
o.client.Off(responseEvent)
|
|
wg.Done()
|
|
}
|
|
|
|
wg.Add(1)
|
|
|
|
go func() {
|
|
<-ctx.Done()
|
|
err = ctx.Err()
|
|
once.Do(done)
|
|
}()
|
|
|
|
err = o.client.On(responseEvent, func(_ *socketio.Channel, data interface{}) {
|
|
if res != nil {
|
|
err = mapstructure.WeakDecode(data, res)
|
|
}
|
|
|
|
once.Do(done)
|
|
})
|
|
if err != nil {
|
|
return errors.Wrapf(err, "error while binding to '%s' event", responseEvent)
|
|
}
|
|
|
|
if err = o.client.Emit(requestEvent, requestData); err != nil {
|
|
return errors.Wrapf(err, "error while emitting event '%s'", requestEvent)
|
|
}
|
|
|
|
wg.Wait()
|
|
|
|
return err
|
|
}
|