<commit_before>// Copyright (C) 2016 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <algorithm>
#include "EventDispatcher.h"

namespace ouzel
{
    EventDispatcher::EventDispatcher()
    {

    }

    EventDispatcher::~EventDispatcher()
    {

    }

    void EventDispatcher::update()
    {
        auto eventHandlersCopy = eventHandlers;

        while (!eventQueue.empty())
        {
            mutex.lock();

            const Event& event = eventQueue.front();
            eventQueue.pop();

            mutex.unlock();

            for (const EventHandlerPtr& eventHandler : eventHandlersCopy)
            {
                if (eventHandler)
                {
                    switch (event.type)
                    {
                        case Event::Type::KEY_DOWN:
                        case Event::Type::KEY_UP:
                        case Event::Type::KEY_REPEAT:
                            if (eventHandler->keyboardHandler)
                            {
                                eventHandler->keyboardHandler(event.type, event.keyboardEvent, event.sender);
                            }
                            break;

                        case Event::Type::MOUSE_DOWN:
                        case Event::Type::MOUSE_UP:
                        case Event::Type::MOUSE_SCROLL:
                        case Event::Type::MOUSE_MOVE:
                            if (eventHandler->mouseHandler)
                            {
                                eventHandler->mouseHandler(event.type, event.mouseEvent, event.sender);
                            }
                            break;
                        case Event::Type::TOUCH_BEGIN:
                        case Event::Type::TOUCH_MOVE:
                        case Event::Type::TOUCH_END:
                        case Event::Type::TOUCH_CANCEL:
                            if (eventHandler->touchHandler)
                            {
                                eventHandler->touchHandler(event.type, event.touchEvent, event.sender);
                            }
                            break;
                        case Event::Type::GAMEPAD_CONNECT:
                        case Event::Type::GAMEPAD_DISCONNECT:
                        case Event::Type::GAMEPAD_BUTTON_CHANGE:
                            if (eventHandler->gamepadHandler)
                            {
                                eventHandler->gamepadHandler(event.type, event.gamepadEvent, event.sender);
                            }
                            break;
                        case Event::Type::WINDOW_SIZE_CHANGE:
                        case Event::Type::WINDOW_TITLE_CHANGE:
                        case Event::Type::WINDOW_FULLSCREEN_CHANGE:
                            if (eventHandler->windowHandler)
                            {
                                eventHandler->windowHandler(event.type, event.windowEvent, event.sender);
                            }
                            break;
                        case Event::Type::LOW_MEMORY:
                        case Event::Type::OPEN_FILE:
                            if (eventHandler->systemHandler)
                            {
                                eventHandler->systemHandler(event.type, event.systemEvent, event.sender);
                            }
                            break;
                        case Event::Type::UI_ENTER_NODE:
                        case Event::Type::UI_LEAVE_NODE:
                        case Event::Type::UI_PRESS_NODE:
                        case Event::Type::UI_RELEASE_NODE:
                        case Event::Type::UI_CLICK_NODE:
                        case Event::Type::UI_DRAG_NODE:
                            if (eventHandler->uiHandler)
                            {
                                eventHandler->uiHandler(event.type, event.uiEvent, event.sender);
                            }
                            break;
                    }
                }
            }
        }
    }

    void EventDispatcher::addEventHandler(const EventHandlerPtr& eventHandler)
    {
        std::vector<EventHandlerPtr>::iterator i = std::find(eventHandlers.begin(), eventHandlers.end(), eventHandler);

        if (i == eventHandlers.end())
        {
            eventHandler->remove = false;
            eventHandlers.push_back(eventHandler);

            std::sort(eventHandlers.begin(), eventHandlers.end(), [](const EventHandlerPtr& a, const EventHandlerPtr& b) {
                return a->priority < b->priority;
            });
        }
    }

    void EventDispatcher::removeEventHandler(const EventHandlerPtr& eventHandler)
    {
        std::vector<EventHandlerPtr>::iterator i = std::find(eventHandlers.begin(), eventHandlers.end(), eventHandler);

        if (i != eventHandlers.end())
        {
            eventHandlers.erase(i);
        }
    }

    void EventDispatcher::dispatchEvent(const Event& event)
    {
        std::lock_guard<std::mutex> mutexLock(mutex);

        eventQueue.push(event);
    }
}
<commit_msg>Handle widget change event<commit_after>// Copyright (C) 2016 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <algorithm>
#include "EventDispatcher.h"

namespace ouzel
{
    EventDispatcher::EventDispatcher()
    {

    }

    EventDispatcher::~EventDispatcher()
    {

    }

    void EventDispatcher::update()
    {
        auto eventHandlersCopy = eventHandlers;

        while (!eventQueue.empty())
        {
            mutex.lock();

            const Event& event = eventQueue.front();
            eventQueue.pop();

            mutex.unlock();

            for (const EventHandlerPtr& eventHandler : eventHandlersCopy)
            {
                if (eventHandler)
                {
                    switch (event.type)
                    {
                        case Event::Type::KEY_DOWN:
                        case Event::Type::KEY_UP:
                        case Event::Type::KEY_REPEAT:
                            if (eventHandler->keyboardHandler)
                            {
                                eventHandler->keyboardHandler(event.type, event.keyboardEvent, event.sender);
                            }
                            break;

                        case Event::Type::MOUSE_DOWN:
                        case Event::Type::MOUSE_UP:
                        case Event::Type::MOUSE_SCROLL:
                        case Event::Type::MOUSE_MOVE:
                            if (eventHandler->mouseHandler)
                            {
                                eventHandler->mouseHandler(event.type, event.mouseEvent, event.sender);
                            }
                            break;
                        case Event::Type::TOUCH_BEGIN:
                        case Event::Type::TOUCH_MOVE:
                        case Event::Type::TOUCH_END:
                        case Event::Type::TOUCH_CANCEL:
                            if (eventHandler->touchHandler)
                            {
                                eventHandler->touchHandler(event.type, event.touchEvent, event.sender);
                            }
                            break;
                        case Event::Type::GAMEPAD_CONNECT:
                        case Event::Type::GAMEPAD_DISCONNECT:
                        case Event::Type::GAMEPAD_BUTTON_CHANGE:
                            if (eventHandler->gamepadHandler)
                            {
                                eventHandler->gamepadHandler(event.type, event.gamepadEvent, event.sender);
                            }
                            break;
                        case Event::Type::WINDOW_SIZE_CHANGE:
                        case Event::Type::WINDOW_TITLE_CHANGE:
                        case Event::Type::WINDOW_FULLSCREEN_CHANGE:
                            if (eventHandler->windowHandler)
                            {
                                eventHandler->windowHandler(event.type, event.windowEvent, event.sender);
                            }
                            break;
                        case Event::Type::LOW_MEMORY:
                        case Event::Type::OPEN_FILE:
                            if (eventHandler->systemHandler)
                            {
                                eventHandler->systemHandler(event.type, event.systemEvent, event.sender);
                            }
                            break;
                        case Event::Type::UI_ENTER_NODE:
                        case Event::Type::UI_LEAVE_NODE:
                        case Event::Type::UI_PRESS_NODE:
                        case Event::Type::UI_RELEASE_NODE:
                        case Event::Type::UI_CLICK_NODE:
                        case Event::Type::UI_DRAG_NODE:
                        case Event::Type::UI_WIDGET_CHANGE:
                            if (eventHandler->uiHandler)
                            {
                                eventHandler->uiHandler(event.type, event.uiEvent, event.sender);
                            }
                            break;
                    }
                }
            }
        }
    }

    void EventDispatcher::addEventHandler(const EventHandlerPtr& eventHandler)
    {
        std::vector<EventHandlerPtr>::iterator i = std::find(eventHandlers.begin(), eventHandlers.end(), eventHandler);

        if (i == eventHandlers.end())
        {
            eventHandler->remove = false;
            eventHandlers.push_back(eventHandler);

            std::sort(eventHandlers.begin(), eventHandlers.end(), [](const EventHandlerPtr& a, const EventHandlerPtr& b) {
                return a->priority < b->priority;
            });
        }
    }

    void EventDispatcher::removeEventHandler(const EventHandlerPtr& eventHandler)
    {
        std::vector<EventHandlerPtr>::iterator i = std::find(eventHandlers.begin(), eventHandlers.end(), eventHandler);

        if (i != eventHandlers.end())
        {
            eventHandlers.erase(i);
        }
    }

    void EventDispatcher::dispatchEvent(const Event& event)
    {
        std::lock_guard<std::mutex> mutexLock(mutex);

        eventQueue.push(event);
    }
}
<|endoftext|>


<commit_before>namespace space_partition
{
    class Chunk
    {
        public:
            // constructor.
            Chunk();

            // destructor.
            ~Chunk();

        private:
            void render();
    };
}
<commit_msg>Added missing `#include` guard.<commit_after>#ifndef __CHUNK_HPP_INCLUDED
#define __CHUNK_HPP_INCLUDED

namespace space_partition
{
    class Chunk
    {
        public:
            // constructor.
            Chunk();

            // destructor.
            ~Chunk();

        private:
            void render();
    };
}

#endif
<|endoftext|>


<commit_before>// cmetab.cpp : implementation of the CMetab class
//

#include <iostream>
#include <string>
#include <vector>

#define  COPASI_TRACE_CONSTRUCTION

#include "copasi.h"
#include "utilities/CGlobals.h"
#include "report/CCopasiObjectReference.h"
#include "CCompartment.h"
#include "CMetab.h"

const CCompartment * CMetab::mpParentCompartment = NULL;

const std::string CMetab::StatusName[] =
  {"fixed", "independent", "dependent"};

void CMetab::setParentCompartment(const CCompartment * parentCompartment)
{mpParentCompartment = parentCompartment;}

/////////////////////////////////////////////////////////////////////////////
// CMetab

CMetab::CMetab(const std::string & name,
               const CCopasiContainer * pParent):
    CCopasiContainer(name, pParent, "Metabolite"),
    mName(mObjectName),
    mConcDbl(Copasi->DefaultConc),
    mIConcDbl(Copasi->DefaultConc),
    mNumberInt((C_INT32)(Copasi->DefaultConc * Copasi->DefaultVolume)),
    mINumberInt((C_INT32)(Copasi->DefaultConc * Copasi->DefaultVolume)),
    mRate(1.0),
    mTT(0.0),
    mStatus(METAB_VARIABLE)
{
  initModel();
  initCompartment(NULL);

  CONSTRUCTOR_TRACE;
}

CMetab::CMetab(const CMetab & src,
               const CCopasiContainer * pParent):
    CCopasiContainer(src, pParent),
    mName(CCopasiContainer::mObjectName),
    mConcDbl(src.mConcDbl),
    mIConcDbl(src.mIConcDbl),
    mNumberInt(src.mNumberInt),
    mINumberInt(src.mINumberInt),
    mRate(src.mRate),
    mTT(src.mTT),
    mStatus(src.mStatus)
{
  initModel();
  initCompartment(src.mpCompartment);

  CONSTRUCTOR_TRACE;
}

CMetab &CMetab::operator=(const CMetabOld &RHS)
{
  mName = RHS.mName;
  mConcDbl = RHS.mIConc;
  mIConcDbl = RHS.mIConc;
  mNumberInt = -1;
  mINumberInt = -1; // Invalid value, this causes checkConcentrationAndNumber() to fix it later
  mRate = 1.0;
  mTT = 0.0;
  mStatus = RHS.mStatus;
  mpCompartment = NULL;
  mpModel = NULL;

  return *this;  // Assignment operator returns left side.
}

CMetab::~CMetab() {DESTRUCTOR_TRACE;}

void CMetab::cleanup() {}

void CMetab::initModel()
{
  mpModel = (CModel *) getObjectAncestor("Model");
  if (!mpModel) mpModel = Copasi->Model;
}

void CMetab::initCompartment(const CCompartment * pCompartment)
{
  mpCompartment = (const CCompartment *) getObjectAncestor("Compartment");
  if (!mpCompartment) mpCompartment = pCompartment;
  if (!mpCompartment) mpCompartment = mpParentCompartment;
}

C_INT32 CMetab::load(CReadConfig &configbuffer)
{
  C_INT32 Fail = 0;

  Fail = configbuffer.getVariable("Metabolite", "string",
                                  (void *) & mName,
                                  CReadConfig::SEARCH);

  if (Fail)
    return Fail;

  Fail = configbuffer.getVariable("InitialConcentration", "C_FLOAT64",
                                  (void *) & mIConcDbl);

  setInitialConcentration(mIConcDbl);
  setConcentration(mIConcDbl);

  Fail = configbuffer.getVariable("InitialParticleNumber", "C_INT32",
                                  (void *) & mINumberInt);

  if (Fail)
    return Fail; // is it really necessary to load and save both representations of quantity?

  mNumberInt = mINumberInt;

  Fail = configbuffer.getVariable("Type", "C_INT16",
                                  (void *) & mStatus);

  if (Fail)
    return Fail;

  // sanity check
  if ((mStatus < 0) || (mStatus > 7))
    {
      CCopasiMessage(CCopasiMessage::WARNING,
                     "The file specifies a non-existing type "
                     "for '%s'.\nReset to internal metabolite.",
                     mName.c_str());
      mStatus = 1;
    }

  // sanity check
  if ((mStatus != METAB_MOIETY) && (mIConcDbl < 0.0))
    {
      CCopasiMessage(CCopasiMessage::WARNING,
                     "The file specifies a negative concentration "
                     "for '%s'.\nReset to default.",
                     mName.c_str());
      mIConcDbl = Copasi->DefaultConc;
    }

  return Fail;
}

