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

#ifndef __FRAMEWORK_UIELEMENT_STATUSINDICATORINTERFACEWRAPPER_HXX_
#define __FRAMEWORK_UIELEMENT_STATUSINDICATORINTERFACEWRAPPER_HXX_

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________

#ifndef __FRAMEWORK_THREADHELP_THREADHELPBASE_HXX_
#include <threadhelp/threadhelpbase.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_GENERIC_HXX_
#include <macros/generic.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_XINTERFACE_HXX_
#include <macros/xinterface.hxx>
#endif

#ifndef __FRAMEWORK_MACROS_XTYPEPROVIDER_HXX_
#include <macros/xtypeprovider.hxx>
#endif

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________

#ifndef _COM_SUN_STAR_TASK_XSTATUSINDICATOR_HPP_
#include <com/sun/star/task/XStatusIndicator.hpp>
#endif

#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif

//_________________________________________________________________________________________________________________
//  other includes
//_________________________________________________________________________________________________________________

#ifndef _RTL_OUSTRING_HXX_
#include <rtl/ustring.hxx>
#endif

#ifndef _CPPUHELPER_WEAK_HXX_
#include <cppuhelper/weak.hxx>
#endif

#include <vector>

namespace framework
{

class StatusIndicatorInterfaceWrapper :   public ::com::sun::star::lang::XTypeProvider       ,
                                          public ::com::sun::star::task::XStatusIndicator    ,
                                          public ::cppu::OWeakObject
{
    public:
        StatusIndicatorInterfaceWrapper( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& rStatusIndicatorImpl );
        virtual ~StatusIndicatorInterfaceWrapper();

        //---------------------------------------------------------------------------------------------------------
        //  XInterface, XTypeProvider
        //---------------------------------------------------------------------------------------------------------
        FWK_DECLARE_XINTERFACE
        FWK_DECLARE_XTYPEPROVIDER

        //---------------------------------------------------------------------------------------------------------
        //  XStatusIndicator
        //---------------------------------------------------------------------------------------------------------
        virtual void SAL_CALL start   ( const ::rtl::OUString& sText  ,
                                              sal_Int32        nRange ) throw( ::com::sun::star::uno::RuntimeException );
        virtual void SAL_CALL end     (                               ) throw( ::com::sun::star::uno::RuntimeException );
        virtual void SAL_CALL reset   (                               ) throw( ::com::sun::star::uno::RuntimeException );
        virtual void SAL_CALL setText ( const ::rtl::OUString& sText  ) throw( ::com::sun::star::uno::RuntimeException );
        virtual void SAL_CALL setValue(       sal_Int32        nValue ) throw( ::com::sun::star::uno::RuntimeException );

    private:
        StatusIndicatorInterfaceWrapper();

        ::com::sun::star::uno::WeakReference< ::com::sun::star::lang::XComponent > m_xStatusIndicatorImpl;
};

}

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

#ifndef __FRAMEWORK_UIELEMENT_STATUSINDICATORINTERFACEWRAPPER_HXX_
#define __FRAMEWORK_UIELEMENT_STATUSINDICATORINTERFACEWRAPPER_HXX_

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________

#include <threadhelp/threadhelpbase.hxx>
#include <macros/generic.hxx>
#include <macros/xinterface.hxx>
#include <macros/xtypeprovider.hxx>

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________
#include <com/sun/star/task/XStatusIndicator.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/lang/XComponent.hpp>

//_________________________________________________________________________________________________________________
//  other includes
//_________________________________________________________________________________________________________________
#include <rtl/ustring.hxx>
#include <cppuhelper/weak.hxx>

#include <vector>

namespace framework
{

class StatusIndicatorInterfaceWrapper :   public ::com::sun::star::lang::XTypeProvider       ,
                                          public ::com::sun::star::task::XStatusIndicator    ,
                                          public ::cppu::OWeakObject
{
    public:
        StatusIndicatorInterfaceWrapper( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& rStatusIndicatorImpl );
        virtual ~StatusIndicatorInterfaceWrapper();

        //---------------------------------------------------------------------------------------------------------
        //  XInterface, XTypeProvider
        //---------------------------------------------------------------------------------------------------------
        FWK_DECLARE_XINTERFACE
        FWK_DECLARE_XTYPEPROVIDER

        //---------------------------------------------------------------------------------------------------------
        //  XStatusIndicator
        //---------------------------------------------------------------------------------------------------------
        virtual void SAL_CALL start   ( const ::rtl::OUString& sText  ,
                                              sal_Int32        nRange ) throw( ::com::sun::star::uno::RuntimeException );
        virtual void SAL_CALL end     (                               ) throw( ::com::sun::star::uno::RuntimeException );
        virtual void SAL_CALL reset   (                               ) throw( ::com::sun::star::uno::RuntimeException );
        virtual void SAL_CALL setText ( const ::rtl::OUString& sText  ) throw( ::com::sun::star::uno::RuntimeException );
        virtual void SAL_CALL setValue(       sal_Int32        nValue ) throw( ::com::sun::star::uno::RuntimeException );

    private:
        StatusIndicatorInterfaceWrapper();

        ::com::sun::star::uno::WeakReference< ::com::sun::star::lang::XComponent > m_xStatusIndicatorImpl;
};

}

#endif // __FRAMEWORK_UIELEMENT_STATUSINDICATORINTERFACEWRAPPER_HXX_
<|endoftext|>


<commit_before><commit_msg>Part: fix various commands on selection detection<commit_after><|endoftext|>


<commit_before>#include "app/RackScrollWidget.hpp"
#include "app/Scene.hpp"
#include "window.hpp"
#include "app.hpp"
#include "settings.hpp"

namespace rack {
namespace app {

RackScrollWidget::RackScrollWidget() {
	zoomWidget = new widget::ZoomWidget;
	container->addChild(zoomWidget);

	rackWidget = new RackWidget;
	rackWidget->box.size = RACK_OFFSET.mult(2);
	zoomWidget->addChild(rackWidget);

	reset();
}

void RackScrollWidget::step() {
	// Clamp zoom
	settings::zoom = math::clamp(settings::zoom, 0.25f, 2.f);
	// Round zoom to nearest percent
	float zoom = std::round(settings::zoom / 0.01) * 0.01;
	if (zoom != zoomWidget->zoom) {
		// Set offset based on zoomPos
		offset = offset.plus(zoomPos).div(zoomWidget->zoom).mult(zoom).minus(zoomPos);
		// Set zoom
		zoomWidget->setZoom(zoom);
	}

	zoomPos = box.size.div(2);

	// Set zoomWidget box to module bounding box
	math::Rect moduleBox = rackWidget->moduleContainer->getChildrenBoundingBox();
	if (!moduleBox.size.isFinite())
		moduleBox = math::Rect(RACK_OFFSET, math::Vec(0, 0));
	zoomWidget->box.pos = moduleBox.pos.mult(zoom);
	zoomWidget->box.size = moduleBox.size.mult(zoom);

	// Expand to moduleBox
	math::Rect scrollBox = moduleBox.grow(RACK_GRID_SIZE.mult(math::Vec(50, 2)));
	scrollBox.pos = scrollBox.pos.mult(zoom);
	scrollBox.size = scrollBox.size.mult(zoom);

	// Expand scrollBox to center the moduleBox
	math::Vec s = box.size.minus(scrollBox.size).max(math::Vec());
	scrollBox.pos = scrollBox.pos.minus(s.div(2));
	scrollBox.size = scrollBox.size.plus(s);

	// Expand to viewport size
	math::Rect viewportBox;
	viewportBox.pos = oldOffset;
	viewportBox.size = box.size;
	scrollBox = scrollBox.expand(viewportBox);

	// Reposition widgets
	zoomWidget->box = scrollBox;
	rackWidget->box.pos = scrollBox.pos.div(zoom).neg();

	// Scroll rack if dragging cable near the edge of the screen
	math::Vec pos = APP->window->mousePos;
	math::Rect viewport = getViewport(box.zeroPos());
	if (rackWidget->incompleteCable) {
		float margin = 20.0;
		float speed = 15.0;
		if (pos.x <= viewport.pos.x + margin)
			offset.x -= speed;
		if (pos.x >= viewport.pos.x + viewport.size.x - margin)
			offset.x += speed;
		if (pos.y <= viewport.pos.y + margin)
			offset.y -= speed;
		if (pos.y >= viewport.pos.y + viewport.size.y - margin)
			offset.y += speed;
	}

	ScrollWidget::step();
	oldOffset = offset;
}

void RackScrollWidget::draw(const DrawArgs &args) {
	// DEBUG("%f %f %f %f", RECT_ARGS(args.clipBox));
	ScrollWidget::draw(args);
}

void RackScrollWidget::onHoverKey(const event::HoverKey &e) {
	ScrollWidget::onHoverKey(e);
	if (e.isConsumed())
		return;

	// Scroll with arrow keys
	float arrowSpeed = 30.0;
	if ((e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL |GLFW_MOD_SHIFT))
		arrowSpeed /= 16.0;
	else if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL)
		arrowSpeed *= 4.0;
	else if ((e.mods & RACK_MOD_MASK) == GLFW_MOD_SHIFT)
		arrowSpeed /= 4.0;

