Grail (C++)  1.4.0
A multi-platform, modular, universal engine for embedding advanced AI in games.
AIEntity.hh
1 // Copyright QED Software 2023.
2 
3 #ifndef GRAIL_AI_ENTITY_H
4 #define GRAIL_AI_ENTITY_H
5 
6 #include "Behavior.hh"
7 #include "Blackboard.hh"
8 #include "EntityToken.hh"
9 
10 #include <atomic>
11 #include <map>
12 #include <memory>
13 #include <mutex>
14 #include <random>
15 #include <string>
16 #include <vector>
17 #include <thread>
18 
19 namespace grail
20 {
21  enum class ProcessingStatus
22  {
23  FREE = 0,
24  RUNNING,
25  DONE,
26  };
27 
28  enum class RegistrationStatus
29  {
30  NOT_REGISTERED,
31  PENDING_REMOVAL,
32  REGISTERED,
33  };
34 
35  class AIEntity;
36  class Reasoner;
37 
39  {
40  public:
41  virtual ~IReasonerChangeObserver() = default;
42  virtual void OnReasonerSet(AIEntity& entity, Reasoner* newReasoner) = 0;
43  };
44 
45  class AIManager;
46 
50  class AIEntity
51  {
52  friend class AIManager;
53  friend class GrailStateSnapshotGenerator;
54  friend class EntityToken;
55 
56  public:
61  AIEntity(const std::string& name = "");
62  AIEntity(const AIEntity&) = delete;
63  AIEntity(AIEntity&&) = delete;
64 
65  virtual ~AIEntity();
66 
67  AIEntity& operator =(const AIEntity&) = delete;
68  AIEntity& operator =(AIEntity&&) = delete;
69 
75  static void ResetNextID(const size_t nextId = 0);
76 
81  void SetReasoner(std::unique_ptr<Reasoner> newReasoner);
82 
87  const Behavior* GetCurrentBehavior() const;
88 
94 
99  std::unique_ptr<Behavior> GetUniqueCurrentBehavior();
100 
105  std::unique_ptr<Behavior> MoveSuspendedBehavior();
106 
111  std::unique_ptr<Reasoner> TakeOwnershipOfReasoner();
112 
113  Reasoner* GetReasoner();
114 
119  void StageBehavior(std::unique_ptr<Behavior> behavior);
120 
125  bool HasStagedBehavior() const;
126 
131  bool HasActiveBehavior() const;
132 
138  void AddSharedBlackboard(const std::string& name, std::shared_ptr<Blackboard>& sharedBlackboard);
139 
144  void RemoveSharedBlackboard(const std::string& name);
145 
151  std::shared_ptr<Blackboard> GetSharedBlackboard(const std::string& name) const;
152 
158 
163  const Blackboard& GetBlackboard() const;
164 
170 
176  void SetId(size_t id);
177  size_t GetId() const;
178  const std::string& GetName() const;
179  std::string GetCurrentBehaviorName() const;
180 
181  protected:
186  virtual void Update(float deltaTime);
187 
188  std::unique_ptr<Reasoner> reasoner;
189  std::map<std::string, std::shared_ptr<Blackboard>> sharedBlackboards{};
190 
191  private:
192  void SelectBehavior();
193  void ExecuteBehavior(float deltaTime);
194  void SuspendPreviousBehavior();
195  void SetupNextBehavior(std::unique_ptr<Behavior> behavior);
196 
197  bool ChangeProcessingStatus(ProcessingStatus newStatus);
198  ProcessingStatus GetProcessingStatus() const;
199 
200  bool ChangeRegistrationStatus(RegistrationStatus newStatus);
201  RegistrationStatus GetRegistrationStatus() const;
202 
203  [[nodiscard]] EntityToken Acquire();
204  bool Release();
205 
206  inline static size_t nextEntityId = 0;
207  std::unique_ptr<Behavior> stagedBehavior = nullptr;
208  std::unique_ptr<Behavior> currentBehavior = nullptr;
209  std::unique_ptr<Behavior> suspendedBehavior = nullptr;
210  Blackboard blackboard{};
211  mutable std::thread::id threadId{};
212  mutable bool isAcquired{false};
213  mutable std::mutex entityUpdateMutex{};
214  mutable std::mutex entityAcquireMutex{};
215  mutable std::mutex behaviorMutex{};
216  mutable std::mutex stagingMutex{};
217  mutable std::mutex reasonerMutex{};
218  float entityDeltaTime{0.f}; //Used only in AIManager. Helps with bookkeeping without additional memory and synchronization overhead.
219  std::vector<IReasonerChangeObserver*> reasonerChangeObservers{};
220 
221  ProcessingStatus processingStatus = ProcessingStatus::FREE;
222  RegistrationStatus registrationStatus = RegistrationStatus::NOT_REGISTERED;
223  size_t id;
224  std::string name;
225  };
226 }
227 #endif //GRAIL_AI_ENTITY_H
grail::AIEntity::AIEntity
AIEntity(const std::string &name="")
AIEntity - Constructs an AIEntity with the given name.
Definition: AIEntity.cpp:14
grail::AIEntity::GetBlackboard
Blackboard & GetBlackboard()
GetBlackboard.
Definition: AIEntity.cpp:306
grail::AIEntity
The AIEntity class - Defines a basic object which can execute behaviors.
Definition: AIEntity.hh:50
grail::AIManager
The AIManager class - Manages registered entities and shared blackboards.
Definition: AIManager.hh:32
grail::AIEntity::SetReasoner
void SetReasoner(std::unique_ptr< Reasoner > newReasoner)
SetReasoner.
Definition: AIEntity.cpp:28
grail::Reasoner
The Reasoner class - Entity's "brain", assigns them behaviors chosen by user-defined algorithms.
Definition: Reasoner.hh:21
grail::AIEntity::Update
virtual void Update(float deltaTime)
Update - User defined method. Should in some way update entity's state.
Definition: AIEntity.cpp:141
grail::GrailStateSnapshotGenerator
Definition: GrailStateSnapshotGenerator.h:14
grail::AIEntity::TakeOwnershipOfReasoner
std::unique_ptr< Reasoner > TakeOwnershipOfReasoner()
GetCurrentReasoner.
Definition: AIEntity.cpp:63
grail::AIEntity::MoveSuspendedBehavior
std::unique_ptr< Behavior > MoveSuspendedBehavior()
GetPreviousBehavior.
Definition: AIEntity.cpp:58
grail::Blackboard
The Blackboard class - grail's universal data container.
Definition: Blackboard.hh:15
grail::AIEntity::AddSharedBlackboard
void AddSharedBlackboard(const std::string &name, std::shared_ptr< Blackboard > &sharedBlackboard)
AddSharedBlackboard - Inserts pair of key and blackboard into container of shared blackboards.
Definition: AIEntity.cpp:117
grail::AIEntity::GetCurrentBehavior
const Behavior * GetCurrentBehavior() const
GetCurrentBehavior.
Definition: AIEntity.cpp:43
grail::AIEntity::HasStagedBehavior
bool HasStagedBehavior() const
HasStagedBehavior - checks whether this entity has behavior awaiting its execution.
Definition: AIEntity.cpp:106
grail::IReasonerChangeObserver
Definition: AIEntity.hh:38
grail::Behavior
A high-level abstraction of actions in the game.
Definition: Behavior.hh:22
grail::AIEntity::RemoveReasonerChangeObserver
void RemoveReasonerChangeObserver(IReasonerChangeObserver *observer)
RemoveReasonerChangeObserver - Removes a reasoner change observer so it won't be notified of reasoner...
Definition: AIEntity.cpp:314
grail::AIEntity::GetUniqueCurrentBehavior
std::unique_ptr< Behavior > GetUniqueCurrentBehavior()
GetUniqueCurrentBehavior.
Definition: AIEntity.cpp:53
grail::EntityToken
Definition: EntityToken.hh:8
grail::AIEntity::StageBehavior
void StageBehavior(std::unique_ptr< Behavior > behavior)
StageBehavior - Finishes the current behavior and starts a new one.
Definition: AIEntity.cpp:74
grail::AIEntity::ResetNextID
static void ResetNextID(const size_t nextId=0)
ResetNextID - Resets taken entity IDs. Useful when a game has ended but entities were not destroyed,...
Definition: AIEntity.cpp:23
grail::AIEntity::RemoveSharedBlackboard
void RemoveSharedBlackboard(const std::string &name)
RemoveSharedBlackboard - Removes shared blackboard entry.
Definition: AIEntity.cpp:122
grail::AIEntity::AddReasonerChangeObserver
void AddReasonerChangeObserver(IReasonerChangeObserver *observer)
AddReasonerChangeObserver - Adds a reasoner change observer that will be notified via calling OnReaso...
Definition: AIEntity.cpp:309
grail::AIEntity::GetSharedBlackboard
std::shared_ptr< Blackboard > GetSharedBlackboard(const std::string &name) const
GetSharedBlackboard - Gets shared blackboard identified by given key.
Definition: AIEntity.cpp:131
grail::AIEntity::HasActiveBehavior
bool HasActiveBehavior() const
HasActiveBehavior - Checks whether current behavior is not nullptr.
Definition: AIEntity.cpp:112