<commit_before>// Copyright (C) 2014 - 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

#include <limits>

#include "copasi.h"

#include "CMathEventQueue.h"
#include "CMathContainer.h"
#include "CMathEvent.h"
#include "function/CExpression.h"
#include "randomGenerator/CRandom.h"

#include "copasi/report/CCopasiRootContainer.h"
#include "copasi/commandline/CConfigurationFile.h"

// Uncomment this line below to get debug print out.
// #define DEBUG_OUTPUT 1

CMathEventQueue::CKey::CKey() :
  mExecutionTime(0.0),
  mCascadingLevel(0),
  mEquality(false)
{}

CMathEventQueue::CKey::CKey(const CKey & src) :
  mExecutionTime(src.mExecutionTime),
  mCascadingLevel(src.mCascadingLevel),
  mEquality(src.mEquality)
{}

CMathEventQueue::CKey::CKey(const C_FLOAT64 & executionTime,
                            const bool & equality,
                            const size_t & cascadingLevel):
  mExecutionTime(executionTime),
  mCascadingLevel(cascadingLevel),
  mEquality(equality)
{}

CMathEventQueue::CKey::~CKey()
{}

bool CMathEventQueue::CKey::operator < (const CMathEventQueue::CKey & rhs) const
{
  if (mExecutionTime != rhs.mExecutionTime)
    return mExecutionTime < rhs.mExecutionTime;

  if (mCascadingLevel != rhs.mCascadingLevel)
    return mCascadingLevel > rhs.mCascadingLevel;

  return mEquality < rhs.mEquality;
}

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

CMathEventQueue::CAction::CAction():
  mType(),
  mValues(),
  mpPriority(NULL),
  mpEvent(NULL),
  mpProcessQueue(NULL)
{}

CMathEventQueue::CAction::CAction(const CAction & src):
  mType(src.mType),
  mpPriority(src.mpPriority),
  mValues(src.mValues),
  mpEvent(src.mpEvent),
  mpProcessQueue(src.mpProcessQueue)
{}

CMathEventQueue::CAction::CAction(CMathEvent * pEvent,
                                  CMathEventQueue * pProcessQueue):
  mType(),
  mValues(),
  mpPriority(NULL),
  mpEvent(pEvent),
  mpProcessQueue(pProcessQueue)
{
  mpPriority = (const C_FLOAT64 *) pEvent->getPriority()->getValuePointer();

  switch (pEvent->getType())
    {
      case CEvent::Assignment:
      case CEvent::Discontinuity:
        mType = Calculation;
        break;

      case CEvent::Callback:
        mType = Callback;
        break;
    }
}

CMathEventQueue::CAction::CAction(const CVector< C_FLOAT64 > & values,
                                  CMathEvent * pEvent,
                                  CMathEventQueue * pProcessQueue) :
  mType(CMathEventQueue::CAction::Assignment),
  mpPriority(NULL),
  mValues(values),
  mpEvent(pEvent),
  mpProcessQueue(pProcessQueue)
{
  mpPriority = (const C_FLOAT64 *) pEvent->getPriority()->getValuePointer();
}

CMathEventQueue::CAction::~CAction()
{}

CMath::StateChange CMathEventQueue::CAction::process()
{
  // Assume that nothing is changed
  CMath::StateChange StateChange = CMath::NoChange;

  switch (mType)
    {
      case Calculation:

        if (mpEvent->delayAssignment())
          {
            mpProcessQueue->addAssignment(mpEvent->getExecutionTime(),
                                          mpProcessQueue->mEquality,
                                          mpEvent->getTargetValues(),
                                          mpEvent);
          }
        else
          {
            StateChange = mpEvent->executeAssignment();
          }

        break;

      case Assignment:
        StateChange = mpEvent->setTargetValues(mValues);
        break;

      case Callback:
        mpEvent->executeCallback(mpProcessQueue);
        break;
    }

  return StateChange;
}

CMathEvent * CMathEventQueue::CAction::getEvent() const {return mpEvent;}

const CMathEventQueue::CAction::Type & CMathEventQueue::CAction::getType() const {return mType;}

const C_FLOAT64 & CMathEventQueue::CAction::getPriority() const {return *mpPriority;}

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

CMathEventQueue::CMathEventQueue() :
  mpContainer(NULL),
  mpTime(NULL),
  mActions(),
  mUpdateSequence(),
  mExecutionLimit(10000),
  mExecutionCounter(0),
  mEquality(true),
  mCascadingLevel(0),
  mRootsFound(0),
  mRootValues1(0),
  mRootValues2(0),
  mpRootValuesBefore(&mRootValues1),
  mpRootValuesAfter(&mRootValues2)
{}

CMathEventQueue::CMathEventQueue(CMathContainer & container):
  mpContainer(& container),
  mpTime(NULL),
  mActions(),
  mUpdateSequence(),
  mExecutionLimit(10000),
  mExecutionCounter(0),
  mEquality(true),
  mCascadingLevel(0),
  mRootsFound(0),
  mRootValues1(0),
  mRootValues2(0),
  mpRootValuesBefore(&mRootValues1),
  mpRootValuesAfter(&mRootValues2)
{}

CMathEventQueue::~CMathEventQueue()
{}

bool CMathEventQueue::addAssignment(const C_FLOAT64 & executionTime,
                                    const bool & equality,
                                    const CVectorCore< C_FLOAT64 > & values,
                                    CMathEvent * pEvent)
{
  // It is not possible to proceed backwards in time.
  if (executionTime < *mpTime) return false;

  size_t CascadingLevel = mCascadingLevel;

  // If the assignment is in the future or it has a priority the
  // cascading level must be zero.
  if (executionTime > *mpTime ||
      !isnan(* (C_FLOAT64 *) pEvent->getPriority()->getValuePointer()))
    CascadingLevel = 0;

  pEvent->addPendingAction(mActions.insert(std::make_pair(CKey(executionTime, equality, CascadingLevel),
                           CAction(values, pEvent, this))));

  return true;
}

bool CMathEventQueue::addCalculation(const C_FLOAT64 & executionTime,
                                     const bool & equality,
                                     CMathEvent * pEvent)
{
  // It is not possible to proceed backwards in time.
  if (executionTime < *mpTime) return false;

  size_t CascadingLevel = mCascadingLevel;

  // If the assignment is in the future or it has a priority the
  // cascading level must be zero.
  if (executionTime > *mpTime ||
      !isnan(* (C_FLOAT64 *) pEvent->getPriority()->getValuePointer()))
    CascadingLevel = 0;

  pEvent->addPendingAction(mActions.insert(std::make_pair(CKey(executionTime, equality, CascadingLevel),
                           CAction(pEvent, this))));

  return true;
}

void CMathEventQueue::removeAction(const std::pair< CMathEventQueue::CKey, CMathEventQueue::CAction > & action)
{
  range PendingActions = mActions.equal_range(action.first);

  iterator itAction = PendingActions.first;

  for (; itAction != PendingActions.second; ++itAction)
    {
      if (itAction->second.getEvent() == action.second.getEvent())
        {
          mActions.erase(itAction);
          break;
        }
    }
}

void CMathEventQueue::start()
{
  mActions.clear();

  mpTime = mpContainer->getState(false).array() + mpContainer->getCountFixedEventTargets();

  size_t NumRoots = mpContainer->getRoots().size();
  mRootsFound.resize(NumRoots);
  mRootsFound = 0;
  mRootValues1.resize(NumRoots);
  mRootValues2.resize(NumRoots);
  mpRootValuesBefore = &mRootValues1;
  mpRootValuesAfter = &mRootValues2;

  return;
}

CMath::StateChange CMathEventQueue::process(const bool & priorToOutput)
{
  if (getProcessQueueExecutionTime() > *mpTime)
    return CMath::NoChange;

  mEquality = priorToOutput;
  mExecutionCounter = 0;
  mCascadingLevel = 0;

  bool success = true;
  CMath::StateChange StateChange = CMath::NoChange;

  *mpRootValuesBefore = mpContainer->getRoots();
  mpContainer->updatePriorityValues();

  iterator itAction = getAction();

#ifdef DEBUG_OUTPUT
  std::cout << "State: " << mpContainer->getState(false) << std::endl;
  std::cout << "Roots: " << mpContainer->getRoots() << std::endl;
#endif //DEBUG_OUTPUT

  // The algorithm below will work properly for user ordered events
  // as the queue enforces the proper ordering.
  while (success &&
         itAction != mActions.end() &&
         mCascadingLevel != std::numeric_limits<size_t>::max())
    {
      CMath::StateChange ActionStateChange = executeAction(itAction);
      StateChange |= ActionStateChange;

      if (ActionStateChange != CMath::NoChange)
        {
          mpContainer->updatePriorityValues();
        }

      // State change does not indicate whether we have any root changes. We need to
      // explicitly check for it.
#ifdef DEBUG_OUTPUT
      std::cout << "State: " << mpContainer->getState(false) << std::endl;
      std::cout << "Roots: " << mpContainer->getRoots() << std::endl;
#endif // DEBUG_OUTPUT

      // We switch to the next cascading level so that events triggered by the
      // execution of assignments are properly scheduled.
      mCascadingLevel++;

      // We need to compare the roots before the execution and after
      // to determine which roots need to be charged.
      if (rootsFound())
        {
          // We have to deal with both types of found roots.
          mpContainer->processRoots(mRootsFound);
        }

      // Note, applying the events may have added new events to the queue.
      // The setting of the equality flag for these events may be either true
      // or false.

      // First we handle equalities.
      mEquality = true;

      // Retrieve the pending calculations.
      itAction = getAction();

      while (itAction == mActions.end() &&
             mCascadingLevel > 0)
        {
          // If we are here we have no more actions for this level.
          mCascadingLevel--;

          if (mCascadingLevel == 0)
            {
              mEquality = priorToOutput;
            }

          itAction = getAction();
        }
    }

  return StateChange;
}

