$darkmode
transition_event.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2020 Robert Bosch GmbH
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * SPDX-License-Identifier: Apache-2.0
17  */
64 #pragma once
65 #ifndef CLOE_TRIGGER_TRANSITION_EVENT_HPP_
66 #define CLOE_TRIGGER_TRANSITION_EVENT_HPP_
67 
68 #include <string> // for string
69 
70 #include <cloe/registrar.hpp> // for DirectCallback
71 #include <cloe/trigger.hpp> // for Event, EventFactory
72 
73 namespace cloe {
74 namespace events {
75 
76 template <typename T>
77 class Transition : public Event {
78  public:
79  Transition(const std::string& name, T from, T to)
80  : Event(name), from_(from), to_(to), ready_(false) {}
81  Transition(const Transition<T>&) = delete;
82  Transition(Transition<T>&&) = delete;
83  ~Transition() = default;
84 
85  EventPtr clone() const override { return std::make_unique<Transition<T>>(name(), from_, to_); }
86 
87  bool operator()(const Sync&, T x) {
88  if (ready_) {
89  // Previous state: from
90  if (x == to_) {
91  // State change: from -> to
92  ready_ = false;
93  return true;
94  } else if (x != from_) {
95  // State change: from -> !from
96  ready_ = false;
97  }
98  return false;
99  } else {
100  // Previous state: !from
101  if (x == from_) {
102  ready_ = true;
103  }
104  return false;
105  }
106  }
107 
108  void to_json(Json& j) const override {
109  j = Json{
110  {"from", from_},
111  {"to", to_},
112  };
113  }
114 
115  private:
116  bool ready_;
117  T from_;
118  T to_;
119 };
120 
121 template <typename T>
123  public:
124  using EventType = Transition<T>;
125  TransitionFactory(const std::string& name, const std::string& desc) : EventFactory(name, desc) {}
126 
127  TriggerSchema schema() const override {
128  using namespace fable::schema; // NOLINT(build/namespaces)
129  static const char* desc = "transition between one state and another";
130  return TriggerSchema{
131  name(),
132  description(),
133  InlineSchema(desc, "transition", true),
134  {
135  {"from", make_prototype<T>().description("from state").require()},
136  {"to", make_prototype<T>().description("destination state").require()},
137  },
138  };
139  }
140 
141  EventPtr make(const Conf& c) const override {
142  try {
143  auto from = c.get<T>("from");
144  auto to = c.get<T>("to");
145  return std::make_unique<Transition<T>>(name(), from, to);
146  } catch (std::exception& e) {
147  throw TriggerInvalid(c, e.what());
148  }
149  }
150 
151  EventPtr make(const std::string& s) const override {
152  auto sep = s.find("->");
153  if (sep == std::string::npos) {
154  throw TriggerInvalid(Conf{Json{s}}, "expected format N->M");
155  }
156  // Unfortunately, there's no nice way to do this in C++:
157  auto from = Json{s.substr(0, sep)}.get<T>();
158  auto to = Json{s.substr(sep + 2)}.get<T>();
159  return make(Conf{Json{
160  {"from", from},
161  {"to", to},
162  }});
163  }
164 };
165 
166 template <typename T>
168 
169 } // namespace events
170 } // namespace cloe
171 
172 #endif // CLOE_TRIGGER_TRANSITION_EVENT_HPP_
Definition: conf.hpp:74
Definition: registrar.hpp:45
EventPtr clone() const override
Definition: transition_event.hpp:85
Definition: trigger.hpp:73
Definition: array.hpp:39
Definition: transition_event.hpp:122
T get() const
Definition: conf.hpp:164
Definition: sync.hpp:35
EventPtr make(const Conf &c) const override
Definition: transition_event.hpp:141
Definition: coordinator.hpp:36
Definition: trigger.hpp:487
TriggerSchema schema() const override
Definition: transition_event.hpp:127
Definition: transition_event.hpp:77
Definition: trigger.hpp:300
std::string name() const
Definition: entity.hpp:68
std::string description() const
Definition: entity.hpp:91
void to_json(Json &j) const override
Definition: transition_event.hpp:108
Definition: trigger.hpp:87
EventPtr make(const std::string &s) const override
Definition: transition_event.hpp:151
Definition: trigger.hpp:207