<commit_before>/**
 * @file lltoastscripttextbox.cpp
 * @brief Panel for script llTextBox dialogs
 *
 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 *
 * 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;
 * version 2.1 of the License only.
 *
 * 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 Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h"

#include "lltoastscripttextbox.h"

#include "llfocusmgr.h"

#include "llbutton.h"
#include "lliconctrl.h"
#include "llinventoryfunctions.h"
#include "llnotifications.h"
#include "llviewertexteditor.h"

#include "lluiconstants.h"
#include "llui.h"
#include "llviewercontrol.h"
#include "lltrans.h"
#include "llstyle.h"

#include "llglheaders.h"
#include "llagent.h"
#include "llavatariconctrl.h"
#include "llfloaterinventory.h"
#include "llinventorytype.h"

const S32 LLToastScriptTextbox::DEFAULT_MESSAGE_MAX_LINE_COUNT	= 7;

LLToastScriptTextbox::LLToastScriptTextbox(LLNotificationPtr& notification)
:	LLToastNotifyPanel(notification),
	mInventoryOffer(NULL)
{
	buildFromFile( "panel_notify_textbox.xml");

	const LLSD& payload = notification->getPayload();
	llwarns << "PAYLOAD " << payload << llendl;
	llwarns << "TYPE " << notification->getType() << llendl;
	llwarns << "MESSAGE " << notification->getMessage() << llendl;
	llwarns << "LABEL " << notification->getLabel() << llendl;
	llwarns << "URL " << notification->getURL() << llendl;

	/*
2010-09-29T12:24:44Z WARNING: LLToastScriptTextbox: PAYLOAD {'chat_channel':i-376,'object_id':ubb05bcf2-4eca-2203-13f4-b328411d344f,'sender':'216.82.20.80:13001'}
2010-09-29T12:24:44Z WARNING: LLToastScriptTextbox: TYPE notify
2010-09-29T12:24:44Z WARNING: LLToastScriptTextbox: MESSAGE Tofu Tester's 'lltextbox test'
Write something here...
2010-09-29T12:24:44Z WARNING: LLToastScriptTextbox: LABEL
2010-09-29T12:24:44Z WARNING: LLToastScriptTextbox: URL
*/

	//message subject
	//const std::string& subject = payload["subject"].asString();
	//message body
	const std::string& message = payload["message"].asString();

	std::string timeStr = "["+LLTrans::getString("UTCTimeWeek")+"],["
		+LLTrans::getString("UTCTimeDay")+"] ["
		+LLTrans::getString("UTCTimeMth")+"] ["
		+LLTrans::getString("UTCTimeYr")+"] ["
		+LLTrans::getString("UTCTimeHr")+"]:["
		+LLTrans::getString("UTCTimeMin")+"]:["
		+LLTrans::getString("UTCTimeSec")+"] ["
		+LLTrans::getString("UTCTimeTimezone")+"]";
	const LLDate timeStamp = notification->getDate();
	LLDate notice_date = timeStamp.notNull() ? timeStamp : LLDate::now();
	LLSD substitution;
	substitution["datetime"] = (S32) notice_date.secondsSinceEpoch();
	LLStringUtil::format(timeStr, substitution);

	LLViewerTextEditor* pMessageText = getChild<LLViewerTextEditor>("message");
	pMessageText->clear();

	LLStyle::Params style;

	LLFontGL* date_font = LLFontGL::getFontByName(getString("date_font"));
	if (date_font)
		style.font = date_font;
	pMessageText->appendText(timeStr + "\n", TRUE, style);

	style.font = pMessageText->getDefaultFont();
	pMessageText->appendText(message, TRUE, style);
	/*
	//attachment
	BOOL hasInventory = payload["inventory_offer"].isDefined();

	//attachment text
	LLTextBox * pAttachLink = getChild<LLTextBox>("attachment");
	//attachment icon
	LLIconCtrl* pAttachIcon = getChild<LLIconCtrl>("attachment_icon", TRUE);

	//If attachment is empty let it be invisible and not take place at the panel
	pAttachLink->setVisible(hasInventory);
	pAttachIcon->setVisible(hasInventory);
	if (hasInventory) {
		pAttachLink->setValue(payload["inventory_name"]);

		mInventoryOffer = new LLOfferInfo(payload["inventory_offer"]);
		getChild<LLTextBox>("attachment")->setClickedCallback(boost::bind(
				&LLToastScriptTextbox::onClickAttachment, this));

		LLUIImagePtr attachIconImg = LLInventoryIcon::getIcon(mInventoryOffer->mType,
												LLInventoryType::IT_TEXTURE);
		pAttachIcon->setValue(attachIconImg->getName());
	}
	*/
	//ok button
	LLButton* pOkBtn = getChild<LLButton>("btn_ok");
	pOkBtn->setClickedCallback((boost::bind(&LLToastScriptTextbox::onClickOk, this)));
	setDefaultBtn(pOkBtn);

	S32 maxLinesCount;
	std::istringstream ss( getString("message_max_lines_count") );
	if (!(ss >> maxLinesCount))
	{
		maxLinesCount = DEFAULT_MESSAGE_MAX_LINE_COUNT;
	}
	snapToMessageHeight(pMessageText, maxLinesCount);
}

// virtual
LLToastScriptTextbox::~LLToastScriptTextbox()
{
}

void LLToastScriptTextbox::close()
{
	// The group notice dialog may be an inventory offer.
	// If it has an inventory save button and that button is still enabled
	// Then we need to send the inventory declined message
	/*
	if(mInventoryOffer != NULL)
	{
		mInventoryOffer->forceResponse(IOR_DECLINE);
		mInventoryOffer = NULL;
	}
	*/
	die();
}

#include "lllslconstants.h"
void LLToastScriptTextbox::onClickOk()
{
	LLViewerTextEditor* pMessageText = getChild<LLViewerTextEditor>("message");

	if (pMessageText)
	{
		LLSD response = mNotification->getResponseTemplate();
		//response["OH MY GOD WHAT A HACK"] = "woot";
		response[TEXTBOX_MAGIC_TOKEN] = pMessageText->getText();
		if (response[TEXTBOX_MAGIC_TOKEN].asString().empty())
		{
			// so we can distinguish between a successfully
			// submitted blank textbox, and an ignored toast
			response[TEXTBOX_MAGIC_TOKEN] = true;
		}
		mNotification->respond(response);
		close();
		llwarns << response << llendl;
	}
}
/*
void LLToastScriptTextbox::onClickAttachment()
{
	if (mInventoryOffer != NULL) {
		mInventoryOffer->forceResponse(IOR_ACCEPT);

		LLTextBox * pAttachLink = getChild<LLTextBox> ("attachment");
		static const LLUIColor textColor = LLUIColorTable::instance().getColor(
				"GroupNotifyDimmedTextColor");
		pAttachLink->setColor(textColor);

		LLIconCtrl* pAttachIcon =
				getChild<LLIconCtrl> ("attachment_icon", TRUE);
		pAttachIcon->setEnabled(FALSE);

		//if attachment isn't openable - notify about saving
		if (!isAttachmentOpenable(mInventoryOffer->mType)) {
			LLNotifications::instance().add("AttachmentSaved", LLSD(), LLSD());
		}

		mInventoryOffer = NULL;
	}
}
*/

 /*
//static
bool LLToastScriptTextbox::isAttachmentOpenable(LLAssetType::EType type)
{
	switch(type)
	{
	case LLAssetType::AT_LANDMARK:
	case LLAssetType::AT_NOTECARD:
	case LLAssetType::AT_IMAGE_JPEG:
	case LLAssetType::AT_IMAGE_TGA:
	case LLAssetType::AT_TEXTURE:
	case LLAssetType::AT_TEXTURE_TGA:
		return true;
	default:
		return false;
	}
}

 */
