feat(UML-1462): Доработана очередь сообщений. Мелкие правки.
This commit is contained in:
parent
83f77f62c0
commit
ca08bafe56
@ -60,33 +60,33 @@ void EthEcatPdoFMMU::wait_op() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EthEcatPdoFMMU::process_write_queue(uint8_t* process_data, uint32_t len) {
|
void EthEcatPdoFMMU::process_write_queue(uint8_t* process_data, uint32_t len) {
|
||||||
custom_promise::IPromise *next;
|
queue::QueueEntity<custom_promise::IPromise> *next;
|
||||||
|
|
||||||
mutex_write_.lock();
|
mutex_write_.lock();
|
||||||
|
|
||||||
next = queue_write_.get_next();
|
next = queue_write_.get_first();
|
||||||
last_write_ = &queue_write_;
|
queue_write_.clear();
|
||||||
|
|
||||||
mutex_write_.unlock();
|
mutex_write_.unlock();
|
||||||
|
|
||||||
while(next != nullptr) {
|
while(next != nullptr) {
|
||||||
next->set_value(process_data, len);
|
next->get_data()->set_value(process_data, len);
|
||||||
next = next->get_next();
|
next = next->get_next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EthEcatPdoFMMU::process_read_queue(uint8_t* process_data, uint32_t len) {
|
void EthEcatPdoFMMU::process_read_queue(uint8_t* process_data, uint32_t len) {
|
||||||
custom_promise::IPromise *next;
|
queue::QueueEntity<custom_promise::IPromise> *next;
|
||||||
|
|
||||||
mutex_read_.lock();
|
mutex_read_.lock();
|
||||||
|
|
||||||
next = queue_read_.get_next();
|
next = queue_read_.get_first();
|
||||||
last_read_ = &queue_read_;
|
queue_read_.clear();
|
||||||
|
|
||||||
mutex_read_.unlock();
|
mutex_read_.unlock();
|
||||||
|
|
||||||
while(next != nullptr) {
|
while(next != nullptr) {
|
||||||
next->set_value(process_data, len);
|
next->get_data()->set_value(process_data, len);
|
||||||
next = next->get_next();
|
next = next->get_next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,32 +47,7 @@ private:
|
|||||||
ecat_buffer::EcatBufferSlave& buffer_slave_;
|
ecat_buffer::EcatBufferSlave& buffer_slave_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
// Функтор для обхода и передачи датаграмм в custom_tuple
|
|
||||||
struct DatagramFunctor {
|
|
||||||
telegram::EcatTelegram& telegram;
|
|
||||||
size_t number_of_slaves;
|
|
||||||
datagram::IEcatDatagram *next;
|
|
||||||
|
|
||||||
void operator()(datagram::IEcatDatagram& datagram) {
|
|
||||||
if(next != nullptr) {
|
|
||||||
datagram + *next;
|
|
||||||
}
|
|
||||||
|
|
||||||
next = &datagram;
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator()() {
|
|
||||||
if(next == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
telegram.transfer(*next);
|
|
||||||
} while(next->get_all_wkc() < number_of_slaves);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
class EthEcatPdoFMMU {
|
class EthEcatPdoFMMU {
|
||||||
public:
|
public:
|
||||||
EthEcatPdoFMMU(ecat_buffer::EthEcatBuffer& ecat_buffer): ecat_buffer_{ecat_buffer} { }
|
EthEcatPdoFMMU(ecat_buffer::EthEcatBuffer& ecat_buffer): ecat_buffer_{ecat_buffer} { }
|
||||||
@ -91,8 +66,7 @@ public:
|
|||||||
|
|
||||||
mutex_write_.lock();
|
mutex_write_.lock();
|
||||||
|
|
||||||
custom_promise::IPromise& last_write = (*last_write_) >> promise;
|
queue_write_ + promise;
|
||||||
last_write_ = &last_write;
|
|
||||||
|
|
||||||
mutex_write_.unlock();
|
mutex_write_.unlock();
|
||||||
|
|
||||||
@ -108,8 +82,7 @@ public:
|
|||||||
|
|
||||||
mutex_read_.lock();
|
mutex_read_.lock();
|
||||||
|
|
||||||
custom_promise::IPromise& last_read = (*last_read_) >> promise;
|
queue_read_ + promise;
|
||||||
last_read_ = &last_read;
|
|
||||||
|
|
||||||
mutex_read_.unlock();
|
mutex_read_.unlock();
|
||||||
|
|
||||||
@ -122,8 +95,7 @@ public:
|
|||||||
void pdo_write_async(custom_promise::IPromise& promise) {
|
void pdo_write_async(custom_promise::IPromise& promise) {
|
||||||
mutex_write_.lock();
|
mutex_write_.lock();
|
||||||
|
|
||||||
custom_promise::IPromise& last_write = (*last_write_) >> promise;
|
queue_write_ + promise;
|
||||||
last_write_ = &last_write;
|
|
||||||
|
|
||||||
mutex_write_.unlock();
|
mutex_write_.unlock();
|
||||||
}
|
}
|
||||||
@ -131,8 +103,7 @@ public:
|
|||||||
void pdo_read_async(custom_promise::IPromise& promise) {
|
void pdo_read_async(custom_promise::IPromise& promise) {
|
||||||
mutex_read_.lock();
|
mutex_read_.lock();
|
||||||
|
|
||||||
custom_promise::IPromise& last_read = (*last_read_) >> promise;
|
queue_read_ + promise;
|
||||||
last_read_ = &last_read;
|
|
||||||
|
|
||||||
mutex_read_.unlock();
|
mutex_read_.unlock();
|
||||||
}
|
}
|
||||||
@ -145,11 +116,8 @@ private:
|
|||||||
Mutex mutex_write_;
|
Mutex mutex_write_;
|
||||||
Mutex mutex_read_;
|
Mutex mutex_read_;
|
||||||
|
|
||||||
custom_promise::WritePromise<> queue_write_{0};
|
queue::Queue<custom_promise::IPromise> queue_write_;
|
||||||
custom_promise::ReadPromise<> queue_read_{0};
|
queue::Queue<custom_promise::IPromise> queue_read_;
|
||||||
|
|
||||||
custom_promise::IPromise *last_write_{&queue_write_};
|
|
||||||
custom_promise::IPromise *last_read_{&queue_read_};
|
|
||||||
|
|
||||||
uint32_t pdo_counter_{0};
|
uint32_t pdo_counter_{0};
|
||||||
|
|
||||||
@ -207,55 +175,6 @@ private:
|
|||||||
} while(datagram_read.get_all_wkc() < 0x0001);
|
} while(datagram_read.get_all_wkc() < 0x0001);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// Запись PDO замапленных каждым слейвом
|
|
||||||
template<typename... DataTypes>
|
|
||||||
void write(DataTypes&... data) {
|
|
||||||
if(sizeof...(data) > pdo_fmmu_slaves_.size()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t i = 0;
|
|
||||||
custom_tuple<datagram::EcatDatagram<command::LWR, DataTypes>...> datagram_tuple{pdo_fmmu_slaves_[i++].make_datagram_write(data)...};
|
|
||||||
DatagramFunctor functor{ecat_buffer_.get_ecat().get_telegram(), pdo_fmmu_slaves_.size(), nullptr};
|
|
||||||
|
|
||||||
for_each_reverse(datagram_tuple, functor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Чтение PDO замапленных каждым слейвом
|
|
||||||
template<typename... DataTypes>
|
|
||||||
void read(DataTypes&... data) {
|
|
||||||
if(sizeof...(data) > pdo_fmmu_slaves_.size()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t i = 0;
|
|
||||||
custom_tuple<datagram::EcatDatagram<command::LRD, DataTypes>...> datagram_tuple{pdo_fmmu_slaves_[i++].make_datagram_read(data)...};
|
|
||||||
DatagramFunctor functor{ecat_buffer_.get_ecat().get_telegram(), pdo_fmmu_slaves_.size(), nullptr};
|
|
||||||
|
|
||||||
for_each_reverse(datagram_tuple, functor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Последовательность чтения-записи PDO замапленных каждым слейвом
|
|
||||||
template<typename... DataTypes>
|
|
||||||
void read_write(DataTypes&... data) {
|
|
||||||
if(sizeof...(data) > pdo_fmmu_slaves_.size()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t i = 0;
|
|
||||||
size_t j = 0;
|
|
||||||
|
|
||||||
// custom_tuple с датаграммами и на чтение и на запись в две строки. 1 строка - тип, 2 строка - имя переменной
|
|
||||||
custom_tuple<datagram::EcatDatagram<command::LRD, DataTypes>... , datagram::EcatDatagram<command::LWR, DataTypes>...>
|
|
||||||
datagram_tuple{pdo_fmmu_slaves_[i++].make_datagram_read(data)... , pdo_fmmu_slaves_[j++].make_datagram_write(data)...};
|
|
||||||
|
|
||||||
DatagramFunctor functor{ecat_buffer_.get_ecat().get_telegram(), pdo_fmmu_slaves_.size(), nullptr};
|
|
||||||
|
|
||||||
for_each_reverse(datagram_tuple, functor);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ecat_pdo_fmmu
|
} // namespace ecat_pdo_fmmu
|
||||||
|
@ -353,7 +353,7 @@ public:
|
|||||||
sdo_read<TypeT, uint16_t>(telegram, pdo_map_index, pdo_map_subindex, pdo_block_index);
|
sdo_read<TypeT, uint16_t>(telegram, pdo_map_index, pdo_map_subindex, pdo_block_index);
|
||||||
pdo_map.block_index_map[pdo_map_index].emplace(pdo_map_subindex, pdo_block_index);
|
pdo_map.block_index_map[pdo_map_index].emplace(pdo_map_subindex, pdo_block_index);
|
||||||
|
|
||||||
//DebugP_log("pdo_block_index = 0x02%x\r\n", pdo_block_index);
|
DebugP_log("pdo_block_index = 0x02%x\r\n", pdo_block_index);
|
||||||
|
|
||||||
ecat_buffer::PDODescriptor tmp;
|
ecat_buffer::PDODescriptor tmp;
|
||||||
uint8_t& pdo_block_object_count = tmp.size;
|
uint8_t& pdo_block_object_count = tmp.size;
|
||||||
|
@ -18,6 +18,17 @@
|
|||||||
|
|
||||||
namespace free_rtos {
|
namespace free_rtos {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Порядок инициализации:
|
||||||
|
* Инициализировать и открыть драйвер eth_.Init(...), eth_.Open()
|
||||||
|
* Вызвать EthEcatApi::init(eth_);
|
||||||
|
* Создать служебный поток ecat_task_.Create(...) с вызовом EthEcatApi::process()
|
||||||
|
* Вызвать EthEcatApi::config_init(...)
|
||||||
|
* Создать пользовательский поток ecat_task_pdo_.Create(...)
|
||||||
|
* Для чтения/записи данных в пользовательском потоке вызвать
|
||||||
|
* pdo_write(...), pdo_read(...) или pdo_write_async(...), pdo_read_async(...)
|
||||||
|
*/
|
||||||
|
|
||||||
class EthEcatApi {
|
class EthEcatApi {
|
||||||
public:
|
public:
|
||||||
static void init(Eth& eth);
|
static void init(Eth& eth);
|
||||||
|
@ -18,7 +18,7 @@ namespace free_rtos {
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
ECT_PDOOUTPUTOFFSET = 0x1100, // 0x1100 write, output, rx buffer offset
|
ECT_PDOOUTPUTOFFSET = 0x1100, // 0x1100 write, output, rx buffer offset
|
||||||
ECT_PDOINPUTOFFSET = 0x1400 // 0x1400, 0x1140 read, input, tx buffer offset
|
ECT_PDOINPUTOFFSET = 0x1180 // 0x1400, 0x1140 read, input, tx buffer offset
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -22,54 +22,6 @@ namespace free_rtos {
|
|||||||
|
|
||||||
namespace custom_promise {
|
namespace custom_promise {
|
||||||
|
|
||||||
/*
|
|
||||||
// Функтор для обхода и упаковки датаграмм в custom_tuple
|
|
||||||
struct DatagramPackFunctor : public PackFunctor {
|
|
||||||
DatagramPackFunctor(uint8_t *raw)
|
|
||||||
: PackFunctor{raw} { }
|
|
||||||
|
|
||||||
using PackFunctor::operator ();
|
|
||||||
|
|
||||||
template<typename CommandT, typename... DataTypes>
|
|
||||||
void operator()(datagram::EcatDatagram<CommandT, DataTypes...>& data) {
|
|
||||||
raw = data.pack(raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename CommandT, typename... DataTypes>
|
|
||||||
void operator()(std::vector< datagram::EcatDatagram<CommandT, DataTypes...> >& data) {
|
|
||||||
for(uint16_t i = 1; i < data.size(); i++) {
|
|
||||||
raw = data[i - 1].pack(raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
raw = data[data.size() - 1].pack(raw);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Функтор для обхода и распаковки датаграмм в custom_tuple
|
|
||||||
struct DatagramUnpackFunctor : public UnpackFunctor {
|
|
||||||
DatagramUnpackFunctor(uint8_t *raw)
|
|
||||||
: UnpackFunctor{raw} { }
|
|
||||||
|
|
||||||
using UnpackFunctor::operator ();
|
|
||||||
|
|
||||||
template<typename CommandT, typename... DataTypes>
|
|
||||||
void operator()(datagram::EcatDatagram<CommandT, DataTypes...>& data) {
|
|
||||||
raw = data.unpack(raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename CommandT, typename... DataTypes>
|
|
||||||
void operator()(std::vector< datagram::EcatDatagram<CommandT, DataTypes...> >& data) {
|
|
||||||
for(uint16_t i = 1; i < data.size(); i++) {
|
|
||||||
data[i - 1] + data[i];
|
|
||||||
|
|
||||||
raw = data[i - 1].unpack(raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
raw = data[data.size() - 1].unpack(raw);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
template<typename... DataTypes>
|
template<typename... DataTypes>
|
||||||
class Future {
|
class Future {
|
||||||
public:
|
public:
|
||||||
@ -116,30 +68,12 @@ public:
|
|||||||
IPromise(address::Offset offset = 0)
|
IPromise(address::Offset offset = 0)
|
||||||
: offset_{offset} { }
|
: offset_{offset} { }
|
||||||
|
|
||||||
IPromise* get_next() {
|
|
||||||
queue::QueueEntity<IPromise>* next = queue_entity_.get_next();
|
|
||||||
|
|
||||||
if(next == nullptr) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return next->get_data();
|
|
||||||
}
|
|
||||||
|
|
||||||
queue::QueueEntity<IPromise>& get_queue_entity() {
|
queue::QueueEntity<IPromise>& get_queue_entity() {
|
||||||
return queue_entity_;
|
return queue_entity_;
|
||||||
}
|
}
|
||||||
|
|
||||||
IPromise& operator+(IPromise &next) {
|
queue::Queue<IPromise> operator+(IPromise &next) {
|
||||||
queue_entity_ + next.get_queue_entity();
|
return queue::Queue<IPromise>{queue_entity_, next.get_queue_entity()};
|
||||||
|
|
||||||
return next;
|
|
||||||
}
|
|
||||||
|
|
||||||
IPromise& operator>>(IPromise &next) {
|
|
||||||
queue_entity_ >> next.get_queue_entity();
|
|
||||||
|
|
||||||
return next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void set_value(uint8_t* process_data, uint32_t len) = 0;
|
virtual void set_value(uint8_t* process_data, uint32_t len) = 0;
|
||||||
|
@ -114,14 +114,12 @@ struct each_tuple_element< FunctorT, custom_tuple<> > {
|
|||||||
template<typename TupleT, typename FunctorT>
|
template<typename TupleT, typename FunctorT>
|
||||||
void for_each(TupleT& t, FunctorT& functor) {
|
void for_each(TupleT& t, FunctorT& functor) {
|
||||||
each_tuple_element<FunctorT, TupleT>::for_each(functor, t);
|
each_tuple_element<FunctorT, TupleT>::for_each(functor, t);
|
||||||
functor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Функция для обратного обхода элементов custom_tuple
|
// Функция для обратного обхода элементов custom_tuple
|
||||||
template<typename TupleT, typename FunctorT>
|
template<typename TupleT, typename FunctorT>
|
||||||
void for_each_reverse(TupleT& t, FunctorT& functor) {
|
void for_each_reverse(TupleT& t, FunctorT& functor) {
|
||||||
each_tuple_element<FunctorT, TupleT>::for_each_reverse(functor, t);
|
each_tuple_element<FunctorT, TupleT>::for_each_reverse(functor, t);
|
||||||
functor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -48,20 +48,10 @@ public:
|
|||||||
return queue_entity_;
|
return queue_entity_;
|
||||||
}
|
}
|
||||||
|
|
||||||
IEcatDatagram& operator+(IEcatDatagram &next) {
|
queue::Queue<IEcatDatagram> operator+(IEcatDatagram &next) {
|
||||||
more_ = ec_moredatagrams::EC_MOREDATAGRAMS_MORE;
|
more_ = ec_moredatagrams::EC_MOREDATAGRAMS_MORE;
|
||||||
|
|
||||||
queue_entity_ + next.get_queue_entity();
|
return queue::Queue<IEcatDatagram>{queue_entity_, next.get_queue_entity()};
|
||||||
|
|
||||||
return next;
|
|
||||||
}
|
|
||||||
|
|
||||||
IEcatDatagram& operator>>(IEcatDatagram &next) {
|
|
||||||
more_ = ec_moredatagrams::EC_MOREDATAGRAMS_MORE;
|
|
||||||
|
|
||||||
queue_entity_ >> next.get_queue_entity();
|
|
||||||
|
|
||||||
return next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual uint8_t* pack(uint8_t *raw) = 0;
|
virtual uint8_t* pack(uint8_t *raw) = 0;
|
||||||
|
@ -29,8 +29,6 @@ struct PackFunctorBase {
|
|||||||
|
|
||||||
//DebugP_log((char*)"Data packed: %d\r\n", sizeof(DataT));
|
//DebugP_log((char*)"Data packed: %d\r\n", sizeof(DataT));
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()() { }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Функтор для обхода и упаковки элементов custom_tuple
|
// Функтор для обхода и упаковки элементов custom_tuple
|
||||||
|
@ -14,6 +14,9 @@ namespace free_rtos {
|
|||||||
|
|
||||||
namespace queue {
|
namespace queue {
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
class Queue;
|
||||||
|
|
||||||
template<typename DataType>
|
template<typename DataType>
|
||||||
class QueueEntity {
|
class QueueEntity {
|
||||||
public:
|
public:
|
||||||
@ -28,67 +31,87 @@ public:
|
|||||||
return next_;
|
return next_;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t get_size() {
|
|
||||||
return size_;
|
|
||||||
}
|
|
||||||
|
|
||||||
QueueEntity& operator+(QueueEntity& next) {
|
|
||||||
append(next);
|
|
||||||
//set_next(next);
|
|
||||||
|
|
||||||
return next;
|
|
||||||
}
|
|
||||||
|
|
||||||
QueueEntity& operator>>(QueueEntity& next) {
|
|
||||||
attach(next);
|
|
||||||
|
|
||||||
return next;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
DataType *data_{nullptr};
|
|
||||||
|
|
||||||
QueueEntity *next_{nullptr};
|
|
||||||
QueueEntity *first_{this};
|
|
||||||
QueueEntity *last_{this};
|
|
||||||
|
|
||||||
size_t size_{1};
|
|
||||||
|
|
||||||
void set_next(QueueEntity &next) {
|
void set_next(QueueEntity &next) {
|
||||||
next_ = &next;
|
next_ = &next;
|
||||||
}
|
}
|
||||||
|
|
||||||
QueueEntity* get_last() {
|
private:
|
||||||
|
DataType *data_{nullptr};
|
||||||
|
QueueEntity *next_{nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
class Queue {
|
||||||
|
public:
|
||||||
|
Queue() { }
|
||||||
|
|
||||||
|
explicit Queue(QueueEntity<DataType>& first)
|
||||||
|
: first_{&first}
|
||||||
|
, last_{&first} { }
|
||||||
|
|
||||||
|
Queue(QueueEntity<DataType>& first, QueueEntity<DataType>& next)
|
||||||
|
: first_{&first}
|
||||||
|
, last_{&next} {
|
||||||
|
first.set_next(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
QueueEntity<DataType>* get_first() {
|
||||||
|
return first_;
|
||||||
|
}
|
||||||
|
|
||||||
|
QueueEntity<DataType>* get_last() {
|
||||||
return last_;
|
return last_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_first(QueueEntity* first) {
|
size_t get_size() {
|
||||||
first_ = first;
|
return size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
QueueEntity* append(QueueEntity& next) {
|
Queue& operator+(QueueEntity<DataType>& next) {
|
||||||
if(this != first_) {
|
return append(&next);
|
||||||
first_ = first_->append(next);
|
|
||||||
}else{
|
|
||||||
last_->set_next(next);
|
|
||||||
last_ = next.get_last();
|
|
||||||
|
|
||||||
next.set_first(first_);
|
|
||||||
|
|
||||||
size_++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return first_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QueueEntity* attach(QueueEntity& next) {
|
Queue& operator+(DataType& data) {
|
||||||
if(this != first_) {
|
return append(&data.get_queue_entity());
|
||||||
first_ = first_->attach(next);
|
}
|
||||||
}else{
|
|
||||||
last_->set_next(next);
|
Queue& operator+(Queue& other) {
|
||||||
|
return append(other.get_first(), other.get_last(), other.get_size());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() {
|
||||||
|
return (first_ == nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
first_ = nullptr;
|
||||||
|
last_ = nullptr;
|
||||||
|
size_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QueueEntity<DataType> *first_{nullptr};
|
||||||
|
QueueEntity<DataType> *last_{nullptr};
|
||||||
|
size_t size_{0};
|
||||||
|
|
||||||
|
Queue& append(QueueEntity<DataType> *other_first, QueueEntity<DataType> *other_last = nullptr, size_t other_size = 1) {
|
||||||
|
if(first_ == nullptr) {
|
||||||
|
first_ = other_first;
|
||||||
}
|
}
|
||||||
|
|
||||||
return first_;
|
if(last_ != nullptr) {
|
||||||
|
last_->set_next(*other_first);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(other_last == nullptr) {
|
||||||
|
last_ = other_first;
|
||||||
|
}else{
|
||||||
|
last_ = other_last;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_ += other_size;
|
||||||
|
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user