C_INT32 CMetab::save(CWriteConfig &configbuffer)
{
  C_INT32 Fail = 0;

  Fail = configbuffer.setVariable("Metabolite", "string",
                                  (void *) & mName);

  if (Fail)
    return Fail;

  Fail = configbuffer.setVariable("InitialConcentration", "C_FLOAT64",
                                  (void *) & mIConcDbl);

  if (Fail)
    return Fail;

  Fail = configbuffer.setVariable("InitialParticleNumber", "C_INT32",
                                  (void *) & mINumberInt);

  if (Fail)
    return Fail; // is it really necessary to load and save both representations of quantity?

  Fail = configbuffer.setVariable("Type", "C_INT16",
                                  (void *) & mStatus);

  return Fail;
}

C_INT32 CMetab::saveOld(CWriteConfig &configbuffer)
{
  C_INT32 c, Fail = 0;

  Fail = configbuffer.setVariable("Metabolite", "string", (void *) & mName);
  if (Fail)
    return Fail;
  Fail = configbuffer.setVariable("Concentration", "C_FLOAT64", (void *) & mIConcDbl);
  if (Fail)
    return Fail;
  c = mpModel->getCompartments().getIndex(mpCompartment->getName());
  Fail = configbuffer.setVariable("Compartment", "C_INT32", (void *) & c);
  if (Fail)
    return Fail;
  Fail = configbuffer.setVariable("Type", "C_INT16", (void *) & mStatus);
  return Fail;
}

void CMetab::saveSBML(std::ofstream &fout)
{
  std::string str;
  FixSName(mName, str);
  fout << "\t\t\t<specie name=\"" << str << "\"";
  FixSName(getCompartment()->getName(), str);
  fout << " compartment=\"" + str + "\"";
  fout << " initialAmount=\"" << mIConcDbl << "\"";
  fout << " boundaryCondition=\"";
  if (mStatus == METAB_FIXED)
    fout << "true";
  else
    fout << "false";
  fout << "\"/>" << std::endl;
}

const std::string & CMetab::getName() const
  {
    return mName;
  }

const C_FLOAT64 & CMetab::getConcentration() const
  {
    return mConcDbl;
  }

const C_INT32 & CMetab::getNumberInt() const
  {
    return mNumberInt;
  }

C_FLOAT64 CMetab::getNumberDbl() const
  {
    return mConcDbl * mpCompartment->getVolume()
    * mpModel->getQuantity2NumberFactor();
  }

const C_FLOAT64 & CMetab::getInitialConcentration() const
  {
    return mIConcDbl;
  }

const C_INT32 & CMetab::getInitialNumberInt() const
  {
    return mINumberInt;
  }

C_FLOAT64 CMetab::getInitialNumberDbl() const
  {
    return mIConcDbl * mpCompartment->getVolume()
    * mpModel->getQuantity2NumberFactor();
  }

const C_INT16 & CMetab::getStatus() const
  {
    return mStatus;
  }

const CCompartment * CMetab::getCompartment() const
  {
    return mpCompartment;
  }

const CModel * CMetab::getModel() const
  {
    return mpModel;
  }

void CMetab::setTransitionTime(const C_FLOAT64 & transitionTime)
{
  mTT = transitionTime;
}

const C_FLOAT64 & CMetab::getTransitionTime()
{
  return mTT;
}

void CMetab::setName(const std::string & name)
{
  mName = name;
}

// ***** set quantities ********

void CMetab::setConcentration(const C_FLOAT64 concentration)
{
  mConcDbl = concentration;
  mNumberInt = (C_INT32) (concentration * mpCompartment->getVolume()
                          * mpModel->getQuantity2NumberFactor());
}

void CMetab::setInitialConcentration(const C_FLOAT64 initialConcentration)
{
  mIConcDbl = initialConcentration;
  mINumberInt = (C_INT32) (initialConcentration * mpCompartment->getVolume()
                           * mpModel->getQuantity2NumberFactor());
}

void CMetab::setNumberInt(const C_INT32 number)
{
  mNumberInt = number;
  mConcDbl = ((C_FLOAT64) number) * mpCompartment->getVolumeInv()
             * mpModel->getNumber2QuantityFactor();
}

void CMetab::setInitialNumberInt(const C_INT32 initialNumber)
{
  mINumberInt = initialNumber;
  mIConcDbl = ((C_FLOAT64) initialNumber) * mpCompartment->getVolumeInv()
              * mpModel->getNumber2QuantityFactor();
}

void CMetab::setNumberDbl(const C_FLOAT64 number)
{
  mConcDbl = number * mpCompartment->getVolumeInv()
             * mpModel->getNumber2QuantityFactor();
  mNumberInt = (C_INT32) number;
}

void CMetab::setInitialNumberDbl(const C_FLOAT64 initialNumber)
{
  mIConcDbl = initialNumber * mpCompartment->getVolumeInv()
              * mpModel->getNumber2QuantityFactor();
  mINumberInt = (C_INT32) initialNumber;
}

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

void CMetab::setStatus(const C_INT16 status)
{
  mStatus = status;
}

void CMetab::setCompartment(const CCompartment * compartment)
{
  mpCompartment = compartment;
}

void CMetab::setModel(CModel * model)
{
  mpModel = model;
}

bool CMetab::isValidName(const std::string &name) const
  {
    return (name.find_first_of("; ") == std::string::npos);
  }

void CMetab::initObjects()
{
  addObjectReference("Name", mName);
  addObjectReference("Concentration", mConcDbl);
  addObjectReference("InitialConcentration", mIConcDbl);
  addObjectReference("TransitionTime", mTT);
}

CMetabOld::CMetabOld(const std::string & name,
                     const CCopasiContainer * pParent):
    CCopasiContainer(name, pParent, "Old Metabolite"),
    mName(mObjectName),
    mIConc(Copasi->DefaultConc),
    mStatus(CMetab::METAB_VARIABLE),
    mCompartment()
{CONSTRUCTOR_TRACE;}

CMetabOld::CMetabOld(const CMetabOld & src,
                     const CCopasiContainer * pParent):
    CCopasiContainer(src, pParent),
    mName(mObjectName),
    mIConc(src.mIConc),
    mStatus(src.mStatus),
    mCompartment(src.mCompartment)
{CONSTRUCTOR_TRACE;}

CMetabOld::~CMetabOld() {DESTRUCTOR_TRACE;}

void CMetabOld::cleanup(){}

C_INT32 CMetabOld::load(CReadConfig &configbuffer)
{
  C_INT32 Fail = 0;

  Fail = configbuffer.getVariable("Metabolite", "string",
                                  (void *) & mName,
                                  CReadConfig::SEARCH);

  if (Fail)
    return Fail;

  Fail = configbuffer.getVariable("Concentration", "C_FLOAT64",
                                  (void *) & mIConc);

  if (Fail)
    return Fail;

  Fail = configbuffer.getVariable("Compartment", "C_INT32",
                                  (void *) & mCompartment);

  if (Fail)
    return Fail;

  C_INT32 Status;

  Fail = configbuffer.getVariable("Type", "C_INT32",
                                  (void *) & Status);

  mStatus = (C_INT16) Status;

  // sanity check
  if ((mStatus < 0) || (mStatus > 7))
    {
      CCopasiMessage(CCopasiMessage::WARNING,
                     "The file specifies a non-existing type "
                     "for '%s'.\nReset to internal metabolite.",
                     mName.c_str());
      mStatus = 1;
    }

  // sanity check
  if ((mStatus != METAB_MOIETY) && (mIConc < 0.0))
    {
      CCopasiMessage(CCopasiMessage::WARNING,
                     "The file specifies a negative concentration "
                     "for '%s'.\nReset to default.",
                     mName.c_str());
      mIConc = Copasi->DefaultConc;
    }

  return Fail;
}
C_INT32 CMetabOld::save(CWriteConfig & C_UNUSED(configbuffer)){return 0;}
C_INT32 CMetabOld::getIndex() const {return mCompartment;}
const std::string & CMetabOld::getName() const {return mName;}

/**
 * Returns the address of mIConcDbl  Wei Sun
 */
void * CMetab::getIConcAddr()
{
  return &mIConcDbl;
}

/**
 * Returns the address of mConcDbl
 */
void * CMetab::getConcAddr()
{
  return &mConcDbl;
}

/**
 * Returns the address of mTT
 */
void * CMetab::getTTAddr()
{
  return &mTT;
}

// non-member
bool operator<(const CMetab &lhs, const CMetab &rhs)
{
  // Do the comparison based on the name

  if (lhs.getName() < rhs.getName())
    {
      return true;
    }
  else
    {
      return false;
    }
}

/**
 * Return rate of production of this metaboLite
 */
const C_FLOAT64 & CMetab::getRate() const
  {
    return mRate;
  }

void CMetab::setRate(const C_FLOAT64 & rate)
{
  mRate = rate * getCompartment()->getVolumeInv()
          * mpModel->getNumber2QuantityFactor();
  //  calculateTransitionTime();
}
void CMetab::calculateTransitionTime(void) {mTT = mConcDbl / mRate;}

void CMetab::checkConcentrationAndNumber()
{
  if (mNumberInt < 0)
    {
      setConcentration(getConcentration());
      setInitialConcentration(getInitialConcentration());
    }

  if (mConcDbl < 0)
    {
      setNumberInt(getNumberInt());
      setInitialNumberInt(getInitialNumberInt());
    }
}
<commit_msg>sorted out some include dependencies<commit_after>// cmetab.cpp : implementation of the CMetab class
//

#include <iostream>
#include <string>
#include <vector>

#define  COPASI_TRACE_CONSTRUCTION

#include "copasi.h"
#include "utilities/CGlobals.h"
#include "utilities/utility.h"
#include "report/CCopasiObjectReference.h"
#include "CCompartment.h"
#include "CMetab.h"

const CCompartment * CMetab::mpParentCompartment = NULL;

const std::string CMetab::StatusName[] =
  {"fixed", "independent", "dependent"};

void CMetab::setParentCompartment(const CCompartment * parentCompartment)
{mpParentCompartment = parentCompartment;}

/////////////////////////////////////////////////////////////////////////////
// CMetab

CMetab::CMetab(const std::string & name,
               const CCopasiContainer * pParent):
    CCopasiContainer(name, pParent, "Metabolite"),
    mName(mObjectName),
    mConcDbl(Copasi->DefaultConc),
    mIConcDbl(Copasi->DefaultConc),
    mNumberInt((C_INT32)(Copasi->DefaultConc * Copasi->DefaultVolume)),
    mINumberInt((C_INT32)(Copasi->DefaultConc * Copasi->DefaultVolume)),
    mRate(1.0),
    mTT(0.0),
    mStatus(METAB_VARIABLE)
{
  initModel();
  initCompartment(NULL);

  CONSTRUCTOR_TRACE;
}

CMetab::CMetab(const CMetab & src,
               const CCopasiContainer * pParent):
    CCopasiContainer(src, pParent),
    mName(CCopasiContainer::mObjectName),
    mConcDbl(src.mConcDbl),
    mIConcDbl(src.mIConcDbl),
    mNumberInt(src.mNumberInt),
    mINumberInt(src.mINumberInt),
    mRate(src.mRate),
    mTT(src.mTT),
    mStatus(src.mStatus)
{
  initModel();
  initCompartment(src.mpCompartment);

  CONSTRUCTOR_TRACE;
}

CMetab &CMetab::operator=(const CMetabOld &RHS)
{
  mName = RHS.mName;
  mConcDbl = RHS.mIConc;
  mIConcDbl = RHS.mIConc;
  mNumberInt = -1;
  mINumberInt = -1; // Invalid value, this causes checkConcentrationAndNumber() to fix it later
  mRate = 1.0;
  mTT = 0.0;
  mStatus = RHS.mStatus;
  mpCompartment = NULL;
  mpModel = NULL;

  return *this;  // Assignment operator returns left side.
}

CMetab::~CMetab() {DESTRUCTOR_TRACE;}

void CMetab::cleanup() {}

void CMetab::initModel()
{
  mpModel = (CModel *) getObjectAncestor("Model");
  if (!mpModel) mpModel = Copasi->Model;
}

