aboutsummaryrefslogtreecommitdiff
path: root/osp/impl/service_publisher_impl.cc
blob: 8a984969dea640d6934fb91f48c1a5c6162e85c9 (plain)
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
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "osp/impl/service_publisher_impl.h"

#include <utility>

#include "util/osp_logging.h"

namespace openscreen {
namespace osp {
namespace {

bool IsTransitionValid(ServicePublisher::State from,
                       ServicePublisher::State to) {
  using State = ServicePublisher::State;
  switch (from) {
    case State::kStopped:
      return to == State::kStarting || to == State::kStopping;
    case State::kStarting:
      return to == State::kRunning || to == State::kStopping ||
             to == State::kSuspended;
    case State::kRunning:
      return to == State::kSuspended || to == State::kStopping;
    case State::kStopping:
      return to == State::kStopped;
    case State::kSuspended:
      return to == State::kRunning || to == State::kStopping;
    default:
      OSP_DCHECK(false) << "unknown State value: " << static_cast<int>(from);
      break;
  }
  return false;
}

}  // namespace

ServicePublisherImpl::Delegate::Delegate() = default;
ServicePublisherImpl::Delegate::~Delegate() = default;

void ServicePublisherImpl::Delegate::SetPublisherImpl(
    ServicePublisherImpl* publisher) {
  OSP_DCHECK(!publisher_);
  publisher_ = publisher;
}

ServicePublisherImpl::ServicePublisherImpl(Observer* observer,
                                           std::unique_ptr<Delegate> delegate)
    : ServicePublisher(observer), delegate_(std::move(delegate)) {
  delegate_->SetPublisherImpl(this);
}

ServicePublisherImpl::~ServicePublisherImpl() = default;

bool ServicePublisherImpl::Start() {
  if (state_ != State::kStopped)
    return false;
  state_ = State::kStarting;
  delegate_->StartPublisher(config_);
  return true;
}
bool ServicePublisherImpl::StartAndSuspend() {
  if (state_ != State::kStopped)
    return false;
  state_ = State::kStarting;
  delegate_->StartAndSuspendPublisher(config_);
  return true;
}
bool ServicePublisherImpl::Stop() {
  if (state_ == State::kStopped || state_ == State::kStopping)
    return false;

  state_ = State::kStopping;
  delegate_->StopPublisher();
  return true;
}
bool ServicePublisherImpl::Suspend() {
  if (state_ != State::kRunning && state_ != State::kStarting)
    return false;

  delegate_->SuspendPublisher();
  return true;
}
bool ServicePublisherImpl::Resume() {
  if (state_ != State::kSuspended)
    return false;

  delegate_->ResumePublisher(config_);
  return true;
}

void ServicePublisherImpl::SetState(State state) {
  OSP_DCHECK(IsTransitionValid(state_, state));
  state_ = state;
  if (observer_)
    MaybeNotifyObserver();
}

void ServicePublisherImpl::MaybeNotifyObserver() {
  OSP_DCHECK(observer_);
  switch (state_) {
    case State::kRunning:
      observer_->OnStarted();
      break;
    case State::kStopped:
      observer_->OnStopped();
      break;
    case State::kSuspended:
      observer_->OnSuspended();
      break;
    default:
      break;
  }
}

}  // namespace osp
}  // namespace openscreen