	if (e.action == RACK_HELD) {
		switch (e.key) {
			case GLFW_KEY_LEFT: {
				offset.x -= arrowSpeed;
				e.consume(this);
			} break;
			case GLFW_KEY_RIGHT: {
				offset.x += arrowSpeed;
				e.consume(this);
			} break;
			case GLFW_KEY_UP: {
				offset.y -= arrowSpeed;
				e.consume(this);
			} break;
			case GLFW_KEY_DOWN: {
				offset.y += arrowSpeed;
				e.consume(this);
			} break;
		}
	}
}

void RackScrollWidget::onHoverScroll(const event::HoverScroll &e) {
	if ((APP->window->getMods() & RACK_MOD_MASK) == RACK_MOD_CTRL) {
		// Increase zoom
		float zoomDelta = e.scrollDelta.y / 50 / 4;
		if (settings::invertZoom)
			zoomDelta *= -1;
		settings::zoom *= std::pow(2, zoomDelta);
		zoomPos = e.pos;
		e.consume(this);
		return;
	}

	ScrollWidget::onHoverScroll(e);
}

void RackScrollWidget::reset() {
	offset = RACK_OFFSET.mult(zoomWidget->zoom);
	offset = offset.minus(math::Vec(30, 30));
}

} // namespace app
} // namespace rack
<commit_msg>Simplify RackScrollWidget scroll box computation and behavior.<commit_after>#include "app/RackScrollWidget.hpp"
#include "app/Scene.hpp"
#include "window.hpp"
#include "app.hpp"
#include "settings.hpp"

namespace rack {
namespace app {

RackScrollWidget::RackScrollWidget() {
	zoomWidget = new widget::ZoomWidget;
	container->addChild(zoomWidget);

	rackWidget = new RackWidget;
	rackWidget->box.size = RACK_OFFSET.mult(2);
	zoomWidget->addChild(rackWidget);

	reset();
}

void RackScrollWidget::step() {
	// Clamp zoom
	settings::zoom = math::clamp(settings::zoom, 0.25f, 2.f);
	// Round zoom to nearest percent
	float zoom = std::round(settings::zoom / 0.01) * 0.01;
	if (zoom != zoomWidget->zoom) {
		// Set offset based on zoomPos
		offset = offset.plus(zoomPos).div(zoomWidget->zoom).mult(zoom).minus(zoomPos);
		// Set zoom
		zoomWidget->setZoom(zoom);
	}

	zoomPos = box.size.div(2);

	// Compute module bounding box
	math::Rect moduleBox = rackWidget->moduleContainer->getChildrenBoundingBox();
	if (!moduleBox.size.isFinite())
		moduleBox = math::Rect(RACK_OFFSET, math::Vec(0, 0));

	// Expand moduleBox by half a screen size
	math::Rect scrollBox = moduleBox;
	scrollBox.pos = scrollBox.pos.mult(zoom);
	scrollBox.size = scrollBox.size.mult(zoom);
	scrollBox = scrollBox.grow(box.size.div(2));

	// Expand to the current viewport box so that moving modules (and thus changing the module bounding box) doesn't clamp the scroll offset.
	math::Rect viewportBox;
	viewportBox.pos = oldOffset;
	viewportBox.size = box.size;
	scrollBox = scrollBox.expand(viewportBox);

	// Reposition widgets
	zoomWidget->box = scrollBox;
	rackWidget->box.pos = scrollBox.pos.div(zoom).neg();

	// Scroll rack if dragging cable near the edge of the screen
	math::Vec pos = APP->window->mousePos;
	math::Rect viewport = getViewport(box.zeroPos());
	if (rackWidget->incompleteCable) {
		float margin = 20.0;
		float speed = 15.0;
		if (pos.x <= viewport.pos.x + margin)
			offset.x -= speed;
		if (pos.x >= viewport.pos.x + viewport.size.x - margin)
			offset.x += speed;
		if (pos.y <= viewport.pos.y + margin)
			offset.y -= speed;
		if (pos.y >= viewport.pos.y + viewport.size.y - margin)
			offset.y += speed;
	}

	ScrollWidget::step();
	oldOffset = offset;
}

void RackScrollWidget::draw(const DrawArgs &args) {
	// DEBUG("%f %f %f %f", RECT_ARGS(args.clipBox));
	ScrollWidget::draw(args);
}

void RackScrollWidget::onHoverKey(const event::HoverKey &e) {
	ScrollWidget::onHoverKey(e);
	if (e.isConsumed())
		return;

	// Scroll with arrow keys
	float arrowSpeed = 30.0;
	if ((e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL |GLFW_MOD_SHIFT))
		arrowSpeed /= 16.0;
	else if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL)
		arrowSpeed *= 4.0;
	else if ((e.mods & RACK_MOD_MASK) == GLFW_MOD_SHIFT)
		arrowSpeed /= 4.0;

	if (e.action == RACK_HELD) {
		switch (e.key) {
			case GLFW_KEY_LEFT: {
				offset.x -= arrowSpeed;
				e.consume(this);
			} break;
			case GLFW_KEY_RIGHT: {
				offset.x += arrowSpeed;
				e.consume(this);
			} break;
			case GLFW_KEY_UP: {
				offset.y -= arrowSpeed;
				e.consume(this);
			} break;
			case GLFW_KEY_DOWN: {
				offset.y += arrowSpeed;
				e.consume(this);
			} break;
		}
	}
}

void RackScrollWidget::onHoverScroll(const event::HoverScroll &e) {
	if ((APP->window->getMods() & RACK_MOD_MASK) == RACK_MOD_CTRL) {
		// Increase zoom
		float zoomDelta = e.scrollDelta.y / 50 / 4;
		if (settings::invertZoom)
			zoomDelta *= -1;
		settings::zoom *= std::pow(2, zoomDelta);
		zoomPos = e.pos;
		e.consume(this);
		return;
	}

	ScrollWidget::onHoverScroll(e);
}

void RackScrollWidget::reset() {
	offset = RACK_OFFSET.mult(zoomWidget->zoom);
	offset = offset.minus(math::Vec(30, 30));
}

} // namespace app
} // namespace rack
<|endoftext|>


<commit_before>/*
 (Ported from Arduino to Energia)

SoftwareSerial.cpp (formerly NewSoftSerial.cpp) -
 Multi-instance software serial library for Arduino/Wiring
 -- Interrupt-driven receive and other improvements by ladyada
 (http://ladyada.net)
 -- Tuning, circular buffer, derivation from class Print/Stream,
 multi-instance support, porting to 8MHz processors,
 various optimizations, PROGMEM delay tables, inverse logic and
 direct port writing by Mikal Hart (http://www.arduiniana.org)
 -- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com)
 -- 20MHz processor support by Garrett Mace (http://www.macetech.com)
 -- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)

 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
 version 2.1 of the License, or (at your option) any later version.

 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

 The latest version of this library can always be found at
 http://arduiniana.org.
 */

//
// Includes
//
//#include <avr/interrupt.h>
//#include <avr/pgmspace.h>
//#include "Arduino.h"
#include "Energia.h"
#include "SoftwareSerial.h"

//
// Lookup table
//
typedef struct _DELAY_TABLE
{
  long baud;
  unsigned short rx_delay_centering;
  unsigned short rx_delay_intrabit;
  unsigned short rx_delay_stopbit;
  unsigned short tx_delay;
}
DELAY_TABLE;

#if F_CPU == 16000000L

//formula is roughly rxintra=rxstop=tx = F_CPU / baud / 3 - 5/3
//    so, delay = 16000000 / 3 / baud - 5/3
//      and, rxcenter = 1/2 rxintra
_DELAY_TABLE table[] =
{
  //  baud    rxcenter   rxintra    rxstop    tx
  {115200,   15,        32,        32,       32,      },
  {57600,    38,        78,        78,       78,      },
  {38400,    61,        123,       123,      123,     },
  {31250,    72,        155,       155,      155,     },
  {28800,    80,        170,       170,      170,     },
  {19200,    126,       262,       262,      262,     },
  {14400,    177,       353,       353,      353,     },
  {9600,     265,       540,       540,      540,     },
  {4800,     547,       1095,      1095,     1095,    },
  {2400,     1103,      2190,      2190,     2190,    },
  {1200,     2200,      4400,      4400,     4400,    },
  {300,      8881,      17762,     17762,    17762,   },
};

const int XMIT_START_ADJUSTMENT = 5;
#else
#error This version of SoftwareSerial supports only 16MHz processors

#endif

//
// Statics
//
SoftwareSerial *SoftwareSerial::active_object = 0;
char SoftwareSerial::_receive_buffer[_SS_MAX_RX_BUFF];
volatile uint8_t SoftwareSerial::_receive_buffer_tail = 0;
volatile uint8_t SoftwareSerial::_receive_buffer_head = 0;

//
// Private methods
//

/* static */
inline void SoftwareSerial::tunedDelay(uint16_t delay) {
  //msp430:
  // don't pass in delay of zero, it will not handle it well... could add constant cost of 2 by starting with a jz .+3
  // cycles: pre + mid + post ~= 5 + delay*3
  asm volatile(
    " sub.w #1, %[delay]  \n"  //sub (not immediate, but special constant) from register: 1 cycle
    " jnz .-2            \n"   // 2 cycles regardless of branch
    :                          //no output
    : [delay] "r" (delay)      // input
    :                          // no memory clobber
  );
}