<commit_msg>start to de-cruftify.<commit_after>/**
 * @file lltoastscripttextbox.cpp
 * @brief Panel for script llTextBox dialogs
 *
 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 *
 * 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;
 * version 2.1 of the License only.
 *
 * 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 Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h"

#include "lltoastscripttextbox.h"

#include "llfocusmgr.h"

#include "llbutton.h"
#include "lliconctrl.h"
#include "llinventoryfunctions.h"
#include "llnotifications.h"
#include "llviewertexteditor.h"

#include "lluiconstants.h"
#include "llui.h"
#include "llviewercontrol.h"
#include "lltrans.h"
#include "llstyle.h"

#include "llglheaders.h"
#include "llagent.h"
#include "llavatariconctrl.h"
#include "llfloaterinventory.h"
#include "llinventorytype.h"

const S32 LLToastScriptTextbox::DEFAULT_MESSAGE_MAX_LINE_COUNT	= 7;

LLToastScriptTextbox::LLToastScriptTextbox(LLNotificationPtr& notification)
:	LLToastNotifyPanel(notification),
	mInventoryOffer(NULL)
{
	buildFromFile( "panel_notify_textbox.xml");

	const LLSD& payload = notification->getPayload();
	llwarns << "PAYLOAD " << payload << llendl;
	llwarns << "TYPE " << notification->getType() << llendl;
	llwarns << "MESSAGE " << notification->getMessage() << llendl;
	llwarns << "LABEL " << notification->getLabel() << llendl;
	llwarns << "URL " << notification->getURL() << llendl;

	//message subject
	//const std::string& subject = payload["subject"].asString();
	//message body
	const std::string& message = payload["message"].asString();

	std::string timeStr = "["+LLTrans::getString("UTCTimeWeek")+"],["
		+LLTrans::getString("UTCTimeDay")+"] ["
		+LLTrans::getString("UTCTimeMth")+"] ["
		+LLTrans::getString("UTCTimeYr")+"] ["
		+LLTrans::getString("UTCTimeHr")+"]:["
		+LLTrans::getString("UTCTimeMin")+"]:["
		+LLTrans::getString("UTCTimeSec")+"] ["
		+LLTrans::getString("UTCTimeTimezone")+"]";
	const LLDate timeStamp = notification->getDate();
	LLDate notice_date = timeStamp.notNull() ? timeStamp : LLDate::now();
	LLSD substitution;
	substitution["datetime"] = (S32) notice_date.secondsSinceEpoch();
	LLStringUtil::format(timeStr, substitution);

	LLViewerTextEditor* pMessageText = getChild<LLViewerTextEditor>("message");
	pMessageText->clear();

	LLStyle::Params style;

	LLFontGL* date_font = LLFontGL::getFontByName(getString("date_font"));
	if (date_font)
		style.font = date_font;
	pMessageText->appendText(timeStr + "\n", TRUE, style);

	style.font = pMessageText->getDefaultFont();
	pMessageText->appendText(message, TRUE, style);

	//ok button
	LLButton* pOkBtn = getChild<LLButton>("btn_ok");
	pOkBtn->setClickedCallback((boost::bind(&LLToastScriptTextbox::onClickOk, this)));
	setDefaultBtn(pOkBtn);

	S32 maxLinesCount;
	std::istringstream ss( getString("message_max_lines_count") );
	if (!(ss >> maxLinesCount))
	{
		maxLinesCount = DEFAULT_MESSAGE_MAX_LINE_COUNT;
	}
	snapToMessageHeight(pMessageText, maxLinesCount);
}

// virtual
LLToastScriptTextbox::~LLToastScriptTextbox()
{
}

void LLToastScriptTextbox::close()
{
	die();
}

#include "lllslconstants.h"
void LLToastScriptTextbox::onClickOk()
{
	LLViewerTextEditor* pMessageText = getChild<LLViewerTextEditor>("message");

	if (pMessageText)
	{
		LLSD response = mNotification->getResponseTemplate();
		//response["OH MY GOD WHAT A HACK"] = "woot";
		response[TEXTBOX_MAGIC_TOKEN] = pMessageText->getText();
		if (response[TEXTBOX_MAGIC_TOKEN].asString().empty())
		{
			// so we can distinguish between a successfully
			// submitted blank textbox, and an ignored toast
			response[TEXTBOX_MAGIC_TOKEN] = true;
		}
		mNotification->respond(response);
		close();
		llwarns << response << llendl;
	}
}
<|endoftext|>


<commit_before>#include "ImgProc.h"
#include "Matrix.h"

void ImgProc::Init(Handle<Object> target)
{
    Persistent<Object> inner;
    Local<Object> obj = NanNew<Object>();
    NanAssignPersistent(inner, obj);

    NODE_SET_METHOD(obj, "undistort", Undistort);
    NODE_SET_METHOD(obj, "initUndistortRectifyMap", InitUndistortRectifyMap);
    NODE_SET_METHOD(obj, "remap", Remap);

    target->Set(NanNew("imgproc"), obj);
}

// cv::undistort
NAN_METHOD(ImgProc::Undistort)
{
    NanEscapableScope();

    try {
        // Get the arguments

        // Arg 0 is the image
        Matrix* m0 = ObjectWrap::Unwrap<Matrix>(args[0]->ToObject());
        cv::Mat inputImage = m0->mat;

        // Arg 1 is the camera matrix
        Matrix* m1 = ObjectWrap::Unwrap<Matrix>(args[1]->ToObject());
        cv::Mat K = m1->mat;

        // Arg 2 is the distortion coefficents
        Matrix* m2 = ObjectWrap::Unwrap<Matrix>(args[2]->ToObject());
        cv::Mat dist = m2->mat;

        // Make an mat to hold the result image
        cv::Mat outputImage;

        // Undistort
        cv::undistort(inputImage, outputImage, K, dist);

        // Wrap the output image
        Local<Object> outMatrixWrap = NanNew(Matrix::constructor)->GetFunction()->NewInstance();
        Matrix *outMatrix = ObjectWrap::Unwrap<Matrix>(outMatrixWrap);
        outMatrix->mat = outputImage;

        // Return the output image
        NanReturnValue(outMatrixWrap);

    } catch (cv::Exception &e) {
        const char *err_msg = e.what();
        NanThrowError(err_msg);
        NanReturnUndefined();
    }
}

// cv::initUndistortRectifyMap
NAN_METHOD(ImgProc::InitUndistortRectifyMap)
{
    NanEscapableScope();

    try {

        // Arg 0 is the camera matrix
        Matrix* m0 = ObjectWrap::Unwrap<Matrix>(args[0]->ToObject());
        cv::Mat K = m0->mat;

        // Arg 1 is the distortion coefficents
        Matrix* m1 = ObjectWrap::Unwrap<Matrix>(args[1]->ToObject());
        cv::Mat dist = m1->mat;

        // Arg 2 is the recification transformation
        Matrix* m2 = ObjectWrap::Unwrap<Matrix>(args[2]->ToObject());
        cv::Mat R = m2->mat;

        // Arg 3 is the new camera matrix
        Matrix* m3 = ObjectWrap::Unwrap<Matrix>(args[3]->ToObject());
        cv::Mat newK = m3->mat;

        // Arg 4 is the image size
        cv::Size imageSize;
        if (args[4]->IsArray()) {
            Local<Object> v8sz = args[4]->ToObject();

            imageSize = cv::Size(v8sz->Get(1)->IntegerValue(), v8sz->Get(0)->IntegerValue());
        } else {
            JSTHROW_TYPE("Must pass image size");
        }

        // Arg 5 is the first map type, skip for now
        int m1type = CV_16SC2;

        // Make matrices to hold the output maps
        cv::Mat map1, map2;

        // Compute the rectification map
        cv::initUndistortRectifyMap(K, dist, R, newK, imageSize, m1type, map1, map2);

        // Wrap the output maps
        Local<Object> map1Wrap = NanNew(Matrix::constructor)->GetFunction()->NewInstance();
        Matrix *map1Matrix = ObjectWrap::Unwrap<Matrix>(map1Wrap);
        map1Matrix->mat = map1;

        Local<Object> map2Wrap = NanNew(Matrix::constructor)->GetFunction()->NewInstance();
        Matrix *map2Matrix = ObjectWrap::Unwrap<Matrix>(map2Wrap);
        map2Matrix->mat = map2;

        // Make a return object with the two maps
        Local<Object> ret = NanNew<Object>();
        ret->Set(NanNew<String>("map1"), map1Wrap);
        ret->Set(NanNew<String>("map2"), map2Wrap);

        // Return the maps
        NanReturnValue(ret);

    } catch (cv::Exception &e) {
        const char *err_msg = e.what();
        NanThrowError(err_msg);
        NanReturnUndefined();
    }
}

// cv::remap
NAN_METHOD(ImgProc::Remap)
{
    NanEscapableScope();

    try {
        // Get the arguments

        // Arg 0 is the image
        Matrix* m0 = ObjectWrap::Unwrap<Matrix>(args[0]->ToObject());
        cv::Mat inputImage = m0->mat;

        // Arg 1 is the first map
        Matrix* m1 = ObjectWrap::Unwrap<Matrix>(args[1]->ToObject());
        cv::Mat map1 = m1->mat;

        // Arg 2 is the second map
        Matrix* m2 = ObjectWrap::Unwrap<Matrix>(args[2]->ToObject());
        cv::Mat map2 = m2->mat;

        // Arg 3 is the interpolation mode
        int interpolation = args[3]->IntegerValue();

        // Args 4, 5 border settings, skipping for now

        // Output image
        cv::Mat outputImage;

        // Remap
        cv::remap(inputImage, outputImage, map1, map2, interpolation);

        // Wrap the output image
        Local<Object> outMatrixWrap = NanNew(Matrix::constructor)->GetFunction()->NewInstance();
        Matrix *outMatrix = ObjectWrap::Unwrap<Matrix>(outMatrixWrap);
        outMatrix->mat = outputImage;

        // Return the image
        NanReturnValue(outMatrixWrap);

    } catch (cv::Exception &e) {
        const char *err_msg = e.what();
        NanThrowError(err_msg);
        NanReturnUndefined();
    }
}
<commit_msg>Added map1 type paramter to initUndistortRectifyMap<commit_after>#include "ImgProc.h"
#include "Matrix.h"

void ImgProc::Init(Handle<Object> target)
{
    Persistent<Object> inner;
    Local<Object> obj = NanNew<Object>();
    NanAssignPersistent(inner, obj);

    NODE_SET_METHOD(obj, "undistort", Undistort);
    NODE_SET_METHOD(obj, "initUndistortRectifyMap", InitUndistortRectifyMap);
    NODE_SET_METHOD(obj, "remap", Remap);

    target->Set(NanNew("imgproc"), obj);
}

// cv::undistort
NAN_METHOD(ImgProc::Undistort)
{
    NanEscapableScope();

    try {
        // Get the arguments

        // Arg 0 is the image
        Matrix* m0 = ObjectWrap::Unwrap<Matrix>(args[0]->ToObject());
        cv::Mat inputImage = m0->mat;

        // Arg 1 is the camera matrix
        Matrix* m1 = ObjectWrap::Unwrap<Matrix>(args[1]->ToObject());
        cv::Mat K = m1->mat;

        // Arg 2 is the distortion coefficents
        Matrix* m2 = ObjectWrap::Unwrap<Matrix>(args[2]->ToObject());
        cv::Mat dist = m2->mat;

        // Make an mat to hold the result image
        cv::Mat outputImage;

        // Undistort
        cv::undistort(inputImage, outputImage, K, dist);

        // Wrap the output image
        Local<Object> outMatrixWrap = NanNew(Matrix::constructor)->GetFunction()->NewInstance();
        Matrix *outMatrix = ObjectWrap::Unwrap<Matrix>(outMatrixWrap);
        outMatrix->mat = outputImage;

        // Return the output image
        NanReturnValue(outMatrixWrap);

    } catch (cv::Exception &e) {
        const char *err_msg = e.what();
        NanThrowError(err_msg);
        NanReturnUndefined();
    }
}

// cv::initUndistortRectifyMap
NAN_METHOD(ImgProc::InitUndistortRectifyMap)
{
    NanEscapableScope();

    try {

        // Arg 0 is the camera matrix
        Matrix* m0 = ObjectWrap::Unwrap<Matrix>(args[0]->ToObject());
        cv::Mat K = m0->mat;

        // Arg 1 is the distortion coefficents
        Matrix* m1 = ObjectWrap::Unwrap<Matrix>(args[1]->ToObject());
        cv::Mat dist = m1->mat;

        // Arg 2 is the recification transformation
        Matrix* m2 = ObjectWrap::Unwrap<Matrix>(args[2]->ToObject());
        cv::Mat R = m2->mat;

        // Arg 3 is the new camera matrix
        Matrix* m3 = ObjectWrap::Unwrap<Matrix>(args[3]->ToObject());
        cv::Mat newK = m3->mat;

        // Arg 4 is the image size
        cv::Size imageSize;
        if (args[4]->IsArray()) {
            Local<Object> v8sz = args[4]->ToObject();

            imageSize = cv::Size(v8sz->Get(1)->IntegerValue(), v8sz->Get(0)->IntegerValue());
        } else {
            JSTHROW_TYPE("Must pass image size");
        }

        // Arg 5 is the first map type, skip for now
        int m1type = args[5]->IntegerValue();

        // Make matrices to hold the output maps
        cv::Mat map1, map2;

        // Compute the rectification map
        cv::initUndistortRectifyMap(K, dist, R, newK, imageSize, m1type, map1, map2);

        // Wrap the output maps
        Local<Object> map1Wrap = NanNew(Matrix::constructor)->GetFunction()->NewInstance();
        Matrix *map1Matrix = ObjectWrap::Unwrap<Matrix>(map1Wrap);
        map1Matrix->mat = map1;

        Local<Object> map2Wrap = NanNew(Matrix::constructor)->GetFunction()->NewInstance();
        Matrix *map2Matrix = ObjectWrap::Unwrap<Matrix>(map2Wrap);
        map2Matrix->mat = map2;

        // Make a return object with the two maps
        Local<Object> ret = NanNew<Object>();
        ret->Set(NanNew<String>("map1"), map1Wrap);
        ret->Set(NanNew<String>("map2"), map2Wrap);

        // Return the maps
        NanReturnValue(ret);

    } catch (cv::Exception &e) {
        const char *err_msg = e.what();
        NanThrowError(err_msg);
        NanReturnUndefined();
    }
}

// cv::remap
NAN_METHOD(ImgProc::Remap)
{
    NanEscapableScope();

    try {
        // Get the arguments

        // Arg 0 is the image
        Matrix* m0 = ObjectWrap::Unwrap<Matrix>(args[0]->ToObject());
        cv::Mat inputImage = m0->mat;

        // Arg 1 is the first map
        Matrix* m1 = ObjectWrap::Unwrap<Matrix>(args[1]->ToObject());
        cv::Mat map1 = m1->mat;

        // Arg 2 is the second map
        Matrix* m2 = ObjectWrap::Unwrap<Matrix>(args[2]->ToObject());
        cv::Mat map2 = m2->mat;

        // Arg 3 is the interpolation mode
        int interpolation = args[3]->IntegerValue();

        // Args 4, 5 border settings, skipping for now

        // Output image
        cv::Mat outputImage;

        // Remap
        cv::remap(inputImage, outputImage, map1, map2, interpolation);

        // Wrap the output image
        Local<Object> outMatrixWrap = NanNew(Matrix::constructor)->GetFunction()->NewInstance();
        Matrix *outMatrix = ObjectWrap::Unwrap<Matrix>(outMatrixWrap);
        outMatrix->mat = outputImage;

        // Return the image
        NanReturnValue(outMatrixWrap);

    } catch (cv::Exception &e) {
        const char *err_msg = e.what();
        NanThrowError(err_msg);
        NanReturnUndefined();
    }
}
<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

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

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/
#include "itkExtractChannelFromRgbaImageFilter.h"

// VTK
#include <vtkPolyLine.h>
#include <vtkCellArray.h>
#include <vtkCellData.h>

// misc
#include <math.h>

namespace itk{

  template< class ReferenceImageType, class OutputImageType >
  ExtractChannelFromRgbaImageFilter< ReferenceImageType, OutputImageType >::ExtractChannelFromRgbaImageFilter():
    m_Channel(RED)
  {

  }

  template< class ReferenceImageType, class OutputImageType >
  ExtractChannelFromRgbaImageFilter< ReferenceImageType, OutputImageType >::~ExtractChannelFromRgbaImageFilter()
  {
  }

  template< class ReferenceImageType, class OutputImageType >
  void ExtractChannelFromRgbaImageFilter< ReferenceImageType, OutputImageType >::GenerateData()
  {

    typename InputImageType::Pointer rgbaImage = static_cast< InputImageType * >( this->ProcessObject::GetInput(0) );

    typename OutputImageType::Pointer outputImage =
        static_cast< OutputImageType * >(this->ProcessObject::GetPrimaryOutput());

    typename InputImageType::RegionType region = rgbaImage->GetLargestPossibleRegion();
    outputImage->SetSpacing( m_ReferenceImage->GetSpacing() );   // Set the image spacing
    outputImage->SetOrigin( m_ReferenceImage->GetOrigin() );     // Set the image origin
    outputImage->SetDirection( m_ReferenceImage->GetDirection() );  // Set the image direction
    outputImage->SetRegions( m_ReferenceImage->GetLargestPossibleRegion());
    outputImage->Allocate();
    outputImage->FillBuffer(0);
    float* outImageBufferPointer = outputImage->GetBufferPointer();

    itk::Image< short, 3 >::Pointer counterImage = itk::Image< short, 3 >::New();
    counterImage->SetSpacing( m_ReferenceImage->GetSpacing() );   // Set the image spacing
    counterImage->SetOrigin( m_ReferenceImage->GetOrigin() );     // Set the image origin
    counterImage->SetDirection( m_ReferenceImage->GetDirection() );  // Set the image direction
    counterImage->SetRegions( m_ReferenceImage->GetLargestPossibleRegion());
    counterImage->Allocate();
    counterImage->FillBuffer(0);
    short* counterImageBufferPointer = counterImage->GetBufferPointer();

    int w = m_ReferenceImage->GetLargestPossibleRegion().GetSize().GetElement(0);
    int h = m_ReferenceImage->GetLargestPossibleRegion().GetSize().GetElement(1);
    int d = m_ReferenceImage->GetLargestPossibleRegion().GetSize().GetElement(2);

    typedef ImageRegionConstIterator< InputImageType > InImageIteratorType;
    InImageIteratorType rgbaIt(rgbaImage, region);
    rgbaIt.GoToBegin();
    while(!rgbaIt.IsAtEnd()){

      InPixelType x = rgbaIt.Get();
      ++rgbaIt;

      itk::Point<float, 3> vertex;
      itk::Index<3> index = rgbaIt.GetIndex();

      rgbaImage->TransformIndexToPhysicalPoint(index, vertex);
      outputImage->TransformPhysicalPointToIndex(vertex, index);

      itk::ContinuousIndex<float, 3> contIndex;
      outputImage->TransformPhysicalPointToContinuousIndex(vertex, contIndex);

      float frac_x = contIndex[0] - index[0];
      float frac_y = contIndex[1] - index[1];
      float frac_z = contIndex[2] - index[2];
      int px = index[0];
      if (frac_x<0)
      {
        px -= 1;
        frac_x += 1;
      }
      int py = index[1];
      if (frac_y<0)
      {
        py -= 1;
        frac_y += 1;
      }
      int pz = index[2];
      if (frac_z<0)
      {
        pz -= 1;
        frac_z += 1;
      }
      frac_x = 1-frac_x;
      frac_y = 1-frac_y;
      frac_z = 1-frac_z;

      // int coordinates inside image?
      if (px < 0 || px >= w-1)
        continue;
      if (py < 0 || py >= h-1)
        continue;
      if (pz < 0 || pz >= d-1)
        continue;

      OutPixelType out;
      switch (m_Channel)
      {
      case RED:
        out = (float)x.GetRed()/255;
        break;
      case GREEN:
        out = (float)x.GetGreen()/255;
        break;
      case BLUE:
        out = (float)x.GetBlue()/255;
        break;
      case ALPHA:
        out = (float)x.GetAlpha()/255;
      }

      outImageBufferPointer[( px   + w*(py  + h*pz  ))] += out*(  frac_x)*(  frac_y)*(  frac_z);
      outImageBufferPointer[( px   + w*(py+1+ h*pz  ))] += out*(  frac_x)*(1-frac_y)*(  frac_z);
      outImageBufferPointer[( px   + w*(py  + h*pz+h))] += out*(  frac_x)*(  frac_y)*(1-frac_z);
      outImageBufferPointer[( px   + w*(py+1+ h*pz+h))] += out*(  frac_x)*(1-frac_y)*(1-frac_z);
      outImageBufferPointer[( px+1 + w*(py  + h*pz  ))] += out*(1-frac_x)*(  frac_y)*(  frac_z);
      outImageBufferPointer[( px+1 + w*(py  + h*pz+h))] += out*(1-frac_x)*(  frac_y)*(1-frac_z);
      outImageBufferPointer[( px+1 + w*(py+1+ h*pz  ))] += out*(1-frac_x)*(1-frac_y)*(  frac_z);
      outImageBufferPointer[( px+1 + w*(py+1+ h*pz+h))] += out*(1-frac_x)*(1-frac_y)*(1-frac_z);

      counterImageBufferPointer[( px   + w*(py  + h*pz  ))] += 1;
      counterImageBufferPointer[( px   + w*(py+1+ h*pz  ))] += 1;
      counterImageBufferPointer[( px   + w*(py  + h*pz+h))] += 1;
      counterImageBufferPointer[( px   + w*(py+1+ h*pz+h))] += 1;
      counterImageBufferPointer[( px+1 + w*(py  + h*pz  ))] += 1;
      counterImageBufferPointer[( px+1 + w*(py  + h*pz+h))] += 1;
      counterImageBufferPointer[( px+1 + w*(py+1+ h*pz  ))] += 1;
      counterImageBufferPointer[( px+1 + w*(py+1+ h*pz+h))] += 1;

    }

    typedef ImageRegionIterator< OutputImageType > OutImageIteratorType;
    OutImageIteratorType outIt(outputImage, outputImage->GetLargestPossibleRegion());
    outIt.GoToBegin();
    typedef ImageRegionConstIterator< itk::Image< short, 3 > > CountImageIteratorType;
    CountImageIteratorType counterIt(counterImage, counterImage->GetLargestPossibleRegion());
    counterIt.GoToBegin();

    while(!outIt.IsAtEnd() && !counterIt.IsAtEnd()){
      if (counterIt.Value()>0)
        outIt.Set(outIt.Value()/counterIt.Value());
      ++outIt;
      ++counterIt;
    }
  }
}
<commit_msg>Fix warnings in DiffusionCore module<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

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

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/
#include "itkExtractChannelFromRgbaImageFilter.h"

// VTK
#include <vtkPolyLine.h>
#include <vtkCellArray.h>
#include <vtkCellData.h>

// misc
#include <math.h>

namespace itk{

  template< class ReferenceImageType, class OutputImageType >
  ExtractChannelFromRgbaImageFilter< ReferenceImageType, OutputImageType >::ExtractChannelFromRgbaImageFilter():
    m_Channel(RED)
  {

  }

  template< class ReferenceImageType, class OutputImageType >
  ExtractChannelFromRgbaImageFilter< ReferenceImageType, OutputImageType >::~ExtractChannelFromRgbaImageFilter()
  {
  }

  template< class ReferenceImageType, class OutputImageType >
  void ExtractChannelFromRgbaImageFilter< ReferenceImageType, OutputImageType >::GenerateData()
  {

    typename InputImageType::Pointer rgbaImage = static_cast< InputImageType * >( this->ProcessObject::GetInput(0) );

    typename OutputImageType::Pointer outputImage =
        static_cast< OutputImageType * >(this->ProcessObject::GetPrimaryOutput());

    typename InputImageType::RegionType region = rgbaImage->GetLargestPossibleRegion();
    outputImage->SetSpacing( m_ReferenceImage->GetSpacing() );   // Set the image spacing
    outputImage->SetOrigin( m_ReferenceImage->GetOrigin() );     // Set the image origin
    outputImage->SetDirection( m_ReferenceImage->GetDirection() );  // Set the image direction
    outputImage->SetRegions( m_ReferenceImage->GetLargestPossibleRegion());
    outputImage->Allocate();
    outputImage->FillBuffer(0);
    float* outImageBufferPointer = outputImage->GetBufferPointer();

    itk::Image< short, 3 >::Pointer counterImage = itk::Image< short, 3 >::New();
    counterImage->SetSpacing( m_ReferenceImage->GetSpacing() );   // Set the image spacing
    counterImage->SetOrigin( m_ReferenceImage->GetOrigin() );     // Set the image origin
    counterImage->SetDirection( m_ReferenceImage->GetDirection() );  // Set the image direction
    counterImage->SetRegions( m_ReferenceImage->GetLargestPossibleRegion());
    counterImage->Allocate();
    counterImage->FillBuffer(0);
    short* counterImageBufferPointer = counterImage->GetBufferPointer();

    int w = m_ReferenceImage->GetLargestPossibleRegion().GetSize().GetElement(0);
    int h = m_ReferenceImage->GetLargestPossibleRegion().GetSize().GetElement(1);
    int d = m_ReferenceImage->GetLargestPossibleRegion().GetSize().GetElement(2);

    typedef ImageRegionConstIterator< InputImageType > InImageIteratorType;
    InImageIteratorType rgbaIt(rgbaImage, region);
    rgbaIt.GoToBegin();
    while(!rgbaIt.IsAtEnd()){

      InPixelType x = rgbaIt.Get();
      ++rgbaIt;

      itk::Point<float, 3> vertex;
      itk::Index<3> index = rgbaIt.GetIndex();

      rgbaImage->TransformIndexToPhysicalPoint(index, vertex);
      outputImage->TransformPhysicalPointToIndex(vertex, index);

      itk::ContinuousIndex<float, 3> contIndex;
      outputImage->TransformPhysicalPointToContinuousIndex(vertex, contIndex);

      float frac_x = contIndex[0] - index[0];
      float frac_y = contIndex[1] - index[1];
      float frac_z = contIndex[2] - index[2];
      int px = index[0];
      if (frac_x<0)
      {
        px -= 1;
        frac_x += 1;
      }
      int py = index[1];
      if (frac_y<0)
      {
        py -= 1;
        frac_y += 1;
      }
      int pz = index[2];
      if (frac_z<0)
      {
        pz -= 1;
        frac_z += 1;
      }
      frac_x = 1-frac_x;
      frac_y = 1-frac_y;
      frac_z = 1-frac_z;

      // int coordinates inside image?
      if (px < 0 || px >= w-1)
        continue;
      if (py < 0 || py >= h-1)
        continue;
      if (pz < 0 || pz >= d-1)
        continue;

      OutPixelType out = 0.0f;
      switch (m_Channel)
      {
      case RED:
        out = (float)x.GetRed()/255;
        break;
      case GREEN:
        out = (float)x.GetGreen()/255;
        break;
      case BLUE:
        out = (float)x.GetBlue()/255;
        break;
      case ALPHA:
        out = (float)x.GetAlpha()/255;
      }

      outImageBufferPointer[( px   + w*(py  + h*pz  ))] += out*(  frac_x)*(  frac_y)*(  frac_z);
      outImageBufferPointer[( px   + w*(py+1+ h*pz  ))] += out*(  frac_x)*(1-frac_y)*(  frac_z);
      outImageBufferPointer[( px   + w*(py  + h*pz+h))] += out*(  frac_x)*(  frac_y)*(1-frac_z);
      outImageBufferPointer[( px   + w*(py+1+ h*pz+h))] += out*(  frac_x)*(1-frac_y)*(1-frac_z);
      outImageBufferPointer[( px+1 + w*(py  + h*pz  ))] += out*(1-frac_x)*(  frac_y)*(  frac_z);
      outImageBufferPointer[( px+1 + w*(py  + h*pz+h))] += out*(1-frac_x)*(  frac_y)*(1-frac_z);
      outImageBufferPointer[( px+1 + w*(py+1+ h*pz  ))] += out*(1-frac_x)*(1-frac_y)*(  frac_z);
      outImageBufferPointer[( px+1 + w*(py+1+ h*pz+h))] += out*(1-frac_x)*(1-frac_y)*(1-frac_z);

      counterImageBufferPointer[( px   + w*(py  + h*pz  ))] += 1;
      counterImageBufferPointer[( px   + w*(py+1+ h*pz  ))] += 1;
      counterImageBufferPointer[( px   + w*(py  + h*pz+h))] += 1;
      counterImageBufferPointer[( px   + w*(py+1+ h*pz+h))] += 1;
      counterImageBufferPointer[( px+1 + w*(py  + h*pz  ))] += 1;
      counterImageBufferPointer[( px+1 + w*(py  + h*pz+h))] += 1;
      counterImageBufferPointer[( px+1 + w*(py+1+ h*pz  ))] += 1;
      counterImageBufferPointer[( px+1 + w*(py+1+ h*pz+h))] += 1;

    }

    typedef ImageRegionIterator< OutputImageType > OutImageIteratorType;
    OutImageIteratorType outIt(outputImage, outputImage->GetLargestPossibleRegion());
    outIt.GoToBegin();
    typedef ImageRegionConstIterator< itk::Image< short, 3 > > CountImageIteratorType;
    CountImageIteratorType counterIt(counterImage, counterImage->GetLargestPossibleRegion());
    counterIt.GoToBegin();

    while(!outIt.IsAtEnd() && !counterIt.IsAtEnd()){
      if (counterIt.Value()>0)
        outIt.Set(outIt.Value()/counterIt.Value());
      ++outIt;
      ++counterIt;
    }
  }
}
<|endoftext|>


<commit_before>/**
* @file CleanRoleDecision.h
*
* @author Schahin Tofangchi
*/