void CMetab::initCompartment(const CCompartment * pCompartment)
{
  mpCompartment = (const CCompartment *) getObjectAncestor("Compartment");
  if (!mpCompartment) mpCompartment = pCompartment;
  if (!mpCompartment) mpCompartment = mpParentCompartment;
}

C_INT32 CMetab::load(CReadConfig &configbuffer)
{
  C_INT32 Fail = 0;

  Fail = configbuffer.getVariable("Metabolite", "string",
                                  (void *) & mName,
                                  CReadConfig::SEARCH);

  if (Fail)
    return Fail;

  Fail = configbuffer.getVariable("InitialConcentration", "C_FLOAT64",
                                  (void *) & mIConcDbl);

  setInitialConcentration(mIConcDbl);
  setConcentration(mIConcDbl);

  Fail = configbuffer.getVariable("InitialParticleNumber", "C_INT32",
                                  (void *) & mINumberInt);

  if (Fail)
    return Fail; // is it really necessary to load and save both representations of quantity?

  mNumberInt = mINumberInt;

  Fail = configbuffer.getVariable("Type", "C_INT16",
                                  (void *) & mStatus);

  if (Fail)
    return Fail;

  // sanity check
  if ((mStatus < 0) || (mStatus > 7))
    {
      CCopasiMessage(CCopasiMessage::WARNING,
                     "The file specifies a non-existing type "
                     "for '%s'.\nReset to internal metabolite.",
                     mName.c_str());
      mStatus = 1;
    }

  // sanity check
  if ((mStatus != METAB_MOIETY) && (mIConcDbl < 0.0))
    {
      CCopasiMessage(CCopasiMessage::WARNING,
                     "The file specifies a negative concentration "
                     "for '%s'.\nReset to default.",
                     mName.c_str());
      mIConcDbl = Copasi->DefaultConc;
    }

  return Fail;
}

C_INT32 CMetab::save(CWriteConfig &configbuffer)
{
  C_INT32 Fail = 0;

  Fail = configbuffer.setVariable("Metabolite", "string",
                                  (void *) & mName);

  if (Fail)
    return Fail;

  Fail = configbuffer.setVariable("InitialConcentration", "C_FLOAT64",
                                  (void *) & mIConcDbl);

  if (Fail)
    return Fail;

  Fail = configbuffer.setVariable("InitialParticleNumber", "C_INT32",
                                  (void *) & mINumberInt);

  if (Fail)
    return Fail; // is it really necessary to load and save both representations of quantity?

  Fail = configbuffer.setVariable("Type", "C_INT16",
                                  (void *) & mStatus);

  return Fail;
}

C_INT32 CMetab::saveOld(CWriteConfig &configbuffer)
{
  C_INT32 c, Fail = 0;

  Fail = configbuffer.setVariable("Metabolite", "string", (void *) & mName);
  if (Fail)
    return Fail;
  Fail = configbuffer.setVariable("Concentration", "C_FLOAT64", (void *) & mIConcDbl);
  if (Fail)
    return Fail;
  c = mpModel->getCompartments().getIndex(mpCompartment->getName());
  Fail = configbuffer.setVariable("Compartment", "C_INT32", (void *) & c);
  if (Fail)
    return Fail;
  Fail = configbuffer.setVariable("Type", "C_INT16", (void *) & mStatus);
  return Fail;
}

void CMetab::saveSBML(std::ofstream &fout)
{
  std::string str;
  FixSName(mName, str);
  fout << "\t\t\t<specie name=\"" << str << "\"";
  FixSName(getCompartment()->getName(), str);
  fout << " compartment=\"" + str + "\"";
  fout << " initialAmount=\"" << mIConcDbl << "\"";
  fout << " boundaryCondition=\"";
  if (mStatus == METAB_FIXED)
    fout << "true";
  else
    fout << "false";
  fout << "\"/>" << std::endl;
}

const std::string & CMetab::getName() const
  {
    return mName;
  }

const C_FLOAT64 & CMetab::getConcentration() const
  {
    return mConcDbl;
  }

const C_INT32 & CMetab::getNumberInt() const
  {
    return mNumberInt;
  }

C_FLOAT64 CMetab::getNumberDbl() const
  {
    return mConcDbl * mpCompartment->getVolume()
    * mpModel->getQuantity2NumberFactor();
  }

const C_FLOAT64 & CMetab::getInitialConcentration() const
  {
    return mIConcDbl;
  }

const C_INT32 & CMetab::getInitialNumberInt() const
  {
    return mINumberInt;
  }

C_FLOAT64 CMetab::getInitialNumberDbl() const
  {
    return mIConcDbl * mpCompartment->getVolume()
    * mpModel->getQuantity2NumberFactor();
  }

const C_INT16 & CMetab::getStatus() const
  {
    return mStatus;
  }

const CCompartment * CMetab::getCompartment() const
  {
    return mpCompartment;
  }

const CModel * CMetab::getModel() const
  {
    return mpModel;
  }

void CMetab::setTransitionTime(const C_FLOAT64 & transitionTime)
{
  mTT = transitionTime;
}

const C_FLOAT64 & CMetab::getTransitionTime()
{
  return mTT;
}

void CMetab::setName(const std::string & name)
{
  mName = name;
}

// ***** set quantities ********

void CMetab::setConcentration(const C_FLOAT64 concentration)
{
  mConcDbl = concentration;
  mNumberInt = (C_INT32) (concentration * mpCompartment->getVolume()
                          * mpModel->getQuantity2NumberFactor());
}

void CMetab::setInitialConcentration(const C_FLOAT64 initialConcentration)
{
  mIConcDbl = initialConcentration;
  mINumberInt = (C_INT32) (initialConcentration * mpCompartment->getVolume()
                           * mpModel->getQuantity2NumberFactor());
}

void CMetab::setNumberInt(const C_INT32 number)
{
  mNumberInt = number;
  mConcDbl = ((C_FLOAT64) number) * mpCompartment->getVolumeInv()
             * mpModel->getNumber2QuantityFactor();
}

void CMetab::setInitialNumberInt(const C_INT32 initialNumber)
{
  mINumberInt = initialNumber;
  mIConcDbl = ((C_FLOAT64) initialNumber) * mpCompartment->getVolumeInv()
              * mpModel->getNumber2QuantityFactor();
}

void CMetab::setNumberDbl(const C_FLOAT64 number)
{
  mConcDbl = number * mpCompartment->getVolumeInv()
             * mpModel->getNumber2QuantityFactor();
  mNumberInt = (C_INT32) number;
}

void CMetab::setInitialNumberDbl(const C_FLOAT64 initialNumber)
{
  mIConcDbl = initialNumber * mpCompartment->getVolumeInv()
              * mpModel->getNumber2QuantityFactor();
  mINumberInt = (C_INT32) initialNumber;
}

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

void CMetab::setStatus(const C_INT16 status)
{
  mStatus = status;
}

void CMetab::setCompartment(const CCompartment * compartment)
{
  mpCompartment = compartment;
}

void CMetab::setModel(CModel * model)
{
  mpModel = model;
}

bool CMetab::isValidName(const std::string &name) const
  {
    return (name.find_first_of("; ") == std::string::npos);
  }

void CMetab::initObjects()
{
  addObjectReference("Name", mName);
  addObjectReference("Concentration", mConcDbl);
  addObjectReference("InitialConcentration", mIConcDbl);
  addObjectReference("TransitionTime", mTT);
}

CMetabOld::CMetabOld(const std::string & name,
                     const CCopasiContainer * pParent):
    CCopasiContainer(name, pParent, "Old Metabolite"),
    mName(mObjectName),
    mIConc(Copasi->DefaultConc),
    mStatus(CMetab::METAB_VARIABLE),
    mCompartment()
{CONSTRUCTOR_TRACE;}

CMetabOld::CMetabOld(const CMetabOld & src,
                     const CCopasiContainer * pParent):
    CCopasiContainer(src, pParent),
    mName(mObjectName),
    mIConc(src.mIConc),
    mStatus(src.mStatus),
    mCompartment(src.mCompartment)
{CONSTRUCTOR_TRACE;}

CMetabOld::~CMetabOld() {DESTRUCTOR_TRACE;}

void CMetabOld::cleanup(){}

C_INT32 CMetabOld::load(CReadConfig &configbuffer)
{
  C_INT32 Fail = 0;

  Fail = configbuffer.getVariable("Metabolite", "string",
                                  (void *) & mName,
                                  CReadConfig::SEARCH);

  if (Fail)
    return Fail;

  Fail = configbuffer.getVariable("Concentration", "C_FLOAT64",
                                  (void *) & mIConc);

  if (Fail)
    return Fail;

  Fail = configbuffer.getVariable("Compartment", "C_INT32",
                                  (void *) & mCompartment);

  if (Fail)
    return Fail;

  C_INT32 Status;

  Fail = configbuffer.getVariable("Type", "C_INT32",
                                  (void *) & Status);

  mStatus = (C_INT16) Status;

  // sanity check
  if ((mStatus < 0) || (mStatus > 7))
    {
      CCopasiMessage(CCopasiMessage::WARNING,
                     "The file specifies a non-existing type "
                     "for '%s'.\nReset to internal metabolite.",
                     mName.c_str());
      mStatus = 1;
    }

  // sanity check
  if ((mStatus != METAB_MOIETY) && (mIConc < 0.0))
    {
      CCopasiMessage(CCopasiMessage::WARNING,
                     "The file specifies a negative concentration "
                     "for '%s'.\nReset to default.",
                     mName.c_str());
      mIConc = Copasi->DefaultConc;
    }

  return Fail;
}
C_INT32 CMetabOld::save(CWriteConfig & C_UNUSED(configbuffer)){return 0;}
C_INT32 CMetabOld::getIndex() const {return mCompartment;}
const std::string & CMetabOld::getName() const {return mName;}

/**
 * Returns the address of mIConcDbl  Wei Sun
 */
void * CMetab::getIConcAddr()
{
  return &mIConcDbl;
}

/**
 * Returns the address of mConcDbl
 */
void * CMetab::getConcAddr()
{
  return &mConcDbl;
}

/**
 * Returns the address of mTT
 */
void * CMetab::getTTAddr()
{
  return &mTT;
}

// non-member
bool operator<(const CMetab &lhs, const CMetab &rhs)
{
  // Do the comparison based on the name

  if (lhs.getName() < rhs.getName())
    {
      return true;
    }
  else
    {
      return false;
    }
}

/**
 * Return rate of production of this metaboLite
 */
const C_FLOAT64 & CMetab::getRate() const
  {
    return mRate;
  }

void CMetab::setRate(const C_FLOAT64 & rate)
{
  mRate = rate * getCompartment()->getVolumeInv()
          * mpModel->getNumber2QuantityFactor();
  //  calculateTransitionTime();
}
void CMetab::calculateTransitionTime(void) {mTT = mConcDbl / mRate;}

