-
-
Notifications
You must be signed in to change notification settings - Fork 988
/
playturn_network_adapter.cpp
149 lines (132 loc) · 3.46 KB
/
playturn_network_adapter.cpp
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
#include "playturn_network_adapter.hpp"
#include "network.hpp"
#include "config_assign.hpp"
#include "log.hpp"
#include <boost/assign.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <cassert>
static lg::log_domain log_network("network");
#define ERR_NW LOG_STREAM(err, log_network)
void playturn_network_adapter::read_from_network()
{
assert(!data_.empty());
this->data_.push_back(config());
config& back = data_.back();
bool has_data = this->network_reader_(back);
//ping is handeled by network.cpp and we can ignore it.
back.remove_attribute("ping");
if((!has_data) || back.empty())
{
this->data_.pop_back();
return;
}
assert(!data_.back().empty());
if(back.has_attribute("side_drop"))
{
config child;
child["side_num"] = back["side_drop"];
child["controller"] = back["controller"];
this->data_.push_back(config_of("side_drop", child));
back.remove_attribute("side_drop");
back.remove_attribute("controller");
}
assert(!data_.back().empty());
//there should be no attributes left.
if(back.attribute_range().first != back.attribute_range().second )
{
ERR_NW << "found unexpected attribute:" <<back.debug() << "\n";
}
}
bool playturn_network_adapter::is_at_end()
{
assert(!data_.empty());
return this->next_ == data_.back().ordered_end();
}
bool playturn_network_adapter::read(config& dst)
{
assert(dst.empty());
if(is_at_end())
{
read_from_network();
}
if(is_at_end())
{
//that means we couldn't read anything from the network.
return false;
}
//skip empty data.
while(next_ == data_.begin()->ordered_end())
{
data_.pop_front();
next_ = data_.front().ordered_begin();
assert(!is_at_end());
}
config& child = dst.add_child(next_->key);
//TODO: implement a non const version of ordered children
config& child_old = const_cast<config&>(next_->cfg);
if(next_->key == "turn")
{
//split [turn] indo different [turn] for each child.
assert(next_->cfg.all_children_count() > next_command_num_);
config::all_children_iterator itor = child_old.ordered_begin();
//TODO: implement operator + (all_children_iterator, int ) properly
std::advance(itor, next_command_num_);
//TODO: implement a non const version of ordered children
config& childchild_old = const_cast<config&>(itor->cfg);
config& childchild = child.add_child(itor->key);
childchild.swap(childchild_old);
++next_command_num_;
if(next_->cfg.all_children_count() == next_command_num_)
{
next_command_num_ = 0;
++next_;
}
return true;
}
else
{
child.swap(child_old);
++next_;
return true;
}
}
playturn_network_adapter::playturn_network_adapter(source_type source)
: data_(boost::assign::list_of(config()).convert_to_container<std::list<config> >()),
next_(data_.front().ordered_end()),
next_command_num_(0),
network_reader_(source)
{
}
playturn_network_adapter::~playturn_network_adapter()
{
if(!is_at_end())
{
ERR_NW << "Destroing playturn_network_adapter with an non empty buffer, this means loss of network data\n";
}
}
void playturn_network_adapter::set_source(source_type source)
{
network_reader_ = source;
}
static bool read_config(config& src, config& dst)
{
assert(dst.empty());
if(!src.empty())
{
src.swap(dst);
return true;
}
else
{
return false;
}
}
playturn_network_adapter::source_type playturn_network_adapter::get_source_from_config(config& cfg)
{
return boost::bind(read_config, cfg, _1);
}
bool playturn_network_adapter::read_network(config& cfg)
{
return network::receive_data(cfg) != network::null_connection;
}