// This function sets the current object as the "listening"
// one and returns true if it replaces another
bool SoftwareSerial::listen() {
  if (active_object != this) {
    _buffer_overflow = false;
    uint8_t oldSR = __read_status_register();
    noInterrupts();
    _receive_buffer_head = _receive_buffer_tail = 0;
    active_object = this;
    __write_status_register(oldSR);
    return true;
  }

  return false;
}

//
// The receive routine called by the interrupt handler
//
void SoftwareSerial::recv()
{
  uint8_t d = 0;

  // If RX line is high, then we don't see any start bit
  // so interrupt is probably not for us
  if (_inverse_logic ? rx_pin_read() : !rx_pin_read())
  {
    // Wait approximately 1/2 of a bit width to "center" the sample
    tunedDelay(_rx_delay_centering);

    // Read each of the 8 bits
    for (uint8_t i=0x1; i; i <<= 1)
    {
      tunedDelay(_rx_delay_intrabit);
      uint8_t noti = ~i;
      if (rx_pin_read())
        d |= i;
      else // else clause added to ensure function timing is ~balanced
      d &= noti;
    }

    // skip the stop bit
    tunedDelay(_rx_delay_stopbit);

    if (_inverse_logic)
      d = ~d;

    // if buffer full, set the overflow flag and return
    if ((_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF != _receive_buffer_head)
    {
      // save new data in buffer: tail points to where byte goes
      _receive_buffer[_receive_buffer_tail] = d; // save new byte
      _receive_buffer_tail = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
    }
    else
    {
      _buffer_overflow = true;
    }
  }
}

void SoftwareSerial::tx_pin_write(uint8_t pin_state)
{
  if (pin_state == LOW)
    *_transmitPortRegister &= ~_transmitBitMask;
  else
    *_transmitPortRegister |= _transmitBitMask;
}

uint8_t SoftwareSerial::rx_pin_read()
{
  return *_receivePortRegister & _receiveBitMask;
}

//
// Interrupt handling
//

/* static */
void SoftwareSerial::handle_interrupt()
{
  if (active_object)
  {
    active_object->recv();
  }
}

//
// Constructor
//
SoftwareSerial::SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic /* = false */) :
_rx_delay_centering(0),
_rx_delay_intrabit(0),
_rx_delay_stopbit(0),
_tx_delay(0),
_buffer_overflow(false),
_inverse_logic(inverse_logic)
{
  setTX(transmitPin);
  setRX(receivePin);
}

//
// Destructor
//
SoftwareSerial::~SoftwareSerial()
{
  end();
}

void SoftwareSerial::setTX(uint8_t tx)
{
  pinMode(tx, OUTPUT);
  digitalWrite(tx, HIGH);
  _transmitBitMask = digitalPinToBitMask(tx);
  uint8_t port = digitalPinToPort(tx);
  _transmitPortRegister = portOutputRegister(port);
}

void SoftwareSerial::setRX(uint8_t rx)
{
  pinMode(rx, INPUT);
  if (!_inverse_logic)
    digitalWrite(rx, HIGH);  // pullup for normal logic!
  _receivePin = rx;
  _receiveBitMask = digitalPinToBitMask(rx);
  uint8_t port = digitalPinToPort(rx);
  _receivePortRegister = portInputRegister(port);
}

//
// Public methods
//

void SoftwareSerial::begin(long speed)
{
  _rx_delay_centering = _rx_delay_intrabit = _rx_delay_stopbit = _tx_delay = 0;

  for (unsigned i=0; i<sizeof(table)/sizeof(table[0]); ++i)
  {
    long baud = table[i].baud;
    if (baud == speed)
    {
      _rx_delay_centering = table[i].rx_delay_centering;
      _rx_delay_intrabit = table[i].rx_delay_intrabit;
      _rx_delay_stopbit = table[i].rx_delay_stopbit;
      _tx_delay = table[i].tx_delay;
      break;
    }
  }

  // Set up RX interrupts, but only if we have a valid RX baud rate
  if (_rx_delay_stopbit)
  {
    attachInterrupt(_receivePin, SoftwareSerial::handle_interrupt, FALLING);

    Serial.println("pre delay");
    Serial.print("_tx_delay: ");
    Serial.println(_tx_delay);
    tunedDelay(_tx_delay); // if we were low this establishes the end
  }
  Serial.println("post stopbit");

  listen();
  Serial.println("post listen");
}

void SoftwareSerial::end()
{
  detachInterrupt(_receivePin);
}

// Read data from buffer
int SoftwareSerial::read()
{
  if (!isListening())
    return -1;

  // Empty buffer?
  if (_receive_buffer_head == _receive_buffer_tail)
    return -1;

  // Read from "head"
  uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte
  _receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF;
  return d;
}

int SoftwareSerial::available()
{
  if (!isListening())
    return 0;

  return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF;
}

size_t SoftwareSerial::write(uint8_t b)
{
  if (_tx_delay == 0) {
    setWriteError();
    return 0;
  }

  //interrupts off
  uint8_t oldSR = __read_status_register();
  noInterrupts();

  // Write the start bit
  tx_pin_write(_inverse_logic ? HIGH : LOW);
  tunedDelay(_tx_delay + XMIT_START_ADJUSTMENT);

  // Write each of the 8 bits
  if (_inverse_logic)
  {
    for (byte mask = 0x01; mask; mask <<= 1)
    {
      if (b & mask) // choose bit
        tx_pin_write(LOW); // send 1
      else
        tx_pin_write(HIGH); // send 0

      tunedDelay(_tx_delay);
    }

    tx_pin_write(LOW); // restore pin to natural state
  }
  else
  {
    for (byte mask = 0x01; mask; mask <<= 1)
    {
      if (b & mask) // choose bit
        tx_pin_write(HIGH); // send 1
      else
        tx_pin_write(LOW); // send 0

      tunedDelay(_tx_delay);
    }

    tx_pin_write(HIGH); // restore pin to natural state
  }

  // turn interrupts back on if they were on before
  __write_status_register(oldSR);
  tunedDelay(_tx_delay);

  return 1;
}

void SoftwareSerial::flush()
{
  if (!isListening())
    return;

  uint8_t oldSR = __read_status_register();
  noInterrupts();
  _receive_buffer_head = _receive_buffer_tail = 0;
  __write_status_register(oldSR);
}

int SoftwareSerial::peek()
{
  if (!isListening())
    return -1;

  // Empty buffer?
  if (_receive_buffer_head == _receive_buffer_tail)
    return -1;

  // Read from "head"
  return _receive_buffer[_receive_buffer_head];
}

<commit_msg>Removing more debug statements<commit_after>/*
 (Ported from Arduino to Energia)

SoftwareSerial.cpp (formerly NewSoftSerial.cpp) -
 Multi-instance software serial library for Arduino/Wiring
 -- Interrupt-driven receive and other improvements by ladyada
 (http://ladyada.net)
 -- Tuning, circular buffer, derivation from class Print/Stream,
 multi-instance support, porting to 8MHz processors,
 various optimizations, PROGMEM delay tables, inverse logic and
 direct port writing by Mikal Hart (http://www.arduiniana.org)
 -- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com)
 -- 20MHz processor support by Garrett Mace (http://www.macetech.com)
 -- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)

 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
 version 2.1 of the License, or (at your option) any later version.

 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

 The latest version of this library can always be found at
 http://arduiniana.org.
 */

//
// Includes
//
//#include <avr/interrupt.h>
//#include <avr/pgmspace.h>
//#include "Arduino.h"
#include "Energia.h"
#include "SoftwareSerial.h"

//
// Lookup table
//
typedef struct _DELAY_TABLE
{
  long baud;
  unsigned short rx_delay_centering;
  unsigned short rx_delay_intrabit;
  unsigned short rx_delay_stopbit;
  unsigned short tx_delay;
}
DELAY_TABLE;

#if F_CPU == 16000000L

//formula is roughly rxintra=rxstop=tx = F_CPU / baud / 3 - 5/3
//    so, delay = 16000000 / 3 / baud - 5/3
//      and, rxcenter = 1/2 rxintra
_DELAY_TABLE table[] =
{
  //  baud    rxcenter   rxintra    rxstop    tx
  {115200,   15,        32,        32,       32,      },
  {57600,    38,        78,        78,       78,      },
  {38400,    61,        123,       123,      123,     },
  {31250,    72,        155,       155,      155,     },
  {28800,    80,        170,       170,      170,     },
  {19200,    126,       262,       262,      262,     },
  {14400,    177,       353,       353,      353,     },
  {9600,     265,       540,       540,      540,     },
  {4800,     547,       1095,      1095,     1095,    },
  {2400,     1103,      2190,      2190,     2190,    },
  {1200,     2200,      4400,      4400,     4400,    },
  {300,      8881,      17762,     17762,    17762,   },
};

const int XMIT_START_ADJUSTMENT = 5;
#else
#error This version of SoftwareSerial supports only 16MHz processors

#endif

