$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 
66 #include <string> // for string
67 
68 #include <cloe/registrar.hpp> // for DirectCallback
69 #include <cloe/trigger.hpp> // for Event, EventFactory
70 
71 namespace cloe {
72 namespace events {
73 
74 template <typename T>
75 class Transition : public Event {
76  public:
77  Transition(const std::string& name, T from, T to)
78  : Event(name), from_(from), to_(to), ready_(false) {}
79  Transition(const Transition<T>&) = delete;
80  Transition(Transition<T>&&) = delete;
81  ~Transition() = default;
82 
83  EventPtr clone() const override { return std::make_unique<Transition<T>>(name(), from_, to_); }
84 
85  bool operator()(const Sync&, T x) {
86  if (ready_) {
87  // Previous state: from
88  if (x == to_) {
89  // State change: from -> to
90  ready_ = false;
91  return true;
92  } else if (x != from_) {
93  // State change: from -> !from
94  ready_ = false;
95  }
96  return false;
97  } else {
98  // Previous state: !from
99  if (x == from_) {
100  ready_ = true;
101  }
102  return false;
103  }
104  }
105 
106  void to_json(Json& j) const override {
107  j = Json{
108  {"from", from_},
109  {"to", to_},
110  };
111  }
112 
113  private:
114  bool ready_;
115  T from_;
116  T to_;
117 };
118 
119 template <typename T>
121  public:
122  using EventType = Transition<T>;
123  TransitionFactory(const std::string& name, const std::string& desc) : EventFactory(name, desc) {}
124 
125  TriggerSchema schema() const override {
126  using namespace fable::schema; // NOLINT(build/namespaces)
127  static const char* desc = "transition between one state and another";
128  return TriggerSchema{
129  name(),
130  description(),
131  InlineSchema(desc, "transition", true),
132  {
133  {"from", make_prototype<T>().description("from state").require()},
134  {"to", make_prototype<T>().description("destination state").require()},
135  },
136  };
137  }
138 
139  EventPtr make(const Conf& c) const override {
140  try {
141  auto from = c.get<T>("from");
142  auto to = c.get<T>("to");
143  return std::make_unique<Transition<T>>(name(), from, to);
144  } catch (std::exception& e) {
145  throw TriggerInvalid(c, e.what());
146  }
147  }
148 
149  EventPtr make(const std::string& s) const override {
150  auto sep = s.find("->");
151  if (sep == std::string::npos) {
152  throw TriggerInvalid(Conf{Json{s}}, "expected format N->M");
153  }
154  // Unfortunately, there's no nice way to do this in C++:
155  auto from = Json{s.substr(0, sep)}.get<T>();
156  auto to = Json{s.substr(sep + 2)}.get<T>();
157  return make(Conf{Json{
158  {"from", from},
159  {"to", to},
160  }});
161  }
162 };
163 
164 template <typename T>
165 using TransitionCallback = DirectCallback<Transition<T>, T>;
166 
167 } // namespace events
168 } // namespace cloe
Definition: registrar.hpp:46
const std::string & description() const
Definition: entity.hpp:90
const std::string & name() const
Definition: entity.hpp:67
Definition: trigger.hpp:482
Definition: sync.hpp:34
Definition: trigger.hpp:290
Definition: trigger.hpp:73
Definition: transition_event.hpp:120
EventPtr make(const Conf &c) const override
Definition: transition_event.hpp:139
EventPtr make(const std::string &s) const override
Definition: transition_event.hpp:149
TriggerSchema schema() const override
Definition: transition_event.hpp:125
Definition: transition_event.hpp:75
EventPtr clone() const override
Definition: transition_event.hpp:83
Definition: conf.hpp:81
T get() const
Definition: conf.hpp:297
nlohmann::json Json
Definition: fable_fwd.hpp:35
Definition: trigger.hpp:87
const std::string & description() const
Definition: trigger.hpp:143
Definition: trigger.hpp:207