1 2 // Copyright (C) 2008-2018 Lorenzo Caminiti 3 // Distributed under the Boost Software License, Version 1.0 (see accompanying 4 // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). 5 // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html 6 7 //[mitchell02_observer_main 8 #include "observer/observer.hpp" 9 #include "observer/subject.hpp" 10 #include <boost/contract.hpp> 11 #include <cassert> 12 13 int test_state; // For testing only. 14 15 // Implement an actual subject. 16 class concrete_subject 17 #define BASES public subject 18 : BASES 19 { 20 friend class boost::contract::access; 21 22 typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; // Subcontracting. 23 #undef BASES 24 25 public: 26 typedef int state; // Some state being observed. 27 concrete_subject()28 concrete_subject() : state_() { 29 // Could have omitted contracts here (nothing to check). 30 boost::contract::check c = boost::contract::constructor(this); 31 } 32 ~concrete_subject()33 virtual ~concrete_subject() { 34 // Could have omitted contracts here (nothing to check). 35 boost::contract::check c = boost::contract::destructor(this); 36 } 37 set_state(state const & new_state)38 void set_state(state const& new_state) { 39 // Could have omitted contracts here (nothing to check). 40 boost::contract::check c = boost::contract::public_function(this); 41 42 state_ = new_state; 43 assert(state_ == test_state); 44 notify(); // Notify all observers. 45 } 46 get_state() const47 state get_state() const { 48 // Could have omitted contracts here (nothing to check). 49 boost::contract::check c = boost::contract::public_function(this); 50 return state_; 51 } 52 53 private: 54 state state_; 55 }; 56 57 // Implement an actual observer. 58 class concrete_observer 59 #define BASES public observer 60 : BASES 61 { 62 friend class boost::contract::access; 63 64 typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; // Subcontracting. 65 #undef BASES 66 67 BOOST_CONTRACT_OVERRIDES(up_to_date_with_subject, update) 68 69 public: 70 // Create concrete observer. concrete_observer(concrete_subject const & subj)71 explicit concrete_observer(concrete_subject const& subj) : 72 subject_(subj), observed_state_() { 73 // Could have omitted contracts here (nothing to check). 74 boost::contract::check c = boost::contract::constructor(this); 75 } 76 ~concrete_observer()77 virtual ~concrete_observer() { 78 // Could have omitted contracts here (nothing to check). 79 boost::contract::check c = boost::contract::destructor(this); 80 } 81 82 // Implement base virtual functions. 83 up_to_date_with_subject(boost::contract::virtual_ * v=0) const84 bool up_to_date_with_subject(boost::contract::virtual_* v = 0) 85 const /* override */ { 86 bool result; 87 boost::contract::check c = boost::contract::public_function< 88 override_up_to_date_with_subject 89 >(v, result, &concrete_observer::up_to_date_with_subject, this); 90 91 return result = true; // For simplicity, assume always up-to-date. 92 } 93 update(boost::contract::virtual_ * v=0)94 void update(boost::contract::virtual_* v = 0) /* override */ { 95 boost::contract::check c = boost::contract::public_function< 96 override_update>(v, &concrete_observer::update, this); 97 98 observed_state_ = subject_.get_state(); 99 assert(observed_state_ == test_state); 100 } 101 102 private: 103 concrete_subject const& subject_; 104 concrete_subject::state observed_state_; 105 }; 106 main()107int main() { 108 concrete_subject subj; 109 concrete_observer ob(subj); 110 subj.attach(&ob); 111 112 subj.set_state(test_state = 123); 113 subj.set_state(test_state = 456); 114 115 return 0; 116 } 117 //] 118 119