//
// Statics
//
SoftwareSerial *SoftwareSerial::active_object = 0;
char SoftwareSerial::_receive_buffer[_SS_MAX_RX_BUFF];
volatile uint8_t SoftwareSerial::_receive_buffer_tail = 0;
volatile uint8_t SoftwareSerial::_receive_buffer_head = 0;

//
// Private methods
//

/* static */
inline void SoftwareSerial::tunedDelay(uint16_t delay) {
  //msp430:
  // don't pass in delay of zero, it will not handle it well... could add constant cost of 2 by starting with a jz .+3
  // cycles: pre + mid + post ~= 5 + delay*3
  asm volatile(
    " sub.w #1, %[delay]  \n"  //sub (not immediate, but special constant) from register: 1 cycle
    " jnz .-2            \n"   // 2 cycles regardless of branch
    :                          //no output
    : [delay] "r" (delay)      // input
    :                          // no memory clobber
  );
}

// This function sets the current object as the "listening"
// one and returns true if it replaces another
bool SoftwareSerial::listen() {
  if (active_object != this) {
    _buffer_overflow = false;
    uint8_t oldSR = __read_status_register();
    noInterrupts();
    _receive_buffer_head = _receive_buffer_tail = 0;
    active_object = this;
    __write_status_register(oldSR);
    return true;
  }

  return false;
}

//
// The receive routine called by the interrupt handler
//
void SoftwareSerial::recv()
{
  uint8_t d = 0;

  // If RX line is high, then we don't see any start bit
  // so interrupt is probably not for us
  if (_inverse_logic ? rx_pin_read() : !rx_pin_read())
  {
    // Wait approximately 1/2 of a bit width to "center" the sample
    tunedDelay(_rx_delay_centering);

    // Read each of the 8 bits
    for (uint8_t i=0x1; i; i <<= 1)
    {
      tunedDelay(_rx_delay_intrabit);
      uint8_t noti = ~i;
      if (rx_pin_read())
        d |= i;
      else // else clause added to ensure function timing is ~balanced
      d &= noti;
    }

    // skip the stop bit
    tunedDelay(_rx_delay_stopbit);

    if (_inverse_logic)
      d = ~d;

    // if buffer full, set the overflow flag and return
    if ((_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF != _receive_buffer_head)
    {
      // save new data in buffer: tail points to where byte goes
      _receive_buffer[_receive_buffer_tail] = d; // save new byte
      _receive_buffer_tail = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
    }
    else
    {
      _buffer_overflow = true;
    }
  }
}

void SoftwareSerial::tx_pin_write(uint8_t pin_state)
{
  if (pin_state == LOW)
    *_transmitPortRegister &= ~_transmitBitMask;
  else
    *_transmitPortRegister |= _transmitBitMask;
}

uint8_t SoftwareSerial::rx_pin_read()
{
  return *_receivePortRegister & _receiveBitMask;
}

//
// Interrupt handling
//

/* static */
void SoftwareSerial::handle_interrupt()
{
  if (active_object)
  {
    active_object->recv();
  }
}

//
// Constructor
//
SoftwareSerial::SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic /* = false */) :
_rx_delay_centering(0),
_rx_delay_intrabit(0),
_rx_delay_stopbit(0),
_tx_delay(0),
_buffer_overflow(false),
_inverse_logic(inverse_logic)
{
  setTX(transmitPin);
  setRX(receivePin);
}

//
// Destructor
//
SoftwareSerial::~SoftwareSerial()
{
  end();
}

void SoftwareSerial::setTX(uint8_t tx)
{
  pinMode(tx, OUTPUT);
  digitalWrite(tx, HIGH);
  _transmitBitMask = digitalPinToBitMask(tx);
  uint8_t port = digitalPinToPort(tx);
  _transmitPortRegister = portOutputRegister(port);
}

void SoftwareSerial::setRX(uint8_t rx)
{
  pinMode(rx, INPUT);
  if (!_inverse_logic)
    digitalWrite(rx, HIGH);  // pullup for normal logic!
  _receivePin = rx;
  _receiveBitMask = digitalPinToBitMask(rx);
  uint8_t port = digitalPinToPort(rx);
  _receivePortRegister = portInputRegister(port);
}

//
// Public methods
//

void SoftwareSerial::begin(long speed)
{
  _rx_delay_centering = _rx_delay_intrabit = _rx_delay_stopbit = _tx_delay = 0;

  for (unsigned i=0; i<sizeof(table)/sizeof(table[0]); ++i)
  {
    long baud = table[i].baud;
    if (baud == speed)
    {
      _rx_delay_centering = table[i].rx_delay_centering;
      _rx_delay_intrabit = table[i].rx_delay_intrabit;
      _rx_delay_stopbit = table[i].rx_delay_stopbit;
      _tx_delay = table[i].tx_delay;
      break;
    }
  }

  // Set up RX interrupts, but only if we have a valid RX baud rate
  if (_rx_delay_stopbit)
  {
    attachInterrupt(_receivePin, SoftwareSerial::handle_interrupt, FALLING);

    tunedDelay(_tx_delay); // if we were low this establishes the end
  }

  listen();
}

void SoftwareSerial::end()
{
  detachInterrupt(_receivePin);
}

// Read data from buffer
int SoftwareSerial::read()
{
  if (!isListening())
    return -1;

  // Empty buffer?
  if (_receive_buffer_head == _receive_buffer_tail)
    return -1;

  // Read from "head"
  uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte
  _receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF;
  return d;
}

int SoftwareSerial::available()
{
  if (!isListening())
    return 0;

  return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF;
}

size_t SoftwareSerial::write(uint8_t b)
{
  if (_tx_delay == 0) {
    setWriteError();
    return 0;
  }

  //interrupts off
  uint8_t oldSR = __read_status_register();
  noInterrupts();

  // Write the start bit
  tx_pin_write(_inverse_logic ? HIGH : LOW);
  tunedDelay(_tx_delay + XMIT_START_ADJUSTMENT);

  // Write each of the 8 bits
  if (_inverse_logic)
  {
    for (byte mask = 0x01; mask; mask <<= 1)
    {
      if (b & mask) // choose bit
        tx_pin_write(LOW); // send 1
      else
        tx_pin_write(HIGH); // send 0

      tunedDelay(_tx_delay);
    }

    tx_pin_write(LOW); // restore pin to natural state
  }
  else
  {
    for (byte mask = 0x01; mask; mask <<= 1)
    {
      if (b & mask) // choose bit
        tx_pin_write(HIGH); // send 1
      else
        tx_pin_write(LOW); // send 0

      tunedDelay(_tx_delay);
    }

    tx_pin_write(HIGH); // restore pin to natural state
  }

  // turn interrupts back on if they were on before
  __write_status_register(oldSR);
  tunedDelay(_tx_delay);

  return 1;
}

void SoftwareSerial::flush()
{
  if (!isListening())
    return;

  uint8_t oldSR = __read_status_register();
  noInterrupts();
  _receive_buffer_head = _receive_buffer_tail = 0;
  __write_status_register(oldSR);
}

int SoftwareSerial::peek()
{
  if (!isListening())
    return -1;

  // Empty buffer?
  if (_receive_buffer_head == _receive_buffer_tail)
    return -1;

  // Read from "head"
  return _receive_buffer[_receive_buffer_head];
}

<|endoftext|>


<commit_before>#include "ros/ros.h"
#include "geometry_msgs/Twist.h"
#include "geometry_msgs/Vector3.h"
#include "scr_proto/DiffCommand.h"
#include <eigen3/Eigen/Dense>

// Physical Parameters... What do to with these?
double wheel_radius=4.875/2.0*.0254, axle_half_length=8.4*.0254;
// Maximum loaded motor rotation speed in radians per sec
double motor_max_speed=25;

// Global values for velocity storage
double cmd_vx=0, cmd_vy=0, cmd_vz=0, cmd_wx=0, cmd_wy=0, cmd_wz=0;

// Callback to attach to command velocity subscription
void commandCallback(const geometry_msgs::Twist::ConstPtr& msg){

  // Pull values from message
  cmd_vx = msg->linear.x;
  cmd_wz = msg->angular.z;

}

// Function to calculate wheel speeds given a diff drive command
// Models problem as Ax = b form
Eigen::Vector2d getWheelSpeeds(double wheel_offset, double cmd_x, double cmd_th){
  /*
  @ Params:  wheel_offset -> Distance between center of wheel axle and center of wheel contact
             cmd_x        -> Commanded forward velocity for the robot
             cmd_th       -> Commanded angular velocity about the reference point
  @ Returns: x            -> Eigen::Vector containing body velocities at wheel;
                             x(0) -> Right Wheel
                             x(1) -> Left Wheel
  */

  // Diff Drive Dynamics Solution, vr = right wheel velocity, vl = left wheel velocity
  double vr = cmd_x + cmd_th * wheel_offset/2.0;
  double vl = cmd_x - cmd_th * wheel_offset/2.0;

  // Vector for result and return
  Eigen::Vector2d x;
  // Pack Vector with values and return
  x(0) = vr;
  x(1) = vl;
  return x;

}