CMathEventQueue::iterator CMathEventQueue::getAction()
{
  CKey Pending(*mpTime, mEquality, mCascadingLevel);
  range PendingActions = mActions.equal_range(Pending);

  if (PendingActions.first == PendingActions.second)
    {
      return mActions.end();
    }

  iterator itAction = PendingActions.first;

  std::vector< iterator > PriorityActions;
  C_FLOAT64 HighestPriority = - std::numeric_limits< C_FLOAT64 >::infinity();

  for (; itAction != PendingActions.second; ++itAction)
    {
      // Events without priority are ignored
      if (isnan(itAction->second.getPriority()))
        {
          continue;
        }

      // The priority is lower than the highest
      if (itAction->second.getPriority() < HighestPriority)
        {
          continue;
        }

      // New highest priority
      if (HighestPriority < itAction->second.getPriority())
        {
          HighestPriority = itAction->second.getPriority();
          PriorityActions.clear();
          PriorityActions.push_back(itAction);

          continue;
        }

      // Equal highest priority
      PriorityActions.push_back(itAction);
    }

  switch (PriorityActions.size())
    {
      // No prioritized actions
      case 0:
        // We arbitrarily pick the first
        return PendingActions.first;
        break;

      // One action has the highest priority
      case 1:
        return PriorityActions[0];
        break;

      // Pick one randomly
      default:
        return PriorityActions[mpContainer->getRandomGenerator().getRandomU(PriorityActions.size() - 1)];
        break;
    }

  // We should never get here
  return mActions.end();
}

CMath::StateChange CMathEventQueue::executeAction(CMathEventQueue::iterator itAction)
{
  // Notify the event that the pending action is executed.
  itAction->second.getEvent()->removePendingAction();

  CMath::StateChange StateChange = itAction->second.process();

  mExecutionCounter++;

  mActions.erase(itAction);

  return StateChange;
}

bool CMathEventQueue::rootsFound()
{
  bool rootsFound = false;

  // Calculate the current root values
  *mpRootValuesAfter = mpContainer->getRoots();

  // Compare the root values before and after;
  C_INT * pRootFound = mRootsFound.array();
  C_INT * pRootEnd = pRootFound + mRootsFound.size();
  C_FLOAT64 * pValueBefore = mpRootValuesBefore->array();
  C_FLOAT64 * pValueAfter = mpRootValuesAfter->array();
  CMathEvent::CTrigger::CRootProcessor ** ppRootProcessor = mpContainer->getRootProcessors().array();

  for (; pRootFound != pRootEnd; ++pRootFound, ++pValueBefore, ++pValueAfter, ++ppRootProcessor)
    {
      // Root values which did not change are not found
      if (2.0 * fabs(*pValueAfter - *pValueBefore) <= (fabs(*pValueAfter) + fabs(*pValueBefore)) * std::numeric_limits< C_FLOAT64 >::epsilon())
        {
          *pRootFound = 0;
          continue;
        }

      // Detect whether we have an exact zero (within 10 * epsilon)
      bool zero = (fabs(*pValueAfter) < 10.0 * fabs(*pValueBefore) * std::numeric_limits< C_FLOAT64 >::epsilon());

      // Handle equality
      if ((*ppRootProcessor)->isEquality())
        {
          if ((*ppRootProcessor)->isTrue())
            {
              if (zero || *pValueAfter >= 0.0 || *pValueAfter > *pValueBefore)
                {
                  *pRootFound = 0;
                }
              else
                {
                  *pRootFound = 1;
                  rootsFound = true;
                }
            }
          else
            {
              if (*pValueAfter < 0.0 || *pValueAfter < *pValueBefore)
                {
                  *pRootFound = 0;
                }
              else
                {
                  *pRootFound = 1;
                  rootsFound = true;
                }
            }
        }
      else
        {
          if ((*ppRootProcessor)->isTrue())
            {
              if (*pValueAfter > 0.0 || *pValueAfter > *pValueBefore)
                {
                  *pRootFound = 0;
                }
              else
                {
                  *pRootFound = 1;
                  rootsFound = true;
                }
            }
          else
            {
              if (zero || *pValueAfter <= 0.0 || *pValueAfter < *pValueBefore)
                {
                  *pRootFound = 0;
                }
              else
                {
                  *pRootFound = 1;
                  rootsFound = true;
                }
            }
        }
    }

  // Swap before and after.
  CVector< C_FLOAT64 > * pTmp = mpRootValuesBefore;
  mpRootValuesBefore = mpRootValuesAfter;
  mpRootValuesAfter = pTmp;

  return rootsFound;
}

const C_FLOAT64 & CMathEventQueue::getProcessQueueExecutionTime() const
{
  static C_FLOAT64 Infinity =
    std::numeric_limits< C_FLOAT64 >::infinity();

  if (mActions.empty())
    {
      return Infinity;
    }

  return mActions.begin()->first.getExecutionTime();
}

std::ostream &operator<<(std::ostream &os, const CMathEventQueue & o)
{
  os << "Process Queue" << std::endl;
  CMathEventQueue::const_iterator it;

  if (o.mActions.size()) os << " Actions:" << std::endl;

  for (it = o.mActions.begin(); it != o.mActions.end(); ++it)
    {
      os << "exec time " << it->first.mExecutionTime
         << ", cascading lvl " << it->first.mCascadingLevel
         << ", " << (it->first.mEquality ? "equality, " : "inequality");

      os << std::endl;

      CMathEvent * pEvent = it->second.getEvent();

      os << "pEvent: 0x" << pEvent << ", Action: ";

      switch (it->second.getType())
        {
          case CMathEventQueue::CAction::Calculation:

            if (pEvent->delayAssignment())
              {
                os << "Calculation";
              }
            else
              {
                os << "Calculation & Assignment";
              }

            break;

          case CMathEventQueue::CAction::Assignment:
            os << "Assignment";
            break;

          case CMathEventQueue::CAction::Callback:
            os << "Callback";
            break;
        }

      os << std::endl << std::endl;
    }

  return os;
}
<commit_msg>- don't crash if process is invoked with false<commit_after>// Copyright (C) 2014 - 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

#include <limits>

#include "copasi.h"

#include "CMathEventQueue.h"
#include "CMathContainer.h"
#include "CMathEvent.h"
#include "function/CExpression.h"
#include "randomGenerator/CRandom.h"

#include "copasi/report/CCopasiRootContainer.h"
#include "copasi/commandline/CConfigurationFile.h"

// Uncomment this line below to get debug print out.
// #define DEBUG_OUTPUT 1

CMathEventQueue::CKey::CKey() :
  mExecutionTime(0.0),
  mCascadingLevel(0),
  mEquality(false)
{}

CMathEventQueue::CKey::CKey(const CKey & src) :
  mExecutionTime(src.mExecutionTime),
  mCascadingLevel(src.mCascadingLevel),
  mEquality(src.mEquality)
{}

CMathEventQueue::CKey::CKey(const C_FLOAT64 & executionTime,
                            const bool & equality,
                            const size_t & cascadingLevel):
  mExecutionTime(executionTime),
  mCascadingLevel(cascadingLevel),
  mEquality(equality)
{}

CMathEventQueue::CKey::~CKey()
{}

bool CMathEventQueue::CKey::operator < (const CMathEventQueue::CKey & rhs) const
{
  if (mExecutionTime != rhs.mExecutionTime)
    return mExecutionTime < rhs.mExecutionTime;

  if (mCascadingLevel != rhs.mCascadingLevel)
    return mCascadingLevel > rhs.mCascadingLevel;

  return mEquality < rhs.mEquality;
}

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

CMathEventQueue::CAction::CAction():
  mType(),
  mValues(),
  mpPriority(NULL),
  mpEvent(NULL),
  mpProcessQueue(NULL)
{}

CMathEventQueue::CAction::CAction(const CAction & src):
  mType(src.mType),
  mpPriority(src.mpPriority),
  mValues(src.mValues),
  mpEvent(src.mpEvent),
  mpProcessQueue(src.mpProcessQueue)
{}

CMathEventQueue::CAction::CAction(CMathEvent * pEvent,
                                  CMathEventQueue * pProcessQueue):
  mType(),
  mValues(),
  mpPriority(NULL),
  mpEvent(pEvent),
  mpProcessQueue(pProcessQueue)
{
  mpPriority = (const C_FLOAT64 *) pEvent->getPriority()->getValuePointer();

  switch (pEvent->getType())
    {
      case CEvent::Assignment:
      case CEvent::Discontinuity:
        mType = Calculation;
        break;

      case CEvent::Callback:
        mType = Callback;
        break;
    }
}

CMathEventQueue::CAction::CAction(const CVector< C_FLOAT64 > & values,
                                  CMathEvent * pEvent,
                                  CMathEventQueue * pProcessQueue) :
  mType(CMathEventQueue::CAction::Assignment),
  mpPriority(NULL),
  mValues(values),
  mpEvent(pEvent),
  mpProcessQueue(pProcessQueue)
{
  mpPriority = (const C_FLOAT64 *) pEvent->getPriority()->getValuePointer();
}

CMathEventQueue::CAction::~CAction()
{}

CMath::StateChange CMathEventQueue::CAction::process()
{
  // Assume that nothing is changed
  CMath::StateChange StateChange = CMath::NoChange;

  switch (mType)
    {
      case Calculation:

        if (mpEvent->delayAssignment())
          {
            mpProcessQueue->addAssignment(mpEvent->getExecutionTime(),
                                          mpProcessQueue->mEquality,
                                          mpEvent->getTargetValues(),
                                          mpEvent);
          }
        else
          {
            StateChange = mpEvent->executeAssignment();
          }

        break;

      case Assignment:
        StateChange = mpEvent->setTargetValues(mValues);
        break;

      case Callback:
        mpEvent->executeCallback(mpProcessQueue);
        break;
    }

  return StateChange;
}

CMathEvent * CMathEventQueue::CAction::getEvent() const {return mpEvent;}

const CMathEventQueue::CAction::Type & CMathEventQueue::CAction::getType() const {return mType;}

