package daemon import ( "context" "fmt" "src.dualinventive.com/go/devsim" "src.dualinventive.com/go/devsim/simulator" ) type simulatorClient struct { c devsim.SimulatorServiceClient } var _ simulator.Service = &simulatorClient{} type simulatorClientInfo struct { rep *devsim.SimulatorInfo } var _ simulator.Info = &simulatorClientInfo{} func (sci *simulatorClientInfo) DeviceUID() string { return sci.rep.DeviceUID } func (sci *simulatorClientInfo) Author() string { return sci.rep.Author } func (sci *simulatorClientInfo) Version() string { return sci.rep.Version } func (sci *simulatorClientInfo) Path() string { return "" } func (sci *simulatorClientInfo) Key() string { return sci.rep.Key } func (sci *simulatorClientInfo) Name() string { return sci.rep.Name } type simulatorClientObj struct { simulator.Info deviceUID string c *simulatorClient } func (sco *simulatorClientObj) Start() error { return sco.c.Start(sco.DeviceUID()) } func (sco *simulatorClientObj) Stop() error { return sco.c.Stop(sco.DeviceUID()) } // List return the current managed simulators func (sc *simulatorClient) List() []simulator.Simulator { simList, err := sc.list("") if err != nil { return nil } return simList } func (sc *simulatorClient) list(deviceUID string) ([]simulator.Simulator, error) { infoC, err := sc.c.Info(context.TODO(), &devsim.SimulatorRequest{DeviceUID: deviceUID}) if err != nil { return nil, err } var simList []simulator.Simulator for { rep, err := infoC.Recv() if err != nil { break } sim := &simulatorClientObj{Info: &simulatorClientInfo{rep: rep}, deviceUID: rep.DeviceUID, c: sc} simList = append(simList, sim) } return simList, nil } // Add adds a new simulator in the list of managed simulators. The simulator is prepared to start, but is // not started yet. func (sc *simulatorClient) Add(uri string, version string) (simulator.Info, error) { rep, err := sc.c.Create(context.TODO(), &devsim.SimulatorCreateRequest{Uri: uri, Version: version}) if err != nil { return nil, err } return &simulatorClientInfo{rep: &devsim.SimulatorInfo{DeviceUID: rep.DeviceUID}}, err } // Get returns the simulator with the given deviceUID or an ErrNotFound it returned when the simulator is // not found. func (sc *simulatorClient) Get(deviceUID string) (simulator.Simulator, error) { simList, err := sc.list(deviceUID) if err != nil { return nil, err } if len(simList) == 0 { return nil, fmt.Errorf("not found") } return simList[0], nil } // Remove removes the simulator of the list of managed simulators. This simulator must be stopped in order // to succeeds. An ErrNotFound is returned when the simulator is not found. An ErrNotStopped is returned when the // simulator is still running. func (sc *simulatorClient) Remove(deviceUID string) error { _, err := sc.c.Remove(context.TODO(), &devsim.SimulatorRequest{DeviceUID: deviceUID}) return err } // Start starts the simulator with the given deviceUID. An ErrNotFound is returned when the simulator is // not found. An ErrAlreadyRunning is returned when the simulator is already running. func (sc *simulatorClient) Start(deviceUID string) error { _, err := sc.c.Start(context.TODO(), &devsim.SimulatorRequest{DeviceUID: deviceUID}) return err } // Stop stops the simulator with the given deviceUID. An ErrNotFound is returned when the simulator is // not found. An ErrAlreadyStopped is returned when the simulator is already stopped. func (sc *simulatorClient) Stop(deviceUID string) error { _, err := sc.c.Stop(context.TODO(), &devsim.SimulatorRequest{DeviceUID: deviceUID}) return err }