int main(int argc, char **argv){

  // Initialize Node
  ros::init(argc, argv, "base_controller");

  // Create Nodehandle
  ros::NodeHandle n;

  // Subscribe to Command Velocity topic
  ros::Subscriber cmd_vel_sub = n.subscribe("cmd_vel", 1000, commandCallback);

  ros::Publisher motor_pub = n.advertise<scr_proto::DiffCommand>("/motor_command", 1000);

  ros::Rate loop_rate(10);

  while(ros::ok()){

    // Vector for holding the linear speeds at the wheels
    Eigen::Vector2d wheel_linear_speeds;

    // Pass to linear Alg to solver or something?
    wheel_linear_speeds = getWheelSpeeds(axle_half_length, cmd_vx, cmd_wz);

    // Convert Wheel Velocities to Angular Velocities
    // Be careful for sign flip, as motors are not mounted symmetrically
    double right_wheel_omega = wheel_linear_speeds(0)/wheel_radius;
    double left_wheel_omega = wheel_linear_speeds(1)/wheel_radius;

    // Log info to see output of linear system
    ROS_INFO("Right Motor Desired Speed = [%d]", right_wheel_omega);
    ROS_INFO("Left Motor Desired Speed = [%d]", left_wheel_omega);

    // Declare Message
    scr_proto::DiffCommand motor_com;

    // Populate Message
    // Need to map omega's to value between -127 and 127 for motor driver
    right_wheel_omega *= (127.0/motor_max_speed);
    left_wheel_omega *= (127.0/motor_max_speed);

    motor_com.left_motor = (int)left_wheel_omega;
    motor_com.right_motor = (int)right_wheel_omega;

    // Log Info for debugging
    ROS_INFO("Right Motor Command = [%d]", right_wheel_omega);
    ROS_INFO("Left Motor Command = [%d]", left_wheel_omega);

    // Publish Message
    motor_pub.publish(motor_com);

    // Handle loop rate
    ros::spinOnce();
    loop_rate.sleep();
  }
}

<commit_msg>Factored out one function, fixed stuff.<commit_after>#include "ros/ros.h"
#include "geometry_msgs/Twist.h"
#include "geometry_msgs/Vector3.h"
#include "scr_proto/DiffCommand.h"
#include <eigen3/Eigen/Dense>

// Physical Parameters... What do to with these?
double wheel_radius=4.875/2.0*.0254, axle_half_length=8.4*.0254;
// Maximum loaded motor rotation speed in radians per sec
double motor_max_speed=25;

// Global values for velocity storage
double cmd_vx=0, cmd_vy=0, cmd_vz=0, cmd_wx=0, cmd_wy=0, cmd_wz=0;

// Callback to attach to command velocity subscription
void commandCallback(const geometry_msgs::Twist::ConstPtr& msg){

  // Pull values from message
  cmd_vx = msg->linear.x;
  cmd_wz = msg->angular.z;

}

// Function to calculate wheel speeds given a diff drive command
// Models problem as Ax = b form
Eigen::Vector2d getWheelLinSpeeds(double wheel_offset, double cmd_x, double cmd_th){
  /*
  @ Params:  wheel_offset -> Distance between center of wheel axle and center of wheel contact
             cmd_x        -> Commanded forward velocity for the robot
             cmd_th       -> Commanded angular velocity about the reference point
  @ Returns: x            -> Eigen::Vector containing body velocities at wheel;
                             x(0) -> Right Wheel Linear Speed in m/s
                             x(1) -> Left Wheel Linear Speed in m/s
  */

  // Diff Drive Dynamics Solution, vr = right wheel velocity, vl = left wheel velocity
  double vr = cmd_x + cmd_th * wheel_offset/2.0;
  double vl = cmd_x - cmd_th * wheel_offset/2.0;

  // Vector for result and return
  Eigen::Vector2d x;
  // Pack Vector with values and return
  x(0) = vr;
  x(1) = vl;
  return x;

}

// Function to calculate angular speeds of wheels given differential drvie command
Eigen::Vector2d getWheelSpeeds(double wheel_radius, double wheel_offset, double cmd_x, double cmd_th){
  /*
  @ Params:  wheel_radius -> Radius of wheels in m
             wheel_offset -> Distance between center of wheel axle and center of wheel contact in m
             cmd_x        -> Commanded forward velocity for the robot in m/s
             cmd_th       -> Commanded angular velocity about the reference point in rad/s
  @ Returns: x            -> Eigen::Vector containing body velocities at wheel;
                             x(0) -> Right Wheel Rotational Speed in rad/s
                             x(1) -> Left Wheel Rotational Speed in rad/s

  */

  // Get Linear Speeds
  Eigen::Vector2d speeds = getWheelLinSpeeds(wheel_offset, cmd_x, cmd_th);

  // Translate to Rotational Speeds
  return speeds /= wheel_radius;

}

int main(int argc, char **argv){

  // Initialize Node
  ros::init(argc, argv, "base_controller");

  // Create Nodehandle
  ros::NodeHandle n;

  // Subscribe to Command Velocity topic
  ros::Subscriber cmd_vel_sub = n.subscribe("cmd_vel", 1000, commandCallback);

  ros::Publisher motor_pub = n.advertise<scr_proto::DiffCommand>("/motor_command", 1000);

  ros::Rate loop_rate(10);

  while(ros::ok()){

    // Vector for holding the linear speeds at the wheels
    Eigen::Vector2d wheel_speeds;

    // Get Rotational Speeds given command
    // Be Careful, assumes motor axes point same direction
    wheel_speeds = getWheelSpeeds(wheel_radius, axle_half_length, cmd_vx, cmd_wz);
    double right_wheel_omega = wheel_speeds(0);
    double left_wheel_omega = wheel_speeds(1);

    // Log info to see output of linear system
    ROS_INFO("Right Motor Desired Speed = [%f]", right_wheel_omega);
    ROS_INFO("Left Motor Desired Speed = [%f]", left_wheel_omega);

    // Declare Message
    scr_proto::DiffCommand motor_com;

    // Populate Message
    // Need to map omega's to value between -127 and 127 for motor driver
    right_wheel_omega *= (127.0/motor_max_speed);
    left_wheel_omega *= (127.0/motor_max_speed);

    motor_com.left_motor = (int)left_wheel_omega;
    motor_com.right_motor = (int)right_wheel_omega;

    // Log Info for debugging
    ROS_INFO("Right Motor Command = [%f]", right_wheel_omega);
    ROS_INFO("Left Motor Command = [%f]", left_wheel_omega);

    // Publish Message
    motor_pub.publish(motor_com);

    // Handle loop rate
    ros::spinOnce();
    loop_rate.sleep();
  }
}

<|endoftext|>


<commit_before><commit_msg>set the sound system active flag a little sooner, since some of the stuff at the end of the startup will check to see that startup didn't fail.<commit_after><|endoftext|>


<commit_before>/**
 *  @file SpeciesThermoFactory.cpp
 */

/*
 * $Author$
 * $Revision$
 * $Date$
 */

// Copyright 2001  California Institute of Technology

#ifdef WIN32
#pragma warning(disable:4786)
#endif

#include "SpeciesThermoFactory.h"

#include "SpeciesThermo.h"
#include "NasaThermo.h"
#include "ShomateThermo.h"
#include "PolyThermoMgr.h"
#include "SimpleThermo.h"

#include "SpeciesThermoMgr.h"
#include "speciesThermoTypes.h"

#include "xml.h"
#include "ctml.h"
using namespace ctml;

namespace Cantera {

    SpeciesThermoFactory* SpeciesThermoFactory::__factory = 0;

    static void getSpeciesThermoTypes(XML_Node* node,
        int& has_nasa, int& has_shomate, int& has_simple) {
        const XML_Node& sparray = *node;
        vector<XML_Node*> sp;
        sparray.getChildren("species",sp);
        int ns = sp.size();
        for (int n = 0; n < ns; n++) {
	  XML_Node* spNode = sp[n];
	  if (spNode->hasChild("thermo")) {
            const XML_Node& th = sp[n]->child("thermo");
            if (th.hasChild("NASA")) has_nasa = 1;
            if (th.hasChild("Shomate")) has_shomate = 1;
            if (th.hasChild("const_cp")) has_simple = 1;
            if (th.hasChild("poly")) {
                if (th.child("poly")["order"] == "1") has_simple = 1;
                else throw CanteraError("newSpeciesThermo",
                    "poly with order > 1 not yet supported");
            }
	  } else {
	    throw UnknownSpeciesThermoModel("getSpeciesThermoTypes:",
					    spNode->attrib("name"), "missing");
	  }
        }
    }

    /**
     * Return a species thermo manager to handle the parameterizations
     * specified in a CTML phase specification.
     */
    SpeciesThermo* SpeciesThermoFactory::newSpeciesThermo(XML_Node* node) {
        int inasa = 0, ishomate = 0, isimple = 0;
        getSpeciesThermoTypes(node, inasa, ishomate, isimple);
        return newSpeciesThermo(NASA*inasa
            + SHOMATE*ishomate + SIMPLE*isimple);
    }

    SpeciesThermo* SpeciesThermoFactory::newSpeciesThermo(vector<XML_Node*> nodes) {
        int n = nodes.size();
        int inasa = 0, ishomate = 0, isimple = 0;
        for (int j = 0; j < n; j++) {
            getSpeciesThermoTypes(nodes[j], inasa, ishomate, isimple);
        }
        return newSpeciesThermo(NASA*inasa
            + SHOMATE*ishomate + SIMPLE*isimple);
    }