void CMetab::checkConcentrationAndNumber()
{
  if (mNumberInt < 0)
    {
      setConcentration(getConcentration());
      setInitialConcentration(getInitialConcentration());
    }

  if (mConcDbl < 0)
    {
      setNumberInt(getNumberInt());
      setInitialNumberInt(getInitialNumberInt());
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2004-2015 ZNC, see the NOTICE file for details.
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>
#include <no/nostring.h>

// GTest uses this function to output objects
static void PrintTo(const NoString& s, std::ostream* o)
{
    *o << '"' << s.Escape_n(NoString::EASCII, NoString::EDEBUG) << '"';
}

class EscapeTest : public ::testing::Test
{
protected:
    void testEncode(const NoString& in, const NoString& expectedOut, const NoString& sformat)
    {
        NoString::EEscape format = NoString::ToEscape(sformat);
        NoString out;

        SCOPED_TRACE("Format: " + sformat);

        // Encode, then decode again and check we still got the same string
        out = in.Escape_n(NoString::EASCII, format);
        EXPECT_EQ(expectedOut, out);
        out = out.Escape_n(format, NoString::EASCII);
        EXPECT_EQ(in, out);
    }

    void testString(const NoString& in, const NoString& url, const NoString& html, const NoString& sql, const NoString& tag)
    {
        SCOPED_TRACE("String: " + in);

        testEncode(in, url, "URL");
        testEncode(in, html, "HTML");
        testEncode(in, sql, "SQL");
        testEncode(in, tag, "MSGTAG");
    }
};

TEST_F(EscapeTest, Test)
{
    //          input     url          html             sql         msgtag
    testString("abcdefg", "abcdefg", "abcdefg", "abcdefg", "abcdefg");
    testString("\n\t\r", "%0A%09%0D", "\n\t\r", "\\n\\t\\r", "\\n\t\\r");
    testString("'\"", "%27%22", "'"", "\\'\\\"", "'\"");
    testString("&<>", "%26%3C%3E", "&<>", "&<>", "&<>");
    testString(" ;", "+%3B", " ;", " ;", "\\s\\:");
}

TEST(StringTest, Bool)
{
    EXPECT_EQ(true, NoString(true).ToBool());
    EXPECT_EQ(false, NoString(false).ToBool());
}

#define CS(s) (NoString((s), sizeof(s) - 1))

TEST(StringTest, Cmp)
{
    NoString s = "Bbb";

    EXPECT_EQ(NoString("Bbb"), s);
    EXPECT_LT(NoString("Aaa"), s);
    EXPECT_GT(NoString("Ccc"), s);
    EXPECT_EQ(0, s.StrCmp("Bbb"));
    EXPECT_GT(0, s.StrCmp("bbb"));
    EXPECT_LT(0, s.StrCmp("Aaa"));
    EXPECT_GT(0, s.StrCmp("Ccc"));
    EXPECT_EQ(0, s.CaseCmp("Bbb"));
    EXPECT_EQ(0, s.CaseCmp("bbb"));
    EXPECT_LT(0, s.CaseCmp("Aaa"));
    EXPECT_GT(0, s.CaseCmp("Ccc"));

    EXPECT_TRUE(s.Equals("bbb"));
    EXPECT_FALSE(s.Equals("bbb", true));
    EXPECT_FALSE(s.Equals("bb"));
}

TEST(StringTest, Wild)
{
    EXPECT_TRUE(NoString::WildCmp("", "", NoString::CaseSensitive));
    EXPECT_TRUE(NoString::WildCmp("", "", NoString::CaseInsensitive));

    EXPECT_FALSE(NoString::WildCmp("*a*b*c*", "xy", NoString::CaseSensitive));
    EXPECT_FALSE(NoString::WildCmp("*a*b*c*", "xy", NoString::CaseInsensitive));

    EXPECT_TRUE(NoString::WildCmp("*!?bar@foo", "I_am!~bar@foo", NoString::CaseSensitive));
    EXPECT_TRUE(NoString::WildCmp("*!?bar@foo", "I_am!~bar@foo", NoString::CaseInsensitive));

    EXPECT_FALSE(NoString::WildCmp("*!?BAR@foo", "I_am!~bar@foo", NoString::CaseSensitive));
    EXPECT_TRUE(NoString::WildCmp("*!?BAR@foo", "I_am!~bar@foo", NoString::CaseInsensitive));

    EXPECT_TRUE(NoString::WildCmp("*a*b*c*", "abc", NoString::CaseSensitive));
    EXPECT_TRUE(NoString::WildCmp("*a*b*c*", "abc", NoString::CaseInsensitive));

    EXPECT_FALSE(NoString::WildCmp("*A*b*c*", "abc", NoString::CaseSensitive));
    EXPECT_TRUE(NoString::WildCmp("*A*b*c*", "abc", NoString::CaseInsensitive));

    EXPECT_FALSE(NoString::WildCmp("*a*b*c*", "Abc", NoString::CaseSensitive));
    EXPECT_TRUE(NoString::WildCmp("*a*b*c*", "Abc", NoString::CaseInsensitive));

    EXPECT_TRUE(NoString::WildCmp("*a*b*c*", "axbyc", NoString::CaseSensitive));
    EXPECT_TRUE(NoString::WildCmp("*a*b*c*", "axbyc", NoString::CaseInsensitive));

    EXPECT_FALSE(NoString::WildCmp("*a*B*c*", "AxByC", NoString::CaseSensitive));
    EXPECT_TRUE(NoString::WildCmp("*a*B*c*", "AxByC", NoString::CaseInsensitive));
}

TEST(StringTest, Case)
{
    NoString x = CS("xx");
    NoString X = CS("XX");
    EXPECT_EQ(X, x.AsUpper());
    EXPECT_EQ(x, X.AsLower());
}

TEST(StringTest, Replace)
{
    EXPECT_EQ("(b()b)", NoString("(a()a)").Replace_n("a", "b"));
    EXPECT_EQ("(a()b)", NoString("(a()a)").Replace_n("a", "b", "(", ")"));
    EXPECT_EQ("a(b)", NoString("(a()a)").Replace_n("a", "b", "(", ")", true));
}

TEST(StringTest, Misc)
{
    EXPECT_EQ("Hello,...", NoString("Hello, I'm Bob").Ellipsize(9));
    EXPECT_EQ("Hello, I'm Bob", NoString("Hello, I'm Bob").Ellipsize(90));
    EXPECT_EQ("..", NoString("Hello, I'm Bob").Ellipsize(2));

    EXPECT_EQ("Xy", CS("Xyz").Left(2));
    EXPECT_EQ("Xyz", CS("Xyz").Left(20));

    EXPECT_EQ("yz", CS("Xyz").Right(2));
    EXPECT_EQ("Xyz", CS("Xyz").Right(20));
}

TEST(StringTest, Split)
{
    EXPECT_EQ("a", CS("a b c").Token(0));
    EXPECT_EQ("b", CS("a b c").Token(1));
    EXPECT_EQ("", CS("a b c").Token(100));
    EXPECT_EQ("b c", CS("a b c").Token(1, true));
    EXPECT_EQ("c", CS("a  c").Token(1));
    EXPECT_EQ("", CS("a  c").Token(1, false, " ", true));
    EXPECT_EQ("c", CS("a  c").Token(1, false, "  "));
    EXPECT_EQ(" c", CS("a   c").Token(1, false, "  "));
    EXPECT_EQ("c", CS("a    c").Token(1, false, "  "));
    EXPECT_EQ("b c", CS("a (b c) d").Token(1, false, " ", false, "(", ")"));
    EXPECT_EQ("(b c)", CS("a (b c) d").Token(1, false, " ", false, "(", ")", false));
    EXPECT_EQ("d", CS("a (b c) d").Token(2, false, " ", false, "(", ")", false));

    NoStringVector vexpected;
    NoStringVector vresult;

    vexpected.push_back("a");
    vexpected.push_back("b");
    vexpected.push_back("c");
    CS("a b c").Split(" ", vresult);
    EXPECT_EQ(vexpected, vresult);

    NoStringMap mexpected;
    NoStringMap mresult;

    mexpected["a"] = "b";
    mexpected["c"] = "d";
    CS("a=x&c=d&a=b").URLSplit(mresult);
    EXPECT_EQ(mexpected, mresult) << "URLSplit";
}

TEST(StringTest, NamedFormat)
{
    NoStringMap m;
    m["a"] = "b";
    EXPECT_EQ("{xbyb", NoString::NamedFormat(CS("\\{x{a}y{a}"), m));
}

TEST(StringTest, Equals)
{
    EXPECT_TRUE(CS("ABC").Equals("abc"));
    EXPECT_TRUE(CS("ABC").Equals("abc", NoString::CaseInsensitive));
    EXPECT_FALSE(CS("ABC").Equals("abc", NoString::CaseSensitive));
    EXPECT_TRUE(CS("ABC").Equals("abc", false)); // deprecated
    EXPECT_FALSE(CS("ABC").Equals("abc", true)); // deprecated
}

TEST(StringTest, Find)
{
    EXPECT_EQ(NoString("Hello, I'm Bob").Find("Hello"), 0u);
    EXPECT_EQ(NoString("Hello, I'm Bob").Find("Hello", NoString::CaseInsensitive), 0u);
    EXPECT_EQ(NoString("Hello, I'm Bob").Find("Hello", NoString::CaseSensitive), 0u);

    EXPECT_EQ(NoString("Hello, I'm Bob").Find("i'm"), 7u);
    EXPECT_EQ(NoString("Hello, I'm Bob").Find("i'm", NoString::CaseInsensitive), 7u);
    EXPECT_EQ(NoString("Hello, I'm Bob").Find("i'm", NoString::CaseSensitive), NoString::npos);
}

TEST(StringTest, StartsWith)
{
    EXPECT_TRUE(NoString("Hello, I'm Bob").StartsWith("Hello"));
    EXPECT_TRUE(NoString("Hello, I'm Bob").StartsWith("Hello", NoString::CaseInsensitive));
    EXPECT_TRUE(NoString("Hello, I'm Bob").StartsWith("Hello", NoString::CaseSensitive));

    EXPECT_TRUE(NoString("Hello, I'm Bob").StartsWith("hello"));
    EXPECT_TRUE(NoString("Hello, I'm Bob").StartsWith("hello", NoString::CaseInsensitive));
    EXPECT_FALSE(NoString("Hello, I'm Bob").StartsWith("hello", NoString::CaseSensitive));
}

TEST(StringTest, EndsWith)
{
    EXPECT_TRUE(NoString("Hello, I'm Bob").EndsWith("Bob"));
    EXPECT_TRUE(NoString("Hello, I'm Bob").EndsWith("Bob", NoString::CaseInsensitive));
    EXPECT_TRUE(NoString("Hello, I'm Bob").EndsWith("Bob", NoString::CaseSensitive));

    EXPECT_TRUE(NoString("Hello, I'm Bob").EndsWith("bob"));
    EXPECT_TRUE(NoString("Hello, I'm Bob").EndsWith("bob", NoString::CaseInsensitive));
    EXPECT_FALSE(NoString("Hello, I'm Bob").EndsWith("bob", NoString::CaseSensitive));
}

TEST(StringTest, Contains)
{
    EXPECT_TRUE(NoString("Hello, I'm Bob").Contains("Hello"));
    EXPECT_TRUE(NoString("Hello, I'm Bob").Contains("Hello", NoString::CaseInsensitive));
    EXPECT_TRUE(NoString("Hello, I'm Bob").Contains("Hello", NoString::CaseSensitive));

    EXPECT_TRUE(NoString("Hello, I'm Bob").Contains("i'm"));
    EXPECT_TRUE(NoString("Hello, I'm Bob").Contains("i'm", NoString::CaseInsensitive));
    EXPECT_FALSE(NoString("Hello, I'm Bob").Contains("i'm", NoString::CaseSensitive));

    EXPECT_TRUE(NoString("Hello, I'm Bob").Contains("i'm bob"));
    EXPECT_TRUE(NoString("Hello, I'm Bob").Contains("i'm bob", NoString::CaseInsensitive));
    EXPECT_FALSE(NoString("Hello, I'm Bob").Contains("i'm bob", NoString::CaseSensitive));
}
<commit_msg>Update tests<commit_after>/*
 * Copyright (C) 2004-2015 ZNC, see the NOTICE file for details.
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>
#include <no/nostring.h>

// GTest uses this function to output objects
static void PrintTo(const NoString& s, std::ostream* o)
{
    *o << '"' << s.Escape_n(NoString::EASCII, NoString::EDEBUG) << '"';
}

class EscapeTest : public ::testing::Test
{
protected:
    void testEncode(const NoString& in, const NoString& expectedOut, const NoString& sformat)
    {
        NoString::EEscape format = NoString::ToEscape(sformat);
        NoString out;

        SCOPED_TRACE("Format: " + sformat);

        // Encode, then decode again and check we still got the same string
        out = in.Escape_n(NoString::EASCII, format);
        EXPECT_EQ(expectedOut, out);
        out = out.Escape_n(format, NoString::EASCII);
        EXPECT_EQ(in, out);
    }

    void testString(const NoString& in, const NoString& url, const NoString& html, const NoString& sql, const NoString& tag)
    {
        SCOPED_TRACE("String: " + in);

        testEncode(in, url, "URL");
        testEncode(in, html, "HTML");
        testEncode(in, sql, "SQL");
        testEncode(in, tag, "MSGTAG");
    }
};

TEST_F(EscapeTest, Test)
{
    //          input     url          html             sql         msgtag
    testString("abcdefg", "abcdefg", "abcdefg", "abcdefg", "abcdefg");
    testString("\n\t\r", "%0A%09%0D", "\n\t\r", "\\n\\t\\r", "\\n\t\\r");
    testString("'\"", "%27%22", "'"", "\\'\\\"", "'\"");
    testString("&<>", "%26%3C%3E", "&<>", "&<>", "&<>");
    testString(" ;", "+%3B", " ;", " ;", "\\s\\:");
}

TEST(StringTest, Bool)
{
    EXPECT_EQ(true, NoString(true).ToBool());
    EXPECT_EQ(false, NoString(false).ToBool());
}

#define CS(s) (NoString((s), sizeof(s) - 1))

TEST(StringTest, Cmp)
{
    NoString s = "Bbb";

    EXPECT_EQ(NoString("Bbb"), s);
    EXPECT_LT(NoString("Aaa"), s);
    EXPECT_GT(NoString("Ccc"), s);
    EXPECT_EQ(0, s.Compare("Bbb", NoString::CaseSensitive));
    EXPECT_GT(0, s.Compare("bbb", NoString::CaseSensitive));
    EXPECT_LT(0, s.Compare("Aaa", NoString::CaseSensitive));
    EXPECT_GT(0, s.Compare("Ccc", NoString::CaseSensitive));
    EXPECT_EQ(0, s.Compare("Bbb", NoString::CaseInsensitive));
    EXPECT_EQ(0, s.Compare("bbb", NoString::CaseInsensitive));
    EXPECT_LT(0, s.Compare("Aaa", NoString::CaseInsensitive));
    EXPECT_GT(0, s.Compare("Ccc", NoString::CaseInsensitive));

    EXPECT_TRUE(s.Equals("bbb"));
    EXPECT_FALSE(s.Equals("bbb", NoString::CaseSensitive));
    EXPECT_FALSE(s.Equals("bb"));
}

TEST(StringTest, Wild)
{
    EXPECT_TRUE(NoString::WildCmp("", "", NoString::CaseSensitive));
    EXPECT_TRUE(NoString::WildCmp("", "", NoString::CaseInsensitive));

    EXPECT_FALSE(NoString::WildCmp("*a*b*c*", "xy", NoString::CaseSensitive));
    EXPECT_FALSE(NoString::WildCmp("*a*b*c*", "xy", NoString::CaseInsensitive));

    EXPECT_TRUE(NoString::WildCmp("*!?bar@foo", "I_am!~bar@foo", NoString::CaseSensitive));
    EXPECT_TRUE(NoString::WildCmp("*!?bar@foo", "I_am!~bar@foo", NoString::CaseInsensitive));

    EXPECT_FALSE(NoString::WildCmp("*!?BAR@foo", "I_am!~bar@foo", NoString::CaseSensitive));
    EXPECT_TRUE(NoString::WildCmp("*!?BAR@foo", "I_am!~bar@foo", NoString::CaseInsensitive));

    EXPECT_TRUE(NoString::WildCmp("*a*b*c*", "abc", NoString::CaseSensitive));
    EXPECT_TRUE(NoString::WildCmp("*a*b*c*", "abc", NoString::CaseInsensitive));

    EXPECT_FALSE(NoString::WildCmp("*A*b*c*", "abc", NoString::CaseSensitive));
    EXPECT_TRUE(NoString::WildCmp("*A*b*c*", "abc", NoString::CaseInsensitive));

    EXPECT_FALSE(NoString::WildCmp("*a*b*c*", "Abc", NoString::CaseSensitive));
    EXPECT_TRUE(NoString::WildCmp("*a*b*c*", "Abc", NoString::CaseInsensitive));

    EXPECT_TRUE(NoString::WildCmp("*a*b*c*", "axbyc", NoString::CaseSensitive));
    EXPECT_TRUE(NoString::WildCmp("*a*b*c*", "axbyc", NoString::CaseInsensitive));

    EXPECT_FALSE(NoString::WildCmp("*a*B*c*", "AxByC", NoString::CaseSensitive));
    EXPECT_TRUE(NoString::WildCmp("*a*B*c*", "AxByC", NoString::CaseInsensitive));
}

TEST(StringTest, Case)
{
    NoString x = CS("xx");
    NoString X = CS("XX");
    EXPECT_EQ(X, x.AsUpper());
    EXPECT_EQ(x, X.AsLower());
}

TEST(StringTest, Replace)
{
    EXPECT_EQ("(b()b)", NoString("(a()a)").Replace_n("a", "b"));
    EXPECT_EQ("(a()b)", NoString("(a()a)").Replace_n("a", "b", "(", ")"));
    EXPECT_EQ("a(b)", NoString("(a()a)").Replace_n("a", "b", "(", ")", true));
}

TEST(StringTest, Misc)
{
    EXPECT_EQ("Hello,...", NoString("Hello, I'm Bob").Ellipsize(9));
    EXPECT_EQ("Hello, I'm Bob", NoString("Hello, I'm Bob").Ellipsize(90));
    EXPECT_EQ("..", NoString("Hello, I'm Bob").Ellipsize(2));

    EXPECT_EQ("Xy", CS("Xyz").Left(2));
    EXPECT_EQ("Xyz", CS("Xyz").Left(20));

    EXPECT_EQ("yz", CS("Xyz").Right(2));
    EXPECT_EQ("Xyz", CS("Xyz").Right(20));
}

TEST(StringTest, Split)
{
    EXPECT_EQ("a", CS("a b c").Token(0));
    EXPECT_EQ("b", CS("a b c").Token(1));
    EXPECT_EQ("", CS("a b c").Token(100));
    EXPECT_EQ("b c", CS("a b c").Token(1, true));
    EXPECT_EQ("c", CS("a  c").Token(1));
    EXPECT_EQ("", CS("a  c").Token(1, false, " ", true));
    EXPECT_EQ("c", CS("a  c").Token(1, false, "  "));
    EXPECT_EQ(" c", CS("a   c").Token(1, false, "  "));
    EXPECT_EQ("c", CS("a    c").Token(1, false, "  "));
    EXPECT_EQ("b c", CS("a (b c) d").Token(1, false, " ", false, "(", ")"));
    EXPECT_EQ("(b c)", CS("a (b c) d").Token(1, false, " ", false, "(", ")", false));
    EXPECT_EQ("d", CS("a (b c) d").Token(2, false, " ", false, "(", ")", false));

    NoStringVector vexpected;
    NoStringVector vresult;

    vexpected.push_back("a");
    vexpected.push_back("b");
    vexpected.push_back("c");
    CS("a b c").Split(" ", vresult);
    EXPECT_EQ(vexpected, vresult);
}

TEST(StringTest, NamedFormat)
{
    NoStringMap m;
    m["a"] = "b";
    EXPECT_EQ("{xbyb", NoString::NamedFormat(CS("\\{x{a}y{a}"), m));
}

TEST(StringTest, Equals)
{
    EXPECT_TRUE(CS("ABC").Equals("abc"));
    EXPECT_TRUE(CS("ABC").Equals("abc", NoString::CaseInsensitive));
    EXPECT_FALSE(CS("ABC").Equals("abc", NoString::CaseSensitive));
}

TEST(StringTest, Find)
{
    EXPECT_EQ(NoString("Hello, I'm Bob").Find("Hello"), 0u);
    EXPECT_EQ(NoString("Hello, I'm Bob").Find("Hello", NoString::CaseInsensitive), 0u);
    EXPECT_EQ(NoString("Hello, I'm Bob").Find("Hello", NoString::CaseSensitive), 0u);

    EXPECT_EQ(NoString("Hello, I'm Bob").Find("i'm"), 7u);
    EXPECT_EQ(NoString("Hello, I'm Bob").Find("i'm", NoString::CaseInsensitive), 7u);
    EXPECT_EQ(NoString("Hello, I'm Bob").Find("i'm", NoString::CaseSensitive), NoString::npos);
}

TEST(StringTest, StartsWith)
{
    EXPECT_TRUE(NoString("Hello, I'm Bob").StartsWith("Hello"));
    EXPECT_TRUE(NoString("Hello, I'm Bob").StartsWith("Hello", NoString::CaseInsensitive));
    EXPECT_TRUE(NoString("Hello, I'm Bob").StartsWith("Hello", NoString::CaseSensitive));

    EXPECT_TRUE(NoString("Hello, I'm Bob").StartsWith("hello"));
    EXPECT_TRUE(NoString("Hello, I'm Bob").StartsWith("hello", NoString::CaseInsensitive));
    EXPECT_FALSE(NoString("Hello, I'm Bob").StartsWith("hello", NoString::CaseSensitive));
}

TEST(StringTest, EndsWith)
{
    EXPECT_TRUE(NoString("Hello, I'm Bob").EndsWith("Bob"));
    EXPECT_TRUE(NoString("Hello, I'm Bob").EndsWith("Bob", NoString::CaseInsensitive));
    EXPECT_TRUE(NoString("Hello, I'm Bob").EndsWith("Bob", NoString::CaseSensitive));

    EXPECT_TRUE(NoString("Hello, I'm Bob").EndsWith("bob"));
    EXPECT_TRUE(NoString("Hello, I'm Bob").EndsWith("bob", NoString::CaseInsensitive));
    EXPECT_FALSE(NoString("Hello, I'm Bob").EndsWith("bob", NoString::CaseSensitive));
}

TEST(StringTest, Contains)
{
    EXPECT_TRUE(NoString("Hello, I'm Bob").Contains("Hello"));
    EXPECT_TRUE(NoString("Hello, I'm Bob").Contains("Hello", NoString::CaseInsensitive));
    EXPECT_TRUE(NoString("Hello, I'm Bob").Contains("Hello", NoString::CaseSensitive));

    EXPECT_TRUE(NoString("Hello, I'm Bob").Contains("i'm"));
    EXPECT_TRUE(NoString("Hello, I'm Bob").Contains("i'm", NoString::CaseInsensitive));
    EXPECT_FALSE(NoString("Hello, I'm Bob").Contains("i'm", NoString::CaseSensitive));

    EXPECT_TRUE(NoString("Hello, I'm Bob").Contains("i'm bob"));
    EXPECT_TRUE(NoString("Hello, I'm Bob").Contains("i'm bob", NoString::CaseInsensitive));
    EXPECT_FALSE(NoString("Hello, I'm Bob").Contains("i'm bob", NoString::CaseSensitive));
}
<|endoftext|>


<commit_before>//
// Created by cse on 5/12/17.
//

#include <functional>

#include <QOpenGLExtraFunctions>
#include <QOpenGLFramebufferObject>
#include <QQuickWindow>
#include <QThread>
#include <QScreen>

#include "ThreeDItem.h"
#include "ThreeDInteractor.h"

#include <renderers/OpenGLRenderer.h>
#include <objects/Mesh.h>
#include <scene/Scene.h>
#include <camera/PerspectiveCamera.h>
#include <material/MeshBasicMaterial.h>
#include <geometry/Box.h>
#include <geometry/Plane.h>
#include <geometry/Sphere.h>
#include <helper/AxesHelper.h>
#include "bak/modelloader.h"

namespace lo {
namespace ui {
namespace quick {

using namespace std;
using namespace three;
using namespace three::geometry;
using namespace three::helper;

class FramebufferObjectRenderer : public QQuickFramebufferObject::Renderer, protected QOpenGLExtraFunctions
{
  QColor m_background;

  three::Scene::Ptr _scene;
  three::PerspectiveCamera::Ptr _camera;
  three::OpenGLRenderer::Ptr _renderer;
  three::Renderer::Target::Ptr _target;

  const ThreeDItem *const _item;
  QOpenGLFramebufferObject *_framebufferObject = nullptr;

public:

  explicit FramebufferObjectRenderer(const ThreeDItem *item)
     : _item(item),
       _scene(SceneT<Color>::make("scene", Color(0.4f, 0.4f, 0.6f))),
       _camera(PerspectiveCamera::make(45, item->width() / item->height(), 0.1, 1000)),
       _renderer(OpenGLRenderer::make(
          QOpenGLContext::currentContext(),
          item->width(), item->height(),
          item->window()->screen()->devicePixelRatio()))
  {
    _renderer->setSize(item->width(), item->height());
    AxesHelper::Ptr axes = AxesHelper::make("axis", 20);

    _scene->add(axes);

    Plane::Ptr planeGeometry = Plane::make(60, 20, 1, 1);
    MeshBasicMaterial::Ptr planeMaterial = MeshBasicMaterial::make();
    planeMaterial->color = Color(0xcccccc);

    Color c = planeMaterial->color;

    Mesh::Ptr plane = Mesh_T<Plane, MeshBasicMaterial>::make("plane", planeGeometry, planeMaterial);
    plane->rotation().setX(-0.5f * (float) M_PI);
    plane->position().set(15, 0, 0);

    _scene->add(plane);

    Box::Ptr cubeGeometry = Box::make(4, 4, 4);
    MeshBasicMaterial::Ptr cubeMaterial = MeshBasicMaterial::make();
    cubeMaterial->color = Color(0xff0000);
    cubeMaterial->wireframe = true;

    Mesh::Ptr cube = Mesh_T<Box, MeshBasicMaterial>::make("cube", cubeGeometry, cubeMaterial);
    cube->position().set(-4, 3, 0);

    _scene->add(cube);

    Sphere::Ptr sphereGeometry = Sphere::make(4, 20, 20);
    MeshBasicMaterial::Ptr sphereMaterial = MeshBasicMaterial::make();
    sphereMaterial->color = Color(0x7777ff);
    sphereMaterial->wireframe = true;

    Mesh::Ptr sphere = Mesh_T<Sphere, MeshBasicMaterial>::make("sphere", sphereGeometry, sphereMaterial);
    sphere->position().set(20, 4, 2);

    _scene->add(sphere);

    _camera->position().set(-30, 40, 30);
    _camera->lookAt(_scene->position());
  }

  ~FramebufferObjectRenderer() override = default;

  void synchronize(QQuickFramebufferObject *_item) override
  {
    auto *item = static_cast<ThreeDItem *>(_item);
  }

  void render() override
  {
    _renderer->render(_scene, _camera, _target);
    _item->window()->resetOpenGLState();
  }

  QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) override
  {
    QOpenGLFramebufferObjectFormat format;
    format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
    format.setMipmap(false);
    format.setInternalTextureFormat(GL_RGBA);

    _framebufferObject = new QOpenGLFramebufferObject(size, format);

    _target = OpenGLRenderer::makeExternalTarget(
       _framebufferObject->handle(), _framebufferObject->texture(), _item->width(), _item->height());

    return _framebufferObject;
  }
};

ThreeDItem::ThreeDItem(QQuickItem *parent)
   : QQuickFramebufferObject(parent), m_model(nullptr), m_interactor(new ThreeDInteractor())
{
  setAcceptedMouseButtons(Qt::AllButtons);
  setFlag(QQuickItem::ItemIsFocusScope);
  setFlag(QQuickItem::ItemAcceptsInputMethod);

  //m_loader = new ModelLoader();
  //connect(m_loader, &ModelLoader::modelLoaded, this, &ThreeDItem::modelLoaded, Qt::QueuedConnection);
}

ThreeDItem::~ThreeDItem()
{
  delete m_interactor;
  //delete m_loader;
}

QQuickFramebufferObject::Renderer *ThreeDItem::createRenderer() const
{
  return new FramebufferObjectRenderer(this);
}

void ThreeDItem::setData(QString data) {
  if (data != m_data) {
    m_data = data;

    //m_loader->asynchLoad(QFileInfo(m_data));
  }
}

void ThreeDItem::modelLoaded()
{
  //m_model = m_loader->getLoaded();
  //m_pendingModel = true;
  update();
  emit dataChanged();
}

void ThreeDItem::setBackground(QColor background) {
  if (m_background != background) {
    m_background = background;
    emit backgroundChanged();
  }
}

const shared_ptr<Scene> ThreeDItem::pendingModel()
{
  //if (m_pendingModel) {
  //  m_pendingModel = false;
  //  return m_model;
  //}
  return nullptr;
}

void ThreeDItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
  QQuickFramebufferObject::geometryChanged(newGeometry, oldGeometry);
}

void ThreeDItem::mouseMoveEvent(QMouseEvent *event) {
  m_interactor->SetEvent(event);
  update();
}

void ThreeDItem::mousePressEvent(QMouseEvent *event) {
  m_interactor->SetEvent(event);
  update();
}

void ThreeDItem::mouseReleaseEvent(QMouseEvent *event) {
  m_interactor->SetEvent(event);
  update();
}

void ThreeDItem::mouseDoubleClickEvent(QMouseEvent *event) {
  m_interactor->SetEvent(event);
  update();
}

void ThreeDItem::wheelEvent(QWheelEvent *event) {
  m_interactor->SetEvent(event);
  update();
}

void ThreeDItem::keyPressEvent(QKeyEvent *event) {
  m_interactor->SetEvent(event);
  update();
}

void ThreeDItem::keyReleaseEvent(QKeyEvent *event) {
  m_interactor->SetEvent(event);
  update();
}

void ThreeDItem::focusInEvent(QFocusEvent *event) {
  m_interactor->SetEvent(event);
  forceActiveFocus();
}

void ThreeDItem::focusOutEvent(QFocusEvent *event) {
  m_interactor->SetEvent(event);
  update();
}

void ThreeDItem::releaseResources() {
  QQuickFramebufferObject::releaseResources();
}
}
}
}
<commit_msg>example 1 renders (rightside up)<commit_after>//
// Created by cse on 5/12/17.
//

#include <functional>

#include <QOpenGLExtraFunctions>
#include <QOpenGLFramebufferObject>
#include <QQuickWindow>
#include <QThread>
#include <QScreen>

#include "ThreeDItem.h"
#include "ThreeDInteractor.h"

#include <renderers/OpenGLRenderer.h>
#include <objects/Mesh.h>
#include <scene/Scene.h>
#include <camera/PerspectiveCamera.h>
#include <material/MeshBasicMaterial.h>
#include <geometry/Box.h>
#include <geometry/Plane.h>
#include <geometry/Sphere.h>
#include <helper/AxesHelper.h>
#include "bak/modelloader.h"

namespace lo {
namespace ui {
namespace quick {

using namespace std;
using namespace three;
using namespace three::geometry;
using namespace three::helper;

class FramebufferObjectRenderer : public QQuickFramebufferObject::Renderer, protected QOpenGLExtraFunctions
{
  QColor m_background;

  three::Scene::Ptr _scene;
  three::PerspectiveCamera::Ptr _camera;
  three::OpenGLRenderer::Ptr _renderer;
  three::Renderer::Target::Ptr _target;

  const ThreeDItem *const _item;
  QOpenGLFramebufferObject *_framebufferObject = nullptr;

public:

  explicit FramebufferObjectRenderer(const ThreeDItem *item)
     : _item(item),
       _scene(SceneT<Color>::make("scene", Color(0.4f, 0.4f, 0.6f))),
       _camera(PerspectiveCamera::make(45, item->width() / item->height(), 0.1, 1000)),
       _renderer(OpenGLRenderer::make(
          QOpenGLContext::currentContext(),
          item->width(), item->height(),
          item->window()->screen()->devicePixelRatio()))
  {
    _renderer->setSize(item->width(), item->height());
    AxesHelper::Ptr axes = AxesHelper::make("axis", 20);

    _scene->add(axes);

    Plane::Ptr planeGeometry = Plane::make(60, 20, 1, 1);
    MeshBasicMaterial::Ptr planeMaterial = MeshBasicMaterial::make();
    planeMaterial->color = Color(0xcccccc);

    Color c = planeMaterial->color;

    Mesh::Ptr plane = Mesh_T<Plane, MeshBasicMaterial>::make("plane", planeGeometry, planeMaterial);
    plane->rotation().setX(-0.5f * (float) M_PI);
    plane->position().set(15, 0, 0);

    _scene->add(plane);

    Box::Ptr cubeGeometry = Box::make(4, 4, 4);
    MeshBasicMaterial::Ptr cubeMaterial = MeshBasicMaterial::make();
    cubeMaterial->color = Color(0xff0000);
    cubeMaterial->wireframe = true;

    Mesh::Ptr cube = Mesh_T<Box, MeshBasicMaterial>::make("cube", cubeGeometry, cubeMaterial);
    cube->position().set(-4, 3, 0);

    _scene->add(cube);

    Sphere::Ptr sphereGeometry = Sphere::make(4, 20, 20);
    MeshBasicMaterial::Ptr sphereMaterial = MeshBasicMaterial::make();
    sphereMaterial->color = Color(0x7777ff);
    sphereMaterial->wireframe = true;

    Mesh::Ptr sphere = Mesh_T<Sphere, MeshBasicMaterial>::make("sphere", sphereGeometry, sphereMaterial);
    sphere->position().set(20, 4, 2);

    _scene->add(sphere);

    _camera->position().set(-30, 40, 30);
    _camera->lookAt(_scene->position());
  }

  ~FramebufferObjectRenderer() override = default;

  void synchronize(QQuickFramebufferObject *_item) override
  {
    auto *item = static_cast<ThreeDItem *>(_item);
  }

  void render() override
  {
    _renderer->render(_scene, _camera, _target);
    _item->window()->resetOpenGLState();
  }

  QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) override
  {
    QOpenGLFramebufferObjectFormat format;
    format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
    format.setMipmap(false);
    format.setInternalTextureFormat(GL_RGBA);

    _framebufferObject = new QOpenGLFramebufferObject(size, format);

    _target = OpenGLRenderer::makeExternalTarget(
       _framebufferObject->handle(), _framebufferObject->texture(), _item->width(), _item->height());

    return _framebufferObject;
  }
};

ThreeDItem::ThreeDItem(QQuickItem *parent)
   : QQuickFramebufferObject(parent), m_model(nullptr), m_interactor(new ThreeDInteractor())
{
  setAcceptedMouseButtons(Qt::AllButtons);
  setFlag(QQuickItem::ItemIsFocusScope);
  setFlag(QQuickItem::ItemAcceptsInputMethod);

  setMirrorVertically(true);

  //m_loader = new ModelLoader();
  //connect(m_loader, &ModelLoader::modelLoaded, this, &ThreeDItem::modelLoaded, Qt::QueuedConnection);
}

ThreeDItem::~ThreeDItem()
{
  delete m_interactor;
  //delete m_loader;
}

QQuickFramebufferObject::Renderer *ThreeDItem::createRenderer() const
{
  return new FramebufferObjectRenderer(this);
}

void ThreeDItem::setData(QString data) {
  if (data != m_data) {
    m_data = data;

    //m_loader->asynchLoad(QFileInfo(m_data));
  }
}

void ThreeDItem::modelLoaded()
{
  //m_model = m_loader->getLoaded();
  //m_pendingModel = true;
  update();
  emit dataChanged();
}

void ThreeDItem::setBackground(QColor background) {
  if (m_background != background) {
    m_background = background;
    emit backgroundChanged();
  }
}

const shared_ptr<Scene> ThreeDItem::pendingModel()
{
  //if (m_pendingModel) {
  //  m_pendingModel = false;
  //  return m_model;
  //}
  return nullptr;
}

void ThreeDItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
  QQuickFramebufferObject::geometryChanged(newGeometry, oldGeometry);
}

void ThreeDItem::mouseMoveEvent(QMouseEvent *event) {
  m_interactor->SetEvent(event);
  update();
}

void ThreeDItem::mousePressEvent(QMouseEvent *event) {
  m_interactor->SetEvent(event);
  update();
}

void ThreeDItem::mouseReleaseEvent(QMouseEvent *event) {
  m_interactor->SetEvent(event);
  update();
}

void ThreeDItem::mouseDoubleClickEvent(QMouseEvent *event) {
  m_interactor->SetEvent(event);
  update();
}

void ThreeDItem::wheelEvent(QWheelEvent *event) {
  m_interactor->SetEvent(event);
  update();
}

void ThreeDItem::keyPressEvent(QKeyEvent *event) {
  m_interactor->SetEvent(event);
  update();
}

void ThreeDItem::keyReleaseEvent(QKeyEvent *event) {
  m_interactor->SetEvent(event);
  update();
}

void ThreeDItem::focusInEvent(QFocusEvent *event) {
  m_interactor->SetEvent(event);
  forceActiveFocus();
}

void ThreeDItem::focusOutEvent(QFocusEvent *event) {
  m_interactor->SetEvent(event);
  update();
}

void ThreeDItem::releaseResources() {
  QQuickFramebufferObject::releaseResources();
}
}
}
}
<|endoftext|>


<commit_before>/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * StringUtils.cpp
 * Random String functions.
 * Copyright (C) 2005-2008 Simon Newton
 */

#include <errno.h>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include "ola/StringUtils.h"

namespace ola {

using std::string;
using std::stringstream;
using std::vector;

/*
 * Split a string on delimtiers. If two delimiters appear next to each other an
 * empty string is added to the output list.
 * @param input the string to split
 * @param tokens the vector to store the result in
 * @param delimiters what to split on
 */
void StringSplit(const string &input,
                 vector<string> &tokens,
                 const string &delimiters) {
  string::size_type start_offset = 0;
  string::size_type end_offset = 0;

  while (1) {
    end_offset = input.find_first_of(delimiters, start_offset);
    if (end_offset == string::npos) {
      tokens.push_back(input.substr(start_offset, input.size() - start_offset));
      return;
    }
    tokens.push_back(input.substr(start_offset, end_offset - start_offset));
    start_offset = end_offset + 1 > input.size() ? string::npos :
                   end_offset + 1;
  }
}

/*
 * Trim leading and trailing whitespace from a string.
 * @param the string to trim
 */
void StringTrim(std::string *input) {
  string characters_to_trim = " \n\r\t";
  string::size_type start = input->find_first_not_of(characters_to_trim);
  string::size_type end = input->find_last_not_of(characters_to_trim);

  if (start == string::npos)
    input->clear();
  else
    *input = input->substr(start, end - start + 1);
}

/*
 * Convert an int to a string.
 * @param i the int to convert
 * @return the string representation of the int
 */
string IntToString(int i) {
  stringstream str;
  str << i;
  return str.str();
}

/*
 * Convert a string to a unsigned int.
 * @returns true if sucessfull, false otherwise
 */
bool StringToUInt(const string &value, unsigned int *output) {
  errno = 0;
  long l = strtol(value.data(), NULL, 10);
  if (l < 0 || (l == 0 && errno != 0))
    return false;
  *output = (int) l;
  return true;
}

/*
 * Escape \
 */
void Escape(string *original) {
  for (string::iterator iter = original->begin(); iter != original->end();
      ++iter) {
    if (*iter == '"') {
      iter = original->insert(iter, '\\');
      iter++;
    }
  }
}
}  // ola
<commit_msg> * add a missing include for strtol<commit_after>/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * StringUtils.cpp
 * Random String functions.
 * Copyright (C) 2005-2008 Simon Newton
 */

#include <errno.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include "ola/StringUtils.h"

namespace ola {

using std::string;
using std::stringstream;
using std::vector;

/*
 * Split a string on delimtiers. If two delimiters appear next to each other an
 * empty string is added to the output list.
 * @param input the string to split
 * @param tokens the vector to store the result in
 * @param delimiters what to split on
 */
void StringSplit(const string &input,
                 vector<string> &tokens,
                 const string &delimiters) {
  string::size_type start_offset = 0;
  string::size_type end_offset = 0;

  while (1) {
    end_offset = input.find_first_of(delimiters, start_offset);
    if (end_offset == string::npos) {
      tokens.push_back(input.substr(start_offset, input.size() - start_offset));
      return;
    }
    tokens.push_back(input.substr(start_offset, end_offset - start_offset));
    start_offset = end_offset + 1 > input.size() ? string::npos :
                   end_offset + 1;
  }
}

/*
 * Trim leading and trailing whitespace from a string.
 * @param the string to trim
 */
void StringTrim(std::string *input) {
  string characters_to_trim = " \n\r\t";
  string::size_type start = input->find_first_not_of(characters_to_trim);
  string::size_type end = input->find_last_not_of(characters_to_trim);

  if (start == string::npos)
    input->clear();
  else
    *input = input->substr(start, end - start + 1);
}

/*
 * Convert an int to a string.
 * @param i the int to convert
 * @return the string representation of the int
 */
string IntToString(int i) {
  stringstream str;
  str << i;
  return str.str();
}

/*
 * Convert a string to a unsigned int.
 * @returns true if sucessfull, false otherwise
 */
bool StringToUInt(const string &value, unsigned int *output) {
  errno = 0;
  long l = strtol(value.data(), NULL, 10);
  if (l < 0 || (l == 0 && errno != 0))
    return false;
  *output = (int) l;
  return true;
}

/*
 * Escape \
 */
void Escape(string *original) {
  for (string::iterator iter = original->begin(); iter != original->end();
      ++iter) {
    if (*iter == '"') {
      iter = original->insert(iter, '\\');
      iter++;
    }
  }
}
}  // ola
<|endoftext|>


<commit_before>#include "Transform.h"

#include <algorithm>

Transform::Transform() :
localPosition{ 0, 0, 0 },
localRotation{ 1, 0, 0, 0 },
localScale{ 1, 1, 1 },
parent{ nullptr },
containingJoint{ nullptr }
{
}

Transform::~Transform()
{
}

Transform* Transform::getParent()
{
	return parent;
}

void Transform::setParent(Transform* newParent)
{
	using namespace std;

	auto worldPos = getWorldPosition();

	// If this Transform has a parent, remove it from the parent's list of children
	if (parent != nullptr)
		parent->removeChild(this);

	// Set the new parent
	parent = newParent;
	parent->addChild(this);
	setWorldPosition(worldPos);
}

Vector3f Transform::getLocalPosition() const
{
	return localPosition;
}

void Transform::setLocalPosition(const Vector3f& pos)
{
	localPosition = pos;
}

Vector3f Transform::getWorldPosition() const
{
	auto parentWorldPos = parent == nullptr ? Vector3f{ 0, 0, 0 } : parent->getWorldPosition();

	return getWorldRotation().transform() * (parentWorldPos + localPosition);
}

void Transform::setWorldPosition(const Vector3f& pos)
{
	if (parent == nullptr)
	{
		localPosition = pos;
	}
	else
	{
		auto parentWorldPos = parent->getWorldPosition();
		localPosition = pos - parentWorldPos;
	}
}

Quatf Transform::getLocalRotation() const
{
	return localRotation;
}

void Transform::setLocalRotation(const Quatf& rot)
{
	localRotation = rot;
	localRotation.normalize();
}

Quatf Transform::getWorldRotation() const
{
	auto parentWorldRot = parent == nullptr ? Quatf{ 1, 0, 0, 0 } : parent->getWorldRotation();

	return parentWorldRot * localRotation;
}

void Transform::setWorldRotation(const Quatf& rot)
{

}

std::vector<Transform*>& Transform::getChildren()
{
	return children;
}

void Transform::addChild(Transform* child)
{
	using namespace std;

	// Ensure the child is not already in the list
	if (find(begin(children), end(children), child) == end(children))
		children.push_back(child);

}

void Transform::removeChild(const Transform* child)
{
	using namespace std;

	children.erase( remove(begin(children), end(children), child), end(children) );
}

Joint* Transform::getJoint()
{
	return containingJoint;
}

void Transform::setJoint(Joint* newJoint)
{
	containingJoint = newJoint;
}<commit_msg>Code to start getting correct world position<commit_after>#include "Transform.h"

#include <algorithm>

Transform::Transform() :
localPosition{ 0, 0, 0 },
localRotation{ 1, 0, 0, 0 },
localScale{ 1, 1, 1 },
parent{ nullptr },
containingJoint{ nullptr }
{
}

Transform::~Transform()
{
}

Transform* Transform::getParent()
{
	return parent;
}

void Transform::setParent(Transform* newParent)
{
	using namespace std;

	auto worldPos = getWorldPosition();

	// If this Transform has a parent, remove it from the parent's list of children
	if (parent != nullptr)
		parent->removeChild(this);

	// Set the new parent
	parent = newParent;
	parent->addChild(this);
	setWorldPosition(worldPos);
}

Vector3f Transform::getLocalPosition() const
{
	return localPosition;
}

void Transform::setLocalPosition(const Vector3f& pos)
{
	localPosition = pos;
}

Vector3f Transform::getWorldPosition() const
{
	auto parentWorldPos = parent == nullptr ? Vector3f{ 0, 0, 0 } : parent->getWorldPosition();

	return parentWorldPos + localPosition;

	//auto len2 = localRotation.lengthSq();
	//auto conjRot = ~localRotation;

	//Quatf invRot{ conjRot.w / len2, conjRot.v / len2 };
	//invRot.normalize();

	//Quatf pos{ 0, localPosition };

	//auto newPos = invRot * pos * ~invRot;

	//return parentWorldPos + newPos.v;
}

void Transform::setWorldPosition(const Vector3f& pos)
{
	if (parent == nullptr)
	{
		localPosition = pos;
	}
	else
	{
		auto parentWorldPos = parent->getWorldPosition();
		localPosition = pos - parentWorldPos;
	}
}

Quatf Transform::getLocalRotation() const
{
	return localRotation;
}

void Transform::setLocalRotation(const Quatf& rot)
{
	localRotation = rot;
	localRotation.normalize();
}

Quatf Transform::getWorldRotation() const
{
	auto parentWorldRot = parent == nullptr ? Quatf{ 1, 0, 0, 0 } : parent->getWorldRotation();

	return parentWorldRot * localRotation;
}

void Transform::setWorldRotation(const Quatf& rot)
{

}

std::vector<Transform*>& Transform::getChildren()
{
	return children;
}

void Transform::addChild(Transform* child)
{
	using namespace std;

	// Ensure the child is not already in the list
	if (find(begin(children), end(children), child) == end(children))
		children.push_back(child);

}

void Transform::removeChild(const Transform* child)
{
	using namespace std;

	children.erase( remove(begin(children), end(children), child), end(children) );
}

Joint* Transform::getJoint()
{
	return containingJoint;
}

void Transform::setJoint(Joint* newJoint)
{
	containingJoint = newJoint;
}<|endoftext|>


<commit_before>#include "../../../cplusplus_lib/include/tools/misc/global_macros.h"

#ifdef __USE_CANTERA_

/*!
	  A simple Fortran 77 interface

 This file is an example of how to write an interface to use Cantera
 in Fortran 77 programs. The basic idea is to store pointers to
 Cantera objects in global storage, and then create Fortran-callable
 functions that access the objects through the pointers.

 This particular example defines functions that return thermodynamic
 properties, transport properties, and kinetic rates for reacting
 ideal gas mixtures. Only a single pointer to an IdealGasMix object is
 stored, so only one reaction mechanism may be used at any one time in
 the application.  Of course, it is a simple modification to store
 multiple objects if it is desired to use multiple reaction
 mechanisms.

 The functions defined here are ones commonly needed in application
 programs that simulate gas-phase combustion or similar
 processes. Similar libraries to access other capabilities of Cantera
 (surface chemistry, etc.) could be written in the same way.

 This library is designed for Fortran compilers that expect external
 procedure names to be lowercase with a trailing underscore. If this
 is not the case, the procedure names must be edited before use.

 */

 // add any other Cantera header files you need here
#include "cantera/IdealGasMix.h"
#include "cantera/zeroD/IdealGasReactor.h"

using namespace Cantera;
using namespace std;
using std::string;

// store a pointer to an IdealGasMix object
static IdealGasMix* _gas = 0;

// provides access to the pointers for functions in other libraries
IdealGasMix* _gasptr()
{
	return _gas;
}

#include "cantera/transport.h"

// store a pointer to a transport manager
static Transport* _trans = 0;
Transport* _transptr()
{
	return _trans;
}

// error handler
void handleError(CanteraError& err)
{
	std::cout << err.what() << std::endl;
	exit(-1);
}

// extern "C" turns off C++ name-mangling, so that the procedure names
// in the object file are exactly as shown here.

extern "C" {

	/**
	 * Read in a reaction mechanism file and create an IdealGasMix
	 * object. The file may be in Cantera input format or in CTML. (If
	 * you have a file in Chemkin-compatible format, use utility
	 * program ck2cti first to convert it into Cantera format.)
	 */
	void newidealgasmix_(char* file, char* id, char* transport,
		ftnlen lenfile, ftnlen lenid, ftnlen lentr)
	{
		string trmodel = "";
		try {
			string fin = string(file, lenfile);
			string fth = string(id, lenid);
			trmodel = string(transport, lentr);
			delete _gas;
			_gas = new IdealGasMix(fin, fth);
		}
		catch (CanteraError& err) {
			handleError(err);
		}
		try {
			delete _trans;
			_trans = newTransportMgr(trmodel, _gas, 1);
		}
		catch (CanteraError& err) {
			_trans = newTransportMgr("", _gas, 1);
		}
	}

	/// integer function nElements()
	integer nelements_()
	{
		return _gas->nElements();
	}

	/// integer function nSpecies()
	integer nspecies_()
	{
		return _gas->nSpecies();
	}

	/// integer function nReactions()
	integer nreactions_()
	{
		return _gas->nReactions();
	}

	void getspeciesname_(integer* k, char* name, ftnlen n)
	{
		int ik = *k - 1;
		std::fill(name, name + n, ' ');
		string spnm = _gas->speciesName(ik);
		int ns = spnm.size();
		unsigned int nmx = (ns > n ? n : ns);
		copy(spnm.begin(), spnm.begin() + nmx, name);
	}

	//-------------- setting the state ----------------------------

	/// subroutine setState_TPX(T, P, X)
	void setstate_tpx_(doublereal* T, doublereal* P, doublereal* X)
	{
		try {
			_gas->setState_TPX(*T, *P, X);
		}
		catch (CanteraError& err) {
			handleError(err);
		}
	}

	/// subroutine setState_TPX_String(T, P, X)
	void setstate_tpx_string_(doublereal* T, doublereal* P,
		char* X, ftnlen lenx)
	{
		try {
			_gas->setState_TPX(*T, *P, string(X, lenx));
		}
		catch (CanteraError& err) {
			handleError(err);
		}
	}

	void setstate_try_(doublereal* T, doublereal* rho, doublereal* Y)
	{
		try {
			_gas->setState_TRY(*T, *rho, Y);
		}
		catch (CanteraError& err) {
			handleError(err);
		}
	}

	void setstate_tpy_(doublereal* T, doublereal* p, doublereal* Y)
	{
		try {
			_gas->setState_TPY(*T, *p, Y);
		}
		catch (CanteraError& err) {
			handleError(err);
		}
	}

	void setstate_sp_(doublereal* s, doublereal* p)
	{
		try {
			_gas->setState_SP(*s, *p);
		}
		catch (CanteraError& err) {
			handleError(err);
		}
	}

	void setmassfraction_(doublereal* Y) {
		try {
			_gas->setMassFractions(*Y);
		}
		catch (CanteraError& err) {
			handleError(err);
		}
	}

	void setstate_tr_(doublereal* T, doublereal* rho) {
		_gas->setState_TR(*T, *rho);
	}
	catch (CanteraError& err) {
		handleError(err);
	}
}

//-------------- thermodynamic properties ----------------------

/// Temperature (K)
doublereal temperature_()
{
	return _gas->temperature();
}

/// Pressure (Pa)
doublereal pressure_()
{
	return _gas->pressure();
}

/// Density (kg/m^3)
doublereal density_()
{
	return _gas->density();
}

/// Mean molar mass (kg/kmol).
doublereal meanmolarmass_()
{
	return _gas->meanMolecularWeight();
}

/// Molar enthalpy (J/kmol)
doublereal enthalpy_mole_()
{
	return _gas->enthalpy_mole();
}

/// Molar internal energy (J/kmol)
doublereal intenergy_mole_()
{
	return _gas->intEnergy_mole();
}

/// Molar entropy (J/kmol-K)
doublereal entropy_mole_()
{
	return _gas->entropy_mole();
}

/// Molar heat capacity at constant P (J/kmol-K)
doublereal cp_mole_()
{
	return _gas->cp_mole();
}

/// Molar Gibbs function (J/kmol)
doublereal gibbs_mole_()
{
	return _gas->gibbs_mole();
}

doublereal enthalpy_mass_()
{
	return _gas->enthalpy_mass();
}

doublereal intenergy_mass_()
{
	return _gas->intEnergy_mass();
}

doublereal entropy_mass_()
{
	return _gas->entropy_mass();
}

doublereal cp_mass_()
{
	return _gas->cp_mass();
}

doublereal cv_mass_()
{
	return _gas->cv_mass();
}

doublereal gibbs_mass_()
{
	return _gas->gibbs_mass();
}

void gotmolefractions_(doublereal* x)
{
	_gas->getMoleFractions(x);
}

void gotmassfractions_(doublereal* y)
{
	_gas->getMassFractions(y);
}

void equilibrate_(char* opt, ftnlen lenopt)
{
	try {
		if (lenopt != 2) {
			throw CanteraError("equilibrate",
				"two-character string required.");
		}
		string optstr = string(opt, 2);
		_gas->equilibrate(optstr);
	}
	catch (CanteraError& err) {
		handleError(err);
	}
}

//---------------- kinetics -------------------------

void getreactioneqn_(integer* i, char* eqn, ftnlen n)
{
	int irxn = *i - 1;
	std::fill(eqn, eqn + n, ' ');
	string e = _gas->reactionString(irxn);
	int ns = e.size();
	unsigned int nmx = (ns > n ? n : ns);
	copy(e.begin(), e.begin() + nmx, eqn);
}

void getnetproductionrates_(doublereal* wdot)
{
	_gas->getNetProductionRates(wdot);
}

void getcreationrates_(doublereal* cdot)
{
	_gas->getCreationRates(cdot);
}

void getdestructionrates_(doublereal* ddot)
{
	_gas->getDestructionRates(ddot);
}

void getnetratesofprogress_(doublereal* q)
{
	_gas->getNetRatesOfProgress(q);
}

void getfwdratesofprogress_(doublereal* q)
{
	_gas->getFwdRatesOfProgress(q);
}

void getrevratesofprogress_(doublereal* q)
{
	_gas->getRevRatesOfProgress(q);
}

//-------------------- transport properties --------------------

double viscosity_()
{
	try {
		return _trans->viscosity();
	}
	catch (CanteraError& err) {
		handleError(err);
		return 0.0;
	}
}

double thermalconductivity_()
{
	try {
		return _trans->thermalConductivity();
	}
	catch (CanteraError& err) {
		handleError(err);
		return 0.0;
	}
}

void getmixdiffcoeffs_(double* diff)
{
	try {
		_trans->getMixDiffCoeffs(diff);
	}
	catch (CanteraError& err) {
		handleError(err);
	}
}

void getthermaldiffcoeffs_(double* dt)
{
	try {
		_trans->getThermalDiffCoeffs(dt);
	}
	catch (CanteraError& err) {
		handleError(err);
	}
}

}

#endif // __USE_CANTERA_<commit_msg>tiny change.<commit_after>#include "../../../cplusplus_lib/include/tools/misc/global_macros.h"

#ifdef __USE_CANTERA_

/*!
	  A simple Fortran 77 interface

 This file is an example of how to write an interface to use Cantera
 in Fortran 77 programs. The basic idea is to store pointers to
 Cantera objects in global storage, and then create Fortran-callable
 functions that access the objects through the pointers.

 This particular example defines functions that return thermodynamic
 properties, transport properties, and kinetic rates for reacting
 ideal gas mixtures. Only a single pointer to an IdealGasMix object is
 stored, so only one reaction mechanism may be used at any one time in
 the application.  Of course, it is a simple modification to store
 multiple objects if it is desired to use multiple reaction
 mechanisms.

 The functions defined here are ones commonly needed in application
 programs that simulate gas-phase combustion or similar
 processes. Similar libraries to access other capabilities of Cantera
 (surface chemistry, etc.) could be written in the same way.

 This library is designed for Fortran compilers that expect external
 procedure names to be lowercase with a trailing underscore. If this
 is not the case, the procedure names must be edited before use.

 */

 // add any other Cantera header files you need here
#include "cantera/IdealGasMix.h"
#include "cantera/zeroD/IdealGasReactor.h"

using namespace Cantera;
using namespace std;
using std::string;

// store a pointer to an IdealGasMix object
static IdealGasMix* _gas = 0;

// provides access to the pointers for functions in other libraries
IdealGasMix* _gasptr()
{
	return _gas;
}

#include "cantera/transport.h"

// store a pointer to a transport manager
static Transport* _trans = 0;
Transport* _transptr()
{
	return _trans;
}

// error handler
void handleError(CanteraError& err)
{
	std::cout << err.what() << std::endl;
	exit(-1);
}

// extern "C" turns off C++ name-mangling, so that the procedure names
// in the object file are exactly as shown here.

extern "C" {

	/**
	 * Read in a reaction mechanism file and create an IdealGasMix
	 * object. The file may be in Cantera input format or in CTML. (If
	 * you have a file in Chemkin-compatible format, use utility
	 * program ck2cti first to convert it into Cantera format.)
	 */
	void newidealgasmix_(char* file, char* id, char* transport,
		ftnlen lenfile, ftnlen lenid, ftnlen lentr)
	{
		string trmodel = "";
		try {
			string fin = string(file, lenfile);
			string fth = string(id, lenid);
			trmodel = string(transport, lentr);
			delete _gas;
			_gas = new IdealGasMix(fin, fth);
		}
		catch (CanteraError& err) {
			handleError(err);
		}
		try {
			delete _trans;
			_trans = newTransportMgr(trmodel, _gas, 1);
		}
		catch (CanteraError& err) {
			_trans = newTransportMgr("", _gas, 1);
		}
	}

	/// integer function nElements()
	integer nelements_()
	{
		return _gas->nElements();
	}

	/// integer function nSpecies()
	integer nspecies_()
	{
		return _gas->nSpecies();
	}

	/// integer function nReactions()
	integer nreactions_()
	{
		return _gas->nReactions();
	}

	void getspeciesname_(integer* k, char* name, ftnlen n)
	{
		int ik = *k - 1;
		std::fill(name, name + n, ' ');
		string spnm = _gas->speciesName(ik);
		int ns = spnm.size();
		unsigned int nmx = (ns > n ? n : ns);
		copy(spnm.begin(), spnm.begin() + nmx, name);
	}

	//-------------- setting the state ----------------------------

	/// subroutine setState_TPX(T, P, X)
	void setstate_tpx_(doublereal* T, doublereal* P, doublereal* X)
	{
		try {
			_gas->setState_TPX(*T, *P, X);
		}
		catch (CanteraError& err) {
			handleError(err);
		}
	}

	/// subroutine setState_TPX_String(T, P, X)
	void setstate_tpx_string_(doublereal* T, doublereal* P,
		char* X, ftnlen lenx)
	{
		try {
			_gas->setState_TPX(*T, *P, string(X, lenx));
		}
		catch (CanteraError& err) {
			handleError(err);
		}
	}

	void setstate_try_(doublereal* T, doublereal* rho, doublereal* Y)
	{
		try {
			_gas->setState_TRY(*T, *rho, Y);
		}
		catch (CanteraError& err) {
			handleError(err);
		}
	}

	void setstate_tpy_(doublereal* T, doublereal* p, doublereal* Y)
	{
		try {
			_gas->setState_TPY(*T, *p, Y);
		}
		catch (CanteraError& err) {
			handleError(err);
		}
	}

	void setstate_sp_(doublereal* s, doublereal* p)
	{
		try {
			_gas->setState_SP(*s, *p);
		}
		catch (CanteraError& err) {
			handleError(err);
		}
	}

	void setmassfraction_(doublereal* Y) {
		try {
			_gas->setMassFractions(*Y);
		}
		catch (CanteraError& err) {
			handleError(err);
		}
	}

	void setstate_tr_(doublereal* T, doublereal* rho) {
		try {
			_gas->setState_TR(*T, *rho);
		}
		catch (CanteraError& err) {
			handleError(err);
		}
	}

	//-------------- thermodynamic properties ----------------------

	/// Temperature (K)
	doublereal temperature_()
	{
		return _gas->temperature();
	}

	/// Pressure (Pa)
	doublereal pressure_()
	{
		return _gas->pressure();
	}

	/// Density (kg/m^3)
	doublereal density_()
	{
		return _gas->density();
	}

	/// Mean molar mass (kg/kmol).
	doublereal meanmolarmass_()
	{
		return _gas->meanMolecularWeight();
	}

	/// Molar enthalpy (J/kmol)
	doublereal enthalpy_mole_()
	{
		return _gas->enthalpy_mole();
	}

	/// Molar internal energy (J/kmol)
	doublereal intenergy_mole_()
	{
		return _gas->intEnergy_mole();
	}

	/// Molar entropy (J/kmol-K)
	doublereal entropy_mole_()
	{
		return _gas->entropy_mole();
	}

	/// Molar heat capacity at constant P (J/kmol-K)
	doublereal cp_mole_()
	{
		return _gas->cp_mole();
	}

	/// Molar Gibbs function (J/kmol)
	doublereal gibbs_mole_()
	{
		return _gas->gibbs_mole();
	}

	doublereal enthalpy_mass_()
	{
		return _gas->enthalpy_mass();
	}

	doublereal intenergy_mass_()
	{
		return _gas->intEnergy_mass();
	}

	doublereal entropy_mass_()
	{
		return _gas->entropy_mass();
	}

	doublereal cp_mass_()
	{
		return _gas->cp_mass();
	}

	doublereal cv_mass_()
	{
		return _gas->cv_mass();
	}

	doublereal gibbs_mass_()
	{
		return _gas->gibbs_mass();
	}

	void gotmolefractions_(doublereal* x)
	{
		_gas->getMoleFractions(x);
	}

	void gotmassfractions_(doublereal* y)
	{
		_gas->getMassFractions(y);
	}

	void equilibrate_(char* opt, ftnlen lenopt)
	{
		try {
			if (lenopt != 2) {
				throw CanteraError("equilibrate",
					"two-character string required.");
			}
			string optstr = string(opt, 2);
			_gas->equilibrate(optstr);
		}
		catch (CanteraError& err) {
			handleError(err);
		}
	}

	//---------------- kinetics -------------------------

	void getreactioneqn_(integer* i, char* eqn, ftnlen n)
	{
		int irxn = *i - 1;
		std::fill(eqn, eqn + n, ' ');
		string e = _gas->reactionString(irxn);
		int ns = e.size();
		unsigned int nmx = (ns > n ? n : ns);
		copy(e.begin(), e.begin() + nmx, eqn);
	}

	void getnetproductionrates_(doublereal* wdot)
	{
		_gas->getNetProductionRates(wdot);
	}

	void getcreationrates_(doublereal* cdot)
	{
		_gas->getCreationRates(cdot);
	}

	void getdestructionrates_(doublereal* ddot)
	{
		_gas->getDestructionRates(ddot);
	}

	void getnetratesofprogress_(doublereal* q)
	{
		_gas->getNetRatesOfProgress(q);
	}

	void getfwdratesofprogress_(doublereal* q)
	{
		_gas->getFwdRatesOfProgress(q);
	}

	void getrevratesofprogress_(doublereal* q)
	{
		_gas->getRevRatesOfProgress(q);
	}

	//-------------------- transport properties --------------------

	double viscosity_()
	{
		try {
			return _trans->viscosity();
		}
		catch (CanteraError& err) {
			handleError(err);
			return 0.0;
		}
	}

	double thermalconductivity_()
	{
		try {
			return _trans->thermalConductivity();
		}
		catch (CanteraError& err) {
			handleError(err);
			return 0.0;
		}
	}

	void getmixdiffcoeffs_(double* diff)
	{
		try {
			_trans->getMixDiffCoeffs(diff);
		}
		catch (CanteraError& err) {
			handleError(err);
		}
	}

	void getthermaldiffcoeffs_(double* dt)
	{
		try {
			_trans->getThermalDiffCoeffs(dt);
		}
		catch (CanteraError& err) {
			handleError(err);
		}
	}

}

#endif // __USE_CANTERA_<|endoftext|>