Main Page · Modules · All Classes · Class Hierarchy
MABehavior.hpp
1 /*
2  * This file is part of the AiBO+ project
3  *
4  * Copyright (C) 2005-2016 Csaba Kertész (csaba.kertesz@gmail.com)
5  *
6  * AiBO+ is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * AiBO+ is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
19  *
20  */
21 
22 #pragma once
23 
24 #include "core/MASignal.hpp"
25 #include "types/MALeg.hpp"
26 #include "sound/MASoundBase.hpp"
27 
28 #include <boost/shared_ptr.hpp>
29 #include <boost/unordered_map.hpp>
30 
31 #include <vector>
32 
33 class MABehavior;
34 class MAController;
35 class MCTimer;
36 
42 #define MABEHAVIOR_CREATE(_behavior, _master, ...) \
44  MABEHAVIOR_CREATE_S(_behavior, _master, "", __VA_ARGS__)
45 
46 // The pointer magic _master -> Temp -> Master is done to avoid c-type casts.
47 // _master can be NULL then the compiler will complain to dynamic cast NULL pointer.
48 // Interestingly, static_cast works, but dynamic_cast causes crash in mindaibotests.
49 #define MABEHAVIOR_CREATE_S(_behavior, _master, _name_suffix, ...) \
50  { \
51  MABehavior* _Temp = _master; \
52  MABehavior* _Master = static_cast<MABehavior*>(_Temp); \
53  \
54  if (!MABehavior::Exists(MCGetClassName<_behavior>(nullptr, _name_suffix)) && \
55  !(_Master != nullptr && \
56  (_Master->GetState() == MABehavior::Failed || \
57  _Master->GetState() == MABehavior::Finished))) \
58  { \
59  _behavior* Behavior = new _behavior(__VA_ARGS__); \
60  \
61  if (_Master != nullptr) \
62  _Master->AddSlave(*Behavior); \
63  } \
64  }
65 
67 #define MABEHAVIOR_GET(_behavior) \
68  MABEHAVIOR_GET_S(_behavior, "")
69 
70 #define MABEHAVIOR_GET_S(_behavior, _name_suffix) \
71  dynamic_cast<_behavior*>(MABehavior::GetBehavior(MCGetClassName<_behavior>(nullptr, _name_suffix)));
72 
74 #define MABEHAVIOR_EXISTS(_behavior) \
75  MABEHAVIOR_EXISTS_S(_behavior, "")
76 
77 #define MABEHAVIOR_EXISTS_S(_behavior, _name_suffix) \
78  MABehavior::Exists(MCGetClassName<_behavior>(nullptr, _name_suffix))
79 
81 #define MABEHAVIOR_DELETE(_behavior) \
82  MABEHAVIOR_DELETE_S(_behavior, "")
83 
84 #define MABEHAVIOR_DELETE_S(_behavior, _name_suffix) \
85  { \
86  MABehavior* Behavior = MABehavior::GetBehavior(MCGetClassName<_behavior>(nullptr, _name_suffix)); \
87  \
88  if (Behavior) \
89  { \
90  Behavior->MarkDirty(); \
91  } \
92  }
93 
95 #define MABEHAVIOR_IS_NORMAL(_behavior) \
96  MABEHAVIOR_IS_NORMAL_S(_behavior, "")
97 
98 #define MABEHAVIOR_IS_NORMAL_S(_behavior, _name_suffix) \
99  (MABEHAVIOR_EXISTS_S(_behavior, _name_suffix) ? \
100  MABehavior::GetBehavior(MCGetClassName<_behavior>(nullptr, _name_suffix))->GetState() == MABehavior::Normal : \
101  false)
102 
104 #define MABEHAVIOR_IS_ACTIVATED(_behavior) \
105  MABEHAVIOR_IS_ACTIVATED_S(_behavior, "")
106 
107 #define MABEHAVIOR_IS_ACTIVATED_S(_behavior, _name_suffix) \
108  (MABEHAVIOR_EXISTS_S(_behavior, _name_suffix) ? \
109  MABehavior::GetBehavior(MCGetClassName<_behavior>(nullptr, _name_suffix))->GetState() == MABehavior::Activated : \
110  false)
111 
113 #define MABEHAVIOR_IS_FINISHED(_behavior) \
114  MABEHAVIOR_IS_FINISHED_S(_behavior, "")
115 
116 #define MABEHAVIOR_IS_FINISHED_S(_behavior, _name_suffix) \
117  (MABEHAVIOR_EXISTS_S(_behavior, _name_suffix) ? \
118  MABehavior::GetBehavior(MCGetClassName<_behavior>(nullptr, _name_suffix))->GetState() == MABehavior::Finished : \
119  false)
120 
122 #define MABEHAVIOR_IS_FAILED(_behavior) \
123  MABEHAVIOR_IS_FAILED_ADNVANCED(_behavior, "")
124 
125 #define MABEHAVIOR_IS_FAILED_ADNVANCED(_behavior, _name_suffix) \
126  (MABEHAVIOR_EXISTS_S(_behavior, _name_suffix) ? \
127  MABehavior::GetBehavior(MCGetClassName<_behavior>(nullptr, _name_suffix))->GetState() == MABehavior::Failed : \
128  false)
129 
130 namespace MA
131 {
133 typedef std::vector<boost::shared_ptr<MABehavior> > BehaviorList;
134 
136 typedef std::vector<MABehavior*> BehaviorPtrList;
137 
139 typedef boost::unordered_map<std::string, float> DesiredConnectionMap;
140 
142 typedef boost::unordered_map<MABehavior*, float> ConnectionMap;
143 
145 typedef boost::unordered_map<std::string, int> IncomingActivationMap;
146 
148 typedef boost::unordered_multimap<MAController*, std::string> ControllerTransitionMap;
149 
151 typedef boost::unordered_map<MAIntervalNum<int>*, float> EmotionWeightMap;
152 }
153 
158 {
159  MA_SLOT_CLASS
160 
162  typedef MASignal<MABehavior&> BehaviorDestroyedSignalType;
163 
165  template <typename T>
166  friend void boost::checked_delete(T*);
167 
168 public:
170  typedef enum
171  {
172  NoStimulus = 0,
176 
178  typedef enum
179  {
180  Normal = 0,
184  } StateType;
185 
194  MABehavior(const std::string& type_name, bool dynamic = true);
195  virtual ~MABehavior();
196 
204  static const MA::BehaviorList& GetBehaviors();
205 
213  static const MA::BehaviorList& GetNewBehaviors();
214 
222  static void SetVerbose(bool new_state);
223 
231  static bool IsVerbose();
232 
240  static void ClearBehaviorStateEvents();
241 
251  static MABehavior* GetBehavior(const std::string& type_name);
252 
266  static bool Exists(const std::string& type_name, bool can_be_dying = false);
267 
281  static bool Exists(const MABehavior* behavior, bool can_be_dying = false);
282 
301  static bool IsDying(const std::string& type_name);
302 
321  static bool IsDying(const MABehavior* behavior);
322 
332  static void CalculateActivations();
333 
339  static void GarbageCollection();
340 
349  static void Cleanup();
350 
356  static void MergeNewBehaviors();
357 
363  static void DumpBehaviors();
364 
372  static bool IsMergeNeeded();
373 
381  inline const std::string& GetTypeName() const
382  {
383  return TypeName;
384  }
385 
393  inline StateType GetState() const
394  {
395  return State;
396  }
397 
405  inline bool IsDynamic() const
406  {
407  return Dynamic;
408  }
409 
417  void AddSlave(MABehavior& slave);
418 
426  MABehavior* GetMaster();
427 
435  void SetMaster(MABehavior* master);
436 
444  bool HasSlave() const;
445 
446 protected:
447 
453  void ResetSelfActivation();
454 
460  void SetMaxSelfActivation();
461 
469  void SetSelfActivationDuration(const int new_duration);
470 
478  int GetSelfActivationDuration() const;
479 
480 public:
481 
490  void SetLifetimeExpirationTime(const unsigned int expiration_time);
491 
499  void SetActivatedStateExpirationTime(const unsigned int expiration_time);
500 
508  int GetElapsedActivatedStateTime() const;
509 
520  int GetActivationLevel();
521 
529  bool HasActivatedStateExpired() const;
530 
539  void Input();
540 
548  void SetState(StateType new_state);
549 
555  void MarkDirty();
556 
565  void StartTransition(MAController& controller, const std::string& transition_name);
566 
575  void RegisterActiveTransition(MAController& controller, const std::string& transition_name);
576 
586  int PlaySound(const std::string& name);
587 
597  int PlaySound(MA::SoundBaseSPtr sound);
598 
599 private:
600 
608  void AddConnection(MABehavior& other);
609 
617  void RemoveConnection(MABehavior& other);
618 
626  virtual MABehavior::StimulusLevelType GetCurrentStimulus() = 0;
627 
635  bool AreActiveTransitionsFinished();
636 
644  bool AnyActiveTransitionFailed() const;
645 
651  void StopActiveTransitions();
652 
658  void ClearActiveTransitions();
659 
667  bool AreSoundPlaybacksFinished();
668 
674  void ClearSoundPlaybacks();
675 
683  virtual bool IsFinished();
684 
692  virtual bool IsFailed();
693 
699  virtual void ActivatingActions();
700 
706  virtual void ActivatedStateUpdate();
707 
713  virtual void FailingActions();
714 
720  virtual void FinishingActions();
721 
727  void SendOutgoingActivations();
728 
734  void ClearIncomingActivations();
735 
743  void AddIncomingActivation(int value);
744 
752  void SlaveDeleted(MABehavior& behavior);
753 
754 public:
756  boost::shared_ptr<BehaviorDestroyedSignalType> BehaviorDestroyedSignal;
757 private:
759  std::string TypeName;
761  StateType State;
764 protected:
766  MA::DesiredConnectionMap DesiredConnections;
767 private:
769  MA::BehaviorPtrList SlaveBehaviors;
771  MA::ConnectionMap Connections;
772  /*
773  * Self-activation level (scaled: 0 - neutral; 100 - maximal activation).
774  * This variable is the likelihood for the behavior to be activated and it inhibits or
775  * stimulates other behaviors via connections. The default time to reach the maximal
776  * activation is 1000 ms.
777  */
778  MAIntervalNum<int> SelfActivation;
782  bool Dynamic;
784  boost::shared_ptr<MCTimer> ActivatedStateTimer;
786  boost::shared_ptr<MCTimer> LifetimeTimer;
790  MA::ControllerTransitionMap ActiveTransitions;
794  MC::StringList QueuedSounds;
796  std::vector<MA::SoundBaseSPtr> QueuedInMemorySounds;
798  MA::EmotionWeightMap EmotionWeights;
799 };
800 
813 template <typename T>
815 {
816  if (!MABehavior::Exists(MCGetClassName<T>()) &&
817  !(master != nullptr &&
818  (master->GetState() == MABehavior::Failed || master->GetState() == MABehavior::Finished)))
819  {
820  T* Behavior = new T();
821 
822  if (master)
823  master->AddSlave(*Behavior);
824  return Behavior;
825  }
826  return nullptr;
827 }
828 
MC::StringList QueuedSounds
Queued sounds.
Definition: MABehavior.hpp:794
static bool Exists(const std::string &type_name, bool can_be_dying=false)
Check if a behavior exists.
Definition: MABehavior.cpp:175
MA_SLOT_CLASS typedef MASignal< MABehavior & > BehaviorDestroyedSignalType
Behavior destroyed signal type.
Definition: MABehavior.hpp:162
boost::shared_ptr< BehaviorDestroyedSignalType > BehaviorDestroyedSignal
Behavior destruction signal.
Definition: MABehavior.hpp:756
MA::DesiredConnectionMap DesiredConnections
Desired connection map to other behaviors.
Definition: MABehavior.hpp:766
Behavior base class.
Definition: MABehavior.hpp:157
std::vector< MA::SoundBaseSPtr > QueuedInMemorySounds
Queued in-memory sounds.
Definition: MABehavior.hpp:796
MABehavior * Master
Master behavior of the subnetwork where the behavior belongs to.
Definition: MABehavior.hpp:763
MA::EmotionWeightMap EmotionWeights
Emotion weight map.
Definition: MABehavior.hpp:798
Base class for the controllers.
#define MC_DISABLE_COPY(class_name)
Helper macro to disable the copy constructor and assignment operator of a class (object copying) ...
Definition: MCDefs.hpp:604
int IncomingActivationLevel
Incoming activation level.
Definition: MABehavior.hpp:780
MABehavior * MACreateBehavior(MABehavior *master)
Create a behavior.
Definition: MABehavior.hpp:814
MA::BehaviorPtrList SlaveBehaviors
The list of the slave (child) behaviors.
Definition: MABehavior.hpp:769
StateType GetState() const
Get the behavior state.
Definition: MABehavior.hpp:393
boost::shared_ptr< MCTimer > LifetimeTimer
Lifetime duration timer.
Definition: MABehavior.hpp:786
StateType State
The current behavior state.
Definition: MABehavior.hpp:761
int SoundPlaybackID
Active sound playback during the activated state.
Definition: MABehavior.hpp:792
int ActivatedStateStartTimestamp
Activated state starting timestamp.
Definition: MABehavior.hpp:788
bool IsDynamic() const
Check if the behavior is dynamic.
Definition: MABehavior.hpp:405
MA::ConnectionMap Connections
Connection map to other behaviors.
Definition: MABehavior.hpp:771
MA::ControllerTransitionMap ActiveTransitions
LED or motion transitions during the activated state.
Definition: MABehavior.hpp:790
bool Dynamic
Whether the behavior is dynamic (it is destroyed after in failed or finished state) ...
Definition: MABehavior.hpp:782
Simple timer class with microsecond precision.
Definition: MCTimer.hpp:59
boost::shared_ptr< MCTimer > ActivatedStateTimer
Active state duration timer.
Definition: MABehavior.hpp:784
const std::string & GetTypeName() const
Get the behavior type name.
Definition: MABehavior.hpp:381
void AddSlave(MABehavior &slave)
Add a slave behavior.
Definition: MABehavior.cpp:460
std::string TypeName
A unique behavior type name.
Definition: MABehavior.hpp:759