    SpeciesThermo* SpeciesThermoFactory::newSpeciesThermoOpt(vector<XML_Node*> nodes) {
        int n = nodes.size();
        int inasa = 0, ishomate = 0, isimple = 0;
        for (int j = 0; j < n; j++) {
	  try {
            getSpeciesThermoTypes(nodes[j], inasa, ishomate, isimple);
	  } catch (UnknownSpeciesThermoModel) {

	  }
        }
        return newSpeciesThermo(NASA*inasa
            + SHOMATE*ishomate + SIMPLE*isimple);
    }

    SpeciesThermo* SpeciesThermoFactory::newSpeciesThermo(int type) {

        switch (type) {

        case NASA:
            return new NasaThermo;
        case SHOMATE:
            return new ShomateThermo;
        case SIMPLE:
            return new SimpleThermo;
        case NASA + SHOMATE:
            return new SpeciesThermoDuo<NasaThermo, ShomateThermo>;
        case NASA + SIMPLE:
            return new SpeciesThermoDuo<NasaThermo, SimpleThermo>;
        default:
            throw UnknownSpeciesThermo(
                "SpeciesThermoFactory::newSpeciesThermo",type);
            return 0;
        }
    }

        /// Check the continuity of properties at the midpoint
        /// temperature, and adjust the high-T coefficients to
        /// make the properties exactly continuous at Tmid.
    void NasaThermo::checkContinuity(double tmid, const doublereal* clow,
            doublereal* chigh) {

            // heat capacity
            doublereal cplow = poly4(tmid, clow+2);
            doublereal cphigh = poly4(tmid, chigh+2);
            doublereal delta = cplow - cphigh;
            if (fabs(delta/cplow) > 0.001) {
                writelog("\n**** WARNING ****\nDiscontinuity in cp/R detected at Tmid = "
                    +fp2str(tmid)+"\n");
                writelog("\tValue computed using low-temperature polynomial:  "+fp2str(cplow)+".\n");
                writelog("\tValue computed using high-temperature polynomial: "+fp2str(cphigh)+".\n");
            }
            //chigh[2] += cplow - cphigh;

            // enthalpy
            doublereal hrtlow = enthalpy_RT(tmid, clow);
            doublereal hrthigh = enthalpy_RT(tmid, chigh);
            delta = hrtlow - hrthigh;
            //            chigh[0] += tmid*(hrtlow - hrthigh);
            if (fabs(delta/hrtlow) > 0.001) {
                writelog("\n**** WARNING ****\nDiscontinuity in h/RT detected at Tmid = "
                    +fp2str(tmid)+"\n");
                writelog("\tValue computed using low-temperature polynomial:  "+fp2str(hrtlow)+".\n");
                writelog("\tValue computed using high-temperature polynomial: "+fp2str(hrthigh)+".\n");
            }

            // entropy
            doublereal srlow = entropy_R(tmid, clow);
            doublereal srhigh = entropy_R(tmid, chigh);
            //chigh[1] += srlow - srhigh;
            delta = srlow - srhigh;
            if (fabs(delta/srlow) > 0.001) {
                writelog("\n**** WARNING ****\nDiscontinuity in s/R detected at Tmid = "
                    +fp2str(tmid)+"\n");
                writelog("\tValue computed using low-temperature polynomial:  "+fp2str(srlow)+".\n");
                writelog("\tValue computed using high-temperature polynomial: "+fp2str(srhigh)+".\n");
            }
        }

    /**
     * Install a NASA polynomial thermodynamic property
     * parameterization for species k into a SpeciesThermo instance.
     */
    static void installNasaThermoFromXML(SpeciesThermo& sp, int k,
        const XML_Node* f0ptr, const XML_Node* f1ptr) {
        doublereal tmin0, tmax0, tmin1, tmax1, tmin, tmid, tmax;

        const XML_Node& f0 = *f0ptr;
        bool dualRange = false;
        if (f1ptr) {dualRange = true;}
        tmin0 = fpValue(f0["Tmin"]);
        tmax0 = fpValue(f0["Tmax"]);
        tmin1 = tmax0;
        tmax1 = tmin1 + 0.0001;
        if (dualRange) {
            tmin1 = fpValue((*f1ptr)["Tmin"]);
            tmax1 = fpValue((*f1ptr)["Tmax"]);
        }

        vector_fp c0, c1;
        if (fabs(tmax0 - tmin1) < 0.01) {
            tmin = tmin0;
            tmid = tmax0;
            tmax = tmax1;
            getFloatArray(f0.child("floatArray"), c0, false);
            if (dualRange)
                getFloatArray(f1ptr->child("floatArray"), c1, false);
            else
                c1.resize(7,0.0);
        }
        else if (fabs(tmax1 - tmin0) < 0.01) {
            tmin = tmin1;
            tmid = tmax1;
            tmax = tmax0;
            getFloatArray(f1ptr->child("floatArray"), c0, false);
            getFloatArray(f0.child("floatArray"), c1, false);
        }
        else {
            throw CanteraError("installNasaThermo",
			       "non-continuous temperature ranges.");
        }
        array_fp c(15);
        c[0] = tmid;
        doublereal p0 = OneAtm;
        c[1] = c0[5];
        c[2] = c0[6];
        copy(c0.begin(), c0.begin()+5, c.begin() + 3);
        c[8] = c1[5];
        c[9] = c1[6];
        copy(c1.begin(), c1.begin()+5, c.begin() + 10);
        sp.install(k, NASA, c.begin(), tmin, tmax, p0);
    }

    /**
     * Install a NASA polynomial thermodynamic property
     * parameterization for species k.
     */
    static void installShomateThermoFromXML(SpeciesThermo& sp, int k,
        const XML_Node* f0ptr, const XML_Node* f1ptr) {
        doublereal tmin0, tmax0, tmin1, tmax1, tmin, tmid, tmax;

        const XML_Node& f0 = *f0ptr;
        bool dualRange = false;
        if (f1ptr) {dualRange = true;}
        tmin0 = fpValue(f0["Tmin"]);
        tmax0 = fpValue(f0["Tmax"]);
        tmin1 = tmax0;
        tmax1 = tmin1 + 0.0001;
        if (dualRange) {
            tmin1 = fpValue((*f1ptr)["Tmin"]);
            tmax1 = fpValue((*f1ptr)["Tmax"]);
        }

        vector_fp c0, c1;
        if (fabs(tmax0 - tmin1) < 0.01) {
            tmin = tmin0;
            tmid = tmax0;
            tmax = tmax1;
            getFloatArray(f0.child("floatArray"), c0, false);
            if (dualRange)
                getFloatArray(f1ptr->child("floatArray"), c1, false);
            else
                c1.resize(7,0.0);
        }
        else if (fabs(tmax1 - tmin0) < 0.01) {
            tmin = tmin1;
            tmid = tmax1;
            tmax = tmax0;
            getFloatArray(f1ptr->child("floatArray"), c0, false);
            getFloatArray(f0.child("floatArray"), c1, false);
        }
        else {
            throw CanteraError("installShomateThermo",
			       "non-continuous temperature ranges.");
        }
        array_fp c(15);
        c[0] = tmid;
        doublereal p0 = OneAtm;
        copy(c0.begin(), c0.begin()+7, c.begin() + 1);
        copy(c1.begin(), c1.begin()+7, c.begin() + 8);
        sp.install(k, SHOMATE, c.begin(), tmin, tmax, p0);
    }

    /**
     * Install a constant-cp thermodynamic property
     * parameterization for species k.
     */
    static void installSimpleThermoFromXML(SpeciesThermo& sp, int k,
        const XML_Node& f) {
        doublereal tmin, tmax;
        tmin = fpValue(f["Tmin"]);
        tmax = fpValue(f["Tmax"]);
        if (tmax == 0.0) tmax = 1.0e30;

        vector_fp c(4);
        c[0] = getFloat(f, "t0", "-");
        c[1] = getFloat(f, "h0", "-");
        c[2] = getFloat(f, "s0", "-");
        c[3] = getFloat(f, "cp0", "-");
        doublereal p0 = OneAtm;
        sp.install(k, SIMPLE, c.begin(), tmin, tmax, p0);
    }

