Skip to content
Snippets Groups Projects
PackingAbstraction.hpp 3.72 KiB
Newer Older
/*
 * PackingAbstraction.hpp
 *
 *  Created on: 29. 5. 2018
 *	  Author: Jan Travnicek
 */

#ifndef _PACKING_ABSTRACTION_HPP_
#define _PACKING_ABSTRACTION_HPP_

#include <abstraction/ValueOperationAbstraction.hpp>
#include <alib/memory>
#include <alib/array>
#include <registry/Registry.h>

namespace abstraction {

template < class ... ParamTypes >
class PackingAbstraction : public OperationAbstraction {
	struct ConnectionTarget {
		unsigned targetId;
		unsigned paramPosition;
	};

	ext::vector < std::shared_ptr < abstraction::OperationAbstraction > > m_abstractions;
	ext::array < ext::vector < ConnectionTarget >, sizeof ... ( ParamTypes ) > m_connections;
	unsigned m_resultId;

public:
	PackingAbstraction ( ext::vector < std::shared_ptr < abstraction::OperationAbstraction > > abstractions, unsigned resultId ) : m_abstractions ( std::move ( abstractions ) ), m_resultId ( resultId ) {
	}

	bool setInnerConnection ( unsigned sourceId, unsigned targetId, unsigned paramPosition, bool move ) {
		return m_abstractions [ targetId ]->attachInput ( m_abstractions [ sourceId ], paramPosition, move );
	}

	bool clearInnerConnection ( unsigned targetId, unsigned paramPosition ) {
		return m_abstractions [ targetId ]->detachInput ( paramPosition );
	}

	void setOuterConnection ( unsigned sourceId, unsigned targetId, unsigned paramPosition ) {
		m_connections [ sourceId ].push_back ( ConnectionTarget { targetId, paramPosition } );
	}

private:
	virtual bool attachInput ( const std::shared_ptr < OperationAbstraction > & input, unsigned index, bool move ) override {
		for ( const ConnectionTarget & target : m_connections [ index ] )
			m_abstractions [ target.targetId ]->attachInput ( input, target.paramPosition, move );

		return true;
	}

	virtual bool detachInput ( unsigned index ) override {
		for ( const ConnectionTarget & target : m_connections [ index ] )
			m_abstractions [ target.targetId ]->detachInput ( target.paramPosition );

		return true;
	}
public:
	virtual bool inputsReady ( ) const override {
		for ( const std::shared_ptr < abstraction::OperationAbstraction > & operation : m_abstractions )
			if ( operation->inputsReady ( ) == false )
				return false;

		return true;
	}

	virtual bool inputsAttached ( ) const override {
		for ( const std::shared_ptr < abstraction::OperationAbstraction > & operation : m_abstractions )
			if ( operation->inputsAttached ( ) == false )
				return false;

		return true;
	}

	virtual bool run ( ) override {
		if ( ! this->inputsReady ( ) )
			return false;

		if ( this->cached ( ) )
			return true;

		return m_abstractions [ m_resultId ]->run ( );
	}

	virtual bool eval ( ) override {
		if ( ! inputsAttached ( ) )
			return false;

		if ( this->cached ( ) )
			return true;

		return m_abstractions [ m_resultId ]->eval ( );
	}

	virtual unsigned numberOfParams ( ) const override {
		return sizeof ... ( ParamTypes );
	}

	virtual bool isReady ( ) const override {
		return m_abstractions [ m_resultId ]->isReady ( );
	}

	virtual bool cached ( ) const override {
		return isReady ( );
	}

	virtual ext::type_index getParamTypeIndex ( unsigned index ) const override {
		return m_abstractions [ m_connections.at ( index ) [ 0 ].targetId ]->getParamTypeIndex ( m_connections.at ( index ) [ 0 ].paramPosition );
	}

	virtual ext::type_index getReturnTypeIndex ( ) const override {
		return m_abstractions [ m_resultId ]->getReturnTypeIndex ( );
	}

	virtual ext::type_index getRuntimeReturnTypeIndex ( ) const override {
		return m_abstractions [ m_resultId ]->getRuntimeReturnTypeIndex ( );
	}

	virtual std::shared_ptr < abstraction::OperationAbstraction > getProxyAbstraction ( ) override {
		return m_abstractions [ m_resultId ]->getProxyAbstraction ( );
	}

};

} /* namespace abstraction */

#endif /* _PACKING_ABSTRACTION_HPP_ */