Skip navigation links
IT services and product development
Menu
TwoLogs
IT services and product development

Source code for C_Connector

Download

The source files for this module are listed below.  You can also download the module C_Connector as a zip archive; this archive contains all the source files and documentation.

Description

Connectors allow bi-directional linked list-like connections between an arbitrary amount of objects.

Information

The TConnector class is a base class that allows your classes to be linked together in a linked list-like manner.  All the links are bi-directional.  You can link as many objects together as you want; the linking structure is not limited to a flat (two-dimensional) list.

To connect two objects together, just call Connect on one of them and pass it the object to connect to.  The reverse connection will also automatically be added.  To disconnect two objects, just call the Disconnect method and pass it the object to disconnect from.  You can also call the DisconnectAll method to disconnect the object from all it's connected objects.  The IsConnected and ConnectionCount methods allow you to query the connection status of an object.

A TConnector object also implements STL-like begin() and end() methods to access all connected objects via a standard STL iterator.

If a TConnector object goes out of scope, it will also automatically break all it's connections.

Files

Each file belonging to this source code module is listed below.

Connector.h

/*******************************************************************************

  Version: 4
  Author:  Carl Colijn, TwoLogs
  Contact: c.colijn@twologs.com
  Source:  https://www.twologs.com/sourcecode

  This code is freely distributable, as long as this comment remains intact.
  If you find this source useful, you may use this code in your own projects
  free of charge, but some acknowledgement to the author of this code is always
  appreciated :)
  The source is however distributed 'as is' without waranty and/or support, and
  may not be fit for each and every application.  Use it at your own discretion
  and at your own risk.
  The source already has undergone testing.  This doesn't mean however that all
  bugs are removed from this piece of code.  If you find one of them, please
  contact me about it.  I can however not guarantee when and if the bug will be
  fixed.

  More information about this module can be found in the accompanying HTML file.

*******************************************************************************/

#ifndef INCLUDE_TWOLOGS_COMMON_CONNECTOR_H
#define INCLUDE_TWOLOGS_COMMON_CONNECTOR_H

#include <set>

class TConnector {
public:
  // Con- & destructor
  TConnector();
  virtual ~TConnector();

  // Makes a new connection with the given connector
  bool Connect(TConnector* otherPtr);

  // Disconnects the connection from the given connector
  bool Disconnect(TConnector* otherPtr);

  // Disconnects all connectors
  bool DisconnectAll();

  // The range of connected connectors
  typedef std::multiset<TConnector*> TConnectorPtrs;
  TConnectorPtrs::iterator begin();
  TConnectorPtrs::iterator end();

  // Returns whether we are connected to other connectors
  bool IsConnected() const;

  // Returns the number of connected connectors
  unsigned long ConnectionCount() const;

private:
  // The connections connected to this connector
  TConnectorPtrs m_connectorPtrs;
};

#endif // INCLUDE_TWOLOGS_COMMON_CONNECTOR_H

Connector.cpp

/*******************************************************************************

  Version: 4
  Author:  Carl Colijn, TwoLogs
  Contact: c.colijn@twologs.com
  Source:  https://www.twologs.com/sourcecode

  This code is freely distributable, as long as this comment remains intact.
  If you find this source useful, you may use this code in your own projects
  free of charge, but some acknowledgement to the author of this code is always
  appreciated :)
  The source is however distributed 'as is' without waranty and/or support, and
  may not be fit for each and every application.  Use it at your own discretion
  and at your own risk.
  The source already has undergone testing.  This doesn't mean however that all
  bugs are removed from this piece of code.  If you find one of them, please
  contact me about it.  I can however not guarantee when and if the bug will be
  fixed.

  More information about this module can be found in the accompanying HTML file.

*******************************************************************************/

#include "Connector.h"

// Con- & destructor
TConnector::TConnector() {
}
TConnector::~TConnector() {
  // Disconnect all our connections
  while (m_connectorPtrs.size() > 0) {
    Disconnect(*m_connectorPtrs.begin());
  }
}

// Makes a new connection with the given connector
bool TConnector::Connect(TConnector* otherPtr) {
  // Add us to the list of the other connector
  auto otherNewConnectorPtrPtr = otherPtr->m_connectorPtrs.insert(this);
  bool allOK = otherNewConnectorPtrPtr != otherPtr->m_connectorPtrs.end();
  if (allOK) {
    // Done -> also add the other connector to our list
    auto ourNewConnectorPtrPtr = m_connectorPtrs.insert(otherPtr);
    allOK = ourNewConnectorPtrPtr != m_connectorPtrs.end();
    if (!allOK) {
      // Couldn't -> remove us from the list of the other connector again
      otherPtr->m_connectorPtrs.erase(otherNewConnectorPtrPtr);
    }
  }

  // And return if a new connection could be established
  return allOK;
}

// Disconnects the connection from the given connector
bool TConnector::Disconnect(TConnector* otherPtr) {
  // Disconnect us from the other connector
  return 1 == m_connectorPtrs.erase(otherPtr) &&
  // ... and the other way around as well
         1 == otherPtr->m_connectorPtrs.erase(this);
}

// Disconnects all connectors
bool TConnector::DisconnectAll() {
  bool allOK = true;
  for(TConnector* otherPtr: m_connectorPtrs) {
    allOK = allOK && (1 == otherPtr->m_connectorPtrs.erase(this));
  }
  m_connectorPtrs.clear();
  return allOK;
}

// The range of connected connectors
TConnector::TConnectorPtrs::iterator TConnector::begin() {
  return m_connectorPtrs.begin();
}
TConnector::TConnectorPtrs::iterator TConnector::end() {
  return m_connectorPtrs.end();
}

// Returns whether we are connected to other connectors
bool TConnector::IsConnected() const {
  return m_connectorPtrs.begin() != m_connectorPtrs.end();
}

// Returns the number of connected connectors
unsigned long TConnector::ConnectionCount() const {
  return m_connectorPtrs.size();
}