#include "CleanRoleDecision.h"
#include <PlatformInterface/Platform.h>
#include <Tools/DataConversion.h>

#include <math.h>
#include <list>

using namespace std;

CleanRoleDecision::CleanRoleDecision()
{
  getDebugParameterList().add(&parameters);
}

CleanRoleDecision::~CleanRoleDecision()
{
  getDebugParameterList().remove(&parameters);
}

void CleanRoleDecision::execute() {
    getRoleDecisionModel().resetRobotStates();
    computeStrikers();

}//end execute

void CleanRoleDecision::computeStrikers()
{
    // container storing robots, which want to be striker, and their time to ball
    std::map<unsigned int, unsigned int> possible_striker;

    // iterate over all robots(messages)
    for (auto const& i : getTeamMessage().data) {
        unsigned int robotNumber = i.first;
        const TeamMessageData& msg = i.second;

        // if striker lost the ball, he gets a time bonus before he lost the ball completely ...
        double loose_ball_bonus = msg.playerNumber == getRoleDecisionModel().firstStriker?parameters.strikerBonusTime:0.0;

        // check if the robot is able to play and sees the ball
        bool isRobotInactive = msg.fallen
                || msg.custom.isPenalized
                || msg.ballAge < 0 //Ball hasn't been seen
                || (msg.ballAge + getFrameInfo().getTimeSince(msg.frameInfo.getTime()) > parameters.maxBallLostTime + loose_ball_bonus); //Ball isn't fresh

        // ignore "DEAD" and inactive robots
        if(isRobotDead(robotNumber) || isRobotInactive) { continue; }

        // for all active robots, which sees the ball AND previously announced to want to be striker ...
        if (msg.custom.wantsToBeStriker) {
            // ... remember them as possible striker with their time to ball
            possible_striker[robotNumber] = msg.custom.timeToBall;
        }
    }//end for

    // get my own message, but skip "first frame"! (until i add myself to teamcomm)
    double ownTimeToBall = std::numeric_limits<unsigned int>::max();
    const auto own = getTeamMessage().data.find(getPlayerInfo().playerNumber);
    if(own != getTeamMessage().data.end()) {
        // i want to be striker, if i'm not the goalie and i'm "active" (not fallen/panelized, see the ball)!!!
        getRoleDecisionModel().wantsToBeStriker = own->second.playerNumber != 1
                                                  && !(own->second.fallen || own->second.custom.isPenalized || own->second.ballAge < 0
                                                  || (own->second.ballAge + getFrameInfo().getTimeSince(own->second.frameInfo.getTime()) > parameters.maxBallLostTime + (getPlayerInfo().playerNumber==getRoleDecisionModel().firstStriker?parameters.strikerBonusTime:0.0)));

        // if i'm striker, i get a time bonus!
        // NOTE: ownTimeToBall can be negative if the robot is close to ball (!)
        ownTimeToBall = static_cast<double>(own->second.custom.timeToBall) - (own->second.custom.wasStriker ? 300.0 : 0.0);
    }

    // clear for new striker decision
    getRoleDecisionModel().resetStriker();
    // set the new striker
    for (auto it = possible_striker.cbegin(); it != possible_striker.cend(); ++it) {
        //If two robots want to be striker, the one with a smaller number is favoured => is the first in the map!!
        if(getRoleDecisionModel().firstStriker == std::numeric_limits<int>::max()) {
            getRoleDecisionModel().firstStriker = it->first;
        } else if (getRoleDecisionModel().secondStriker == std::numeric_limits<int>::max()) {
            getRoleDecisionModel().secondStriker = it->first;
        }
        // if there's a robot closer to the ball than myself, i don't want to be striker!
        if(it->second < ownTimeToBall) {
            getRoleDecisionModel().wantsToBeStriker = false;
        }
    }

    PLOT(std::string("CleanRoleDecision:FirstStrikerDecision"), getRoleDecisionModel().firstStriker);
    PLOT(std::string("CleanRoleDecision:SecondStrikerDecision"), getRoleDecisionModel().secondStriker);
}