    /**
     * Install a species thermodynamic property parameterization
     * for one species into a species thermo manager.
     * @param k species number
     * @param s XML node specifying species
     * @param spthermo species thermo manager
     */
    void SpeciesThermoFactory::
    installThermoForSpecies(int k, const XML_Node& s,
        SpeciesThermo& spthermo) {

	const XML_Node& thermo = s.child("thermo");
	const vector<XML_Node*>& tp = thermo.children();
	int nc = tp.size();
	if (nc == 1) {
            const XML_Node* f = tp[0];
            if (f->name() == "Shomate") {
                installShomateThermoFromXML(spthermo, k, f, 0);
            }
            else if (f->name() == "const_cp") {
                installSimpleThermoFromXML(spthermo, k, *f);
            }
            else if (f->name() == "NASA") {
                installNasaThermoFromXML(spthermo, k, f, 0);
            }
            else {
                UnknownSpeciesThermoModel("installSpecies", s["name"], f->name());
            }
	}
	else if (nc == 2) {
            const XML_Node* f0 = tp[0];
            const XML_Node* f1 = tp[1];
            if (f0->name() == "NASA" && f1->name() == "NASA") {
                installNasaThermoFromXML(spthermo, k, f0, f1);
            }
            else if (f0->name() == "Shomate" && f1->name() == "Shomate") {
                installShomateThermoFromXML(spthermo, k, f0, f1);
            }
            else {
                UnknownSpeciesThermoModel("installSpecies", s["name"],
                    f0->name() + " and " + f1->name());
            }
	}
	else {
	    UnknownSpeciesThermoModel("installSpecies", s["name"],
                "multiple");
	}
    }

}
<commit_msg>Added a few throw statements that was missing. Added a throw UnknownSpeciesThermo statement for cases where the complete thermo block is missing. This is necessary for particle species object to function.<commit_after>/**
 *  @file SpeciesThermoFactory.cpp
 */

/*
 * $Author$
 * $Revision$
 * $Date$
 */

// Copyright 2001  California Institute of Technology

#ifdef WIN32
#pragma warning(disable:4786)
#endif

#include "SpeciesThermoFactory.h"

#include "SpeciesThermo.h"
#include "NasaThermo.h"
#include "ShomateThermo.h"
#include "PolyThermoMgr.h"
#include "SimpleThermo.h"

#include "SpeciesThermoMgr.h"
#include "speciesThermoTypes.h"

#include "xml.h"
#include "ctml.h"
using namespace ctml;

namespace Cantera {

    SpeciesThermoFactory* SpeciesThermoFactory::__factory = 0;

    static void getSpeciesThermoTypes(XML_Node* node,
        int& has_nasa, int& has_shomate, int& has_simple) {
        const XML_Node& sparray = *node;
        vector<XML_Node*> sp;
        sparray.getChildren("species",sp);
        int ns = sp.size();
        for (int n = 0; n < ns; n++) {
	  XML_Node* spNode = sp[n];
	  if (spNode->hasChild("thermo")) {
            const XML_Node& th = sp[n]->child("thermo");
            if (th.hasChild("NASA")) has_nasa = 1;
            if (th.hasChild("Shomate")) has_shomate = 1;
            if (th.hasChild("const_cp")) has_simple = 1;
            if (th.hasChild("poly")) {
                if (th.child("poly")["order"] == "1") has_simple = 1;
                else throw CanteraError("newSpeciesThermo",
                    "poly with order > 1 not yet supported");
            }
	  } else {
	    throw UnknownSpeciesThermoModel("getSpeciesThermoTypes:",
					    spNode->attrib("name"), "missing");
	  }
        }
    }

    /**
     * Return a species thermo manager to handle the parameterizations
     * specified in a CTML phase specification.
     */
    SpeciesThermo* SpeciesThermoFactory::newSpeciesThermo(XML_Node* node) {
        int inasa = 0, ishomate = 0, isimple = 0;
        getSpeciesThermoTypes(node, inasa, ishomate, isimple);
        return newSpeciesThermo(NASA*inasa
            + SHOMATE*ishomate + SIMPLE*isimple);
    }

    SpeciesThermo* SpeciesThermoFactory::
    newSpeciesThermo(vector<XML_Node*> nodes) {
        int n = nodes.size();
        int inasa = 0, ishomate = 0, isimple = 0;
        for (int j = 0; j < n; j++) {
            getSpeciesThermoTypes(nodes[j], inasa, ishomate, isimple);
        }
        return newSpeciesThermo(NASA*inasa
            + SHOMATE*ishomate + SIMPLE*isimple);
    }

    SpeciesThermo* SpeciesThermoFactory::
    newSpeciesThermoOpt(vector<XML_Node*> nodes) {
        int n = nodes.size();
        int inasa = 0, ishomate = 0, isimple = 0;
        for (int j = 0; j < n; j++) {
	  try {
            getSpeciesThermoTypes(nodes[j], inasa, ishomate, isimple);
	  } catch (UnknownSpeciesThermoModel) {

	  }
        }
        return newSpeciesThermo(NASA*inasa
            + SHOMATE*ishomate + SIMPLE*isimple);
    }

    SpeciesThermo* SpeciesThermoFactory::newSpeciesThermo(int type) {

        switch (type) {

        case NASA:
            return new NasaThermo;
        case SHOMATE:
            return new ShomateThermo;
        case SIMPLE:
            return new SimpleThermo;
        case NASA + SHOMATE:
            return new SpeciesThermoDuo<NasaThermo, ShomateThermo>;
        case NASA + SIMPLE:
            return new SpeciesThermoDuo<NasaThermo, SimpleThermo>;
        default:
            throw UnknownSpeciesThermo(
                "SpeciesThermoFactory::newSpeciesThermo",type);
            return 0;
        }
    }

        /// Check the continuity of properties at the midpoint
        /// temperature, and adjust the high-T coefficients to
        /// make the properties exactly continuous at Tmid.
    void NasaThermo::checkContinuity(double tmid, const doublereal* clow,
            doublereal* chigh) {

            // heat capacity
            doublereal cplow = poly4(tmid, clow+2);
            doublereal cphigh = poly4(tmid, chigh+2);
            doublereal delta = cplow - cphigh;
            if (fabs(delta/cplow) > 0.001) {
                writelog("\n**** WARNING ****\nDiscontinuity in cp/R detected at Tmid = "
                    +fp2str(tmid)+"\n");
                writelog("\tValue computed using low-temperature polynomial:  "+fp2str(cplow)+".\n");
                writelog("\tValue computed using high-temperature polynomial: "+fp2str(cphigh)+".\n");
            }
            //chigh[2] += cplow - cphigh;

            // enthalpy
            doublereal hrtlow = enthalpy_RT(tmid, clow);
            doublereal hrthigh = enthalpy_RT(tmid, chigh);
            delta = hrtlow - hrthigh;
            //            chigh[0] += tmid*(hrtlow - hrthigh);
            if (fabs(delta/hrtlow) > 0.001) {
                writelog("\n**** WARNING ****\nDiscontinuity in h/RT detected at Tmid = "
                    +fp2str(tmid)+"\n");
                writelog("\tValue computed using low-temperature polynomial:  "+fp2str(hrtlow)+".\n");
                writelog("\tValue computed using high-temperature polynomial: "+fp2str(hrthigh)+".\n");
            }

            // entropy
            doublereal srlow = entropy_R(tmid, clow);
            doublereal srhigh = entropy_R(tmid, chigh);
            //chigh[1] += srlow - srhigh;
            delta = srlow - srhigh;
            if (fabs(delta/srlow) > 0.001) {
                writelog("\n**** WARNING ****\nDiscontinuity in s/R detected at Tmid = "
                    +fp2str(tmid)+"\n");
                writelog("\tValue computed using low-temperature polynomial:  "+fp2str(srlow)+".\n");
                writelog("\tValue computed using high-temperature polynomial: "+fp2str(srhigh)+".\n");
            }
        }

    /**
     * Install a NASA polynomial thermodynamic property
     * parameterization for species k into a SpeciesThermo instance.
     */
    static void installNasaThermoFromXML(SpeciesThermo& sp, int k,
        const XML_Node* f0ptr, const XML_Node* f1ptr) {
        doublereal tmin0, tmax0, tmin1, tmax1, tmin, tmid, tmax;

        const XML_Node& f0 = *f0ptr;
        bool dualRange = false;
        if (f1ptr) {dualRange = true;}
        tmin0 = fpValue(f0["Tmin"]);
        tmax0 = fpValue(f0["Tmax"]);
        tmin1 = tmax0;
        tmax1 = tmin1 + 0.0001;
        if (dualRange) {
            tmin1 = fpValue((*f1ptr)["Tmin"]);
            tmax1 = fpValue((*f1ptr)["Tmax"]);
        }

        vector_fp c0, c1;
        if (fabs(tmax0 - tmin1) < 0.01) {
            tmin = tmin0;
            tmid = tmax0;
            tmax = tmax1;
            getFloatArray(f0.child("floatArray"), c0, false);
            if (dualRange)
                getFloatArray(f1ptr->child("floatArray"), c1, false);
            else
                c1.resize(7,0.0);
        }
        else if (fabs(tmax1 - tmin0) < 0.01) {
            tmin = tmin1;
            tmid = tmax1;
            tmax = tmax0;
            getFloatArray(f1ptr->child("floatArray"), c0, false);
            getFloatArray(f0.child("floatArray"), c1, false);
        }
        else {
            throw CanteraError("installNasaThermo",
			       "non-continuous temperature ranges.");
        }
        array_fp c(15);
        c[0] = tmid;
        doublereal p0 = OneAtm;
        c[1] = c0[5];
        c[2] = c0[6];
        copy(c0.begin(), c0.begin()+5, c.begin() + 3);
        c[8] = c1[5];
        c[9] = c1[6];
        copy(c1.begin(), c1.begin()+5, c.begin() + 10);
        sp.install(k, NASA, c.begin(), tmin, tmax, p0);
    }

