RISC-V/V203/usb/common/mirror.h
2024-10-15 19:26:19 +02:00

60 lines
1.9 KiB
C++

#ifndef MIRROR_H
#define MIRROR_H
#include <stdio.h>
#include "baselayer.h"
/**
* @file
* @brief Obraceč datového toku.
* @class Mirror
* @brief Obraceč datového toku má 2 třídy.
*
* TwoTop je vlastní obraceč, dědí vlastnosti BaseLayer, pouze metoda Up je přetížena -
* to je to vlastní převrácení. Hlavní třída Mirror, jejíž instance je pak v kódu použita
* obsahuje 2 rovnocenné instance třídy TwoTop, které musí být ve stacku vždy navrchu.
* První část stacku volá Up jedné instance, druhá Up té druhé. Proto tam musí být dvě.
* Podobně by šel udělat něco jako Fork, odbočení datového toku.
* A zase - všechny metody jsou tak jednoduché, že jsou celé v hlavičce, tedy inline.
*
* @class TwoTop
* @brief Vlastní obraceč.
* Ono to vypadá hodně zmateně, ale používá se to snadno - dokonce to funguje.
*
*/
class TwoTop : public BaseLayer {
public:
/// Konstruktor
explicit TwoTop () noexcept : BaseLayer (), x (nullptr) {};
/// Setter pro x
void setX (BaseLayer & bl) { x = & bl; };
/// Přetížení metody Up, nic jiného není potřeba
uint32_t Up (const char* data, uint32_t len) {
if (!x) return 0; // pro jistotu
// To, co přišlo zespoda, pošlu druhou instancí zase dolů
return x->Down (data, len);
};
private:
/// Fakticky ukazatel na druhou instanci TwoTop
BaseLayer * x;
};
class Mirror {
public:
/// Konstruktor
explicit Mirror () noexcept : L(), R() {
L.setX (R); R.setX (L);
};
/**
Zřetězení voláme 2x. Poprvé pro jednu +=, podruhé -= pro druhou instanci TwoTop.
Protože je tato třída navrchu (vlevo), operátor nic nevrací.
*/
void operator += (BaseLayer& bl) { L += bl; return; };
void operator -= (BaseLayer& bl) { R += bl; return; };
private:
TwoTop L, R; //!< 2 instance Top
};
#endif // MIRROR_H