168 lines
4.3 KiB
C++
168 lines
4.3 KiB
C++
/*
|
||
* ControlSystemWrapper.hpp
|
||
*
|
||
* Created on: 30 мая 2020 г.
|
||
* Author: LeonidTitov
|
||
*/
|
||
|
||
#ifndef UMLIBRARY_TECHNOLOGICAL_ADAPTER_CONTROLSYSTEMWRAPPER_HPP_
|
||
#define UMLIBRARY_TECHNOLOGICAL_ADAPTER_CONTROLSYSTEMWRAPPER_HPP_
|
||
|
||
#include "../../common/ResourceKeeper.hpp"
|
||
|
||
namespace technological { namespace adapter {
|
||
|
||
template<class Input>
|
||
struct TieInterface {
|
||
virtual Input * try_connect() = 0;
|
||
virtual void disconnect() = 0;
|
||
|
||
typedef Input InputConnector;
|
||
|
||
virtual ~TieInterface() = default;
|
||
};
|
||
|
||
//Грабим два интерфейса, связываем, предоставляем один интерфейс.
|
||
template<class Input, class Interconnect, class Output, class OnConnect, class OnDisonnect>
|
||
class TieWrapper : public TieInterface<Input> {
|
||
public:
|
||
|
||
Input * try_connect();
|
||
void disconnect();
|
||
|
||
TieWrapper( ResourceKeeper<Interconnect> & interconnect, TieInterface<Output> & output,
|
||
OnConnect on_connect = OnConnect(), OnDisonnect on_disconnect = OnDisonnect() ) :
|
||
interconnect(interconnect), output(output), on_connect(on_connect), on_disconnect(on_disconnect) {}
|
||
|
||
typedef TieInterface<Input> Interface;
|
||
|
||
private:
|
||
Locable<Interconnect> interconnect;
|
||
TieInterface<Output> & output;
|
||
|
||
OnConnect on_connect;
|
||
OnDisonnect on_disconnect;
|
||
};
|
||
|
||
template<class Input, class Interconnect, class OnConnect, class OnDisonnect>
|
||
class EndpointWrapper : public TieInterface<Input> {
|
||
public:
|
||
|
||
Input * try_connect();
|
||
void disconnect();
|
||
|
||
EndpointWrapper( ResourceKeeper<Interconnect> & endpoint, OnConnect on_connect = OnConnect(), OnDisonnect on_disconnect = OnDisonnect() ) :
|
||
interconnect(endpoint), on_connect(on_connect), on_disconnect(on_disconnect) {}
|
||
|
||
private:
|
||
Locable<Interconnect> interconnect;
|
||
|
||
OnConnect on_connect;
|
||
OnDisonnect on_disconnect;
|
||
};
|
||
|
||
template<class Input, class Interconnect>
|
||
class TieInterconnector : public TieInterface<Input> {
|
||
public:
|
||
|
||
Input * try_connect();
|
||
void disconnect();
|
||
|
||
TieInterconnector( TieInterface<Input> & a, TieInterface<Input> & b, Interconnect interconnect = Interconnect() ) :
|
||
a(a), b(b), interconnect(interconnect) {}
|
||
|
||
private:
|
||
TieInterface<Input> & a;
|
||
TieInterface<Input> & b;
|
||
|
||
Interconnect interconnect;
|
||
};
|
||
|
||
}
|
||
}
|
||
|
||
template<class Input, class Interconnect, class Output, class OnConnect, class OnDisonnect>
|
||
inline Input * technological::adapter::TieWrapper<Input, Interconnect, Output, OnConnect, OnDisonnect>::try_connect() {
|
||
|
||
if( interconnect.try_lock() ) {
|
||
|
||
Output * out_interface = output.try_connect();
|
||
|
||
if( out_interface ) {
|
||
|
||
on_connect( interconnect.pointer(), out_interface );
|
||
|
||
} else
|
||
interconnect.unlock();
|
||
}
|
||
|
||
return interconnect.pointer();
|
||
|
||
}
|
||
|
||
template<class Input, class Interconnect, class Output, class OnConnect, class OnDisonnect>
|
||
inline void technological::adapter::TieWrapper<Input, Interconnect, Output, OnConnect, OnDisonnect>::disconnect() {
|
||
|
||
on_disconnect( interconnect.pointer() );
|
||
|
||
output.disconnect();
|
||
|
||
interconnect.unlock();
|
||
|
||
}
|
||
|
||
template<class Input, class Interconnect, class OnConnect, class OnDisonnect>
|
||
inline Input * technological::adapter::EndpointWrapper<Input, Interconnect,
|
||
OnConnect, OnDisonnect>::try_connect() {
|
||
|
||
if( interconnect.try_lock() ) {
|
||
|
||
on_connect( interconnect.pointer() );
|
||
|
||
}
|
||
|
||
return interconnect.pointer();
|
||
}
|
||
|
||
template<class Input, class Interconnect, class OnConnect, class OnDisonnect>
|
||
inline void technological::adapter::EndpointWrapper<Input, Interconnect,
|
||
OnConnect, OnDisonnect>::disconnect() {
|
||
|
||
on_disconnect( interconnect.pointer() );
|
||
|
||
interconnect.unlock();
|
||
}
|
||
|
||
template<class Input, class Interconnect>
|
||
inline Input * technological::adapter::TieInterconnector<Input, Interconnect>::try_connect() {
|
||
|
||
Input * output = nullptr;
|
||
|
||
Input * input_a = a.try_connect();
|
||
|
||
if( input_a ) {
|
||
|
||
Input * input_b = b.try_connect();
|
||
|
||
if( input_b ) {
|
||
|
||
output = interconnect( input_a, input_b );
|
||
|
||
} else
|
||
a.disconnect();
|
||
|
||
}
|
||
|
||
return output;
|
||
}
|
||
|
||
template<class Input, class Interconnect>
|
||
inline void technological::adapter::TieInterconnector<Input, Interconnect>::disconnect() {
|
||
|
||
b.disconnect();
|
||
a.disconnect();
|
||
|
||
}
|
||
|
||
#endif /* UMLIBRARY_TECHNOLOGICAL_ADAPTER_CONTROLSYSTEMWRAPPER_HPP_ */
|