    /**
     * Install a NASA polynomial thermodynamic property
     * parameterization for species k.
     */
    static void installShomateThermoFromXML(SpeciesThermo& sp, int k,
        const XML_Node* f0ptr, const XML_Node* f1ptr) {
        doublereal tmin0, tmax0, tmin1, tmax1, tmin, tmid, tmax;

        const XML_Node& f0 = *f0ptr;
        bool dualRange = false;
        if (f1ptr) {dualRange = true;}
        tmin0 = fpValue(f0["Tmin"]);
        tmax0 = fpValue(f0["Tmax"]);
        tmin1 = tmax0;
        tmax1 = tmin1 + 0.0001;
        if (dualRange) {
            tmin1 = fpValue((*f1ptr)["Tmin"]);
            tmax1 = fpValue((*f1ptr)["Tmax"]);
        }

        vector_fp c0, c1;
        if (fabs(tmax0 - tmin1) < 0.01) {
            tmin = tmin0;
            tmid = tmax0;
            tmax = tmax1;
            getFloatArray(f0.child("floatArray"), c0, false);
            if (dualRange)
                getFloatArray(f1ptr->child("floatArray"), c1, false);
            else
                c1.resize(7,0.0);
        }
        else if (fabs(tmax1 - tmin0) < 0.01) {
            tmin = tmin1;
            tmid = tmax1;
            tmax = tmax0;
            getFloatArray(f1ptr->child("floatArray"), c0, false);
            getFloatArray(f0.child("floatArray"), c1, false);
        }
        else {
            throw CanteraError("installShomateThermo",
			       "non-continuous temperature ranges.");
        }
        array_fp c(15);
        c[0] = tmid;
        doublereal p0 = OneAtm;
        copy(c0.begin(), c0.begin()+7, c.begin() + 1);
        copy(c1.begin(), c1.begin()+7, c.begin() + 8);
        sp.install(k, SHOMATE, c.begin(), tmin, tmax, p0);
    }

    /**
     * Install a constant-cp thermodynamic property
     * parameterization for species k.
     */
    static void installSimpleThermoFromXML(SpeciesThermo& sp, int k,
        const XML_Node& f) {
        doublereal tmin, tmax;
        tmin = fpValue(f["Tmin"]);
        tmax = fpValue(f["Tmax"]);
        if (tmax == 0.0) tmax = 1.0e30;

        vector_fp c(4);
        c[0] = getFloat(f, "t0", "-");
        c[1] = getFloat(f, "h0", "-");
        c[2] = getFloat(f, "s0", "-");
        c[3] = getFloat(f, "cp0", "-");
        doublereal p0 = OneAtm;
        sp.install(k, SIMPLE, c.begin(), tmin, tmax, p0);
    }

    /**
     * Install a species thermodynamic property parameterization
     * for one species into a species thermo manager.
     * @param k species number
     * @param s XML node specifying species
     * @param spthermo species thermo manager
     */
    void SpeciesThermoFactory::
    installThermoForSpecies(int k, const XML_Node& s,
        SpeciesThermo& spthermo) {
	/*
	 * Check to see that the species block has a thermo block
	 * before processing. Throw an error if not there.
	 */
	if (!(s.hasChild("thermo"))) {
	  throw UnknownSpeciesThermoModel("installSpecies",
					  s["name"], "<nonexistent>");
	}
	const XML_Node& thermo = s.child("thermo");
	const vector<XML_Node*>& tp = thermo.children();
	int nc = tp.size();
	if (nc == 1) {
            const XML_Node* f = tp[0];
            if (f->name() == "Shomate") {
                installShomateThermoFromXML(spthermo, k, f, 0);
            }
            else if (f->name() == "const_cp") {
                installSimpleThermoFromXML(spthermo, k, *f);
            }
            else if (f->name() == "NASA") {
                installNasaThermoFromXML(spthermo, k, f, 0);
            }
            else {
                throw UnknownSpeciesThermoModel("installSpecies",
						s["name"], f->name());
            }
	}
	else if (nc == 2) {
            const XML_Node* f0 = tp[0];
            const XML_Node* f1 = tp[1];
            if (f0->name() == "NASA" && f1->name() == "NASA") {
                installNasaThermoFromXML(spthermo, k, f0, f1);
            }
            else if (f0->name() == "Shomate" && f1->name() == "Shomate") {
                installShomateThermoFromXML(spthermo, k, f0, f1);
            }
            else {
                throw UnknownSpeciesThermoModel("installSpecies", s["name"],
						f0->name() + " and "
						+ f1->name());
            }
	}
	else {
	    throw UnknownSpeciesThermoModel("installSpecies", s["name"],
					    "multiple");
	}
    }

}
<|endoftext|>


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

#include <precomp.h>
#include <toolkit/hf_linachain.hxx>

// NOT FULLY DEFINED SERVICES
#include <toolkit/out_position.hxx>

HF_LinkedNameChain::HF_LinkedNameChain( Xml::Element & o_rOut )
    :   HtmlMaker( o_rOut
                        >> *new Html::Paragraph
                            << new Html::ClassAttr("namechain") )
{
}

HF_LinkedNameChain::~HF_LinkedNameChain()
{
}

void
HF_LinkedNameChain::Produce_CompleteChain( output::Position &  i_curPosition,
                                           F_LinkMaker         i_linkMaker ) const
{
    produce_Level(i_curPosition.RelatedNode(), i_curPosition, i_linkMaker);
}

void
HF_LinkedNameChain::Produce_CompleteChain_forModule( output::Position &  i_curPosition,
                                                     F_LinkMaker         i_linkMaker ) const
{
    if (i_curPosition.Depth() == 0)
        return;
    produce_Level(*i_curPosition.RelatedNode().Parent(), i_curPosition, i_linkMaker);
}

namespace
{

StreamStr aLinkBuf(200);

}

void
HF_LinkedNameChain::produce_Level( output::Node &      i_levelNode,
                                   output::Position &  i_startPosition,
                                   F_LinkMaker         i_linkMaker ) const
{
    if ( i_levelNode.Depth() > 0 )
    {
        produce_Level( *i_levelNode.Parent(),
                       i_startPosition,
                       i_linkMaker );
    }

    aLinkBuf.reset();

    String
        sFileName = (*i_linkMaker)(i_levelNode.Name());
    output::Position
        aLevelPos(i_levelNode, sFileName);

    i_startPosition.Get_LinkTo(aLinkBuf, aLevelPos);

    if ( i_levelNode.Depth() > 0 )
    {
        CurOut()
        >> *new Html::Link(aLinkBuf.c_str())
            << new Html::ClassAttr("namechain")
            << i_levelNode.Name();
        CurOut() << " :: ";
    }
    else
    {
        CurOut()
        >> *new Html::Link(aLinkBuf.c_str())
            << new Html::ClassAttr("namechain")
            << "::";
        CurOut() << " ";
    }
}
<commit_msg>INTEGRATION: CWS adc18 (1.4.2); FILE MERGED 2007/10/18 15:23:15 np 1.4.2.1: #i81775#<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: hf_linachain.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2007-11-02 16:41:40 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <precomp.h>
#include <toolkit/hf_linachain.hxx>

// NOT FULLY DEFINED SERVICES
#include <toolkit/out_position.hxx>

HF_LinkedNameChain::HF_LinkedNameChain( Xml::Element & o_rOut )
    :   HtmlMaker( o_rOut
                        >> *new Html::Paragraph
                            << new Html::ClassAttr("namechain") )
{
}

HF_LinkedNameChain::~HF_LinkedNameChain()
{
}

void
HF_LinkedNameChain::Produce_CompleteChain( const output::Position & i_curPosition,
                                           F_LinkMaker              i_linkMaker ) const
{
    produce_Level(i_curPosition.RelatedNode(), i_curPosition, i_linkMaker);
}

void
HF_LinkedNameChain::Produce_CompleteChain_forModule( const output::Position &  i_curPosition,
                                                     F_LinkMaker               i_linkMaker ) const
{
    if (i_curPosition.Depth() == 0)
        return;
    produce_Level(*i_curPosition.RelatedNode().Parent(), i_curPosition, i_linkMaker);
}

namespace
{

StreamStr aLinkBuf(200);

}

void
HF_LinkedNameChain::produce_Level( output::Node &           i_levelNode,
                                   const output::Position & i_startPosition,
                                   F_LinkMaker              i_linkMaker ) const
{
    if ( i_levelNode.Depth() > 0 )
    {
        produce_Level( *i_levelNode.Parent(),
                       i_startPosition,
                       i_linkMaker );
    }

    aLinkBuf.reset();

    String
        sFileName = (*i_linkMaker)(i_levelNode.Name());
    output::Position
        aLevelPos(i_levelNode, sFileName);

    i_startPosition.Get_LinkTo(aLinkBuf, aLevelPos);

    if ( i_levelNode.Depth() > 0 )
    {
        CurOut()
        >> *new Html::Link(aLinkBuf.c_str())
            << new Html::ClassAttr("namechain")
            << i_levelNode.Name();
        CurOut() << " :: ";
    }
    else
    {
        CurOut()
        >> *new Html::Link(aLinkBuf.c_str())
            << new Html::ClassAttr("namechain")
            << "::";
        CurOut() << " ";
    }
}
<|endoftext|>