File: trivial_kds.cpp

package info (click to toggle)
cgal 4.0-5
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 65,068 kB
  • sloc: cpp: 500,870; ansic: 102,544; sh: 321; python: 92; makefile: 75; xml: 2
file content (185 lines) | stat: -rw-r--r-- 5,716 bytes parent folder | download
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
#include <CGAL/Kinetic/Ref_counted.h>
#include <CGAL/Kinetic/Exact_simulation_traits.h>
#include <CGAL/Kinetic/listeners.h>
#include <CGAL/Kinetic/Event_base.h>
#include <iostream>
#include <set>
#include <vector>

#ifdef _MSC_VER
#pragma warning(disable:4355) // complaint about using 'this' to
                                // initialize a member
#endif

// This must be external since operator<< has to be defined
template <class Object, class Time, class KDS>
struct Trivial_event: public CGAL::Kinetic::Event_base<KDS*>
{
  typedef CGAL::Kinetic::Event_base<KDS*> P;
  Trivial_event(){}
  template <class It, class Map>
  Trivial_event(It beg, It end, const Map &m, KDS *kds): P(kds) {
    for (; beg != end; ++beg) {
      objects_.push_back(m[*beg]);
    }
  }
  void write(std::ostream &out) const {
    out << "An event";
  }
  void process() const
  {
    std::cout << "The following objects are in the table: ";
    for (typename std::vector<Object>::const_iterator
	   cit= objects_.begin();
	 cit != objects_.end(); ++cit) {
      std::cout << *cit << " ";
    }
    std::cout << std::endl;
    P::kds()->set_processed(true);
  }

  std::vector<Object> objects_;
};



/*!  This is a trivial kinetic data structure which doesn't actually
  do anything, other than print what it should be doing and maintain 1
  certificate in the event queue which has a list of all the moving
  objects in the moving object table.
*/
template <class Traits>
struct Trivial_kds: CGAL::Kinetic::Ref_counted<Trivial_kds<Traits> >
{
  typedef Trivial_kds<Traits> This;
  typedef typename Traits::Active_points_1_table::Data Point;
  typedef typename Traits::Simulator::Time Time;
  typedef typename Traits::Active_points_1_table::Key Point_key;
  typedef typename Traits::Simulator::Event_key Event_key;
  CGAL_KINETIC_DECLARE_LISTENERS(typename Traits::Simulator, typename Traits::Active_points_1_table)
public:
  typedef Trivial_event<Point, Time, This> Event;

  Trivial_kds(Traits tr): has_certificates_(true),
			  tr_(tr){
    CGAL_KINETIC_INITIALIZE_LISTENERS(tr_.simulator_handle(),
				      tr_.active_points_1_table_handle());
  }

  // this method is called with the value true when the event is processed
  void set_processed(bool tf) {
    if (tf== true) {
      event_= Event_key();
      set_has_certificates(false);
      set_has_certificates(true);
    }
  }

  void audit() const
  {
    /* In a real KDS you could use tr_.instantaneous_kernel() to build
       a static version of the kinetic data structure and check it for
       equality with the kinetic version.
    */
    CGAL_assertion(event_.is_valid());
    std::cout << "The structure is trivially correct at time "
	      << tr_.simulator_handle()->audit_time() << std::endl;
  }

  void set_has_certificates(bool tf) {
    typename Traits::Simulator::Handle sp= tr_.simulator_handle();
    if (has_certificates_ != tf) {
      has_certificates_=tf;
      if (has_certificates_) {
	bool ev= event_.is_valid();
	CGAL_assertion(!ev);
	Time t= CGAL::to_interval(sp->current_time()).second+1;
	event_= sp->new_event(t, Event(objects_.begin(),
				       objects_.end(),
				       *tr_.active_points_1_table_handle(),
				       this));
	std::cout << "Created event (" << event_ << ") at time " << t << std::endl;
      } else {
	if (event_.is_valid()) {
	  std::cout << "Deleting event " << event_ << std::endl;
	  sp->delete_event(event_);
	  event_=Event_key();
	}
      }
    }
  }

  bool has_certificates() const
  {
    // you can't use !event_ because the simulation
    // might end before the time you tried to schedule the event.
    return has_certificates_;
  }

  void insert(Point_key k) {
    std::cout << "Updating structure to include new object "
	      << k << "." << std::endl;
    objects_.insert(k);
    if (has_certificates_) {
      std::cout << "Updating all certificates which depend on "
                << k << "." << std::endl;
      set_has_certificates(false);
      set_has_certificates(true);
    }
  }

  void set(Point_key k) {
    if (has_certificates_) {
      std::cout << "Updating all certificates which depend on "
                << k << "." << std::endl;
      set_has_certificates(false);
      set_has_certificates(true);
    } else {
      std::cout << "An object changed, but there was no certificate."<< std::endl;
    }
  }

  void erase(Point_key k) {
    std::cout << "An object " << k << " was removed."<< std::endl;
    objects_.erase(k);
    if (has_certificates_) {
      std::cout << "Updating all certificates which depend on "
                << k << "." << std::endl;
      set_has_certificates(false);
      set_has_certificates(true);
    }
  }

protected:
  bool has_certificates_;
  std::set<Point_key > objects_;
  Event_key event_;
  Traits tr_;
};

int main(int, char *[])
{
  typedef CGAL::Kinetic::Exact_simulation_traits Traits;
  typedef Trivial_kds<Traits> TKDS;

  Traits tr(1,100);
  TKDS::Handle tk= new TKDS(tr);

  Traits::Simulator::Handle sp=tr.simulator_handle();

  Traits::Simulator::Function_kernel::Construct_function cf
    = tr.kinetic_kernel_object().function_kernel_object().construct_function_object();

  tk->set_has_certificates(true);

  typedef Traits::Kinetic_kernel::Point_2 Point;
  Traits::Active_points_1_table::Key k
    = tr.active_points_1_table_handle()->insert(Point(cf(1), cf(0)));
  sp->set_current_event_number(sp->current_event_number()+10);
  tr.active_points_1_table_handle()
    ->set(k, Traits::Kinetic_kernel::Point_2(cf(2), cf(0)));
  sp->set_current_event_number(sp->current_event_number()+10);
  tr.active_points_1_table_handle()->erase(k);
  sp->set_current_event_number(sp->current_event_number()+10);
  return EXIT_SUCCESS;
}