bool CleanRoleDecision::isRobotDead(unsigned int robotNumber) {
    double failureProbability = 0.0;
    std::map<unsigned int, double>::const_iterator robotFailure = getTeamMessageStatisticsModel().failureProbabilities.find(robotNumber);
    if (robotFailure != getTeamMessageStatisticsModel().failureProbabilities.end()) {
      failureProbability = robotFailure->second;
    }
    bool isDead = failureProbability > parameters.minFailureProbability && robotNumber != getPlayerInfo().playerNumber;
    // update dead/alive lists
    if (isDead) { //Message is not fresh
      getRoleDecisionModel().deadRobots.push_back(robotNumber);
    } else {
      getRoleDecisionModel().aliveRobots.push_back(robotNumber);
    }
    return isDead;
}
<commit_msg>reversed previous changes, instead skip striker computation on first frame, until robot added himself to teamcomm<commit_after>/**
* @file CleanRoleDecision.h
*
* @author Schahin Tofangchi
*/

#include "CleanRoleDecision.h"
#include <PlatformInterface/Platform.h>
#include <Tools/DataConversion.h>

#include <math.h>
#include <list>

using namespace std;

CleanRoleDecision::CleanRoleDecision()
{
  getDebugParameterList().add(&parameters);
}

CleanRoleDecision::~CleanRoleDecision()
{
  getDebugParameterList().remove(&parameters);
}

void CleanRoleDecision::execute() {
    getRoleDecisionModel().resetRobotStates();
    computeStrikers();

}//end execute

void CleanRoleDecision::computeStrikers()
{
    // skip "first frame"! (until i add myself to teamcomm)
    if(getTeamMessage().data.find(getPlayerInfo().playerNumber) == getTeamMessage().data.end()) { return; }

    // container storing robots, which want to be striker, and their time to ball
    std::map<unsigned int, unsigned int> possible_striker;

    // iterate over all robots(messages)
    for (auto const& i : getTeamMessage().data) {
        unsigned int robotNumber = i.first;
        const TeamMessageData& msg = i.second;

        // if striker lost the ball, he gets a time bonus before he lost the ball completely ...
        double loose_ball_bonus = msg.playerNumber == getRoleDecisionModel().firstStriker?parameters.strikerBonusTime:0.0;

        // check if the robot is able to play and sees the ball
        bool isRobotInactive = msg.fallen
                || msg.custom.isPenalized
                || msg.ballAge < 0 //Ball hasn't been seen
                || (msg.ballAge + getFrameInfo().getTimeSince(msg.frameInfo.getTime()) > parameters.maxBallLostTime + loose_ball_bonus); //Ball isn't fresh

        // ignore "DEAD" and inactive robots
        if(isRobotDead(robotNumber) || isRobotInactive) { continue; }

        // for all active robots, which sees the ball AND previously announced to want to be striker ...
        if (msg.custom.wantsToBeStriker) {
            // ... remember them as possible striker with their time to ball
            possible_striker[robotNumber] = msg.custom.timeToBall;
        }
    }//end for

    // get my own message
    auto ownMessage = getTeamMessage().data.at(getPlayerInfo().playerNumber);
    // i want to be striker, if i'm not the goalie and i'm "active" (not fallen/panelized, see the ball)!!!
    getRoleDecisionModel().wantsToBeStriker = ownMessage.playerNumber != 1
                                              && !(ownMessage.fallen || ownMessage.custom.isPenalized || ownMessage.ballAge < 0
                                              || (ownMessage.ballAge + getFrameInfo().getTimeSince(ownMessage.frameInfo.getTime()) > parameters.maxBallLostTime + (getPlayerInfo().playerNumber==getRoleDecisionModel().firstStriker?parameters.strikerBonusTime:0.0)));

    // if i'm striker, i get a time bonus!
    // NOTE: ownTimeToBall can be negative if the robot is close to ball (!)
    double ownTimeToBall = static_cast<double>(ownMessage.custom.timeToBall) - (ownMessage.custom.wasStriker ? 300.0 : 0.0);

    // clear for new striker decision
    getRoleDecisionModel().resetStriker();
    // set the new striker
    for (auto it = possible_striker.cbegin(); it != possible_striker.cend(); ++it) {
        //If two robots want to be striker, the one with a smaller number is favoured => is the first in the map!!
        if(getRoleDecisionModel().firstStriker == std::numeric_limits<int>::max()) {
            getRoleDecisionModel().firstStriker = it->first;
        } else if (getRoleDecisionModel().secondStriker == std::numeric_limits<int>::max()) {
            getRoleDecisionModel().secondStriker = it->first;
        }
        // if there's a robot closer to the ball than myself, i don't want to be striker!
        if(it->second < ownTimeToBall) {
            getRoleDecisionModel().wantsToBeStriker = false;
        }
    }

    PLOT(std::string("CleanRoleDecision:FirstStrikerDecision"), getRoleDecisionModel().firstStriker);
    PLOT(std::string("CleanRoleDecision:SecondStrikerDecision"), getRoleDecisionModel().secondStriker);
}