const C_FLOAT64 & CMathEventQueue::CAction::getPriority() const {return *mpPriority;}

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

CMathEventQueue::CMathEventQueue() :
  mpContainer(NULL),
  mpTime(NULL),
  mActions(),
  mUpdateSequence(),
  mExecutionLimit(10000),
  mExecutionCounter(0),
  mEquality(true),
  mCascadingLevel(0),
  mRootsFound(0),
  mRootValues1(0),
  mRootValues2(0),
  mpRootValuesBefore(&mRootValues1),
  mpRootValuesAfter(&mRootValues2)
{}

CMathEventQueue::CMathEventQueue(CMathContainer & container):
  mpContainer(& container),
  mpTime(NULL),
  mActions(),
  mUpdateSequence(),
  mExecutionLimit(10000),
  mExecutionCounter(0),
  mEquality(true),
  mCascadingLevel(0),
  mRootsFound(0),
  mRootValues1(0),
  mRootValues2(0),
  mpRootValuesBefore(&mRootValues1),
  mpRootValuesAfter(&mRootValues2)
{}

CMathEventQueue::~CMathEventQueue()
{}

bool CMathEventQueue::addAssignment(const C_FLOAT64 & executionTime,
                                    const bool & equality,
                                    const CVectorCore< C_FLOAT64 > & values,
                                    CMathEvent * pEvent)
{
  // It is not possible to proceed backwards in time.
  if (executionTime < *mpTime) return false;

  size_t CascadingLevel = mCascadingLevel;

  // If the assignment is in the future or it has a priority the
  // cascading level must be zero.
  if (executionTime > *mpTime ||
      !isnan(* (C_FLOAT64 *) pEvent->getPriority()->getValuePointer()))
    CascadingLevel = 0;

  pEvent->addPendingAction(mActions.insert(std::make_pair(CKey(executionTime, equality, CascadingLevel),
                           CAction(values, pEvent, this))));

  return true;
}

bool CMathEventQueue::addCalculation(const C_FLOAT64 & executionTime,
                                     const bool & equality,
                                     CMathEvent * pEvent)
{
  // It is not possible to proceed backwards in time.
  if (executionTime < *mpTime) return false;

  size_t CascadingLevel = mCascadingLevel;

  // If the assignment is in the future or it has a priority the
  // cascading level must be zero.
  if (executionTime > *mpTime ||
      !isnan(* (C_FLOAT64 *) pEvent->getPriority()->getValuePointer()))
    CascadingLevel = 0;

  pEvent->addPendingAction(mActions.insert(std::make_pair(CKey(executionTime, equality, CascadingLevel),
                           CAction(pEvent, this))));

  return true;
}

void CMathEventQueue::removeAction(const std::pair< CMathEventQueue::CKey, CMathEventQueue::CAction > & action)
{
  range PendingActions = mActions.equal_range(action.first);

  iterator itAction = PendingActions.first;

  for (; itAction != PendingActions.second; ++itAction)
    {
      if (itAction->second.getEvent() == action.second.getEvent())
        {
          mActions.erase(itAction);
          break;
        }
    }
}

void CMathEventQueue::start()
{
  mActions.clear();

  mpTime = mpContainer->getState(false).array() + mpContainer->getCountFixedEventTargets();

  size_t NumRoots = mpContainer->getRoots().size();
  mRootsFound.resize(NumRoots);
  mRootsFound = 0;
  mRootValues1.resize(NumRoots);
  mRootValues2.resize(NumRoots);
  mpRootValuesBefore = &mRootValues1;
  mpRootValuesAfter = &mRootValues2;

  return;
}

CMath::StateChange CMathEventQueue::process(const bool & priorToOutput)
{
  if (mpTime != NULL && getProcessQueueExecutionTime() > *mpTime)
    return CMath::NoChange;

  mEquality = priorToOutput;
  mExecutionCounter = 0;
  mCascadingLevel = 0;

  bool success = true;
  CMath::StateChange StateChange = CMath::NoChange;

  *mpRootValuesBefore = mpContainer->getRoots();
  mpContainer->updatePriorityValues();

  iterator itAction = getAction();

#ifdef DEBUG_OUTPUT
  std::cout << "State: " << mpContainer->getState(false) << std::endl;
  std::cout << "Roots: " << mpContainer->getRoots() << std::endl;
#endif //DEBUG_OUTPUT

  // The algorithm below will work properly for user ordered events
  // as the queue enforces the proper ordering.
  while (success &&
         itAction != mActions.end() &&
         mCascadingLevel != std::numeric_limits<size_t>::max())
    {
      CMath::StateChange ActionStateChange = executeAction(itAction);
      StateChange |= ActionStateChange;

      if (ActionStateChange != CMath::NoChange)
        {
          mpContainer->updatePriorityValues();
        }

      // State change does not indicate whether we have any root changes. We need to
      // explicitly check for it.
#ifdef DEBUG_OUTPUT
      std::cout << "State: " << mpContainer->getState(false) << std::endl;
      std::cout << "Roots: " << mpContainer->getRoots() << std::endl;
#endif // DEBUG_OUTPUT

      // We switch to the next cascading level so that events triggered by the
      // execution of assignments are properly scheduled.
      mCascadingLevel++;

      // We need to compare the roots before the execution and after
      // to determine which roots need to be charged.
      if (rootsFound())
        {
          // We have to deal with both types of found roots.
          mpContainer->processRoots(mRootsFound);
        }

      // Note, applying the events may have added new events to the queue.
      // The setting of the equality flag for these events may be either true
      // or false.

      // First we handle equalities.
      mEquality = true;

      // Retrieve the pending calculations.
      itAction = getAction();

      while (itAction == mActions.end() &&
             mCascadingLevel > 0)
        {
          // If we are here we have no more actions for this level.
          mCascadingLevel--;

          if (mCascadingLevel == 0)
            {
              mEquality = priorToOutput;
            }

          itAction = getAction();
        }
    }

  return StateChange;
}

CMathEventQueue::iterator CMathEventQueue::getAction()
{
  if (mpTime == NULL) return mActions.end();

  CKey Pending(*mpTime, mEquality, mCascadingLevel);
  range PendingActions = mActions.equal_range(Pending);

  if (PendingActions.first == PendingActions.second)
    {
      return mActions.end();
    }

  iterator itAction = PendingActions.first;

  std::vector< iterator > PriorityActions;
  C_FLOAT64 HighestPriority = - std::numeric_limits< C_FLOAT64 >::infinity();

  for (; itAction != PendingActions.second; ++itAction)
    {
      // Events without priority are ignored
      if (isnan(itAction->second.getPriority()))
        {
          continue;
        }

      // The priority is lower than the highest
      if (itAction->second.getPriority() < HighestPriority)
        {
          continue;
        }

      // New highest priority
      if (HighestPriority < itAction->second.getPriority())
        {
          HighestPriority = itAction->second.getPriority();
          PriorityActions.clear();
          PriorityActions.push_back(itAction);

          continue;
        }

      // Equal highest priority
      PriorityActions.push_back(itAction);
    }

  switch (PriorityActions.size())
    {
        // No prioritized actions
      case 0:
        // We arbitrarily pick the first
        return PendingActions.first;
        break;

        // One action has the highest priority
      case 1:
        return PriorityActions[0];
        break;

        // Pick one randomly
      default:
        return PriorityActions[mpContainer->getRandomGenerator().getRandomU(PriorityActions.size() - 1)];
        break;
    }

  // We should never get here
  return mActions.end();
}

CMath::StateChange CMathEventQueue::executeAction(CMathEventQueue::iterator itAction)
{
  // Notify the event that the pending action is executed.
  itAction->second.getEvent()->removePendingAction();

  CMath::StateChange StateChange = itAction->second.process();

  mExecutionCounter++;

  mActions.erase(itAction);

  return StateChange;
}

bool CMathEventQueue::rootsFound()
{
  bool rootsFound = false;

  // Calculate the current root values
  *mpRootValuesAfter = mpContainer->getRoots();

  // Compare the root values before and after;
  C_INT * pRootFound = mRootsFound.array();
  C_INT * pRootEnd = pRootFound + mRootsFound.size();
  C_FLOAT64 * pValueBefore = mpRootValuesBefore->array();
  C_FLOAT64 * pValueAfter = mpRootValuesAfter->array();
  CMathEvent::CTrigger::CRootProcessor ** ppRootProcessor = mpContainer->getRootProcessors().array();

  for (; pRootFound != pRootEnd; ++pRootFound, ++pValueBefore, ++pValueAfter, ++ppRootProcessor)
    {
      // Root values which did not change are not found
      if (2.0 * fabs(*pValueAfter - *pValueBefore) <= (fabs(*pValueAfter) + fabs(*pValueBefore)) * std::numeric_limits< C_FLOAT64 >::epsilon())
        {
          *pRootFound = 0;
          continue;
        }

      // Detect whether we have an exact zero (within 10 * epsilon)
      bool zero = (fabs(*pValueAfter) < 10.0 * fabs(*pValueBefore) * std::numeric_limits< C_FLOAT64 >::epsilon());

      // Handle equality
      if ((*ppRootProcessor)->isEquality())
        {
          if ((*ppRootProcessor)->isTrue())
            {
              if (zero || *pValueAfter >= 0.0 || *pValueAfter > *pValueBefore)
                {
                  *pRootFound = 0;
                }
              else
                {
                  *pRootFound = 1;
                  rootsFound = true;
                }
            }
          else
            {
              if (*pValueAfter < 0.0 || *pValueAfter < *pValueBefore)
                {
                  *pRootFound = 0;
                }
              else
                {
                  *pRootFound = 1;
                  rootsFound = true;
                }
            }
        }
      else
        {
          if ((*ppRootProcessor)->isTrue())
            {
              if (*pValueAfter > 0.0 || *pValueAfter > *pValueBefore)
                {
                  *pRootFound = 0;
                }
              else
                {
                  *pRootFound = 1;
                  rootsFound = true;
                }
            }
          else
            {
              if (zero || *pValueAfter <= 0.0 || *pValueAfter < *pValueBefore)
                {
                  *pRootFound = 0;
                }
              else
                {
                  *pRootFound = 1;
                  rootsFound = true;
                }
            }
        }
    }

  // Swap before and after.
  CVector< C_FLOAT64 > * pTmp = mpRootValuesBefore;
  mpRootValuesBefore = mpRootValuesAfter;
  mpRootValuesAfter = pTmp;

  return rootsFound;
}

