The Battle for Wesnoth  1.19.13+dev
playturn_network_adapter.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2017 - 2025
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
16 #include "log.hpp"
17 #include "utils/general.hpp"
18 
19 #include <cassert>
20 #include <functional>
21 #include <utility>
22 
23 
24 static lg::log_domain log_network("network");
25 #define DBG_NW LOG_STREAM(debug, log_network)
26 #define LOG_NW LOG_STREAM(info, log_network)
27 #define ERR_NW LOG_STREAM(err, log_network)
28 
30 {
31  assert(!data_.empty());
32 
33  this->data_.emplace_back();
34  config& back = data_.back();
35  bool has_data = false;
36  try
37  {
38  has_data = this->network_reader_(back);
39  }
40  catch(...)
41  {
42  //Reading from network can throw, we want to ignore the possibly corrupt packet in this case.
43  DBG_NW << "Caught exception reading from the network: " << utils::get_unknown_exception_type();
44  this->data_.pop_back();
45  throw;
46  }
47  if((!has_data) || back.empty())
48  {
49  this->data_.pop_back();
50  return;
51  }
52  assert(!data_.back().empty());
53 
54  if(!back.attribute_range().empty() )
55  {
56  ERR_NW << "found unexpected attribute:" <<back.debug();
57  this->data_.pop_back();
58  //ignore those here
59  }
60  assert(!data_.back().empty());
61  //there should be no attributes left.
62 }
63 
65 {
66  assert(!data_.empty());
67  if (data_.size() > 1) return false;
68  return this->next_ == data_.back().ordered_end();
69 }
70 
72 {
73  data_front_.emplace_front(std::move(cfg));
74 }
75 
77 {
78  assert(dst.empty());
79  if(!data_front_.empty())
80  {
81  dst = std::move(data_front_.back());
82  data_front_.pop_back();
83  return true;
84  }
85  if(is_at_end())
86  {
88  }
89  if(is_at_end())
90  {
91  //that means we couldn't read anything from the network.
92  return false;
93  }
94  //skip empty data.
95  while(next_ == data_.begin()->ordered_end())
96  {
97  data_.pop_front();
98  next_ = data_.front().ordered_begin();
99  assert(!is_at_end());
100  }
101  config& child = dst.add_child(next_->key);
102  config& child_old = next_->cfg;
103  if(next_->key == "turn")
104  {
105  //split [turn] indo different [turn] for each child.
106  assert(next_->cfg.all_children_count() > next_command_num_);
107  config::all_children_iterator itor = child_old.ordered_begin();
108  std::advance(itor, next_command_num_);
109  config& childchild_old = itor->cfg;
110  config& childchild = child.add_child(itor->key);
111  childchild.swap(childchild_old);
112 
114  if(next_->cfg.all_children_count() == next_command_num_)
115  {
116  next_command_num_ = 0;
117  ++next_;
118  }
119  return true;
120  }
121  else
122  {
123  child.swap(child_old);
124  ++next_;
125  return true;
126  }
127 }
128 
130  : network_reader_(std::move(source))
131  , data_({config()})
132  , data_front_()
133  , next_(data_.front().ordered_end())
134  , next_command_num_(0)
135 
136 {
137 }
138 
140 {
141  try {
142  if(!is_at_end())
143  {
144  LOG_NW << "Destroying playturn_network_adapter with an non empty buffer, this means loss of network data";
145  }
146  } catch (...) {}
147 }
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:158
const_all_children_iterator ordered_begin() const
Definition: config.cpp:860
const_attr_itors attribute_range() const
Definition: config.cpp:756
std::string debug() const
Definition: config.cpp:1236
void swap(config &cfg)
Definition: config.cpp:1332
bool empty() const
Definition: config.cpp:845
config & add_child(config_key_type key)
Definition: config.cpp:436
std::function< bool(config &)> source_type
config::all_children_iterator next_
playturn_network_adapter(source_type source)
Standard logging facilities (interface).
std::string get_unknown_exception_type()
Utility function for finding the type of thing caught with catch(...).
Definition: general.cpp:23
#define ERR_NW
#define LOG_NW
static lg::log_domain log_network("network")
#define DBG_NW
rect dst
Location on the final composed sheet.
bool empty() const
False if both w and h are > 0, true otherwise.
Definition: rect.cpp:49