bool CleanRoleDecision::isRobotDead(unsigned int robotNumber) {
    double failureProbability = 0.0;
    std::map<unsigned int, double>::const_iterator robotFailure = getTeamMessageStatisticsModel().failureProbabilities.find(robotNumber);
    if (robotFailure != getTeamMessageStatisticsModel().failureProbabilities.end()) {
      failureProbability = robotFailure->second;
    }
    bool isDead = failureProbability > parameters.minFailureProbability && robotNumber != getPlayerInfo().playerNumber;
    // update dead/alive lists
    if (isDead) { //Message is not fresh
      getRoleDecisionModel().deadRobots.push_back(robotNumber);
    } else {
      getRoleDecisionModel().aliveRobots.push_back(robotNumber);
    }
    return isDead;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: UpdateLockManager.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-12-14 17:25:48 $
 *
 *  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 "UpdateLockManager.hxx"

#include "MutexOwner.hxx"
#include "ViewShellBase.hxx"

#ifndef _COM_SUN_STAR_FRAME_XLAYOUTMANAGER_HPP_
#include <com/sun/star/frame/XLayoutManager.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XLAYOUTMANAGEREVENTBROADCASTER_HPP_
#include <com/sun/star/frame/XLayoutManagerEventBroadcaster.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_LAYOUTMANAGEREVENTS_HPP_
#include <com/sun/star/frame/LayoutManagerEvents.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif

#ifndef _CPPUHELPER_COMPBASE1_HXX_
#include <cppuhelper/compbase1.hxx>
#endif

#include <vcl/timer.hxx>
#include <sfx2/viewfrm.hxx>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star;

namespace {
typedef cppu::WeakComponentImplHelper1<frame::XLayoutManagerListener> InterfaceBase;
}

namespace sd {

/** This implementation class not only implements the Lock() and Unlock()
    methods but as well listens for the right combination of events to call
    Unlock() when all is ready after the PaneManager has switched (some of)
    its view shells.
*/

class UpdateLockManager::Implementation
    : protected MutexOwner,
      public InterfaceBase
{
public:
    Implementation (ViewShellBase& rBase);
    virtual ~Implementation (void);

    void Lock (void);
    void Unlock (void);
    bool IsLocked (void) const;

    /** Unlock regardless of the current lock level.
    */
    void ForceUnlock (void);

private:
    ViewShellBase& mrBase;
    /// A lock level greater than 0 indicates that the ViewShellBase is locked.
    sal_Int32 mnLockDepth;
    /// The emergency timer to unlock the ViewShellBase when all else fails.
    Timer maTimer;
    /// Remember when to unlock after a layout event from frame::XLayoutManager
    bool mbUnlockOnNextLayout;
    /// Remember whether we are listening to the frame::XLayoutManager
    bool mbListenerIsRegistered;
    /// Remember whether the frame::XLayoutManager is locked.
    bool mbLayouterIsLocked;
    /** We hold a weak reference to the layout manager in order to have
        access to it even when the ViewShellBase object is not valid anymore
        and can not be used to obtain the layout manager.
    */
    WeakReference<frame::XLayoutManager> mxLayoutManager;

    //=====  frame::XLayoutEventListener  =====================================

    /** The event of the layouter are observed to find the best moment for
        unlocking.  This is the first layout after the lock level of the
        layouter drops to one (we hold a lock to it ourselves which we
        release when unlocking).
    */
    virtual void SAL_CALL layoutEvent (
        const lang::EventObject& xSource,
        sal_Int16 eLayoutEvent,
        const Any& rInfo)
        throw (uno::RuntimeException);

    //=====  lang::XEventListener  ============================================
    virtual void SAL_CALL
        disposing (const lang::EventObject& rEventObject)
        throw (::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL disposing (void);

    /** This is only a fallback to make the office usable when for some
        reason the intended way of unlocking it failed.
    */
    DECL_LINK(Timeout, void*);

    /** Convenience method that finds the layout manager associated with the
        frame that shows the ViewShellBase.
    */
    Reference<frame::XLayoutManager> GetLayoutManager (void);

    Implementation (const Implementation&); // Not implemented.
    Implementation& operator= (const Implementation&); // Not implemented.
};

//===== UpdateLockManager =====================================================

UpdateLockManager::UpdateLockManager (ViewShellBase& rBase)
    : mpImpl(new Implementation(rBase))
{
    mpImpl->acquire();
}

UpdateLockManager::~UpdateLockManager (void)
{
    if (mpImpl != NULL)
    {
        mpImpl->ForceUnlock();
        mpImpl->release();
    }
}

void UpdateLockManager::Disable (void)
{
    if (mpImpl != NULL)
    {
        mpImpl->ForceUnlock();
        mpImpl->release();
        mpImpl = NULL;
    }
}

void UpdateLockManager::Lock (void)
{
    if (mpImpl != NULL)
        mpImpl->Lock();
}

void UpdateLockManager::Unlock (void)
{
    if (mpImpl != NULL)
        mpImpl->Unlock();
}

bool UpdateLockManager::IsLocked (void) const
{
    if (mpImpl != NULL)
        return mpImpl->IsLocked();
    else
        return false;
}

//===== UpdateLock::Implementation ============================================

UpdateLockManager::Implementation::Implementation (ViewShellBase& rBase)
    : InterfaceBase(maMutex),
      mrBase(rBase),
      mnLockDepth(0),
      maTimer(),
      mbUnlockOnNextLayout(false),
      mbListenerIsRegistered(false),
      mbLayouterIsLocked(false)
{
}

UpdateLockManager::Implementation::~Implementation (void)
{
    OSL_ASSERT(mnLockDepth==0);
    ForceUnlock();
}

void UpdateLockManager::Implementation::Lock (void)
{
    ++mnLockDepth;
    if (mnLockDepth == 1)
    {
        Reference<frame::XLayoutManager> xLayouter (GetLayoutManager());
        if (xLayouter.is())
        {
            // Register as event listener.
            Reference<frame::XLayoutManagerEventBroadcaster> xBroadcaster (
                xLayouter, UNO_QUERY);
            if (xBroadcaster.is())
            {
                mbListenerIsRegistered = true;
                xBroadcaster->addLayoutManagerEventListener(
                    Reference<frame::XLayoutManagerListener> (
                        static_cast<XWeak*>(this), UNO_QUERY) );
            }

            // Lock the layout manager.
            mbLayouterIsLocked = true;
            xLayouter->lock();
        }

        // As a fallback, when the notification mechanism does not work (or is
        // incorrectly used) we use a timer that will unlock us eventually.
        maTimer.SetTimeout(5000 /*ms*/);
        maTimer.SetTimeoutHdl(LINK(this,UpdateLockManager::Implementation,Timeout));
        maTimer.Start();
    }
}

void UpdateLockManager::Implementation::Unlock (void)
{
    --mnLockDepth;

    if (mnLockDepth == 0)
    {
        // Stop the timer.  We don't need it anymore.
        maTimer.Stop();

        try
        {
            Reference<frame::XLayoutManager> xLayouter (GetLayoutManager());
            if (xLayouter.is())
            {
                // Detach from the layouter.
                if (mbListenerIsRegistered)
                {
                    Reference<frame::XLayoutManagerEventBroadcaster> xBroadcaster (
                        xLayouter, UNO_QUERY);
                    if (xBroadcaster.is())
                    {
                        mbListenerIsRegistered = false;
                        xBroadcaster->removeLayoutManagerEventListener(
                            Reference<frame::XLayoutManagerListener> (
                                static_cast<XWeak*>(this), UNO_QUERY) );
                    }
                }

                // Unlock the layouter.
                if (mbLayouterIsLocked)
                {
                    mbLayouterIsLocked = false;
                    xLayouter->unlock();
                }
            }
        }
        catch (RuntimeException)
        { }

        // Force a rearrangement of the UI elements of the views.
        mrBase.Rearrange();
    }
}

bool UpdateLockManager::Implementation::IsLocked (void) const
{
    return (mnLockDepth > 0);
}

void UpdateLockManager::Implementation::ForceUnlock (void)
{
    while (IsLocked())
        Unlock();
}

void SAL_CALL UpdateLockManager::Implementation::layoutEvent (
    const lang::EventObject& xSource,
    sal_Int16 eLayoutEvent,
    const Any& rInfo)
    throw (uno::RuntimeException)
{
    switch (eLayoutEvent)
    {
        case frame::LayoutManagerEvents::LOCK:
        {
            sal_Int32 nLockCount;
            rInfo >>= nLockCount;
        }
        break;

        case frame::LayoutManagerEvents::UNLOCK:
        {
            sal_Int32 nLockCount;
            rInfo >>= nLockCount;
            if (nLockCount == 1)
            {
                // The lock count dropped to one.  This means that we are
                // the only one that still holds a lock to the layout
                // manager.  We unlock the layout manager now and the
                // ViewShellBase on the next layout of the layout manager.
                mbUnlockOnNextLayout = true;
                Reference<frame::XLayoutManager> xLayouter (GetLayoutManager());
                if (xLayouter.is() && mbLayouterIsLocked)
                {
                    mbLayouterIsLocked = false;
                    xLayouter->unlock();
                }
            }
        }
        break;

        case frame::LayoutManagerEvents::LAYOUT:
            // Unlock when the layout manager is not still locked.
            if (mbUnlockOnNextLayout)
                Unlock();
            break;
    }
}

void SAL_CALL UpdateLockManager::Implementation::disposing (const lang::EventObject& rEventObject)
    throw (::com::sun::star::uno::RuntimeException)
{
}

void SAL_CALL UpdateLockManager::Implementation::disposing (void)
{
}

IMPL_LINK(UpdateLockManager::Implementation, Timeout, void*, unused)
{
    // This method is only called when all else failed.  We unlock
    // regardless of how deep the lock depth.
    while (mnLockDepth > 0)
        Unlock();
    return 1;
}

Reference< ::com::sun::star::frame::XLayoutManager>
    UpdateLockManager::Implementation::GetLayoutManager (void)
{
    Reference<frame::XLayoutManager> xLayoutManager;

    if (mxLayoutManager.get() == NULL)
    {
        if (mrBase.GetViewFrame()!=NULL
            && mrBase.GetViewFrame()->GetFrame()!=NULL)
        {
            Reference<beans::XPropertySet> xFrameProperties (
                mrBase.GetViewFrame()->GetFrame()->GetFrameInterface(),
                UNO_QUERY);
            if (xFrameProperties.is())
            {
                try
                {
                    Any aValue (xFrameProperties->getPropertyValue(
                        ::rtl::OUString::createFromAscii("LayoutManager")));
                    aValue >>= xLayoutManager;
                }
                catch (const beans::UnknownPropertyException& rException)
                {
                    (void)rException;
                }
            }
            mxLayoutManager = xLayoutManager;
        }
    }
    else
        xLayoutManager = mxLayoutManager;

    return xLayoutManager;
}

} // end of anonymous namespace
<commit_msg>INTEGRATION: CWS pchfix02 (1.5.216); FILE MERGED 2006/09/01 17:37:34 kaib 1.5.216.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: UpdateLockManager.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 19:32:52 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#include "UpdateLockManager.hxx"

#include "MutexOwner.hxx"
#include "ViewShellBase.hxx"

#ifndef _COM_SUN_STAR_FRAME_XLAYOUTMANAGER_HPP_
#include <com/sun/star/frame/XLayoutManager.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XLAYOUTMANAGEREVENTBROADCASTER_HPP_
#include <com/sun/star/frame/XLayoutManagerEventBroadcaster.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_LAYOUTMANAGEREVENTS_HPP_
#include <com/sun/star/frame/LayoutManagerEvents.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif

#ifndef _CPPUHELPER_COMPBASE1_HXX_
#include <cppuhelper/compbase1.hxx>
#endif

#include <vcl/timer.hxx>
#include <sfx2/viewfrm.hxx>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star;

namespace {
typedef cppu::WeakComponentImplHelper1<frame::XLayoutManagerListener> InterfaceBase;
}

namespace sd {

/** This implementation class not only implements the Lock() and Unlock()
    methods but as well listens for the right combination of events to call
    Unlock() when all is ready after the PaneManager has switched (some of)
    its view shells.
*/

class UpdateLockManager::Implementation
    : protected MutexOwner,
      public InterfaceBase
{
public:
    Implementation (ViewShellBase& rBase);
    virtual ~Implementation (void);

    void Lock (void);
    void Unlock (void);
    bool IsLocked (void) const;

    /** Unlock regardless of the current lock level.
    */
    void ForceUnlock (void);

private:
    ViewShellBase& mrBase;
    /// A lock level greater than 0 indicates that the ViewShellBase is locked.
    sal_Int32 mnLockDepth;
    /// The emergency timer to unlock the ViewShellBase when all else fails.
    Timer maTimer;
    /// Remember when to unlock after a layout event from frame::XLayoutManager
    bool mbUnlockOnNextLayout;
    /// Remember whether we are listening to the frame::XLayoutManager
    bool mbListenerIsRegistered;
    /// Remember whether the frame::XLayoutManager is locked.
    bool mbLayouterIsLocked;
    /** We hold a weak reference to the layout manager in order to have
        access to it even when the ViewShellBase object is not valid anymore
        and can not be used to obtain the layout manager.
    */
    WeakReference<frame::XLayoutManager> mxLayoutManager;

    //=====  frame::XLayoutEventListener  =====================================

    /** The event of the layouter are observed to find the best moment for
        unlocking.  This is the first layout after the lock level of the
        layouter drops to one (we hold a lock to it ourselves which we
        release when unlocking).
    */
    virtual void SAL_CALL layoutEvent (
        const lang::EventObject& xSource,
        sal_Int16 eLayoutEvent,
        const Any& rInfo)
        throw (uno::RuntimeException);

    //=====  lang::XEventListener  ============================================
    virtual void SAL_CALL
        disposing (const lang::EventObject& rEventObject)
        throw (::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL disposing (void);

    /** This is only a fallback to make the office usable when for some
        reason the intended way of unlocking it failed.
    */
    DECL_LINK(Timeout, void*);

    /** Convenience method that finds the layout manager associated with the
        frame that shows the ViewShellBase.
    */
    Reference<frame::XLayoutManager> GetLayoutManager (void);

    Implementation (const Implementation&); // Not implemented.
    Implementation& operator= (const Implementation&); // Not implemented.
};

//===== UpdateLockManager =====================================================

UpdateLockManager::UpdateLockManager (ViewShellBase& rBase)
    : mpImpl(new Implementation(rBase))
{
    mpImpl->acquire();
}

UpdateLockManager::~UpdateLockManager (void)
{
    if (mpImpl != NULL)
    {
        mpImpl->ForceUnlock();
        mpImpl->release();
    }
}

void UpdateLockManager::Disable (void)
{
    if (mpImpl != NULL)
    {
        mpImpl->ForceUnlock();
        mpImpl->release();
        mpImpl = NULL;
    }
}

void UpdateLockManager::Lock (void)
{
    if (mpImpl != NULL)
        mpImpl->Lock();
}

void UpdateLockManager::Unlock (void)
{
    if (mpImpl != NULL)
        mpImpl->Unlock();
}

bool UpdateLockManager::IsLocked (void) const
{
    if (mpImpl != NULL)
        return mpImpl->IsLocked();
    else
        return false;
}

//===== UpdateLock::Implementation ============================================

UpdateLockManager::Implementation::Implementation (ViewShellBase& rBase)
    : InterfaceBase(maMutex),
      mrBase(rBase),
      mnLockDepth(0),
      maTimer(),
      mbUnlockOnNextLayout(false),
      mbListenerIsRegistered(false),
      mbLayouterIsLocked(false)
{
}

UpdateLockManager::Implementation::~Implementation (void)
{
    OSL_ASSERT(mnLockDepth==0);
    ForceUnlock();
}

void UpdateLockManager::Implementation::Lock (void)
{
    ++mnLockDepth;
    if (mnLockDepth == 1)
    {
        Reference<frame::XLayoutManager> xLayouter (GetLayoutManager());
        if (xLayouter.is())
        {
            // Register as event listener.
            Reference<frame::XLayoutManagerEventBroadcaster> xBroadcaster (
                xLayouter, UNO_QUERY);
            if (xBroadcaster.is())
            {
                mbListenerIsRegistered = true;
                xBroadcaster->addLayoutManagerEventListener(
                    Reference<frame::XLayoutManagerListener> (
                        static_cast<XWeak*>(this), UNO_QUERY) );
            }

            // Lock the layout manager.
            mbLayouterIsLocked = true;
            xLayouter->lock();
        }

        // As a fallback, when the notification mechanism does not work (or is
        // incorrectly used) we use a timer that will unlock us eventually.
        maTimer.SetTimeout(5000 /*ms*/);
        maTimer.SetTimeoutHdl(LINK(this,UpdateLockManager::Implementation,Timeout));
        maTimer.Start();
    }
}

void UpdateLockManager::Implementation::Unlock (void)
{
    --mnLockDepth;

    if (mnLockDepth == 0)
    {
        // Stop the timer.  We don't need it anymore.
        maTimer.Stop();

        try
        {
            Reference<frame::XLayoutManager> xLayouter (GetLayoutManager());
            if (xLayouter.is())
            {
                // Detach from the layouter.
                if (mbListenerIsRegistered)
                {
                    Reference<frame::XLayoutManagerEventBroadcaster> xBroadcaster (
                        xLayouter, UNO_QUERY);
                    if (xBroadcaster.is())
                    {
                        mbListenerIsRegistered = false;
                        xBroadcaster->removeLayoutManagerEventListener(
                            Reference<frame::XLayoutManagerListener> (
                                static_cast<XWeak*>(this), UNO_QUERY) );
                    }
                }

                // Unlock the layouter.
                if (mbLayouterIsLocked)
                {
                    mbLayouterIsLocked = false;
                    xLayouter->unlock();
                }
            }
        }
        catch (RuntimeException)
        { }

        // Force a rearrangement of the UI elements of the views.
        mrBase.Rearrange();
    }
}

bool UpdateLockManager::Implementation::IsLocked (void) const
{
    return (mnLockDepth > 0);
}

void UpdateLockManager::Implementation::ForceUnlock (void)
{
    while (IsLocked())
        Unlock();
}

void SAL_CALL UpdateLockManager::Implementation::layoutEvent (
    const lang::EventObject& xSource,
    sal_Int16 eLayoutEvent,
    const Any& rInfo)
    throw (uno::RuntimeException)
{
    switch (eLayoutEvent)
    {
        case frame::LayoutManagerEvents::LOCK:
        {
            sal_Int32 nLockCount;
            rInfo >>= nLockCount;
        }
        break;

        case frame::LayoutManagerEvents::UNLOCK:
        {
            sal_Int32 nLockCount;
            rInfo >>= nLockCount;
            if (nLockCount == 1)
            {
                // The lock count dropped to one.  This means that we are
                // the only one that still holds a lock to the layout
                // manager.  We unlock the layout manager now and the
                // ViewShellBase on the next layout of the layout manager.
                mbUnlockOnNextLayout = true;
                Reference<frame::XLayoutManager> xLayouter (GetLayoutManager());
                if (xLayouter.is() && mbLayouterIsLocked)
                {
                    mbLayouterIsLocked = false;
                    xLayouter->unlock();
                }
            }
        }
        break;

        case frame::LayoutManagerEvents::LAYOUT:
            // Unlock when the layout manager is not still locked.
            if (mbUnlockOnNextLayout)
                Unlock();
            break;
    }
}

void SAL_CALL UpdateLockManager::Implementation::disposing (const lang::EventObject& rEventObject)
    throw (::com::sun::star::uno::RuntimeException)
{
}

void SAL_CALL UpdateLockManager::Implementation::disposing (void)
{
}

IMPL_LINK(UpdateLockManager::Implementation, Timeout, void*, unused)
{
    // This method is only called when all else failed.  We unlock
    // regardless of how deep the lock depth.
    while (mnLockDepth > 0)
        Unlock();
    return 1;
}

Reference< ::com::sun::star::frame::XLayoutManager>
    UpdateLockManager::Implementation::GetLayoutManager (void)
{
    Reference<frame::XLayoutManager> xLayoutManager;

    if (mxLayoutManager.get() == NULL)
    {
        if (mrBase.GetViewFrame()!=NULL
            && mrBase.GetViewFrame()->GetFrame()!=NULL)
        {
            Reference<beans::XPropertySet> xFrameProperties (
                mrBase.GetViewFrame()->GetFrame()->GetFrameInterface(),
                UNO_QUERY);
            if (xFrameProperties.is())
            {
                try
                {
                    Any aValue (xFrameProperties->getPropertyValue(
                        ::rtl::OUString::createFromAscii("LayoutManager")));
                    aValue >>= xLayoutManager;
                }
                catch (const beans::UnknownPropertyException& rException)
                {
                    (void)rException;
                }
            }
            mxLayoutManager = xLayoutManager;
        }
    }
    else
        xLayoutManager = mxLayoutManager;

    return xLayoutManager;
}

} // end of anonymous namespace
<|endoftext|>


<commit_before>
// (c) COPYRIGHT URI/MIT 1994-1996
// Please read the full copyright statement in the file COPYRIGH.
//
// Authors:
//      jhrg,jimg       James Gallagher (jgallagher@gso.uri.edu)

//
// jhrg 7/29/94

// $Log: AttrTable.cc,v $
// Revision 1.16  1997/05/13 23:32:11  jimg
// Added changes to handle the new Alias and lexical scoping rules.
//
// Revision 1.15  1997/01/13 16:56:03  jimg
// Changed the name of the private member `map' to `attr_map' to avoid a name
// collision with the STL'd map class.
//
// Revision 1.14  1996/08/13 20:49:30  jimg
// Added __unused__ to definition of char rcsid[].
//
// Revision 1.13  1996/05/31 23:29:21  jimg
// Updated copyright notice.
//
// Revision 1.12  1996/04/05 00:21:18  jimg
// Compiled with g++ -Wall and fixed various warnings.
//
// Revision 1.11  1995/07/09  21:28:50  jimg
// Added copyright notice.
//
// Revision 1.10  1995/02/10  02:27:53  jimg
// Fixed an error where two attributes could be declared with the same name
// (for the same variable) if they hade different types.
//
// Revision 1.9  1994/12/21  03:03:37  reza
// Added overloading functions for get_attr_num().
//
// Revision 1.8  1994/12/07  21:09:24  jimg
// Added support for vectors of attributes (using XPlex from libg++).
//
// Revision 1.7  1994/10/13  15:43:29  jimg
// Added a new version of append_attr that takes (const char *)s and modified
// the version that takes strings to take (const String &).
//
// Revision 1.6  1994/10/05  16:38:17  jimg
// Changed internal representation of the attribute table from a Map
// to a DLList<>.
//
// Revision 1.5  1994/09/27  22:42:44  jimg
// Changed definition of the class AttrTable; it no longer inherits from
// AttrVHMap, instead it uses that class (contains a member that is an instance
// of AttrVHMap).
// Added mfuncs to AttrTable so that the new member could be set/accessed.
//
// Revision 1.4  1994/09/09  15:26:39  jimg
// Removed operator<< and added print() since I have no good way to define
// operator>>. It seems best to define all operators from a set (like <<, >>)
// or none at all. Since parse() is the input mfunc, it seems that output
// should be a mfunc too.
//
// Revision 1.3  1994/08/02  20:11:27  jimg
// Changes operator<< so that it writes a parsable version of the
// attribute table.
//' comments and rcsid[] variables (syntax errors due to //
// comments caused compilation failures.
// das.tab.c and .h are commited now as well.
//
// Revision 1.1  1994/08/02  18:32:04  jimg
// The implementation of AttrTable. This file defined ostream &operator<< and
// a static class variable String empty (it is initialized to "").
//

#include "config_dap.h"

static char rcsid[] __unused__ ="$Id: AttrTable.cc,v 1.16 1997/05/13 23:32:11 jimg Exp $";

#ifdef __GNUG__
#pragma implementation
#endif

#include <assert.h>

#include <ostream.h>

#include "AttrTable.h"

// Private member functions

// When CON_ONLY is true, stop recurring when at the last container.
// This ensures that the Pix returned will reference the AttrTable which
// containes the attribute - not the attribute itself.
Pix
AttrTable::find(const String &target, bool cont_only = false)
{
    if (target.contains(".")) {
	String name = (String)target; // cast away const
	String container = name.before(".");
	String field = name.after(".");

	Pix p = simple_find(container);
	if ((p) && attr_map(p).type == Attr_container) {
	    if (cont_only && !field.contains("."))
		return p;
	    else
		return attr_map(p).value.attributes->find(field, cont_only);
	}
	else
	    return 0;
    }
    else
	return simple_find(target);
}

Pix
AttrTable::simple_find(const String &target)
{
    for (Pix p = attr_map.first(); p; attr_map.next(p))
	if (target == attr_map(p).name)
	    return p;
    return 0;
}

String
AttrTable::AttrTypeToString(const AttrType at)
{
    switch (at) {
      case Attr_container: return "Container";
      case Attr_byte: return "Byte";
      case Attr_int32: return "Int32";
      case Attr_uint32: return "Uint32";
      case Attr_float64: return "Float64";
      case Attr_string: return "String";
      case Attr_url: return "Url";
      default: return "";
    }
}

AttrType
AttrTable::StringToAttrType(const String &s)
{
    String s2 = capitalize(s);
    if (s2 == "Container")
	return Attr_container;
    else if (s2 == "Byte")
	return Attr_byte;
    else if (s2 == "Int32")
	return Attr_int32;
    else if (s2 == "Uint32")
	return Attr_uint32;
    else if (s2 == "Float64")
	return Attr_float64;
    else if (s2 == "String")
	return Attr_string;
    else if (s2 == "Url")
	return Attr_url;
    else
	return Attr_unknown;
}

// Public member functions

AttrTable::AttrTable()
{
}

AttrTable::~AttrTable()
{
    for (Pix p = attr_map.first(); p; attr_map.next(p))
	// Don't delete the referenced objects in an alias!
	if (!attr_map(p).is_alias)
	    if (attr_map(p).type == Attr_container)
		delete attr_map(p).value.attributes;
	    else
		delete attr_map(p).value.attr;
}

Pix
AttrTable::first_attr()
{
    return attr_map.first();
}

void
AttrTable::next_attr(Pix &p)
{
    attr_map.next(p);
}

String
AttrTable::get_name(Pix p)
{
    assert(p);
    return attr_map(p).name;
}

bool
AttrTable::is_container(Pix p)
{
    assert(p);
    return attr_map(p).type == Attr_container;
}

AttrTable *
AttrTable::get_attr_table(Pix p)
{
    assert(p);
    return attr_map(p).type == Attr_container ? attr_map(p).value.attributes : 0;
}

AttrTable *
AttrTable::get_attr_table(const String &name)
{
    Pix p = find(name, true);	// Return only Pixes to container attributes
    return (p) ?  get_attr_table(p) : 0;
}

AttrTable *
AttrTable::get_attr_table(const char *name)
{
    return get_attr_table((String)name);
}

String
AttrTable::get_type(Pix p)
{
    assert(p);
    return AttrTypeToString(attr_map(p).type);
}

String
AttrTable::get_type(const String &name)
{
    Pix p = find(name);
    return (p) ?  get_type(p) : (String)"";
}

String
AttrTable::get_type(const char *name)
{
    return get_type((String)name);
}

AttrType
AttrTable::get_attr_type(Pix p)
{
    assert(p);
    return attr_map(p).type;
}

AttrType
AttrTable::get_attr_type(const String &name)
{
    Pix p = find(name);
    return (p) ?  get_attr_type(p) : Attr_unknown;
}

AttrType
AttrTable::get_attr_type(const char *name)
{
    return get_attr_type((String)name);
}

unsigned int
AttrTable::get_attr_num(Pix p)
{
    assert(p);
    return attr_map(p).type == Attr_container ? 0 : attr_map(p).value.attr->length();
}

unsigned int
AttrTable::get_attr_num(const String &name)
{
    Pix p = find(name);
    return (p) ?  get_attr_num(p) : 0;
}

unsigned int
AttrTable::get_attr_num(const char *name)
{
    return get_attr_num((String)name);
}

String
AttrTable::get_attr(Pix p, unsigned int i)
{
    assert(p);
    return attr_map(p).type == Attr_container ? (String)"None" : (*attr_map(p).value.attr)[i];
}

String
AttrTable::get_attr(const String &name, unsigned int i)
{
    Pix p = find(name);
    return (p) ? get_attr(p, i) : (String)"";
}

String
AttrTable::get_attr(const char *name, unsigned int i)
{
    return get_attr((String)name, i);
}

StringXPlex *
AttrTable::get_attr_vector(Pix p)
{
    assert(p);
    return attr_map(p).type != Attr_container ? attr_map(p).value.attr : 0;
}

StringXPlex *
AttrTable::get_attr_vector(const String &name)
{
    Pix p = find(name);
    return (p) ?  get_attr_vector(p) : 0;
}

unsigned int
AttrTable::append_attr(const String &name, const String &type,
		       const String &attr)
{
    Pix p = find(name);
    // If the types don't match OR this attribute is a container, calling
    // this mfunc is an error!
    if (p && (get_type(p) != type
	      || get_type(p) == "Container"))
	return 0;
    else if (p)			// Must be a new attribute value; add it.
	return attr_map(p).value.attr->add_high(attr) + 1;
    else {			// Must be a completely new attribute; add it
	entry e;

	e.name = name;
	e.is_alias = false;
	e.type = StringToAttrType(type); // Record type using standard names.
	e.value.attr = new StringXPlex;
	unsigned int len = e.value.attr->add_high(attr) + 1;

	attr_map.append(e);

	return len;		// return the length of the attr XPlex
    }
}

AttrTable *
AttrTable::append_container(const String &name)
{
    Pix p = find(name);

    // Return an error if NAME already exists.
    if (p)
	return 0;

    entry e;
    e.name = name;
    e.is_alias = false;
    e.type = Attr_container;
    e.value.attributes = new AttrTable();

    attr_map.append(e);

    return e.value.attributes;
}

bool
AttrTable::attr_alias(const String &alias, AttrTable *at, const String &name)
{
    // It is an error for alias to exist already.
    if (find(alias))
	return false;

    // Check for null Attrtable for source (information to be aliased).
    if (!at)
	return false;

    // Make sure that `name' really exists.
    Pix p = at->find(name);
    if (!p)
	return false;

    entry e;
    e.name = alias;
    e.is_alias = true;
    e.type = at->attr_map(p).type;
    if (e.type == Attr_container)
	e.value.attributes = at->get_attr_table(p);
    else {
	e.value.attr = at->attr_map(p).value.attr;
    }

    attr_map.append(e);

    return true;
}

bool
AttrTable::attr_alias(const String &alias, const String &name)
{
    return attr_alias(alias, this, name);
}

// Delete the attribute NAME. If NAME is an array of attributes, delete the
// I(th) element if I is >= 0. If I is -1 (the default), remove the entire
// attribute even f it is an array of values.
//
// Returns: void

void
AttrTable::del_attr(const String &name, int i)
{
    Pix p = find(name);
    if (p) {
	if (i == -1) {		// Delete the whole attribute
	    attr_map.prev(p);	// p now points to the previous element
	    attr_map.del_after(p);	// ... delete the following element
	}
	else {			// Delete one element from attribute array
	    // Don't try to delete elements from the vector of values if the
	    // map is a container!
	    if (attr_map(p).type == Attr_container)
		return;

	    StringXPlex *sxp = attr_map(p).value.attr;

	    assert(i >= 0 && i < sxp->fence());
	    for (int j = i+1; j < sxp->fence(); ++j)
		sxp[j-1] = sxp[j]; // mv array elements to empty space
	    (void) sxp->del_high(); // rm extra element
	}
    }
}

void
AttrTable::print(ostream &os, String pad)
{
    for(Pix p = attr_map.first(); p; attr_map.next(p)) {
	switch (attr_map(p).type) {
	  case Attr_container:
	    os << pad << get_name(p) << " {" << endl;

	    attr_map(p).value.attributes->print(os, pad + "    ");

	    os << pad << "}" << endl;
	    break;

	  default: {
		os << pad << get_type(p) << " " << get_name(p) << " " ;

		StringXPlex *sxp = attr_map(p).value.attr;

		for (int i = 0; i < sxp->high(); ++i)
		    os << (*sxp)[i] << ", ";

		os << (*sxp)[sxp->high()] << ";" << endl;
	    }
	    break;
	}
    }
}
<commit_msg>Added mfuncs with char * parameters for some of the calls. See AttrTable.h<commit_after>
// (c) COPYRIGHT URI/MIT 1994-1996
// Please read the full copyright statement in the file COPYRIGH.
//
// Authors:
//      jhrg,jimg       James Gallagher (jgallagher@gso.uri.edu)

//
// jhrg 7/29/94

// $Log: AttrTable.cc,v $
// Revision 1.17  1997/06/06 03:12:44  jimg
// Added mfuncs with char * parameters for some of the calls. See AttrTable.h
//
// Revision 1.16  1997/05/13 23:32:11  jimg
// Added changes to handle the new Alias and lexical scoping rules.
//
// Revision 1.15  1997/01/13 16:56:03  jimg
// Changed the name of the private member `map' to `attr_map' to avoid a name
// collision with the STL'd map class.
//
// Revision 1.14  1996/08/13 20:49:30  jimg
// Added __unused__ to definition of char rcsid[].
//
// Revision 1.13  1996/05/31 23:29:21  jimg
// Updated copyright notice.
//
// Revision 1.12  1996/04/05 00:21:18  jimg
// Compiled with g++ -Wall and fixed various warnings.
//
// Revision 1.11  1995/07/09  21:28:50  jimg
// Added copyright notice.
//
// Revision 1.10  1995/02/10  02:27:53  jimg
// Fixed an error where two attributes could be declared with the same name
// (for the same variable) if they hade different types.
//
// Revision 1.9  1994/12/21  03:03:37  reza
// Added overloading functions for get_attr_num().
//
// Revision 1.8  1994/12/07  21:09:24  jimg
// Added support for vectors of attributes (using XPlex from libg++).
//
// Revision 1.7  1994/10/13  15:43:29  jimg
// Added a new version of append_attr that takes (const char *)s and modified
// the version that takes strings to take (const String &).
//
// Revision 1.6  1994/10/05  16:38:17  jimg
// Changed internal representation of the attribute table from a Map
// to a DLList<>.
//
// Revision 1.5  1994/09/27  22:42:44  jimg
// Changed definition of the class AttrTable; it no longer inherits from
// AttrVHMap, instead it uses that class (contains a member that is an instance
// of AttrVHMap).
// Added mfuncs to AttrTable so that the new member could be set/accessed.
//
// Revision 1.4  1994/09/09  15:26:39  jimg
// Removed operator<< and added print() since I have no good way to define
// operator>>. It seems best to define all operators from a set (like <<, >>)
// or none at all. Since parse() is the input mfunc, it seems that output
// should be a mfunc too.
//
// Revision 1.3  1994/08/02  20:11:27  jimg
// Changes operator<< so that it writes a parsable version of the
// attribute table.
//' comments and rcsid[] variables (syntax errors due to //
// comments caused compilation failures.
// das.tab.c and .h are commited now as well.
//
// Revision 1.1  1994/08/02  18:32:04  jimg
// The implementation of AttrTable. This file defined ostream &operator<< and
// a static class variable String empty (it is initialized to "").
//

#include "config_dap.h"

static char rcsid[] __unused__ ="$Id: AttrTable.cc,v 1.17 1997/06/06 03:12:44 jimg Exp $";

#ifdef __GNUG__
#pragma implementation
#endif

#include <assert.h>

#include <ostream.h>

#include "AttrTable.h"

// Private member functions

// When CON_ONLY is true, stop recurring when at the last container.
// This ensures that the Pix returned will reference the AttrTable which
// containes the attribute - not the attribute itself.
Pix
AttrTable::find(const String &target, bool cont_only = false)
{
    if (target.contains(".")) {
	String name = (String)target; // cast away const
	String container = name.before(".");
	String field = name.after(".");

	Pix p = simple_find(container);
	if ((p) && attr_map(p).type == Attr_container) {
	    if (cont_only && !field.contains("."))
		return p;
	    else
		return attr_map(p).value.attributes->find(field, cont_only);
	}
	else
	    return 0;
    }
    else
	return simple_find(target);
}

Pix
AttrTable::simple_find(const String &target)
{
    for (Pix p = attr_map.first(); p; attr_map.next(p))
	if (target == attr_map(p).name)
	    return p;
    return 0;
}

String
AttrTable::AttrTypeToString(const AttrType at)
{
    switch (at) {
      case Attr_container: return "Container";
      case Attr_byte: return "Byte";
      case Attr_int32: return "Int32";
      case Attr_uint32: return "Uint32";
      case Attr_float64: return "Float64";
      case Attr_string: return "String";
      case Attr_url: return "Url";
      default: return "";
    }
}

AttrType
AttrTable::StringToAttrType(const String &s)
{
    String s2 = capitalize(s);
    if (s2 == "Container")
	return Attr_container;
    else if (s2 == "Byte")
	return Attr_byte;
    else if (s2 == "Int32")
	return Attr_int32;
    else if (s2 == "Uint32")
	return Attr_uint32;
    else if (s2 == "Float64")
	return Attr_float64;
    else if (s2 == "String")
	return Attr_string;
    else if (s2 == "Url")
	return Attr_url;
    else
	return Attr_unknown;
}

// Public member functions

AttrTable::AttrTable()
{
}

AttrTable::~AttrTable()
{
    for (Pix p = attr_map.first(); p; attr_map.next(p))
	// Don't delete the referenced objects in an alias!
	if (!attr_map(p).is_alias)
	    if (attr_map(p).type == Attr_container)
		delete attr_map(p).value.attributes;
	    else
		delete attr_map(p).value.attr;
}

Pix
AttrTable::first_attr()
{
    return attr_map.first();
}

void
AttrTable::next_attr(Pix &p)
{
    attr_map.next(p);
}

String
AttrTable::get_name(Pix p)
{
    assert(p);
    return attr_map(p).name;
}

bool
AttrTable::is_container(Pix p)
{
    assert(p);
    return attr_map(p).type == Attr_container;
}

AttrTable *
AttrTable::get_attr_table(Pix p)
{
    assert(p);
    return attr_map(p).type == Attr_container ? attr_map(p).value.attributes : 0;
}

AttrTable *
AttrTable::get_attr_table(const String &name)
{
    Pix p = find(name, true);	// Return only Pixes to container attributes
    return (p) ?  get_attr_table(p) : 0;
}

AttrTable *
AttrTable::get_attr_table(const char *name)
{
    return get_attr_table((String)name);
}

String
AttrTable::get_type(Pix p)
{
    assert(p);
    return AttrTypeToString(attr_map(p).type);
}

String
AttrTable::get_type(const String &name)
{
    Pix p = find(name);
    return (p) ?  get_type(p) : (String)"";
}

String
AttrTable::get_type(const char *name)
{
    return get_type((String)name);
}

AttrType
AttrTable::get_attr_type(Pix p)
{
    assert(p);
    return attr_map(p).type;
}

AttrType
AttrTable::get_attr_type(const String &name)
{
    Pix p = find(name);
    return (p) ?  get_attr_type(p) : Attr_unknown;
}

AttrType
AttrTable::get_attr_type(const char *name)
{
    return get_attr_type((String)name);
}

unsigned int
AttrTable::get_attr_num(Pix p)
{
    assert(p);
    return attr_map(p).type == Attr_container ? 0 : attr_map(p).value.attr->length();
}

unsigned int
AttrTable::get_attr_num(const String &name)
{
    Pix p = find(name);
    return (p) ?  get_attr_num(p) : 0;
}

unsigned int
AttrTable::get_attr_num(const char *name)
{
    return get_attr_num((String)name);
}

String
AttrTable::get_attr(Pix p, unsigned int i)
{
    assert(p);
    return attr_map(p).type == Attr_container ? (String)"None" : (*attr_map(p).value.attr)[i];
}

String
AttrTable::get_attr(const String &name, unsigned int i)
{
    Pix p = find(name);
    return (p) ? get_attr(p, i) : (String)"";
}

String
AttrTable::get_attr(const char *name, unsigned int i)
{
    return get_attr((String)name, i);
}

StringXPlex *
AttrTable::get_attr_vector(Pix p)
{
    assert(p);
    return attr_map(p).type != Attr_container ? attr_map(p).value.attr : 0;
}

StringXPlex *
AttrTable::get_attr_vector(const String &name)
{
    Pix p = find(name);
    return (p) ?  get_attr_vector(p) : 0;
}

StringXPlex *
AttrTable::get_attr_vector(const char *name)
{
    return get_attr_vector((String)name);
}

unsigned int
AttrTable::append_attr(const String &name, const String &type,
		       const String &attr)
{
    Pix p = find(name);
    // If the types don't match OR this attribute is a container, calling
    // this mfunc is an error!
    if (p && (get_type(p) != type
	      || get_type(p) == "Container"))
	return 0;
    else if (p)			// Must be a new attribute value; add it.
	return attr_map(p).value.attr->add_high(attr) + 1;
    else {			// Must be a completely new attribute; add it
	entry e;

	e.name = name;
	e.is_alias = false;
	e.type = StringToAttrType(type); // Record type using standard names.
	e.value.attr = new StringXPlex;
	unsigned int len = e.value.attr->add_high(attr) + 1;

	attr_map.append(e);

	return len;		// return the length of the attr XPlex
    }
}

unsigned int
AttrTable::append_attr(const char *name, const char *type, const char *attr)
{
    return append_attr((String)name, (String)type, (String)attr);
}

AttrTable *
AttrTable::append_container(const String &name)
{
    Pix p = find(name);

    // Return an error if NAME already exists.
    if (p)
	return 0;

    entry e;
    e.name = name;
    e.is_alias = false;
    e.type = Attr_container;
    e.value.attributes = new AttrTable();

    attr_map.append(e);

    return e.value.attributes;
}

bool
AttrTable::attr_alias(const String &alias, AttrTable *at, const String &name)
{
    // It is an error for alias to exist already.
    if (find(alias))
	return false;

    // Check for null Attrtable for source (information to be aliased).
    if (!at)
	return false;

    // Make sure that `name' really exists.
    Pix p = at->find(name);
    if (!p)
	return false;

    entry e;
    e.name = alias;
    e.is_alias = true;
    e.type = at->attr_map(p).type;
    if (e.type == Attr_container)
	e.value.attributes = at->get_attr_table(p);
    else {
	e.value.attr = at->attr_map(p).value.attr;
    }

    attr_map.append(e);

    return true;
}

bool
AttrTable::attr_alias(const String &alias, const String &name)
{
    return attr_alias(alias, this, name);
}

// Delete the attribute NAME. If NAME is an array of attributes, delete the
// I(th) element if I is >= 0. If I is -1 (the default), remove the entire
// attribute even f it is an array of values.
//
// Returns: void

void
AttrTable::del_attr(const String &name, int i)
{
    Pix p = find(name);
    if (p) {
	if (i == -1) {		// Delete the whole attribute
	    attr_map.prev(p);	// p now points to the previous element
	    attr_map.del_after(p);	// ... delete the following element
	}
	else {			// Delete one element from attribute array
	    // Don't try to delete elements from the vector of values if the
	    // map is a container!
	    if (attr_map(p).type == Attr_container)
		return;

	    StringXPlex *sxp = attr_map(p).value.attr;

	    assert(i >= 0 && i < sxp->fence());
	    for (int j = i+1; j < sxp->fence(); ++j)
		sxp[j-1] = sxp[j]; // mv array elements to empty space
	    (void) sxp->del_high(); // rm extra element
	}
    }
}

void
AttrTable::print(ostream &os, String pad)
{
    for(Pix p = attr_map.first(); p; attr_map.next(p)) {
	switch (attr_map(p).type) {
	  case Attr_container:
	    os << pad << get_name(p) << " {" << endl;

	    attr_map(p).value.attributes->print(os, pad + "    ");

	    os << pad << "}" << endl;
	    break;

	  default: {
		os << pad << get_type(p) << " " << get_name(p) << " " ;

		StringXPlex *sxp = attr_map(p).value.attr;

		for (int i = 0; i < sxp->high(); ++i)
		    os << (*sxp)[i] << ", ";

		os << (*sxp)[sxp->high()] << ";" << endl;
	    }
	    break;
	}
    }
}
<|endoftext|>


<commit_before>/**
* @Author: Ubi de Feo | Future Tailors
* @Date:   2017-07-09 16:34:07
* @Last Modified by: sbhklr
* @Last Modified time: 2020-04-23 12:34:23
**/

#include "FTDebouncer.h"

#define DEFAULT_DEBOUNCE_DELAY 40

/*	CONSTRUCTORS/DESTRUCTOR	*/
FTDebouncer::FTDebouncer() : _debounceDelay(DEFAULT_DEBOUNCE_DELAY) {
}

FTDebouncer::FTDebouncer(uint16_t debounceDelay) : _debounceDelay(debounceDelay) {
}

FTDebouncer::~FTDebouncer() {
}

/*	METHODS	*/

void FTDebouncer::addPin(uint8_t pinNr, uint8_t restState, int pullMode) {
	DebounceItem *debounceItem = new DebounceItem();

	debounceItem->pinNumber = pinNr;
	debounceItem->restState = restState;

	if (_firstDebounceItem == nullptr) {
		_firstDebounceItem = debounceItem;
	} else {
		_lastDebounceItem->nextItem = debounceItem;
	}

	_lastDebounceItem = debounceItem;

	pinMode(pinNr, static_cast<uint8_t>(pullMode));

	++_debouncedItemsCount;
}
void FTDebouncer::setPinEnabled(uint8_t pinNr, bool enabled){
	for(DebounceItem *debounceItem = _firstDebounceItem; debounceItem != nullptr; debounceItem = debounceItem->nextItem){
		if(debounceItem->pinNumber == pinNr){
			if(enabled) pinMode(debounceItem->pinNumber, debounceItem->pullMode);
			debounceItem->enabled = enabled;
			return;
		}
	}
}
void FTDebouncer::begin(){
	this->init();
}
void FTDebouncer::init() {
	unsigned long currentMilliseconds = millis();

	for(DebounceItem *debounceItem = _firstDebounceItem; debounceItem != nullptr; debounceItem = debounceItem->nextItem){
		debounceItem->lastTimeChecked = currentMilliseconds;
		debounceItem->currentState = debounceItem->previousState = debounceItem->restState;
		debounceItem->currentDebouncedState = debounceItem->previousDebouncedState = debounceItem->restState;
		debounceItem->enabled = true;
	}
}

void FTDebouncer::run() {
	for(DebounceItem *debounceItem = _firstDebounceItem; debounceItem != nullptr; debounceItem = debounceItem->nextItem){
		debounceItem->currentState = digitalRead(debounceItem->pinNumber);
	}

	this->debouncePins();
	this->checkStateChange();
}
void FTDebouncer::update(){
	this->run();
}
void FTDebouncer::debouncePins() {
	unsigned long currentMilliseconds = millis();

	for(DebounceItem *debounceItem = _firstDebounceItem; debounceItem != nullptr; debounceItem = debounceItem->nextItem){
		if (debounceItem->currentState != debounceItem->previousState) {
			debounceItem->lastTimeChecked = currentMilliseconds;
		}
		if (currentMilliseconds - debounceItem->lastTimeChecked > _debounceDelay) {
			if (debounceItem->previousState == debounceItem->currentState) {
				debounceItem->lastTimeChecked = currentMilliseconds;
				debounceItem->currentDebouncedState = debounceItem->currentState;
			}
		}
		debounceItem->previousState = debounceItem->currentState;
	}
}

void FTDebouncer::checkStateChange() {

	for(DebounceItem *debounceItem = _firstDebounceItem; debounceItem != nullptr; debounceItem = debounceItem->nextItem){
		if(!debounceItem->enabled) continue;
		if (debounceItem->previousDebouncedState != debounceItem->currentDebouncedState) {

			if (debounceItem->currentDebouncedState == debounceItem->restState) {
				onPinDeactivated(static_cast<int>(debounceItem->pinNumber));
			} else {
				onPinActivated(static_cast<int>(debounceItem->pinNumber));
			}
		}
		debounceItem->previousDebouncedState = debounceItem->currentDebouncedState;
	}
}

uint8_t FTDebouncer::getPinCount(){
	return _debouncedItemsCount;
}
<commit_msg>Rename pinNr parameter to be more expressive<commit_after>/**
* @Author: Ubi de Feo | Future Tailors
* @Date:   2017-07-09 16:34:07
* @Last Modified by: sbhklr
* @Last Modified time: 2020-04-23 12:34:23
**/

#include "FTDebouncer.h"

#define DEFAULT_DEBOUNCE_DELAY 40

/*	CONSTRUCTORS/DESTRUCTOR	*/
FTDebouncer::FTDebouncer() : _debounceDelay(DEFAULT_DEBOUNCE_DELAY) {
}

FTDebouncer::FTDebouncer(uint16_t debounceDelay) : _debounceDelay(debounceDelay) {
}

FTDebouncer::~FTDebouncer() {
}

/*	METHODS	*/

void FTDebouncer::addPin(uint8_t pinNumber, uint8_t restState, int pullMode) {
	DebounceItem *debounceItem = new DebounceItem();

	debounceItem->pinNumber = pinNumber;
	debounceItem->restState = restState;

	if (_firstDebounceItem == nullptr) {
		_firstDebounceItem = debounceItem;
	} else {
		_lastDebounceItem->nextItem = debounceItem;
	}

	_lastDebounceItem = debounceItem;

	pinMode(pinNumber, static_cast<uint8_t>(pullMode));

	++_debouncedItemsCount;
}

void FTDebouncer::setPinEnabled(uint8_t pinNumber, bool enabled){
	for(DebounceItem *debounceItem = _firstDebounceItem; debounceItem != nullptr; debounceItem = debounceItem->nextItem){
		if(debounceItem->pinNumber == pinNumber){
			if(enabled) pinMode(debounceItem->pinNumber, debounceItem->pullMode);
			debounceItem->enabled = enabled;
			return;
		}
	}
}
void FTDebouncer::begin(){
	this->init();
}

void FTDebouncer::init() {
	unsigned long currentMilliseconds = millis();

	for(DebounceItem *debounceItem = _firstDebounceItem; debounceItem != nullptr; debounceItem = debounceItem->nextItem){
		debounceItem->lastTimeChecked = currentMilliseconds;
		debounceItem->currentState = debounceItem->previousState = debounceItem->restState;
		debounceItem->currentDebouncedState = debounceItem->previousDebouncedState = debounceItem->restState;
		debounceItem->enabled = true;
	}
}

void FTDebouncer::run() {
	for(DebounceItem *debounceItem = _firstDebounceItem; debounceItem != nullptr; debounceItem = debounceItem->nextItem){
		debounceItem->currentState = digitalRead(debounceItem->pinNumber);
	}

	this->debouncePins();
	this->checkStateChange();
}

void FTDebouncer::update(){
	this->run();
}

void FTDebouncer::debouncePins() {
	unsigned long currentMilliseconds = millis();

	for(DebounceItem *debounceItem = _firstDebounceItem; debounceItem != nullptr; debounceItem = debounceItem->nextItem){
		if (debounceItem->currentState != debounceItem->previousState) {
			debounceItem->lastTimeChecked = currentMilliseconds;
		}
		if (currentMilliseconds - debounceItem->lastTimeChecked > _debounceDelay) {
			if (debounceItem->previousState == debounceItem->currentState) {
				debounceItem->lastTimeChecked = currentMilliseconds;
				debounceItem->currentDebouncedState = debounceItem->currentState;
			}
		}
		debounceItem->previousState = debounceItem->currentState;
	}
}

void FTDebouncer::checkStateChange() {

	for(DebounceItem *debounceItem = _firstDebounceItem; debounceItem != nullptr; debounceItem = debounceItem->nextItem){
		if(!debounceItem->enabled) continue;
		if (debounceItem->previousDebouncedState != debounceItem->currentDebouncedState) {

			if (debounceItem->currentDebouncedState == debounceItem->restState) {
				onPinDeactivated(static_cast<int>(debounceItem->pinNumber));
			} else {
				onPinActivated(static_cast<int>(debounceItem->pinNumber));
			}
		}
		debounceItem->previousDebouncedState = debounceItem->currentDebouncedState;
	}
}

uint8_t FTDebouncer::getPinCount(){
	return _debouncedItemsCount;
}
<|endoftext|>