const C_FLOAT64 & CMathEventQueue::getProcessQueueExecutionTime() const
{
  static C_FLOAT64 Infinity =
    std::numeric_limits< C_FLOAT64 >::infinity();

  if (mActions.empty())
    {
      return Infinity;
    }

  return mActions.begin()->first.getExecutionTime();
}

std::ostream &operator<<(std::ostream &os, const CMathEventQueue & o)
{
  os << "Process Queue" << std::endl;
  CMathEventQueue::const_iterator it;

  if (o.mActions.size()) os << " Actions:" << std::endl;

  for (it = o.mActions.begin(); it != o.mActions.end(); ++it)
    {
      os << "exec time " << it->first.mExecutionTime
         << ", cascading lvl " << it->first.mCascadingLevel
         << ", " << (it->first.mEquality ? "equality, " : "inequality");

      os << std::endl;

      CMathEvent * pEvent = it->second.getEvent();

      os << "pEvent: 0x" << pEvent << ", Action: ";

      switch (it->second.getType())
        {
          case CMathEventQueue::CAction::Calculation:

            if (pEvent->delayAssignment())
              {
                os << "Calculation";
              }
            else
              {
                os << "Calculation & Assignment";
              }

            break;

          case CMathEventQueue::CAction::Assignment:
            os << "Assignment";
            break;

          case CMathEventQueue::CAction::Callback:
            os << "Callback";
            break;
        }

      os << std::endl << std::endl;
    }

  return os;
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/aura/monitor_change_observer_x11.h"

#include <algorithm>
#include <map>
#include <set>
#include <vector>

#include <X11/extensions/Xrandr.h>

#include "base/message_pump_x.h"
#include "ui/aura/env.h"
#include "ui/aura/dispatcher_linux.h"
#include "ui/aura/monitor_manager.h"
#include "ui/gfx/monitor.h"

namespace aura {
namespace internal {

namespace {
XRRModeInfo* FindMode(XRRScreenResources* screen_resources, XID current_mode) {
  for (int m = 0; m < screen_resources->nmode; m++) {
    XRRModeInfo *mode = &screen_resources->modes[m];
    if (mode->id == current_mode)
      return mode;
  }
  return NULL;
}

bool CompareMonitorY(gfx::Monitor lhs, gfx::Monitor rhs) {
  return lhs.bounds().y() < rhs.bounds().y();
}

}  // namespace

MonitorChangeObserverX11::MonitorChangeObserverX11()
    : xdisplay_(base::MessagePumpX::GetDefaultXDisplay()),
      x_root_window_(DefaultRootWindow(xdisplay_)),
      xrandr_event_base_(0) {
  XRRSelectInput(xdisplay_, x_root_window_, RRScreenChangeNotifyMask);
  int error_base_ignored;
  XRRQueryExtension(xdisplay_, &xrandr_event_base_, &error_base_ignored);
  static_cast<DispatcherLinux*>(
      Env::GetInstance()->GetDispatcher())->
      WindowDispatcherCreated(x_root_window_, this);
}

MonitorChangeObserverX11::~MonitorChangeObserverX11() {
  static_cast<DispatcherLinux*>(
      Env::GetInstance()->GetDispatcher())->
      WindowDispatcherDestroying(x_root_window_);
}

bool MonitorChangeObserverX11::Dispatch(const base::NativeEvent& event) {
  if (event->type - xrandr_event_base_ == RRScreenChangeNotify) {
    NotifyMonitorChange();
  }
  return true;
}

void MonitorChangeObserverX11::NotifyMonitorChange() {
  if (!MonitorManager::use_fullscreen_host_window())
    return;  // Use the default monitor that monitor manager determined.

  XRRScreenResources* screen_resources =
      XRRGetScreenResources(xdisplay_, x_root_window_);
  std::map<XID, XRRCrtcInfo*> crtc_info_map;

  for (int c = 0; c < screen_resources->ncrtc; c++) {
    XID crtc_id = screen_resources->crtcs[c];
    XRRCrtcInfo *crtc_info =
        XRRGetCrtcInfo(xdisplay_, screen_resources, crtc_id);
    crtc_info_map[crtc_id] = crtc_info;
  }

  std::vector<gfx::Monitor> monitors;
  std::set<int> y_coords;
  for (int o = 0; o < screen_resources->noutput; o++) {
    XRROutputInfo *output_info =
        XRRGetOutputInfo(xdisplay_,
                         screen_resources,
                         screen_resources->outputs[o]);
    if (output_info->connection != RR_Connected) {
      XRRFreeOutputInfo(output_info);
      continue;
    }
    XRRCrtcInfo* crtc_info = crtc_info_map[output_info->crtc];
    if (!crtc_info) {
      LOG(WARNING) << "Crtc not found for output";
      continue;
    }
    XRRModeInfo* mode = FindMode(screen_resources, crtc_info->mode);
    CHECK(mode);
    // Mirrored monitors have the same y coordinates.
    if (y_coords.find(crtc_info->y) != y_coords.end())
      continue;
    // TODO(oshima): Create unique ID for the monitor.
    monitors.push_back(gfx::Monitor(
        0,
        gfx::Rect(crtc_info->x, crtc_info->y, mode->width, mode->height)));
    y_coords.insert(crtc_info->y);
    XRRFreeOutputInfo(output_info);
  }

  // Free all allocated resources.
  for (std::map<XID, XRRCrtcInfo*>::const_iterator iter = crtc_info_map.begin();
       iter != crtc_info_map.end(); ++iter) {
    XRRFreeCrtcInfo(iter->second);
  }
  XRRFreeScreenResources(screen_resources);

  // PowerManager lays out the outputs vertically. Sort them by Y
  // coordinates.
  std::sort(monitors.begin(), monitors.end(), CompareMonitorY);
  // TODO(oshima): Assisgn index as ID for now. Use unique ID.
  int id = 0;
  for (std::vector<gfx::Monitor>::iterator iter = monitors.begin();
       iter != monitors.end(); ++iter, ++id)
    (*iter).set_id(id);

  Env::GetInstance()->monitor_manager()
      ->OnNativeMonitorsChanged(monitors);
}

}  // namespace internal
}  // namespace aura
<commit_msg>[ASH] Use real coordinates to sort monitors<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/aura/monitor_change_observer_x11.h"

#include <algorithm>
#include <map>
#include <set>
#include <vector>

#include <X11/extensions/Xrandr.h>

#include "base/message_pump_x.h"
#include "ui/aura/env.h"
#include "ui/aura/dispatcher_linux.h"
#include "ui/aura/monitor_manager.h"
#include "ui/gfx/monitor.h"

namespace aura {
namespace internal {

namespace {
XRRModeInfo* FindMode(XRRScreenResources* screen_resources, XID current_mode) {
  for (int m = 0; m < screen_resources->nmode; m++) {
    XRRModeInfo *mode = &screen_resources->modes[m];
    if (mode->id == current_mode)
      return mode;
  }
  return NULL;
}

bool CompareMonitorY(const gfx::Monitor& lhs, const gfx::Monitor& rhs) {
  return lhs.bounds_in_pixel().y() > rhs.bounds_in_pixel().y();
}

}  // namespace

MonitorChangeObserverX11::MonitorChangeObserverX11()
    : xdisplay_(base::MessagePumpX::GetDefaultXDisplay()),
      x_root_window_(DefaultRootWindow(xdisplay_)),
      xrandr_event_base_(0) {
  XRRSelectInput(xdisplay_, x_root_window_, RRScreenChangeNotifyMask);
  int error_base_ignored;
  XRRQueryExtension(xdisplay_, &xrandr_event_base_, &error_base_ignored);
  static_cast<DispatcherLinux*>(
      Env::GetInstance()->GetDispatcher())->
      WindowDispatcherCreated(x_root_window_, this);
}

MonitorChangeObserverX11::~MonitorChangeObserverX11() {
  static_cast<DispatcherLinux*>(
      Env::GetInstance()->GetDispatcher())->
      WindowDispatcherDestroying(x_root_window_);
}

bool MonitorChangeObserverX11::Dispatch(const base::NativeEvent& event) {
  if (event->type - xrandr_event_base_ == RRScreenChangeNotify) {
    NotifyMonitorChange();
  }
  return true;
}

void MonitorChangeObserverX11::NotifyMonitorChange() {
  if (!MonitorManager::use_fullscreen_host_window())
    return;  // Use the default monitor that monitor manager determined.

  XRRScreenResources* screen_resources =
      XRRGetScreenResources(xdisplay_, x_root_window_);
  std::map<XID, XRRCrtcInfo*> crtc_info_map;

  for (int c = 0; c < screen_resources->ncrtc; c++) {
    XID crtc_id = screen_resources->crtcs[c];
    XRRCrtcInfo *crtc_info =
        XRRGetCrtcInfo(xdisplay_, screen_resources, crtc_id);
    crtc_info_map[crtc_id] = crtc_info;
  }

  std::vector<gfx::Monitor> monitors;
  std::set<int> y_coords;
  for (int o = 0; o < screen_resources->noutput; o++) {
    XRROutputInfo *output_info =
        XRRGetOutputInfo(xdisplay_,
                         screen_resources,
                         screen_resources->outputs[o]);
    if (output_info->connection != RR_Connected) {
      XRRFreeOutputInfo(output_info);
      continue;
    }
    XRRCrtcInfo* crtc_info = crtc_info_map[output_info->crtc];
    if (!crtc_info) {
      LOG(WARNING) << "Crtc not found for output";
      continue;
    }
    XRRModeInfo* mode = FindMode(screen_resources, crtc_info->mode);
    CHECK(mode);
    // Mirrored monitors have the same y coordinates.
    if (y_coords.find(crtc_info->y) != y_coords.end())
      continue;
    // TODO(oshima): Create unique ID for the monitor.
    monitors.push_back(gfx::Monitor(
        0,
        gfx::Rect(crtc_info->x, crtc_info->y, mode->width, mode->height)));
    y_coords.insert(crtc_info->y);
    XRRFreeOutputInfo(output_info);
  }

  // Free all allocated resources.
  for (std::map<XID, XRRCrtcInfo*>::const_iterator iter = crtc_info_map.begin();
       iter != crtc_info_map.end(); ++iter) {
    XRRFreeCrtcInfo(iter->second);
  }
  XRRFreeScreenResources(screen_resources);

  // PowerManager lays out the outputs vertically. Sort them by Y
  // coordinates.
  std::sort(monitors.begin(), monitors.end(), CompareMonitorY);
  // TODO(oshima): Assisgn index as ID for now. Use unique ID.
  int id = 0;
  for (std::vector<gfx::Monitor>::iterator iter = monitors.begin();
       iter != monitors.end(); ++iter, ++id)
    (*iter).set_id(id);

  Env::GetInstance()->monitor_manager()
      ->OnNativeMonitorsChanged(monitors);
}

}  // namespace internal
}  // namespace aura
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "Connection.h"
#include "../libutils/Buffer.h"

CConnection::CConnection(void)
{
	m_Timeout = 0;
	m_AutoDelete = false;
	m_Connected = false;
	CLog::Default()->Printf(5, "CConnection(%p)", this);
}

CConnection::~CConnection(void)
{
	CLog::Default()->Printf(5, "~CConnection(%p)", this);
}

void CConnection::SetTimeout(int Timeout)
{
	m_Timeout = Timeout;
}

void CConnection::Reconnect()
{
	Disconnect();
	Connect(m_ConnectString);
}

void CConnection::SendBuffer(CBuffer &buffer)
{
	Send(buffer.getBuffer(), buffer.getSize());
}

<commit_msg>conn count<commit_after>#include "stdafx.h"
#include "Connection.h"
#include "../libutils/Buffer.h"

static int g_ConnectionCount=0;

CConnection::CConnection(void)
{
	m_Timeout = 0;
	m_AutoDelete = false;
	m_Connected = false;
	CLog::Default()->Printf(5, "CConnection(%p)", this);
	g_ConnectionCount++;
}

CConnection::~CConnection(void)
{
	g_ConnectionCount--;
	CLog::Default()->Printf(g_ConnectionCount<30?5:3, "~CConnection(%p). Total %d conn", this, g_ConnectionCount);
}

void CConnection::SetTimeout(int Timeout)
{
	m_Timeout = Timeout;
}

void CConnection::Reconnect()
{
	Disconnect();
	Connect(m_ConnectString);
}

void CConnection::SendBuffer(CBuffer &buffer)
{
	Send(buffer.getBuffer(), buffer.getSize());
}

<|endoftext|>


<commit_before>/*=============================================================================

  MYPROJECT: A software package for whatever.

  Copyright (c) University College London (UCL). All rights reserved.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.

  See LICENSE.txt in the top level directory for details.

=============================================================================*/

#include "mpQQuickVTKView.h"
#include <vtkRendererCollection.h>
#include <vtkEventQtSlotConnect.h>
#include <QVTKInteractorAdapter.h>
#include <QMutexLocker>

namespace mp {

//-----------------------------------------------------------------------------
QQuickVTKView::~QQuickVTKView()
{
  if (m_VTKRenderWindow)
  {
    m_VTKRenderWindowInteractor->Disable();
    m_VTKRenderWindow->SetInteractor(nullptr);
#ifdef BUILD_VTK_OpenGL2
    m_VTKRenderWindow->SetReadyForRendering(false);
#endif
    m_VTKRenderWindow->SetMapped(0);
    m_VTKRenderWindow->RemoveAllObservers();
    vtkRendererCollection *c = m_VTKRenderWindow->GetRenderers();
    vtkRenderer *v = nullptr;
    while(v = c->GetNextItem(), v != nullptr)
    {
      m_VTKRenderWindow->RemoveRenderer(v);
    }
  }
}

//-----------------------------------------------------------------------------
QQuickVTKView::QQuickVTKView(QWindow * parent)
: QQuickView(parent)
, m_Mutex(QMutex::NonRecursive)
, m_VTKRenderWindow(nullptr)
, m_VTKRenderWindowInteractor(nullptr)
, m_VTKInteractorStyleMultiTouchCamera(nullptr)
, m_EraseBeforeVTKRendering(true)
{
  this->Init();
}

//-----------------------------------------------------------------------------
QQuickVTKView::QQuickVTKView(QQmlEngine * engine, QWindow * parent)
: QQuickView(engine, parent)
, m_Mutex(QMutex::NonRecursive)
, m_VTKRenderWindow(nullptr)
, m_VTKRenderWindowInteractor(nullptr)
, m_VTKInteractorStyleMultiTouchCamera(nullptr)
, m_EraseBeforeVTKRendering(true)
{
  this->Init();
}

//-----------------------------------------------------------------------------
QQuickVTKView::QQuickVTKView(const QUrl & source, QWindow * parent)
: QQuickView(source, parent)
, m_Mutex(QMutex::NonRecursive)
, m_VTKRenderWindow(nullptr)
, m_VTKRenderWindowInteractor(nullptr)
, m_VTKInteractorStyleMultiTouchCamera(nullptr)
, m_EraseBeforeVTKRendering(true)
{
  this->Init();
}

//-----------------------------------------------------------------------------
void QQuickVTKView::Init()
{
  m_VTKRenderWindow = vtkExternalOpenGLRenderWindow::New();

  m_VTKInteractorStyleMultiTouchCamera = vtkInteractorStyleMultiTouchCamera::New();

  m_VTKRenderWindowInteractor = vtkRenderWindowInteractor::New();
  m_VTKRenderWindowInteractor->SetRenderWindow(m_VTKRenderWindow);
  m_VTKRenderWindowInteractor->SetInteractorStyle(m_VTKInteractorStyleMultiTouchCamera);
  m_VTKRenderWindowInteractor->SetEnableRender(false);

  m_VTKInteractorAdapter = new QVTKInteractorAdapter(this);
  m_VTKInteractorAdapter->SetDevicePixelRatio(this->devicePixelRatio());

  m_EventSlotConnector = vtkSmartPointer<vtkEventQtSlotConnect>::New();

  connect(this, SIGNAL(beforeRendering()), this, SLOT(Render()), Qt::DirectConnection);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::AddRenderer(vtkRenderer* r)
{
  m_VTKRenderWindow->AddRenderer(r);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::RemoveRenderer(vtkRenderer *r)
{
  m_VTKRenderWindow->RemoveRenderer(r);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::SetEraseBeforeVTKRendering(bool b)
{
  m_EraseBeforeVTKRendering = b;
  m_VTKRenderWindow->SetErase(m_EraseBeforeVTKRendering);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::Render()
{
  emit beforeVTKRendering();

  QMutexLocker lock(&m_Mutex);
  m_VTKRenderWindow->Render();

  emit afterVTKRendering();
}

//-----------------------------------------------------------------------------
void QQuickVTKView::SetEnabled(bool isEnabled)
{
  if (isEnabled)
  {
    m_VTKRenderWindowInteractor->Enable();
  }
  else
  {
    m_VTKRenderWindowInteractor->Disable();
  }
}

//-----------------------------------------------------------------------------
bool QQuickVTKView::event(QEvent *e)
{
  if(e->type() == QEvent::TouchBegin ||
     e->type() == QEvent::TouchUpdate ||
     e->type() == QEvent::TouchEnd
    )
  {
    QMutexLocker lock(&m_Mutex);
    if(m_VTKRenderWindow
#ifdef BUILD_VTK_OpenGL2
      && m_VTKRenderWindow->GetReadyForRendering()
#endif
      )
    {
      m_VTKInteractorAdapter->ProcessEvent(e, m_VTKRenderWindow->GetInteractor());
      if (e->isAccepted())
      {
        return true;
      }
    }
  }
  return QQuickView::event(e);
}

//-----------------------------------------------------------------------------
bool QQuickVTKView::ProcessEvent(QEvent* e)
{
  QMutexLocker lock(&m_Mutex);
  if (m_VTKRenderWindow
#ifdef BUILD_VTK_OpenGL2
    && m_VTKRenderWindow->GetReadyForRendering()
#endif
    )
  {
    return m_VTKInteractorAdapter->ProcessEvent(e, m_VTKRenderWindowInteractor);
  }
  return false;
}

//-----------------------------------------------------------------------------
void QQuickVTKView::mousePressEvent(QMouseEvent* event)
{
  this->ProcessEvent(event);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::mouseMoveEvent(QMouseEvent* event)
{
  this->ProcessEvent(event);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::mouseReleaseEvent(QMouseEvent* event)
{
  this->ProcessEvent(event);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::mouseDoubleClickEvent(QMouseEvent* event)
{
  this->ProcessEvent(event);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::keyPressEvent(QKeyEvent* event)
{
  this->ProcessEvent(event);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::keyReleaseEvent(QKeyEvent* event)
{
  this->ProcessEvent(event);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::enterEvent(QEvent* event)
{
  this->ProcessEvent(event);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::leaveEvent(QEvent* event)
{
  this->ProcessEvent(event);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::wheelEvent(QWheelEvent* event)
{
  this->ProcessEvent(event);
}

//-----------------------------------------------------------------------------
} // end namespace
<commit_msg>Issue #39: Only call Render if window is mapped and ready.<commit_after>/*=============================================================================

  MYPROJECT: A software package for whatever.

  Copyright (c) University College London (UCL). All rights reserved.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.

  See LICENSE.txt in the top level directory for details.

=============================================================================*/

#include "mpQQuickVTKView.h"
#include <vtkRendererCollection.h>
#include <vtkEventQtSlotConnect.h>
#include <QVTKInteractorAdapter.h>
#include <QMutexLocker>

namespace mp {

//-----------------------------------------------------------------------------
QQuickVTKView::~QQuickVTKView()
{
  if (m_VTKRenderWindow)
  {
    m_VTKRenderWindowInteractor->Disable();
    m_VTKRenderWindow->SetInteractor(nullptr);
#ifdef BUILD_VTK_OpenGL2
    m_VTKRenderWindow->SetReadyForRendering(false);
#endif
    m_VTKRenderWindow->SetMapped(0);
    m_VTKRenderWindow->RemoveAllObservers();
    vtkRendererCollection *c = m_VTKRenderWindow->GetRenderers();
    vtkRenderer *v = nullptr;
    while(v = c->GetNextItem(), v != nullptr)
    {
      m_VTKRenderWindow->RemoveRenderer(v);
    }
  }
}

//-----------------------------------------------------------------------------
QQuickVTKView::QQuickVTKView(QWindow * parent)
: QQuickView(parent)
, m_Mutex(QMutex::NonRecursive)
, m_VTKRenderWindow(nullptr)
, m_VTKRenderWindowInteractor(nullptr)
, m_VTKInteractorStyleMultiTouchCamera(nullptr)
, m_EraseBeforeVTKRendering(true)
{
  this->Init();
}

//-----------------------------------------------------------------------------
QQuickVTKView::QQuickVTKView(QQmlEngine * engine, QWindow * parent)
: QQuickView(engine, parent)
, m_Mutex(QMutex::NonRecursive)
, m_VTKRenderWindow(nullptr)
, m_VTKRenderWindowInteractor(nullptr)
, m_VTKInteractorStyleMultiTouchCamera(nullptr)
, m_EraseBeforeVTKRendering(true)
{
  this->Init();
}

//-----------------------------------------------------------------------------
QQuickVTKView::QQuickVTKView(const QUrl & source, QWindow * parent)
: QQuickView(source, parent)
, m_Mutex(QMutex::NonRecursive)
, m_VTKRenderWindow(nullptr)
, m_VTKRenderWindowInteractor(nullptr)
, m_VTKInteractorStyleMultiTouchCamera(nullptr)
, m_EraseBeforeVTKRendering(true)
{
  this->Init();
}

//-----------------------------------------------------------------------------
void QQuickVTKView::Init()
{
  m_VTKRenderWindow = vtkExternalOpenGLRenderWindow::New();

  m_VTKInteractorStyleMultiTouchCamera = vtkInteractorStyleMultiTouchCamera::New();

  m_VTKRenderWindowInteractor = vtkRenderWindowInteractor::New();
  m_VTKRenderWindowInteractor->SetRenderWindow(m_VTKRenderWindow);
  m_VTKRenderWindowInteractor->SetInteractorStyle(m_VTKInteractorStyleMultiTouchCamera);
  m_VTKRenderWindowInteractor->SetEnableRender(false);

  m_VTKInteractorAdapter = new QVTKInteractorAdapter(this);
  m_VTKInteractorAdapter->SetDevicePixelRatio(this->devicePixelRatio());

  m_EventSlotConnector = vtkSmartPointer<vtkEventQtSlotConnect>::New();

  connect(this, SIGNAL(beforeRendering()), this, SLOT(Render()), Qt::DirectConnection);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::AddRenderer(vtkRenderer* r)
{
  m_VTKRenderWindow->AddRenderer(r);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::RemoveRenderer(vtkRenderer *r)
{
  m_VTKRenderWindow->RemoveRenderer(r);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::SetEraseBeforeVTKRendering(bool b)
{
  m_EraseBeforeVTKRendering = b;
  m_VTKRenderWindow->SetErase(m_EraseBeforeVTKRendering);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::Render()
{
  emit beforeVTKRendering();

  QMutexLocker lock(&m_Mutex);
  if (m_VTKRenderWindow->GetMapped()
#ifdef BUILD_VTK_OpenGL2
    && m_VTKRenderWindow->GetReadyForRendering()
#endif
     )
  {
    m_VTKRenderWindow->Render();
  }
  emit afterVTKRendering();
}

//-----------------------------------------------------------------------------
void QQuickVTKView::SetEnabled(bool isEnabled)
{
  if (isEnabled)
  {
    m_VTKRenderWindowInteractor->Enable();
  }
  else
  {
    m_VTKRenderWindowInteractor->Disable();
  }
}

//-----------------------------------------------------------------------------
bool QQuickVTKView::event(QEvent *e)
{
  if(e->type() == QEvent::TouchBegin ||
     e->type() == QEvent::TouchUpdate ||
     e->type() == QEvent::TouchEnd
    )
  {
    QMutexLocker lock(&m_Mutex);
    if(m_VTKRenderWindow
#ifdef BUILD_VTK_OpenGL2
      && m_VTKRenderWindow->GetReadyForRendering()
#endif
      )
    {
      m_VTKInteractorAdapter->ProcessEvent(e, m_VTKRenderWindow->GetInteractor());
      if (e->isAccepted())
      {
        return true;
      }
    }
  }
  return QQuickView::event(e);
}

//-----------------------------------------------------------------------------
bool QQuickVTKView::ProcessEvent(QEvent* e)
{
  QMutexLocker lock(&m_Mutex);
  if (m_VTKRenderWindow
#ifdef BUILD_VTK_OpenGL2
    && m_VTKRenderWindow->GetReadyForRendering()
#endif
    )
  {
    return m_VTKInteractorAdapter->ProcessEvent(e, m_VTKRenderWindowInteractor);
  }
  return false;
}

//-----------------------------------------------------------------------------
void QQuickVTKView::mousePressEvent(QMouseEvent* event)
{
  this->ProcessEvent(event);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::mouseMoveEvent(QMouseEvent* event)
{
  this->ProcessEvent(event);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::mouseReleaseEvent(QMouseEvent* event)
{
  this->ProcessEvent(event);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::mouseDoubleClickEvent(QMouseEvent* event)
{
  this->ProcessEvent(event);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::keyPressEvent(QKeyEvent* event)
{
  this->ProcessEvent(event);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::keyReleaseEvent(QKeyEvent* event)
{
  this->ProcessEvent(event);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::enterEvent(QEvent* event)
{
  this->ProcessEvent(event);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::leaveEvent(QEvent* event)
{
  this->ProcessEvent(event);
}

//-----------------------------------------------------------------------------
void QQuickVTKView::wheelEvent(QWheelEvent* event)
{
  this->ProcessEvent(event);
}

//-----------------------------------------------------------------------------
} // end namespace
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: MColumnAlias.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hjs $ $Date: 2004-06-25 18:26:52 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): Willem van Dorp
 *
 *
 ************************************************************************/

#ifndef _CONNECTIVITY_MAB_COLUMNALIAS_HXX_
#include "MColumnAlias.hxx"
#endif
#ifndef CONNECTIVITY_SCONNECTION_HXX
#include "MConnection.hxx"
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef CONNECTIVITY_MOZAB_MEXTCONFIGACCESS_HXX
#include "MExtConfigAccess.hxx"
#endif

using namespace ::connectivity;
using namespace ::connectivity::mozab;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;

static const ::rtl::OUString sProgrammaticNames[] =
{
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("FirstName")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("LastName")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DisplayName")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("NickName")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("PrimaryEmail")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SecondEmail")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("PreferMailFormat")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("WorkPhone")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("HomePhone")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("FaxNumber")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("PagerNumber")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("CellularNumber")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("HomeAddress")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("HomeAddress2")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("HomeCity")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("HomeState")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("HomeZipCode")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("HomeCountry")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("WorkAddress")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("WorkAddress2")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("WorkCity")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("WorkState")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("WorkZipCode")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("WorkCountry")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("JobTitle")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Department")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Company")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("WebPage1")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("WebPage2")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("BirthYear")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("BirthMonth")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("BirthDay")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Custom1")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Custom2")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Custom3")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Custom4")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Notes"))
};
//------------------------------------------------------------------------------
OColumnAlias::OColumnAlias()
{
    // Initialise m_aAlias with the default values from sProgrammaticNames.
    initialise();

    // Initialise m_aAlias map with the default values from sProgrammaticNames.
    setAliasMap();
}
//------------------------------------------------------------------
OColumnAlias::~OColumnAlias()
{
}
//------------------------------------------------------------------
void OColumnAlias::initialise()
{
    m_aAlias.reserve( END - FIRSTNAME + 1 );
    for (sal_Int32 i(FIRSTNAME); i < END; ++i)
        m_aAlias.push_back(sProgrammaticNames[i]);

    return;
}
//------------------------------------------------------------------
void OColumnAlias::setAlias(const ::com::sun::star::uno::Reference<
                                       ::com::sun::star::lang::XMultiServiceFactory >& _rxORB)
{
        // open our driver settings config node

        // the config path for our own driver's settings
    Reference< XPropertySet > xDriverNode = createDriverConfigNode( _rxORB );
    if ( xDriverNode.is() )
    {
        try
        {
            //.............................................................
            Reference< XNameAccess > xAliasesNode;
            xDriverNode->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ColumnAliases")) ) >>= xAliasesNode;
            OSL_ENSURE( xAliasesNode.is(), "OColumnAlias::setAlias: missing the aliases node!" );

            // this is a set of string nodes
            Sequence< ::rtl::OUString > aColumnProgrammaticNames;
            if ( xAliasesNode.is() )
                aColumnProgrammaticNames = xAliasesNode->getElementNames();

            //.............................................................
            // travel through all the set elements
            const ::rtl::OUString* pProgrammaticNames = aColumnProgrammaticNames.getConstArray();
            const ::rtl::OUString* pProgrammaticNamesEnd = pProgrammaticNames + aColumnProgrammaticNames.getLength();
            ::rtl::OUString sAssignedAlias;

            for ( ; pProgrammaticNames < pProgrammaticNamesEnd; ++pProgrammaticNames )
            {
                OSL_ENSURE( m_aAliasMap.end() != m_aAliasMap.find( *pProgrammaticNames ),
                    "OColumnAlias::setAlias: found an invalid programmtic name!" );
                    // if this asserts, somebody stored a programmatic name in the configuration
                    // which is not allowed (i.e. not in the list of known programmatics).

#if OSL_DEBUG_LEVEL > 0
                sal_Bool bExtractionSuccess =
#endif
                xAliasesNode->getByName( *pProgrammaticNames) >>= sAssignedAlias;
                OSL_ENSURE( bExtractionSuccess, "OColumnAlias::setAlias: invalid config data!" );

                // normalize in case the config data is corrupted
                // (what we really don't need is an empty alias ...)
                if ( 0 == sAssignedAlias.getLength() )
                      sAssignedAlias = *pProgrammaticNames;

                //.............................................................
                // check the value
                // look up the programmatic indicated by pProgrammaticNames in the known programmatics
                const ::rtl::OUString* pProgrammatic = sProgrammaticNames + FIRSTNAME;
                const ::rtl::OUString* pProgrammaticEnd = sProgrammaticNames + END;

                OSL_ENSURE( (sal_Int32)m_aAlias.size() == pProgrammaticEnd - pProgrammatic,
                    "OColumnAlias::setAlias: aliases vector not yet initialized!" );

                // the destination where we want to remember the alias
                ::std::vector< ::rtl::OUString >::iterator aDestination = m_aAlias.begin();

                for ( ; pProgrammatic < pProgrammaticEnd; ++pProgrammatic, ++aDestination )
                {
                    if ( pProgrammaticNames->equals( *pProgrammatic ) )
                    {
                        // add alias to the vector
                        *aDestination = sAssignedAlias;
                        break;
                    }
                }
            }
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "OColumnAlias::setAlias: could not read my driver's configuration data!" );
        }
    }

    // Initialise m_aAliasMap.
    setAliasMap();

    return;
}
//------------------------------------------------------------------
const ::std::vector< ::rtl::OUString> & OColumnAlias::getAlias() const
{
    return m_aAlias;
}
//------------------------------------------------------------------
const ::std::map< ::rtl::OUString, ::rtl::OUString> & OColumnAlias::getAliasMap() const
{
    return m_aAliasMap;
}
//------------------------------------------------------------------
void OColumnAlias::setAliasMap()
{
        // Fill the map with the values of m_aAlias
        // and the sProgrammaticNames array.
    for (sal_Int32 i(FIRSTNAME); i < END; ++i) {
        m_aAliasMap[m_aAlias[i]] = sProgrammaticNames[i];
    }

        return;
}
//------------------------------------------------------------------
<commit_msg>INTEGRATION: CWS ooo19126 (1.6.138); FILE MERGED 2005/09/05 17:24:19 rt 1.6.138.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: MColumnAlias.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 06:16:03 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _CONNECTIVITY_MAB_COLUMNALIAS_HXX_
#include "MColumnAlias.hxx"
#endif
#ifndef CONNECTIVITY_SCONNECTION_HXX
#include "MConnection.hxx"
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef CONNECTIVITY_MOZAB_MEXTCONFIGACCESS_HXX
#include "MExtConfigAccess.hxx"
#endif

using namespace ::connectivity;
using namespace ::connectivity::mozab;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;

static const ::rtl::OUString sProgrammaticNames[] =
{
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("FirstName")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("LastName")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DisplayName")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("NickName")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("PrimaryEmail")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("SecondEmail")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("PreferMailFormat")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("WorkPhone")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("HomePhone")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("FaxNumber")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("PagerNumber")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("CellularNumber")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("HomeAddress")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("HomeAddress2")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("HomeCity")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("HomeState")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("HomeZipCode")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("HomeCountry")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("WorkAddress")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("WorkAddress2")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("WorkCity")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("WorkState")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("WorkZipCode")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("WorkCountry")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("JobTitle")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Department")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Company")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("WebPage1")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("WebPage2")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("BirthYear")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("BirthMonth")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("BirthDay")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Custom1")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Custom2")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Custom3")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Custom4")),
    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Notes"))
};
//------------------------------------------------------------------------------
OColumnAlias::OColumnAlias()
{
    // Initialise m_aAlias with the default values from sProgrammaticNames.
    initialise();

    // Initialise m_aAlias map with the default values from sProgrammaticNames.
    setAliasMap();
}
//------------------------------------------------------------------
OColumnAlias::~OColumnAlias()
{
}
//------------------------------------------------------------------
void OColumnAlias::initialise()
{
    m_aAlias.reserve( END - FIRSTNAME + 1 );
    for (sal_Int32 i(FIRSTNAME); i < END; ++i)
        m_aAlias.push_back(sProgrammaticNames[i]);

    return;
}
//------------------------------------------------------------------
void OColumnAlias::setAlias(const ::com::sun::star::uno::Reference<
                                       ::com::sun::star::lang::XMultiServiceFactory >& _rxORB)
{
        // open our driver settings config node

        // the config path for our own driver's settings
    Reference< XPropertySet > xDriverNode = createDriverConfigNode( _rxORB );
    if ( xDriverNode.is() )
    {
        try
        {
            //.............................................................
            Reference< XNameAccess > xAliasesNode;
            xDriverNode->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ColumnAliases")) ) >>= xAliasesNode;
            OSL_ENSURE( xAliasesNode.is(), "OColumnAlias::setAlias: missing the aliases node!" );

            // this is a set of string nodes
            Sequence< ::rtl::OUString > aColumnProgrammaticNames;
            if ( xAliasesNode.is() )
                aColumnProgrammaticNames = xAliasesNode->getElementNames();

            //.............................................................
            // travel through all the set elements
            const ::rtl::OUString* pProgrammaticNames = aColumnProgrammaticNames.getConstArray();
            const ::rtl::OUString* pProgrammaticNamesEnd = pProgrammaticNames + aColumnProgrammaticNames.getLength();
            ::rtl::OUString sAssignedAlias;

            for ( ; pProgrammaticNames < pProgrammaticNamesEnd; ++pProgrammaticNames )
            {
                OSL_ENSURE( m_aAliasMap.end() != m_aAliasMap.find( *pProgrammaticNames ),
                    "OColumnAlias::setAlias: found an invalid programmtic name!" );
                    // if this asserts, somebody stored a programmatic name in the configuration
                    // which is not allowed (i.e. not in the list of known programmatics).

#if OSL_DEBUG_LEVEL > 0
                sal_Bool bExtractionSuccess =
#endif
                xAliasesNode->getByName( *pProgrammaticNames) >>= sAssignedAlias;
                OSL_ENSURE( bExtractionSuccess, "OColumnAlias::setAlias: invalid config data!" );

                // normalize in case the config data is corrupted
                // (what we really don't need is an empty alias ...)
                if ( 0 == sAssignedAlias.getLength() )
                      sAssignedAlias = *pProgrammaticNames;

                //.............................................................
                // check the value
                // look up the programmatic indicated by pProgrammaticNames in the known programmatics
                const ::rtl::OUString* pProgrammatic = sProgrammaticNames + FIRSTNAME;
                const ::rtl::OUString* pProgrammaticEnd = sProgrammaticNames + END;

                OSL_ENSURE( (sal_Int32)m_aAlias.size() == pProgrammaticEnd - pProgrammatic,
                    "OColumnAlias::setAlias: aliases vector not yet initialized!" );

                // the destination where we want to remember the alias
                ::std::vector< ::rtl::OUString >::iterator aDestination = m_aAlias.begin();

                for ( ; pProgrammatic < pProgrammaticEnd; ++pProgrammatic, ++aDestination )
                {
                    if ( pProgrammaticNames->equals( *pProgrammatic ) )
                    {
                        // add alias to the vector
                        *aDestination = sAssignedAlias;
                        break;
                    }
                }
            }
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "OColumnAlias::setAlias: could not read my driver's configuration data!" );
        }
    }

    // Initialise m_aAliasMap.
    setAliasMap();

    return;
}
//------------------------------------------------------------------
const ::std::vector< ::rtl::OUString> & OColumnAlias::getAlias() const
{
    return m_aAlias;
}
//------------------------------------------------------------------
const ::std::map< ::rtl::OUString, ::rtl::OUString> & OColumnAlias::getAliasMap() const
{
    return m_aAliasMap;
}
//------------------------------------------------------------------
void OColumnAlias::setAliasMap()
{
        // Fill the map with the values of m_aAlias
        // and the sProgrammaticNames array.
    for (sal_Int32 i(FIRSTNAME); i < END; ++i) {
        m_aAliasMap[m_aAlias[i]] = sProgrammaticNames[i];
    }

        return;
}
//------------------------------------------------------------------
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: configpathes.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2006-07-25 09:51:36 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef INCLUDED_UNOTOOLSDLLAPI_H
#include "unotools/unotoolsdllapi.h"
#endif

#ifndef UNOTOOLS_CONFIGPATHES_HXX_INCLUDED
#define UNOTOOLS_CONFIGPATHES_HXX_INCLUDED

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

namespace rtl
{
    class OUString;
}

//----------------------------------------------------------------------------
namespace utl
{
//----------------------------------------------------------------------------
    /** extract the local nodename and the parent nodepath
        from a configuration path.

        @param _sInPath
            A configuration path that is not an empty or root path.

            If this is not a valid configuration path, it is interpreted as
            local name of a node.

        @param _rsOutPath
            On exit: The configuration path obtained by dropping
                     the last level off <var>_sInPath</var>.

                     If <var>_sInPath</var> could not be parsed as a valid
                     configuration path, this is set to an empty string.

        @param _rsLocalName
            On exit: The plain (non-escaped) name of the node identified by
                     <var>_sInPath</var>.

                     If <var>_sInPath</var> could not be parsed as a valid
                     configuration path, this is set to <var>_sInPath</var>.

        @returns
            <TRUE/>,  if a parent path could be set
            <FALSE/>, if the path was a one-level path or an invalid path

    */
    UNOTOOLS_DLLPUBLIC sal_Bool splitLastFromConfigurationPath(::rtl::OUString const& _sInPath,
                                            ::rtl::OUString& _rsOutPath,
                                            ::rtl::OUString& _rsLocalName);

//----------------------------------------------------------------------------
    /** extract the first nodename from a configuration path.

        @param _sInPath
            A relative configuration path that is not empty.

            If this is not a valid configuration path, it is interpreted as
            a single name of a node.

        @returns
            The plain (non-escaped) name of the node that is the first step
            when traversing <var>_sInPath</var>.

            If <var>_sInPath</var> could not be parsed as a valid
            configuration path, it is returned unaltered.

    */
    UNOTOOLS_DLLPUBLIC ::rtl::OUString extractFirstFromConfigurationPath(::rtl::OUString const& _sInPath);

//----------------------------------------------------------------------------
    /** check whether a path is to a nested node with respect to a parent path.

        @param _sNestedPath
            A configuration path that maybe points to a descendant of the node
            identified by <var>_sPrefixPath</var>, with both pathes starting
            from the same node (or both being absolute).

        @param _sPrefixPath
            A configuration path.

            If this path is absolute, <var>_sNestedPath</var> should be absolute;
            If this path is relative, <var>_sNestedPath</var> should be relative;
            If this path is empty,    <var>_sNestedPath</var> may start with a '/',
            which is disregarded.

        @returns
            <TRUE/>, if <var>_sPrefixPath</var> is  a prefix of <var>_sNestedPath</var>;
            <FALSE/> otherwise.

            If both pathes are equal <TRUE/> is returned.

    */
    sal_Bool isPrefixOfConfigurationPath(::rtl::OUString const& _sNestedPath,
                                         ::rtl::OUString const& _sPrefixPath);

//----------------------------------------------------------------------------
    /** get the relative path to a nested node with respect to a parent path.

        @param _sNestedPath
            A configuration path that points to a descendant of the node
            identified by <var>_sPrefixPath</var>, with both pathes starting
            from the same node (or both being absolute).

        @param _sPrefixPath
            A configuration path.

            If this path is absolute, <var>_sNestedPath</var> must be absolute;
            If this path is relative, <var>_sNestedPath</var> must be relative;
            If this path is empty, <var>_sNestedPath</var> may start with a '/',
            which is stripped.

        @returns
            The remaining relative path from the target of <var>_sPrefixPath</var>
            to the target of <var>_sNestedPath</var>.

            If <var>_sPrefixPath</var> is not a prefix of <var>_sNestedPath</var>,
            <var>_sNestedPath</var> is returned unaltered.

    */
    ::rtl::OUString dropPrefixFromConfigurationPath(::rtl::OUString const& _sNestedPath,
                                                    ::rtl::OUString const& _sPrefixPath);

//----------------------------------------------------------------------------
    /** Create a one-level relative configuration path from a set element name
        without a known set element type.

        @param _sElementName
            An arbitrary string that is to be interpreted as
            name of a configuration set element.

        @returns
            A one-level relative path to the element, of the form
            "*['<Name>']", where <Name> is properly escaped.

    */
    UNOTOOLS_DLLPUBLIC ::rtl::OUString wrapConfigurationElementName(::rtl::OUString const& _sElementName);

//----------------------------------------------------------------------------
    /** Create a one-level relative configuration path from a set element name
        and a known set element type.

        @param _sElementName
            An arbitrary string that is to be interpreted as
            name of a configuration set element.

        @param _sTypeName
            An string identifying the type of the element. Usually this is be
            the name of the element-template of the set.

        @returns
            A one-level relative path to the element, of the form
            "<Type>['<Name>']", where <Name> is properly escaped.

    */
    ::rtl::OUString wrapConfigurationElementName(::rtl::OUString const& _sElementName,
                                                 ::rtl::OUString const& _sTypeName);

//----------------------------------------------------------------------------
}   // namespace utl
//----------------------------------------------------------------------------

#endif // UNOTOOLS_CONFIGPATHES_HXX_INCLUDED

<commit_msg>INTEGRATION: CWS changefileheader (1.4.92); FILE MERGED 2008/04/01 16:03:26 thb 1.4.92.3: #i85898# Stripping all external header guards 2008/04/01 12:59:34 thb 1.4.92.2: #i85898# Stripping all external header guards 2008/03/31 13:03:34 rt 1.4.92.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: configpathes.hxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#include "unotools/unotoolsdllapi.h"

#ifndef UNOTOOLS_CONFIGPATHES_HXX_INCLUDED
#define UNOTOOLS_CONFIGPATHES_HXX_INCLUDED
#include <sal/types.h>

namespace rtl
{
    class OUString;
}

//----------------------------------------------------------------------------
namespace utl
{
//----------------------------------------------------------------------------
    /** extract the local nodename and the parent nodepath
        from a configuration path.

        @param _sInPath
            A configuration path that is not an empty or root path.

            If this is not a valid configuration path, it is interpreted as
            local name of a node.

        @param _rsOutPath
            On exit: The configuration path obtained by dropping
                     the last level off <var>_sInPath</var>.

                     If <var>_sInPath</var> could not be parsed as a valid
                     configuration path, this is set to an empty string.

        @param _rsLocalName
            On exit: The plain (non-escaped) name of the node identified by
                     <var>_sInPath</var>.

                     If <var>_sInPath</var> could not be parsed as a valid
                     configuration path, this is set to <var>_sInPath</var>.

        @returns
            <TRUE/>,  if a parent path could be set
            <FALSE/>, if the path was a one-level path or an invalid path

    */
    UNOTOOLS_DLLPUBLIC sal_Bool splitLastFromConfigurationPath(::rtl::OUString const& _sInPath,
                                            ::rtl::OUString& _rsOutPath,
                                            ::rtl::OUString& _rsLocalName);

//----------------------------------------------------------------------------
    /** extract the first nodename from a configuration path.

        @param _sInPath
            A relative configuration path that is not empty.

            If this is not a valid configuration path, it is interpreted as
            a single name of a node.

        @returns
            The plain (non-escaped) name of the node that is the first step
            when traversing <var>_sInPath</var>.

            If <var>_sInPath</var> could not be parsed as a valid
            configuration path, it is returned unaltered.

    */
    UNOTOOLS_DLLPUBLIC ::rtl::OUString extractFirstFromConfigurationPath(::rtl::OUString const& _sInPath);

//----------------------------------------------------------------------------
    /** check whether a path is to a nested node with respect to a parent path.

        @param _sNestedPath
            A configuration path that maybe points to a descendant of the node
            identified by <var>_sPrefixPath</var>, with both pathes starting
            from the same node (or both being absolute).

        @param _sPrefixPath
            A configuration path.

            If this path is absolute, <var>_sNestedPath</var> should be absolute;
            If this path is relative, <var>_sNestedPath</var> should be relative;
            If this path is empty,    <var>_sNestedPath</var> may start with a '/',
            which is disregarded.

        @returns
            <TRUE/>, if <var>_sPrefixPath</var> is  a prefix of <var>_sNestedPath</var>;
            <FALSE/> otherwise.

            If both pathes are equal <TRUE/> is returned.

    */
    sal_Bool isPrefixOfConfigurationPath(::rtl::OUString const& _sNestedPath,
                                         ::rtl::OUString const& _sPrefixPath);

//----------------------------------------------------------------------------
    /** get the relative path to a nested node with respect to a parent path.

        @param _sNestedPath
            A configuration path that points to a descendant of the node
            identified by <var>_sPrefixPath</var>, with both pathes starting
            from the same node (or both being absolute).

        @param _sPrefixPath
            A configuration path.

            If this path is absolute, <var>_sNestedPath</var> must be absolute;
            If this path is relative, <var>_sNestedPath</var> must be relative;
            If this path is empty, <var>_sNestedPath</var> may start with a '/',
            which is stripped.

        @returns
            The remaining relative path from the target of <var>_sPrefixPath</var>
            to the target of <var>_sNestedPath</var>.

            If <var>_sPrefixPath</var> is not a prefix of <var>_sNestedPath</var>,
            <var>_sNestedPath</var> is returned unaltered.

    */
    ::rtl::OUString dropPrefixFromConfigurationPath(::rtl::OUString const& _sNestedPath,
                                                    ::rtl::OUString const& _sPrefixPath);

//----------------------------------------------------------------------------
    /** Create a one-level relative configuration path from a set element name
        without a known set element type.

        @param _sElementName
            An arbitrary string that is to be interpreted as
            name of a configuration set element.

        @returns
            A one-level relative path to the element, of the form
            "*['<Name>']", where <Name> is properly escaped.

    */
    UNOTOOLS_DLLPUBLIC ::rtl::OUString wrapConfigurationElementName(::rtl::OUString const& _sElementName);

//----------------------------------------------------------------------------
    /** Create a one-level relative configuration path from a set element name
        and a known set element type.

        @param _sElementName
            An arbitrary string that is to be interpreted as
            name of a configuration set element.

        @param _sTypeName
            An string identifying the type of the element. Usually this is be
            the name of the element-template of the set.

        @returns
            A one-level relative path to the element, of the form
            "<Type>['<Name>']", where <Name> is properly escaped.

    */
    ::rtl::OUString wrapConfigurationElementName(::rtl::OUString const& _sElementName,
                                                 ::rtl::OUString const& _sTypeName);

//----------------------------------------------------------------------------
}   // namespace utl
//----------------------------------------------------------------------------

#endif // UNOTOOLS_CONFIGPATHES_HXX_INCLUDED

<|endoftext|>


<commit_before><commit_msg>For now, reintroduce the horrible static counter into utl::TempFile<commit_after><|endoftext|>