summaryrefslogtreecommitdiffstats
path: root/src/core/logic/RBAArbitratorImpl.hpp
blob: e6c37a149d8304a2a3559357687851e66ae8068f (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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/**
 * 調停ロジック実装クラスヘッダファイル
 */

#ifndef RBAARBITORATORIMPL_HPP
#define RBAARBITORATORIMPL_HPP

#include <cstdint>
#include <set>
#include <memory>
#include <mutex>
#include <deque>
#include <unordered_map>
#include "RBAArbitrator.hpp"
#include "RBARequestQueMember.hpp"
#include "RBAResultSet.hpp"
#include "RBAResultImpl.hpp"

namespace rba
{

class RBAModelImpl;
class RBAAffectInfo;
class RBARollbacker;
class RBAWindowRouter;
class RBAConstraintImpl;
#ifdef RBA_USE_LOG
class RBALogManager;
#endif

class DLL_EXPORT RBAArbitratorImpl
{
public:
  RBAArbitratorImpl()=default;
  RBAArbitratorImpl(const RBAArbitratorImpl&)=delete;
  RBAArbitratorImpl(const RBAArbitratorImpl&&)=delete;
  RBAArbitratorImpl& operator=(const RBAArbitratorImpl&)=delete;
  RBAArbitratorImpl& operator=(const RBAArbitratorImpl&&)=delete;
  virtual ~RBAArbitratorImpl()=default;

  bool isValidContext(const std::string& context);
  bool isValidContext(std::list<std::string>& contexts);
  bool setRequestData(
      const std::string& context, bool require,
      std::list<std::pair<std::string, std::int32_t>>* const properties = nullptr,
      std::uint32_t syncIndex = 0xFFFFU);
  void setRequestData(const RBAContentState* state, bool require);
  void setRequestData(const RBAContent* const content, bool require);
  void setActive(const RBASceneImpl* const scene, const bool require);
  void setSceneProperty(const RBAAbstractProperty* const prop, const std::int32_t value);
  void setRequestData(std::list<std::string>& contexts, const bool require);
#ifdef RBA_USE_LOG
  void checkAllConstraints();
#endif
  void updateResult();
  void checkCancelContent() const;
  void createResultData();

  bool satisfiesConstraints() const;
  std::unique_ptr<RBAResult> arbitrateMain();
  void arbitrate(std::list<RBAAllocatable*>& allocatables);
  void arbitrateAllocatable(RBAAllocatable* allocatable,
                            std::set<const RBAAllocatable*>& revisited,
                            const std::int32_t nest, RBAAffectInfo* const affectInfo,
                            RBARollbacker* const parentRollbacker);
  void getAffectedAllocatables(
      RBAAllocatable* allocatable,
      std::list<RBAConstraintImpl*>& falseConstraints,
      std::list<RBAAllocatable*>& affectedAllocatables);
  void getAffectAllocatableWithoutAlreadyAffected(
      std::list<RBAAllocatable*>& allocatables,
      RBAAllocatable* affectAllocatable, RBAAffectInfo* affectInfo,
      std::list<RBAAllocatable*>& result);
  void addAffectAllocatable(std::list<RBAAllocatable*>& allocatables,
                            RBAAllocatable* affectAllocatable,
                            RBAAffectInfo* affectInfo);

  bool sortContentStates(const RBAAllocatable* const allocatable,
                         std::list<const RBAContentState*>& states) const;
  void postArbitrate();
  void changeContentStateCancelWithPolicy(const RBAContentState* const state);
  void collectRevisitAllocatable(
      std::list<const RBAAllocatable*>* const totalRevisitAllocatables,
      RBAAllocatable*& allocatable,
      std::list<RBAConstraintImpl*>& falseConstraints,
      std::set<const RBAAllocatable*>& revisited);

  bool isDefeat(const RBAContentState* const winner,
                const RBAContentState* const loser) const;

  static std::int32_t getViewActionPriority(const RBAViewActionType viewActionType);
  static bool compareViewAction(const std::unique_ptr<RBAViewAction>& lhs,
                                const std::unique_ptr<RBAViewAction>& rhs);
  RBAResultImpl* getResult() const;  /// rba_toolで使用する
  bool isCancelChecked(const RBAContentState* const state) const;
  bool isCancel(const RBAContentState* const state) const;

#ifdef RBA_USE_LOG
  void setResultLog();
#endif

 private:
  void differenceArbitrate();
  bool checkConstraints(std::list<RBAConstraintImpl*>& constraints,
                        std::list<RBAConstraintImpl*>& falseConstraints,
                        const RBAAllocatable* const allocatable);
  bool checkConstraintAndReArbitrate(RBAAllocatable* allocatable,
                                     std::set<const RBAAllocatable*>& revisited,
                                     const std::int32_t nest,
                                     RBAAffectInfo* const affectInfo,
                                     RBARollbacker* const parentRollbacker,
                                     std::list<RBAConstraintImpl*>& constraints,
                                     bool * const isSkipped, const bool isFinal);
  void setCancel(const RBAContentState* const state, const bool checked);
  void getSortedContentStates(
      const RBAAllocatable* const allocatable,
      std::list<const RBAContentState*>& contentStates) const;

#ifdef RBA_USE_LOG
  // ログ出力
  void logRequestArbitration();
  void logPreResultArbitration();
  void logRequestForCoverage();
  void logResultArbitration();
  void logResultForCoverage();
  void setLogToResult();
#endif

 public:
  RBAArbitrator* getArb() const;
  void setArb(RBAArbitrator* const arb);
  RBAModelImpl* getModel() const;
  void setModel(RBAModelImpl* const model);
  std::set<const RBAContentState*>& getCancelChecked();
  std::unique_ptr<RBAResultImpl>& getResultRef() const;
  void setResult(std::unique_ptr<RBAResultImpl> result);
  std::unique_ptr<RBAResultSet>& getNextResultSet();
  void setNextResultSet(std::unique_ptr<RBAResultSet> nextResultSet);
  std::unique_ptr<RBAResultSet>& getBackupResultSet();
  void setBackupResultSet(std::unique_ptr<RBAResultSet> backupResultSet);
  std::unique_ptr<RBAResultSet>& getReservedResultSet();
  void setReservedResultSet(std::unique_ptr<RBAResultSet> reservedResultSet);
  std::recursive_mutex& getMutex() const;
#ifdef RBA_USE_LOG
  bool getSimulationMode();
  void setSimulationMode(bool simulationMode);
#endif
  std::deque<std::unique_ptr<RBARequestQueMember>>& getRequestQue();

 private:
  RBAArbitrator* arb_ {nullptr};
  RBAModelImpl* model_ {nullptr};
  RBAWindowRouter* windowRouter_ {nullptr};

#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4251)
#endif
  std::set<const RBAContentState*> cancelChecked_;
#ifdef _MSC_VER
#pragma warning(pop)
#endif

  mutable std::unique_ptr<RBAResultImpl> result_;
  // 次の調停でCurrentResultSetとして使用するResultSet
  std::unique_ptr<RBAResultSet> nextResultSet_;
  // 次の調停でPreviousResultSetとして使用するResultSet
  std::unique_ptr<RBAResultSet> backupResultSet_;
  // cancelArbitration()でCurrentResultSetとして使用するResultSet
  std::unique_ptr<RBAResultSet> reservedResultSet_;
  // satisfiesConstraints()でCurrentResultSetとして使用するResultSet
  std::unique_ptr<RBAResultSet> resultSetForSatisfiesConstraints_;
  mutable std::recursive_mutex mutex_;
  // 調停要求を受けた時とき、常に調停するアロケータブル
  std::set<const RBAAllocatable*> allwaysArbitrateAllocatables_;
#ifdef RBA_USE_LOG
  bool simulationMode_ = false;
#endif
  std::deque<std::unique_ptr<RBARequestQueMember>> requestQue_;
  std::uint32_t syncIndex_ {0xFFFFU};

};

class DLL_EXPORT RBAArbitrator::Impl
{
 public:
  Impl(RBAArbitrator* const arb, RBAModelImpl* const newModel);
  Impl(const Impl&)=delete;
  Impl(const Impl&&)=delete;
  Impl& operator=(const Impl&)=delete;
  Impl& operator=(const Impl&&)=delete;
#ifdef RBA_USE_LOG
  Impl(RBAArbitrator* arb,
       RBAModelImpl* newModel, RBALogManager* logManager);
#endif
  virtual ~Impl()=default;

 public:
  RBAModelImpl* getModel();
  void setModel(RBAModelImpl* const newModel);
  void initialize(std::list<std::string>& contexts);
  std::unique_ptr<RBAResult> execute(const std::string& contextName,
                                     const bool require = true);
  std::unique_ptr<RBAResult> execute(std::list<std::string>& contexts,
                                     const bool require = true);
  std::unique_ptr<RBAResult> execute(
      const std::string& sceneName,
      std::list<std::pair<std::string, std::int32_t>>& properties);
  std::unique_ptr<RBAResult>
  setResultContentState(const std::string& allocatableName,
                        const std::string& contextName);
  std::unique_ptr<RBAResult> cancelArbitration();

  void clearArbitration();
  bool setScene(const std::string& sceneName, const bool require,
                std::list<std::pair<std::string, std::int32_t>>& properties);
  bool setContentState(const std::string& contextName, const bool require);
  bool setAllocatableResult(const std::string& allocatableName,
                            const std::string& contextName);

  bool evaluate(const RBAExpression* const expression);
  const RBARuleObject* evaluateObject(const RBAExpression* const expression);
  int32_t evaluateValue(const RBAExpression* const expression);

  RBAArbitratorImpl* getImpl();

 private:
  RBAArbitratorImpl impl_;

};

}

#endif